[PYTHON] [Sprachverarbeitung 100 Schläge 2020] Kapitel 4: Morphologische Analyse

Einführung

Die Version 2020 von 100 Klopfen der Sprachverarbeitung, die als Sammlung von Problemen der Verarbeitung natürlicher Sprache bekannt ist, wurde veröffentlicht. Dieser Artikel fasst die Ergebnisse der Lösung Kapitel 4: Morphologische Analyse aus den folgenden Kapiteln 1 bis 10 zusammen. ..

Vorbereitungen

Wir verwenden Google Colaboratory für Antworten. Ausführliche Informationen zum Einrichten und Verwenden von Google Colaboratory finden Sie in diesem Artikel. Das Notizbuch mit den Ausführungsergebnissen der folgenden Antworten ist unter [github] verfügbar (https://github.com/hana-mame/nlp100/blob/master/chapter04.ipynb).

Kapitel 4: Morphologische Analyse

Verwenden Sie MeCab, um den Text (neko.txt) von Natsume Sosekis Roman "Ich bin eine Katze" morphologisch zu analysieren und das Ergebnis in einer Datei namens neko.txt.mecab zu speichern. Verwenden Sie diese Datei, um ein Programm zu implementieren, das die folgenden Fragen beantwortet.

Laden Sie zunächst die angegebenen Daten herunter. Wenn Sie den folgenden Befehl in der Zelle von Google Colaboratory ausführen, wird die Zieldatei in das aktuelle Verzeichnis heruntergeladen.

!wget https://nlp100.github.io/data/neko.txt

[Wget] Befehl - Datei durch Angabe der URL herunterladen

Installieren Sie als Nächstes MeCab.

!apt install mecab libmecab-dev mecab-ipadic-utf8

Nach Abschluss der Installation wird sofort eine morphologische Analyse durchgeführt. Durch Ausführen des folgenden Befehls wird das Ergebnis der morphologischen Analyse von `neko.txt``` als` neko.txt.mecab``` ausgegeben.

!mecab -o ./neko.txt.mecab ./neko.txt

Morphologische Analyse (Wikipedia) MeCab-Befehlszeilenargumentliste und ihr Ausführungsbeispiel

Überprüfen Sie das Ausgabeergebnis.

#Überprüfen Sie die Anzahl der Zeilen
!wc -l ./neko.txt.mecab

Ausgabe


216302 ./neko.txt.mecab
#Überprüfen Sie die ersten 10 Zeilen
!head -10 ./neko.txt.mecab

Ausgabe


Ein Substantiv,Nummer,*,*,*,*,einer,Ichi,Ichi
EOS
EOS
Symbol,Leer,*,*,*,*, , , 
Mein Substantiv,Gleichbedeutend,Allgemeines,*,*,*,ich,Wagahai,Wagahai
Ist ein Assistent,Hilfe,*,*,*,*,Ist,C.,Beeindruckend
Cat Nomen,Allgemeines,*,*,*,*,Katze,Katze,Katze
Mit Hilfsverb,*,*,*,Besondere,Kontinuierlicher Typ,Ist,De,De
Ein Hilfsverb,*,*,*,Fünf Schritte, La Linie Al,Grundform,Gibt es,Al,Al
.. Symbol,Phrase,*,*,*,*,。,。,。

30. Lesen der Ergebnisse der morphologischen Analyse

Implementieren Sie ein Programm, das die Ergebnisse der morphologischen Analyse liest (neko.txt.mecab). Jedes morphologische Element wird jedoch in einem Zuordnungstyp mit dem Schlüssel der Oberflächenform (Oberfläche), der Grundform (Basis), einem Teil des Wortes (pos) und einem Teil der Wortunterklassifizierung 1 (pos1) gespeichert, und ein Satz wird als Liste morphologischer Elemente (Zuordnungstyp) ausgedrückt. Machen wir das. Verwenden Sie für die restlichen Probleme in Kapitel 4 das hier erstellte Programm.

filename = './neko.txt.mecab'

sentences = []
morphs = []
with open(filename, mode='r') as f:
  for line in f:  #Zeile für Zeile lesen
    if line != 'EOS\n':  #Anders als das Ende des Satzes: Speichert morphologische Analyseinformationen in einem Wörterbuchtyp und fügt sie der morphologischen Liste hinzu
      surface, attr = line.split('\t')
      attr = attr.split(',')
      morph = {'surface': surface, 'base': attr[6], 'pos': attr[0], 'pos1': attr[1]}
      morphs.append(morph)
    else:  #Satzende: Morphologische Elementliste zur Satzliste hinzufügen
      sentences.append(morphs)
      morphs = []

#Bestätigung
for morph in sentences[2]:
  print(morph)

Ausgabe


{'surface': '\u3000', 'base': '\u3000', 'pos': 'Symbol', 'pos1': 'Leer'}
{'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'}

Lesen und Schreiben von Dateien mit Python Zeichenfolgen in Python teilen Schleifenverarbeitung durch Python für Anweisung Wie man eine bedingte Verzweigung mit einer if-Anweisung in Python schreibt Dict () und Wave-Klammern zum Erstellen eines Wörterbuchs in Python, Wörterbucheinschlussnotation Hinzufügen eines Elements zu einer Liste (einem Array) in Python

31. Verb

Extrahieren Sie alle Oberflächenformen des Verbs.

Danach werden wir die in 30 erstellten `Sätze``` verarbeiten. Der Typ `set```, in dem das Ergebnis gespeichert ist, ist ein Datentyp, der eine Menge darstellt und keine Duplizierung zulässt. Selbst wenn Sie ein Element hinzufügen, ohne darüber nachzudenken, können Sie daher ein Ergebnis erhalten, das sich nicht auf natürliche Weise überlappt, was in einem Fall wie dieser Frage praktisch ist.

ans = set()
for sentence in sentences:
  for morph in sentence:
    if morph['pos'] == 'Verb':
      ans.add(morph['surface'])  #Da es sich um einen Satztyp handelt, bleiben nur eindeutige Elemente erhalten.

#
print(f': {len(ans)}\n')
print('------')
for i in range(10):
  print(list(ans)[i])

``


: 3893

------
Art der Oberflächenform des Verbs Beispielausgabe Art der Oberflächenform des Verbs Beispielgewinn
Shinobi
Ausrichten
Beachten
Show
Schnell
Getrennt
Behalten
Matsuwa
Von

Python, Set-Operation mit Set-Typ

32. Prototyp des Verbs

Extrahieren Sie alle Originalformen des Verbs.

ans = set()
for sentence in sentences:
  for morph in sentence:
    if morph['pos'] == 'Verb':
      ans.add(morph['base'])

#Bestätigung
print(f'Arten von Verbprototypen: {len(ans)}\n')
print('---Stichprobe---')
for i in range(10):
  print(list(ans)[i])

Ausgabe


Arten von Verbprototypen: 2300

---Stichprobe---
Ausrichten
Erwarten
Unerbittlich
Kann schlagen
Reagieren
verpflichten
Falten
durchbohren
Wachsen
sagen

33. "B von A"

Extrahieren Sie die Nomenklatur, in der zwei Nomenklaturen durch "Nein" verbunden sind.

ans = set()
for sentence in sentences:
  for i in range(1, len(sentence) - 1):
    if sentence[i - 1]['pos'] == 'Substantiv' and sentence[i]['surface'] == 'von' and sentence[i + 1]['pos'] == 'Substantiv':
      ans.add(sentence[i - 1]['surface'] + sentence[i]['surface'] + sentence[i + 1]['surface'])

#Bestätigung
print(f'"Substantiv+von+名詞」von種類: {len(ans)}\n')
print('---Stichprobe---')
for i in range(10):
  print(list(ans)[i])

Ausgabe


"Substantiv+von+名詞」von種類: 4924

---Stichprobe---
Der Körper der Krankheit
Eine Seite der
ich hasse mich
Probleme mit der Polizei
Des Gesetzes
Geeignet für Dinge
Detektiv der Welt
Angst vor Schutz
Zwei Elemente
Stehende Herde

Ermitteln Sie die Größe von Objekten verschiedener Typen mit der len-Funktion von Python Strings mit Python verketten und kombinieren

34. Verkettung der Nomenklatur

Extrahieren Sie die Verkettung der Nomenklatur (Substantive, die nacheinander erscheinen) mit der längsten Übereinstimmung.

Für jeden Satz werden die folgenden Regeln in der Reihenfolge des ersten morphologischen Elements angewendet, und die Verkettung der Nomenklatur wird mit der längsten Übereinstimmung extrahiert.

  1. Wenn es sich um ein Substantiv handelt, verketten Sie es mit `Substantiven``` und zählen Sie die Anzahl der Verkettungen (` num```).
  2. Bei Nicht-Nomenklaturen geben Sie aus, wenn die Anzahl der Verkettungen bis zu diesem Punkt 2 oder mehr beträgt, und initialisieren Sie `Nomen``` und` num```
  3. Andernfalls initialisieren Sie `Nomen``` und` num```
ans = set()
for sentence in sentences:
  nouns = ''
  num = 0
  for i in range(len(sentence)):
    if sentence[i]['pos'] == 'Substantiv':  # 最初の形態素から順に、Substantivであればnounsに連結し、連結数(num)Anzahl
      nouns = ''.join([nouns, sentence[i]['surface']])
      num += 1
    elif num >= 2:  #Andere Ausgaben als die Nomenklatur und wenn die Anzahl der Verkettungen bis zu diesem Punkt 2 oder mehr beträgt, werden Substantive und num initialisiert.
      ans.add(nouns)
      nouns = ''
      num = 0
    else:  #Andernfalls initialisieren Sie Substantive und num
      nouns = ''
      num = 0

#Bestätigung
print(f'Arten der verketteten Nomenklatur: {len(ans)}\n')
print('---Stichprobe---')
for i in range(10):
  print(list(ans)[i])

Ausgabe


Arten der verketteten Nomenklatur: 4454

---Stichprobe---
Kan Inoguchi
Straße heute
Muss Welt haben
Zwei Blätter
Du Champagner
Annäherung
Dummkopf
Kitsukigaki
10 Jahre jetzt
Andere als Stimulation

35. Häufigkeit des Auftretens von Wörtern

Finden Sie die Wörter, die im Satz erscheinen, und ihre Häufigkeit des Auftretens, und ordnen Sie sie in absteigender Reihenfolge der Häufigkeit des Auftretens an.

from collections import defaultdict 

ans = defaultdict(int)
for sentence in sentences:
  for i in range(len(sentence)):
    if sentence[i]['pos'] != 'Symbol':
      ans[sentence[i]['base']] += 1  #Aktualisieren Sie die Anzahl der Wörter(Setze 1, wenn es das erste Wort ist)
ans = sorted(ans.items(), key=lambda x: x[1], reverse=True)

#Bestätigung
for i in range(5):
  print(ans[i])

Ausgabe


('von', 9194)
('Hand', 6848)
('Ist', 6420)
('Zu', 6243)
('Zu', 6071)

Verwendung von Python defaultdict Liste der Wörterbücher in Python nach einem bestimmten Schlüsselwert sortieren

36. Top 10 der häufigsten Wörter

Zeigen Sie die 10 Wörter mit hoher Häufigkeit und ihrer Häufigkeit in einem Diagramm an (z. B. einem Balkendiagramm).

Installieren Sie `` `japanize_matplotlib```, um Japanisch mit matplotlib anzuzeigen.

!pip install japanize_matplotlib

[Super einfach] Wie man die japanische Notation von matplotlib in nur 2 Schritten korrespondiert

Aggregieren Sie dann wie bei 35 die Häufigkeit des Auftretens und visualisieren Sie sie mit einem Balkendiagramm.

import matplotlib.pyplot as plt
import japanize_matplotlib

ans = defaultdict(int)
for sentence in sentences:
  for i in range(len(sentence)):
    if sentence[i]['pos'] != 'Symbol':
      ans[sentence[i]['base']] += 1  #Aktualisieren Sie die Anzahl der Wörter(Setze 1, wenn es das erste Wort ist)
ans = sorted(ans.items(), key=lambda x: x[1], reverse=True)

keys = [a[0] for a in ans[0:10]]
values = [a[1] for a in ans[0:10]]
plt.figure(figsize=(8, 4))
plt.bar(keys, values)
plt.show()

36.png

Grundlagen der Python Graph Drawing Library Matplotlib

37. Top 10 Wörter, die häufig zusammen mit "Katze" vorkommen

Zeigen Sie 10 Wörter an, die häufig zusammen mit "cat" (hohe Häufigkeit des gemeinsamen Auftretens) und deren Häufigkeit des Auftretens in einem Diagramm (z. B. einem Balkendiagramm) vorkommen.

Ich habe den Teil des Wortes hier nicht ausgewählt, da es keine bestimmte Anweisung gibt, aber je nach Zweck denke ich, dass das Ergebnis durch Entfernen der Hilfswörter aussagekräftiger wird.

ans = defaultdict(int)
for sentence in sentences:
  if 'Katze' in [morph['surface'] for morph in sentence]:  # 文の形態素に「Katze」が含まれる場合のみ辞書に追加
    for i in range(len(sentence)):
      if sentence[i]['pos'] != 'Symbol':
        ans[sentence[i]['base']] += 1  #Aktualisieren Sie die Anzahl der Wörter(Setze 1, wenn es das erste Wort ist)
del ans['Katze']
ans = sorted(ans.items(), key=lambda x: x[1], reverse=True)

keys = [a[0] for a in ans[0:10]]
values = [a[1] for a in ans[0:10]]
plt.figure(figsize=(8, 4))
plt.bar(keys, values)
plt.show()

37.png

Wörterbuchelemente in Python löschen

38. Histogramm

Zeichnen Sie ein Histogramm der Häufigkeit des Auftretens von Wörtern (die horizontale Achse repräsentiert die Häufigkeit des Auftretens und die vertikale Achse repräsentiert die Anzahl der Arten von Wörtern, die die Häufigkeit des Auftretens als Balkendiagramm verwenden).

ans = defaultdict(int)
for sentence in sentences:
  for i in range(len(sentence)):
    if sentence[i]['pos'] != 'Symbol':
      ans[sentence[i]['base']] += 1  #Aktualisieren Sie die Anzahl der Wörter(Setze 1, wenn es das erste Wort ist)
ans = ans.values()

plt.figure(figsize=(8, 4))
plt.hist(ans, bins=100)
plt.show()

38.png

In Python nur Wörterbuchschlüssel und -werte als Liste abrufen

39. Zipfs Gesetz

Zeichnen Sie beide logarithmischen Diagramme mit der Worthäufigkeitsrangfolge auf der horizontalen Achse und der Worthäufigkeit auf der vertikalen Achse.

import math

ans = defaultdict(int)
for sentence in sentences:
  for i in range(len(sentence)):
    if sentence[i]['pos'] != 'Symbol':
      ans[sentence[i]['base']] += 1  #Aktualisieren Sie die Anzahl der Wörter(Setze 1, wenn es das erste Wort ist)
ans = sorted(ans.items(), key=lambda x: x[1], reverse=True)

ranks = [math.log(r + 1) for r in range(len(ans))]
values = [math.log(a[1]) for a in ans]
plt.figure(figsize=(8, 4))
plt.scatter(ranks, values)
plt.show()

39.png

[Zip's Law (Wikipedia)](https://ja.wikipedia.org/wiki/%E3%82%B8%E3%83%83%E3%83%97%E3%81%AE%E6%B3% 95% E5% 89% 87) Exponential- / Logarithmusfunktionen mit Python berechnen

abschließend

Sprachverarbeitung 100 Klopfen sind so konzipiert, dass Sie nicht nur die Verarbeitung natürlicher Sprache selbst lernen können, sondern auch die grundlegende Datenverarbeitung und das allgemeine maschinelle Lernen. Sogar diejenigen, die maschinelles Lernen in Online-Kursen studieren, können sehr gute Ergebnisse erzielen. Probieren Sie es also bitte aus.

Recommended Posts

100 Sprachverarbeitungsklopfen 2020: Kapitel 4 (morphologische Analyse)
[Sprachverarbeitung 100 Schläge 2020] Kapitel 4: Morphologische Analyse
Sprachverarbeitung 100 Schläge Kapitel 4: Morphologische Analyse 31. Verben
100 Sprachverarbeitung klopft Morphologische Analyse in Kapitel 4 gelernt
100 Sprachverarbeitung Knock 2020 Kapitel 4: Morphologische Analyse
[Sprachverarbeitung 100 Schläge 2020] Kapitel 5: Abhängigkeitsanalyse
100 Language Processing Knock 2015 Kapitel 4 Morphologische Analyse (30-39)
100 natürliche Sprachverarbeitung klopft Kapitel 4 Morphologische Analyse (erste Hälfte)
100 natürliche Sprachverarbeitung klopft Kapitel 4 Morphologische Analyse (zweite Hälfte)
100 Sprachverarbeitungsklopfen ~ Kapitel 1
100 Sprachverarbeitung klopft Kapitel 2 (10 ~ 19)
Verarbeitung natürlicher Sprache 1 Morphologische Analyse
100 Sprachverarbeitungsklopfen 03 ~ 05
100 Sprachverarbeitungsklopfen (2020): 40
100 Sprachverarbeitungsklopfen (2020): 32
100 Sprachverarbeitung Knock 2015 Kapitel 5 Abhängigkeitsanalyse (40-49)
100 Sprachverarbeitungsklopfen (2020): 35
[Sprachverarbeitung 100 Schläge 2020] Kapitel 3: Reguläre Ausdrücke
100 Sprachverarbeitungsklopfen (2020): 47
100 Sprachverarbeitungsklopfen (2020): 39
100 Klicks in der Verarbeitung natürlicher Sprache Kapitel 4 Kommentar
[Sprachverarbeitung 100 Schläge 2020] Kapitel 6: Maschinelles Lernen
100 Sprachverarbeitungsklopfen (2020): 22
100 Sprachverarbeitungsklopfen (2020): 26
100 Sprachverarbeitungsklopfen (2020): 34
100 Sprachverarbeitungsklopfen (2020): 29
100 Sprachverarbeitungsklopfen (2020): 49
100 Sprachverarbeitungsklopfen 06 ~ 09
100 Sprachverarbeitungsklopfen (2020): 43
100 Sprachverarbeitungsklopfen (2020): 24
[Sprachverarbeitung 100 Schläge 2020] Kapitel 1: Vorbereitende Bewegung
100 Sprachverarbeitungsklopfen (2020): 45
100 Sprachverarbeitungsklopfen (2020): 10-19
[Sprachverarbeitung 100 Schläge 2020] Kapitel 7: Wortvektor
100 Sprachverarbeitungsklopfen (2020): 30
100 Sprachverarbeitung Knock 2020 Kapitel 5: Abhängigkeitsanalyse
100 Sprachverarbeitungsklopfen (2020): 00-09
100 Sprachverarbeitung klopfen 2020: Kapitel 3 (regulärer Ausdruck)
100 Sprachverarbeitungsklopfen (2020): 31
[Sprachverarbeitung 100 Schläge 2020] Kapitel 8: Neuronales Netz
100 Sprachverarbeitungsklopfen (2020): 48
[Sprachverarbeitung 100 Schläge 2020] Kapitel 2: UNIX-Befehle
100 Sprachverarbeitungsklopfen (2020): 41
100 Sprachverarbeitungsklopfen (2020): 37
[Sprachverarbeitung 100 Schläge 2020] Kapitel 9: RNN, CNN
100 Sprachverarbeitungsklopfen (2020): 25
100 Sprachverarbeitungsklopfen (2020): 33
100 Sprachverarbeitungsklopfen (2020): 27
100 natürliche Sprachverarbeitung klopft Kapitel 5 Abhängigkeitsanalyse (zweite Hälfte)
100 Sprachverarbeitungsklopfen (2020): 46
100 Sprachverarbeitungsklopfen (2020): 21
100 natürliche Sprachverarbeitung klopft Kapitel 5 Abhängigkeitsanalyse (erste Hälfte)
100 Sprachverarbeitungsklopfen (2020): 36
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