lda 可以处理中文_使用GibbsLDA++实现LDA主题模型

a36228a85ddb2b55869672cb304844d9.png

LDA(Latent Dirichlet Allocation)是由Blei等人在2003年提出来的。LDA是在pLSI的基础上增加了贝叶斯框架,是pLSI变成了贝叶斯主题模型的LDA。

概率模型求参数,当然需要进行参数估计,LDA参数估计的方法有:

  1. 变分贝叶斯推断(VB);
  2. 期望传播(EP);
  3. Collapsed Gibbs Sampling;
  4. Collapsed Variational Bayesian(CVB),结合了Collapsed Gibbs Sampling和Variational Inference两种方法;

这几种方法无论哪种方法,我们所有处理的任务都是相同的,即根据给定的最优化目标函数,得到对参数的估计。

GibbsLDA ++是使用Gibbs采样技术进行参数估计和推理的Latent Dirichlet Allocation(LDA)的C / C ++实现。这里就不过多介绍理,本文主要是使用GIbbsLDA++,后期整理好笔记会写一篇关于LDA理论的文章。

需要注意的我使用的是Linux系统,因为这样使用起来比较简单。

1.准备GibbsLDA++工具

https://sourceforge.net/projects/gibbslda/​sourceforge.net
595db550a907bebb2dd8f4688f1c0a02.png

下载得到下面的压缩包:

9d46876483c015de54b7ab32b025c4f5.png
GibbsLDA++下载后的压缩包

接下来就是要使用命令对压缩包进行解压:

  1. cd ~ (进入用户的家目录)
  2. mkdir LDA (在家目录中创建一个LDA文件)
  3. cd ~/LDA (进入刚刚创建的LDA文件中)
  4. gunzip ~/Downloads/GibbsLDA++-0.2.tar.gz (因为下载后文件在~/Downloads中)
  5. tar -xf ~/Downloads/GibbsLDA++-0.2.tar
  6. ll (可以在LDA文件中查看到GibbsLDA++-0.2文件夹)

71151d33cf34cb8ecae9628a4228e712.png
解压缩的步骤

因为是使用C/C++编写的程序,所以需要进行编译:

  1. cd ~/LDA/GibbsLDA++-0.2/ (进入GibbsLDA++的目录中)
  2. make clean (删除旧的object)
  3. make (编译)

在make的时候,会重新生成objects, 也就说新的object覆盖旧的objects,make clean 是删除旧的objects。所以应该是make已经含有了make clean的功能。但是实际用的时候,比如多次编译调试运行, 有时候必须make clean一下,直接make,上次留下来的错误似乎不能清干净。

之后可能会报两种错误:

237901a674bb520d20ea1df039653b59.png
atof的错误

a391d2844ea581d9cf9e39683b0f74c9.png
print的错误
  • utils.cpp 找不到 'atof'函数,补上 #include <cstdlib>
  • lda.cpp 找不到 'printf' 函数,补上 #include <cstdio>

下面就是解决这两个错误的详细步骤:

  1. cd ~/LDA/GibbsLDA++-0.2/ (进入GibbsLDA++的目录中)
  2. vim src/utils.cpp (使用vim编辑文件)
  3. vim src/lda.cpp (使用vim编辑文件)

319005c4bf73172d060a8e9dedb891ae.png
对utils.cpp的处理

d04102c7bbaf3f833163b4ac9e7b6a02.png
对lda.cpp的处理

修改完了错误,再次执行下面两行命令:

  1. make clean
  2. make

前面的准备工作就完成了。

2.准备数据集

关于使用的语料这里有几点需要注意的:

  1. 文件的格式必须是dat。如果原始文件是.txt文件,你可以直接把.txt的后缀名换成.dat即可;
  2. 文件的第一行必须是总共的文章篇数;
  3. 对于文本内容:
    1. 英文:去掉一些停用词以及"for a of the and to in"这样无意义的词;
    2. 中文:进行分词,以及停用词;
  4. 文章格式是ANSI,文章中不能有空行;

我这里使用的是完成分词但是没有去掉停用词的2043篇不同主题的新闻文本(也就是2043行):

a4a7a840edd65469efc19f729b8e7e62.png
分词后的新闻内容

3.执行命令运行程序

