[PYTHON] Traitement du langage 100 knocks-44: Visualisation des arbres dépendants

Traitement du langage 100 coups 2015 ["Chapitre 5: Analyse des dépendances"](http: //www.cl.ecei. Il s'agit d'un enregistrement de la 44ème "Visualisation de l'arbre dépendant" de tohoku.ac.jp/nlp100/#ch5). La visualisation permet de comprendre très facilement comment le document est dépendant. Si vous visualisez la dépendance, vous pouvez faire quelque chose de bien comme dans l'article "J'ai essayé d'analyser linguistiquement les phrases incompréhensibles de Karen Takizawa.".

Lien de référence

Lien Remarques
044.Visualisation des arbres dépendants.ipynb Lien GitHub du programme de réponse
100 coups de traitement du langage amateur:44 Copiez et collez la source de nombreuses pièces source
Officiel de CaboCha Page CaboCha à regarder en premier

environnement

J'ai installé CRF ++ et CaboCha il y a trop longtemps et j'ai oublié comment les installer. Puisqu'il s'agit d'un package qui n'a pas du tout été mis à jour, nous n'avons pas reconstruit l'environnement. Je me souviens seulement d'avoir été frustré lorsque j'ai décidé d'utiliser CaboCha sous Windows. Je pense que je ne pourrais pas l'utiliser sur Windows 64 bits (j'ai une mémoire vague et peut-être qu'il y a un problème avec ma capacité technique).

type version Contenu
OS Ubuntu18.04.01 LTS Il fonctionne virtuellement
pyenv 1.2.16 J'utilise pyenv car j'utilise parfois plusieurs environnements Python
Python 3.8.1 python3 sur pyenv.8.J'utilise 1
Les packages sont gérés à l'aide de venv
Mecab 0.996-5 apt-Installer avec get
CRF++ 0.58 C'est trop vieux et j'ai oublié comment l'installer(Peut-êtremake install)
CaboCha 0.69 C'est trop vieux et j'ai oublié comment l'installer(Peut-êtremake install)

Dans l'environnement ci-dessus, j'utilise les packages Python supplémentaires suivants. Installez simplement avec pip ordinaire.

type version
pydot 1.4.1

Chapitre 5: Analyse des dépendances

contenu de l'étude

Appliquer l'analyseur de dépendances CaboCha à "Je suis un chat" et expérimenter le fonctionnement de l'arbre de dépendances et l'analyse syntaxique.

Classe, Analyse des dépendances, CaboCha, Clause, Dépendance, Cas, Syntaxe des verbes fonctionnels, Chemin des dépendances, [Graphviz](http: / /www.graphviz.org/)

Contenu frappé

Utilisation de CaboCha pour le texte du roman de Soseki Natsume "Je suis un chat" (neko.txt) Analysez la dépendance et enregistrez le résultat dans un fichier appelé neko.txt.cabocha. Utilisez ce fichier pour implémenter un programme qui répond aux questions suivantes.

44. Visualisation de l'arbre dépendant

Visualisez l'arbre de dépendance d'une phrase donnée sous forme de graphe orienté. Pour la visualisation, convertissez l'arborescence des dépendances en langage DOT et [Graphviz](http: / /www.graphviz.org/) doit être utilisé. De plus, pour visualiser des graphiques dirigés directement à partir de Python, utilisez pydot.

Supplément au problème (à propos de la «visualisation et du graphe orienté»)

Visualisation

Il semble qu'il existe deux types de visualisation. J'ignore la première méthode. Je n'ai pas vérifié si la première méthode est facile. Cela n'a pas d'importance parce que je ne l'ai pas utilisé dans "Traitement du langage amateur 100 coups: 44" auquel je fais toujours référence dans mes coups.

Pour la visualisation, convertissez l'arborescence des dépendances en langage DOT et [Graphviz](http: //www.graphviz.org/) doit être utilisé.

Cette fois, j'ai utilisé la méthode suivante. Avec cela, tout ce que vous avez à faire est d'installer pydot avec pip et de le transmettre à la fonction en Python.

De plus, pour visualiser des graphiques dirigés directement depuis Python, utilisez pydot.

Graphique dirigé

Tout d'abord, [** Théorie des graphes **](https://ja.wikipedia.org/wiki/%E3%82%B0%E3%83%A9%E3%83%95%E7%90%86%E8% Il y a quelque chose qui s'appelle AB% 96)

La théorie des graphes (théorie des graphes) est une théorie mathématique des graphes constituée d'un ensemble de nœuds (nœuds / sommets) et d'un ensemble d'arêtes (branches / côtés).

