[PYTHON] Sprachverarbeitung 100 Knocks-44: Visualisierung abhängiger Bäume

Sprachverarbeitung 100 Schläge 2015 ["Kapitel 5: Abhängigkeitsanalyse"](http: //www.cl.ecei. Es ist eine Aufzeichnung von 44. "Visualisierung des abhängigen Baums" von tohoku.ac.jp/nlp100/#ch5). Durch die Visualisierung ist es sehr einfach zu verstehen, wie das Dokument abhängig ist. Wenn Sie sich die Abhängigkeit vorstellen, können Sie etwas Nettes tun, wie im Artikel "Ich habe versucht, die unverständlichen Sätze von Karen Takizawa sprachlich zu analysieren.".

Referenzlink

Verknüpfung Bemerkungen
044.Visualisierung abhängiger Bäume.ipynb Antwortprogramm GitHub Link
100 Klicks Amateur-Sprachverarbeitung:44 Kopieren Sie die Quelle vieler Quellteile und fügen Sie sie ein
CaboCha Beamter CaboCha Seite zuerst anzuschauen

Umgebung

Ich habe CRF ++ und CaboCha vor zu langer Zeit installiert und vergessen, wie man sie installiert. Da es sich um ein Paket handelt, das überhaupt nicht aktualisiert wurde, haben wir die Umgebung nicht neu erstellt. Ich erinnere mich nur, dass ich frustriert war, als ich mich für CaboCha unter Windows entschied. Ich glaube, ich konnte es unter 64-Bit-Windows nicht verwenden (ich habe einen vagen Speicher und möglicherweise liegt ein Problem mit meinen technischen Fähigkeiten vor).

Art Ausführung Inhalt
OS Ubuntu18.04.01 LTS Es läuft virtuell
pyenv 1.2.16 Ich benutze pyenv, weil ich manchmal mehrere Python-Umgebungen benutze
Python 3.8.1 python3 auf pyenv.8.Ich benutze 1
Pakete werden mit venv verwaltet
Mecab 0.996-5 apt-Installieren Sie mit get
CRF++ 0.58 Es ist zu alt und ich habe vergessen, wie man es installiert(Vielleichtmake install)
CaboCha 0.69 Es ist zu alt und ich habe vergessen, wie man es installiert(Vielleichtmake install)

In der obigen Umgebung verwende ich die folgenden zusätzlichen Python-Pakete. Einfach mit normalem Pip installieren.

Art Ausführung
pydot 1.4.1

Kapitel 5: Abhängigkeitsanalyse

Inhalt des Studiums

Wenden Sie den Abhängigkeitsanalysator CaboCha auf "Ich bin eine Katze" an und erleben Sie die Funktionsweise des Abhängigkeitsbaums und der syntaktischen Analyse.

Klasse, Abhängigkeitsanalyse, CaboCha, Klausel, Abhängigkeit, Groß- / Kleinschreibung, funktionale Verbsyntax, Abhängigkeitspfad, [Graphviz](http: / /www.graphviz.org/)

Klopfe an den Inhalt

Verwenden von CaboCha für den Text (neko.txt) von Natsume Sosekis Roman "Ich bin eine Katze" Analysieren Sie die Abhängigkeit und speichern Sie das Ergebnis in einer Datei namens neko.txt.cabocha. Verwenden Sie diese Datei, um ein Programm zu implementieren, das die folgenden Fragen beantwortet.

44. Visualisierung des abhängigen Baums

Visualisieren Sie den Abhängigkeitsbaum eines bestimmten Satzes als gerichteten Graphen. Konvertieren Sie zur Visualisierung den Abhängigkeitsbaum in DOT-Sprache und [Graphviz](http: / /www.graphviz.org/) sollte verwendet werden. Verwenden Sie pydot, um gerichtete Diagramme direkt aus Python zu visualisieren.

Problemergänzung (Über "Visualisierung und gerichtete Grafik")

Visualisierung

Es scheint, dass es zwei Arten der Visualisierung gibt. Ich ignoriere die erste Methode. Ich habe nicht überprüft, ob die erste Methode einfach ist. Es spielt keine Rolle, weil ich es nicht in "Amateur-Sprachverarbeitung 100 Schläge: 44" verwendet habe, auf das ich mich in meinen Schlägen immer beziehe.

Konvertieren Sie zur Visualisierung den Abhängigkeitsbaum in DOT-Sprache und [Graphviz](http: //www.graphviz.org/) sollte verwendet werden.

Dieses Mal habe ich die folgende Methode verwendet. Dazu müssen Sie nur pydot mit pip installieren und an die Funktion in Python übergeben.

Verwenden Sie pydot, um gerichtete Diagramme direkt aus Python zu visualisieren.

Gerichteter Graph

Zunächst [** Graphentheorie **](https://ja.wikipedia.org/wiki/%E3%82%B0%E3%83%A9%E3%83%95%E7%90%86%E8% Es gibt etwas namens AB% 96)

Graphentheorie (Graphentheorie) ist eine mathematische Theorie von Graphen, die aus einer Menge von Knoten (Knoten / Eckpunkten) und einer Menge von Kanten (Zweige / Seiten) besteht.

[Definition des gerichteten Graphen und des ungültigen Graphen wie unten](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) ist ungefähr (der "gerichtete Graph" hat eine Richtung). Bitte folgen Sie dem Link für Details.

Wenn Sie nicht nur überlegen möchten, wie eine Verbindung hergestellt werden soll, sondern auch, "von welcher zu welcher", fügen Sie der Kante einen Pfeil hinzu. Ein solcher Graph wird als gerichteter Graph oder Digraph bezeichnet. Ein Diagramm ohne Pfeil wird als ungerichtetes Diagramm bezeichnet.

Antworten

Antwortprogramm [044. Visualisierung des abhängigen tree.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

#Trennzeichen
separator = re.compile('\t|,')

#Abhängigkeit
dependancy = re.compile(r'''(?:\*\s\d+\s) #Nicht erfassbar
                            (-?\d+)       #Zahlen(Kontakt)
                          ''', re.VERBOSE)

text = input('Bitte geben Sie Text ein')

#Ursprünglicher Wert
if len(text) == 0:
    text = 'Ich erinnere mich nicht genau, ob ich es gesagt habe oder nicht, aber ich glaube, ich habe es wahrscheinlich gesagt, als ich neulich eine Handwundenparty hatte, ohne das Gefühl zu haben, dass ich es ein wenig gesagt habe. Ich habe es versucht, aber ich kam zu dem Schluss, dass es egal ist, ob ich es sage oder nicht.'

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  #Indexnummer der Kontaktklausel

phrase = ''
chunks = []
for line in proc.stdout.decode('UTF-8').splitlines():
    dependancies = dependancy.match(line)
    
    #Wenn es sich nicht um ein EOS- oder Abhängigkeitsanalyseergebnis handelt(Beachten Sie, dass EOS keine Zeilenumbrüche hat)
    if not (line == 'EOS' or dependancies):
        #Durch Tabulator und Komma geteilt
        cols = separator.split(line)
        phrase += cols[0] #Oberflächentyp(surface)

    #Wenn es ein morphologisches Analyseergebnis im EOS- oder Abhängigkeitsanalyseergebnis gibt
    elif phrase != '':
        chunks.append(Chunk(phrase, dst))
        phrase = ''

    #Im Falle eines Abhängigkeitsergebnisses
    if dependancies:
        dst = int(dependancies.group(1))

#In ein Format geändert, das etwas mit einem Kontakt an pydot übergibt
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)))

#Speichern Sie das Bild mit pydot als gerichtete Grafik
if len(edges) > 0:
    graph = pydot.graph_from_edges(edges, directed=True)
    graph.write_png('044.dot.png')

Kommentar beantworten

Text Eingabe

Der "gegebene Satz" -Teil des Klopfens wird durch die "Eingabe" -Funktion gegeben (entspricht er der Frageabsicht?). Wenn nichts eingegeben wird, wird der Anfangswert verwendet.

python


text = input('Bitte geben Sie Text ein')

#Ursprünglicher Wert
if len(text) == 0:
    text = 'Ich erinnere mich nicht genau, ob ich es gesagt habe oder nicht, aber ich glaube, ich habe es wahrscheinlich gesagt, als ich neulich eine Handwundenparty hatte, ohne das Gefühl zu haben, dass ich es ein wenig gesagt habe. Ich habe es versucht, aber ich kam zu dem Schluss, dass es egal ist, ob ich es sage oder nicht.'

CaboCha Ausführungsteil

Der CaboCha-Ausführungsteil wird mithilfe der Funktion "run" des Paket "subprocess" in der Shell ausgeführt. Ich habe den Python-Wrapper von CaboCha nicht verwendet, weil er nur ärgerlich war.

python


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

Der erste Teil des von der Funktion "Drucken" ausgegebenen Inhalts lautet wie folgt.

Teil des Druckergebnisses


* 0 1D 0/4 0.285960
Sprich Verb,Unabhängigkeit,*,*,Godan / Wa Line Erinnerung,Kontinuierliche Verbindung,Erzählen,Es,Es
Der Assistent,Verbindungsassistent,*,*,*,*,Hand,Te,Te
Ah Verb,Nicht unabhängig,*,*,Fünf Schritte, La Linie,Kontinuierliche Verbindung,Gibt es,Ah,Ah
Hilfsverb,*,*,*,Besondere,Grundform,Ta,Ta,Ta
Ka Assistent,Hilfs- / Parallelassistent / Endassistent,*,*,*,*,Oder,Leistung,Leistung
* 1 4D 0/4 2.230543
Sprich Verb,Unabhängigkeit,*,*,Godan / Wa Line Erinnerung,Kontinuierliche Verbindung,Erzählen,Es,Es
Das Verb,Nicht unabhängig,*,*,Ein Schritt,Unvollkommene Form,Teru,Te,Te
Kein Hilfsverb,*,*,*,Spezieller Nai,Kontinuierliche Verbindung,Abwesend,Naka,Naka
Hilfsverb,*,*,*,Besondere,Grundform,Ta,Ta,Ta
Ka Assistent,Hilfs- / Parallelassistent / Endassistent,*,*,*,*,Oder,Leistung,Leistung
* 2 4D 0/3 2.418727
Welche Nase,Gleichbedeutend,Allgemeines,*,*,*,Welche,Dotch,Dotch
Hilfsverb,*,*,*,Besondere,Kontinuierliche Verbindung,Ist,Papa,Papa
Hilfsverb,*,*,*,Besondere,Grundform,Ta,Ta,Ta
Ka Assistent,Hilfs- / Parallelassistent / Endassistent,*,*,*,*,Oder,Leistung,Leistung

python


#In ein Format geändert, das etwas mit einem Kontakt an pydot übergibt
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)))

