软件工程第一次编程作业

软件工程 班级链接
作业要求 作业要求链接
作业要求目标 实现论文查重功能

论文查重仓库地址

PSP表格

PSP2.1 Personal Software Process Stages 预估耗时(分钟) 实际耗时(分钟)
Planning 计划 60 30
Estimate 估计这个任务需要多少时间 1860 1865
Development 开发 600 480
Analysis 需求分析 (包括学习新技术) 600 600
Design Spec 生成设计文档 120 180
Design Review 设计复审 30 60
Coding Standard 代码规范 (为目前的开发制定合适的规范) 30 15
Design 具体设计 60 80
Coding 具体编码 600 480
Code Review 代码复审 30 65
Test 测试(自我测试,修改代码,提交修改) 120 180
Reporting 报告 60 15
Test Report 测试报告 60 30
Size Measurement 计算工作量 60 120
Postmortem & Process Improvement Plan 事后总结, 并提出过程改进计划 60 10
合计 1860 1865

设计过程

需求分析

  • 一开始觉得要实现一个论文查重系统有很多的功能需要实现,不过搜索了一下资料发现其实很多功能调用已有的接口就可以实现。
    研究了几个方法,一个是用SimHash算法然后算海明距离。SiMHash主要有分词Hash加权合并降维几个步骤,然后用海明距离算相似度。

    不过后面选择了比较多人用的通过jieba分词然后用余弦相似度来算相似度。搜索资料过程中发现Gensim库是一个比较擅于处理自然语言的工具包,同时Gensim支持文档的流式处理,可优化内存于是决定使用。但是实际运用过程中发现调用的接口对于我来说还是比较难学习。。。


设计文档

我先是了解了下Gensim的原理

  1. 安装Gensim

pip install gensim

  1. 预处理语料:使用gensim提供的预处理函数来对文本进行预处理。这些预处理函数可以删除标点符号、停用词和数字,将文本转换为小写,并使用词干提取器将单词转换为其基本形式。
    def preprocess(text):
        return preprocess_string(text)
    
    original_preprocessed = preprocess(original_text)
    plagiarized_preprocessed = preprocess(plagiarized_text)

实际使用发现这个功能并没有很好的处理好,也是导致论文查重率结果异常的模块

  1. 创建文档对象:使用gensim的corpora.Dictionary类创建文档对象。将预处理的文本作为输入,并使用字典的add_documents()方法将其添加到文档对象中。

dictionary = corpora.Dictionary()
dictionary.add_documents([original_preprocessed, plagiarized_preprocessed])
  1. 创建语料库,将文本转换为稀疏向量:使用字典的doc2bow()方法将预处理的文本转换为词袋表示法。这将创建一个稀疏矩阵,其中每行代表一个文档,每列代表一个单词。每个单元格的值表示相应单词在相应文档中出现的次数。
plagiarized_corpus = [dictionary.doc2bow(doc) for doc in [plagiarized_preprocessed]]

doc2bow函数将文本转换为词袋模型,还需使用TF-IDF模型将其转换为向量。:

tfidf = models.TfidfModel(corpus)
  1. 计算相似度

index = similarities.Similarity('index', [original_corpus], num_features=len(dictionary))
similarities = index[plagiarized_corpus][0]

具体设计

  1. 文件的预处理还是使用了jieba分词,一个preprocessed的接口比较麻烦,另一个是处理出来的结果比较异常
    img
def preprocessed(text):
    text = jieba.lcut(text)
    preprocessed = []
    for word in text:
        if (re.match(u"[a-zA-Z0-9\u4e00-\u9fa5]", word)):
            preprocessed.append(word)
        else:
            pass
    return preprocessed

注释:re.match(pattern,string,flags=0)
从一个字符串的开始位置起匹配正则表达式返回match对象
pattern,表示正则中的模式字符串
string,即表示要被处理的字符串

  1. 计算相似度部分在代码中注释了,原理和前面介绍的差不多,但是没有用TF-IDF模型,接口还需要研究一下
    texts=[original_preprocessed,plagiarized_preprocessed]
    dictionary = corpora.Dictionary(texts)
    corpus = [dictionary.doc2bow(text) for text in texts]
    similarity = similarities.Similarity('-Similarity-index', corpus, num_features=len(dictionary))
    test_corpus_1 = dictionary.doc2bow(original_preprocessed)
    cosine_sim = similarity[test_corpus_1][1]
    return cosine_sim
  1. 部分结果
    与orig_0.8_dis_7.txt
    img

    与orig_0.8_dis_15.txt
    img

    与orig_0.8_rep.txt
    img

计算模块接口部分的性能

使用了SnakeViz
使用 cProfile 生成统计文件
python -m cProfile -o test.profile main.py

用 SnakeViz 对 cProfile 进行可视化
snakeviz test.profile

img
img
img

测试用例

测试了一下主要功能,输入了两篇一样的文本,测试similarity的值是否为1
python -m unittest
img
OK

代码覆盖率

coverage run test.py
coverage report
img
coverage html -d covhtml
img
img

posted @ 2023-03-14 23:36  x;  阅读(52)  评论(0)    收藏  举报