[PYTHON] Défi pour générer des en-têtes Yahoo! News en utilisant uniquement l'API COTOHA

introduction

L'API COTOHA mène une campagne de collaboration avec Qiita. Je veux que PS4 refasse FF7 bientôt. (-P-)

https://zine.qiita.com/event/collaboration-cotoha-api/

C'est un motif complètement impur, mais j'ai essayé le traitement du langage naturel en utilisant l'API COTOHA. Aujourd'hui est la date limite pour poster, donc c'est assez proche, mais j'ai réussi à y arriver ...

Ce que j'ai fait

J'ai essayé de résumer les articles de presse en utilisant uniquement l'API fournie par COTOHA. Le thème est ** Génération d'en-têtes Yahoo! News **.

Rubrique Yahoo! News

Comme vous le savez tous sur Yahoo! News, chaque article a un titre. Par exemple, cela ressemble à ce qui suit.

スクリーンショット 2020-03-10 23.54.59.png

Cette rubrique, que je vois habituellement avec désinvolture, est en fait faite selon diverses règles et est profonde.

Tout d'abord, afin de communiquer simplement et systématiquement dans un espace limité Le nombre de caractères est limité à ** jusqu'à 13 caractères ** (pour être exact, 13,5 caractères y compris les espaces demi-largeur).

L'en-tête contient également des ** informations de localisation **. En cas d'incident ou d'accident, l'importance des nouvelles et le degré d'intérêt des utilisateurs varient considérablement selon l'endroit où elles se produisent.

Et les mots utilisés dans les titres sont essentiellement des ** mots dans l'article **. Parce que les articles sont distribués à chaque média, sauf si cela ne rentre pas dans le nombre de caractères Il semble qu'il le fasse pour ne pas déformer le contenu de l'article.

Si vous voulez créer un titre en utilisant les mots de l'article, utilisez l'API COTOHA Je pensais pouvoir le faire dans une certaine mesure.

Il existe d'autres règles, mais les règles que nous avons couvertes cette fois sont résumées ci-dessous.

[Référence] Le secret des sujets d'actualité Yahoo! https://news.yahoo.co.jp/newshack/inside/yahoonews_topics_heading.html

COTOHA API ** API pour le traitement du langage naturel et la reconnaissance vocale ** fournie par NTT Communications. 14 API de traitement du langage naturel et de traitement de la voix telles que l'analyse syntaxique et la reconnaissance vocale sont fournies. https://api.ce-cotoha.com/contents/index.html

Cette fois, j'ai utilisé la ** version Developers ** de l'API COTOHA. Il existe certaines restrictions par rapport à la version Enterprise, mais vous pouvez l'utiliser gratuitement.

Articles ciblés cette fois

Cette fois, j'ai ciblé l'article suivant indiquant que Bill Gates a pris sa retraite de la SP. https://news.yahoo.co.jp/pickup/6354056

Voici le titre qui était joint.

Bill Gates prend sa retraite en tant que directeur de la SP

Umm. Certainement complet et facile à comprendre.

Étape 1: Tout d'abord, lancez un défi avec juste l'API de résumé

L'API COTOHA fournit une ** API récapitulative **. Bien qu'il soit encore en version bêta, vous pouvez l'utiliser pour ** extraire des phrases que vous jugez importantes dans la phrase **.

Tout d'abord, j'ai décidé d'extraire une phrase en utilisant cette API.

{
  "result": "Gates a pris sa retraite de la ligne de direction en 2008 et a pris sa retraite en tant que président en 2014, mais est resté au conseil d'administration.",
  "status": 0
}

J'ai pu l'extraire en toute sécurité, mais il dépasse clairement 13 caractères, donc je dois ** le raccourcir **. Je m'inquiétais de savoir comment le raccourcir, mais j'ai décidé de continuer avec la méthode ** de ne laisser que les mots-clés de haute importance **.

Étape 2: Extraire les mots importants à l'aide de l'API d'extraction de mots clés

Plus tôt, j'ai écrit dans l'article de Qiita que vous pouvez extraire des mots-clés de grande importance en utilisant term extract.

