Doc2vec超出了初学者的指导

时间:2019-03-25 10:07:38

标签: python dataframe gensim doc2vec

到目前为止,我一直以最基本的方式使用doc2vec,但成效有限。我能够找到类似的文档,但是经常会出现很多误报。我的主要目标是为用户需求建立分类算法。这是为了帮助用户进行需求分析和搜索。

我知道这实际上不是足够大的数据集,所以有一些问题我需要帮助:

  1. 如何训练一组文档,并在另一组文档上构建矢量?
  2. 如何调整模型,特别是为向量空间选择正确的维数
  3. 如何为单词向量创建层次聚类,应该使用一个模型来完成,还是应该创建单独的单词和文档分类模型?
  4. 我没有基本事实,这是在调整如何测量结果质量时的无监督学习?
  5. 最后,是否有任何推荐的在线资源可能涵盖上述内容。

我一直在用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

我希望实现的是一组文档向量,这将有助于从自由文本和层次聚类中查找相似的用户需求,以构建现有需求的导航。

1 个答案:

答案 0 :(得分:2)

您应该查看doc2vec-目录(或viewable online)中与gensim捆绑在一起的docs/notebooks Jupyter笔记本,以获取更多正确使用示例。仔细查看tag doc2vec(尤其是my answers)上的现有SO答案,可能还会使您了解常见错误。)

要在无人监督的情况下调整模型,您实际上需要一些特定于域的可重复评估得分。这可能需要遍历整个群集和最终应用程序,然后将其成功计入“应”为您手工创建的数据子集提供的某些结果上。

为了进行比较,如果您查看原始的“段落向量”论文,它使用了来自现有搜索引擎的前十批搜索结果摘要的现有批次作为训练文档,但是随后根据其放置效果对任何模型进行了评分排名前10位的代码段比随机的第3个文档彼此靠近。在Wikipedia文章或Arxiv论文上接受培训的后续论文“带段落向量的文档嵌入”,并根据所得模型将文档归入那些系统中相同的预编类别中的程度来调整其模型。

您可以对每个文档矢量使用任何聚类算法。 Doc2Vec的输出(作为每个矢量的文档)可以成为下游算法的输入。 (我不确定您对“单独的单词和文档分类模型”的含义。您仅描述了文档级的最终需求,尽管有些Doc2Vec模式,您可能根本不需要单词向量...将创建此类向量。)

模型经过训练和冻结后,可以使用infer_vector()方法为新颖文档创建矢量。

查看数据/代码的细节,一些观察:

  • 目前尚不清楚您的多列是什么,或者它们应该是单独的文档(而不是合并为一个文档)。查看一些完整的行可能有助于弄清数据的本质。
  • 这是一个很小的数据集-大多数已发布的Doc2Vec作品都在数万至数百万个文档上运行。此算法在处理更多数据时效果最佳。
  • 原始作品为每个文档仅提供了一个唯一ID标签。尽管gensim Doc2Vec支持为文档提供多个标签,但正如您在此处所做的那样,最好将其视为一种高级技术。它实质上会稀释从文档中跨多个标签学到的信息,这可能会削弱结果,尤其是在小型数据集中。
  • [li] 10-20个训练时期是已发表作品中最常见的时期,但更多的时期可能对较小的数据集特别有用。最好也设置模型初始化的时期,因为该值也将是将来infer_vector()操作所使用的默认值(除非在那里明确传递了另一个值)。
  • 这两种方法的结构有点奇怪-保存未经训练的模型,但是也许马上进行训练并覆盖它? (或者您只是想将带有预先建立的词汇表的保存模型重新用于具有不同数据的多次训练?)
  • Word2VecDoc2Vec通常比尝试训练稀有单词(默认为min_count=5或实用时更大)更好。与在更大的世界中单词“真正”的重要性相比,只出现一次或几次的单词在用法上常常是特质的。与通用模式相比,保留它们会使模型更大,训练起来更慢,并且更有可能反映数据的特质。