Как использовать TaggedDocument в gensim?

У меня есть два каталога, из которых я хочу прочитать их текстовые файлы и пометить их, но я не знаю, как это сделать через TaggedDocument. Я думал, что это будет работать как TaggedDocument([Strings],[Labels]), но это явно не работает.

Это мой код:

from gensim import models
from gensim.models.doc2vec import TaggedDocument
import utilities as util
import os
from sklearn import svm
from nltk.tokenize import sent_tokenize
CogPath = "./FixedCog/"
NotCogPath = "./FixedNotCog/"
SamplePath ="./Sample/"
docs = []
tags = []
CogList = [p for p in os.listdir(CogPath) if p.endswith('.txt')]
NotCogList = [p for p in os.listdir(NotCogPath) if p.endswith('.txt')]
SampleList = [p for p in os.listdir(SamplePath) if p.endswith('.txt')]
for doc in CogList:
     str = open(CogPath+doc,'r').read().decode("utf-8")
     docs.append(str)
     print docs
     tags.append(doc)
     print "###########"
     print tags
     print "!!!!!!!!!!!"
for doc in NotCogList:
     str = open(NotCogPath+doc,'r').read().decode("utf-8")
     docs.append(str)
     tags.append(doc)
for doc in SampleList:
     str = open(SamplePath + doc, 'r').read().decode("utf-8")
     docs.append(str)
     tags.append(doc)

T = TaggedDocument(docs,tags)

model = models.Doc2Vec(T,alpha=.025, min_alpha=.025, min_count=1,size=50)

и это ошибка, которую я получаю:

Traceback (most recent call last):
  File "/home/farhood/PycharmProjects/word2vec_prj/doc2vec.py", line 34, in <module>
    model = models.Doc2Vec(T,alpha=.025, min_alpha=.025, min_count=1,size=50)
  File "/home/farhood/anaconda2/lib/python2.7/site-packages/gensim/models/doc2vec.py", line 635, in __init__
    self.build_vocab(documents, trim_rule=trim_rule)
  File "/home/farhood/anaconda2/lib/python2.7/site-packages/gensim/models/word2vec.py", line 544, in build_vocab
    self.scan_vocab(sentences, progress_per=progress_per, trim_rule=trim_rule)  # initial survey
  File "/home/farhood/anaconda2/lib/python2.7/site-packages/gensim/models/doc2vec.py", line 674, in scan_vocab
    if isinstance(document.words, string_types):
AttributeError: 'list' object has no attribute 'words'

person Farhood    schedule 16.07.2017    source источник
comment
Отдельно от вашего основного вопроса: если конечное min_alpha будет тем же значением, что и начальное alpha, это означает, что ваше обучение не выполняет надлежащий стохастический градиентный спуск. Кроме того, min_count=1 редко бывает полезен при обучении Word2Vec/Doc2Vec — сохранение таких редких слов приводит к тому, что обучение занимает больше времени и влияет на качество оставшихся векторов слов/документов.   -  person gojomo    schedule 16.07.2017
comment
о min_alpha я скопировал его из примера кода, за которым следует этот код: for epoch in range(10): model.train(docs) model.alpha -= 0.002 # decrease the learning rate model.min_alpha = model.alpha # fix the learning rate, no decay и о min_count: мой набор данных очень ограничен, и некоторые слова не так уж часто встречаются, но имеют большое значение, также я отфильтровал большинство стоп-слова и частые ежедневные слова.   -  person Farhood    schedule 17.07.2017
comment
Это плохой образец для подражания. Если вы передаете свой корпус при создании экземпляра Doc2Vec, он автоматически выполнит все свои обучающие проходы и автоматически будет управлять скоростью обучения от alpha до min_alpha, и вам не следует вызывать train() самостоятельно. (И если вы это сделаете, как вы показали без каких-либо других подробностей, последние версии gensim выдадут ошибку, потому что это такая распространенная ошибка.) Это редкая, опытная вещь, чтобы вызвать train() самостоятельно или много со значением по умолчанию alpha/ min_alpha.   -  person gojomo    schedule 18.07.2017


Ответы (3)


Входными данными для модели Doc2Vec должен быть список TaggedDocument(['list','of','word'], [TAG_001]). Хорошей практикой является использование индексов предложений в качестве тегов. Например, для обучения модели Doc2Vec с двумя предложениями (то есть документами, абзацами):

s1 = 'the quick fox brown fox jumps over the lazy dog'
s1_tag = '001'
s2 = 'i want to burn a zero-day'
s2_tag = '002'

docs = []
docs.append(TaggedDocument(words=s1.split(), tags=[s1_tag])
docs.append(TaggedDocument(words=s2.split(), tags=[s2_tag])

model = gensim.models.Doc2Vec(vector_size=300, window=5, min_count=5, workers=4, epochs=20)
model.build_vocab(docs)

print 'Start training process...'
model.train(docs, total_examples=model.corpus_count, epochs=model.iter)

#save model
model.save(model_path)
person biendltb    schedule 23.06.2018

Поэтому я просто немного поэкспериментировал и нашел это на github:

class TaggedDocument(namedtuple('TaggedDocument', 'words tags')):
    """
    A single document, made up of `words` (a list of unicode string tokens)
    and `tags` (a list of tokens). Tags may be one or more unicode string
    tokens, but typical practice (which will also be most memory-efficient) is
    for the tags list to include a unique integer id as the only tag.

    Replaces "sentence as a list of words" from Word2Vec.

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

for doc in CogList:
     str = open(CogPath+doc,'r').read().decode("utf-8")
     str_list = str.split()
     T = TaggedDocument(str_list,[doc])
     docs.append(T)
person Farhood    schedule 16.07.2017
comment
Да: Doc2Vec ожидает, что корпус будет итерируемой коллекцией, где каждый отдельный элемент (документ) имеет форму TaggedDocument. (То есть у него есть список words и список tags.) - person gojomo; 16.07.2017

В качестве примера вы можете использовать common_texts gensim:

from gensim.test.utils import common_texts
from gensim.models.doc2vec import Doc2Vec, TaggedDocument

documents = [TaggedDocument(doc, [i]) for i, doc in enumerate(common_texts)]
model = Doc2Vec(documents, vector_size=5, window=2, min_count=1, workers=4)

Это будет использовать common_texts и TaggedDocument для создания представления документа, ожидаемого алгоритмом Doc2Vec.

person Cybernetic    schedule 22.07.2019