web-dev-qa-db-de.com

Wie berechnet man die Satzähnlichkeit mit dem Word2vec-Modell von gensim mit Python?

Nach dem Gensim Word2Vec kann ich das Word2vec-Modell im gensim-Paket verwenden, um die Ähnlichkeit zwischen zwei Wörtern zu berechnen.

z.B.

trained_model.similarity('woman', 'man') 
0.73723527

Das Word2vec-Modell kann jedoch die Satzähnlichkeit nicht vorhersagen. Ich finde das LSI-Modell mit Satzähnlichkeit in gensim heraus, was aber nicht mit dem Word2vec-Modell kombiniert werden kann. Die Länge des Korpus jedes Satzes, den ich habe, ist nicht sehr lang (weniger als 10 Wörter). Gibt es einfache Wege, um das Ziel zu erreichen?

89
zhfkt

Dies ist eigentlich ein ziemlich herausforderndes Problem, das Sie fragen. Um eine Satzähnlichkeit zu berechnen, müssen Sie ein grammatikalisches Modell des Satzes erstellen, um äquivalente Strukturen zu verstehen (z. B. "er ging gestern zum Laden" und "gestern ging er zum Laden") Eigennamen, statistische Zusammenhänge/Zusammenhänge in vielen realen Textbeispielen finden usw.

Die einfachste Sache, die Sie versuchen könnten - obwohl ich nicht weiß, wie gut dies funktionieren würde und Sie sicherlich nicht die optimalen Ergebnisse erzielen würde - wäre, zunächst alle "Stopp" -Wörter (Wörter wie "the", "a") zu entfernen "usw. usw., die dem Satz nicht viel Bedeutung hinzufügen) und führen dann Word2vec für die Wörter in beiden Sätzen aus, summieren Sie die Vektoren in dem einen Satz, summieren Sie die Vektoren in dem anderen Satz und finden Sie den Unterschied zwischen die Summen Wenn Sie sie zusammenfassen, anstatt einen wortweisen Unterschied zu machen, unterliegen Sie zumindest nicht der Reihenfolge des Wortes. Davon abgesehen wird dies in vielerlei Hinsicht scheitern und ist auf keinen Fall eine gute Lösung (obwohl gute Lösungen für dieses Problem fast immer etwas NLP, maschinelles Lernen und andere Klugheit beinhalten).

Kurz gesagt, nein, es gibt keinen einfachen Weg, dies zu tun (zumindest nicht, um es gut zu machen).

70

Da Sie gensim verwenden, sollten Sie wahrscheinlich die doc2vec-Implementierung verwenden. doc2vec ist eine Erweiterung von Word2vec auf Phrasen-, Satz- und Dokumentebene. Es ist eine ziemlich einfache Erweiterung, die hier beschrieben wird

http://cs.stanford.edu/~quocle/paragraph_vector.pdf

Gensim ist Nizza, weil es intuitiv, schnell und flexibel ist. Das Tolle ist, dass Sie die vorgefertigten Word-Einbettungen von der offiziellen Word2vec-Seite abrufen können und die syn0-Schicht des Doc2Vec-Modells von gensim sichtbar gemacht wird, sodass Sie die Wort-Einbettungen mit diesen hochwertigen Vektoren säen können!

GoogleNews-Vectors-negative300.bin.gz

Ich denke, gensim ist definitiv das einfachste (und für mich bisher beste) Werkzeug, um einen Satz in einen Vektorraum einzubetten.

Es gibt andere Satz-zu-Vektor-Techniken als die oben in Le & Mikolovs Artikel vorgeschlagene. Socher und Manning aus Stanford sind sicherlich zwei der berühmtesten Forscher, die in diesem Bereich arbeiten. Ihre Arbeit basiert auf dem Prinzip der Komposition - die Semantik des Satzes stammt aus:

1. semantics of the words

2. rules for how these words interact and combine into phrases

Sie haben einige solcher Modelle vorgeschlagen (wie sie immer komplexer werden), wie Kompositionalität verwendet werden kann, um Repräsentationen auf Satzebene zu erstellen.

2011 - rekursiver Autoencoder entfalten (sehr vergleichsweise einfach. Beginnen Sie hier, wenn Sie interessiert sind)

2012 - Matrix-Vektor-Neuronales Netzwerk

2013 - neuronales Tensornetzwerk

2015 - Baum-LSTM