Übrigens hat "Kanten" solche Inhalte.

((0, 'Haben Sie gesagt'), (1, 'Hast du nicht gesagt'))
((1, 'Hast du nicht gesagt'), (4, 'Ich erinnere mich nicht'))
((2, 'Welches war'), (4, 'Ich erinnere mich nicht'))
((3, 'Richtig'), (4, 'Ich erinnere mich nicht'))
((4, 'Ich erinnere mich nicht'), (19, 'Ich habe darüber nachgedacht,'))
((5, 'Bestimmt'), (7, 'Hurra'))
((6, 'Eine Handwundenparty in dieser Zeit'), (7, 'Hurra'))
((7, 'Hurra'), (8, 'Manchmal'))
((8, 'Manchmal'), (10, 'Sagte'))
((9, 'Ein bisschen'), (10, 'Sagte'))
((10, 'Sagte'), (11, 'Gefühl'))
((11, 'Gefühl'), (12, 'Ohne'))
((12, 'Ohne'), (14, 'Nishimo'))
((13, 'Ohne'), (14, 'Nishimo'))
((14, 'Nishimo'), (15, 'Ohne'))
((15, 'Ohne'), (17, 'Ich glaube ich habe gesagt'))
((16, 'Vielleicht'), (17, 'Ich glaube ich habe gesagt'))
((17, 'Ich glaube ich habe gesagt'), (19, 'Ich habe darüber nachgedacht,'))
((18, 'Bis hierhin'), (19, 'Ich habe darüber nachgedacht,'))
((19, 'Ich habe darüber nachgedacht,'), (28, 'Es hängt davon ab, ob.'))
((20, 'Ach je'), (21, 'Ich werde Ihnen sagen'))
((21, 'Ich werde Ihnen sagen'), (28, 'Es hängt davon ab, ob.'))
((22, 'Sagen'), (23, 'Es ist mir egal'))
((23, 'Es ist mir egal'), (25, 'Es gibt kein Problem,'))
((24, 'Bis zu diesem Punkt'), (25, 'Es gibt kein Problem,'))
((25, 'Es gibt kein Problem,'), (26, 'Ich denke'))
((26, 'Ich denke'), (27, 'Erreicht'))
((27, 'Erreicht'), (28, 'Es hängt davon ab, ob.'))