[Référence] Générateur automatique de balises Qiita https://qiita.com/fukumasa/items/7f6f69d4f6336aff3d90

L'API COTOHA fournit également une ** API d'extraction de mots clés **, Les expressions et mots caractéristiques contenus dans le texte peuvent être extraits en tant que mots-clés.

Extrayons les mots-clés de la phrase extraite précédemment.

{
  "result": [
    {
      "form": "Président",
      "score": 14.48722
    },
    {
      "form": "Ligne",
      "score": 11.3583
    },
    {
      "form": "Retraité",
      "score": 11.2471
    },
    {
      "form": "Conseil d'administration",
      "score": 10.0
    }
  ],
  "status": 0,
  "message": ""
}

À ce stade, je suis déjà méfiant ... ** Les informations essentielles "qui" ** (M. Gates) n'ont pas été extraites. Eh bien, je vais continuer pour le moment.

Étape 3: Extraire les informations de localisation à l'aide de l'API d'extraction d'expression unique

Comme je l'ai écrit dans la règle d'ouverture, l'en-tête doit inclure des informations de localisation. COTOHA fournit une API pratique pour récupérer des informations de localisation. ** API d'extraction d'expressions unique **. En utilisant cette API, vous pouvez obtenir des expressions uniques telles que des noms de personnes et des noms de lieux.

Je l'ai essayé avec la phrase que j'ai extraite plus tôt, mais elle n'incluait pas les informations de localisation.

Si elle est incluse, c'est très simple, mais ** "extrait les informations de localisation" avec "de" ** J'ai décidé de l'inclure au début du résumé.

Étape 4: Ajouter des mots auxiliaires aux mots-clés à l'aide de l'API d'analyse syntaxique

Il semble difficile de générer un titre (une phrase) simplement en organisant ces mots-clés extraits. Je ne pouvais pas faire de choses avancées pour générer automatiquement des phrases basées sur des mots-clés, et j'étais assez inquiète.

Depuis que j'impose la restriction d'utiliser uniquement l'API COTOHA, lorsque j'ai regardé à nouveau la liste des API, une a flashé. À l'aide de ** l'API d'analyse de syntaxe **, vous pouvez ajouter ** des mots auxiliaires tels que "ga" et "o" à chaque mot-clé extrait pour connecter chaque mot-clé **.

En utilisant cette API, le texte est décomposé en clauses et morphologie, et les relations de dépendance entre les clauses et Des relations de dépendance entre les éléments morphologiques, des informations sémantiques telles que des informations de paroles de partie, etc. sont ajoutées.

