Doc2Vec 最相似的向量与输入向量不匹配

Doc2Vec most similar vectors don't match an input vector

我有一个包含大约 40 000 条记录的职位发布数据集。我使用 NER 从字典中大约 30 000 个技能的描述中提取技能。每项技能都表示为唯一标识符。

帖子的技能数量分布如下所示:

平均 15.12 | 标准 11.22 | 最小 1.00 | 25% 7.00 | 50% 13.00 | 75% 20.00 |

我只使用技能 ID 训练了一个 word2vec 模型,它或多或少工作得很好。我可以找到与给定技能最相似的技能,结果看起来不错。

但是当涉及到 doc2vec 模型时,我对结果并不满意。

我有大约 3200 个不同的职位名称,其中大部分只有很少的条目,并且有相当一部分来自同一领域('front end developer'、'senior javascript developer'、'front end engineer').我特意申请了各种职位,我将这些职位用作 doc2vec.TaggedDocument() 中的标签。我的目标是在 docvecs.most_similar().

中输入技能向量时看到一些相关的职位

训练模型后(我尝试了不同的时期数 (100,500,1000) 和矢量大小(40 和 100))有时它可以正常工作,但大多数时候不能。例如,对于像 [numpy, postgresql, pandas, xgboost, python, pytorch] 这样的技能集,我得到了最相似的职位名称,其技能集如 [家庭法庭、表演、咨询、社会工作].

会不会是我的数据集大小有问题?或者文档的大小(我认为我的文本很短)?我还认为我误解了一些关于 doc2vec 机制的东西,只是忽略了它。我还想问问你是否知道任何其他的,也许更高级的想法,我可以如何从技能集中获得相关的职位头衔,并比较两个技能集向量,如果它们接近或远离。

更新:

我的数据中的职位是 'tags',技能是 'words'。每个文本都有一个标签。有 40 000 个文件,有 3200 个重复标签。文档中出现 7881 个独特的技能 ID。每个文档的平均技能词数为 15.

我的数据示例:

         job_titles                                             skills
1  business manager                 12 13 873 4811 482 2384 48 293 48
2    java developer      48 2838 291 37 484 192 92 485 17 23 299 23...
3    data scientist      383 48 587 475 2394 5716 293 585 1923 494 3

我的代码示例:

def tagged_document(df):
    #tagging documents
    for index, row in df.iterrows():
        yield gensim.models.doc2vec.TaggedDocument(row['skills'].split(), [row['job_title']])


data_for_training = list(tagged_document(job_data[['job_titles', 'skills']])

model_d2v = gensim.models.doc2vec.Doc2Vec(vector_size=50, min_count=2, epochs=100)

model_d2v.train(data_for_training, total_examples=model_d2v.corpus_count, epochs=model_d2v.epochs)

#the skill set contains close skills which represent a front end developer
skillset_ids = '12 34 556 453 1934'.split()                                                  
new_vector = model_d2v.infer_vector(skillset_ids, epochs=100)
model_d2v.docvecs.most_similar(positive=[new_vector], topn=30)

我最近一直在试验,发现如果我过滤掉少于 10 个技能的文档,它的性能会好一些。尽管如此,还是出现了一些不相关的职位。

没有看到你的代码(或者至少是它的主要选择的草图),很难判断你是否犯了 shooting-self-in-foot 错误,比如常见的“自己管理 alpha以下糟糕的在线示例”问题:My Doc2Vec code, after many loops of training, isn't giving good results. What might be wrong?

(你的最小测试数量 epochs 是 100 似乎很可疑;10-20 个时期是已发表作品中的常见值,当数据集的大小和每个文档的大小都很丰富时,虽然更多pass 有时可以帮助处理更薄的数据。)

同样,从您的描述中,您的培训文档是什么样子的,并不完全清楚。例如:

  • tags头衔和words技能吗?
  • 每个文本都有一个 tag 吗?
  • 如果有 3,200 个唯一 tags 和 30,000 个唯一 words,是只有 3,200 个 TaggedDocuments 还是更多重复标题?
  • 每个 TaggedDocument 的平均 skill-words 是多少?

此外,如果您使用 word-vectors(针对技能)作为查询向量,则必须确保使用能够实际训练这些的训练模式。一些 Doc2Vec 模式,例如普通 PV-DBOW (dm=0) 根本不会训练 word-vectors,但它们将作为 randomly-initialized 垃圾存在。 (无论是加non-defaultdbow_words=1加skip-gramword-training,还是切换成PV-DMdm=1模式,都会保证word-vectors是co-trained 并在可比较的坐标 space.)