Ich löse 100 Klopfen bei der Sprachverarbeitung in einer Studiensitzung, die sich auf Mitglieder des Unternehmens, aber den Antwortcode und die Lösung konzentriert Dies ist eine Zusammenfassung der Tricks, die ich dabei nützlich fand. Der größte Teil des Inhalts wurde von mir selbst untersucht und verifiziert, enthält jedoch auch Informationen, die von anderen Mitgliedern der Studiengruppe geteilt wurden.
Bis zu Kapitel 3 war der Inhalt für alle Python-Programmierungen verwendbar, aber da es sich bei diesem Kapitel um eine morphologische Analyse handelt, ähnelt es endlich mehr der Sprachverarbeitung.
Legen Sie neko.txt
im selben Verzeichnis wie die ipynb- (oder Python-) Datei ab
!mecab neko.txt -o neko.txt.mecab
Das Ergebnis der morphologischen Analyse wird dann in "neko.txt.mecab" aufgezeichnet.
import re
import itertools
def parse_text(flat=True):
with open('neko.txt.mecab') as file:
morphs = []
sentence = []
for line in file:
if re.search(r'EOS', line):
continue
surface, rest = line.split('\t')
arr = rest.split(',')
sentence.append({
'surface': surface,
'base': arr[6],
'pos': arr[0],
'pos1': arr[1],
})
if surface == ' ': #Leerzeichen gelten nicht als morphologische Elemente
sentence.pop(-1)
if surface in [' ', '。']: #Betrachten Sie Leerzeichen und Interpunktion als das Ende eines Satzes
morphs.append(sentence)
sentence = []
if flat:
return list(itertools.chain.from_iterable(morphs))
else:
return morphs
parse_text(flat=False)[:10]
Ergebnis
[[{'surface': 'ich', 'base': 'ich', 'pos': 'Substantiv', 'pos1': '代Substantiv'},
{'surface': 'Ist', 'base': 'Ist', 'pos': 'Partikel', 'pos1': '係Partikel'},
{'surface': 'Katze', 'base': 'Katze', 'pos': 'Substantiv', 'pos1': 'Allgemeines'},
{'surface': 'damit', 'base': 'Ist', 'pos': 'Hilfsverb', 'pos1': '*'},
{'surface': 'Gibt es', 'base': 'Gibt es', 'pos': 'Hilfsverb', 'pos1': '*'},
{'surface': '。', 'base': '。', 'pos': 'Symbol', 'pos1': 'Phrase'}],
[{'surface': 'Name', 'base': 'Name', 'pos': 'Substantiv', 'pos1': 'Allgemeines'},
Für dieses Problem muss "ein Satz als Liste morphologischer Elemente ausgedrückt werden (Zuordnungstyp)". Bei Verwendung dieser Funktion in Problem 31 und höher wurde der Rückgabewert jedoch abgeflacht (nicht verschachtelt). ) Ist einfacher zu handhaben, deshalb habe ich beschlossen, ein formelles Argument namens "flach" vorzubereiten. Der Standardwert für diese "flache" ist "wahr", aber in dieser Ausgabe übergebe ich das Argument "flach = falsch", weil ich eine nicht abgeflachte Liste möchte.
Der Grund, warum in der letzten Zeile "[: 10]" steht, ist, dass es genau richtig war, dass die Anzahl der zur Bestätigung anzuzeigenden Elemente etwa 10 betrug, sodass keine besondere Notwendigkeit besteht.
import numpy as np
def extract_surface():
verbs = list(filter(lambda morph: morph['pos'] == 'Verb', parse_text()))
return [verb['surface'] for verb in verbs]
print(extract_surface()[:100])
Ergebnis
['Geboren', 'Tsuka', 'Shi', 'Weinen', 'Shi', 'Ist', 'Start', 'Sie sehen', 'Hör mal zu', 'Fang', 'Gekocht', 'Essen', 'Gedanken', 'Wird geladen', 'Sein', 'Aufzug', 'Sein', 'Shi', 'Ah', 'Beruhigen', 'Sie sehen', 'Sie sehen', 'Gedanken', 'Verbleibend', 'Ist', 'Sa', 'Re', 'Shi', 'Treffen', 'Treffen', 'Shi', 'nur', 'Wenn', 'Shi', 'Ist', 'Schlag', 'einstellen', 'Schwach', 'trinken', 'Kennt', 'Hinsetzen', 'Oh', 'Machen', 'Shi', 'Start', 'Bewegung', 'Bewegung', 'Verstehen', 'Herumgehen', 'Werden', 'Vom Assistenten', 'Gedanken', 'Ist', 'Saり', 'Shi', 'aus', 'Shi', 'Ist', 'Gedankenausそ', 'Verstehen', 'Mit', 'Sie sehenる', 'ich', 'Oh', 'Sie sehenえ', '隠Shi', 'Shiまっ', 'Anders', '明ich', 'ich', 'Sein', '這ichausShi', 'Sie sehenる', 'Wegschmeißen', 'Sein', '這ichausす', 'Gibt es', 'Hinsetzen', 'Shi', 'Gedanken', 'Sie sehen', 'aus', 'Shi', 'Weinen', 'Kommen', 'くReる', 'GedankenMit', 'Schließlich', 'Sie sehen', 'Kommen', 'Gekreuzt', 'Nehmen', 'Verringert', 'Kommen', 'Weinen', 'aus', 'Gibt es', 'Gibt es', 'Shi', 'Es ist Zeit']
Der Rückgabewert kann auch als "Liste (Karte (Lambda Morph: Morph ['Oberfläche'], Verben))" erstellt werden. Die Verwendung der Einschlussnotation wie oben ist jedoch ein präziserer Code.
Dies hängt auch davon ab, wie Sie die Problemanweisung interpretieren. Wenn Sie jedoch keine doppelten Elemente in der Rückgabeliste zulassen möchten, setzen Sie die letzte Zeile der Funktion.
return set([verb['surface'] for verb in verbs])
Es gibt Methoden wie.
def extract_base():
verbs = list(filter(lambda morph: morph['pos'] == 'Verb', parse_text()))
return [verb['base'] for verb in verbs]
print(extract_base()[:100])
Ergebnis
['Geboren', 'Tsukuri', 'Machen', 'Schrei', 'Machen', 'Ist', 'Start', 'sehen', 'Hör mal zu', 'Erfassung', 'Kochen', 'Essen', 'Überlegen', 'Stellen', 'Sein', 'Aufzug', 'Sein', 'Machen', 'Gibt es', '落ちTsukuri', 'sehen', 'sehen', 'Überlegen', 'Bleiben übrig', 'Ist', 'Machen', 'Sein', 'Machen', 'Treffen', 'Treffen', 'Machen', 'Nomu', 'Werden', 'Machen', 'Ist', 'Schlag', 'Machen', 'Schwach', 'trinken', 'kennt', 'Hinsetzen', 'Oru', 'Machen', 'Machen', 'Start', 'Bewegung', 'Bewegung', 'Verstehen', 'Herumgehen', 'Werden', 'Gerettet werden', 'Überlegen', 'Ist', 'Saru', 'Machen', 'Geh raus', 'Machen', 'Ist', 'Ausdenken', 'Verstehen', 'Anfügen', 'sehen', 'Ist', 'Oru', 'erscheinen', 'ausblenden', 'Enden', 'Falsch', 'Deutlich sein', 'Ist', 'Sein', 'Herauskriechen', 'sehen', 'Verwerfen', 'Sein', 'Herauskriechen', 'Gibt es', 'Hinsetzen', 'Machen', 'Überlegen', 'sehen', 'Geh raus', 'Machen', 'Schrei', 'Kommen Sie', 'くSein', '考えAnfügen', 'machen', 'sehen', 'Kommen Sie', 'Kreuz', 'Nehmen', 'verringern', 'Kommen Sie', 'Schrei', 'Geh raus', 'Gibt es', 'Gibt es', 'Machen', 'Rasieren']
Fast das gleiche wie 31.
def extract_sahens():
return list(filter(lambda morph: morph['pos1'] == 'Verbindung ändern', parse_text()))
extract_sahens()[:20]
Ergebnis
[{'surface': 'Registrieren', 'base': 'Registrieren', 'pos': 'Substantiv', 'pos1': 'Verbindung ändern'},
{'surface': 'Erinnerung', 'base': 'Erinnerung', 'pos': 'Substantiv', 'pos1': 'Verbindung ändern'},
{'surface': 'Geschichte', 'base': 'Geschichte', 'pos': 'Substantiv', 'pos1': 'Verbindung ändern'},
{'surface': 'Dekoration', 'base': 'Dekoration', 'pos': 'Substantiv', 'pos1': 'Verbindung ändern'},
{'surface': 'Vorsprung', 'base': 'Vorsprung', 'pos': 'Substantiv', 'pos1': 'Verbindung ändern'},
...
Fast das gleiche wie 31.
def extract_noun_phrases():
morphs = parse_text()
phrases = []
for i, morph in enumerate(morphs):
if morph['surface'] == 'von' and morphs[i - 1]['pos'] == 'Substantiv' \
and morphs[i + 1]['pos'] == 'Substantiv':
phrases.append(
morphs[i - 1]['surface'] + 'von' + morphs[i + 1]['surface'])
return phrases
print(extract_noun_phrases()[:100])
Ergebnis
['Seine Handfläche', 'Auf der Handfläche', 'Studentengesicht', 'Sollte Gesicht', 'Mitten im Gesicht', 'In dem Loch', 'Kalligraphiepalme', 'Die Rückseite der Handfläche', 'Was', 'Essentielle Mutter', 'Auf dem Strohhalm', 'In Sasahara', 'Vor dem Teich', 'Auf dem Teich', 'Loch im Zaun', 'Drei Nachbarn', 'Zeitablauf', 'Im Haus', 'Sein Schüler', 'Andere Menschen als', 'Vorheriger Schüler', 'Deine Chance', 'Drei von euch', 'Juckreiz in der Brust', 'Haushälterin', 'Meister', 'Unter der Nase', 'Mein Gesicht', 'Mein Zuhause', 'Mein Ehemann', 'Heimzeug', 'Unsere', 'Sein Studium', 'Auf dem Buch', 'Hautfarbe', 'Auf dem Buch', 'Seine jede Nacht', 'Außer', 'Neben meinem Mann', 'Sein Knie', 'Auf dem Knie', 'Aus Erfahrung', 'Auf der Reisschüssel', 'Auf dem 炬 燵', 'Von hier', 'Begleitetes Bett', 'Zwischen ihnen', 'Begleiter', 'Beispiel Nerv', 'Sexueller Meister', 'Nächster Raum', 'Egoistisch', 'Für mich', 'Zwischen den Brettern in der Küche', 'Respekt für mich', 'Mukai weiß', 'Wie ein Ball', 'Haus dort', 'Heimschüler', 'Hinterer Teich', 'Eltern-Kind-Liebe', 'Weitere Diskussion', 'Kopf stechen', 'Regenschirm von 鰡', 'Für Sie', 'Militärhaus', 'Meister des Ersatzes', 'Lehrerhaus', 'Katzenzeit', 'Mein Haus', 'Haushälterin', 'Voller Englisch', 'Schwache Magengewohnheit', 'Im Gepäckträger', 'Hira no Sect', 'Monatliches Gehalt', 'Vorerst', 'Wie unten', 'Wie jetzt', 'Memoiren des Meisters', 'Sein Freund', 'Brille mit Goldrand', 'Das Gesicht des Meisters', 'Phantasie im Inneren', 'Übersetzt', 'Vermieter von Interesse', 'Hinter dem goldenen Rand', 'Hinter mir', 'Sein Freund', 'Mein Kreis', 'Um das Gesicht', 'Das Ergebnis der Zugabe', 'Gesichtszüge', 'Andere Katzen', 'Unbeholfener Diener', 'Mein Ehemann', 'Katze der gleichen Produktion', 'Gefleckte Haut', 'Färbung des Meisters', 'Relative Muskeln']
Wenn Sie "enumerate ()" verwenden, können Sie die Information, dass "morph" in "morphs" "i" ist, als Variable verwenden, was ein ordentlicher Code ist.
def extract_continuous_nouns():
morphs = parse_text()
continuous_nouns = []
for i, morph in enumerate(morphs):
if morph['pos'] == 'Substantiv' and morphs[i + 1]['pos'] == 'Substantiv':
continuous_noun = morph['surface'] + morphs[i + 1]['surface']
j = 1
while morphs[i + 1 + j]['pos'] == 'Substantiv':
continuous_noun += morphs[i + 1 + j]['surface']
j += 1
continuous_nouns.append(continuous_noun)
return continuous_nouns
print(extract_continuous_nouns()[:100])
Ergebnis
['In Menschen', 'Rechtzeitig', 'Dann Katze', 'Puupuu und Rauch', 'In der Villa', 'Drei Haare', 'Anders als Student', 'Fünfundvierzig Henne', 'Gohen', 'Neulich', 'Mima', 'Deine Küche', 'Mama zurück', 'Wohnhaus', 'Ganztägiges Studium', 'Fleißiger Arbeiter', 'Fleißiger Arbeiter', 'Fleißig', 'Ein paar Seiten', 'Drei Seiten', 'Anders als mein Mann', 'So weit ich bin', 'Morgenmeister', 'Zwei Personen', 'Zuletzt schwer', '--Katze', 'Neurogastrische Schwäche', 'Magenschwäche', 'Finger', 'Schrecklicher Arsch', 'Sprachpause', 'Meine Frau', 'Insgesamt', 'Muskelrichtung', 'Shiro', 'Jedes Mal', 'Shiro', 'Neulich Ball', 'Vier', 'dritter Tag', 'Tag', 'Vier', 'Shiro', 'Unsere Katzen', 'Etc.', 'Katzen', 'Familienleben', 'Leben', 'Drei Haare君', 'Mao', 'Eigentum', 'Zwischen uns', 'Zwischen derselben Familie', 'Augenstich', 'Sie sind Menschen', 'Wir', 'ich', 'Shiro', 'Drei Haare君', 'Mao', 'Voller Fehler', 'Herr Hoshi', 'Munemori', 'Munemori', 'Monatliches Gehaltsdatum', 'Aquarellfarbe', 'Jeden Tag jeden Tag lernen', 'Tägliches Studium', 'Person', 'Bürste selbst', 'Über Brille', 'Itari', 'Vermieter Andrea del Salt', 'Tau', 'Kalt 鴉', 'Diese Breite', 'Live malen', 'Am nächsten Tag', 'Würziger Stock', 'Jetzt ich', 'Jetzt ich', 'Wellenprodukt', 'Wunder', 'Blinde Katze', 'Geheimnis in meinem Herzen', 'Wie viel Andrea del Salt', 'Ein weiterer großer', 'Brechen', 'Dummer Typ', 'Dummer Typ', 'Würziger Stock', 'Dummer TypAnruf', 'Ruf einen Bastard an', 'Anruf', 'Hirai', 'Dummer Typ', 'Jeder wächst', 'Wo hin', 'Mehrmals', '10 tsubo']
import pandas as pd
def sort_by_freq():
words = [morph['base'] for morph in parse_text()]
return pd.Series(words).value_counts()
sort_by_freq()[:20]
Ergebnis
9194
。 7486
6868
、 6772
Ist 6420
...
Importieren Sie als alternative Lösung die Standardbibliothek "Sammlungen" wie unten gezeigt.
from collections import Counter
Sie können auch die Methode "most_common ()" des Objekts "Counter ()" verwenden (anstelle der "value_counts ()" der "Pandas").
return Counter(words).most_common()
Ergebnis
[('von', 9194),
('。', 7486),
('Hand', 6868),
('、', 6772),
('Ist', 6420),
...
Der Unterschied zwischen diesen beiden Lösungen besteht darin, dass "value_counts ()" "Series" zurückgibt, während "most_common ()" ein Array von Tapples zurückgibt, sodass eines für eine einfachere nachfolgende Verarbeitung verwendet werden sollte. Ist es nicht gut
import japanize_matplotlib
def draw_bar_graph():
sort_by_freq()[:10].plot.bar()
draw_bar_graph()
Es dauert eine Weile, bis Japanisch angezeigt wird, aber es war einfach, die im Artikel hier eingeführte Bibliothek namens "japanize_matplotlib" zu verwenden.
Auch in Bezug auf den Inhalt der Funktion wollte ich sie kurz schreiben, also habe ich ".plot.bar ()" für das "Series" -Objekt verwendet.
import matplotlib.pyplot as plt
Nach dem Import von matplotlib
as funktioniert es auch dann, wenn Sie wie folgt schreiben.
morph_freqs = sort_by_freq()[:10]
plt.bar(morph_freqs.index, morph_freqs)
import matplotlib.pyplot as plt
def draw_hist():
plt.xlabel('Häufigkeit des Auftretens')
plt.ylabel('Anzahl der Worttypen')
plt.hist(sort_by_freq(), bins=200)
draw_hist()
Wenn Sie das Ganze anzeigen möchten, handelt es sich um einen solchen Code, der jedoch etwas schwer zu erkennen ist. Daher ist es möglicherweise realistischer, den Anzeigebereich wie folgt einzuschränken.
def draw_hist_2():
plt.xlabel('Häufigkeit des Auftretens')
plt.ylabel('Anzahl der Worttypen')
plt.title('Erscheinungsfrequenz 20 oder weniger')
plt.hist(sort_by_freq(), bins=20, range=(1, 20))
draw_hist_2()
def draw_log_graph():
plt.xscale('log')
plt.yscale('log')
plt.xlabel('Rangfolge der Erscheinungshäufigkeit')
plt.ylabel('Häufigkeit des Auftretens')
plt.scatter(range(1, len(sort_by_freq()) + 1), sort_by_freq(), s=10)
draw_log_graph()
Beim Aufrufen der "Scatter" -Methode können Sie die Größe der Punkte mit der Option "s" angeben. Der Standardwert ist 20, aber er war etwas groß, also habe ich ihn auf "10" gesetzt.
MeCab ist Open Source Software, aber es war interessant zu wissen, dass es immer noch so viele Dinge kann.
Andererseits hatte ich auch das Gefühl, dass die Genauigkeit der Analyse allein damit nicht perfekt war (zum Beispiel wurde "Puuputo" zurückgegeben, da das Ausgabeergebnis bei 35 keine Nomenklatur, sondern ein Zusatz ist). Um dieses Problem zu lösen, ist es meiner Meinung nach notwendig, verschiedene Wörterbücher auszuprobieren und selbst anzupassen.
Das ist alles für dieses Kapitel, aber wenn Sie einen Fehler machen, kommentieren Sie bitte.
Recommended Posts