3.1 训练

lda -est [-alpha <double>] [-beta <double>] [-ntopics <int>] [-niters <int>] 
[-savestep <int>] [-twords <int>] -dfile <string>

其中([]中的参数是可选的):

  • -est:从头开始估算LDA模型;
  • -alpha <double>:alpha的值,LDA的超参数。alpha的默认值为50 / K(K是主题数),文档~主题的先验分布参数,也就是说在LDA中文档~主题分布不再像pLSI中的唯一确定的,而是一个随机变量,随机变量服从的就是参数为alpha的Dirichlet先验分布;
  • -beta <double>:β的值,也是LDA的超参数。其默认值为0.1,主题~词项的先验分布参数,也就是说在LDA中主题~词项分布不再像pLSI中的唯一确定的,而是一个随机变量,随机变量服从的就是参数为β的Dirichlet先验分布;
  • -ntopics <int>:主题数量。其默认值为100.这取决于输入数据集;
  • -niters <int>:Gibbs采样迭代次数。默认值为2000;
  • -savestep <int>:将LDA模型保存到硬盘的步骤(由Gibbs采样迭代次数计算)。默认值为200;
  • -twords <int>:每个主题最可能的单词数。默认值为零。如果您将此参数设置为大于零的值(例如20),则每次将模型保存到硬盘时,GibbsLDA ++将根据上面的参数savedtep打印出每个主题最多20个最可能单词的列表。
  • -dfile <string>:输入训练数据文件;

训练程序只需要执行下面的命令:

  1. cd ~/LDA/GibbsLDA++-0.2/ (进入GibbsLDA++的目录)
  2. src/lda -est -alpha 0.5 -beta 0.1 -ntopics 100 -niters 1000 -savestep 100 -twords 20 -dfile ~/Desktop/news.dat (因为我的数据文件在桌面上,并且名称为news.dat)

上面命令的含义就是我们执行LDA程序是以参数为alpha = 0.5的先验Dirichlet分布选择文档~主题分布,以参数β = 0.1的先验Dirichlet分布选择主题~词项分布,选择100个主题数,然后迭代1000次,每100次输出结果,结果中的主题和词项分布中每一个主题下概率值最大的前20个词项,训练的数据地址~/Desktop/news.dat。

4b9991a7b4c0ce040815e49694059ecc.png
执行迭代1000次,程序完成,然后会保存最终的模型

然后会发现生成了很多文件,因为前面每迭代100次输出保存一次模型:

c6ab0658925de9f0d8aa2614e36660e6.png
每迭代到100输出一个词结果

从结果上来看我们最后也保存了最终的模型(model-final),从上面的一堆文件中可以找到最终模型文件:

0aa28ab71b4c903ed69b17d4c6a746aa.png
最终的模型

既然得到的最终的模型,那现在来看一个这6(还有一个整个过程只有一个的wordmap.txt)文件都表示什么吧:

  • wordmap.txt:是word与id的映射关系表(一共64374个词项)

88d24eb25e724552c63ce869182351b7.png
word与id映射
  • model-final.theta:每篇文档的主题分布(2043 x 100矩阵),2043篇文章,100个主题

ea9a7076b851a8041112027029078729.png
第一篇文档的100个主题概率
  • model-final.phi:每个主题的词项概率分布,一个主题数×词数量的矩阵(我的数据是100×),数据还是挺大的,特征稀疏,每一篇文档的词项数量稀少,所以会有下面的这种状况

e6b456d2ca55d3edb77b61d9bd92f222.png
主题词向量概率
  • model-final.tassign:每篇文章中不同的词语对应的不同的topic的分类,所以共有2043行

dcccd57de7e3d0b4a49e73d927d5c13f.png
文章中的每个单词对应100个主题中的那个主题
  • model-final.twords:这个文件表示了每个主题和主题下对应的词,以及词的概率:

13869c0dcd3e82b8de798ec7506a8157.png
每个主题和主题下对应的词,以及词的概率
  • model-final.others :指的是训练的时候所使用的参数,下面和我们前面的命令中指定的参数一致:

a8f6df20974e92b1b3f1374b3eab7182.png
训练时候参数列表

3.2 测试

