[PYTHON] Einführung in Word2Vec, die auch Katzen verstehen können

Motivation

Schön dich kennenzulernen, mein Name ist pyaNotty. Dies ist der erste Beitrag. Vor kurzem hatte ich die Gelegenheit, mit MeCab und Keras in Kontakt zu treten, deshalb wollte ich etwas in natürlicher Sprache ausprobieren. Ich höre, dass verteilte Ausdrücke mit Word2Vec häufig für die Verarbeitung natürlicher Sprache verwendet werden, insbesondere für die Satzgenerierung mit LSTM. Dieses Mal werde ich versuchen, einen verteilten Ausdruck von Wörtern zu erstellen, die mit Word2Vec dem LSTM-Modell zugeführt werden können.

Selbst der Autor, der nur die Intelligenz einer Katze besitzt, ist leicht zu handhaben.

Was ist Word2Vec?

Ein Modell zum Konvertieren von Wörtern in Vektoren.

Wenn Sie ein LSTM-Modell oder etwas mit Text trainieren, können Sie das Modell nicht mit rohen Zeichenfolgen füttern. Daher ist es notwendig, den Satz in einen numerischen Ausdruck umzuwandeln. Zum Beispiel wird im Fall des Satzes "Dies ist ein Stift" nach dem Zerlegen der Teile in Wörter wie ['Dies ist', 'Stift', 'ist'] jedes Wort in einen numerischen Ausdruck umgewandelt.

Am einfachsten ist es, jedem Wort eine eindeutige ID zu geben. Wenn Sie ['das ist', 'Stift', 'ist'] → [1, 2, 3] usw. konvertieren, können Sie in das Ichiou-Modell gelangen. In diesem Zustand funktioniert das Training des Modells jedoch nicht, da die Beziehungen zwischen Wörtern nicht ausgedrückt werden können.

Daher ist Word2Vec eine Methode zum Erfassen eines numerischen Ausdrucks, der die Beziehungen zwischen Wörtern enthält. Sie können es verwenden, um den Abstand zwischen "Stift" und "Apfel" zu ermitteln oder um "Stift" + "Apfel" = "Ananas" zu berechnen. Der Autor ist verwirrt, und wenn ich hier anfange, eine Geschichte zu schreiben, wird der Artikel von selbst ausgefüllt. Weitere Informationen finden Sie unter Dieses Buch % 83% AD% E3% 81% 8B% E3% 82% 89% E4% BD% 9C% E3% 82% 8BTiefenlernen-% E2% 80% 95% E8% 87% AA% E7% 84% B6% E8% A8% 80% E8% AA% 9E% E5% 87% A6% E7% 90% 86% E7% B7% A8-% E6% 96% 8E% E8% 97% A4-% E5% BA% B7% Bitte beziehen Sie sich auf E6% AF% 85 / dp / 4873118360).

Korpuserstellung

Um ein Word2Vec-Modell zu erstellen, müssen Sie einen Korpus erstellen (grob gesagt eine Liste von Wörtern). Eine übliche Methode besteht darin, einen Korpus aus einer großen Menge von Text zu erstellen, der bei Wikipedia gesammelt wurde. Als Modell, das beispielsweise aus dem Wikipedia-Korpus erstellt wurde, wird japanischer Entitätsvektor im Web veröffentlicht. Ich bin.

Dieses Mal möchte ich Romanautor werden, also möchte ich den Text kratzen und einen Korpus erstellen. Da die dedizierte API für die Öffentlichkeit zugänglich ist, ist es einfach, Sätze zu sammeln. Lassen Sie es uns sofort implementieren. Implementiert in Python3.7.

import requests
import gzip
import pandas as pd
import datetime
import time

api_url="https://api.syosetu.com/novelapi/api/" 
df = pd.DataFrame()
endtime = int(datetime.datetime.now().timestamp())

