Es ist ein Herausforderungsrekord von 100 Sprachverarbeitungsklopfen 2015. Die Umgebung ist Ubuntu 16.04 LTS + Python 3.5.2 : : Anaconda 4.1.1 (64-Bit). Klicken Sie hier, um eine Liste der vergangenen Schläge anzuzeigen (http://qiita.com/segavvy/items/fb50ba8097d59475f760).
Verwenden Sie CaboCha, um eine Abhängigkeitsanalyse für den Text (neko.txt) von Natsume Sosekis Roman "Ich bin eine Katze" durchzuführen und das Ergebnis in einer Datei namens neko.txt.cabocha zu speichern. Verwenden Sie diese Datei, um ein Programm zu implementieren, das die folgenden Fragen beantwortet.
Implementieren Sie zusätzlich zu> 40 die Klauselklasse Chunk. Diese Klasse enthält eine Liste von Morph-Elementen (Morph-Objekten) (Morphs), eine Liste verwandter Klauselindexnummern (dst) und eine Liste verwandter ursprünglicher Klauselindexnummern (srcs) als Mitgliedsvariablen. Lesen Sie außerdem das Analyseergebnis von CaboCha des Eingabetextes, drücken Sie einen Satz als Liste von Chunk-Objekten aus und zeigen Sie die Zeichenfolge und den Kontakt der Phrase des achten Satzes an. Verwenden Sie für die restlichen Probleme in Kapitel 5 das hier erstellte Programm.
main.py
# coding: utf-8
import CaboCha
import re
fname = 'neko.txt'
fname_parsed = 'neko.txt.cabocha'
def parse_neko():
'''Analyse basierend auf "Ich bin eine Katze"
"Ich bin eine Katze"(neko.txt)Abhängige Analyse und Neko.txt.Speichern Sie zu Cabocha
'''
with open(fname) as data_file, \
open(fname_parsed, mode='w') as out_file:
cabocha = CaboCha.Parser()
for line in data_file:
out_file.write(
cabocha.parse(line).toString(CaboCha.FORMAT_LATTICE)
)
class Morph:
'''
Morphologische Klasse
Oberflächenform (Oberfläche), Grundform (Basis), Teil des Wortes (pos), Teil des Wortes Unterklasse 1 (pos1)
Haben in Mitgliedsvariablen
'''
def __init__(self, surface, base, pos, pos1):
'''Initialisieren'''
self.surface = surface
self.base = base
self.pos = pos
self.pos1 = pos1
def __str__(self):
'''Zeichenfolgendarstellung des Objekts'''
return 'surface[{}]\tbase[{}]\tpos[{}]\tpos1[{}]'\
.format(self.surface, self.base, self.pos, self.pos1)
class Chunk:
'''
Phrasenklasse
Liste der Morph-Elemente (Morph-Objekte) (Morphs), Zielklausel-Indexnummer (dst),
Es enthält eine Liste (srcs) der Indexnummern der ursprünglichen Klausel als Mitgliedsvariable.
'''
def __init__(self):
'''Initialisieren'''
self.morphs = []
self.srcs = []
self.dst = -1
def __str__(self):
'''Zeichenfolgendarstellung des Objekts'''
surface = ''
for morph in self.morphs:
surface += morph.surface
return '{}\tsrcs{}\tdst[{}]'.format(surface, self.srcs, self.dst)
def neco_lines():
'''Generator der Ergebnisse der Abhängigkeitsanalyse für "Ich bin eine Katze"
Lesen Sie die Ergebnisse der Abhängigkeitsanalyse von "Ich bin eine Katze" nacheinander.
Gibt Satz für Satz eine Liste der Chunk-Klassen zurück
Rückgabewert:
Liste der 1-Satz-Chunk-Klassen
'''
with open(fname_parsed) as file_parsed:
chunks = dict() #Speichern Sie Chunk mit idx als Schlüssel
idx = -1
for line in file_parsed:
#Beurteilung des Endes eines Satzes
if line == 'EOS\n':
#Gibt eine Liste von Chunks zurück
if len(chunks) > 0:
#Sortieren Sie Chunks nach Schlüssel und rufen Sie nur den Wert ab
sorted_tuple = sorted(chunks.items(), key=lambda x: x[0])
yield list(zip(*sorted_tuple))[1]
chunks.clear()
else:
yield []
#Der Anfang ist*Da die Zeile von das Ergebnis einer Abhängigkeitsanalyse ist, erstellen Sie Chunk
elif line[0] == '*':
#Holen Sie sich die Chunk-Indexnummer und die Kontaktindexnummer
cols = line.split(' ')
idx = int(cols[1])
dst = int(re.search(r'(.*?)D', cols[2]).group(1))
#Generieren Sie (falls nicht) Chunk und legen Sie die Indexnummer des Kontakts fest
if idx not in chunks:
chunks[idx] = Chunk()
chunks[idx].dst = dst
#Generieren Sie (falls nicht) einen Teil des Kontakts und fügen Sie die Indexnummer des Kontakts hinzu
if dst != -1:
if dst not in chunks:
chunks[dst] = Chunk()
chunks[dst].srcs.append(idx)
#Die anderen Zeilen sind die Ergebnisse der morphologischen Analyse. Erstellen Sie also Morph und fügen Sie es Chunk hinzu.
else:
#Andernfalls wird die Oberflächenebene durch Tabulatoren getrennt','Durch Pause trennen
cols = line.split('\t')
res_cols = cols[1].split(',')
#Morph erstellen, zur Liste hinzufügen
chunks[idx].morphs.append(
Morph(
cols[0], # surface
res_cols[6], # base
res_cols[0], # pos
res_cols[1] # pos1
)
)
raise StopIteration
#Abhängigkeitsanalyse
parse_neko()
#Erstellen Sie eine Liste Satz für Satz
for i, chunks in enumerate(neco_lines(), 1):
#Zeigen Sie den 8. Satz an
if i == 8:
for j, chunk in enumerate(chunks):
print('[{}]{}'.format(j, chunk))
break
Das Problem ist "Kontakt anzeigen", aber die Kontaktquelle wird auch angezeigt, um die Implementierung der Chunk-Klasse zu bestätigen.
Terminal
[0]Ich bin srcs[] dst[5]
[1]Hier srcs[] dst[2]
[2]Zum ersten Mal srcs[1] dst[3]
[3]Menschliche srcs[2] dst[4]
[4]Dinge srcs[3] dst[5]
[5]sah. srcs[0, 4] dst[-1]
Das Ergebnis der Abhängigkeitsanalyse von CaboCha hat die Form, dass eine Zeile, die mit "*" beginnt, in das Ergebnis der morphologischen Analyse eingefügt wird und das Ergebnis der Abhängigkeitsanalyse dort ausgegeben wird.
Beispiel für das Ergebnis der Abhängigkeitsanalyse
* 3 5D 1/2 0.656580
Diese Zeile ist durch Leerzeichen getrennt und enthält den folgenden Inhalt.
Säule | Bedeutung |
---|---|
1 | Die erste Spalte ist* .. Zeigt an, dass es sich um ein Ergebnis der Abhängigkeitsanalyse handelt. |
2 | Phrasennummer (Ganzzahl ab 0) |
3 | Kontaktnummer +D |
4 | Hauptadresse/Funktionswortposition und beliebig viele Identitätsspalten |
5 | Verlobungspunktzahl. Im Allgemeinen ist es umso einfacher, sich zu engagieren, je größer der Wert ist. |
In dieser Ausgabe werden nur die Spalten 2 und 3 verwendet. Einzelheiten zu den Analyseergebnissen finden Sie auf der offiziellen Website CaboCha / Noch ein weiterer japanischer Abhängigkeitsstrukturanalysator.
Das Problem war diesmal die Reihenfolge, in der die Chunk-Objekte erstellt wurden. Lesen Sie vorerst zeilenweise neko.txt.cabocha, erstellen Sie das entsprechende Chunk-Objekt, wenn Sie auch nur eine Information im Chunk-Objekt speichern können, und fügen Sie die Informationen dort hinzu, wenn sie bereits erstellt wurden. Ich habe versucht, es im Fluss von zu implementieren. Die Reihenfolge beim Erstellen von Chunk-Objekten ist nicht die Reihenfolge des Erscheinungsbilds. Da der Inhalt in keiner bestimmten Reihenfolge aufgeführt ist, da das Wörterbuch ebenfalls verwendet wird, wird er nach Klauselnummer sortiert und am Ende extrahiert. Ich dachte nach dem Erstellen, aber es war möglicherweise effizienter, zuerst Chunk-Objekte in der Reihenfolge der Klauselnummer ohne Abhängigkeitsinformationen zu erstellen und die Abhängigkeitsinformationen später festzulegen. Das ist alles für den 42. Schlag. Wenn Sie Fehler haben, würde ich mich freuen, wenn Sie darauf hinweisen könnten.
Recommended Posts