前面介绍了使用-est从头重新训练模型的命令,当然还有两个训练模型的命令:

  1. -estc就是在原有模型的基础上,再次训练模型;
  2. -inf就是用已经训练好的模型进行文档的主题分布的推断;

使用-estc命令其实和-est的使用差不多,下面主要介绍一下使用-inf命令使用已经训练好的模型推断新的文章,当然在第一行写上文章的数量以及文件的后缀名为.dat都是不能少的:

1
参考消息 网 报道 洛杉矶 冠 有 冷酷 沉睡 者 GrimSleeper 之 称 的 连环 杀人 事件 在 拖延 超过 年后 嫌犯 终于 在 定罪 曾 在 洛杉矶 警局 停车场 做 过 清洁工 今 已 的 LonnieDavidFranklinJr 在 年前 涉嫌 犯下 起 谋杀 和 起性 侵 被 陪审团 判 有罪 台湾 中 时 电子报 援引 洛杉矶 时报 的 报道 称 当 宣判 罪行 时 嫌犯 面 无表情 令人发指 但 受害者 家人 对于 结果 表示 高兴 他们 说 我们 逮到 他 了 虽然 花 了 长时间 但 感谢 老天爷 的 帮忙 此 案件 拖延 已 久 警方 一直 无法 查出 这个 当时 恶名昭彰 的 冷酷 沉睡 者 甚至 数度 抓 错 人 但 因 嫌犯 儿子 年前 曾 因 案 入狱 让 警方 有 了 意外 的 收获 据 了解 警方 因 在 采集 嫌犯 儿子 DNA 时 意外 发现 他 与 嫌犯 有 血缘关系 最终 因为 这 DNA 证据 得以 将 嫌犯 逮捕 归案 据 了解 嫌犯 被 指控 在 至 期间 曾多次 谋杀 经济 困顿 的 至 的 黑人 女子 被害人 先 遭到 性 侵 之后 在 胸口 中 枪 死亡 再 被装 进 垃圾袋 中 另外 警方 表示 嫌犯 还 在 家中 收藏 了 疑似 为 受害者 的 照片 推断 是 性 侵 后 留给 自己 的 纪念品 此案 经过 的 审理 后 陪审团 在 判决 出炉 以 项 谋杀罪 和 项 谋杀 未遂 罪名 起诉 他 稿件 来源 参考消息 网 

下面看一看命令以及命令的各个参数:

src/lda -inf -dir <string> -model <string> [-niters <int>] 
[-twords <int>] -dfile <string>

其中([]中的参数是可选的):

  • -inf:使用先前估计的LDA模型推断先前未见过的(新)数据;
  • -dir <string>:该目录包含先前估计的模型;
  • -model <string>:先前估计的模型的名称;
  • -niters <int>:用于推理的吉布斯采样迭代次数。默认值为20;
  • -twords <int>:新数据的每个主题最可能的单词数。默认值为零。如果将此参数设置为大于零的值(例如20),GibbsLDA ++将在推断后打印出每个主题最可能出现的前20个单词列表;
  • -dfile <string>:包含新数据的文件;

执行下面的命令,直到迭代完成:

  1. src/lda -inf -dir ~/Desktop/ -model model-final -niters 100 -twords 20 -dfile test_new.txt

这里有几点需要注意的:

  1. -dir是一个目录,也就是包含产生的模型的目录;
  2. -model是先前估计的模型,会发现产生了很多的文件,到底哪个能作为产生模型的名称呢?比如迭代第400次时候产生很多model-00400.[ theta | phi | tassign | twords | others],前面的model-00400就是我们模型的名称,本次实验,我使用的是最后产生的模型,那么模型名称也就是model-final,当然这里我们可以使用任意被我们保存的时刻,比如说使用迭代200次的模型,那么相对应的模型名称就是model-00200;
  3. -dfile是要测试的文件,格式和训练的文件格式相同(.dat后缀,第一行为文章数),注意这里只需要写上文件名称即可(也就是测试文件和模型都需要放在一个目录中,也就是-dir后面的目录下)

1040385e1bd2a00a7721e0c6a991376b.png
迭代100次

c40755377ccfc195243a3d074e1ff9e5.png
测试产生的文件

测试产生的每个文件和训练的时候产生的文件含义一样,这里就不在赘述。

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值