interval = 3600*24
cnt = len(df)
while cnt < 100000:
  #Holen Sie sich den Titel und die Inhaltsangabe des Romans im Zeitbereich
  time_range = str(endtime - interval) + '-' + str(endtime)
  payload = {'out': 'json','gzip': 5,'order': 'new','lim': 500,
             'lastup': time_range,
             'of': 't-ua-s'}
  res = requests.get(api_url, params=payload).content
  r =  gzip.decompress(res).decode("utf-8") 

  df_temp = pd.read_json(r).drop(0)
  df = pd.concat([df, df_temp])

  #time_Bereich nach Intervall verschieben
  endtime -= interval
  cnt = len(df['title'].unique())
  time.sleep(2)

Aus der aktuellen Zeit habe ich den Titel und die Zusammenfassung der letzten 100.000 Romane erhalten. Aus den gesammelten Daten erstellen wir aus der Zusammenfassung einen Korpus. Speichern Sie zunächst die txt-Datei.

import pandas as pd

df = pd.read_csv('./data/titles.csv')
txt = ''

#Verbinden Sie ungefähr alle Synopsen
for i in range(len(df)):
    txt += df['story'][i]

with open('./data/story.txt', mode='w', encoding='utf-8') as f:
    f.write(txt)

Erstellen Sie einen Korpus aus der gespeicherten txt-Datei. Entfernen Sie nach dem Teilen mit MeCab unnötige Symbole und schreiben Sie in eine txt-Datei. Der Code basiert auf diesem Artikel.

import MeCab
import re
import os
import sys

mecab = MeCab.Tagger('-Ochasen -d C:\mecab-ipadic-neologd')

class Corpus:
    def __init__(self, text):
        self.text = text
        self.formated = ""
        self.corpus = []

        self.format()
        self.split()

        
    def split(self):
        node = mecab.parseToNode(str(self.formated))
        while node:
            PoS = node.feature.split(",")[0]

            if PoS not in "BOS/EOS":#Derjenige, der mit den Spezifikationen von Mecab herauskommt, stört
                self.corpus.append(node.surface)

            node = node.next

    def format(self):
        ret= re.sub(r'https?://[\w/:%#\$&\?\(\)~\.=\+\-…]+', "", self.text)#URL
        ret = re.sub(r"[0-9]+", "0", ret)#Nummer bis 0
        ret = re.sub(r"[!-/]", "", ret)#Symbol halber Breite
        ret = re.sub(r"[:-@]", "", ret)#Symbol halber Breite
        ret = re.sub(r"[[-`]", "", ret)#Symbol halber Breite
        ret = re.sub(r"[{|}-]", "", ret)#Symbol halber Breite
        ret = re.sub(r"[() * [] ... [] << >> = ~ "" + * ,. ・ _? !! / ◀ ▲:]", "", ret)#Symbol in voller Breite
        ret = re.sub("[\n]", "", ret)#Zeilenumbrüche, Leerzeichen
        ret = re.sub("[\u3000]", "", ret)

        self.formated = ret

    def rtn_corpus(self):
        ret = " ".join(self.corpus)
        return ret


input_file = "./data/story.txt"
output_file = "./data/corpus.txt"

with open(input_file, encoding='utf-8') as in_f:
    lines = in_f.readlines()
    with open(output_file, mode='w', encoding='utf-8') as out_f:
        for l in lines:
            text = Corpus(l).rtn_corpus()
            out_f.write(text + '')

Sie haben erfolgreich einen Korpus erstellt.

corpus.txt


