Adventskalender 17. Tag Ich war zu spät .. ..
Da ich [100 Schläge auf die Sprachverarbeitung] gelöst habe (http://www.cl.ecei.tohoku.ac.jp/nlp100/), werde ich die Antwort und den Eindruck einzeln schreiben (zweiter Teil) Es hat viel länger gedauert als beim letzten Mal ~~~
Für die Umwelt usw. hier (vorheriger Link)
Verwenden Sie CaboCha, um den Text (neko.txt) von Natsume Sosekis Roman "Ich bin eine Katze" abhängig zu machen und zu analysieren, 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.
import CaboCha
c = CaboCha.Parser()
with open('./neko.txt') as f:
text = f.read()
with open('./neko.txt.cabocha', mode='w') as f:
for se in [s + '。' for s in text.split('。')]:
f.write(c.parse(se ).toString(CaboCha.FORMAT_LATTICE))
Eigentlich ist es die erste Abhängigkeitsanalyse, also habe ich allein damit viel gesucht
Implementieren Sie die Klasse Morph, die die Morphologie darstellt. Diese Klasse hat eine Oberflächenform (Oberfläche), eine Basisform (Basis), ein Teilwort (pos) und eine Teilwortunterklassifikation 1 (pos1) als Elementvariablen. Lesen Sie außerdem das Analyseergebnis von CaboCha (neko.txt.cabocha), drücken Sie jeden Satz als Liste von Morph-Objekten aus und zeigen Sie die morphologische Elementzeichenfolge des dritten Satzes an.
# 40
class Morph:
def __init__(self, surface, base, pos, pos1):
self.surface = surface
self.base = base
self.pos = pos
self.pos1 = pos1
doc = []
with open('./neko.txt.cabocha') as f:
sentence = []
line = f.readline()
while(line):
while('EOS' not in line):
if not line.startswith('*'):
cols = line.split('\t')
m = Morph(
surface=cols[0],
base=cols[1].split(',')[-3],
pos=cols[1].split(',')[0],
pos1=cols[1].split(',')[1],
)
sentence.append(m)
line = f.readline()
doc.append(sentence)
sentence = []
line = f.readline()
print([t.surface for t in doc[2]])
Tun Sie dies, während Sie das Ausgabeformat von CaboCha überprüfen
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.
# 41
class Chunk:
def __init__(self, morphs, dst, srcs):
self.morphs = morphs
self.dst = dst
self.srcs = srcs
doc = []
with open('./neko.txt.cabocha') as f:
sentence = []
line = f.readline()
while(line):
if line.startswith('*'):
cols = line.split(' ')
#Setzen Sie nichts eine Zeile über die vorherige EOS
if cols[1] != '0':
sentence.append(c)
c = Chunk(
morphs=[],
dst=int(cols[2].split('D')[0]),
srcs=[]
)
elif 'EOS' in line:
sentence.append(c)
#Der Prozess, etwas zu finden, das von Ihnen abhängt
for i, c in enumerate(sentence):
c.srcs = [idx for idx, chk, in enumerate(sentence) if chk.dst == i ]
doc.append(sentence)
sentence = []
else:
cols = line.split('\t')
if cols[1].split(',')[0] != "Symbol":
m = Morph(
surface=cols[0],
base=cols[1].split(',')[-3],
pos=cols[1].split(',')[0],
pos1=cols[1].split(',')[1],
)
c.morphs.append(m)
line = f.readline()
for c in doc[7]:
print(c.dst, end=', ')
for m in c.morphs:
print(m.surface, end="")
print()
for c in doc[0]:
print(c.dst, end=', ')
for m in c.morphs:
print(m.surface)
print(m.pos)
print()
Ich habe darüber nachgedacht, wie ich den Ausdruck finden kann, der mit mir zusammenhängt, aber ich konnte mir keinen guten vorstellen, also habe ich einfach eine Schleife erstellt und gescannt.
Extrahieren Sie den gesamten Text der ursprünglichen Klausel und der zugehörigen Klausel in tabulatorgetrenntem Format. Geben Sie jedoch keine Symbole wie Satzzeichen aus.
# 42
#Alle sind jupyter(chrome)Weil es 50 härtet
for i, d in enumerate(doc[:50]):
for c in d:
if int(c.dst) == -1:
continue
for m in c.morphs:
if m.pos == 'Symbol':
continue
print(m.surface, end="")
print('\t', end="")
for m in d[c.dst].morphs:
if m.pos == 'Symbol':
continue
print(m.surface, end="")
print()
Tun Sie dies, während Sie sich der Sätze, Phrasen und Morphologie bewusst sind
Wenn sich Klauseln mit Nomenklatur auf Klauseln mit Verben beziehen, extrahieren Sie sie in tabulatorgetrennten Formaten. Geben Sie jedoch keine Symbole wie Satzzeichen aus.
# 43
#Alle sind jupyter(chrome)Weil es 50 härtet
for i, d in enumerate(doc[:50]):
for c in d:
if int(c.dst) == -1:
continue
contain_noun = 'Substantiv' in [m.pos for m in c.morphs]
contain_verb = 'Verb' in [m.pos for m in d[c.dst].morphs]
if contain_noun and contain_verb:
for m in c.morphs:
if m.pos == 'Symbol':
continue
print(m.surface, end="")
print('\t', end="")
for m in d[int(c.dst)].morphs:
if m.pos == 'Symbol':
continue
print(m.surface, end="")
print()
Ich habe einfach mit if
gesucht
Visualisieren Sie den Abhängigkeitsbaum eines bestimmten Satzes als gerichteten Graphen. Zur Visualisierung ist es ratsam, den Abhängigkeitsbaum in die DOT-Sprache zu konvertieren und Graphviz zu verwenden. Verwenden Sie pydot, um gerichtete Diagramme direkt aus Python zu visualisieren.
# 44
import random, pathlib
from graphviz import Digraph
f = pathlib.Path('nekocabocha.png')
fmt = f.suffix.lstrip('.')
fname = f.stem
target_doc = random.choice(doc)
target_doc = doc[8]
idx = doc.index(target_doc)
dot = Digraph(format=fmt)
dot.attr("node", shape="circle")
N = len(target_doc)
#Knoten hinzufügen
for i in range(N):
dot.node(str(i), ''.join([m.surface for m in target_doc[i].morphs]))
#Kante hinzufügen
for i in range(N):
if target_doc[i].dst >= 0:
dot.edge(str(i), str(target_doc[i].dst))
# dot.engine = "circo"
dot.filename = filename
dot.render()
print(''.join([m.surface for c in target_doc for m in c.morphs]))
print(dot)
from IPython.display import Image, display_png
display_png(Image(str(f)))
Ich habe nicht viel getan, während ich dachte, dass Visualisierung Spaß machen würde, also habe ich es zum ersten Mal gemacht, und Wikipedia war genug, um eine grobe Vorstellung von der DOT-Sprache zu bekommen.
Ich möchte den diesmal verwendeten Satz als Korpus betrachten und die möglichen Fälle japanischer Prädikate untersuchen. Stellen Sie sich das Verb als Prädikat und das Hilfsverb der Phrase, die sich auf das Verb bezieht, als Fall vor und geben Sie das Prädikat und den Fall in einem durch Tabulatoren getrennten Format aus. Stellen Sie jedoch sicher, dass die Ausgabe den folgenden Spezifikationen entspricht. In einer Phrase, die ein Verb enthält, wird die Grundform des Verbs ganz links als Prädikat verwendet. Verwenden Sie die Hilfswörter, die sich auf das Prädikat beziehen Wenn das Prädikat mehrere Hilfswörter (Phrasen) enthält, ordnen Sie alle Hilfswörter in Wörterbuchreihenfolge an, die durch Leerzeichen getrennt sind. Betrachten Sie den Beispielsatz (8. Satz von neko.txt.cabocha), der besagt, 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. "Beginnen"
See is
Speichern Sie die Ausgabe dieses Programms in einer Datei und überprüfen Sie die folgenden Elemente mit UNIX-Befehlen. Eine Kombination von Prädikaten und Fallmustern, die häufig im Korpus vorkommen Fallmuster der Verben "do", "see" und "give" (in der Reihenfolge der Häufigkeit des Auftretens im Korpus anordnen)
# 45
with open("neko_verb.txt", mode="w") as f:
for s in doc:
for c in s:
if 'Verb' in [m.pos for m in c.morphs]:
row = c.morphs[0].base
j_list = []
for i in c.srcs:
if len(s[i].morphs) < 2:
continue
srclast = s[i].morphs[-1]
if srclast.pos == 'Partikel':
j_list.append(srclast.surface)
if len(j_list) > 0:
j_list.sort()
row += "\t" + " ".join(j_list)
f.write(row + "\n")
$ cat neko_verb.txt | sort | uniq -c | sort -rn -k 3
$ cat neko_verb.txt | grep "^Machen" | sort | uniq -c | sort -rn -k 3
$ cat neko_verb.txt | grep "sehen" | sort | uniq -c | sort -rn -k 3
$ cat neko_verb.txt | grep "geben" | sort | uniq -c | sort -rn -k 3
Kombinieren Sie bisher den "Teil der Wörter" und "Empfang"
Ä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 (es ist nicht erforderlich, das nachfolgende Verb zu entfernen). 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), der besagt, 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. "Beginnen Sie hier" "Sehen Sie, was ich sehe"
# 46
#Obwohl es sich vom Ausgabebeispiel unterscheidet, entspricht dieses Beispiel der Spezifikation des Problems
for s in doc:
for c in s:
if 'Verb' in [m.pos for m in c.morphs]:
row = c.morphs[0].base
j_list = []
c_list = []
for i in c.srcs:
if len(s[i].morphs) < 2:
continue
srclast = s[i].morphs[-1]
if srclast.pos == 'Partikel':
j_list.append(srclast.surface)
c_list.append(''.join([m.surface for m in s[i].morphs]))
if len(j_list) > 0:
j_list.sort()
c_list.sort()
row += "\t" + " ".join(j_list) + "\t"+ " ".join(c_list)
print(row)
Wenn es mehrere Klauseln gibt, die sich auf das Prädikat beziehen, ordnen Sie sie in derselben Norm und Reihenfolge an wie die Hilfswörter, getrennt durch Leerzeichen.
Es unterscheidet sich also vom Ausgabebeispiel, aber die Klauseln werden auch unabhängig voneinander sortiert
Ich möchte nur auf den Fall achten, in dem das Verb wo case eine Sa-hen-Verbindungsnomenklatur enthält. Ändern Sie 46 Programme, um die folgenden Spezifikationen zu erfüllen. Nur wenn die Phrase bestehend aus "Sahen-Verbindungsnomen + (Hilfsverb)" mit dem Verb verwandt ist Das Prädikat lautet "Sahen-Verbindungsnomen + ist die Grundform von + Verb", und wenn eine Phrase mehrere Verben enthält, wird das Verb ganz links verwendet. Wenn das Prädikat mehrere Hilfswörter (Phrasen) enthält, ordnen Sie alle Hilfswörter in Wörterbuchreihenfolge an, die durch Leerzeichen getrennt sind. Wenn sich mehrere Klauseln auf das Prädikat beziehen, ordnen Sie alle durch Leerzeichen getrennten Begriffe an (richten Sie sie nach der Reihenfolge der Hilfswörter aus). Zum Beispiel sollte die folgende Ausgabe aus dem Satz erhalten werden: "Der Meister wird auf den Brief antworten, selbst wenn er an einen anderen Ort kommt." "Wenn ich antworte, steht mein Mann im Brief" Speichern Sie die Ausgabe dieses Programms in einer Datei und überprüfen Sie die folgenden Elemente mit UNIX-Befehlen. Prädikate, die häufig im Korpus vorkommen (Sahen-Verbindungsnomenklatur + + Verb) Prädikate und Verbmuster, die häufig im Korpus vorkommen
# 47
with open("neko_func_verb.txt", mode="w") as f:
for s in doc:
for c in s:
if 'Verb' in [m.pos for m in c.morphs]:
verb = c.morphs[0].base
for i in c.srcs:
v_head = s[i].morphs[-2:]
if len(v_head) < 2:
continue
if v_head[0].pos1 == "Verbindung ändern" and v_head[1].surface == "Zu":
verb = ''.join([m.surface for m in v_head]) + verb
joshi_dic = {}
for j in c.srcs:
if len(s[j].morphs) < 2:
continue
srclast = s[j].morphs[-1]
if srclast.pos == 'Partikel' and srclast.surface != "Zu":
joshi_dic[srclast.surface] = ''.join([m.surface for m in s[j].morphs])
if len(joshi_dic.keys()) > 0:
joshi_list = list(joshi_dic.keys())
joshi_list.sort()
row = verb + "\t" + " ".join(joshi_list) + "\t" + " ".join([joshi_dic[joshi] for joshi in joshi_list])
f.write(row + "\n")
$ cat neko_func_verb.txt | sed "s/\t/ /g"| cut -f 1 -d " " | sort | uniq -c | sort -rn -k 3
$ cat neko_func_verb.txt | sed "s/\t/+/g"| cut -f 1,2 -d "+" | sed "s/+/\t/g" | sort | uniq -c | sort -rn -k 3
Wenn das Prädikat mehrere Klauseln enthält, ordnen Sie alle durch Leerzeichen getrennten Begriffe an (richten Sie sie nach der Reihenfolge der Hilfswörter aus).
Da dies dasselbe war, habe ich es zu einem Wörterbuchtyp gemacht und es zugeordnet Egal wie oft ich das Problem lese, ich kann es nicht verstehen und bekomme von hier aus Probleme
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 von der Startklausel bis zur Endklausel des Pfads die Ausdrücke jeder Klausel mit "->" 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 sah-> sah
Hier-> Zum ersten Mal-> Mensch-> Ich habe etwas gesehen->
Mensch-> Ich habe etwas gesehen->
Ich habe etwas gesehen->
# 48
for s in doc:
for c in s:
if "Substantiv" in [m.pos for m in c.morphs]:
row = "".join([m.surface for m in c.morphs])
chunk_to = c.dst
if chunk_to == -1:
continue
while(chunk_to != -1):
row += " -> " + "".join([m.surface for m in s[chunk_to].morphs])
chunk_to = s[chunk_to].dst
print(row)
Dies wurde im Vergleich zum vorherigen Problem reibungslos gelöst
Extrahieren Sie den kürzesten Abhängigkeitspfad, der alle Nomenklaturpaare im Satz verbindet. Wenn jedoch die Klauselnummern des Nomenklaturpaars i und j sind (i <j), muss der Abhängigkeitspfad die folgenden Spezifikationen erfüllen. Ähnlich wie bei Problem 48 wird der Pfad ausgedrückt, indem die Ausdrücke (oberflächenmorphologische Elemente) jeder Phrase von der Startklausel bis zur Endklausel mit "->" verkettet werden. Ersetzen Sie die in den Abschnitten i und j enthaltene Nomenklatur durch X bzw. Y. Darüber hinaus kann die Form des Abhängigkeitspfads auf zwei Arten betrachtet werden. Wenn Klausel j auf dem Pfad von Klausel i zum Stamm des Syntaxbaums vorhanden ist: Zeigen Sie den Pfad von Klausel i zu Klausel j an Anders als oben, wenn sich Klausel i und Klausel j an einer gemeinsamen Klausel k auf dem Pfad von Klausel j zur Wurzel des Syntaxbaums überschneiden: der Pfad unmittelbar vor Klausel i zu Klausel k und der Pfad unmittelbar vor Klausel j zu Klausel k, Klausel k Der Inhalt von wird durch "|" verbunden und angezeigt. Die folgende Ausgabe sollte beispielsweise aus dem Satz "Ich habe hier zum ersten Mal einen Menschen gesehen" (8. Satz von neko.txt.cabocha) erhalten werden.
X ist|In Y.->Beginnen mit->Mensch->Dinge|sah
X ist|Genannt Y.->Dinge|sah
X ist|Y.|sah
X-> Start-> Y
X-> Start-> Mensch-> Y
X-> Y
# 49
for s in doc:
# i <Keine Notwendigkeit für das Ende wegen j
for i, c in enumerate(s[:-1]):
if "Substantiv" in [m.pos for m in c.morphs] and c.morphs[-1].pos == "Partikel":
#Finden Sie j
for c_rest in s[i+1:]:
if "Substantiv" in [m.pos for m in c_rest.morphs] and c_rest.morphs[-1].pos == "Partikel":
i_clause = "".join([m.surface if m.pos != "Substantiv" else "X" for m in c.morphs])
j_clause = "".join([m.surface if m.pos != "Substantiv" else "Y" for m in c_rest.morphs])
row = i_clause
chunk_to = c.dst
#Fragen Sie nach dem Pfad, um zu sehen, ob sich j auf dem Pfad befindet
kkr_path = [chunk_to]
while(kkr_path[-1] != -1):
kkr_path.append(s[chunk_to].dst)
chunk_to = s[chunk_to].dst
if s.index(c_rest) in kkr_path:
chunk_to = c.dst
while(chunk_to != s.index(c_rest)):
row += " -> " + "".join([m.surface for m in s[chunk_to].morphs])
chunk_to = s[chunk_to].dst
row += " -> " + j_clause
else:
row += " | " + j_clause
chunk_to = c_rest.dst
while(s[chunk_to].dst != -1):
row += " -> " + "".join([m.surface for m in s[chunk_to].morphs])
chunk_to = s[chunk_to].dst
row += " | " + "".join([m.surface for m in s[chunk_to].morphs])
print(row)
Ersetzen Sie die in den Abschnitten i und j enthaltene Nomenklatur durch X bzw. Y.
Die Spezifikationen und Ausgabebeispiele waren auch hier etwas anders, aber ich habe sie durch eine Nomenklatur wie "X ga" ersetzt.
Führen Sie die folgende Verarbeitung für den englischen Text (nlp.txt) durch.
$ wget http://www.cl.ecei.tohoku.ac.jp/nlp100/data/nlp.txt
(. Oder; oder: oder? Oder!) → Leerzeichen → Betrachten Sie das Muster des englischen Kapitals als Satzbegrenzer und geben Sie das Eingabedokument in Form eines Satzes pro Zeile aus.
# 50
import re
sentence_sep = re.compile(r'(\.|;|:|\?|!) ([A-Z])')
with open("./nlp.txt") as f:
txt = f.read()
txt = re.sub(sentence_sep, r'\1\n\2', txt)
print(txt)
Ich habe es beim Nachdenken gelöst
Behandeln Sie Leerzeichen als Wortumbrüche, nehmen Sie 50 Ausgaben als Eingabe und geben Sie sie in Form eines Wortes pro Zeile aus. Geben Sie jedoch am Ende der Anweisung eine Leerzeile aus.
# 51
def space2return(txt):
sentence_sep = re.compile(r'(\.|;|:|\?|!)\n([A-Z])')
txt = re.sub(sentence_sep, r'\1\n\n\2', txt)
return re.sub(r' ', r'\n', txt)
txt = space2return(txt)
print(txt)
Empfängt 50 Ausgaben, reagiert jedoch ad hoc, da es sich aufgrund von Zeilenumbrüchen im Satz etwas unerwartet verhält
Nehmen Sie die Ausgabe von> 51 als Eingabe, wenden Sie den Stemming-Algorithmus von Porter an und geben Sie das Wort und den Stem in tabulatorgetrennten Formaten aus. In Python sollte das Stemming-Modul als Implementierung des Stemming-Algorithmus von Porter verwendet werden.
# 52
from nltk.stem import PorterStemmer
ps = PorterStemmer()
def stem_text(txt):
for l in txt.split('\n'):
yield l + '\t' + ps .stem(l)
for line in stem_text(txt):
print(line)
Es war nicht in Links bereitgestellt, also habe ich es stattdessen verwendet. Ich habe versucht, Yield zu verwenden, was ich normalerweise vermeide, aber festgestellt, dass der Rückgabewert ein Iterator ist.
53 Tokenization
Verwenden Sie Stanford Core NLP, um das Analyseergebnis des Eingabetextes im XML-Format zu erhalten. Lesen Sie auch diese XML-Datei und geben Sie den Eingabetext in Form eines Wortes pro Zeile aus.
$ wget http://nlp.stanford.edu/software/stanford-corenlp-full-2018-10-05.zip
$ unzip stanford-corenlp-full-2018-10-05.zip
$ java -cp "./stanford-corenlp-full-2018-10-05/*" edu.stanford.nlp.pipeline.StanfordCoreNLP -annotators tokenize,ssplit,parse,lemma,ner,coref -file ./nlp.txt
Dieser Typ, anstatt unter XML-Parsing zu leiden
Lesen Sie die Referenz für -annotators
, wenn Sie Java ausführen, und ändern Sie sie gegebenenfalls
# 53
import xml.etree.ElementTree as ET
tree = ET.parse("./nlp.txt.xml")
root = tree.getroot()
for token in root.iter("token"):
print(token.find("word").text)
Ist dies eine Möglichkeit, das Ganze auszugeben und die Tags zu überprüfen?
Lesen Sie das XML-Analyseergebnis von Stanford Core NLP und geben Sie Wörter, Deckspelzen und Teile in tabulatorgetrennten Formaten aus.
# 54
for token in root.iter("token"):
print(token.find("word").text + "\t" + token.find("lemma").text + "\t" + token.find("POS").text)
Sehr schwer zu sehen
Extrahieren Sie alle Personennamen im Eingabetext.
# 55
for token in root.iter("token"):
NERtag = token.find("NER").text
if NERtag == "PERSON":
print(token.find("word").text)
Ich dachte, es sei eine Implementierung, aber sie wurde markiert
Ersetzen Sie den Referenzausdruck (Erwähnung) im Satz durch den repräsentativen Referenzausdruck (repräsentative Erwähnung) basierend auf dem Ergebnis der Co-Referenzanalyse von Stanford Core NLP. Achten Sie beim Ersetzen jedoch darauf, dass der ursprüngliche Referenzausdruck verstanden wird, z. B. "Repräsentativer Referenzausdruck (Referenzausdruck)".
# 56
rep_dic_list = []
#Ein Wörterbuch erstellen
for coreferences in root.findall("document/coreference"):
for mentions in coreferences:
for m in mentions:
if "representative" in m.attrib:
rep_txt = m.find("text").text
else:
tmp_dic = {}
tmp_dic["sentence"] = m.find("sentence").text
tmp_dic["start"] = m.find("start").text
tmp_dic["end"] = m.find("end").text
tmp_dic["rep_txt"] = rep_txt
rep_dic_list.append(tmp_dic)
#Ausgabe
for s in root.iter("sentence"):
rep_sent_list = [rd for rd in rep_dic_list if rd["sentence"] == s.attrib["id"]]
#Gibt an, ob die Anweisung ersetzt werden muss
if len(rep_sent_list) == 0:
print(" ".join([token.find("word").text for token in s.iter("token")]), end=" ")
else:
for token in s.iter("token"):
tid = token.attrib["id"]
rep_token_list = [rd for rd in rep_sent_list if rd["start"] == tid or rd["end"] == tid]
if len(rep_token_list) > 0:
#Da es nur einen gibt, nehmen Sie ihn heraus
rep_dic = rep_token_list[0]
#Dekoration
if tid == rep_dic["start"]:
print("「" + rep_dic["rep_txt"] + " (", end=" ")
if tid == rep_dic["end"]:
print(")」", end=" ")
print(token.find("word").text, end=" ")
Ich konnte die Problemstellung nicht verstehen und habe sie lange hier gelassen. Erstellen Sie ein Wörterbuch und ändern Sie es, anstatt es zu ersetzen
Visualisieren Sie die reduzierten Abhängigkeiten des Stanford Core NLP als gerichteten Graphen. Zur Visualisierung ist es ratsam, den Abhängigkeitsbaum in die DOT-Sprache zu konvertieren und Graphviz zu verwenden. Verwenden Sie pydot, um gerichtete Diagramme direkt aus Python zu visualisieren.
# 57
import random, pathlib
from graphviz import Digraph
f = pathlib.Path('nlp.png')
fmt = f.suffix.lstrip('.')
fname = f.stem
dot = Digraph(format=fmt)
dot.attr("node", shape="circle")
sent_id = 3
for sents in root.findall(f"document/sentences/sentence[@id='{sent_id}']"):
for deps in sents:
for dep in deps.findall("[@type='collapsed-dependencies']"):
for token in dep:
gvnr = token.find("governor")
dpnt = token.find("dependent")
dot.node(gvnr.attrib["idx"], gvnr.text)
dot.node(dpnt.attrib["idx"], dpnt.text)
dot.edge(gvnr.attrib["idx"], dpnt.attrib["idx"])
dot.filename = fname
dot.render()
# print(dot)
from IPython.display import Image, display_png
display_png(Image(str(f)))
Zuerst habe ich "Gouverneur" und "abhängig" durchlaufen, also habe ich überhaupt nicht verstanden.
Geben Sie die Menge des "Subjekt-Prädikat-Objekts" in tabulatorgetrenntem Format basierend auf dem Ergebnis der Abhängigkeitsanalyse (kollabierte Abhängigkeiten) von Stanford Core NLP aus. Im Folgenden finden Sie jedoch die Definitionen des Subjekts, Prädikats und Objekts.
Prädikat: Ein Wort, das Kinder (Angehörige) von nsubj- und dobj-Beziehungen hat
Betreff: Kind (abhängig), das eine nsubj-Beziehung zum Prädikat hat
Objekt: Ein Kind (abhängig), das eine dobj-Beziehung zum Prädikat hat
# 58
for sents in root.findall(f"document/sentences/sentence"):
for deps in sents:
for dep in deps.findall("[@type='collapsed-dependencies']"):
nsubj_list = []
for token in dep.findall("./dep[@type='nsubj']"):
gvnr = token.find("governor")
dpnt = token.find("dependent")
nsubj_list.append( {
(gvnr.attrib["idx"], gvnr.text): (dpnt.attrib["idx"], dpnt.text)
})
for token in dep.findall("./dep[@type='dobj']"):
gvnr = token.find("governor")
dpnt = token.find("dependent")
dobj_tuple = (gvnr.attrib["idx"], gvnr.text)
if dobj_tuple in [list(nsubj.keys())[0] for nsubj in nsubj_list]:
idx = [list(nsubj.keys())[0] for nsubj in nsubj_list].index( dobj_tuple )
jutugo = gvnr.text
shugo = nsubj_list[idx][dobj_tuple][1]
mokutekigo = dpnt.text
print(shugo + "\t" + jutugo + "\t" + mokutekigo)
Richtlinie zum einmaligen Erstellen eines Wörterbuchs und anschließendes Suchen nach einem Wörterbuch, das die Bedingungen erfüllt
Lesen Sie das Ergebnis der Phrasenstrukturanalyse von Stanford Core NLP (S-Formel) und zeigen Sie alle Nomenklaturphrasen (NP) im Satz an. Alle verschachtelten Nomenklaturen anzeigen.
# 59
import xml.etree.ElementTree as ET
import re
def search_nest(t):
if isinstance(t[0], str):
if isinstance(t[1], str):
if t[0] == "NP":
print(t[1])
return t[1]
else:
if t[0] == "NP":
np_list = []
for i in t[1:]:
res = search_nest(i)
if isinstance(res, str):
np_list.append(search_nest(i))
if len(np_list) > 0:
print(' '.join(np_list))
else:
for i in t[1:]:
search_nest(i)
else:
for i in t:
search_nest(i)
tree = ET.parse("./nlp.txt.xml")
root = tree.getroot()
sent_id = 30
for parse in root.findall(f"document/sentences/sentence[@id='{sent_id}']/parse"):
S_str = parse.text
S_str = S_str.replace("(", "('")
S_str = S_str.replace(")", "')")
S_str = S_str.replace(" ", "', '")
S_str = S_str.replace("'(", "(")
S_str = S_str.replace(")'", ")")
exec(f"S_tuple = {S_str[:-2]}")
search_nest(S_tuple)
Ich konnte die Verschachtelung von ()
nicht erkennen und habe die größte schmutzige Implementierung in meinem Leben vorgenommen. Ich habe sie fest in einen Taple-Typ codiert und rekursiv extrahiert.
Ich habe "Regex" ausprobiert, konnte es aber nicht selbst lösen, daher habe ich der Antwort Priorität eingeräumt.
Es dauerte ungefähr doppelt so lange wie in den Kapiteln 1 bis 4, da beide Kapitel die ersten Bibliotheken waren und die Anzahl der Sprachverarbeitungsbegriffe plötzlich zunahm. Der Rest sind jedoch DB, ML und Vektor, daher bin ich nicht vorsichtig.