2015-07-09 5 views
37

Как получить векторы документов из двух текстовых документов с использованием Doc2vec? Я новичок в этом, поэтому было бы полезно, если бы кто-то мог указать мне в правильном направлении/помочь мне с некоторым учебникомDoc2vec: Как получить векторы документов

Я использую библиотеку gensim python.

doc1=["This is a sentence","This is another sentence"] 
documents1=[doc.strip().split(" ") for doc in doc1 ] 
model = doc2vec.Doc2Vec(documents1, size = 100, window = 300, min_count = 10, workers=4) 

Я получаю AttributeError: «список» объект имеет нет атрибута «слова» всякий раз, когда я запускаю это

ответ

23
doc=["This is a sentence","This is another sentence"] 
documents=[doc.strip().split(" ") for doc in doc1 ] 
model = doc2vec.Doc2Vec(documents, size = 100, window = 300, min_count = 10, workers=4) 

Я получил AttributeError: «список» объект не имеет атрибута «слова», потому что входные документы в Doc2vec() не были в правильном формате LabeledSentence. Надеюсь, что этот ниже пример поможет вам понять формат.

documents = LabeledSentence(words=[u'some', u'words', u'here'], labels=[u'SENT_1']) 

Подробнее здесь: http://rare-technologies.com/doc2vec-tutorial/ Однако, я решил эту проблему, принимая входные данные из файла с помощью TaggedLineDocument().
Формат файла: один документ = одна строка = один объект TaggedDocument. Слова должны быть предварительно обработаны и разделены пробелами, тэги автоматически создаются из номера строки документа.

sentences=doc2vec.TaggedLineDocument(file_path) 
model = doc2vec.Doc2Vec(sentences,size = 100, window = 300, min_count = 10, workers=4) 

Чтобы получить вектор документа: Вы можете использовать docvecs. Подробнее здесь: https://radimrehurek.com/gensim/models/doc2vec.html#gensim.models.doc2vec.TaggedDocument

docvec = model.docvecs[99] 

где 99 является идентификатор документа вектор которого мы хотим. Если метки находятся в целочисленном формате (по умолчанию, если вы загружаете с помощью TaggedLineDocument()), прямо используйте целочисленный идентификатор, как я. Если метки находятся в строчном формате, используйте «SENT_99». Это похоже на Word2vec

+1

Просто, чтобы подтвердить, после тренировки model_dm и model_dbow, как показано в учебнике (https: //linanqiu.github.io/2015/05/20/word2vec-sentiment /) Я возвращаю вектор документа для первого учебного документа, используя model_dm.docvecs ['TRAIN_0']. Это верно? – Sangram

+0

да, это правильно, и тогда вы можете сравнить несколько документов с функцией расстояния и т. Д. –

+2

Мои учебные документы более 5 м, однако, когда я использую docvec = model.docvecs [11], он показал, что 11 является нашей границей для оси 0 с размером 10. Я проверил размер docvecs, только 10, он должен был более чем 5 миллионов – Kun

33

Gensim обновлен. Синтаксис LabeledSentence не содержит этикеток. Есть теперь тегов - см документации для LabeledSentence https://radimrehurek.com/gensim/models/doc2vec.html

Однако @ bee2502 был прав с

docvec = model.docvecs[99] 

Это будет дорожа 100th вектора для обученной модели, она работает с целыми числами и строками.

28

Если вы хотите обучить модель Doc2Vec, ваш набор данных должен содержать списки слов (аналогичные формату Word2Vec) и теги (идентификатор документов). Он также может содержать дополнительную информацию (см. https://github.com/RaRe-Technologies/gensim/blob/develop/docs/notebooks/doc2vec-IMDB.ipynb для получения дополнительной информации).

# Import libraries 

from gensim.models import doc2vec 
from collections import namedtuple 

# Load data 

doc1 = ["This is a sentence", "This is another sentence"] 

# Transform data (you can add more data preprocessing steps) 

docs = [] 
analyzedDocument = namedtuple('AnalyzedDocument', 'words tags') 
for i, text in enumerate(doc1): 
    words = text.lower().split() 
    tags = [i] 
    docs.append(analyzedDocument(words, tags)) 

# Train model (set min_count = 1, if you want the model to work with the provided example data set) 

model = doc2vec.Doc2Vec(docs, size = 100, window = 300, min_count = 1, workers = 4) 

# Get the vectors 

model.docvecs[0] 
model.docvecs[1] 

ОБНОВЛЕНИЕ (как обучать в эпохи): функция Doc2Vec содержит alpha и min_alpha параметры, но это означает, что скорость обучения распадается в течение одной эпохи от alpha к min_alpha. Обучить несколько эпох, установить скорость обучения вручную, как это:

from gensim.models import doc2vec 
import random 

alpha_val = 0.025  # Initial learning rate 
min_alpha_val = 1e-4  # Minimum for linear learning rate decay 
passes = 15    # Number of passes of one document during training 

alpha_delta = (alpha_val - min_alpha_val)/(passes - 1) 

model = doc2vec.Doc2Vec(size = 100 # Model initialization 
    , window = 300 
    , min_count = 1 
    , workers = 4) 

model.build_vocab(docs) # Building vocabulary 

for epoch in range(passes): 

    # Shuffling gets better results 

    random.shuffle(docs) 

    # Train 

    model.alpha, model.min_alpha = alpha_val, alpha_val 

    model.train(docs) 

    # Logs 

    print('Completed pass %i at alpha %f' % (epoch + 1, alpha_val)) 

    # Next run alpha 

    alpha_val -= alpha_delta 
+0

Мне очень нравится идея использования 'namedtuple' здесь, но что меня смущает, если есть doc2? Похоже, что «теги» являются «id» для предложения, а не для документа. В списке 'docs' кажется, что в нем может быть более одного документа. –

+0

На самом деле в doc1 есть два разных документа (не два предложения в одном документе). Я не знаю, почему @ bee2502 назвал это как 'doc1'. Однако вы можете догадаться об этом из строки 'documents1 = [doc.strip(). Split (" ") для doc в doc1]' –

+0

@ LenkaVraná Множество танков для отличного ответа :) Нужно ли нам готовить нашу модель doc2vec несколько эпопей ? Если да, то как мы можем это сделать с приведенным выше примером? –