基于Python实现 LDA 模型执行简单的文字片段分类任务100010999

题目:从给定的语料库中均匀抽取 200 个段落(每个段落大于 500 个词), 每个段落的标签就是对应段落所属的小说。利用 LDA 模型对于文本建模,并把每个段落表示为主题分布后进行分类。验证与分析分类结果。

背景:

一篇文档可以包含多个主题,所以会有主题分布这个概率. 可以这么理解一篇文章的生成:先以一定的概率选取某个主题,然后再以一定的概率选取该主题下的某个词,不断重复这两步,直到完成整个文档。**LDA 解决的问题就是,分析给定的一篇文章都有什么主题,每个主题出现的占比大小是多少。**LDA 对短文本的主题分类效果比较差。

从宏观上来看,在 LDA 模型中,以 topic 作为中间层,问题可以用如下形式进行表示: P(单词|文档) = P(单词|主题) × P(主题|文档),即 P(w|d) = P(w|t)×P(t|d),其中的 P(单词|文档) 是已知的,直接从给定的文档中就可以计算得出的,P(单词|主题)和 P(主题|文档)是用来进行拟合的,调整这两个分布,直至符合单词文档的实际分布。也就是说,最终需要求的是 P(单词|主题)和P(主题|文档)这两个分布,而真正对文档主题分布有用的,是 P(主题|文档)这个分布,即 P(t|d)。

LDA 模型生成文档步骤:

在 LDA 模型中,一篇文档的生成方式如下:

  1. 从迪利克雷分布α中取样生成文档 i 主题分布θi;

  2. 从主题的多项式分布θi 中取样生成文档i 第j 个词的主题 zi,j;

  3. 从迪利克雷分布β中取样生成主题 zi,j 对应的词语分布Φzi,j;

  4. 从词语的多项式分布Φzi,j 中采样最终生成词语 wi,j。

题解

解题路线:

我们将全部 16 篇金庸小说作为语料进行 LDA 模型构建,在 16 篇小说中随机均匀抽取长度不小于 500 的 248 个片段,将每个小说名作为片段标签。利用已经构筑好的 LDA 模型得到片段的主题分布。利用片段的主题分布与标签,划分训练集和测试集,选择 SVM 模型进行分类任务。

LDA 模型构建:

首先进行数据预处理。将原 16 篇文档整理合并,按行划分,形成合并文档process.txt,接着进行分词并去掉停用词,分词这里使用 jieba 工具包,停用词表这里使用GitHub - goto456/stopwords: 中文常用停用词表(哈工大停用词表、百度停用词表等) 中的中文停用词表。

接着利用 gensim 进行 LDA 模型构建。读取文本数据 59423 条, 利用corpora.Dictionary() 进行词典构建, 利用 doc2bow() 计算文本向量。 利用gensim.models.TfidfModel()进行模型构建,选择构建的主题数量为 20,最后利用gensim.models.ldamodel()进行模型的训练。训练参数设置如下:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-BISRO59A-1685494692606)(20512318.png)]

空间限制,这里列举某 4 个主题前 10 个主要词概率分布。

主题1 孩儿 解药 门派 西域 二哥 道人 经脉 食指 不该 真气
主题1 0.01356217 0.00776301 0.00596932 0.00596429 0.00588608 0.00504877 0.00492453 0.00473175 0.00459261 0.00418687
主题2 少林 少林寺 大师 方丈 弟子 赵钱孙 下山 糊涂 蒙古
主题2 0.01163895 0.01116088 0.01039371 0.00825011 0.00789407 0.00647364 0.00500936 0.0044;57 0.00439796 0.00437793
主题3 师兄 刀法 较量 落下 打听 苍老 惊讶 不忍 岩石
主题3 0.02051514 0.01500916 0.00787329 0.00592551 0.00577093 0.00554486 0.00523014 0.00493958 0.00479358 0.00467229
主题4 壁上 各派 老前辈 伯伯 人均 殿下 奔到 六个
主题4 0.00882462 0.00580436 0.00528313 0.00514028 0.00456607 0.00445411 0.00406776 0.00405323 0.00402811 0.00400323

片段主题分布生成:

由于 LDA 对短文本的主题分类效果比较差。所以摘取的片段不宜过短。我们首先将各个文档分别进行预处理,再进行长段落选择。发现并不是每一个小说都有足够数量的 500 词以上的段落,因此我们将部分小说段落进行合并。共摘取 248 个片段。代码如下

quanji_x=[]
quanji_y=[]
we10=0
for we in range(len(ttext0)):
     jj=0
     for we1 in range(len(ttext0[we])):#每一篇
     	temp=[]
     	if len(jieba.lcut(ttext0[we][we1])) >=40 and we1>we10+40:#某一段大于 10
             for juju in range(40):
                 cd_100=[]
                 cd_99=jieba.lcut(ttext0[we][we1+juju])
                 for dd in cd_99:
                     if dd not in stop_words:
                     cd_100.append(dd)
             	temp+=cd_100
     		assert len(temp)>700
            quanji_x.append(temp)
            quanji_y.append(we)
            jj+=1
     	if jj>30:#大于 20 就下一篇
 			we10 = we1
 			break

所得到的 248 个片段,其中片段最短长度为 50795,最短为 884,平均长度为。可见我们每个片段的词数较多,主题特征相应应该也较多,应该更加有利于后续分类的效果。

依建立片段的词袋模型并输入 LDA 模型得到各个片段的主题分布概率值。将其作为特征值,将片段的所属小说名作为标签,得到总数据集。数据集特征以及标签见 Test.xlsx

SVM 分类:

进行数据集随机划分,代码如下:

X_train, X_test, y_train, y_test = model_selection.train_test_split(X, y, test_size = 0.2, random_state = 1234)

用 sklearn 的 SVM 包进行训练预测,由于测试集合数量不多,这里不一一按照类别进行召回率与精确率计算,直接按照预测正确除以总数计算分类效果。测试集标签以及最终预测结果如下:

1.在 test_size=0.2,random_state=1234 时候,准确率为 96%;

2.在 test_size=0.1,random_state=4231 时候,准确率为 100%。

结论分析:

结果验证了所构建 LDA 模型的有效性,通过对于片段的主题分布进行分类, 可以较为准确的识别出属于哪一篇小说。

通过本次实验,我掌握了构建 LDA 模型的流程,更加熟练得掌握了文档的数据预处理,并且可以利用LDA 模型进行一些简单的文字片段分类任务。

代码汇总:

详细工程文档见。这里展示文档功能划分:

  • pre.py 文档预处理

  • exp3.py 片段生成与 LDA 模型构建以及数据集主题分布生成

  • svm.py 支持向量机分类

?? 资源

在这里插入图片描述

大小: 10.8MB
?? 资源下载:https://download.csdn.net/download/s1t16/87503854
注:如当前文章或代码侵犯了您的权益,请私信作者删除!