前言
本文涉及代码已上传个人GitHub
题目:论文查重
描述如下:
设计一个论文查重算法,给出一个原文文件和一个在这份原文上经过了增删改的抄袭版论文的文件,在答案文件中输出其重复率。
原文示例:今天是星期天,天气晴,今天晚上我要去看电影。
抄袭版示例:今天是周天,天气晴朗,我晚上要去看电影。
要求输入输出采用文件输入输出,规范如下:
从命令行参数给出:论文原文的文件的绝对路径。
从命令行参数给出:抄袭版论文的文件的绝对路径。
从命令行参数给出:输出的答案文件的绝对路径。
我们提供一份样例,课堂上下发,上传到班级群,使用方法是:orig.txt是原文,其他orig_add.txt等均为抄袭版论文。
注意:答案文件中输出的答案为浮点型,精确到小数点后两位
查询网上文章,总结出实现思路:
先将待处理的数据(中文文章)进行分词,得到一个存储若干个词汇的列表
接着计算并记录出列表中词汇对应出现的次数,将这些次数列出来即可认为我们得到了一个向量
将两个数据对应的向量代入夹角余弦定理
计算的值意义为两向量的偏移度,这里也即对应两个数据的相似度
除了余弦定理求相似度,还可以使用欧氏距离、海明距离等
所用接口
jieba.cut
用于对中文句子进行分词,功能非常强大,详细功能见GitHub
该方法提供多种分词模式供选择,这里只需用到默认最简单的“精确模式”。
代码:
seg_list = jieba.cut("他来到了网易杭研大厦") # 默认是精确模式
print(", ".join(seg_list))
运行结果:
他, 来到, 了, 网易, 杭研, 大厦
re.match
由于对比对象为中文或英文单词,因此应该对读取到的文件数据中存在的换行符\n、标点符号过滤掉,这里选择用正则表达式来匹配符合的数据。
代码:
def filter(str):
str = jieba.lcut(str)
result = []
for tags in str:
if (re.match(u"[a-zA-Z0-9\u4e00-\u9fa5]", tags)):
result.append(tags)
else:
pass
return result
这里正则表达式为u"[a-zA-Z0-9\u4e00-\u9fa5]",也即对jieba.cut分词之后的列表中的值,只保留英文a-zA-z、数字0-9和中文\u4e00-\u9fa5的结果。
gensim.dictionary.doc2bow
Doc2Bow是gensim中封装的一个方法,主要用于实现Bow模型。
Bag-of-words model (BoW model) 最早出现在自然语言处理(Natural Language Processing)和信息检索(Information Retrieval)领域.。该模型忽略掉文本的语法和语序等要素,将其仅仅看作是若干个词汇的集合,文档中每个单词的出现都是独立的。
例如:
text1='John likes to watch movies. Mary likes too.'
text2='John also likes to watch football games.'
基于上述两个文档中出现的单词,构建如下一个词典 (dictionary):
{"John": 1, "likes": 2,"to": 3, "watch": 4, "movies": 5,"also": 6, "fo