Der Verlobte des Prinzen, Dalia, ist verzweifelt zu hören, dass der Prinz gute Beziehungen zu den einfachen Leuten hat, weil der Vater, der die königliche Macht regieren will, ihm sagt, dass Sie definitiv die Königin sein werden, aber Dalia merkt plötzlich, dass er erwachsen ist. Ich frage mich, ob es in Ordnung ist, sich zu verloben, und wenn wir nicht da wären, wäre dieses Land glücklicher, und wenn wir nicht wären, wäre es brillant verstreut wie die ekelhafte bösartige Tochter des Romans. Bitte beachten Sie, dass es typografische Fehler und unklare Sätze gibt, die häufig überarbeitet und geändert wurden. Obwohl der Titel Reverse Harlem lautet, verwendet die Heldin Reverse Harlem nicht, aber die Bösewichtstochter versteht ihn falsch als Reverse Harlem. Außerdem schrieb ich, dass nicht nur die Bösewichtstochter, sondern auch die anderen Charaktere in einer anderen Welt wiedergeboren wurden, aber ich änderte den Zeitplan und die Bösewichtstochter änderte die Einstellung der wiedergeborenen Person. Es tut mir leid für die häufigen Änderungen.\Chinatsu, der von einem großen Immobilienunternehmen abgestiegen war, um für eine Immobilienverwaltungsgesellschaft einer Tochtergesellschaft zu arbeiten, war deprimiert und machte sich an die Arbeit. Es war der schwebende Geist eines ehemaligen Bankiers, Takamura Genki, der neben mir saß. Chinatsu, von der bekannt war, dass sie eine Verfassung hat, in der Geister im Gespräch mit ihr gesehen werden können, wird leider als Ghost Property Manager ausgewählt.\Und der Geist eines ehemaligen Bankiers, der als schwebender Geist im Büro Genki besessen war, und der coole, gutaussehende Chef Harutaka werden für das Geistereigentum Chinatsu verantwortlich sein. Wenn Sie den Geist mit Geist berühren, wird die Vergangenheit des Geistes sein Gekaufte Spezialfähigkeit aktiviert Mit dieser Kraft erkennen sie die wahre Todesursache, während sie das Bedauern der Geister lösen. Ein solch okkultes Liebesgeheimnis Lloyd, der ein Ritter eines Landes war, ist der Wächter einer Prinzessin. Eines Tages stiegen die beiden in eine Kutsche, um an einem Tanz in einem Nachbarland teilzunehmen, aber der Ritter, der die Kutsche durch die Hände eines feindlichen Landes von einer Klippe fallen ließ, sagte, Kaburagi Shigure würde als nächstes aufwachen. Shigure Kaburagi, eine Schülerin, die als Frau wiedergeboren worden war, traf Rin Kiriyama, der sowohl in Bunbu als auch in Rin einen Schritt höher lag, und das Schicksal der beiden begann sich zu bewegen. Er verlor seine Mutter, als er jung war und an einer schweren Herzkrankheit litt. Im Garten verbringe ich den größten Teil meines Lebens einsam, aber ich habe den Sinn des Lebens verloren. Eines Tages traf ich ein Mädchen namens Amatsuka Nagisa. Ich fühlte mich von der Schönheit und Freundlichkeit von Nagisa angezogen. Ich war zum ersten Mal in Nagisa verliebt und habe meine Gedanken erbeten. Lotus hat den Sinn des Lebens wiedererlangt, aber Nagisa hat gestanden, dass ich bald sterben werde. Ich bin verzweifelt. Ein Lichtstrahl, der in die Sonne scheint, ein Licht, das aussieht wie die Sonne, das war die Sonne, Mahal-neechan, ich möchte deine Prinzessin sein, ich bin der ältere Maiharu und der jüngere Cousin, die Liebe zur Sonne und bis dahin. Eine traurige Liebesgeschichte Eine Geschichte über ein Mädchen mit einer besonderen Kraft, die ich evakuieren werde, weil sich meine Sicherheit verschlechtert hat. Shiro Sakamoto, ein Detektiv der Präfekturpolizei von Osaka, wird von einem krebskranken Arzt zu einer Woche Leben verurteilt. Zu diesem Zeitpunkt möchte er in Japan leben.

Auf diese Weise wird die Aufzählung der geteilten Wörter in der txt-Datei gespeichert.

Word2Vec-Modelltraining