seine Papiere sind alle auf socher.org erhältlich. Einige dieser Modelle sind verfügbar, aber ich würde immer noch empfehlen, doc2vec von gensim. Zum einen ist der URAE 2011 nicht besonders mächtig. Darüber hinaus verfügt er über Gewichte, die für das Umschreiben von News-y-Daten geeignet sind. Mit dem von ihm bereitgestellten Code können Sie das Netzwerk nicht neu trainieren. Sie können auch nicht verschiedene Word-Vektoren austauschen, so dass Sie 2011 mit den Pre-Word2vec-Einbettungen von Turian stecken bleiben. Diese Vektoren liegen sicherlich nicht auf der Ebene von Word2vec oder GloVe.

Hat mit dem Tree LSTM noch nicht gearbeitet, aber es scheint vielversprechend zu sein!

tl; dr Ja, benutze doc2vec von gensim. Es gibt aber auch andere Methoden!

63
Willie

Wenn Sie Word2vec verwenden, müssen Sie den Durchschnittsvektor für alle Wörter in jedem Satz/Dokument berechnen und Cosinusähnlichkeit zwischen Vektoren verwenden:

import numpy as np
from scipy import spatial

index2Word_set = set(model.wv.index2Word)

def avg_feature_vector(sentence, model, num_features, index2Word_set):
    words = sentence.split()
    feature_vec = np.zeros((num_features, ), dtype='float32')
    n_words = 0
    for Word in words:
        if Word in index2Word_set:
            n_words += 1
            feature_vec = np.add(feature_vec, model[Word])
    if (n_words > 0):
        feature_vec = np.divide(feature_vec, n_words)
    return feature_vec

Ähnlichkeit berechnen:

s1_afv = avg_feature_vector('this is a sentence', model=model, num_features=300, index2Word_set=index2Word_set)
s2_afv = avg_feature_vector('this is also sentence', model=model, num_features=300, index2Word_set=index2Word_set)
sim = 1 - spatial.distance.cosine(s1_afv, s2_afv)
print(sim)

> 0.915479828613
27
tbmihailov

sie können den Distanzalgorithmus von Word Mover verwenden. Hier ist eine einfache Beschreibung von WMD .

#load Word2vec model, here GoogleNews is used
model = gensim.models.KeyedVectors.load_Word2vec_format('../GoogleNews-vectors-negative300.bin', binary=True)
#two sample sentences 
s1 = 'the first sentence'
s2 = 'the second text'

#calculate distance between two sentences using WMD algorithm
distance = model.wmdistance(s1, s2)

print ('distance = %.3f' % distance)

Ps .: Wenn Sie einen Fehler in Bezug auf die import pyemd library haben, können Sie ihn mit folgendem Befehl installieren:

pip install pyemd
19
Ehsan

Sobald Sie die Summe der beiden Sätze von Word-Vektoren berechnet haben, sollten Sie den Kosinus zwischen den Vektoren und nicht den Unterschied zwischen den Vektoren nehmen. Der Cosinus kann berechnet werden, indem das Punktprodukt der zwei Vektoren normiert wird. Daher ist die Wortzählung kein Faktor. 

16
Rani Nelken

Ich möchte die vorhandene Lösung aktualisieren, um den Leuten zu helfen, die die semantische Ähnlichkeit von Sätzen berechnen möchten.

Schritt 1:

Laden Sie das geeignete Modell mit gensim und berechnen Sie die Wortvektoren für Wörter im Satz, und speichern Sie sie als Wortliste

Schritt 2: Berechnen des Satzvektors

Die Berechnung der semantischen Ähnlichkeit zwischen Sätzen war zuvor schwierig, aber kürzlich wurde ein Artikel mit dem Titel " EINE EINFACHE, ABER BEWEGLICHE BASIS FÜR SENTENZ. _. EMBEDDINGS " vorgeschlagen, die einen einfachen Ansatz durch Berechnung des gewichteten Durchschnitts von Word nahe legt Vektoren im Satz und entfernen dann die Projektionen der Durchschnittsvektoren auf ihre erste Hauptkomponente. Hier ist die Gewichtung eines Wortes w a/(a ​​+ p(w)) mit einem Parameter und p(w) die (geschätzte) Wortfrequenz, die als glatte Umkehrfrequenz bezeichnet wird. Diese Methode arbeitet wesentlich besser.

Ein einfacher Code zum Berechnen des Satzvektors unter Verwendung von SIF (glatte Inversfrequenz) der in der Arbeit vorgeschlagenen Methode wurde here gegeben.

Schritt 3: Verwenden Sie sklearn cosine_similarity, laden Sie zwei Vektoren für die Sätze und berechnen Sie die Ähnlichkeit.

Dies ist die einfachste und effizienteste Methode zur Berechnung der Satzähnlichkeit.

8
Poorna Prudhvi

