Text Mining von word2vec usw. von Python ([Informationen zur Informationsabteilung der High School II] Unterrichtsmaterialien für die Lehrerausbildung)

Einführung

Im letzten Artikel habe ich ein einfaches Text Mining durchgeführt, das auf der Arbeit von Aozora Bunko basiert. https://qiita.com/ereyester/items/7c220a49c15073809c33 Dieses Mal möchte ich Word2vec verwenden, um die Ähnlichkeit von Wörtern zu untersuchen. Es gibt viele andere Artikel über Word2vec, daher werde ich sie nicht im Detail erklären. Word2Vec verstehen [Python] Verwendung von Word2Vec Dieses Mal möchte ich mich auf die Funktion von word2vec.Word2Vec () in gensim.models of gensim konzentrieren. Der Mechanismus von Word2vec, der von Bildern verstanden wird

Lehrmaterial

[Informationsmaterial für Lehrer der High School "Information II" (Haupt): Ministerium für Bildung, Kultur, Sport, Wissenschaft und Technologie](https://www.mext.go.jp/a_menu/shotou/zyouhou/detail/mext_00742.html Unterrichtsmaterialien "Information II" für die Lehrerausbildung (Hauptteil): Ministerium für Bildung, Kultur, Sport, Wissenschaft und Technologie ") Kapitel 3 Informations- und Datenwissenschaft, zweite Hälfte (PDF: 7,6 MB)

Umgebung

Teile, die in den Unterrichtsmaterialien aufgenommen werden sollen

Lernen 18 Text Mining und Bilderkennung: "2. Text Mining mit MeCab"

Implementierungsbeispiel und Ergebnis in Python

Vorbereitung

Laden Sie in Python ein Paket namens gensim für maschinelles Lernen mit Word2vec.

!pip install gensim

Laden Sie als Nächstes das Emotionswörterbuch herunter, damit die Emotionsanalyse später durchgeführt werden kann. Eine Emotionsanalyse ist möglich, indem der Abstand zu den Hauptbegriffen der Begriffe ermittelt wird, die Emotionen mit Word2vec während der Emotionsanalyse anzeigen. Hier wird jedoch als japanisches Wörterbuch die Emotionsanalyse mithilfe der PN-Tabelle des Tokyo Institute of Technology durchgeführt. Ich werde.

import urllib.request
import pandas as pd

#PN-Tabellenlink
url = 'http://www.lr.pi.titech.ac.jp/~takamura/pubs/pn_ja.dic'

#Name der Datei speichern
file_path = 'pn_ja.dic'

with urllib.request.urlopen(url) as dl_file:
    with open(file_path, 'wb') as out_file:
        out_file.write(dl_file.read())

#Lesen Sie das Wörterbuch
dic = pd.read_csv('/content/pn_ja.dic', sep = ':', encoding= 'shift_jis', names = ('word','reading','Info1', 'PN'))

print(dic)

Das Ausführungsergebnis ist wie folgt.

       word reading Info1        PN
0 Ausgezeichnet ausgezeichnet Verb 1.000000
1 gutes gutes Adjektiv 0.999995
2 Freut euch Freudiges Verb 0.999979
3 Lob Lob Verb 0.999979
4 Medetai Medetai Adjektiv 0.999645
...     ...     ...   ...       ...
55120 Nein Nein Hilfsverb-0.999997
55121 Schrecklich schreckliche Adjektive-0.999997
55122 Krankheitsnomenklatur-0.999998
55123 Stirb ohne Verb-0.999999
55124 Schlechte schlechte Adjektive-1.000000

[55125 rows x 4 columns]

Installieren Sie als Nächstes Mecab.

(Hinzugefügt um 19:00 Uhr am 18.09.2020) Der Autor von mecab-python3 wies darauf hin, dass es nicht erforderlich ist, mecab, libmecab-dev und ipadic vor der Installation von mecab-python3 mit Eignung zu installieren, daher werde ich das Problem beheben.

!pip install mecab-python3
!pip install unidic-lite

Modellbildung und Textanalyse mit Word2vec

Konvertieren Sie den zu analysierenden Text in separaten Text und speichern Sie ihn zum Lernen mit word2vec. Folgen Sie den unteren Schritten. (1) Laden Sie die Textdaten von "Bo-chan" herunter und lesen Sie sie, um eine Textanalyse für Natsume Sosekis "Bo-chan" durchzuführen. (2) Entfernen Sie Rubin, Anmerkungen usw. ③ Extrahieren Sie Nomenklaturen, Adjektive und Verben aus dem Text von "Bo-chan", entfernen Sie Zahlen und nicht unabhängige Wörter, konvertieren Sie sie in "separates Schreiben" und konvertieren Sie sie in eine Datei namens tf.txt.

from collections import Counter
import MeCab    #Lesen Sie MeCab
import zipfile
import os.path,glob
import re

#Geben Sie die URL von "Bochan" an.
url = 'https://www.aozora.gr.jp/cards/000148/files/752_ruby_2438.zip'

#Name der Zip-Datei speichern
file_path = 'temp.zip'

#Öffnen Sie die Datei des Jungen und löschen Sie die gelesene Datei
with urllib.request.urlopen(url) as dl_file:
    with open(file_path, 'wb') as out_file:
        out_file.write(dl_file.read())
        with zipfile.ZipFile(file_path) as zf:
            listfiles = zf.namelist()
            zf.extractall()

os.remove(file_path)

# shift_Lesen Sie mit jis
with open(listfiles[0], 'rb') as f:
    text = f.read().decode('shift_jis')

#Entfernen von Rubin, Anmerkungen usw.
text = re.split(r'\-{5,}', text)[2]
text = re.split(r'Unteres Buch:', text)[0]
text = re.sub(r'《.+?》', '', text)
text = re.sub(r'[#.+?]', '', text)
text = text.strip()

#Bereiten Sie die Verwendung von MeCab vor
tagger = MeCab.Tagger()

#Fehler, wenn nicht initialisiert
tagger.parse("")

#Morphologische Analyse mit NMeCab
node = tagger.parseToNode(text)
word_list_raw = []
result_dict_raw = {}
#Extrahieren Sie Nomenklatur, Adjektive und Verben
wordclass_list = ['Substantiv','Adjektiv','Verb']
#Ausgeschlossen sind Zahlen, Nichtunabhängigkeit, Synonyme und Suffixe
not_fine_word_class_list = ["Nummer", "Nicht unabhängig", "Gleichbedeutend","Suffix"]

while node:
    #Mehr Informationen bekommen
    word_feature = node.feature.split(",")
    #Holen Sie sich Wörter (im Prinzip Grundform)
    word = node.surface
    #Holen Sie sich Teil Texte
    word_class = word_feature[0]
    fine_word_class = word_feature[1]
    #Geben Sie an, was aus dem Teil extrahiert und was ausgeschlossen werden soll
    if ((word not in ['', ' ','\r', '\u3000']) \
        and (word_class in wordclass_list) \
        and (fine_word_class not in not_fine_word_class_list)):
        #Wortliste
        word_list_raw.append(word)
        result_dict_raw[word] = [word_class, fine_word_class]
    #Fahren Sie mit dem nächsten Wort fort
    node = node.next
print(word_list_raw)

wakachi_text = ' '.join(word_list_raw);

#Name der Wakachi-Datei speichern
file2_path = 'tf.txt'

with open(file2_path, 'w') as out_file:
    out_file.write(wakachi_text)

print(wakachi_text)

Das Ausführungsergebnis ist wie folgt.

['einer', 'Die Übergabe', 'Waffenlose Waffe', 'Kleines Angebot', 'Zeit', 'Verlust', 'Shi', 'Ist', 'Schule',…
Handwaffe eines Elternteils, kleiner Dienst, verlorene Schule, Zeit- und Minutenschule, Springen nach unten ...

Als nächstes folgt die Konstruktion des Modells durch word2vec, die den Hauptteil dieses Artikels darstellt.

from gensim.models import word2vec
import logging

logging.basicConfig(format='%(asctime)s : %(levelname)s : %(message)s', level=logging.INFO)
sentence_data = word2vec.LineSentence('tf.txt')
model_bochan = word2vec.Word2Vec(sentence_data,
                         sg=1,        # Skip-gram
                         size=100,    #Anzahl der Dimensionen
                         min_count=5, # min_Verwerfen Sie Wörter, die weniger als gezählt wurden
                         window=12,   #Maximale Anzahl von Wörtern im Kontext
                         hs=0,        #Hierarchie Softmax(0 für negative Abtastung)
                         negative=5,  #Negative Abtastung
                         iter=10      #Anzahl der Epochen
                         )

model_bochan.save('test.model')

Importieren Sie das word2vec des Gensim-Moduls und erstellen Sie das Modell mit Word2Vec.

In word2vec stehen zwei Lernmodelle zur Verfügung.

Ich werde diese beiden Erklärungen weglassen, aber da in den Unterrichtsmaterialien das Sprunggramm verwendet wird, wird das Sprunggramm entsprechend verwendet. (Im Allgemeinen zeigt das Überspringen-Gramm eine bessere Leistung in CBOW und Überspringen-Gramm.)

Die Anzahl der Dimensionen des Wortvektors entspricht der Standardeinstellung, ist jedoch auf 100 festgelegt. Die Bedingung für das Verwerfen von Wörtern besteht darin, Wörter zu ignorieren, die weniger als fünfmal vorkommen. Die maximale Anzahl von Wörtern vor und nach der Erkennung als Kontext beträgt 12.

Es gibt zwei Algorithmen, die das Lernen beschleunigen. -Hierarchical Softmax -Negative Sampling Ich werde diese beiden Erklärungen weglassen. Ich verwende hier Negative Sampling.

Diese Erklärung ist http://tkengo.github.io/blog/2016/05/09/understand-how-to-learn-word2vec/ Ist detailliert.

Die Anzahl der Korpusiterationen wird mit 10 angegeben. Dies ist die Anzahl der Epochen, die angeben, wie oft Trainingsdaten vom neuronalen Netzwerk trainiert werden.

Dadurch konnten wir das Modell bauen.

Schauen wir uns als nächstes die Ähnlichkeit der Wörter sowie die Unterrichtsmaterialien an. Schlage das Wort rot nach.

model   = word2vec.Word2Vec.load('/content/test.model')
results = model.most_similar(positive=['rot'], topn=100)

for result in results:
    print(result[0], '\t', result[1])

Das Ausführungsergebnis ist wie folgt.

:
2020-09-16 12:30:12,986 : INFO : precomputing L2-norms of word weight vectors
Hemd 0.9854607582092285
Ärgerlich 0.9401918053627014
Vorname 0.9231084585189819
Gorki 0.9050831198692322
Kenne 0.8979452252388
Schonend 0.897865891456604
0 zustimmen.8932155966758728
Russland Aya 0.8931306004524231
Madonna 0.890703558921814
:

Wie oben erwähnt, stellte sich heraus, dass die Zeichen wie rote Hemden an die Spitze kamen. Als nächstes subtrahieren wir als Beispiel für das Subtrahieren der Elemente des Modells "Shirt" von "Madonna".

model = word2vec.Word2Vec.load('/content/test.model')

results = model.most_similar(positive=['Madonna'], negative=['Hemd'], topn=100)
for result in results:
    print(result[0], '\t', result[1])

Das Ausführungsergebnis ist wie folgt.

:
INFO : precomputing L2-norms of word weight vectors
Stimme 0.2074282020330429
Geisha 0.1831434667110443
Knödel 0.13945674896240234
Unterhaltung 0.13744047284126282
Tenfura 0.11241232603788376
Batter 0.10779635608196259
Lehrer 0.08393052220344543
Geist 0.08120302855968475
Freundlichkeit 0.0712042897939682
:

Indem wir das Element Hemd von Madonna subtrahierten, konnten wir Elemente wie Stimme, Lehrer, Geisha und Freundlichkeit extrahieren.

Im Folgenden wird das Addieren und Subtrahieren von Elementen durch word2vec detailliert beschrieben. https://www.pc-koubou.jp/magazine/9905

Einfache Emotionsanalyse per PN-Tabelle

Eine Emotionsanalyse ist sogar mit Word2Vec möglich, indem der Abstand zu den Hauptbegriffen der Emotion ermittelt wird. Hier möchte ich jedoch mit dem oben gelesenen Emotionswörterbuch (PN-Tabelle) wie im Lehrmaterial analysieren.

Konvertieren Sie zunächst das Wörterbuch vom Datenrahmentyp in den Diktattyp, um die Handhabung zu vereinfachen.

dic2 = dic[['word', 'PN']].rename(columns={'word': 'TERM'})

#Konvertieren Sie die PN-Tabelle vom Datenrahmen in den Diktattyp
word_list = list(dic2['TERM'])
pn_list = list(dic2['PN'])  #Die Art des Inhalts ist numpy.float64

pn_dict = dict(zip(word_list, pn_list))

print(pn_dict)

Das Ausführungsergebnis ist wie folgt.

{'Ausgezeichnet': 1.0, 'gut': 0.9999950000000001, 'Jubeln': 0.9999790000000001, 'loben': 0.9999790000000001, 'Herzliche Glückwünsche': 0.9996450000000001,…

Positive Terme werden auf einen Wert nahe 1 und negative Terme auf einen Wert nahe -1 gesetzt.

Nehmen Sie als nächstes die Nomenklatur und Adjektive aus "Bochan" und entfernen Sie die Zahlen und Suffixe. Versuchen Sie, positive und negative Wörter anzuzeigen, indem Sie eine Worthäufigkeitstabelle und ein Emotionswörterbuch kombinieren.

#Bereiten Sie die Verwendung von MeCab vor
tagger = MeCab.Tagger()

#Fehler, wenn nicht initialisiert
tagger.parse("")

#Morphologische Analyse mit NMeCab
node = tagger.parseToNode(text)
word_list_raw = []
extra_result_list = []
#Extrahieren Sie Nomenklatur, Adjektive und Verben
wordclass_list = ['Substantiv','Adjektiv']
#Ausgeschlossen sind Zahlen, Nichtunabhängigkeit, Synonyme und Suffixe
not_fine_word_class_list = ["Nummer","Suffix", "Nicht unabhängig"]

while node:
    #Mehr Informationen bekommen
    word_feature = node.feature.split(",")
    #Holen Sie sich Wörter (im Prinzip Grundform)
    word = node.surface
    #Holen Sie sich Teil Texte
    word_class = word_feature[0]
    fine_word_class = word_feature[1]
    #Geben Sie an, was aus dem Teil extrahiert und was ausgeschlossen werden soll
    if ((word not in ['', ' ','\r', '\u3000']) \
        and (word_class in wordclass_list) \
        and (fine_word_class not in not_fine_word_class_list)):
        #Wortliste
        word_list_raw.append(word)
    #Fahren Sie mit dem nächsten Wort fort
    node = node.next

freq_counterlist_raw = Counter(word_list_raw)
dict_freq_raw = dict(freq_counterlist_raw)

extra_result_list = []
for k, v in dict_freq_raw.items():
    if k in pn_dict:
        extra_result_list.append([k, v, pn_dict[k]])

extra_result_pn_sorted_list = sorted(extra_result_list, key=lambda x:x[2], reverse=True)
print("Positive Worte")
display(extra_result_pn_sorted_list[:10])
print("Negative Wörter")
display(extra_result_pn_sorted_list[-10:-1])

Das Ausführungsergebnis ist wie folgt.

Positive Worte
[['Herzliche Glückwünsche', 1, 0.9996450000000001],
 ['gut', 2, 0.9993139999999999],
 ['glücklich', 1, 0.998871],
 ['Sortiment', 1, 0.998208],
 ['Anerkennung', 2, 0.997308],
 ['Gerechtigkeit', 1, 0.9972780000000001],
 ['Beeindruckt', 10, 0.997201],
 ['Entschuldigung', 1, 0.9967889999999999],
 ['Förderung', 1, 0.9959040000000001],
 ['Angemessenheit', 1, 0.995553]]
Negative Wörter
[['Rau', 13, -0.9993340000000001],
 ['eng', 7, -0.999342],
 ['Kalt', 1, -0.999383],
 ['Bestrafung', 5, -0.9994299999999999],
 ['Feind', 3, -0.9995790000000001],
 ['schmerzlich', 1, -0.9997879999999999],
 ['Arm', 6, -0.9998309999999999],
 ['Abwesend', 338, -0.9999969999999999],
 ['krank', 6, -0.9999979999999999]]

Das zweite Element der Liste ist die Häufigkeit des Auftretens (Häufigkeit), und das dritte ist ein Wert, der anzeigt, ob es positiv oder negativ ist. Lassen Sie uns abschließend sehen, welches der positiven und negativen Wörter häufig für "Bo-chan" als Ganzes verwendet wird. (Die Häufigkeit des Auftretens von Wörtern wird jedoch nicht gemäß den Unterrichtsmaterialien verwendet.)

pos_n = sum(x[2] > 0 for x in extra_result_pn_sorted_list)

print(pos_n)

neg_n = sum(x[2] < 0 for x in extra_result_pn_sorted_list)

print(neg_n)

Das Ausführungsergebnis ist wie folgt.

182
1914

Ich fand heraus, dass in "Bo-chan" oft negative Wörter verwendet werden.

Kommentar

In Bezug auf die Verarbeitung in Bezug auf word2vec wurden mit Python und R keine ähnlichen Ergebnisse erzielt. Daher werde ich versuchen, die Ursache zu finden, wenn ich es mir in Zukunft leisten kann.

Quellcode

https://gist.github.com/ereyester/101ae0da17e747b701b67fe9fe137b84

Recommended Posts

Text Mining von word2vec usw. von Python ([Informationen zur Informationsabteilung der High School II] Unterrichtsmaterialien für die Lehrerausbildung)
[Informationen I / Information II der Informationsabteilung der High School] Zusammenfassung der Unterrichtsmaterialien für die Lehrerausbildung durch Python
Binäre Klassifizierung nach Entscheidungsbaum nach Python ([Informationen zur Informationsabteilung der High School II] Unterrichtsmaterialien für die Lehrerausbildung)
Klassifizierung nach der k-Nachbarschaftsmethode (kNN) nach Python ([Informationen zur Informationsabteilung der High School II] Unterrichtsmaterialien für die Lehrerausbildung)
Datenanalyse durch Clustering mit der k-means-Methode (Python) ([Informationen zur Informationsabteilung der High School II] Unterrichtsmaterialien für die Lehrerausbildung)
[Informationen der High School Information Department I] Unterrichtsmaterialien für die Lehrerausbildung: Datenformat und Visualisierung (Python)
Hauptkomponentenanalyse mit Python (Scikit-Lernversion, Pandas & Numpy-Version) ([Informationen zur Informationsabteilung der High School II] Unterrichtsmaterialien für die Lehrerausbildung)
Objekterkennung mit YOLO (Python) ([Informationen zur Informationsabteilung der High School II] Unterrichtsmaterialien für die Lehrerausbildung)
[Informationen zu Richtlinien für das Lernen an Gymnasien I] Unterrichtsmaterialien für die Lehrerausbildung: Implementierung der Huffman-Methode durch Python
Web-Lehrmaterialien zum Erlernen von Python