Schließlich erstellen wir ein Word2Vec-Modell. Die Methode mit word2vec von gensim ist bequem und gut. Es endet wirklich in einem Augenblick.

from gensim.models import word2vec

#Laden Sie den Korpus, den Sie gerade erstellt haben
corpus = './data/corpus.txt'
sentences = word2vec.Text8Corpus(corpus)

#Trainiere das Modell
model = word2vec.Word2Vec(sentences,#Korpus zu verwenden
                          size=200,#Anzahl der Dimensionen des zu erstellenden Vektors
                          sg=0#skip-Ob Gramm verwendet werden soll,Diesmal geh mit cbow
                          )

#Modell speichern
model.wv.save('./narou.model')

Ich werde nur die Parameter für die Modellerstellung kurz erläutern. Der Parameter sg gibt die Methode an, die beim Erstellen des Modells verwendet werden soll. Erstellen Sie ein Modell mit CBOW mit sg = 0 und überspringen Sie ein Gramm mit sg = 1. CBOW ist eine Methode, um Wörter dazwischen aus umgebenden Wörtern abzuleiten. Wenn es einen Satz "Dies ist ein Stift" gibt, ist es ein Bild der Eingabe von "Dies ist" und "Ist" und der Ausgabe von "Stift". Überspringen-Gramm ist das Gegenteil von CBOW und leitet umgebende Wörter aus einem Wort ab. Daher werden in CBOW und Skip-Gram die Eingabeebene und die Ausgabeschicht so wie sie sind vertauscht. 機械学習殴り書き-20.jpg Entschuldigen Sie die grobe Zahl, bitte verzeihen Sie mir, weil ich alles tun werde.

Dies ist das Ende der Modellerstellung. Danke für deine harte Arbeit.

Versuche zu spielen

Nachdem Sie ein Modell erstellt haben, lassen Sie uns ein wenig damit spielen.