Y a-t-il une relation entre les mots-clés extraits et les mots auxiliaires? (Je ne sais pas comment l'exprimer ...) semble pouvoir être extrait. Par exemple, dans le cas de «l'air est délicieux», c'est comme extraire «ga» comme mot auxiliaire pour le mot-clé «air».

Utilisons cette API pour ajouter un mot auxiliaire au mot clé précédent.

Réponse renvoyée (pliée car longue)
{
  "result": [
    {
      "chunk_info": {
        "id": 0,
        "head": 7,
        "dep": "D",
        "chunk_head": 1,
        "chunk_func": 2,
        "links": []
      },
      "tokens": [
        {
          "id": 0,
          "form": "portes",
          "kana": "portes",
          "lemma": "portes",
          "pos": "nom",
          "features": [
            "Unique",
            "Nom de famille"
          ],
          "attributes": {}
        },
        {
          "id": 1,
          "form": "m",
          "kana": "Shi",
          "lemma": "m",
          "pos": "Suffixe de nomenclature",
          "features": [
            "nom"
          ],
          "dependency_labels": [
            {
              "token_id": 0,
              "label": "name"
            },
            {
              "token_id": 2,
              "label": "case"
            }
          ],
          "attributes": {}
        },
        {
          "id": 2,
          "form": "Est",
          "kana": "C",
          "lemma": "Est",
          "pos": "Mots auxiliaires consécutifs",
          "features": [],
          "attributes": {}
        }
      ]
    },
    {
      "chunk_info": {
        "id": 1,
        "head": 4,
        "dep": "D",
        "chunk_head": 0,
        "chunk_func": 1,
        "links": []
      },
      "tokens": [
        {
          "id": 3,
          "form": "2008",
          "kana": "Nisen Hachinen",
          "lemma": "2008",
          "pos": "nom",
          "features": [
            "Date et l'heure"
          ],
          "dependency_labels": [
            {
              "token_id": 4,
              "label": "case"
            }
          ],
          "attributes": {}
        },
        {
          "id": 4,
          "form": "À",
          "kana": "ré",
          "lemma": "À",
          "pos": "Assistant de cas",
          "features": [
            "Utilisation continue"
          ],
          "attributes": {}
        }
      ]
    },
    {
      "chunk_info": {
        "id": 2,
        "head": 3,
        "dep": "D",
        "chunk_head": 0,
        "chunk_func": 1,
        "links": []
      },
      "tokens": [
        {
          "id": 5,
          "form": "la gestion",
          "kana": "Keiei",
          "lemma": "la gestion",
          "pos": "nom",
          "features": [
            "mouvement"
          ],
          "dependency_labels": [
            {
              "token_id": 6,
              "label": "case"
            }
          ],
          "attributes": {}
        },
        {
          "id": 6,
          "form": "de",
          "kana": "Non",
          "lemma": "de",
          "pos": "Assistant de cas",
          "features": [
            "syndicat"
          ],
          "attributes": {}
        }
      ]
    },
    {
      "chunk_info": {
        "id": 3,
        "head": 4,
        "dep": "D",
        "chunk_head": 0,
        "chunk_func": 1,
        "links": [
          {
            "link": 2,
            "label": "adjectivals"
          }
        ]
      },
      "tokens": [
        {
          "id": 7,
          "form": "Ligne",
          "kana": "Issen",
          "lemma": "Ligne",
          "pos": "nom",
          "features": [],
          "dependency_labels": [
            {
              "token_id": 5,
              "label": "nmod"
            },
            {
              "token_id": 8,
              "label": "case"
            }
          ],
          "attributes": {}
        },
        {
          "id": 8,
          "form": "De",
          "kana": "Kara",
          "lemma": "De",
          "pos": "Assistant de cas",
          "features": [
            "Utilisation continue"
          ],
          "attributes": {}
        }
      ]
    },
    {
      "chunk_info": {
        "id": 4,
        "head": 7,
        "dep": "P",
        "chunk_head": 0,
        "chunk_func": 1,
        "links": [
          {
            "link": 1,
            "label": "goal"
          },
          {
            "link": 3,
            "label": "object"
          }
        ],
        "predicate": []
      },
      "tokens": [
        {
          "id": 9,
          "form": "Se retirer",
          "kana": "Sirizo",
          "lemma": "Battre en retraite",
          "pos": "Tronc de verbe",
          "features": [
            "K"
          ],
          "dependency_labels": [
            {
              "token_id": 3,
              "label": "nmod"
            },
            {
              "token_id": 7,
              "label": "dobj"
            },
            {
              "token_id": 10,
              "label": "aux"
            },
            {
              "token_id": 11,
              "label": "punct"
            }
          ],
          "attributes": {}
        },
        {
          "id": 10,
          "form": "Ki",
          "kana": "Ki",
          "lemma": "Ki",
          "pos": "Suffixe de verbe",
          "features": [
            "Utilisation continue"
          ],
          "attributes": {}
        },
        {
          "id": 11,
          "form": "、",
          "kana": "",
          "lemma": "、",
          "pos": "Point de lecture",
          "features": [],
          "attributes": {}
        }
      ]
    },
    {
      "chunk_info": {
        "id": 5,
        "head": 7,
        "dep": "D",
        "chunk_head": 0,
        "chunk_func": 1,
        "links": []
      },
      "tokens": [
        {
          "id": 12,
          "form": "14 ans",
          "kana": "Juyonen",
          "lemma": "14 ans",
          "pos": "nom",
          "features": [
            "Date et l'heure"
          ],
          "dependency_labels": [
            {
              "token_id": 13,
              "label": "case"
            }
          ],
          "attributes": {}
        },
        {
          "id": 13,
          "form": "À",
          "kana": "Niha",
          "lemma": "À",
          "pos": "Mots auxiliaires consécutifs",
          "features": [],
          "attributes": {}
        }
      ]
    },
    {
      "chunk_info": {
        "id": 6,
        "head": 7,
        "dep": "D",
        "chunk_head": 0,
        "chunk_func": 1,
        "links": []
      },
      "tokens": [
        {
          "id": 14,
          "form": "Président",
          "kana": "Kaicho",
          "lemma": "Président",
          "pos": "nom",
          "features": [],
          "dependency_labels": [
            {
              "token_id": 15,
              "label": "case"
            }
          ],
          "attributes": {}
        },
        {
          "id": 15,
          "form": "À",
          "kana": "Wo",
          "lemma": "À",
          "pos": "Assistant de cas",
          "features": [
            "Utilisation continue"
          ],
          "attributes": {}
        }
      ]
    },
    {
      "chunk_info": {
        "id": 7,
        "head": 9,
        "dep": "D",
        "chunk_head": 0,
        "chunk_func": 3,
        "links": [
          {
            "link": 0,
            "label": "agent"
          },
          {
            "link": 4,
            "label": "manner"
          },
          {
            "link": 5,
            "label": "time"
          },
          {
            "link": 6,
            "label": "agent"
          }
        ],
        "predicate": [
          "past"
        ]
      },
      "tokens": [
        {
          "id": 16,
          "form": "Retraité",
          "kana": "Étain",
          "lemma": "Retraité",
          "pos": "nom",
          "features": [
            "mouvement"
          ],
          "dependency_labels": [
            {
              "token_id": 1,
              "label": "nsubj"
            },
            {
              "token_id": 9,
              "label": "advcl"
            },
            {
              "token_id": 12,
              "label": "nmod"
            },
            {
              "token_id": 14,
              "label": "nsubj"
            },
            {
              "token_id": 17,
              "label": "aux"
            },
            {
              "token_id": 18,
              "label": "aux"
            },
            {
              "token_id": 19,
              "label": "mark"
            },
            {
              "token_id": 20,
              "label": "punct"
            }
          ],
          "attributes": {}
        },
        {
          "id": 17,
          "form": "Shi",
          "kana": "Shi",
          "lemma": "Shi",
          "pos": "Fin d'utilisation verbale",
          "features": [],
          "attributes": {}
        },
        {
          "id": 18,
          "form": "Ta",
          "kana": "Ta",
          "lemma": "Ta",
          "pos": "Suffixe de verbe",
          "features": [
            "Relier"
          ],
          "attributes": {}
        },
        {
          "id": 19,
          "form": "Mais",
          "kana": "Géorgie",
          "lemma": "Mais",
          "pos": "Suffixe de connexion",
          "features": [
            "Utilisation continue"
          ],
          "attributes": {}
        },
        {
          "id": 20,
          "form": "、",
          "kana": "",
          "lemma": "、",
          "pos": "Point de lecture",
          "features": [],
          "attributes": {}
        }
      ]
    },
    {
      "chunk_info": {
        "id": 8,
        "head": 9,
        "dep": "D",
        "chunk_head": 0,
        "chunk_func": 1,
        "links": []
      },
      "tokens": [
        {
          "id": 21,
          "form": "Conseil d'administration",
          "kana": "Trishimaryakukai",
          "lemma": "Conseil d'administration",
          "pos": "nom",
          "features": [],
          "dependency_labels": [
            {
              "token_id": 22,
              "label": "case"
            }
          ],
          "attributes": {}
        },
        {
          "id": 22,
          "form": "À",
          "kana": "Niha",
          "lemma": "À",
          "pos": "Mots auxiliaires consécutifs",
          "features": [],
          "attributes": {}
        }
      ]
    },
    {
      "chunk_info": {
        "id": 9,
        "head": -1,
        "dep": "O",
        "chunk_head": 0,
        "chunk_func": 4,
        "links": [
          {
            "link": 7,
            "label": "manner"
          },
          {
            "link": 8,
            "label": "place"
          }
        ],
        "predicate": [
          "past",
          "past"
        ]
      },
      "tokens": [
        {
          "id": 23,
          "form": "Restant",
          "kana": "Noko",
          "lemma": "Rester",
          "pos": "Tronc de verbe",
          "features": [
            "R"
          ],
          "dependency_labels": [
            {
              "token_id": 16,
              "label": "advcl"
            },
            {
              "token_id": 21,
              "label": "nmod"
            },
            {
              "token_id": 24,
              "label": "aux"
            },
            {
              "token_id": 25,
              "label": "aux"
            },
            {
              "token_id": 26,
              "label": "aux"
            },
            {
              "token_id": 27,
              "label": "aux"
            },
            {
              "token_id": 28,
              "label": "punct"
            }
          ],
          "attributes": {}
        },
        {
          "id": 24,
          "form": "Tsu",
          "kana": "Tsu",
          "lemma": "Tsu",
          "pos": "Fin d'utilisation verbale",
          "features": [],
          "attributes": {}
        },
        {
          "id": 25,
          "form": "main",
          "kana": "Te",
          "lemma": "main",
          "pos": "Suffixe de verbe",
          "features": [
            "Relier",
            "Utilisation continue"
          ],
          "attributes": {}
        },
        {
          "id": 26,
          "form": "je",
          "kana": "je",
          "lemma": "Est",
          "pos": "Tronc de verbe",
          "features": [
            "A",
            "L pour une utilisation continue"
          ],
          "attributes": {}
        },
        {
          "id": 27,
          "form": "Ta",
          "kana": "Ta",
          "lemma": "Ta",
          "pos": "Suffixe de verbe",
          "features": [
            "Arrêtez"
          ],
          "attributes": {}
        },
        {
          "id": 28,
          "form": "。",
          "kana": "",
          "lemma": "。",
          "pos": "Phrase",
          "features": [],
          "attributes": {}
        }
      ]
    }
  ],
  "status": 0,
  "message": ""
}
['Président', 'De la ligne', 'Retraité', 'Au tableau']

Étape 5: Générez un titre!

Combinons chaque mot-clé avec le mot auxiliaire pour créer une phrase de 13 caractères ou moins. Je l'ai presque obtenu à l'étape 4, mais j'ai obtenu ce résultat.

Retiré de la ligne

Je ne pense pas que ce soit un titre intrigant **, "Qui a pris sa retraite?", Mais ce sont des informations erronées parce que j'ai quitté le directeur au lieu du président. Je vais te dire.

Cependant, comme je l'ai écrit à l'étape 2, il n'y a aucune information indiquant "qui" ou des noms de sociétés tels que "Microsoft" et "MS", donc cela semble subtile, il est donc objectif de voir à quel point l'en-tête généré cette fois est bon **. J'ai décidé de le chercher **.

Étape 6: vérifier l'exhaustivité de l'en-tête généré à l'aide de l'API de calcul de similarité

Vous pouvez également vérifier l'exhaustivité des en-têtes générés à l'aide de l'API COTOHA. ** API de calcul de similarité **. En utilisant cette API, vous pouvez ** calculer la similitude sémantique entre deux phrases **. La similitude est sortie dans la plage de définition de 0 à 1, et plus elle est proche de 1, plus la similitude entre les textes est grande.

Le titre «Bill Gates a pris sa retraite en tant que directeur de la SP» joint à l'article J'ai essayé de calculer la similitude de l'en-tête généré "Le président s'est retiré de la ligne".

{
  "result": {
    "score": 0.9716939
  },
  "status": 0,
  "message": "OK"
}

Oh, 0,97 n'est pas assez cher ...! ?? (Perplexe Si COTOHA le dit. ..

prime

Pour référence, j'ai également essayé d'autres articles.

Révolution au dépanneur "Lentin"

L'article fait 4 pages au total, mais pour le moment, je ne l'ai essayé que sur la 1ère page. https://news.yahoo.co.jp/pickup/6353834

● Une phrase extraite
Maintenant, il attire l'attention en tant que produit qui symbolise la révolution du menton dans la gamme qui progresse dans l'industrie du dépanneur.
● Mots clés extraits
['symbole', 'attention', 'gamme', 'industrie du confort', 'révolution du menton']

** ● Titre généré **

Dans le domaine de l'attention symbolique(Similitude: 0.45899978)

Même si vous regardez le titre, c'est un gâchis ... La similitude est également très faible. Après tout, les mots-clés extraits sont ** attachés par ordre décroissant de score pour faire une phrase **, donc Je pense que ça ressemble à ça. Vous savez peut-être pour la première fois que Chin est abrégé en ** Lentin ** dans la gamme. Ou plutôt, qu'est-ce que la révolution Chin?

Le jeu dure 60 minutes par jour à 80% en faveur du plan

Il s'agit d'un article sur la réglementation du jeu dans la préfecture de Kagawa, qui est controversé. https://news.yahoo.co.jp/pickup/6353894

● Une phrase extraite
Une ordonnance relative à la "dépendance au jeu" que l'Assemblée préfectorale de Kagawa entend faire appliquer en avril.
● Mots clés extraits
['Ordonnance sur les contre-mesures', 'Assemblée préfectorale de Kagawa', 'Mise en application', 'Dépendance au jeu']

** ● Titre généré **

Ordonnance sur les mesures d'application de l'Assemblée préfectorale de Kagawa(Similitude: 0.2842004)

Si vous regardez le titre, il est difficile de dire à partir de l'exemple de jeu dans la préfecture de Kagawa, mais ce que je veux transmettre dans cet article est probablement ** 80% des supporters **. Le degré de similitude est également très faible. Cependant, la phrase extraite et l'en-tête généré ne contenaient pas d'informations numériques. En outre, bien que l'article contienne une valeur spécifique de 84%, il est converti en une expression facile à comprendre de 80% dans l'en-tête. Il est plus facile de se faire une idée si vous le dites grossièrement que si vous le dites en détail. Ce domaine est-il une compétence unique aux humains?

Chutes de neige à Tokyo

L'article d'hier. Il semble qu'il ait neigé à Tokyo. Il fait encore froid ... https://news.yahoo.co.jp/pickup/6354091

● Une phrase extraite
Dans le centre de Tokyo, qui est plus de 10 ℃ de moins que midi d'hier, après avoir observé la température maximale de 12,3 ℃ après minuit le 14, la température a baissé régulièrement et est maintenant de 2,5 ℃ à 14h00.
● Mots clés extraits
['Observation', 'Température', '12 .3 ° c ',' 2.5 ° c ', '10 ° c et plus']
● Informations de localisation extraites
['Shin Tokyo']

** ● Titre généré **

Température observée dans le centre de Tokyo(Similitude: 0.99335754)

Bien qu'il s'agisse d'un boîtier contenant des informations de localisation, il consomme jusqu'à 4 caractères dans le centre de Tokyo et la quantité d'informations créées n'est pas très importante. J'ai l'impression que les mots-clés extraits contiennent également trop d'informations numériques. Cependant, la similitude est extrêmement élevée à 0,99 ...

Résumé

Cela peut sembler un peu subtil si le titre généré cette fois est considéré comme un grand succès, mais c'était amusant de le faire. En premier lieu, lorsque j'ai examiné le résumé, il semble qu'il existe à peu près les classifications suivantes.

L'API de synthèse fournie par COTOHA utilisée cette fois est l'ancien ** type d'extraction **.

Cependant, comme nous le faisons dans Yahoo! News, lorsque vous essayez de créer un résumé selon diverses règles et restrictions, il est difficile de créer un résumé uniquement avec le type d'extraction, donc ** combiner avec d'autres services ** ou ce dernier ** type abstrait J'ai senti qu'il serait nécessaire d'utiliser le service de synthèse **.

De plus, afin de réduire le nombre de caractères, il semble facile de l'omettre car il existe des règles pour les noms de pays, etc., mais dans la plage, le menton est abrégé en lentine et 84% est exprimé en 80% de manière facile à comprendre. Je pense que les obstacles sont toujours élevés même si j'utilise la technologie de traitement du langage naturel.

J'ai senti que le jour où la génération d'en-tête Yahoo! News (technique habile) serait remplacée par l'IA ne viendrait pas pour le moment.

à la fin

Personnellement, j'aime le traitement du langage naturel car il est intéressant. Cependant, je n'ai pas beaucoup d'occasions de l'utiliser au travail, alors j'aimerais continuer à en profiter en privé. S'il vous plaît PS4.

Site de référence

L'article suivant de Qiita est très utile pour le résumé.

[Référence] Code source

Il peut y avoir beaucoup de divagations, mais si vous êtes intéressé, jetez-y un œil
import requests
import pprint
import json
import re
from bs4 import BeautifulSoup

base_url = 'https://api.ce-cotoha.com/api/dev/nlp/'


'''
Obtenez un jeton d'accès pour l'API COTOHA
'''
def get_access_token():
    url = 'https://api.ce-cotoha.com/v1/oauth/accesstokens'

    req_data = {
      'grantType' : 'client_credentials',
      'clientId' : 'identité du client',
      'clientSecret' : 'Secret du client'
    }

    headers = {
        'Content-Type' : 'application/json'
    }

    response = requests.post(url, json.dumps(req_data), headers=headers)
    token = response.json()['access_token']
    
    return token


'''
Appelez l'API de résumé
'''
def get_summary(token, document) :
    url = base_url + '/beta/summary'

    req_data = {
        'document' : document,
        'sent_len' : '1'
    }

    headers = {
        'Content-Type' : 'application/json;charset=UTF-8',
        'Authorization' : 'Bearer {}'.format(token)
    }

    response = requests.post(url, json.dumps(req_data), headers=headers)
    summary = response.json()['result']
    
    return summary


'''
Appelez l'API d'extraction de mots clés
'''
def get_keywords(token, document):
    url = base_url + '/v1/keyword'

    req_data = {
        'document' : document,
        'type' : 'default',
        'do_segment' : True
    }

    headers = {
        'Content-Type' : 'application/json;charset=UTF-8',
        'Authorization' : 'Bearer {}'.format(token)
    }

    response = requests.post(url, json.dumps(req_data), headers=headers)
    keywords = [item.get('form') for item in response.json()['result']]
    
    return keywords


'''
Appelez l'API d'extraction d'expression unique pour obtenir des informations sur l'emplacement
'''
def get_ne_loc(token,sentence):
    url = base_url + '/v1/ne'

    req_data = {
        'sentence' : sentence
    }

    headers = {
        'Content-Type' : 'application/json;charset=UTF-8',
        'Authorization' : 'Bearer {}'.format(token)
    }
    
    response = requests.post(url, json.dumps(req_data), headers=headers)
    ne = response.json()['result']
    
    ne_loc = []
    for item in ne:
        if item['class'] == 'LOC':
            ne_loc.append(item['form'])
    
    #Il y a des cas où la duplication se produit si seuls des mots sont utilisés
    if ne_loc:
        ne_loc = list(set(ne_loc))
        
    return ne_loc

    
'''
Appelez l'API d'analyse syntaxique
'''
def parse_doc(token, sentence) :
    url = base_url + '/v1/parse'

    req_data = {
        'sentence':sentence
    }

    headers = {
        'Content-Type' : 'application/json;charset=UTF-8',
        'Authorization' : 'Bearer {}'.format(token)
    }
    
    response = requests.post(url, json.dumps(req_data), headers=headers)
    parsed_result = response.json()['result']
    
    tokens = []
    for tokens_ary in parsed_result:
        for token in tokens_ary['tokens']:
            if token:
                tokens.append(token)
        
    return tokens


'''
Appelez l'API de calcul de similarité
'''
def get_similarity(token, doc1, doc2):
    url = base_url + '/v1/similarity'

    req_data = {
        's1' : doc1,
        's2' : doc2,
        'type' : 'kuzure'
    }

    headers = {
        'Content-Type' : 'application/json;charset=UTF-8',
        'Authorization' : 'Bearer {}'.format(token)
    }
    
    response = requests.post(url, json.dumps(req_data), headers=headers)
    similarity = response.json()['result']
        
    return similarity       


'''
Yahoo!Extraire le contenu de l'URL de l'article d'actualité
(Prend en charge une seule page, ne prend pas en charge plusieurs pages ou des formats d'article spécifiques...)
'''
def get_contents(url):
    top_page = requests.get(url) 
    soup = BeautifulSoup(top_page.text, 'lxml')
    article_url = soup.find('div',class_=re.compile('pickupMain_articleInfo')).find('a').get('href')
    article_page = requests.get(article_url) 
    soup = BeautifulSoup(article_page.text, "lxml")
    for tag in soup.find_all('p',{'class':'photoOffer'}):
        tag.decompose()
    for tag in soup.find_all('a'):
        tag.decompose()
    contents =  re.sub('\n|\u3000','',soup.find('div',class_=re.compile('articleMain')).getText());
    
    return contents


'''
Yahoo!Extraire le titre de l'URL de l'article d'actualité
(C'est la bonne réponse)
'''
def get_title(url):
    top_page = requests.get(url) 
    soup = BeautifulSoup(top_page.text, "lxml")
    title = soup.find("title").getText().split(' - ')[0]
    
    return title


'''
Yahoo!Générer des sujets pour les articles de presse
'''
def create_news_topic(token, contents):
    #Résumé de l'article implémenté
    summary = get_summary(token, contents)
    print(summary)
    print("------------")
    
    #Si le résumé comporte 13 caractères ou moins, renvoyez-le en tant que sujet
    if len(summary) <= 13:
        return summary[:-1]

    #Extraire les mots-clés et les noms de lieux du résumé
    keywords = get_keywords(token, summary)
    print(keywords)
    print("------------")
    ne_loc = get_ne_loc(token, summary)
    print(ne_loc)
    print("------------") 

    topic = ''
    #Ajouter à l'en-tête s'il y a des informations de localisation
    #Même s'il y en a plusieurs, seul le premier pour le moment
    if ne_loc:
        topic += ne_loc[0] + 'alors'
        #Supprimer s'il est également inclus dans le mot clé
        if ne_loc[0] in keywords:
            keywords.remove(ne_loc[0])

    #Analyse syntaxiquement du résumé
    tokens = parse_doc(token, summary)

    #Créez un résumé tout en obtenant les assistants de mots clés
    for keyword in keywords:
        for token in tokens:
            if token['form'] == keyword:
                print(token)
                for dependency_label in token['dependency_labels']:
                    if dependency_label['label'] == 'case':
                        keyword += tokens[int(dependency_label['token_id'])]['form']
                        break
                break
    
        if len(topic) + len(keyword) <= 13:
            topic += keyword
        else:
            return topic

    return topic


'''
Principale
'''
if __name__ == '__main__':
    #Yahoo vous souhaitez générer des titres!URL de l'article d'actualité
    url = 'https://news.yahoo.co.jp/pickup/6354056'   

    #Extraire le contenu et le titre de l'article
    contents = get_contents(url)
    title = get_title(url)
    print("------------")
    print(contents)
    print("------------")
    print(title)
    print("------------")    
    
    #Obtenez un jeton pour l'API COTOHA
    token = get_access_token()
    
    #Générer des en-têtes d'article
    topic = create_news_topic(token, contents)
    print(topic)
    print("------------") 
    
    #Calculer la similitude entre le cap d'origine et le cap généré
    similarity = get_similarity(token, title, topic)['score']
    print(similarity)
    print("------------") 

Recommended Posts

Défi pour générer des en-têtes Yahoo! News en utilisant uniquement l'API COTOHA
Publication groupée sur Qiita: équipe utilisant l'API Qiita
Générer des spécifications d'API à l'aide de GO / Gingin-swagger
J'ai essayé de toucher l'API COTOHA
Jouez avec Dajare en utilisant l'API COTOHA
Laissez l'API COTOHA faire les choses difficiles - Introduction à "apprendre en utilisant" le traitement du langage naturel -