软工作业2:个人项目-论文查重(python)
这个作业属于哪个课程 | 计科21级12班 |
---|---|
这个作业要求在哪里 | 个人项目-论文查重(python) |
这个作业的目标 | 个人完成一次查重项目,要求了解项目开发工程,懂得使用PSP表格,完成性能分析以及测试等 |
github地址:https://github.com/xiaoroise/xiaoroise
PSP
PSP2.1 | Personal Software Process Stages | 预估耗时(分钟) | 实际耗时(分钟) |
---|---|---|---|
Planning | 计划 | 60 | 80 |
Estimate | 估计这个任务需要多少时间 | 740 | 750 |
Development | 开发 | 300 | 250 |
Analysis | 需求分析 (包括学习新技术) | 30 | 25 |
Design Spec | 生成设计文档 | 20 | 20 |
Design Review | 设计复审 | 20 | 30 |
Coding Standard | 代码规范 (为目前的开发制定合适的规范) | 20 | 35 |
Design | 具体设计 | 50 | 40 |
Coding | 具体编码 | 50 | 70 |
Code Review | 代码复审 | 20 | 20 |
Test | 测试(自我测试,修改代码,提交修改) | 50 | 40 |
Reporting | 报告 | 40 | 20 |
Test Repor | 测试报告 | 40 | 50 |
Size Measurement | 计算工作量 | 10 | 10 |
Postmortem & Process Improvement Plan | 事后总结, 并提出过程改进计划 | 30 | 20 |
合计 | 740 | 750 |
一、需求
题目:论文查重
描述如下:
设计一个论文查重算法,给出一个原文文件和一个在这份原文上经过了增删改的抄袭版论文的文件,在答案文件中输出其重复率。
原文示例:今天是星期天,天气晴,今天晚上我要去看电影。
抄袭版示例:今天是周天,天气晴朗,我晚上要去看电影。
要求输入输出采用文件输入输出,规范如下:
从命令行参数给出:论文原文的文件的绝对路径。
从命令行参数给出:抄袭版论文的文件的绝对路径。
从命令行参数给出:输出的答案文件的绝对路径。
我们提供一份样例,课堂上下发,上传到班级群,使用方法是:orig.txt是原文,其他orig_add.txt等均为抄袭版论文。
二、计算模块接口的设计与实现过程
项目截图
实现算法:TF-IDF与余弦相似性
使用TF-IDF算法,首先将两篇文章分词,提取各自的关键词,组成一个集合。计算两个向量的余弦相似度,值越大就表示越相似,两篇文章的文章相似度转变为计算两个词频向量的夹角,夹角越小即代表文章相似度越高,夹角越大即代表文章相似度越低。在二维空间中计算两向量间的夹角大小可利用余弦定理,从而扩展到n维空间中也成立。
1、jieba库
jieba是优秀的中文分词第三方库,依靠中文词库确定汉字之间的关联概率,汉字间概率大的组成词组,形成分词结果
导入jieba库,利用jieba.lcut函数实现分词
def filter(str):
# 将读取到的文件内容先进行jieba分词,
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
2、gensim库
使用gensim库gensim进行词典文档集数据处理以及余弦相似度计算
def calc_similarity(text1, text2):
texts = [text1, text2]
# 形成词典
dictionary = gensim.corpora.Dictionary(texts)
# 形成向量
corpus = [dictionary.doc2bow(text) for text in texts]
# print(corpus)
similarity = gensim.similarities.Similarity('-Similarity-index', corpus, num_features=len(dictionary))
test_corpus_1 = dictionary.doc2bow(text1)
cosine_sim = similarity[test_corpus_1][1]
return cosine_sim
三、性能测试及改进
Code Quality Analysis
PyCharm的Inspect Code提供了代码静态审查功能,可以检测出语法错误。在结果检查后将警告等全部清除。
python中的性能分析工具:Line_profiler
函数get_file_contents(path)(提取文章内容)
函数filter(str)(分词)
函数calc_similarity(text1, text2)(余弦相似度计算)
main函数
可见,在项目中,耗时最长的是文件的提取与分词函数的进行,暂时无法再改进性能了。
Python代码覆盖率分析工具Coverage
Coverage是一个Python代码覆盖率分析工具,它可以用于衡量Python测试代码的质量。通过给代码执行带来的覆盖率数据,Coverage可以帮助我们找出测试代码中的漏洞,并且指明哪些代码没有被测试到。以下对代码进行覆盖率测试:
其中覆盖率已达96%,有两句函数并没有执行,如下:
此语句为防止标点等消除出问题后,防止报错处理,无法删减
四、单元测试
使用python单元测试框架:unittest
unittest是python自带的一个单元测试框架,不仅适用于单元测试,还可用于Web、Appium、接口自动化测试用例的开发与执行;此框架可以组织执行测试用例,并且提供了丰富的断言方法,判断测试用例是否执行通过,并生成测试结果。以下为笔者对以下三个函数的测试数据,覆盖率都达到了100%
1、test_get_file.py(文件提取函数)
2、test_jieba.py(将提取的文件分词函数)
3、test_calc_similarity.py(余弦相似性计算函数)
五、异常以及优化处理
在调试阶段,针对使用者方便查重,设置输入文件路径,也防止文件路径出错问题。程序引入os.path.exists()方法用于检验文件是否存在,对文件路径进行判断,如果文件路径不存在,则退出程序。
if __name__ == '__main__':
#path1 = "D:\\pythonProject1\\orig.txt" # 论文原文的文件的绝对路径(作业要求)
#path2 = "D:\\pythonProject1\\orig_0.8_add.txt" # 抄袭版论文的文件的绝对路径
path1 = input("输入论文原文的文件的绝对路径:")
path2 = input("输入抄袭版论文的文件的绝对路径:")
if not os.path.exists(path1):
print("论文原文文件不存在!")
exit()
if not os.path.exists(path2):
print("抄袭版论文文件不存在!")
exit()
main(path1, path2)
六、实测结果
对以下两个文档进行测试结果
论文原文:orig.txt
抄袭版论文:orig_0.8_add.txt