model.wv['Andere Welt']
array([-2.11708   ,  0.48667097,  1.4323529 ,  1.2636857 ,  3.7746162 ,
        1.3120568 ,  2.2951639 , -0.8711858 ,  1.1539211 , -0.54808956,
        0.6777047 ,  0.21446693, -1.3346114 ,  3.0864553 ,  2.8941932 ,
        0.78770447,  1.4938581 , -1.7187694 , -0.58673733,  1.3345109 ,
       -0.5837457 ,  1.1400971 , -1.3413094 , -1.1784658 ,  0.5038208 ,
        0.2184668 ,  0.7903634 ,  0.99530613,  1.1820349 , -0.39339375,
        1.1770552 ,  1.1574073 ,  0.8442716 , -1.5331408 , -1.3503907 ,
       -0.22193083, -1.2109485 ,  3.1873496 ,  1.5198792 , -0.3475026 ,
        1.1639794 ,  2.1614919 ,  1.44486   ,  1.4375949 , -0.12329875,
        0.76681995,  1.0177598 ,  0.15669581,  1.1294595 ,  0.6686    ,
       -2.159141  ,  2.169207  , -0.00955578,  0.3961775 ,  0.839961  ,
        0.05453613, -0.4493284 ,  2.4686203 ,  0.35897058,  0.6430457 ,
       -0.7321106 , -0.06844574,  1.1651453 ,  1.440661  , -1.9773052 ,
       -1.0753456 , -1.3506272 ,  0.90463066, -1.5573175 ,  3.1350327 ,
        2.821969  ,  1.6074497 , -0.03897483,  0.84363884,  2.4653218 ,
        0.65267706,  0.22048295,  2.229037  ,  0.8114238 , -2.0834744 ,
        0.47891453, -1.1666266 , -0.5350998 ,  0.25257212,  2.3054895 ,
       -1.2035478 ,  2.7664409 , -2.121225  ,  1.3237966 , -0.40595815,
       -0.69292945, -0.39868835,  0.22690924,  0.3353806 , -1.3963023 ,
        0.48296794,  1.5792748 , -1.4290403 , -0.7156262 ,  2.1010907 ,
        0.4076586 , -0.47208166,  1.3889042 ,  0.9942379 , -0.3618385 ,
        0.10046659, -2.8085515 , -0.12091257,  1.33154   ,  1.196143  ,
       -1.3222407 , -2.2687335 , -0.74325466, -0.6354738 ,  1.2630842 ,
       -0.98507017, -1.5422399 ,  2.0910058 , -0.71927756,  0.3105838 ,
        1.4744896 , -0.84034425,  1.3462327 ,  0.08759955,  0.29124606,
       -1.9146007 ,  1.361217  ,  2.059756  , -0.73954767, -0.8559703 ,
        1.9385318 ,  0.44165856,  0.76255304,  0.26668853,  2.135404  ,
        0.37146965,  0.17825744,  0.73358685, -0.40393773, -0.58863884,
        2.9904902 ,  0.5401901 , -0.90699816, -0.03270415,  1.4531562 ,
       -2.6180272 ,  0.03460709, -1.028743  , -1.1348175 ,  0.9340523 ,
       -1.8640583 , -0.68235844,  1.8670527 ,  0.6017655 , -1.0030158 ,
       -1.7779472 ,  0.5410166 , -0.54911584,  1.4723094 , -1.229491  ,
        1.768442  ,  0.41630363, -2.417083  , -0.46536174,  0.26779643,
        0.6326522 ,  1.2000504 ,  1.1760272 , -0.17639238,  1.1781607 ,
       -3.0334888 ,  0.93554455,  0.52397215, -0.4301726 ,  1.3797791 ,
       -3.2156737 , -0.9460046 , -0.32353514, -0.27070895, -0.01405313,
        0.78362066, -0.41299725, -1.148895  ,  1.810671  , -1.0644491 ,
       -1.2899619 , -1.2057134 , -0.43731746, -0.5561588 ,  0.18522681,
       -0.86407244,  0.6044319 ,  0.3605701 ,  1.167799  , -1.2906225 ,
       -0.41644478,  1.3338335 , -0.2976896 ,  0.56920403,  2.6792917 ],
      dtype=float32)

Auf diese Weise kann der gelernte Wortvektor als Array von Numpy abgerufen werden.

Da es sich um eine Vektordarstellung handelt, ist es natürlich möglich, verschiedene Operationen zwischen Vektoren durchzuführen. Lassen Sie uns einen Vektor finden, der dem anderen Welt-Havector ähnlich ist. Es scheint, dass die Ähnlichkeit ähnlicher Wortvektoren im Allgemeinen durch die Kosinusähnlichkeit gemessen wird. Die Kosinusähnlichkeit zwischen den beiden Wortvektoren $ \ boldsymbol {w} _1 $ und $ \ boldsymbol {w} _2 $ ist gegeben durch:

\mathrm{similarity}(\boldsymbol{w}_1, \boldsymbol{w}_2) = \frac{\boldsymbol{w}_1.\boldsymbol{w}_2}{|\boldsymbol{w}_1||\boldsymbol{w}_2|}

Da dies $ cos \ theta $ im euklidischen Raum darstellt, scheint es intuitiv so zu sein, dass die Kosinusähnlichkeit so ist, dass die beiden Wortvektoren in die gleiche Richtung zeigen.

Mit der Methode most_similar können Sie die Top-10-Wörter mit der höchsten Kosinusähnlichkeit abrufen.

model.wv.most_similar('Andere Welt')
[('In einer anderen Welt wiedergeboren', 0.6330794095993042),
 ('Eine andere Welt', 0.6327196359634399),
 ('Transfer in eine andere Welt', 0.5990908145904541),
 ('echte Welt', 0.5668200850486755),
 ('neue Welt', 0.5559623837471008),
 ('Anders', 0.5458788871765137),
 ('Welt', 0.5394454002380371),
 ('Modernes Japan', 0.5360320210456848),
 ('Außerirdische Welt', 0.5353666543960571),
 ('Diese Welt', 0.5082162618637085)]

