zoukankan      html  css  js  c++  java
  • gensim学习笔记

    1、词向量建模的word2vec模型和用于长文本向量建模的doc2vec模型

      在Gensim中实现word2vec模型非常简单。首先,我们需要将原始的训练语料转化成一个sentence的迭代器;每一次迭代返回的sentence是一个word(utf8格式)的列表:

    class MySentences(object):
        def __init__(self, dirname):
            self.dirname = dirname
    
        def __iter__(self):
            for fname in os.listdir(self.dirname):
                for line in open(os.path.join(self.dirname, fname)):
                    yield line.split()
    
    sentences = MySentences('/some/directory') # a memory-friendly iterator

      接下来,我们用这个迭代器作为输入,构造一个Gensim内建的word2vec模型的对象(即将原始的one-hot向量转化为word2vec向量):

    model = gensim.models.Word2Vec(sentences)

      我们也可以指定模型训练的参数,例如采用的模型(Skip-gram或是CBoW);负采样的个数;embedding向量的维度等。

      Word2vec对象还支持online learning。我们可以将更多的训练数据传递给一个已经训练好的word2vec对象,继续更新模型的参数:

    model = gensim.models.Word2Vec.load('/tmp/mymodel')
    model.train(more_sentences)

      若要查看某一个word对应的word2vec向量,可以将这个word作为索引传递给训练好的模型对象:

    model['computer']  # raw NumPy vector of a word

      Doc2vec是Mikolov在word2vec基础上提出的另一个用于计算长文本向量的工具。它的工作原理与word2vec极为相似——只是将长文本作为一个特殊的token id引入训练语料中。在Gensim中,doc2vec也是继承于word2vec的一个子类。因此,无论是API的参数接口还是调用文本向量的方式,doc2vec与word2vec都极为相似。

      主要的区别是在对输入数据的预处理上。Doc2vec接受一个由LabeledSentence对象组成的迭代器作为其构造函数的输入参数。其中,LabeledSentence是Gensim内建的一个类,它接受两个List作为其初始化的参数:word list和label list。

    from gensim.models.doc2vec import LabeledSentence
    sentence = LabeledSentence(words=[u'some', u'words', u'here'], tags=[u'SENT_1'])

    类似地,可以构造一个迭代器对象,将原始的训练数据文本转化成LabeledSentence对象:

    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])

    准备好训练数据,模型的训练便只是一行命令:

    from gensim.models import Doc2Vec
    model = Doc2Vec(dm=1, size=100, window=5, negative=5, hs=0, min_count=2, workers=4)

    该代码将同时训练word和sentence label的语义向量。如果我们只想训练label向量,可以传入参数train_words=False以固定词向量参数,传入参数训练可用

    model.train(sentense)

    2、ldamodel LDA主题聚类模型

      首先介绍下ldamodel的几个属性和方法。
    • num_terms:获取字典中词的个数,一般就是训练样本中所有不同词的个数;num_topics:获取主题的个数,一般是训练时自己设的,默认值是100;num_updates:获取文档的个数,字面上是获取更新的次数,在这里,每一个文档都是一次更新,所以就是文档个数。
    • get_topic_terms(topicid, topn=10):获取某个主题下的前topn个词语,越相关的在前面,topicid是要显示主题的id值;
    • get_term_topics(word_id, minimum_probability=None):获取某个词最有可能的主题列表,word_id为词id值,minimum_probability为阈值;
    • get_document_topics(bow, minimum_probability=None, minimum_phi_value=None, per_word_topics=False):per_word_topics为False时获取某个文档最有可能具有的主题列表,per_word_topics为True时还得到文档中每个词属于的主题列表,bow为文档,minimum_probability确定主题的阈值,minimum_phi_value判断词属于主题的阈值。

      如果用get_term_topics(word_id),只会获得在整个样本下,某个词属于某些主题的可能性,而并不是针对特定文档的某个词属于某些主题的可能性。显然,使用get_document_topics(bow, per_word_topics=True)可以得到,比如:

      整个返回是个元组,形式为([a],[b],[c]),上图中第一行为a列表,显示的内容是可能性大于minimum_probability的主题及其可能性;第二行为b列表,显示每个词及其可能属于的主题,且其可能性大于minimum_phi_value;第三行为c列表,显示每个词及其可能属于的主题以及可能性。如果只使用get_document_topics(bow)那么只会显示第一行数据。
    算法部分,确实主题是根据上下文有变化的,在gensim包中,应用的是EM算法,但却不是原始论文中使用的变分EM算法,当然主要思想是一致的。就像批最优化与随机最优化的关系,哈夫曼的算法中,没有将所有文档整体带入进行迭代计算,而是对每一篇文档进行迭代计算,使得当前文档具有最优的doc-topic和topic-word分布,直至所有文档迭代完。所以在计算新文档时,只需对新文档再进行一次迭代更新(这也是为什么num_updates等于文档数的,因为每个文档都会更新一次)就可获得新文档相应的分布。


  • 相关阅读:
    hdu 2196(树上点分治)
    hdu 4807(网络流 + 贪心)
    hdu4101
    hdu4216
    hdu 4219, 树形概率DP
    hdu 4127 A*搜索
    hdu 4126
    hdu 5296,15年多校1-7
    poj3436 ACM Computer Factory
    Fence
  • 原文地址:https://www.cnblogs.com/zongfa/p/9556471.html
Copyright © 2011-2022 走看看