Gerichtete grafische Darstellung

Verwenden Sie zum Schluss die Funktion graph_from_edges, um ein gültiges Diagramm zu erstellen, und verwenden Sie die Funktion write_png, um das Bild zu speichern. Durch Setzen von "gerichtet = wahr" zum Zeitpunkt der gerichteten grafischen Darstellung wird die Linie zwischen den Segmenten zu einem Pfeil.

#Speichern Sie das Bild mit pydot als gerichtete Grafik
if len(edges) > 0:
    graph = pydot.graph_from_edges(edges, directed=True)
    graph.write_png('044.dot.png')

Ausgabeergebnis (Ausführungsergebnis)

Wenn das Programm ausgeführt wird, werden die folgenden Ergebnisse ausgegeben.

image.png

Dies ist übrigens die ursprüngliche Geschichte dieses Dokuments. Artikel "[Play] Synthetische Analyse von Shinkalions Tonne Demo Mail". image.png

Recommended Posts

Sprachverarbeitung 100 Knocks-44: Visualisierung abhängiger Bäume
100 Sprachverarbeitung Knock-59: Analyse der S-Formel
100 Sprachverarbeitungsklopfen (2020): 28
100 Sprachverarbeitungsklopfen (2020): 38
100 Sprachverarbeitung klopfen 00 ~ 02
100 Sprachverarbeitung Knock-91: Vorbereitung von Analogiedaten
100 Sprachverarbeitung Knock-26: Entfernen von hervorgehobenem Markup
100 Sprachverarbeitung klopfen 2020 [00 ~ 39 Antwort]
100 Sprachverarbeitung klopfen 2020 [00-79 Antwort]
100 Sprachverarbeitung klopfen 2020 [00 ~ 69 Antwort]
100 Sprachverarbeitung Knock 2020 Kapitel 1
100 Amateur-Sprachverarbeitungsklopfen: 17
100 Sprachverarbeitung klopfen 2020 [00 ~ 49 Antwort]
100 Sprachverarbeitung Knock-52: Stemming
100 Sprachverarbeitung Knock Kapitel 1
100 Amateur-Sprachverarbeitungsklopfen: 07
100 Sprachverarbeitung Knock 2020 Kapitel 3
100 Sprachverarbeitung Knock 2020 Kapitel 2
100 Amateur-Sprachverarbeitungsklopfen: 09
100 Amateur-Sprachverarbeitungsklopfen: 47
100 Sprachverarbeitung Knock-53: Tokenisierung
100 Amateur-Sprachverarbeitungsklopfen: 97
100 Sprachverarbeitung klopfen 2020 [00 ~ 59 Antwort]
100 Amateur-Sprachverarbeitungsklopfen: 67
100 Sprachverarbeitung Knock-32 (mit Pandas): Prototyp des Verbs
Sprachverarbeitung 100 Schläge-45: Extraktion von Verbfallmustern
100 Sprachverarbeitung Knock-75 (mit Scicit-Learn): Gewicht der Identität
100 Sprachverarbeitung Knock-99 (mit Pandas): Visualisierung durch t-SNE
100 Sprachverarbeitung Knock-51: Wortausschnitt
100 Sprachverarbeitung Knock-58: Extraktion von Taple
100 Sprachverarbeitung Knock-57: Abhängigkeitsanalyse
100 Sprachverarbeitung Knock-50: Satzumbruch
100 Sprachverarbeitung Knock-36 (unter Verwendung von Pandas): Häufigkeit des Auftretens von Wörtern
100 Sprachverarbeitung Knock Kapitel 1 (Python)
100 Sprachverarbeitung Knock Kapitel 2 (Python)
100 Sprachverarbeitung Knock-25: Vorlagenextraktion
Sprachverarbeitung 100 Knock-87: Wortähnlichkeit
Sprachverarbeitung 100 Schläge-49: Extraktion von Abhängigkeitspfaden zwischen Nomenklatur
Ich habe versucht, 100 Sprachverarbeitung klopfen 2020
100 Sprachverarbeitung Knock-56: Co-Referenz-Analyse
Lösen von 100 Sprachverarbeitungsklopfen 2020 (01. "Patatokukashi")
Lernen Sie mit "Google Colaboratory" ganz einfach 100 Sprachverarbeitungsklopfen 2020.
100 Amateur-Sprachverarbeitungsklopfen: Zusammenfassung
100 Sprachverarbeitung Knock-77 (mit Scicit-Learn): Messung der korrekten Antwortrate
100 Sprachverarbeitung Knock-42: Anzeige der Phrase der betroffenen Person und der betroffenen Person
Sprachverarbeitung 100 Knocks-29: Holen Sie sich die URL des Flaggenbildes
100 Sprachverarbeitung Knock 2020 Kapitel 2: UNIX-Befehle
100 Sprachverarbeitung Knock 2015 Kapitel 5 Abhängigkeitsanalyse (40-49)
100 Sprachverarbeitungsklopfen mit Python (Kapitel 1)
100 Sprachverarbeitung Knock Kapitel 1 in Python
100 Sprachverarbeitung Knock 2020 Kapitel 4: Morphologische Analyse
100 Sprachverarbeitung Knock 2020 Kapitel 9: RNN, CNN
100 Sprachverarbeitung Knock-76 (mit Scicit-Learn): Beschriftung
100 Sprachverarbeitung Knock-55: Extraktion eindeutiger Ausdrücke
Ich habe versucht, 100 Sprachverarbeitung klopfen 2020: Kapitel 3
100 Sprachverarbeitung Knock-82 (Kontextwort): Kontextextraktion
100 Sprachverarbeitungsklopfen mit Python (Kapitel 3)
100 Sprachverarbeitungsklopfen: Kapitel 1 Vorbereitungsbewegung
100 Sprachverarbeitung Knock 2020 Kapitel 6: Maschinelles Lernen
100 Sprachverarbeitung Knock Kapitel 4: Morphologische Analyse
Sprachverarbeitung 100 knock-86: Wortvektoranzeige