[PYTHON] Vektorisieren Sie Sätze und suchen Sie nach ähnlichen Sätzen

Ich habe mit Doc2Vec nach ähnlichen Sätzen gesucht, daher werde ich die Implementierung vorstellen.

Was ist Doc2Vec?

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.

Implementierungsbeispiel

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.)

Umgebung

Bitte verwenden können.

Lernen

  1. Holen Sie sich die Textdatei
  2. Holen Sie sich Text aus der Datei
  3. Entfernen Sie unnötige Teile aus dem Text
  4. In Worte zerlegen
  5. Lernen Sie mit Doc2Vec
  6. Trainingsdaten ausgeben

Prozess nach dem Fluss von.

1. Holen Sie sich die Textdatei

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.

2. Holen Sie sich Text aus der Datei

def read_document(path):
    with open(path, 'r', encoding='sjis', errors='ignore') as f:
        return f.read()

3. Entfernen Sie unnötige Teile aus dem Text

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.

4. In Worte zerlegen

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.

5. Lernen Sie mit Doc2Vec

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)

6. Trainingsdaten ausgeben

model.save(OUTPUT_MODEL)

OUTPUT_MODEL enthält den Ausgabepfad.

Suche Sätze nach Wort

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])

Beispiel für die Suche nach "Katze"

猫.PNG

Beispiel für die Suche nach "Schnee"

雪.PNG

Suche nach ähnlichen Sätzen

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])

Ein Beispiel für die Suche nach "Ich bin eine Katze" von Soseki Natsume

夏目漱石.PNG

Ein Beispiel für die Suche nach "menschlicher Disqualifikation" von Osamu Tadashi

太宰治.PNG

Zusammenfassung

Ich habe versucht, eine Suche nach ähnlichen Sätzen in Doc2Vec zu implementieren. Ich hoffe, Sie finden es hilfreich.

Wenn ein Fehler auftritt

Nur der Fehler, der in meiner Umgebung aufgetreten ist, aber ich werde die Lösung veröffentlichen.

Referenz

[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

Vektorisieren Sie Sätze und suchen Sie nach ähnlichen Sätzen
Kausales Denken und kausale Suche von Python (für Anfänger)
Ungefähre Suche nach dem nächsten Nachbarn für eine ähnliche Bildanalyse (für Anfänger) (1)
Suchen Sie rekursiv nach Dateien und Verzeichnissen in Python und geben Sie sie aus
Interaktive Konsolenanwendung für die Adress- und Postleitzahlensuche
Probieren Sie die ähnliche Suche von Image Search mit Python SDK [Search] aus.
Durchsuche den pandas.DataFrame mit einer Variablen und erhalte die entsprechende Zeile.
Suchliste nach doppelten Elementen
Suchen Sie nach dem Namen der OpenCV-Funktion
Suchen Sie nach Zeichenfolgen in Dateien
WordNet-Struktur und Synonym-Suche
Fallstricke und Problemumgehungen für pandas.DataFrame.to_sql
Suchen Sie in numpy.array nach True
[Python] Suche nach Tiefenpriorität und Suche nach Breitenpriorität
Suche nach Zeichenketten in Dateien [Vergleich zwischen Bash und PowerShell]
Speichern, Wiederherstellen und Abfragen der Suche von Python-Klasseninstanzen mit mongodb