R语言︱LDA主题模型——最优主题数选取(topicmodels)+LDAvis可视化(l。。。
R语⾔︱LDA主题模型——最优主题数选取
(topicmodels)+LDAvis可视化(l。。。
笔者寄语:在⾃⼰学LDA主题模型时候,发现该模型有这么⼏个未解决的问题:
1、LDA主题数量,多少个才是最优的。
2、作出主题之后,主题-主题,主题与词语之间关联如何衡量。
于是在查阅⼏位⽼师做的成果之后,将他们的成果撮合在⼀起。笔者发现R⾥⾯⽬前有两个包可以做LDA模型,是lda包+topicmodels包,两个包在使⽤的过程中,需要整理的数据都是不⼀样的,所以数据处理会是⼀个不省⼼的过程。
主题模型的概念,⽹络上的博客很多都有介绍,算是⽐较成型的⼀个⽅法,笔者推荐以下博客:
1、
2、
3、
—————————————————————————————————————————
两种的估计⽅法——VEM 以及 gibbs
通常逼近这个后验分布的⽅法可以分为两类:
1. 变异算法(variational algorithms),这是⼀种决定论式的⽅法。变异式算法假设⼀些参数分布,并根据这些理想中的分布与后验的数据相⽐较,并从中到最接近的。由此,将⼀个估计问题转化为最优化问题。最主要的算法是变异式的期望最⼤化算法(variational expectation-maximization,VEM)。这个⽅法是最主要使⽤的⽅法。在R软件的tomicmodels包中被重点使⽤。
2. 基于抽样的算法。抽样的算法,如吉布斯抽样(gibbs sampling)主要是构造⼀个马尔科夫链,从后验的实证的分布中抽取⼀些样本,以之估计后验分布。吉布斯抽样的⽅法在R软件的lda包中⼴泛使⽤。
参考:
————————————————————————————————————————————————————————
R包列举——lda和topicmodel
在R语⾔中,有两个包(package)提供了LDA模型:lda和topicmodels。
lda提供了基于Gibbs采样的经典LDA、MMSB(the mixed-membership stochastic blockmodel )、RTM(Relational Topic Model)和基于VEM(variational expectation-maximization)的sLDA  (supervised LDA)、RTM.。
topicmodels基于包tm,提供LDA_VEM、LDA_Gibbs、CTM_VEM(correlated topics model)三种模型。
另外包textir也提供了其他类型的主题模型。
参考:
—————————————————————————————————————————————————
R语⾔第三包:LDA主题模型⼜有了⼀个新包:text2vec包
LDA主题模型是基于lda包开发的(Jonathan Chang),在下次发布的时候该主题模型的引擎就会嵌⼊到lda包之中,⽬前text2vec开发模型要⽐lda快2倍,⽐topicmodels包快10倍。LSA模型是基于irlab包。
可参考博客:
————————————————————————————————————————
R语⾔第四包:dfrtopics
dfrtopics历史很悠久,但是国内很少有⼈提及这个packages,这个包是通过调⽤java⾥⾯的MALLET 来进⾏运作。
github主页:github/agoldst/dfrtopics
介绍⼏个函数:
1、top_words
##    topic    word weight
##    <int>    <chr>  <int>
## 1      1      two  3602
## 2      1 evidence  1779
## 3      1 original  1472
## 4      1    fact  1452
## 5      1    lines  1410
## 6      1    case  1350
## 7      1    found  1221
## 8      1    line  1086
## 9      1    given  1029
## 10    1 question    968
## # ... with 390 more rows
可以⼀键⽣成相应词的词频表⼀样的内容。
2、逆天功能
查看主题随着时间的趋势波动情况,topic_series
srs <- topic_series(m, breaks="years")
head(srs)
##  topic    pubdate    weight
## 1    1 1906-01-01 0.05454418
## 2    1 1907-01-01 0.02907561
## 3    1 1908-01-01 0.05912942
## 4    1 1909-01-01 0.06755607
## 5    1 1910-01-01 0.04966935
## 6    1 1911-01-01 0.07378674
还有可视化功能
———————————————————————————————————————
⼀、最优主题数选取
本部分来⾃于⼤⾳如霜()团队,⽤不同主体数量下的复杂度以及对数似然值作为评判指标。
对于未知分布q,复杂度的值越⼩,说明模型越好,⽽对数似然值越⼤越好,刚好相反。基于复杂度和对数似然值判断语料库中的主题数量,就是计算不同主题数量下的复杂度和对数似然值之间的变化。可以将复杂度和对数似然值变化的拐点对应的主题数作为标准主题数,拐点以后复杂度和对数似然值的变化区域平缓。观察拐点和趋势需要对数据可视化,因此,分别做复杂度、对数似然值与主题数⽬的趋势图。
关于主题数的选择,⽹络中⼤多是在topicmodels包之上开发⽽得:
fold_num = 10
kv_num = c(5, 10*c(1:5, 10))
seed_num = 2003
smp<-function(cross=fold_num,n,seed)生活百科小常识
{
set.seed(seed)
dd=list()
aa0=sample(rep(1:cross,ceiling(n/cross))[1:n],n)
for (i in 1:cross) dd[[i]]=(1:n)[aa0==i]
return(dd)
}
selectK<-function(dtm,kv=kv_num,SEED=seed_num,cross=fold_num,sp) # change 60 to 15 {
per_ctm=NULL
log_ctm=NULL
for (k in kv)
{
per=NULL
loglik=NULL
for (i in 1:3)  #only run for 3 replications#
为什么音箱没有声音
{
cat("R is running for", "topic", k, "fold", i,
as.character(as.POSIXlt(Sys.time(), "Asia/Shanghai")),"\n")
te=sp[[i]]
tr=setdiff(1:nrow(dtm),te)
# VEM = LDA(dtm[tr, ], k = k, control = list(seed = SEED)),
# VEM_fixed = LDA(dtm[tr,], k = k, control = list(estimate.alpha = FALSE, seed = SEED)),
CTM = CTM(dtm[tr,], k = k,
control = list(seed = SEED, var = list(tol = 10^-4), em = list(tol = 10^-3)))
# Gibbs = LDA(dtm[tr,], k = k, method = "Gibbs",
# control = list(seed = SEED, burnin = 1000,thin = 100, iter = 1000))
per=c(per,perplexity(CTM,newdata=dtm[te,]))
loglik=c(loglik,logLik(CTM,newdata=dtm[te,]))
}
per_ctm=rbind(per_ctm,per)
log_ctm=rbind(log_ctm,loglik)
}
return(list(perplex=per_ctm,loglik=log_ctm))
}
sp=smp(n=nrow(dtm),seed=seed_num)
system.time((ctmK=selectK(dtm=dtm,kv=kv_num,SEED=seed_num,cross=fold_num,sp=sp))) ## plot the perplexity
m_per=apply(ctmK[[1]],1,mean)
m_log=apply(ctmK[[2]],1,mean)
k=c(kv_num)
df = ctmK[[1]]  # perplexity matrix
matplot(k, df, type = c("b"), xlab = "Number of topics",
ylab = "Perplexity", pch=1:5,col = 1, main = '')
legend("bottomright", legend = paste("fold", 1:5), col=1, pch=1:5)
有趣的是计算时间:
> system.time((ctmK=selectK(dtm=dtm,kv=kv_num,SEED=seed_num,cross=fold_num,sp=sp)))
R is running for topic 5 fold 1 2013-08-31 18:26:32
R is running for topic 5 fold 2 2013-08-31 18:26:39
R is running for topic 5 fold 3 2013-08-31 18:26:45
R is running for topic 10 fold 1 2013-08-31 18:26:50
R is running for topic 10 fold 2 2013-08-31 18:27:14
R is running for topic 10 fold 3 2013-08-31 18:27:36
R is running for topic 20 fold 1 2013-08-31 18:27:57中国的科学家
R is running for topic 20 fold 2 2013-08-31 18:29:42
R is running for topic 20 fold 3 2013-08-31 18:32:00
R is running for topic 30 fold 1 2013-08-31 18:33:42
R is running for topic 30 fold 2 2013-08-31 18:37:39
R is running for topic 30 fold 3 2013-08-31 18:45:46
R is running for topic 40 fold 1 2013-08-31 18:52:52
上古卷轴5安息
R is running for topic 40 fold 2 2013-08-31 18:57:26
R is running for topic 40 fold 3 2013-08-31 19:00:31
嚼槟榔R is running for topic 50 fold 1 2013-08-31 19:03:47
R is running for topic 50 fold 2 2013-08-31 19:04:02
R is running for topic 50 fold 3 2013-08-31 19:04:52
R is running for topic 100 fold 1 2013-08-31 19:05:42
R is running for topic 100 fold 2 2013-08-31 19:06:05
R is running for topic 100 fold 3 2013-08-31 19:06:28
user  system elapsed
2417.801.13 2419.28
看⼀下最终绘制的perplexity的图,如下可见,在本例当中,当主题数量为30的时候,perplexity最⼩,模型的最⼤似然率最⾼,由此确定主题数量为30。 (code参考:)吊顶品牌
————————————————————————————————————————
⼆、LDAvis可视化
该包作者探究了主题-主题,主题-词语之间的关联,主题-主题⽤多维标度的⽅式,将两者投影在低维空间,从⽽进⾏⽐较。
主题与词语之间的关联,以前⼀般是直接⽤每个词条的词频、TFIDF来衡量主题与词语的关联,作者⽤了以下的公式(公式整理来⾃)
relevance(term w | topic t)=λ* p(w | t)+(1-λ)* p(w | t)/p(w);
该主题-词语关联度⼤概就是综合了,词频+词语的独特性,两种属性,其中这个λ就是调节两种属性哪
个重要的参数。在0-1之间,可以由研究者⾃⼰调节,当然这个λ究竟多少为好,看具体案例具体分析。
笔者在实践的过程中,因为分词的过程中没有把⽆效词洗⼲净,最后主题数会出现很多垃圾词,通过调节这个λ,碰运⽓可以消除⼀些垃圾词,笔者还没出λ最优办法,基本靠蒙...
打开⽂件需要⽤特殊的浏览器:Mozilla Firefox(如图)

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。