翻译:Doc2vec指导

来源:互联网 发布:php获取字符串的位置 编辑:程序博客网 时间:2024/06/07 14:50

说明:新接触Doc2vec,从网上搜了一下用法,总觉得不是很清晰,偶然找到一片国外博客,觉得比较友好。在搜索资料时,深受英语阅读能力低下的困扰,有身在宝藏之中却不识,坐在盛宴桌边却不能动的无力感。所以尝试翻译并保留在这,本人能力有限,如有错误,请重拍。

这是一篇2014年的博客,API有些已经过时,但不影响使用

原文链接:https://rare-technologies.com/doc2vec-tutorial/


在最新更新的gensim 0.10.3版本中,新添加了一个Doc2Vec类。这个类的理论根据,包括这篇指导,都是来自杰出的Tim Emerick 和论文:《Distributed Representations of Sentences and Documents》

Doc2Vec(也叫paragraph2vec, sentence embeddings)继承自wod2vec算法,是一种无监督的学习大量连续文本算法,可以学习段落或者文章。

重要提示:doc2vec在0.12.0版本中做了重要更新。API更简洁,训练速度更快,开放了更多训练参数。下面要介绍的基本用法仍然适用,想要看更多更新请移步:https://github.com/RaRe-Technologies/gensim/blob/develop/docs/notebooks/doc2vec-IMDB.ipynb

引用Tim自己的介绍:

输入

因为Doc2Vec类继承自gensim的word2Vec类,所以许多应用模式是相似的。你可以轻松的选择表示向量的维度,滑动的窗口打下,工作的workers数和几乎所有你在word2vec中可以调整的参数。

其中一个例外是训练方法的不同。在woed2vec中,两种算法的名称是:“continuous bag of words” (cbow) and “skip-gram” (sg);在doc2vec中,响应的算法是:“distributed memory” (dm) and “distributed bag of words” (dbow)。因为在论文中“distributed memory” (dm)效果表现的明显更好,所以doc2vex的默认模式是dm,如果想用dbow模式,可以通过dm=0来选择。

Doc2Vec的输入是LabeledSentence对象的迭代器。每个这样的对象代表一个句子,并由两个列表组成:文本列表和labels列表:

sentence = LabeledSentence(words=[u'some', u'words', u'here'], labels=[u'SENT_1'])

译者注:现在关键字“labels” 已经改成“tags”

算法会调用这个迭代器两次:一次是创建向量,另一次是用输入数据训练模型,学习能在数据集中表示各个文本和labels的向量。

尽管算法允许为一个文本赋予多个labels(我已经尝试过),更流行的使用案例是给每个文本赋予一个能唯一识别的labels。可以通过下面的类,传入一个每行是一个文本的文件来实现:

class LabeledLineSentence(object):   def __init__(self, filename):       self.filename = filename   def __iter__(self):       for uid, line in enumerate(open(filename)):           yield LabeledSentence(words=line.split(), labels=['SENT_%s' % uid])

在doc2vec module模块中,有更通用的LabeledLineSentence类,可以在doc2vec API docs中查看。

训练

Dec2Vec会同时学习文本和labels的表达向量。如果想单独学习文本向量,可以在Doc2Vec类中用train_lbls=False选择。同样的,如果想学习labels向量,保留文本向量不变,可以通过train_words=False选择。

该算法运行时有一个注意点,因为在迭代数据的过程中学习速率下降,仅在LabeledSentence中可见的labels却以固定的学习速度被训练,这经常产生不太理想的训练结果。我通过下面的任一方式获得了比较好的结果:

  1. randomizing the order of input sentences, or
  2. manually controlling the learning rate over the course of several iterations.

例如,想要在10次训练中仅改变学习速率,可按如下方法:

model = Doc2Vec(alpha=0.025, min_alpha=0.025)  # use fixed learning ratemodel.build_vocab(sentences)for epoch in range(10):   model.train(sentences)   model.alpha -= 0.002  # decrease the learning rate   model.min_alpha = model.alpha  # fix the learning rate, no decay

就像word2vec一样,这个算法也是机遇c写的,运行速度相当快。

Radim提示:I wanted to include the obligatory run-on-English-Wikipedia-example at this point, with some timings and code.但是我没有得到计较好的doc2vec模型解释。我们正在努力做一个doc2vec的延展功能,一个不需要从RAM中为每个文档读取向量,并且对一个新的文本能给出新向量的API,更多请Ping me

缓存问题

现在的版本中,所有的label向量分别的存在RAM中,在每个文本一个向量的案例中,需要的RAM会随着文本量线性增加。会不会成为一个问题取决于你的文本量和硬件RAM。

I/O

Doc2Vec的用法和gensim‘s Word2Vec 用法相似,可以保存活着载入训练好的模型,直接用python中的方法活着Doc2Vec中的方法Doc2Vec.save()Doc2Vec.save()

model = Doc2Vec(sentences)...# store the model to mmap-able filesmodel.save('/tmp/my_model.doc2vec')# load the model backmodel_loaded = Doc2Vec.load('/tmp/my_model.doc2vec')

有一些常用的方法:

model.most_similar()model.doesnt_match()model.similarity()

每行的文本和label也向量支持通过model['word']查询,或者通过model.syn0一次查询全部。更多调用方法:See the docs

译者注:自己用model.syn0报错,不知道为啥。


还是应该看原文,下面的有些评论也很有价值

原创粉丝点击