文章相似度检索工具
开发环境
基于Windows操作系统,使用vs进行开发。
项目介绍
功能介绍
本项目实现的是一个根据词频获取两篇文章相似度的工具。文本相似度检索经常使用在文本聚类,文本分类,文本挖掘,信息检索上,像是常见的论文查重工具也都是基于文本相似度进行检索分析的。
本项目分别利用相对词频,tf-idf计算两篇文章的相似度,计算结果较为可靠。
检索原理
基于词频进行文本相似度的检索需要统计词频,构建词频特征向量,利用特征向量夹角余弦来表示文本相似度。步骤可以概括为:分词->统计词频->词频向量->相似度计算。
分词是中文检索要加上的特殊的环节,中文不像英文词之间有空格作为间隔,中文是连贯的,为了词频统计我们需要将其按照语义进行分词。
分词的原理也较为复杂,这里给出一篇讲解分词原理的博客。
https://www.cnblogs.com/BaiYiShaoNian/p/5071802.html
接下来统计词频。但在统计次品的时候要注意不计算停用词的词频。停用词是指没有什么实际含义的词,例如:数字,标点,代词,语气助词,副词,介词,连接词等。我们要先去除文章中的停用词,再统计词频。词频即为单词在文章中出现的次数,词频越大一般可认为该词越重要。
构建词频向量需要对词进行编码,确定统计出来的向量的每一维都该表示相同的词的词频,这样构建出来的向量才有意义。把两个文本中的所有有效词全部编码,对于长文本可以按词频从大到小排序,取前n个关键词,再按照编码构建词频向量。
最后计算向量相似度。这里可以使用欧几里得距离,余弦相似度,曼哈顿距离等来计算。我这里通过余弦相似度来进行计算。公式为:cos(θ) = (A * B) / (||A|| * ||B||)
。
计算文本相似度过程举例:1
2文本1:今天有事,没办法去学校上课了。
文本2:真想去学校上课,但是今天有事,去不了学校了。
分词后:1
2文本1:今天/有事/,/没办法/去/学校/上课/了。
文本2:真想/去/学校/上课/,/但是/今天/有事/,/去不了/学校/了。
去掉停用词后统计有效词的词频:1
2文本1:有事:1,没办法:1,去:1,学校:1,上课:1
文本2:真想:1,去:1,学校:2,上课:1,有事:1,去不了:1
提取所有有效词:1
学校,去,真想,上课,有事,去不了,没办法
对有效词进行编码:1
学校:0,去:1,真想:2,上课:3,有事:4,去不了:5,没办法:6
根据编码构建两个文本的词频向量:1
2
3
4文档1的词频:{[0 : 1], [1 : 1], [2, 0], [3 : 1], [4 : 1], [5 : 0], [6 : 1]}
文档2的词频:{[0 : 2], [1 : 1], [2 : 1], [3 : 1], [4 : 1], [5 : 1], [6 : 0]}
文档1词频向量:{1, 1, 0, 1, 1, 0, 1}
文档2词频向量:{2, 1, 1, 1, 1, 1, 0}
最后计算向量相似度即可。
功能模块
分词模块
分词模块主要利用github上的开源工具结巴分词
完成分词工作,其可以将文本内容按照词义分成词组放到vector
中。但是要注意结巴分词
只支持UTF8编码,而Windows上默认使用GBK编码因此中间我们要想对读取到的文本进行一次转码操作。
词频获取模块
词频获取即遍历分词后的vector
统计词语出现次数即可,注意这里还要过滤掉没有用的停用词。但是这样统计出的词频知识绝对词频,在两篇长度差距较大的文章中可信度角度,因此在这个模块中我将绝对词频 / 总词数 = 相对词频
得出相对词频,相对词频可以提高词频可靠性。同时为了进一步提高可靠度我利用tf-idf
算法二次统计词频。tf-idf = tf * idf
,其中idf
为逆文档率,它表示每一个词重要性的权重,一个词越少见它的值越大,反之越小。这样的词频统计方法是经过大数据分析后的产物,因此可靠程度更高。
排序编码模块
要获取词频向量要先对其进行编码,但是我们不能将文章中所有此都作为编码构建向量,因为那样的向量太长了且没有针对性,因此我选择对两篇文章中出现频率最高的前n个词进行提取,最后根据去重后的n个词进行编码再构建词频向量。
这里需要先对每篇文章中统计好的词频根据词频大小进行排序,得出前n个出现频率最高的词,再将其放到一个容器中进行去重,去重我们可以选择使用set
容器,去重后set
中词就是我们需要构建词频向量的码值。
构建词频向量及计算相似度模块
对两种的两种词频分别构建好码值后,对两篇文章依次利用码值和统计好的词频构建词频向量,构建好词频向量后分别计算两种词频向量的余弦相似度,得出结果。
文件配置模块
检索工具有两种使用模式,我们可以在命令行通过参数直接给入字典位置,两个文章路径直接使用,也可以通过编写配置文件的方式进行使用,配置文件的路径需要在参数中提交。
配置文件中可以配置两篇文章获取码值的大小,字典路径,文件路径等。
项目效果预览
文章相似度检索。
项目中遇到的问题
编码转换
在使用分词工具时发现分词工具无法达到满意的效果,无法将词合理的提取,在网上看了官方说明后发现其仅支持UTF8编码,而Windows默认GBK编码,因此其之间必须进行转码才能协同工作。而转码工作需要用的系统函数,并不能直接从GBK转换至UTF8,需要用宽字符也就是UTF16作为桥梁才能进行转换。转码的编写让我了解了Windows下转码的接口以及宽字符和多字节编码转换的应用。
相对词频
一开始项目利用绝对词频作为词频统计,但是发现如果两篇文章长度有极大差别的情况下,相似度的计算并不准确,于是我考虑计算出相对词频作为依据再进行统计。
为了进一步提高准确率我又在网上学习了idf
逆文档率的作用,从而通过相对词频和tf-idf
两种依据计算文章相似度,提高准确率。
项目扩展方向
文章查重
目前工具仅可以比较两篇文章之间的相似度,而在实际应用中我们往往要比较多篇文章之间的相似度,例如在文章查重的使用上。接下来项目可以进一步扩展为可以查取多篇文章之间的重复度,并且反馈给用户,为了查取效率我们可以开启多线程进行并行查取。在查重后我们还可以显示相似度较高的几组文章,对用户进行提醒,也可以筛选出相似度最高的两篇文章。
文章归纳
对所给文章依次比较得出相似度,相似度较高的文章可以归纳为一类文章,同时我们还可以通过idf
得出文章的关键字,以此为依据对文章进行归纳整理,从而可以将其扩展为一个文章归纳工具。