到目前为止,我一直以最基本的方式使用doc2vec,但成效有限.我能够找到类似的文档,但是经常会出现很多误报.我的主要目标是为用户需求建立分类算法.这有助于进行用户需求分析和搜索.
我知道这确实不是一个足够大的数据集,所以有一些问题我需要帮助:
>如何训练一组文档并在另一组文档上构建矢量?
>如何调整模型,特别是为向量空间选择正确的维数
>如何为单词向量创建层次聚类,应该使用一个模型来完成,还是应该创建单独的单词和文档分类模型?
>我没有基础知识,这是在调整如何测量结果质量时的无监督学习?
>最后,是否有推荐的在线资源可以涵盖上述内容.
我一直在用2000个文档中的100个向量调用一次train,每个向量约有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
我希望实现的是一组文档向量,这将有助于从自由文本和层次聚类中查找相似的用户需求,以构建现有需求的导航.
doc2vec
(尤其是my answers)的现有SO答案可能还会使您了解常见错误.)
要在无人监督的情况下调整模型,您实际上需要一些特定于域的可重复评估得分.这可能需要遍历整个群集和最终应用程序,然后将其成功计入“应”为您手工创建的数据子集提供的某些结果上.
为了进行比较,如果您查看原始的“段落矢量”论文,它使用了来自现有搜索引擎的前十个搜索结果片段的现有批次作为训练文档,但是随后根据其对片段的放置程度进行了评分在前十名的前十名中,彼此之间的距离比随机的第3个文档更近.在Wikipedia文章或Arxiv论文上接受培训的后续论文“带段落向量的文档嵌入”,并根据所得模型将文档归入那些系统中相同的预编类别中的程度来调整其模型.
您可以对每个文档矢量使用任何聚类算法. Doc2Vec的输出(作为每个矢量的文档)可以成为下游算法的输入. (我不确定您对“单独的单词和文档分类模型”的含义.您仅描述了文档级的最终需求,可能根本不需要单词向量…尽管某些Doc2Vec模式会创建此类向量)
在训练和冻结模型之后,可以使用infer_vector()方法为新颖文档创建矢量.
查看您的数据/代码的细节,一些观察:
>不清楚您的多列是什么,或者它们应该是单独的文档(而不是合并为一个文档).查看一些完整的行可能有助于弄清数据的本质.
>这是一个很小的数据集-大多数已发布的Doc2Vec作品都可处理数万至数百万个文档.此算法在处理更多数据时效果最佳.
>原始作品仅给每个文档一个唯一的ID标签.尽管gensim Doc2Vec支持为文档提供多个标签,但正如您在此处所做的那样,最好将其视为一种高级技术.它本质上稀释了从文档中跨多个标签学习的内容,这可能会削弱结果,尤其是在小型数据集中.
> 10-20个训练时期是已发表作品中最常见的时期,尽管对于较小的数据集尤其有用.最好也设置模型初始化的时期,因为该值也将用作将来的infer_vector()操作的默认值(除非在那里明确传递了另一个值).
>两种方法的结构有点奇怪-保存未经训练的模型,但是也许马上进行训练并覆盖它? (或者您只是想将已保存的带有预先建立的词汇的模型重新用于具有不同数据的多次训练?)
>与尝试对其进行训练相比,Word2Vec和Doc2Vec通常会更好地丢弃稀有单词(在可行时,默认值min_count = 5或更大).与在更大的世界中单词“真正”的重要性相比,只出现一次或几次的单词在用法上常常是特质的.与通用模式相比,保留它们会使模型更大,训练起来更慢,并且更有可能反映数据的特质.