【问题标题】:Why Gensim most similar in doc2vec gives the same vector as the output?为什么 doc2vec 中最相似的 Gensim 给出与输出相同的向量?
【发布时间】:2019-02-28 08:42:45
【问题描述】:

我正在使用以下代码来获取用户帖子的有序列表。

model = doc2vec.Doc2Vec.load(doc2vec_model_name)
doc_vectors = model.docvecs.doctag_syn0
doc_tags = model.docvecs.offset2doctag

for w, sim in model.docvecs.most_similar(positive=[model.infer_vector('phone_comments')], topn=4000):
        print(w, sim)
        fw.write(w)
        fw.write(" (")
        fw.write(str(sim))
        fw.write(")")
        fw.write("\n")

fw.close()

但是,我也得到了向量"phone comments"(我用来查找最近的邻居)在列表的第 6 位。我在代码中有什么错误吗?还是 Gensim 中的问题(因为向量不能是自身的邻居)?

编辑

Doc2vec模型训练代码

######Preprocessing
docs = []
analyzedDocument = namedtuple('AnalyzedDocument', 'words tags')
for key, value in my_d.items():
    value = re.sub("[^1-9a-zA-Z]"," ", value)
    words = value.lower().split()
    tags = key.replace(' ', '_')
    docs.append(analyzedDocument(words, tags.split(' ')))

sentences = []  # Initialize an empty list of sentences
######Get n-grams
#Get list of lists of tokenised words. 1 sentence = 1 list
for item in docs:
    sentences.append(item.words)

#identify bigrams and trigrams (trigram_sentences_project) 
trigram_sentences_project = []
bigram = Phrases(sentences, min_count=5, delimiter=b' ')
trigram = Phrases(bigram[sentences], min_count=5, delimiter=b' ')

for sent in sentences:
    bigrams_ = bigram[sent]
    trigrams_ = trigram[bigram[sent]]
    trigram_sentences_project.append(trigrams_)

paper_count = 0
for item in trigram_sentences_project:
    docs[paper_count] = docs[paper_count]._replace(words=item)
    paper_count = paper_count+1

# Train model
model = doc2vec.Doc2Vec(docs, size = 100, window = 300, min_count = 5, workers = 4, iter = 20)

#Save the trained model for later use to take the similarity values
model_name = user_defined_doc2vec_model_name
model.save(model_name)

【问题讨论】:

    标签: nlp data-mining gensim word2vec doc2vec


    【解决方案1】:

    infer_vector() 方法需要一个令牌列表,就像用于训练模型的文本示例(通常是 TaggedDocument 对象)的 words 属性一样。

    您提供了一个简单的字符串'phone_comments',它看起来像infer_vector(),就像列表['p', 'h', 'o', 'n', 'e', '_', 'c', 'o', 'm', 'm', 'e', 'n', 't', 's']一样。因此,most_similar() 的原始向量可能是垃圾。

    此外,您不会取回输入 'phone_comments',而是取回不同的字符串 'phone comments'。如果这是模型中的标签名称,那么它一定是在模型训练期间提供的tag。它与phone_comments 的表面相似性可能毫无意义——它们是不同的字符串。

    (但也可能暗示你的训练也有问题,将本应为words=['phone', 'comments']的文本训练为words=['p', 'h', 'o', 'n', 'e', ' ', 'c', 'o', 'm', 'm', 'e', 'n', 't', 's']。)

    【讨论】:

    • 非常感谢您的出色回答 :) 我已使用我的 doc2vec 培训代码更新了我的问题。正如您所提到的,我正在使用 TaggedDocument 对象。请你让我知道我在哪里犯了错误? :)
    • 顺便说一下phone_comment是我在tarining中使用的标签(有与手机相关的cmets列表)
    • 目前的问题是什么?在将您提供给infer_vector() 的内容修复为令牌列表后,您是否得到相同的结果? (您不应该这样做。)修复后,如果结果有问题怎么办?
    • infer_vector() 方法需要一个令牌列表,就像用于训练模型的文本示例的 words 属性一样。因此,如果您在训练期间使用 words=['phone', 'comments'] 提供了一个文本,以推断类似文本的向量,您需要执行 infer_vector(['phone', 'comments'])
    • infer_vector() 方法用于从新文本创建新的文档向量。因此,您应该向它提供新文档的words。您没有提供任何现有标签。如果您想获得在批量训练期间为您提供的标签之一训练的向量,您只需使用索引访问查找它:model.docvecs['phone_comments']
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2022-01-17
    • 1970-01-01
    • 2019-06-08
    • 1970-01-01
    • 1970-01-01
    • 2017-03-26
    • 2018-08-14
    相关资源
    最近更新 更多