[PYTHON] Sprachverarbeitung 100 Schläge-48: Extraktion des Weges von der Nase zur Wurzel

Sprachverarbeitung 100 Schläge 2015 ["Kapitel 5: Abhängigkeitsanalyse"](http: //www.cl.ecei. Es ist eine Aufzeichnung von 48. "Extrahieren des Pfades von der Nase zur Wurzel" von tohoku.ac.jp/nlp100/#ch5). .. Es ist etwas einfacher als das letzte Klopfen. Dies liegt daran, dass es nicht so viele Bedingungen gibt und nur der Kontakt kontinuierlich ausgegeben wird.

Referenzlink

Verknüpfung Bemerkungen
048.Extraktion von Pfaden von der Nomenklatur zu den Wurzeln.ipynb Antwortprogramm GitHub Link
100 Klicks Amateur-Sprachverarbeitung:48 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)

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.

48. Extraktion des Weges von der Nase zur Wurzel

Extrahieren Sie für eine Klausel, die die gesamte Nomenklatur des Satzes enthält, den Pfad von dieser Klausel zum Stamm des Syntaxbaums. Der Pfad im Syntaxbaum muss jedoch die folgenden Spezifikationen erfüllen.

  • Jede Klausel wird durch eine (oberflächliche) morphologische Sequenz dargestellt
  • Verketten Sie die Ausdrücke jeder Klausel mit "->" von der Startklausel bis zur Endklausel des Pfads.

Aus dem Satz "Ich habe hier zum ersten Mal einen Menschen gesehen" (8. Satz von neko.txt.cabocha) sollte die folgende Ausgabe erhalten werden.

ich bin->sah
Hier->Beginnen mit->Mensch->Dinge->sah
Mensch->Dinge->sah
Dinge->sah

Antworten

Antwortprogramm [048. Extraktion des Pfades von der Nase zu root.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 / 048.% E5% 90% 8D% E8% A9% 9E% E3% 81% 8B% E3% 82% 89% E6 % A0% B9% E3% 81% B8% E3% 81% AE% E3% 83% 91% E3% 82% B9% E3% 81% AE% E6% 8A% BD% E5% 87% BA.ipynb)

import re

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

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

class Morph:
    def __init__(self, line):
        
        #Durch Tabulator und Komma geteilt
        cols = separator.split(line)
        
        self.surface = cols[0] #Oberflächentyp(surface)
        self.base = cols[7]    #Grundform(base)
        self.pos = cols[1]     #Teil(pos)
        self.pos1 = cols[2]    #Teiltexte Unterklassifizierung 1(pos1)

class Chunk:
    def __init__(self, morphs, dst):
        self.morphs = morphs
        self.dst  = dst  #Indexnummer der Kontaktklausel
        
        self.phrase = ''
        self.noun = False
        
        for morph in morphs:
            if morph.pos != 'Symbol':
                self.phrase += morph.surface #Für Nicht-Symbole
            if morph.pos == 'Substantiv':
                self.noun = True

morphs = []
chunks = []
sentences = []

with open('./neko.txt.cabocha') as f:
    
    for line in f:
        dependancies = dependancy.match(line)
        
        #Wenn es sich nicht um ein EOS- oder Abhängigkeitsanalyseergebnis handelt
        if not (line == 'EOS\n' or dependancies):
            morphs.append(Morph(line))
            
        #Wenn es ein morphologisches Analyseergebnis im EOS- oder Abhängigkeitsanalyseergebnis gibt
        elif len(morphs) > 0:
            chunks.append(Chunk(morphs, dst))
            morphs = []
       
        #Im Falle eines Abhängigkeitsergebnisses
        if dependancies:
            dst = int(dependancies.group(1))
        
        #Wenn es eine Abhängigkeit gibt, führt dies zu EOS
        if line == 'EOS\n' and len(chunks) > 0:
            sentences.append(chunks)
            chunks = []

for i, sentence in enumerate(sentences):
    for chunk in sentence:
        if chunk.noun and chunk.dst != -1:
            line = chunk.phrase
            current_chunk = chunk
            while current_chunk.dst != -1:
                line = line + ' -> ' + sentence[current_chunk.dst].phrase
                current_chunk = sentence[current_chunk.dst]
            print(i, '\t',line)
    #Begrenzt, weil es viele gibt
    if i > 10:
        break

