主题模型(三):LDA主题个数选择
在上一篇文章的最后,我们生成了15个模型(主题数分别从1到15),然鹅,问题来了,到底多少个主题,才是最好的主题模型呢?到底有没有可以评价一个模型好坏的标准呢?答案肯定是有的,而且还不止一个呢!
先说一个,我最开始做实验的时候用的,肉眼观察法。即通过经验来判断选择几个主题(靠猜),显然这是一个不错的方法。我当时和老大说完,老大一直夸我聪明,并打了我一顿,不说了,医院的WiFi不大好用。
目前比较成熟的判断一个LDA模型是否合理的标准一般有两个,一个是一致性,另一个是困惑度。(因为咱们这篇文章是应用向的,所以一致性和困惑度的计算公式,就不列出来了。有想了解的同学,可以去网上查相关资料或者关注并私信我们。)通俗一点解释下就是,困惑度表示的对于一篇文章来说,我们有多不确定它是属于某个主题的。即主题的个数越多,模型的困惑度就越低,但是注意一点,当主题数很多的时候,生成的模型往往会过拟合,所以不能单纯依靠困惑度来判断一个模型的好坏。这时候我们的另一个判断标准就有作用了。biubiu~一致性!当我们从困惑度了解一个主题数目大致的范围的时候,我们就可以用一致性从这个范围内选择更合适的主题了。
主题个数的选择
有了上面的简单的介绍。我们就可以~~苦逼~~快乐的做实验了。实验思路如下,计算每个模型的困惑度,根据困惑度的实验结果,在合理的范围内进行一致性实验。最后得出效果最好主题个数。
话不多说,计算困惑度也好,计算一致性也罢。我们首先得有模型呀,巧妇难为无米之炊,(如果有的同学不知道怎么生成模型的话,可以去看上一篇文章,那里介绍怎么生成模型,几乎每一行代码都有解释,一定可以看懂的。)所以,我们首先读取上一次训练好的的模型 :
lda = models.ldamodel.LdaModel.load(model_name)
接下来就是重点了。计算困惑度和一致性。
perplexity = lda.log_perplexity(corpus)
cv_tmp = CoherenceModel(model=lda, texts=texts, dictionary=dictionary, coherence='c_v')
好了这篇文章结束了,大家散了吧!!没错,我就是这么短
为了看起来更炫酷一点,我们计算出来15个模型的困惑度并将其可视化表示。这里几乎没有难点,就一个for循环就可以搞定,然后就又到了python时刻(调包),以主题数为横坐标,以困惑度为纵坐标,画图。接下来是代码时间!
def perplexity_visible_model(self, topic_num, data_num):
@description: 绘制困惑度-主题数目曲线
@param {type}
@return:
# texts = self.fenci_data()
_, corpus = self.weibo_lda()
x_list = []
y_list = []
for i in range(1,topic_num):
model_name = './lda_{}_{}.model'.format(i, data_num)
try:
lda = models.ldamodel.LdaModel.load(model_name)-
perplexity = lda.log_perplexity(corpus)
print(perplexity)
x_list.append(i)
y_list.append(perplexity)
except Exception as e:
print(e)
plt.xlabel('num topics')
plt.ylabel('perplexity score')
plt.legend(('perplexity_values'), loc='best')
plt.show()
我把代码跑出来的图贴在这里:
得到这个结果后,我们便可以分析数据了。由前面的分析,我们知道,困惑度是越低越好的,那么我们应该选择主题越多越好,但是,显然这是不对的。因为当主题太多时,我们的模型已经过拟合了。我们发现当主题个数超过8时,模型的困惑度就会一直下降。所以,我们在1-7的主题个数中考虑最终的主题个数。
在已经计算过困惑度后,我们在之前实验的基础上计算一致性并绘制图像,选择最合适的主题。又到了快乐的代码时间:
def visible_model(self, topic_num, data_num):
@description: 可视化模型
@param :topic_num:主题的数量
@param :data_num:数据的量
@return: 可视化lda模型
dictionary, _ = self.weibo_lda()
texts = self.fenci_data()
x_list = []
y_list = []
for i in range(1,topic_num):
model_name = './lda_{}_{}.model'.format(i, data_num)
try:
lda = models.ldamodel.LdaModel.load(model_name)
cv_tmp = CoherenceModel(model=lda, texts=texts, dictionary=dictionary, coherence='c_v')
x_list.append(i)
y_list.append(cv_tmp.get_coherence())
except:
print('没有这个模型:{}'.format(model_name))
plt.plot(x_list, y_list)
plt.xlabel('num topics')
plt.ylabel('coherence score')
plt.legend(('coherence_values'), loc='best')
plt.show()
在上面的图像中,我们可以发现,当主题选择4时,模型的得分最高,所以,正常来说,我们应该选择4个主题的模型,那么选择4个主题到底对不对呢。它生成的模型又是什么样子的呢?有没有办法知道呢?
可视化模型
为了回答上面的问题。我们又开始了快乐的调包生活(没错,只有你想不到,没有python做不到!),生成模型的重点代码,我先给大家单独写出来
vis_data = pyLDAvis.gensim.prepare(lda, corpus, dictionary)
pyLDAvis.show(vis_data, open_browser=False)
这两行代码就是生成可视化模型的核心代码了。也很简单吧。完整的函数以及生成的模型如下:
def visibel(self, topic_num, data_num):
@description: 可视化模型
@param {type}
@return: