[补遗]零基础小白使用LDA模型

 

一.输入解读:


-est -alpha 0.5 -beta 0.1 -ntopics 70 -niters 2000 -savestep 1000 -twords 15 -dfile 2.nohtml.nospace.seg.cn.nospace

这是我用LDA训练模型时使用的参数,以下为各参数的解读。

 


-est


表示
进行模型估计;另外还有两个可选的为-estc继续估计;还有一个-inf为利用训练好的模型来估计新文档。




-alpha 0.5 -beta 0.1 


这个两个参数涉及了很多看了就头大的公式,直观上比较好理解的引用梁斌penny的说法其中α,大家可以调大调小了试试看,调大了的结果是每个文档接近同一个topic,即让p(wi|topici)发挥的作用小,这样p(di|topici)发挥的作用就大。其中的β,调大的结果是让p(di|topici)发挥的作用变下,而让p(wi|topici)发挥的作用变大,体现在每个topic更集中在几个词汇上面,或者而每个词汇都尽可能的百分百概率转移到一个topic上。


就我个人而言,因为不知道怎么用。所以一直都是选用的0.50.1这两个。


GibbsLDA++的文档中说明了alpha默认使用topic数目除以100.




-ntopics


主题数。一开始比较让我费解的一个问题是这个主题数指的是输入的每一个文档的主题数目还是所有文档组成的整个语料库的主题数目。后来经过王利锋Fandy耐心指导,有了粗浅的认识。这里的主题数目是指整个输入的语料库的主题数,而后对少量文档进行inf的时候,尽管也会按照那么多的主题数进行推断。但是在输出文件.theta会有一个主题文档的分布,我们可以看到这是一个稀疏矩阵,有很多近似于0的数据。只有非零的那几个才是inf的文档的真实主题。因此我们大概可以推测说LDA模型即是用尽可能多训练数据产生尽可能多的主题,如果能够覆盖世界上所有主题,那么inf的结果是最接近真实的那个。所以训练的数据越大越好。




-niters 2000


迭代次数,一般需要1000次以上才能收敛,达到较好的效果。




-savestep 1000


迭代多少轮保存一次。如果训练语料很大的话,建议勤保存。此参数对模型计算结果没有影响。


-twords 15


用以描述该主题的词数,按概率从高到低选取。此参数对模型计算结果没有影响。


-dfile


训练文件。格式第一行是文档篇数,2-N行是每行一篇文档。由于LDA是词袋模型,所以文档的标点,助词,语气词之类对分析没有作用。因此需要对文档做分词,去除停用词和词干化处理。输入的每一行仅包含文档中的实义词即可,看到很多论文只选名词。


关于输入的文档不得不提的是编码问题,浪费我时间最多的问题。使用UTF8编码读入的时候,第一个字符会出现乱码的情况,导致程序提示找不到可利用的文件。


解决办法:1.改用ANS.I编码 2.修改源代码,先把第一行读掉,在第二行写读入文档的数目


est的数据使用ANS.I编码,输出的Wordmaputf8型的,但如果inf的时候输入的数据是ans.1类型的,则无法与wordmap中的词语匹配。并且我使用的GibbsLDA++inf时加入的新词没有处理导致了一个莫名其妙的错误,调试了1个小时在一个if里找到了


// word not found, i.e., word unseen in training data


// do anything? (future decision)


这两行注释仰天长叹……


所以,还是把第一行做别的用处吧,从第二行开始写文档篇数,3-N行写文档。



二.输出解读:


其实输出内容在GibbsLDA++的文档里已经说的很明白了,简单翻译一下吧。


训练后输出会有这些文件:


.others


.phi  


.theta


.tassign


.twords


Wordmap.txt


1..twords


这个文件绝对是看得人最多的因为里面有看得懂的文字..主要是显示了描述每个主题的词语,选取对主题贡献最大的twords(前面的输入参数)个,后面那个数字..姑且认为是贡献率?




2..others


这个也比较好理解,里面保存了训练模型时的参数。其中nwords是表示输入语料库中去重后的词数。




3.wordmap.txt


保存了每个词语和它对应的整数,在计算的时候程序会先给每个词语按照出现顺序从0开始编号,然后用它的整数编号代入计算。




4..phi 


是一个主题词语分布。每一行代表一个主题,行中每一个数字代表wordmap中的词语对此主题的贡献。



0.007328 0.000014 0.000014 0.001421 0.000014 0.000014


0.000293 0.001132 0.000154 0.000293 0.000293 0.000154(节选部分矩阵,实际上这个矩阵很大)


代表两个主题,wordmap中编号为0的词语对主题0贡献了0.007328,对主题1贡献了0.000293




5..theta


是一个主题文档分布,每一行代表一个文档,行中每一个数字代表某主题对文档的贡献。


例子可以参照上面的。


6..tassign


每一行代表一个输入的文档。表示了该文档中每个词语与其匹配的主题。


836:26 837:29 1087:12 200:12 1241:3 450:26 1242:26 1172:12 910:12 4:22 5:22 6:22 1243:22 1117:26 852:26


此行表示一个输入文档有在wordmap中标号为836,837,1087等的词语组成,这些词语分别被分配给了主题2629,12



三.补遗:


1.由于是隐主题,所以每个主题是由主题下可能的词汇来描述的。没有一个明确的主题词对应每一个主题。(这点曾经困扰过我,不过像我这么笨的人应该不多)




2.
如何判断取的参数是否到位,est出来的模型是否可靠。光靠看来直观判断是不可靠的,在林鸿飞老师的基于LDA模型的博客垃圾评论发现我看到他们采用了一个叫交叉熵的参数来判断,交叉熵越小说明模型越逼近现实。我采用的计算方式是对每个主题词语分布中词语的贡献率取以2为底的对数,然后求平均值。结果在7.2-7.5之间,与林鸿飞老师论文中提及的挺像,不知道是否正确。




3.
因为初始化的时候会有一个随机分配,所以即使利用同一个模型针对同样的文档做inf的结果并不是确定的,但是大体上变动不大。



四.参考:

1.LuHeng的博客

2. 梁斌的博客

3.新浪微博@王利锋Fandy@xueminzhao @白硕SH

4.基于LDA模型的博客垃圾评论发现
林鸿飞

发表评论

电子邮件地址不会被公开。

您可以使用这些HTML标签和属性: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>