[PYTHON] Sprachverarbeitung 100 Knocks-46: Extraktion von Verbfall-Frame-Informationen

Sprachverarbeitung 100 Schläge 2015 ["Kapitel 5: Abhängigkeitsanalyse"](http: //www.cl.ecei. Dies ist die Aufzeichnung von 46. "Extraktion von Verbfallrahmeninformationen" von tohoku.ac.jp/nlp100/#ch5). Beim letzten Mal wurden nur die Hilfswörter ausgegeben, aber diesmal werden auch die Phrasen (jeder Frame) ausgegeben. Natürlich ist es noch schwieriger ...

Referenzlink

Verknüpfung Bemerkungen
046.Extraktion von Verb-Case-Frame-Informationen.ipynb Antwortprogramm GitHub Link
100 Klicks Amateur-Sprachverarbeitung:46 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ß- und Kleinschreibung, funktionale Verbsyntax, Abhängigkeitspfad, [Graphviz](http: / /www.graphviz.org/)

Inhalt anklopfen

Verwenden von CaboCha für den Text von Soseki Natsumes Roman "Ich bin eine Katze" (neko.txt) 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.

[46. Extraktion von Informationen zum Verbfall] [http://www.cl.ecei.tohoku.ac.jp/nlp100/#sec46)

Ändern Sie das Programm> 45 und geben Sie den Begriff (die Klausel selbst in Bezug auf das Prädikat) in einem durch Tabulatoren getrennten Format aus, das dem Prädikat und dem Fallmuster folgt. Erfüllen Sie zusätzlich zu den 45 Spezifikationen die folgenden Spezifikationen.

  • Der Begriff sollte eine Wortfolge der Klausel sein, die sich auf das Prädikat bezieht (das nachfolgende Verb muss nicht entfernt werden).
  • Wenn es mehrere Klauseln gibt, die sich auf das Prädikat beziehen, ordnen Sie sie in derselben Norm und Reihenfolge wie die Hilfswörter an, die durch Leerzeichen getrennt sind.

Betrachten Sie den Beispielsatz (8. Satz von neko.txt.cabocha), dass "ich hier zum ersten Mal einen Menschen gesehen habe". Dieser Satz enthält zwei Verben, "begin" und "see", und die Phrase, die sich auf "begin" bezieht, wird als "here" analysiert, und die Phrase, die sich auf "see" bezieht, wird als "I am" und "thing" analysiert. Sollte die folgende Ausgabe erzeugen.

Fang hier an
Sehen Sie, was ich sehe

Aufgabenergänzung (über "jeden Frame (Fallgrammatik)")

Wenn Sie interessiert sind, lesen Sie bitte Wikipedia "Kaku Grammatik". Sie können es lösen, ohne zu schauen. Ich verstehe es nicht nur durch einen Blick darauf.

Antworten

Antwortprogramm [046. Extraktion von Verb-Case-Frame-Informationen.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 / 046.% E5% 8B% 95% E8% A9% 9E% E3% 81% AE% E6% A0% BC% E3% 83% 95% E3% 83% AC% E3% 83% BC% E3% 83% A0% E6% 83% 85% E5% A0% B1% 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 teilen
        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)

    def __init__(self, morphs, dst):
        self.morphs = morphs
        self.srcs = []   #Liste der ursprünglichen Klauselindexnummern
        self.dst  = dst  #Indexnummer der Kontaktklausel
        
        self.phrase = ''
        self.verb = ''
        self.joshi = ''
        
        for morph in morphs:            
            if morph.pos != 'Symbol':
                self.phrase += morph.surface #Für Nicht-Symbole
                self.joshi = ''  #Leer für Nicht-Symbole, um die letzte Zeile der Verben ohne Symbole abzurufen
            if morph.pos == 'Verb':
                self.verb = morph.base
            if morph.pos == 'Partikel':
                self.joshi = morph.base

#Ersetzen Sie den Ursprung und fügen Sie die Chunk-Liste zur Anweisungsliste hinzu
def append_sentence(chunks, sentences):
    
    #Ersetzen Sie den Unternehmer
    for i, chunk in enumerate(chunks):
        if chunk.dst != -1:
            chunks[chunk.dst].srcs.append(i)
    sentences.append(chunks)
    return sentences, []

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, chunks = append_sentence(chunks, sentences)

def output_file(out_file, sentence, chunk):
    #Erstellen Sie eine Liste der Angestellten
    sources = [[sentence[source].joshi, sentence[source].phrase] \
                for source in chunk.srcs if sentence[source].joshi != '']
            
    if len(sources) > 0:
        sources.sort()
        joshi = ' '.join([row[0] for row in sources])
        phrase = ' '.join([row[1] for row in sources])
        out_file.write(('{}\t{}\t{}\n'.format(chunk.verb, joshi, phrase)))

with open('./046.result_python.txt', 'w') as out_file:
    for sentence in sentences:
        for chunk in sentence:
            if chunk.verb != '' and len(chunk.srcs) > 0:
                output_file(out_file, sentence, chunk)

Kommentar beantworten

Chunk-Klasse

Immerhin wurde die Chunk-Klasse, die die Lebensader von Kapitel 5 darstellt, gegenüber der vorherigen Zeit geändert. Ich habe die Instanzvariable Phrase erstellt und den Klauseltext eingefügt. Alles andere ist das gleiche.

python


class Chunk:
    def __init__(self, morphs, dst):
        self.morphs = morphs
        self.srcs = []   #Liste der ursprünglichen Klauselindexnummern
        self.dst  = dst  #Indexnummer der Kontaktklausel
        
        self.phrase = ''
        self.verb = ''
        self.joshi = ''
        
        for morph in morphs:
            if morph.pos != 'Symbol':
                self.phrase += morph.surface #Für Nicht-Symbole
                self.joshi = ''  #Leer für Nicht-Symbole, um die letzte Zeile der Verben ohne Symbole abzurufen
            if morph.pos == 'Verb':
                self.verb = morph.base
            if morph.pos == 'Partikel':
                self.joshi = morph.base

Dateiausgabefunktion

Da es ziemlich kompliziert wurde, habe ich den Dateiausgabeteil als Funktion ausgeschnitten. Eine Liste von Hilfswörtern und -klauseln wird mit der ersten Listeneinschlussnotation erstellt und nach dem Sortieren mit der Funktion "join" ausgegeben.

python


def output_file(out_file, sentence, chunk):
    #Erstellen Sie eine Liste der Angestellten
    sources = [[sentence[source].joshi, sentence[source].phrase] \
                for source in chunk.srcs if sentence[source].joshi != '']
            
    if len(sources) > 0:
        sources.sort()
        joshi = ' '.join([row[0] for row in sources])
        phrase = ' '.join([row[1] for row in sources])
        out_file.write(('{}\t{}\t{}\n'.format(chunk.verb, joshi, phrase)))

Ausgabeergebnis (Ausführungsergebnis)

Wenn das Programm ausgeführt wird, werden die folgenden Ergebnisse ausgegeben (nur die ersten 10 Elemente).

bash:046.result_python.txt


Wo man geboren wird
Ich habe eine Ahnung
Wo ich geweint habe
Das einzige was ich geweint habe
Fang hier an
Sehen Sie, was ich sehe
Hör später zu
Fang uns
Kochen und fangen
Essen und kochen

Recommended Posts

Sprachverarbeitung 100 Knocks-46: Extraktion von Verbfall-Frame-Informationen
Sprachverarbeitung 100 Schläge-45: Extraktion von Verbfallmustern
100 Sprachverarbeitung Knock-22: Extraktion des Kategorienamens
Sprachverarbeitung 100 Schläge-48: Extraktion des Weges von der Nase zur Wurzel
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): 26
100 Sprachverarbeitungsklopfen (2020): 34
100 Sprachverarbeitungsklopfen (2020): 42
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
100 Sprachverarbeitung Knock-32 (mit Pandas): Prototyp des Verbs
100 Amateur-Sprachverarbeitungsklopfen: 41
100 Amateur-Sprachverarbeitungsklopfen: 71
100 Amateur-Sprachverarbeitungsklopfen: 56
100 Amateur-Sprachverarbeitungsklopfen: 50
100 Amateur-Sprachverarbeitungsklopfen: 59
100 Amateur-Sprachverarbeitungsklopfen: 70
100 Amateur-Sprachverarbeitungsklopfen: 62
100 Amateur-Sprachverarbeitungsklopfen: 60
100 Amateur-Sprachverarbeitungsklopfen: 30
100 Amateur-Sprachverarbeitungsklopfen: 06
100 Amateur-Sprachverarbeitungsklopfen: 84
100 Amateur-Sprachverarbeitungsklopfen: 81
100 Amateur-Sprachverarbeitungsklopfen: 33
100 Amateur-Sprachverarbeitungsklopfen: 46
100 Amateur-Sprachverarbeitungsklopfen: 88
100 Amateur-Sprachverarbeitungsklopfen: 89
100 Amateur-Sprachverarbeitungsklopfen: 40
100 Amateur-Sprachverarbeitungsklopfen: 45
100 Amateur-Sprachverarbeitungsklopfen: 43
100 Amateur-Sprachverarbeitungsklopfen: 55
100 Amateur-Sprachverarbeitungsklopfen: 22
100 Amateur-Sprachverarbeitungsklopfen: 61
100 Amateur-Sprachverarbeitungsklopfen: 94
100 Amateur-Sprachverarbeitungsklopfen: 54
100 Amateur-Sprachverarbeitungsklopfen: 04
100 Amateur-Sprachverarbeitungsklopfen: 63