基于向量空间模型的中文文本相似度计算
因为在海量数据处理课程上布置了一个计算中文文档相似度的作业,在网上找了一圈没有得到比较直接又漂亮的结局方案,不得已自己动手了 :]。当然也不可能自己从零开始,那就自己去找轮子以及组装轮子的办法咯~
首先明确作业要求所使用来计算文本相似度的是向量空间模型,以我的理解来说这应该算是其中比较基础而简单的一种计算文本相似度的模型,具体看 Wiki 向量空间模型 就好了。然后在附录里发现了一个相关的 Python 开源库 Gensim,这还不是美滋滋~
大致看了一下 Gensim,主要是提供的对于原始文本的向量化处理、TF-IDF 的计算以及一些更深入的潜在语义分析算法等功能,基本上前两个功能就够我们使用了,整个教程也很简短很快能过一遍。
大致思路
结合老师课上讲的内容以及这篇 TF-IDF与余弦相似性的应用(二):找出相似文章 博客,大概理清了使用向量空间模型计算中文文本相似度的步骤:
中文分词(Python 上比较好用的有 Jieba),就相当于英文使用天然的空格进行的分词操作。
构建“词袋”(bag-of-words)。对于短文章来说,可能取要比较的两个文本的分词结果集合就行;但是对于长文章来说这显然是不现实的,那就需要使用 TF-IDF 来分别提取有限特征词来组成关键词库。
以“词袋”为基础生成文本向量,这里一般是使用 TF-IDF 作为词在文档中的权重。
通过计算文本向量之间的余弦来衡量相似度(衡量标准有很多,这里取向量空间模型中的标准方法)。
代码实现
因为拿到的是已经标注过并分好词的语料,所以中文分词这一步骤就不需要自己做了(但其实这是比较复杂的一部分)。我这边的主要的工作就是把语料处理成文档词组列表,后面基本就可以丢给 Gensim 自行处理了。代码以及注释请移步 GitHub。
最后的试验结果是基于平均 170 词的 3148 篇短文章,使用的词袋大小约为 33000,计算文章两两之间的相似度总共耗时约 20s。因为主要计算过程是直接使用了 Gensim 库,所以暂时也没有什么好的优化方法。
语料是老师给的也不好直接放出来,就贴两个找到的相似度比较高的文本的部分内容吧,效果还是不错的:
1 | 19980101-01-001-001/m 迈向/v 充满/v 希望/n 的/u 新/a 世纪/n ——/w 一九九八年/t 新年/t 讲话/n (/w 附/v 图片/n 1/m 张/q )/w |
1 | 19980128-01-002-001/m 在/p 春节/t 团拜会/n 上/f 的/u 讲话/n (/w 附/v 图片/n 1/m 张/q )/w |