[Définition du graphe orienté et du graphe invalide comme ci-dessous](https://ja.wikipedia.org/wiki/%E3%82%B0%E3%83%A9%E3%83%95%E7%90%86% E8% AB% 96 #% E6% A6% 82% E8% A6% 81) est à peu près (le "graphe orienté" a une direction). Veuillez suivre le lien pour plus de détails.

Si vous voulez considérer non seulement comment vous connecter, mais aussi «à partir de laquelle», ajoutez une flèche au bord. Un tel graphe est appelé graphe orienté ou digraphe. Un graphique sans flèche est appelé un graphique non orienté.

Répondre

Programme de réponse [044. Visualisation de l'arbre dépendant.ipynb](https://github.com/YoheiFukuhara/nlp100/blob/master/05.%E4%BF%82%E3%82%8A%E5%8F%97 % E3% 81% 91% E8% A7% A3% E6% 9E% 90 / 044.% E4% BF% 82% E3% 82% 8A% E5% 8F% 97% E3% 81% 91% E6% 9C% A8% E3% 81% AE% E5% 8F% AF% E8% A6% 96% E5% 8C% 96.ipynb)

import re
from subprocess import run, PIPE

import pydot

#Délimiteur
separator = re.compile('\t|,')

#Dépendance
dependancy = re.compile(r'''(?:\*\s\d+\s) #Non soumis à la capture
                            (-?\d+)       #Nombres(Contact)
                          ''', re.VERBOSE)

text = input('Veuillez saisir du texte')

#valeur initiale
if len(text) == 0:
    text = 'Je ne me souviens pas si je l'ai dit ou non, mais je pense que je l'ai probablement dit lors d'une fête à la main l'autre jour. Je l'ai essayé, mais j'en suis venu à penser que peu importe que je le dise ou non.'

cmd = 'echo {} | cabocha -f1'.format(text)
proc = run(cmd, shell=True, stdout=PIPE, stderr=PIPE)
print(proc.stdout.decode('UTF-8'))

class Chunk:
    def __init__(self, phrase, dst):
        self.phrase = phrase
        self.dst = dst  #Numéro d'index de la clause de contact

phrase = ''
chunks = []
for line in proc.stdout.decode('UTF-8').splitlines():
    dependancies = dependancy.match(line)
    
    #S'il ne s'agit pas d'EOS ou du résultat de l'analyse des dépendances(Notez qu'EOS n'a pas de sauts de ligne)
    if not (line == 'EOS' or dependancies):
        #Diviser par tabulation et virgule
        cols = separator.split(line)
        phrase += cols[0] #Type de surface(surface)

    #Lorsqu'il y a une analyse morphologique, le résultat de l'analyse EOS ou des dépendances
    elif phrase != '':
        chunks.append(Chunk(phrase, dst))
        phrase = ''

    #En cas de dépendance résultat
    if dependancies:
        dst = int(dependancies.group(1))

#Changé en un format qui transmet quelque chose avec un contact à pydot
edges = []
for i, chunk in enumerate(chunks):
    if chunk.dst != -1 and \
       chunk.phrase != '' and \
       chunks[chunk.dst].phrase != '':
        edges.append(((i, chunk.phrase), (chunk.dst, chunks[chunk.dst].phrase)))

#Enregistrer l'image en tant que graphique dirigé avec pydot
if len(edges) > 0:
    graph = pydot.graph_from_edges(edges, directed=True)
    graph.write_png('044.dot.png')

Répondre au commentaire

Saisie de texte

La partie "phrase donnée" du coup est donnée par la fonction ʻinput` (est-elle conforme à l'intention de la question?). Si rien n'est entré, la valeur initiale sera utilisée.

python


text = input('Veuillez saisir du texte')

#valeur initiale
if len(text) == 0:
    text = 'Je ne me souviens pas si je l'ai dit ou non, mais je pense que je l'ai probablement dit lors d'une fête à la main l'autre jour. Je l'ai essayé, mais j'en suis venu à penser que peu importe que je le dise ou non.'

Partie d'exécution CaboCha

La partie exécution CaboCha utilise la fonction run du package subprocess pour exécuter le shell. Je n'ai pas utilisé le wrapper Python de CaboCha parce que c'était purement ennuyeux.

python


cmd = 'echo {} | cabocha -f1'.format(text)
proc = run(cmd, shell=True, stdout=PIPE, stderr=PIPE)
print(proc.stdout.decode('UTF-8'))

La première partie du contenu produit par la fonction print est la suivante.

Partie du résultat d'impression


* 0 1D 0/4 0.285960
Dire le verbe,Indépendance,*,*,Rappel de ligne Godan / Wa,Connexion continue,Dire,Il,Il
Te assistant,Assistant de connexion,*,*,*,*,main,Te,Te
Ah verbe,Non indépendant,*,*,Cinq étapes, La ligne,Connexion continue,y a-t-il,Ah,Ah
Verbe auxiliaire,*,*,*,Spécial,Forme basique,Ta,Ta,Ta
Assistant Ka,Sous-auxiliaire / assistant parallèle / assistant final,*,*,*,*,Ou,Puissance,Puissance
* 1 4D 0/4 2.230543
Dire le verbe,Indépendance,*,*,Rappel de ligne Godan / Wa,Connexion continue,Dire,Il,Il
Verbe te,Non indépendant,*,*,Un pas,Forme imparfaite,Teru,Te,Te
Pas de verbe auxiliaire,*,*,*,Spécial Nai,Connexion continue,Absent,Naka,Naka
Verbe auxiliaire,*,*,*,Spécial,Forme basique,Ta,Ta,Ta
Assistant Ka,Sous-auxiliaire / assistant parallèle / assistant final,*,*,*,*,Ou,Puissance,Puissance
* 2 4D 0/3 2.418727
Quel nez,Synonyme,Général,*,*,*,Lequel,Dotch,Dotch
Verbe auxiliaire,*,*,*,Spécial,Connexion continue,Est,Papa,Papa
Verbe auxiliaire,*,*,*,Spécial,Forme basique,Ta,Ta,Ta
Assistant Ka,Sous-auxiliaire / assistant parallèle / assistant final,*,*,*,*,Ou,Puissance,Puissance

python


#Changé en un format qui transmet quelque chose avec un contact à pydot
edges = []
for i, chunk in enumerate(chunks):
    if chunk.dst != -1 and \
       chunk.phrase != '' and \
       chunks[chunk.dst].phrase != '':
        edges.append(((i, chunk.phrase), (chunk.dst, chunks[chunk.dst].phrase)))

Au fait, «edges» a un tel contenu.

((0, 'Avez vous dit'), (1, 'N'as-tu pas dit'))
((1, 'N'as-tu pas dit'), (4, 'Je ne me souviens pas'))
((2, 'Ce qui était'), (4, 'Je ne me souviens pas'))
((3, 'Correctement'), (4, 'Je ne me souviens pas'))
((4, 'Je ne me souviens pas'), (19, 'J'y ai pensé,'))
((5, 'Certainement'), (7, 'Hourra'))
((6, 'Une fête à remontage manuel pendant cette période'), (7, 'Hourra'))
((7, 'Hourra'), (8, 'quelquefois'))
((8, 'quelquefois'), (10, 'M'a dit'))
((9, 'Un petit peu'), (10, 'M'a dit'))
((10, 'M'a dit'), (11, 'Sentiment'))
((11, 'Sentiment'), (12, 'Sans pour autant'))
((12, 'Sans pour autant'), (14, 'Nishimo'))
((13, 'Sans pour autant'), (14, 'Nishimo'))
((14, 'Nishimo'), (15, 'Sans pour autant'))
((15, 'Sans pour autant'), (17, 'Je crois que j'ai dit'))
((16, 'Peut-être'), (17, 'Je crois que j'ai dit'))
((17, 'Je crois que j'ai dit'), (19, 'J'y ai pensé,'))
((18, 'Jusqu'ici'), (19, 'J'y ai pensé,'))
((19, 'J'y ai pensé,'), (28, 'Ça dépend.'))
((20, 'Oh cher'), (21, 'je te le dirai'))
((21, 'je te le dirai'), (28, 'Ça dépend.'))
((22, 'Dire'), (23, 'Je m'en fous'))
((23, 'Je m'en fiche'), (25, 'Il n'y a pas de problème,'))
((24, 'Jusqu'à ce point'), (25, 'Il n'y a pas de problème,'))
((25, 'Il n'y a pas de problème,'), (26, 'je pense'))
((26, 'je pense'), (27, 'Atteint'))
((27, 'Atteint'), (28, 'Ça dépend.'))

Graphisme dirigé

Enfin, utilisez la fonction graph_from_edges pour créer un graphique valide et utilisez la fonction write_png pour enregistrer l'image. En définissant «dirigé = Vrai» au moment du graphique dirigé, la ligne entre les segments devient une flèche.

#Enregistrer l'image en tant que graphique dirigé avec pydot
if len(edges) > 0:
    graph = pydot.graph_from_edges(edges, directed=True)
    graph.write_png('044.dot.png')

Résultat de sortie (résultat de l'exécution)

Lorsque le programme est exécuté, les résultats suivants sont affichés.

image.png

Au fait, c'est l'histoire originale de ce document. Article "[Play] Analyse synthétique du mail de démonstration de Shinkalion". image.png

Recommended Posts

Traitement du langage 100 knocks-44: Visualisation des arbres dépendants
100 traitement du langage knock-59: analyse de la formule S
100 coups de traitement linguistique (2020): 28
100 coups de traitement linguistique (2020): 38
100 traitement de la langue frapper 00 ~ 02
100 traitement du langage knock-91: Préparation des données d'analogie
100 Language Processing Knock-26: suppression du balisage accentué
100 traitements linguistiques Knock 2020 [00 ~ 39 réponse]
100 langues de traitement knock 2020 [00-79 réponse]
100 traitements linguistiques Knock 2020 [00 ~ 69 réponse]
100 Language Processing Knock 2020 Chapitre 1
100 coups de traitement du langage amateur: 17
100 traitements linguistiques Knock 2020 [00 ~ 49 réponse]
100 Traitement du langage Knock-52: Stemming
100 Traitement du langage Knock Chapitre 1
100 coups de langue amateur: 07
100 Language Processing Knock 2020 Chapitre 3
100 Language Processing Knock 2020 Chapitre 2
100 coups de traitement du langage amateur: 09
100 coups en traitement du langage amateur: 47
Traitement 100 langues knock-53: Tokenisation
100 coups de traitement du langage amateur: 97
100 traitements linguistiques Knock 2020 [00 ~ 59 réponse]
100 coups de traitement du langage amateur: 67
100 Language Processing Knock-32 (utilisant des pandas): Prototype de verbe
Traitement du langage 100 knocks-45: Extraction de modèles de cas verbaux
100 traitement du langage knock-75 (en utilisant scicit-learn): poids de l'identité
100 traitement du langage knock-99 (à l'aide de pandas): visualisation par t-SNE
100 traitement du langage Knock-51: découpage de mots
100 Language Processing Knock-58: Extraction de Taple
100 Language Processing Knock-57: Analyse des dépendances
100 traitement linguistique knock-50: coupure de phrase
100 traitement du langage knock-36 (en utilisant des pandas): fréquence d'occurrence des mots
100 Language Processing Knock Chapitre 1 (Python)
100 Language Processing Knock Chapitre 2 (Python)
100 Language Processing Knock-25: Extraction de modèles
Traitement du langage 100 Knock-87: similitude des mots
Traitement du langage 100 knocks-49: Extraction de chemins de dépendances entre nomenclature
J'ai essayé 100 traitements linguistiques Knock 2020
100 Language Processing Knock-56: analyse de co-référence
Résolution de 100 traitements linguistiques Knock 2020 (01. "Patatokukashi")
Apprenez facilement 100 traitements linguistiques Knock 2020 avec "Google Colaboratory"
100 coups de traitement du langage amateur: Résumé
100 traitements linguistiques knock-77 (en utilisant scicit-learn): mesure du taux de réponse
100 traitement de la langue knock-42: Affichage de la phrase de la personne concernée et de la personne concernée
Traitement linguistique 100 knocks-29: Obtenez l'URL de l'image du drapeau
100 Language Processing Knock 2020 Chapitre 2: Commandes UNIX
100 Language Processing Knock 2015 Chapitre 5 Analyse des dépendances (40-49)
100 traitements de langage avec Python
100 Language Processing Knock Chapitre 1 en Python
100 Language Processing Knock 2020 Chapitre 4: Analyse morphologique
100 Language Processing Knock 2020 Chapitre 9: RNN, CNN
100 traitement du langage knock-76 (en utilisant scicit-learn): étiquetage
100 Language Processing Knock-55: extraction d'expressions uniques
J'ai essayé 100 traitements linguistiques Knock 2020: Chapitre 3
100 Language Processing Knock-82 (mot de contexte): Extraction de contexte
100 traitements de langage avec Python (chapitre 3)
100 Language Processing Knock: Chapitre 1 Mouvement préparatoire
100 Language Processing Knock 2020 Chapitre 6: Apprentissage automatique
100 Traitement du langage Knock Chapitre 4: Analyse morphologique
Traitement du langage 100 knock-86: affichage vectoriel Word