到目前为止,我一直在以最基本的方式使用 doc2vec,但收效甚微。我能够找到类似的文件,但我经常会得到很多误报。我的主要目标是针对用户需求构建分类算法。这有助于用户需求分析和搜索。
我知道这不是一个足够大的数据集,所以有几个问题我想得到帮助:
- 如何在一组文档上训练并在另一组文档上构建向量?
- 如何调整模型,特别是为向量空间选择正确的维数
- 我应该如何为词向量创建层次聚类,应该使用一个模型来实现还是应该创建单独的词和文档分类模型?
- 我没有基本事实,这是调优时的无监督学习 我该如何衡量结果的质量?
- 最后,是否有任何推荐的在线资源可能涵盖上述部分内容。
我一直在 2000 个文档上用 100 个向量调用一次训练,每个向量大约有 100 个单词,每个文档有 22 列,由单元格和行标记。
def tag_dataframe(df, selected_cols):
tagged_cells = []
headers = list(df.columns.values)
for index, row in df.iterrows():
row_tag = 'row_' + str(index)
for col_name in headers:
if col_name in selected_cols:
col_tag = 'col_' + col_name
cell_tag = 'cell_' + str(index) + '_' + col_name
cell_val = str(row[col_name])
if cell_val == 'nan':
continue
cleaned_text = clean_str(cell_val)
if len(cleaned_text) == 0:
continue
tagged_cells.append(
gensim.models.doc2vec.TaggedDocument(
cleaned_text,
[row_tag, cell_tag]))
print('tagged rows')
return tagged_cells
def load_or_build_vocab(model_path, tagged_cells):
if os.path.exists(model_path):
print('Loading vocab')
d2vm = gensim.models.Doc2Vec.load(model_path)
else:
print('building vocab')
d2vm = gensim.models.Doc2Vec(
vector_size=100,
min_count=0,
alpha=0.025,
min_alpha=0.001)
d2vm.build_vocab(tagged_cells)
print(' built')
d2vm.save(model_path)
return d2vm
def load_or_train_model(model_path, d2vm, tagged_cells):
if os.path.exists(model_path):
print('Loading Model')
d2vm = gensim.models.Doc2Vec.load(model_path)
else:
print('Training Model')
d2vm.train(
tagged_cells,
total_examples=len(tagged_cells),
epochs=100)
print(' trained')
d2vm.save(model_path)
return d2vm
我希望实现的是一组文档向量,这将有助于从自由文本和层次聚类中找到相似的用户需求,以构建现有需求的导航。
最佳答案
您应该在其 docs/notebooks
目录(或 viewable online )中查看与 gensim 捆绑在一起的 doc2vec-
Jupyter 笔记本,以获取更多正确使用示例。查看 tag doc2vec
上的现有 SO 答案(也许尤其是 my answers )也可能会让您了解常见错误。)
要在无监督环境中调整模型,您本质上需要一些特定领域的可重复评估分数。这可能需要遍历您的整个集群和终端应用程序,然后根据它“应该”为您的手动创建的数据子集提供的某些结果计算其成功。
为了比较,如果您查看原始的“段落向量”论文,它使用现有搜索引擎中的前 10 个搜索结果片段的现有批处理作为训练文档,但随后根据它的表现对任何模型进行评分共享前 10 名中的片段彼此之间的距离比随机的第 3 个文档更近。后续论文“Document Embedding with Paragraph Vectors”在维基百科文章或 Arxiv 论文上进行了训练,并根据生成的模型将文档放入这些系统中存在的相同预分类类别的程度来调整他们的模型。
您可以对每个文档向量使用任何聚类算法。 Doc2Vec
的输出,作为每个向量的文档,可以成为下游算法的输入。 (我不确定你所说的“单独的单词和文档分类模型”是什么意思。你只描述了文档级的最终需求,你可能根本不需要单词向量......虽然一些 Doc2Vec
模式将创建这样的向量。)
在模型经过训练和卡住后,您可以使用 infer_vector()
方法为新文档创建向量。
查看您的数据/代码的细节,一些观察结果:
- 不清楚您的多列是什么,或者它们应该是单独的文档(而不是合并到一个文档中)。查看一些完整的行可能有助于弄清楚数据的本质。
- 这是一个很小的数据集 - 大多数已发布的
Doc2Vec
工作都在数万到数百万的文档上运行。该算法最适合处理更多数据。 - 最初的工作只给每个文档一个唯一的 ID 标签。虽然 gensim
Doc2Vec
支持为文档提供多个标签,正如您在此处所做的那样,但最好将其视为一种高级技术。它实质上稀释了可以从跨多个标签的文档中学到的东西,这可能会削弱结果,尤其是在小型数据集中。 - 10-20 个训练阶段在已发表的作品中最为常见,但更多训练阶段可能对较小的数据集特别有帮助。最好在模型初始化时也设置纪元,因为该值也将是 future
infer_vector()
操作的默认值(除非在那里明确传递了另一个值)。 - 您的两种方法的结构有点奇怪 - 保存一个未经训练的模型,但可能会立即训练并覆盖它? (或者您只是想重新使用已保存的带有预建词汇表的模型,以使用不同的数据进行多次训练?) 相较于尝试训练他们。与这个词在更大的世界中的“真正”重要性相比,只出现一次或几次的词在用法上通常是特殊的。保留它们会使模型更大,训练速度更慢,并且比可概括的模式更可能反射(reflect)数据的特质。
关于python - Doc2vec 超越初学者指导,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55335354/