在上一篇文章的最后,我们生成了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:
'''
dictionary, corpus = self.weibo_lda()
model_name = './lda_{}_{}.model'.format(topic_num, data_num)
lda = models.ldamodel.LdaModel.load(model_name)
vis_data = pyLDAvis.gensim.prepare(lda, corpus, dictionary)
pyLDAvis.show(vis_data, open_browser=False)
代码中的变量,都是之前提过的,哈哈哈哈,我猜你忘记了,我再写一遍,dictionary和corpus分别是生成的字典和词袋。lda是读出来的模型。这样依赖,可视化的模型就绘制好了。
正常来说,我们就可以分析数据了,但是我知道你可能有几个问题,首先,这个图花里花哨的,每个部分都是啥意思呀? 其次,我怎么知道这个主题个数就是最好的,我要看7个主题的,8个主题的!
我们先解释上面的图的含义,首先,图的左侧表示的是主题。有几个泡泡就有几个主题。上面我们就有4个主题。图的右侧表示的是每个主题中常出现的单词,就是我们计算一致性和困惑度时用到的。一个好的模型,上面的圈圈(圈圈圆圆圈圈,天天年年天天的我,看着你的脸~ 咦?为什么我可以发语音)之间应该是不重叠的。即表示各个主题之间可以完美的分隔开。从图中可以看出。我们的模型还算不错,为了对比,我又跑了个七个主题的可视化模型。
大家可以看到,7个主题的效果确实没有4个主题的好!
接下来就到了最后一步了。我们需要知道,这几个主题想表达的是什么呢?每个主题都该有自己核心意义吧。这就到了大家小学就学过的看图说话了。我作为5年4班的体育委员,先给大家说下我自己的看法,大家自己训练好模型后,就可以自由发挥了。
主题一的内容是,住院患者对治愈的渴望,对医院外面世界的向往。在这场灾难中亲情的体现。是个人角度
主题二的内容是,则是从国家角度出发。在这场战疫中。国家的作用。全民抗疫,无数的物资流入疫情严重地区
主题三的内容是,这场疫情中,确诊病例,疑似病例的变化情况
主题四的内容是,受灾严重的一些地区相关微博