Извлечение векторов из Doc2Vec

Я пытаюсь извлечь вектор документов для использования в регрессионной модели для прогнозирования.

Я загрузил около 1 400 000 помеченных предложений в doc2vec для обучения, однако мне удалось получить только 10 векторов с помощью model.docvecs.

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

In : documents[0]

Out: TaggedDocument(words=['descript', 'yet'], tags='0')

In : documents[-1]

Out: TaggedDocument(words=['new', 'tag', 'red', 'sparkl', 'firm', 'price', 'free', 'ship'], tags='1482534')

Это код, используемый для обучения модели doc2vec

model = gensim.models.Doc2Vec(min_count=1, window=5, size=100, sample=1e-4, negative=5, workers=4)
model.build_vocab(documents)
model.train(documents, total_examples =len(documents), epochs=1)

Это размерность векторов документов:

In : model.docvecs.doctag_syn0.shape
Out: (10, 100)

В какой части кода я напортачил?

Обновление:

Добавляя к комментарию из sophros, похоже, что я допустил ошибку при создании TaggedDocument перед обучением, которое в результате 1,4 миллиона документов отображаются как 10 документов.

Предоставлено Ирэн Ли в вашем руководстве по Doc2vec, я немного отредактировал класс, который она использовала для создания TaggedDocument

def get_doc(data):

tokenizer = RegexpTokenizer(r'\w+')
en_stop = stopwords.words('english')
p_stemmer = PorterStemmer()

taggeddoc = []

texts = []
for index,i in enumerate(data):
    # for tagged doc
    wordslist = []
    tagslist = []
    i = str(i)
    # clean and tokenize document string
    raw = i.lower()
    tokens = tokenizer.tokenize(raw)
    # remove stop words from tokens
    stopped_tokens = [i for i in tokens if not i in en_stop]
    # remove numbers
    number_tokens = [re.sub(r'[\d]', ' ', i) for i in stopped_tokens]
    number_tokens = ' '.join(number_tokens).split()
    # stem tokens
    stemmed_tokens = [p_stemmer.stem(i) for i in number_tokens]
    # remove empty
    length_tokens = [i for i in stemmed_tokens if len(i) > 1]
    # add tokens to list
    texts.append(length_tokens)

    td = TaggedDocument(gensim.utils.to_unicode(str.encode(' '.join(stemmed_tokens))).split(),str(index))

    taggeddoc.append(td)

return taggeddoc

Ошибка была исправлена, когда я изменил

td = TaggedDocument(gensim.utils.to_unicode(str.encode(' '.join(stemmed_tokens))).split(),str(index))

к этому

td = TaggedDocument(gensim.utils.to_unicode(str.encode(' '.join(stemmed_tokens))).split(),[str(index)])

Похоже, что индекс TaggedDocument должен быть в форме списка для правильной работы TaggedDocument. Для получения дополнительных сведений о том, почему, обратитесь к этому ответу gojomo .


person Loh Ying Hao    schedule 23.01.2018    source источник
comment
Сколько у вас документов? Вы уверены, что у вас нет 1,4 миллиона предложений только в 10 документах?   -  person sophros    schedule 23.01.2018


Ответы (1)


Суть ошибки заключалась в том, что tags для каждого отдельного TaggedDocument предоставлялись в виде простых строк, например '101' или '456'.

Но tags должен быть списком отдельных тегов. Предоставляя простую строку, она обрабатывалась как список символов. Итак, '101' станет ['1', '0', '1'], а '456' станет ['4', '5', '6'].

Таким образом, для любого количества TaggedDocument объектов было только 10 уникальных тегов, однозначных ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9']. Каждый документ просто вызывал обучение некоторого подмножества этих тегов.

Исправление tags как тега "список из одного", например, ['101'], позволяет рассматривать '101' как фактический тег.

person gojomo    schedule 25.01.2018