Ich habe mit Doc2Vec nach ähnlichen Sätzen gesucht, daher werde ich die Implementierung vorstellen.
Damit ein Computer eine natürliche Sprache verarbeiten kann, muss er zunächst einen Wert haben, mit dem die menschliche Sprache umgehen kann. [Word2Vec] existiert als Methode zur Vektorisierung der Bedeutung von Wörtern. Für Details ist das Linkziel sehr leicht zu verstehen, aber grob gesagt wird dieses Wort durch eine Liste von n Wörtern vorher und nachher ausgedrückt. Auf diese Weise werden beispielsweise "Hund" und "Katze" in ähnlichen Zusammenhängen verwendet und können als ähnlich "bedeutend" angesehen werden. Doc2Vec ist eine Anwendung von Word2Vec zum Vektorisieren von Sätzen.
Die folgenden zwei Funktionen werden diesmal mit Doc2Vec realisiert.
Als Beispiel habe ich den Text von Aozora Bunko verwendet. Der in diesem Artikel verwendete Code lautet [Veröffentlicht auf GitHub] [GitHub]. (Der zum Lernen verwendete Text wurde ebenfalls komprimiert, aber bitte beachten Sie, dass er groß ist.)
Bitte verwenden können.
Prozess nach dem Fluss von.
import os
import sys
import MeCab
import collections
from gensim import models
from gensim.models.doc2vec import LabeledSentence
Importieren Sie zunächst die erforderlichen Bibliotheken.
def get_all_files(directory):
for root, dirs, files in os.walk(directory):
for file in files:
yield os.path.join(root, file)
Ruft alle Dateien unter dem angegebenen Verzeichnis ab.
def read_document(path):
with open(path, 'r', encoding='sjis', errors='ignore') as f:
return f.read()
def trim_doc(doc):
lines = doc.splitlines()
valid_lines = []
is_valid = False
horizontal_rule_cnt = 0
break_cnt = 0
for line in lines:
if horizontal_rule_cnt < 2 and '-----' in line:
horizontal_rule_cnt += 1
is_valid = horizontal_rule_cnt == 2
continue
if not(is_valid):
continue
if line == '':
break_cnt += 1
is_valid = break_cnt != 3
continue
break_cnt = 0
valid_lines.append(line)
return ''.join(valid_lines)
Ich denke, dass sich die Verarbeitung hier je nach Zielsatz ändern wird. Dieses Mal habe ich den Erklärungsteil des Textes vor und nach dem Text ignoriert. Es ist unklar, inwieweit dies die Genauigkeit überhaupt beeinflusst.
def split_into_words(doc, name=''):
mecab = MeCab.Tagger("-Ochasen")
valid_doc = trim_doc(doc)
lines = mecab.parse(doc).splitlines()
words = []
for line in lines:
chunks = line.split('\t')
if len(chunks) > 3 and (chunks[3].startswith('Verb') or chunks[3].startswith('Adjektiv') or (chunks[3].startswith('Substantiv') and not chunks[3].startswith('Substantiv-Nummer'))):
words.append(chunks[0])
return LabeledSentence(words=words, tags=[name])
def corpus_to_sentences(corpus):
docs = [read_document(x) for x in corpus]
for idx, (doc, name) in enumerate(zip(docs, corpus)):
sys.stdout.write('\r Vorverarbeitung{} / {}'.format(idx, len(corpus)))
yield split_into_words(doc, name)
Nimmt einen Satz aus einer Datei und zerlegt ihn in Wörter. Um die Genauigkeit zu verbessern, scheinen die zum Lernen verwendeten Wörter manchmal nur Nomenklaturen zu sein. Dieses Mal habe ich Verben, Adjektive und Nomenklaturen (außer Zahlen) verwendet.
def train(sentences):
model = models.Doc2Vec(size=400, alpha=0.0015, sample=1e-4, min_count=1, workers=4)
model.build_vocab(sentences)
for x in range(30):
print(x)
model.train(sentences)
ranks = []
for doc_id in range(100):
inferred_vector = model.infer_vector(sentences[doc_id].words)
sims = model.docvecs.most_similar([inferred_vector], topn=len(model.docvecs))
rank = [docid for docid, sim in sims].index(sentences[doc_id].tags[0])
ranks.append(rank)
print(collections.Counter(ranks))
if collections.Counter(ranks)[0] >= PASSING_PRECISION:
break
return model
Die Parameter für das Lernen werden in den Modellen festgelegt. Doc2Vec-Teil.
alpha Je höher es ist, desto schneller konvergiert es, aber wenn es zu hoch ist, divergiert es. Je niedriger der Wert, desto höher die Genauigkeit, aber desto langsamer die Konvergenz.
sample Zu häufig vorkommende Wörter sind wahrscheinlich bedeutungslose Wörter und werden möglicherweise ignoriert. Stellen Sie diesen Schwellenwert ein.
min_count Im Gegensatz zum Beispiel sind zu seltene Wörter möglicherweise nicht geeignet, um den Satz zu beschreiben, und werden möglicherweise ignoriert. Diesmal habe ich jedoch alle Wörter ins Visier genommen.
for x in range(30):
print(x)
model.train(sentences)
ranks = []
for doc_id in range(100):
inferred_vector = model.infer_vector(sentences[doc_id].words)
sims = model.docvecs.most_similar([inferred_vector], topn=len(model.docvecs))
rank = [docid for docid, sim in sims].index(sentences[doc_id].tags[0])
ranks.append(rank)
print(collections.Counter(ranks))
if collections.Counter(ranks)[0] >= PASSING_PRECISION:
break
return model
Wir lernen und bewerten in diesem Teil. Die Bewertung wird durchgeführt, indem in 100 der gelernten Sätze nach ähnlichen Sätzen gesucht wird und gezählt wird, wie oft der ähnlichste Satz Sie selbst waren. Dieses Mal ist das Lernen 94 Mal oder öfter beendet. (Weil ich mehrmals versucht habe, es zu drehen und die Genauigkeit sich nicht mehr verbessert hat)
model.save(OUTPUT_MODEL)
OUTPUT_MODEL enthält den Ausgabepfad.
model = models.Doc2Vec.load('doc2vec.model')
def search_similar_texts(words):
x = model.infer_vector(words)
most_similar_texts = model.docvecs.most_similar([x])
for similar_text in most_similar_texts:
print(similar_text[0])
Da Doc2Vec gleichzeitig auch Wörter (Word2Vec) vektorisiert, habe ich versucht, nach ähnlichen Wörtern zu suchen.
def search_similar_words(words):
for word in words:
print()
print(word + ':')
for result in model.most_similar(positive=word, topn=10):
print(result[0])
model = models.Doc2Vec.load('doc2vec.model')
def search_similar_texts(path):
most_similar_texts = model.docvecs.most_similar(path)
for similar_text in most_similar_texts:
print(similar_text[0])
Ich habe versucht, eine Suche nach ähnlichen Sätzen in Doc2Vec zu implementieren. Ich hoffe, Sie finden es hilfreich.
Nur der Fehler, der in meiner Umgebung aufgetreten ist, aber ich werde die Lösung veröffentlichen.
Intel MKL FATAL ERROR: Cannot load libmkl_avx2.so or libmkl_def.so.
conda update numpy
gelöst.export KMP_AFFINITY = disabled
.[Word2Vec: Erstaunliche Kraft des Wortvektors, die den Erfinder überrascht] [Word2Vec] [Tutorial zur Berechnung der Dokumentähnlichkeit mithilfe des Doc2Vec-Mechanismus und von gensim] [Tutorial] [Was passiert, wenn Sie mit einem Pixiv-Roman maschinell lernen [trainierte Modelldaten werden verteilt]] [pixiv] [Verwenden Sie TensorFlow, um den Bewegungsunterschied in Abhängigkeit von der Lernrate zu überprüfen.] [Lernrate] [models.doc2vec – Deep learning with paragraph2vec][doc2vec]
<! - Link-> [Word2Vec]:https://deepage.net/bigdata/machine_learning/2016/09/02/word2vec_power_of_word_vector.html [GitHub]:https://github.com/Foo-x/doc2vec-sample [Tutorial]: https://deepage.net/machine_learning/2017/01/08/doc2vec.html [pixiv]:http://inside.pixiv.net/entry/2016/09/13/161454 [Lernrate]: http://qiita.com/isaac-otao/items/6d44fdc0cfc8fed53657 [doc2vec]:https://radimrehurek.com/gensim/models/doc2vec.html
Recommended Posts