Comment utiliser Gensim doc2vec avec des vecteurs de mots pré-formés?

j'ai récemment découvert l'ajout de doc2vec à Gensim. Comment puis-je utiliser des vecteurs de mots préformés (par exemple trouvés dans le site Web original de word2vec) avec doc2vec?

ou doc2vec obtient-il les vecteurs de mots à partir des mêmes phrases qu'il utilise pour la formation sur les vecteurs de paragraphe?

Merci.

25
demandé sur Stergios 2014-12-14 18:13:43

4 réponses

notez que le "DBOW" (dm=0) le mode de formation ne nécessite pas ou ne crée même pas de vecteurs de mots dans le cadre de la formation. Il apprend simplement des vecteurs de document qui sont bons pour prédire chaque mot à son tour (un peu comme le mode de formation de skip-gram de word2vec).

(avant gensim 0.12.0, il y avait le paramètre train_words mentionné dans un autre commentaire, que certains documents ont suggéré de co-entraîner des mots. Cependant, je ne crois pas que cela ait jamais vraiment fonctionné. À partir de gensim 0.12.0, il est le paramètre dbow_words, qui fonctionne pour sauter-gram mots de train simultané avec Doc-vecteurs DBOW. Notez que cela rend la formation plus long par un facteur lié à window. Donc, si vous n'avez pas besoin de mot de vecteurs, vous pouvez toujours désactiver ce.)

dans la méthode de formation" DM" (dm=1), les vecteurs de mots sont formés de façon inhérente au cours du processus avec les vecteurs doc, et sont susceptibles d'affecter également la qualité des vecteurs doc. Il est théoriquement possible de pré-initialiser le Vecteurs de mots à partir de données antérieures. Mais je ne connais aucune raison théorique ou expérimentale solide pour être sûr que cela améliorerait les vecteurs doc.

une expérience fragmentaire que j'ai menée dans ce sens a suggéré que l'entraînement doc-vector a commencé plus rapidement – de meilleures qualités prédictives après les premières passes – mais cet avantage s'est estompé avec plus de passes. Que vous teniez le mot vecteurs constants ou que vous les laissiez continuer à s'adapter à la nouvelle formation, il est également probable que vous considération importante... mais le choix peut dépendre de vos objectifs, de vos données et de la qualité/pertinence des vecteurs de mots préexistants.

(vous pourriez répéter mon expérience avec le intersect_word2vec_format() méthode disponible dans gensim 0.12.0, et essayer différents niveaux de rendre les vecteurs pré-chargés résistants à la nouvelle formation via le syn0_lockf valeurs. Mais rappelez-vous que c'est un territoire expérimental: les résultats de base de doc2vec ne dépendent pas, ou même s'améliorent nécessairement avec, le mot réutilisé vecteur.)

20
répondu gojomo 2018-05-17 14:53:22

Eh bien, j'utilise aussi Doc2Vec récemment. Et je pensais utiliser Lda résultat comme vecteur de mot et corriger ces vecteurs de mot pour obtenir un vecteur de document. Le résultat n'est pas très intéressant, bien que. Peut-être que c'est juste que mes données ne sont pas si bonnes. Le code est ci-dessous. Doc2Vec sauve des vecteurs de mots et des vecteurs de documents ensemble dans le dictionnaire doc2vecmodel.syn0. Vous pouvez modifier directement les valeurs du vecteur. Le seul problème peut être que vous avez besoin de savoir quelle position dans syn0 représente le mot ou document. Les vecteurs sont stockés dans l'ordre aléatoire dans le dictionnaire syn0.

import logging
logging.basicConfig(format='%(asctime)s : %(levelname)s : %(message)s', level=logging.INFO)
from gensim import corpora, models, similarities
import gensim
from sklearn import svm, metrics
import numpy

#Read in texts into div_texts(for LDA and Doc2Vec)
div_texts = []
f = open("clean_ad_nonad.txt")
lines = f.readlines()
f.close()
for line in lines:
    div_texts.append(line.strip().split(" "))

#Set up dictionary and MMcorpus
dictionary = corpora.Dictionary(div_texts)
dictionary.save("ad_nonad_lda_deeplearning.dict")
#dictionary = corpora.Dictionary.load("ad_nonad_lda_deeplearning.dict")
print dictionary.token2id["junk"]
corpus = [dictionary.doc2bow(text) for text in div_texts]
corpora.MmCorpus.serialize("ad_nonad_lda_deeplearning.mm", corpus)

#LDA training
id2token = {}
token2id = dictionary.token2id
for onemap in dictionary.token2id:
    id2token[token2id[onemap]] = onemap
#ldamodel = models.LdaModel(corpus, num_topics = 100, passes = 1000, id2word = id2token)
#ldamodel.save("ldamodel1000pass.lda")
#ldamodel = models.LdaModel(corpus, num_topics = 100, id2word = id2token)
ldamodel = models.LdaModel.load("ldamodel1000pass.lda")
ldatopics = ldamodel.show_topics(num_topics = 100, num_words = len(dictionary), formatted = False)
print ldatopics[10][1]
print ldatopics[10][1][1]
ldawordindex = {}
for i in range(len(dictionary)):
    ldawordindex[ldatopics[0][i][1]] = i

#Doc2Vec initialize
sentences = []
for i in range(len(div_texts)):
    string = "SENT_" + str(i)
    sentence = models.doc2vec.LabeledSentence(div_texts[i], labels = [string])
    sentences.append(sentence)
doc2vecmodel = models.Doc2Vec(sentences, size = 100, window = 5, min_count = 0, dm = 1)
print "Initial word vector for word junk:"
print doc2vecmodel["junk"]

#Replace the word vector with word vectors from LDA
print len(doc2vecmodel.syn0)
index2wordcollection = doc2vecmodel.index2word
print index2wordcollection
for i in range(len(doc2vecmodel.syn0)):
    if index2wordcollection[i].startswith("SENT_"):
        continue
    wordindex = ldawordindex[index2wordcollection[i]]
    wordvectorfromlda = [ldatopics[j][wordindex][0] for j in range(100)]
    doc2vecmodel.syn0[i] = wordvectorfromlda
#print doc2vecmodel.index2word[26841]
#doc2vecmodel.syn0[0] = [0 for i in range(100)]
print "Changed word vector for word junk:"
print doc2vecmodel["junk"]

#Train Doc2Vec
doc2vecmodel.train_words = False 
print "Initial doc vector for 1st document"
print doc2vecmodel["SENT_0"]
for i in range(50):
    print "Round: " + str(i)
    doc2vecmodel.train(sentences)
print "Trained doc vector for 1st document"
print doc2vecmodel["SENT_0"]

#Using SVM to do classification
resultlist = []
for i in range(4143):
    string = "SENT_" + str(i)
    resultlist.append(doc2vecmodel[string])
svm_x_train = []
for i in range(1000):
    svm_x_train.append(resultlist[i])
for i in range(2210,3210):
    svm_x_train.append(resultlist[i])
print len(svm_x_train)

svm_x_test = []
for i in range(1000,2210):
    svm_x_test.append(resultlist[i])
for i in range(3210,4143):
    svm_x_test.append(resultlist[i])
print len(svm_x_test)

svm_y_train = numpy.array([0 for i in range(2000)])
for i in range(1000,2000):
    svm_y_train[i] = 1
print svm_y_train

svm_y_test = numpy.array([0 for i in range(2143)])
for i in range(1210,2143):
    svm_y_test[i] = 1
print svm_y_test


svc = svm.SVC(kernel='linear')
svc.fit(svm_x_train, svm_y_train)

expected = svm_y_test
predicted = svc.predict(svm_x_test)

print("Classification report for classifier %s:\n%s\n"
      % (svc, metrics.classification_report(expected, predicted)))
print("Confusion matrix:\n%s" % metrics.confusion_matrix(expected, predicted))

print doc2vecmodel["junk"]
11
répondu STEVE Guo 2015-03-06 14:56:50

cette version bifurquée de gensim permet de charger des vecteurs de mots pré-formés pour la formation doc2vec. Ici vous avez un exemple sur la façon de l'utiliser. Les vecteurs de mot doivent être dans le format de texte de l'outil C-word2vec: une ligne par vecteur de mot où vient d'abord une chaîne représentant le mot, puis des valeurs flottantes séparées par l'espace, une pour chaque dimension de l'enchâssement.

ce travail appartient à un papier dans lesquels ils affirment que l'utilisation de l'intégration de mots aide en fait à construire les vecteurs de documents. Cependant, je suis presque les mêmes résultats peu importe que je charge ou non les ancrages pré-formés.

Edit: en fait, il y a une différence remarquable dans mes expériences. Quand j'ai chargé les embeddings pré-entraînés j'ai formé doc2vec pour la moitié des itérations pour obtenir presque les mêmes résultats (une formation plus longue que celle qui a produit des résultats plus mauvais dans ma tâche).

9
répondu Álvaro Marco 2016-09-06 15:28:28

Radim vient de poster un tutoriel sur les fonctionnalités doc2vec de gensim (hier, je crois - votre question Est d'actualité!).

Gensim supporte le chargement de vecteurs pré-entraînés à partir de l'implémentation C, comme décrit dans les modèles gensim.documentation de l'API word2vec.

2
répondu AaronD 2014-12-16 19:46:35