Ich verwende die folgende Methode und sie funktioniert gut ..__ Sie müssen zuerst einen POSTagger ausführen und dann Ihren Satz filtern, um die Stoppwörter (Determinanten, Konjunktionen, ...) zu entfernen. Ich empfehle TextBlob APTagger . Dann erstellen Sie ein Word2vec, indem Sie den Mittelwert jedes Word-Vektors im Satz verwenden. Die Methode " n_similarity" in Gemsim Word2vec führt genau dies durch, indem sie zwei zu übersetzende Wortgruppen zulässt.

8
lechatpito

Es gibt Erweiterungen von Word2Vec, die das Problem lösen sollen, längere Textstücke wie Phrasen oder Sätze zu vergleichen. Eines davon ist Absatz2vec oder Doc2vec.

"Verteilte Darstellungen von Sätzen und Dokumenten" http://cs.stanford.edu/~quocle/paragraph_vector.pdf

http://rare-technologies.com/doc2vec-tutorial/

6
Max

Ich habe die Methoden aus den vorherigen Antworten ausprobiert. Es funktioniert, aber der Hauptnachteil ist, dass je länger die Sätze sind, desto größer ist die Ähnlichkeit (um die Ähnlichkeit zu berechnen, verwende ich den Cosinus-Score der beiden mittleren Einbettungen von zwei Sätzen), da je mehr Wörter die positiveren semantischen Wirkungen haben wird dem Satz hinzugefügt. 

Ich dachte, ich sollte meine Meinung ändern und stattdessen die Satzeinbettung verwenden, wie in diesem Artikel und diesem studiert. 

3
lerner

Es gibt eine Funktion aus der Dokumentation eine Liste von Wörtern aufnehmen und ihre Ähnlichkeiten vergleichen.

s1 = 'This room is dirty'
s3 = 'dirty and disgusting room'

distance = model.wv.n_similarity(s1.lower().split(), s2.lower().split())
3
Astariul

Facebook Research Group hat eine neue Lösung namens InferSent .__ veröffentlicht. Ergebnisse und Code werden auf Github veröffentlicht. Es ist ziemlich großartig. Ich habe vor, es zu benutzen. https://github.com/facebookresearch/InferSent

ihre Arbeit https://arxiv.org/abs/1705.02364 Zusammenfassung: Viele moderne NLP-Systeme basieren auf Word-Einbettungen, die zuvor unbeaufsichtigt auf großen Korpora ausgebildet wurden, als Basisfunktionen . Die Bemühungen, Einbettungen für größere Textblöcke wie Sätze zu erhalten, waren jedoch nicht so erfolgreich. Mehrere Versuche, nicht überwachte Repräsentationen von Sätzen zu lernen, haben keine zufriedenstellende Leistung gezeigt, um allgemein akzeptiert zu werden. In diesem Beitrag zeigen wir, wie universelle Satzdarstellungen, die mit den überwachten Daten der Stanford Natural Language Inference-Datensätze trainiert werden, unüberwachte Methoden wie SkipThought-Vektoren bei einer Vielzahl von Übertragungsaufgaben durchweg übertreffen können. Ähnlich wie bei der Bildverarbeitung mithilfe von ImageNet Funktionen zur Verfügung gestellt werden, die dann auf andere Aufgaben übertragen werden können, zeigt unsere Arbeit die Eignung natürlicher Sprachinterferenz für die Übertragung von Lernen auf andere NLP-Aufgaben. Unser Encoder ist öffentlich verfügbar.

2
Ayman Salama

Gensim implementiert ein Modell namens Doc2Vec für Absatzeinbettung .

Es gibt verschiedene Tutorials, die als IPython-Notizbücher dargestellt werden:

Eine andere Methode würde sich auf Word2Vec und Word Mover's Distance (WMD) verlassen, wie in diesem Lernprogramm gezeigt:

Eine alternative Lösung wäre die Verwendung von Durchschnittsvektoren:

from gensim.models import KeyedVectors
from gensim.utils import simple_preprocess    

def tidy_sentence(sentence, vocabulary):
    return [Word for Word in simple_preprocess(sentence) if Word in vocabulary]    

def compute_sentence_similarity(sentence_1, sentence_2, model_wv):
    vocabulary = set(model_wv.index2Word)    
    tokens_1 = tidy_sentence(sentence_1, vocabulary)    
    tokens_2 = tidy_sentence(sentence_2, vocabulary)    
    return model_wv.n_similarity(tokens_1, tokens_2)

wv = KeyedVectors.load('model.wv', mmap='r')
sim = compute_sentence_similarity('this is a sentence', 'this is also sentence', wv)
print(sim)

Wenn Sie Tensorflow ausführen können, können Sie Folgendes versuchen: https://tfhub.dev/google/universal-sentence-encoder/2

0
Wok