从Doc2Vec中提取向量

时间:2018-01-23 12:57:48

标签: gensim doc2vec

我正在尝试提取文档向量以提供给回归模型进行预测。

我已将大约1 400 000个带标签的句子送入doc2vec进行训练,但是我只能使用model.docvecs检索10个向量。

这是我用来训练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 mil文档显示为10个文档。

Irene Li提供有关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的答案。

1 个答案:

答案 0 :(得分:0)

错误的要点是:每个人tags的{​​{1}}都是以简单字符串形式提供的,例如TaggedDocument'101'

但是,'456'应该是一个单独的标记列表。通过提供一个简单的字符串,它被视为字符列表。因此tags将成为'101',而['1', '0', '1']将成为'456'

在任意数量的['4', '5', '6']个对象中,只有10个唯一标记,单个数字TaggedDocument。每个文档只是导致这些标记的某些子集被训练。

['0', '1', '2', '3', '4', '5', '6', '7', '8', '9']更正为一个列表标记,例如tags,可以将['101']视为实际标记。