Kommentar beantworten

Chunk-Klasse

Die Chunk-Klasse ist sauberer als beim letzten Mal. Es hat eine Flagge, die eine Nomenklatur enthält.

python


class Chunk:
    def __init__(self, morphs, dst):
        self.morphs = morphs
        self.dst  = dst  #Indexnummer der Kontaktklausel
        
        self.phrase = ''
        self.noun = False
        
        for morph in morphs:
            if morph.pos != 'Symbol':
                self.phrase += morph.surface #Für Nicht-Symbole
            if morph.pos == 'Substantiv':
                self.noun = True

Ausgabeabschnitt

Es war seit dem letzten Mal viel einfacher, aber stattdessen ist es mit der folgenden Ausgabe etwas komplizierter. Wenn eine Abhängigkeit mit einer Nomenklatur vorliegt, verbindet die while-Klausel die Segmente mit dem Ende der Abhängigkeit.

python


for i, sentence in enumerate(sentences):
    for chunk in sentence:
        if chunk.noun and chunk.dst != -1:
            line = chunk.phrase
            current_chunk = chunk
            while current_chunk.dst != -1:
                line = line + ' -> ' + sentence[current_chunk.dst].phrase
                current_chunk = sentence[current_chunk.dst]
            print(i, '\t',line)
    #Begrenzt, weil es viele gibt
    if i > 10:
        break

Ausgabeergebnis (Ausführungsergebnis)

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

Ausgabeergebnis


2 Der Name ist->Nein
3 wo->Geboren->Katonto->Verwende nicht
3 Katonto->Verwende nicht
3 Ich habe eine Ahnung->Verwende nicht
4 alles->dim->In Tränen->Ich erinnere mich
4 am Ort->In Tränen->Ich erinnere mich
4 Nur was war da->Ich erinnere mich
5 Ich bin->sah
5 hier->Beginnen mit->Mensch->Dinge->sah
5 Menschen->Dinge->sah
5 Dinge->sah
6 Später->Wenn du hörst->Das ist es
6 ist es->Das ist es
6 Hat einen Studenten angerufen->In Menschen->War ein Rennen->Das ist es
6 beim Menschen->War ein Rennen->Das ist es
6 Ichiban->Böse->War ein Rennen->Das ist es
6 böse->War ein Rennen->Das ist es
War 6 Rennen->Das ist es
7 Ein Student ist->Ist eine Geschichte
7 wir->Fang->Kochen->Essen->Ist eine Geschichte
8 Zu dieser Zeit->Ich habe nicht->dachte nicht nach
8 was->Gedanken->Ich habe nicht->dachte nicht nach
8 Gedanken->Ich habe nicht->dachte nicht nach
9 sein->In der Handfläche->Gelegt werden->Aufgehoben->Zeit->Sanft->Gefühl->Nur aufgewärmt
9 in der Handfläche->Gelegt werden->Aufgehoben->Zeit->Sanft->Gefühl->Nur aufgewärmt
9 Sue->Aufgehoben->Zeit->Sanft->Gefühl->Nur aufgewärmt
9 Uhr->Sanft->Gefühl->Nur aufgewärmt
9 Gefühl->Nur aufgewärmt
10 Palmen->Über->beruhigen->ich sah->Mensch->Von Sachen->Wird der Anfang sein
Am 10->beruhigen->ich sah->Mensch->Von Sachen->Wird der Anfang sein
10 Studenten->Gesicht->ich sah->Mensch->Von Sachen->Wird der Anfang sein
10 Gesichter->ich sah->Mensch->Von Sachen->Wird der Anfang sein
10 Ich habe gesehen->Mensch->Von Sachen->Wird der Anfang sein
10 Menschen->Von Sachen->Wird der Anfang sein
10 Dinge->Wird der Anfang sein
11 Uhr->Wenn es eine Sache ist->habe gedacht->Gefühl->Verbleibend
11 seltsam->Wenn es eine Sache ist->habe gedacht->Gefühl->Verbleibend
11 Dinge->habe gedacht->Gefühl->Verbleibend
11 Gefühl->Verbleibend
11 Immer noch->Verbleibend

Recommended Posts

