这个论文属于哪里 | 广工软工课程 |
这个作业要求在哪里 | 论文查重作业 |
这个作业的目标 | / |
其它参考文献 | pycharm性能分析、Simhash、余弦相似度 |
目录
作业的地址
实现的思路
可采用的方案
- 将文本的内容进行一个分词处理,这里可以利用自然语言库jieba,将处理好的两份分词结果合并得到一个共同的集合,随后统计每一个分词在总的词库当中的词频信息,根据词频信息得到两个词频向量,随后我们计算这两个向量的余弦相似度获得两个文本的相似程度。
- 利用simhash方法来计算两个文本的相似度,其主要思想是降维,将高维的特征向量映射成低维的特征向量,通过计算两个向量的汉明距离(将一个字符串变换成另一个字符串所需要替换的字符个数)来确定,通常的流程为:分词、hash、加权、合并、降维。缺点:精确度不是很高,而且对文本长度有较高的要求。
方法一的实现
对于余弦相似度的相似度获取的方案,有两种选择方式:
- 直接将文本的内容全部进行分词处理,对所有的词汇计算一个词频再计算它的余弦相似度,当需要判断的文本的词汇量不大的时候效率很高
- 同样是将文本的内容进行分词处理,但是我们并不利用所有的词汇,我们仅仅统计高频的50个词汇权重,仅只用这50个词汇进行余弦度的计算,这个方法当且仅当文本的词汇量大于300的时候才适用否则会有很大的问题。
短文本处理
import numpy
import jieba
def short_analyse(o_file, c_file):
"""
思路:
我们首先读取数据然后对数据进行一个jieba分词,同时根据正则匹配来过滤掉标点
:param o_file: 原始论文的地址
:param c_file: 抄袭论文的地址
:return: 返回两个分词结果的列表
"""
jieba.setLogLevel(jieba.logging.INFO) # 使用中文词库来进行分词,防止报错
o_list = []
c_list = []
try:
with open(o_file, 'r', encoding='utf-8') as f:
o_lines = f.readlines()
for line in o_lines:
pattern = re.compile(u"[^a-zA-Z0-9\u4e00-\u9fa5]") # 正则匹配保留中文字符
target = pattern.sub("", line)
for data in jieba.lcut(target):
o_list.append(data)
except FileNotFoundError:
print(f"{o_file}这个路径下没有文件")
try:
with open(c_file, 'r', encoding='utf-8') as f:
c_lines = f.readlines()
for line in c_lines:
pattern = re.compile(u"[^a-zA-Z0-9\u4e00-\u9fa5]") # 正则匹配保留中文字符
target = pattern.sub("", line)
for data in jieba.lcut(target):
c_list.append(data)
except FileNotFoundError:
print(f"{c_file}这个路径下没有文件")
all_words = list(set(o_list).union(set(c_list)))
print(all_words)
la = []
lb = []
# 转换为向量的形式
for word in all_words:
la.append(o_list.count(word))
lb.append(c_list.count(word))
# 计算余弦相似度
laa = numpy.array(la)
lbb = numpy.array(lb)
cos = (numpy.dot(laa, lbb.T)) / ((math.sqrt(numpy.dot(laa, laa.T))) * (math.sqrt(numpy.dot(lbb, lbb.T))))
print(f"两篇文章的相似度为{cos}")
长文本的处理过程:
直接利用jieba.analyse 可以直接计算出文本中高频词汇的权重
def long_analyse(fname):
try:
with open(fname, 'r', encoding='utf-8') as f:
content = f.read()
except FileNotFoundError:
print(f"{fname}这个路径下并不存在文件")
tags = jieba.analyse.extract_tags(content, 10)
return tags
def compute_sim(o_file, c_file):
i = set(o_file).intersection(set(c_file))
j = set(o_file).union((set(c_file)))
return round(len(i)*100 / len(j), 2)
def ans(o_file, c_file):
a1 = long_analyse(o_file)
a2 = long_analyse(c_file)
return compute_sim(a1, a2)
方法二的实现
Simhash整体流程图如下:
def simhash_demo(text_a, text_b):
"""
求两文本的相似度
:param text_a:
:param text_b:
:return:
"""
try:
with open(text_a, 'r', encoding='utf-8') as f:
content_a = f.read()
except FileNotFoundError:
print(f"{text_a}这个路径下文件不存在")
raise FileNotFoundError
try:
with open(text_b, 'r', encoding='utf-8') as f:
content_b = f.read()
except FileNotFoundError:
print(f"{text_a}这个路径下文件不存在")
raise FileNotFoundError
a_simhash = Simhash(content_a)
b_simhash = Simhash(content_b)
max_hashbit = max(len(bin(a_simhash.value)), len(bin(b_simhash.value)))
# 汉明距离
distince = a_simhash.distance(b_simhash)
# print(distince)
similar = 1 - distince / max_hashbit
return similar
案例分析
案例一
原文本:今天是星期天,天气晴,今天晚上我要去看电影。
抄袭文本:今天是周天,天气晴朗,我晚上要去看电影。
在较短的文本的情况下,利用jieba.analyse相似度计算结果的差别较大,而正常的利用余弦相似度和simhash计算相似度所得的结果很近似。
案例二
原文本:
但我们仍然不能轻视别人的意见。我们说:“不听老人言,吃亏在眼前”,这不是没有道理的。别人“走过的桥”比我们“走过的路”还多,听取别人的意见,等于站在巨人的肩膀上。听别人的意见可以帮我们避开路上的障碍。我们听父母的,听老师的,听医生的,听专家的,就因为闻道有先后,术业有专攻。所以这种时候,我们就需要听取别人的意见。别人的意见除了帮我们规避风险,弥补不足,还可以帮我们带来成功。古代的政治家们为什么需要名臣辅佐,就因为人力有时而穷,不能尽善尽美,而兼听则明。
抄袭文本:
但,我们不能总是听别人的。人归根结底是自由人,是独立人,所以每个人都需要独立自由的思想。我们事事都听别人的意见,总是听别人的意见,就会丧失自己的主见,别人就有机会控制我们的人生。中国的很多家庭悲剧就产生于做子女的没有自己的独立思想,事事听父母的,到最后孩子成为巨婴,丧失独立思想。子女一朝觉醒,就会怨父母事事安排。悲剧就产生了。
从这个样例当中我们其实也可以发现有一些不足之处,就是调用jieba.analyse 这个库函数的时候极其依赖于我们的关键词的数量,它计算的相似度完全是取决于我们关键词的词频的。但是在这个两篇基本上不相似的文章,余弦相似度和simhash却给出了较高的评分,这说明了单从考虑词汇的角度也是存在一定的问题的。
性能分析
代码覆盖率![](https://i-blog.csdnimg.cn/blog_migrate/093d5a1c8c8f47d66c5b33a3ee948a70.png)
个人PSP
*PSP2.1* | *Personal Software Process Stages* | *预估耗时(分钟)* | *实际耗时(分钟)* |
Planning | 计划 | 60 | 60 |
· Estimate | · 估计这个任务需要多少时间 | 300 | 500 |
Development | 开发 | 200 | 300 |
· Analysis | · 需求分析 (包括学习新技术) | 120 | 120 |
· Design Spec | · 生成设计文档 | 40 | 50 |
· Design Review | · 设计复审 | 30 | 30 |
· Coding Standard | · 代码规范 (为目前的开发制定合适的规范) | 10 | 10 |
· Design | · 具体设计 | 20 | 30 |
· Coding | · 具体编码 | 200 | 300 |
· Code Review | · 代码复审 | 30 | 40 |
· Test | · 测试(自我测试,修改代码,提交修改) | 60 | 120 |
Reporting | 报告 | 80 | 85 |
· Test Repor | · 测试报告 | 50 | 60 |
· Size Measurement | · 计算工作量 | 20 | 30 |
· Postmortem & Process Improvement Plan | · 事后总结, 并提出过程改进计划 | 20 | 20 |
· 合计 | 1210 | 1755 |