Подтвердить что ты не робот

Как использовать Gensim doc2vec с заранее подготовленными векторами слов?

Недавно я встретил дополнение doc2vec к Gensim. Как использовать предварительно подготовленные векторы слов (например, найденные на исходном веб-сайте word2vec) с помощью doc2vec?

Или doc2vec получает слова векторов из тех же предложений, которые он использует для обучения векторам абзаца?

Спасибо.

4b9b3361

Ответ 1

Обратите внимание, что режим обучения "DBOW" (dm=0) не требует или даже не создает словесные векторы как часть обучения. Он просто учит векторам векторов, которые хорошо предсказывают каждое слово по очереди (подобно режиму skip-gram word2vec).

(Перед gensim 0.12.0 был указан параметр train_words, упомянутый в другом комментарии, который будет предлагаться в какой-то документации, будет координировать слова. Однако я не считаю, что это действительно срабатывало. Начиная с gensim 0.12.0, существует параметр dbow_words, который работает с пропущенными графовыми словами одновременно с DBOC doc-векторами. Обратите внимание, что это заставляет обучение занимать больше времени - в зависимости от window. Поэтому, если вам не нужны слова- векторы, вы все равно можете оставить это.)

В методе обучения "DM" (dm=1) слово-векторы по своей природе обучаются во время процесса вместе с doc-векторами и, вероятно, также влияют на качество doc-векторов. Теоретически можно предварительно инициализировать слова-векторы из предыдущих данных. Но я не знаю каких-либо сильных теоретических или экспериментальных причин, чтобы быть уверенным, что это улучшит doc-векторы.

Один фрагментарный эксперимент, который я провел по этим строкам, предположил, что обучение векторам вектора прошло быстрее, чем лучше первые проспективные качества, но это преимущество исчезло с большим количеством проходов. Независимо от того, поддерживаете ли вы векторы векторов постоянными или позволяете им продолжать корректировать новое обучение, также, вероятно, важное соображение... но какой выбор лучше всего может зависеть от ваших целей, набора данных и качества/релевантности ранее существовавших словесных векторов,

(Вы можете повторить мой эксперимент с помощью метода intersect_word2vec_format(), доступного в gensim 0.12.0, и попробовать разные уровни создания предварительно загруженных векторов, устойчивых к новому обучению, с помощью значений syn0_lockf. Но помните, что это экспериментальная территория: основные результаты doc2vec не зависят или даже не улучшаются с использованием повторно используемых векторов слов.)

Ответ 2

Ну, я недавно использовал Doc2Vec. И я думал о том, чтобы использовать результат LDA как вектор слова и исправить эти векторы вектора, чтобы получить вектор документа. Однако результат не очень интересный. Может быть, это просто мой набор данных не так уж хорош. Код ниже. Doc2Vec сохраняет слова векторов и векторов документов в словаре doc2vecmodel.syn0. Вы можете изменить векторные значения. Единственная проблема может заключаться в том, что вам нужно выяснить, какая позиция в syn0 представляет слово или документ. Векторы хранятся в случайном порядке в словаре 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"]

Ответ 3

Эта разветвленная версия gensim позволяет загружать предварительно подготовленные словарные векторы для обучения doc2vec. Здесь у вас есть пример того, как его использовать. Векторные векторы должны быть в текстовом формате инструмента C-word2vec: одна строка на вектор слова, где сначала появляется строка, представляющая слово, а затем значения с плавающей точкой, разделенные пробелами, по одному для каждого измерения вложения.

Эта работа относится к статье в которой они утверждают, что использование предварительно подготовленных вложений слов фактически помогает создавать векторы документов. Однако я получаю почти те же результаты, независимо от того, загружаю ли предварительно подготовленные вложения или нет.

Изменить: На самом деле есть одна замечательная разница в моих экспериментах. Когда я загрузил предварительно обработанные вложения, я обучил doc2vec для половины итераций, чтобы получить почти те же результаты (обучение дольше, чем это привело к худшим результатам в моей задаче).

Ответ 4

Radim просто разместил tutorial на функциях gensim doc2vec (вчера, я считаю, ваш вопрос своевременен!).

Gensim поддерживает загрузку предварительно обученных векторов из реализация C, как описано в документация gensim models.word2vec.