lda sklearn实现

scikit-learn LDA

LDA主题模型的类在sklearn.decomposition.LatentDirichletAllocation包中

主要参数

  1. n_components: 即我们的隐含主题数,需要调参。的大小取决于我们对主题划分的需求,比如我们只需要类似区分是动物,植物,还是非生物这样的粗粒度需求,那么值可以取的很小,个位数即可。如果我们的目标是类似区分不同的动物以及不同的植物,不同的非生物这样的细粒度需求,则值需要取的很大,比如上千上万。此时要求我们的训练文档数量要非常的多。
  2. doc_topic_prior:即我们的文档主题先验Dirichlet分布的参数。一般如果我们没有主题分布的先验知识,可以使用默认值1/。
  3. topic_word_prior:即我们的主题词先验Dirichlet分布的参数。一般如果我们没有主题分布的先验知识,可以使用默认值 1/.
  4. learning_method: 即LDA的求解算法。有 ‘batch’ 和 ‘online’两种选择。 ‘batch’即我们在原理篇讲的变分推断EM算法,而"online"即在线变分推断EM算法,在"batch"的基础上引入了分步训练,将训练样本分批,逐步一批批的用样本更新主题词分布的算法。默认是"online"。选择了‘online’则我们可以在训练时使用partial_fit函数分布训练。不过在scikit-learn 0.20版本中默认算法会改回到"batch"。建议样本量不大只是用来学习的话用"batch"比较好,这样可以少很多参数要调。而样本太多太大的话,"online"则是首选了。
  5. learning、_decay:仅仅在算法使用"online"时有意义,取值最好在(0.5, 1.0],以保证"online"算法渐进的收敛。主要控制"online"算法的学习率,默认是0.7。一般不用修改这个参数。
  6. learning_offset:仅仅在算法使用"online"时有意义,取值要大于1。用来减小前面训练样本批次对最终模型的影响。
  7. max_iter :EM算法的最大迭代次数。
  8. total_samples:仅仅在算法使用"online"时有意义, 即分步训练时每一批文档样本的数量。在使用partial_fit函数时需要。
  9. batch_size: 仅仅在算法使用"online"时有意义, 即每次EM算法迭代时使用的文档样本的数量。
  10. mean_change_tol :即E步更新变分参数的阈值,所有变分参数更新小于阈值则E步结束,转入M步。一般不用修改默认值。
  11. max_doc_update_iter: 即E步更新变分参数的最大迭代次数,如果E步迭代次数达到阈值,则转入M步。

从上面可以看出,如果learning_method使用"batch"算法,则需要注意的参数较少,则如果使用"online",则需要注意"learning_decay", "learning_offset",“total_samples”和“batch_size”等参数。无论是"batch"还是"online", n_topics(), doc_topic_prior(), topic_word_prior()都要注意。如果没有先验知识,则主要关注与主题数。可以说,主题数是LDA主题模型最重要的超参数。

参考代码

  • 文档nlp_test0.txt内容:

沙瑞金赞叹易学习的胸怀,是金山的百姓有福,可是这件事对李达康的触动很大。易学习又回忆起他们三人分开的前一晚,大家一起喝酒话别,易学习被降职到道口县当县长,王大路下海经商,李达康连连赔礼道歉,觉得对不起大家,他最对不起的是王大路,就和易学习一起给王大路凑了5万块钱,王大路自己东挪西撮了5万块,开始下海经商。没想到后来王大路竟然做得风生水起。沙瑞金觉得他们三人,在困难时期还能以沫相助,很不容易。

  • 文档nlp_test2.txt内容:

沙瑞金向毛娅打听他们家在京州的别墅,毛娅笑着说,王大路事业有成之后,要给欧阳菁和她公司的股权,她们没有要,王大路就在京州帝豪园买了三套别墅,可是李达康和易学习都不要,这些房子都在王大路的名下,欧阳菁好像去住过,毛娅不想去,她觉得房子太大很浪费,自己家住得就很踏实。

  • 文档nlp_test4.txt内容:

347年(永和三年)三月,桓温兵至彭模(今四川彭山东南),留下参军周楚、孙盛看守辎重,自己亲率步兵直攻成都。同月,成汉将领李福袭击彭模,结果被孙盛等人击退;而桓温三战三胜,一直逼近成都。

# -*- coding: utf-8 -*-

import jieba
from sklearn.feature_extraction.text import TfidfVectorizer
from sklearn.feature_extraction.text import CountVectorizer
from sklearn.decomposition import LatentDirichletAllocation


jieba.suggest_freq('沙瑞金', True)
jieba.suggest_freq('易学习', True)
jieba.suggest_freq('王大路', True)
jieba.suggest_freq('京州', True)

with open('../data/lda/nlp_test0.txt') as f:
    document = f.read()
    
    document_cut = jieba.cut(document)
    result = ' '.join(document_cut)
    with open('../data/lda/nlp_test1.txt', 'w') as f2:
        f2.write(result)
f.close()
f2.close()


#从文件导入停用词表
stpwrdpath = "../data/lda/stop_words.txt"
stpwrd_dic = open(stpwrdpath, 'rb')
stpwrd_content = stpwrd_dic.read()
#将停用词表转换为list  
stpwrdlst = stpwrd_content.splitlines()
stpwrd_dic.close()

with open('../data/lda/nlp_test1.txt') as f3:
    res1 = f3.read()
# print(res1)

#doc2处理
with open('../data/lda/nlp_test2.txt') as f:
    document2 = f.read()
    
    document2_cut = jieba.cut(document2)
    result = ' '.join(document2_cut)
    with open('../data/lda/nlp_test3.txt', 'w') as f2:
        f2.write(result)
f.close()
f2.close()

with open('../data/lda/nlp_test3.txt') as f4:
    res2 = f4.read()
# print res2

jieba.suggest_freq('桓温', True)
with open('../data/lda/nlp_test4.txt') as f:
    document3 = f.read()
    
    document3_cut = jieba.cut(document3)
    result = ' '.join(document3_cut)
    with open('../data/lda/nlp_test5.txt', 'w') as f3:
        f3.write(result)
f.close()
f3.close()

with open('../data/lda//nlp_test5.txt') as f5:
    res3 = f5.read()


# corpus = [res1,res2,res3]
corpus = [res1,res2,res3]
cntVector = CountVectorizer(stop_words=stpwrdlst)
cntTf = cntVector.fit_transform(corpus)
# print(type(cntTf))


lda = LatentDirichletAllocation(n_components=2,learning_offset=50.)
docres = lda.fit_transform(cntTf)

# print(docres)
print(lda.components_)


def print_top_words(model, feature_names, n_top_words):
    #打印每个主题下权重较高的term
    for topic_idx, topic in enumerate(model.components_):
        print("Topic #%d:" % topic_idx)
        print(" ".join([feature_names[i]
                        for i in topic.argsort()[:-n_top_words - 1:-1]]))
    print
    #打印主题-词语分布矩阵
    print (model.components_)

n_top_words=20
tf_feature_names = cntVector.get_feature_names()
print_top_words(lda, tf_feature_names, n_top_words)

你可能感兴趣的:(lda sklearn实现)