Das Ergebnis war allgemein überzeugend.

Im Modell registrierte Wörter können mit index2word als Liste abgerufen werden.

import copy
index2word = copy.copy(model.wv.index2word)
index2word
['von',
 'Zu',
 'Zu',
 'Ist',
 'Ta',
 'Hand',
 'Aber',
 'Wann',
 'damit',
 'Shi',
 'Nana',
 'Ebenfalls',
 'ich',
 'Abwesend',
 'Re',
 'Machen',
 'Masu',

Standardmäßig stehen häufig verwendete Wörter an erster Stelle in der Liste. Da die Liste keine doppelten Wörter enthält, entspricht die Länge der Anzahl der Vokabeln, über die das Modell verfügt.

len(index2word)
41619

Es scheint, dass ungefähr 42.000 Wörter registriert sind.

Sie können den Index der Liste als Wort-ID verwenden.

index2word.index('Andere Welt')
31

Wenn eine andere Welt auf Platz 32 kommt, habe ich das Gefühl, dass es so sein wird.

Zusammenfassung

Das ist alles zum Erstellen eines Modells mit Word2Vec. Sobald ich den Korpus erstellt hatte, konnte ich leicht ein Modell erstellen, daher fand ich es sehr praktisch. Im nächsten Beitrag (falls vorhanden) möchte ich in der Lage sein, Sätze mit dem Vektormodell (vorläufig) zu generieren, das ich dieses Mal erstellt habe. Dann treffen wir uns wieder.

Recommended Posts

Einführung in Word2Vec, die auch Katzen verstehen können
Einführung in Python, die auch Affen verstehen können (Teil 1)
Einführung in Python, die auch Affen verstehen können (Teil 2)
[Für Anfänger] Super Einführung in neuronale Netze, die selbst Katzen verstehen können
Eine Einführung in Pandas, um zu lernen, während man leidet [Teil 1]
Einführung in Cython ohne tief zu gehen -2-
[Python] Verstehen, wie rekursive Funktionen verwendet werden
Verstehen Sie, wie man Django-Filter verwendet
[Für Anfänger] Super Einführung in neuronale Netze, die selbst Katzen verstehen können
Einführung in Private TensorFlow
Eine Einführung in die Python-Programmierung
Einführung in die Bayes'sche Optimierung
SIR-Modell, das auch Schüler der Mittelstufe verstehen können
Kalman Filter, den Sie verstehen können
Eine Einführung in Mercurial für Nicht-Ingenieure
Erste Schritte mit Python für Nicht-Ingenieure
[Python Tutorial] Eine einfache Einführung in Python
Eine Einführung in OpenCV für maschinelles Lernen
Rekursives neuronales Netzwerk: Eine Einführung in RNN
Eine Einführung in Python für maschinelles Lernen
Eine Einführung in die Objektorientierung - Geben Sie einem Objekt ein Kind.
Eine Einführung in Python für C-Sprachprogrammierer
Verstehe Word2Vec
Was ist ein Algorithmus? Einführung in den Suchalgorithmus] ~ Python ~
Eine Einführung in maschinelles Lernen für Bot-Entwickler
Eine Einführung in die objektorientierte Programmierung für Anfänger von Anfängern
Eine Einführung in die statistische Modellierung für die Datenanalyse
Sogar ein Affe kann verstehen! Über Absichten in discord.py!
Einführung in Python "Re" 1 Erstellen einer Ausführungsumgebung
Eine Einführung in die Sprachanalyse für Musik-Apps
Automatischer Browser-Betrieb, den auch Anfänger ausführen können
Grundlegendes zur Python for Pepper-Entwicklung. -Einführung in Python Box-
[Python] Einführung in das WEB-Scraping | Zusammenfassung der Methoden, die mit dem Webdriver verwendet werden können