Sprachverarbeitung 100 Schläge-48: Extraktion des Weges von der Nase zur Wurzel
Sprachverarbeitung 100 Schläge-49: Extraktion von Abhängigkeitspfaden zwischen Nomenklatur
100 Sprachverarbeitung Knock-22: Extraktion des Kategorienamens
Sprachverarbeitung 100 Knocks-46: Extraktion von Verbfall-Frame-Informationen
[Kapitel 5] Einführung in Python mit 100 Klopfen Sprachverarbeitung
[Kapitel 6] Einführung in Scicit-Learn mit 100 Klopfen Sprachverarbeitung
[Kapitel 3] Einführung in Python mit 100 Klopfen Sprachverarbeitung
[Kapitel 2] Einführung in Python mit 100 Klopfen Sprachverarbeitung
[Kapitel 4] Einführung in Python mit 100 Klopfen Sprachverarbeitung
100 Sprachverarbeitungsklopfen 03 ~ 05
100 Sprachverarbeitungsklopfen (2020): 40
100 Sprachverarbeitungsklopfen (2020): 32
100 Sprachverarbeitungsklopfen (2020): 35
100 Sprachverarbeitungsklopfen (2020): 47
100 Sprachverarbeitungsklopfen (2020): 39
100 Sprachverarbeitungsklopfen (2020): 22
100 Sprachverarbeitungsklopfen (2020): 26
100 Sprachverarbeitungsklopfen (2020): 34
100 Sprachverarbeitungsklopfen (2020): 42
100 Sprachverarbeitungsklopfen (2020): 29
100 Sprachverarbeitungsklopfen (2020): 49
100 Sprachverarbeitungsklopfen 06 ~ 09
100 Sprachverarbeitungsklopfen (2020): 43
100 Sprachverarbeitungsklopfen (2020): 24
100 Sprachverarbeitungsklopfen (2020): 45
100 Sprachverarbeitungsklopfen (2020): 10-19
100 Sprachverarbeitungsklopfen (2020): 30
100 Sprachverarbeitungsklopfen (2020): 00-09
100 Sprachverarbeitungsklopfen (2020): 31
100 Sprachverarbeitungsklopfen (2020): 48
100 Sprachverarbeitungsklopfen (2020): 44
100 Sprachverarbeitungsklopfen (2020): 41
100 Sprachverarbeitungsklopfen (2020): 37
100 Sprachverarbeitungsklopfen (2020): 25
100 Sprachverarbeitungsklopfen (2020): 23
100 Sprachverarbeitungsklopfen (2020): 33
100 Sprachverarbeitungsklopfen (2020): 20
100 Sprachverarbeitungsklopfen (2020): 27
100 Sprachverarbeitungsklopfen (2020): 46
100 Sprachverarbeitungsklopfen (2020): 21
100 Sprachverarbeitungsklopfen (2020): 36
Sprachverarbeitung 100 Schläge-45: Extraktion von Verbfallmustern
Ich habe versucht, die 2020-Version von 100 Sprachverarbeitungsproblemen zu lösen [Kapitel 3: Reguläre Ausdrücke 20 bis 24]
Ich habe versucht, die 2020-Version von 100 Sprachverarbeitungsproblemen zu lösen [Kapitel 1: Vorbereitungsbewegung 00-04]
Ich habe versucht, die 2020-Version von 100 Sprachverarbeitungsproblemen zu lösen [Kapitel 1: Vorbereitungsbewegung 05-09]
100 Amateur-Sprachverarbeitungsklopfen: 41
100 Amateur-Sprachverarbeitungsklopfen: 71
100 Amateur-Sprachverarbeitungsklopfen: 56
100 Amateur-Sprachverarbeitungsklopfen: 24
100 Amateur-Sprachverarbeitungsklopfen: 50
100 Amateur-Sprachverarbeitungsklopfen: 59
100 Amateur-Sprachverarbeitungsklopfen: 70
100 Amateur-Sprachverarbeitungsklopfen: 62
100 Amateur-Sprachverarbeitungsklopfen: 60
100 Amateur-Sprachverarbeitungsklopfen: 92
100 Amateur-Sprachverarbeitungsklopfen: 30
100 Amateur-Sprachverarbeitungsklopfen: 84
100 Amateur-Sprachverarbeitungsklopfen: 33
100 Amateur-Sprachverarbeitungsklopfen: 46
100 Amateur-Sprachverarbeitungsklopfen: 88
100 Amateur-Sprachverarbeitungsklopfen: 89