软件工程第二次编程作业
个人项目作业-论文查重
- 这个作业属于哪个课程: 双学位22级 (广东工业大学)
- 这个作业要求在哪里: 个人项目作业-论文查重
- 这个作业的目标: 开发一个论文查重软件,并通过Git提交到远程代码库,熟悉软件开发流程
- 其他参考文献:
- 现代软件工程讲义 2 工程师的能力评估和发展
- Commit message 和 Change log 编写指南
- 现代软件工程讲义 2 开发技术 - 单元测试 & 回归测试
目录
- 个人项目作业-论文查重
- 模块接口的设计与实现过程
- 计算模块接口部分的性能改进
- 计算模块部分单元测试展示
- 计算模块部分异常处理说明
- PSP表格
- 链接
模块接口的设计与实现过程
本项目是一个基于 Node.js 的论文查重工具,通过命令行接收输入文件路径并输出相似度结果。核心代码位于 Paper_Check_Api.js 文件中。
核心模块与功能:
Paper_Check_Api.js: 主脚本文件,包含了所有核心查重逻辑和命令行接口处理。- 依赖:
fs(Node.js内置文件系统模块) 用于文件读写,segmentit用于中文分词.
- 依赖:
- 文本预处理 (
preprocessTextfunction):- 接收文本字符串作为输入.
- 使用
segmentit.doSegment()进行中文分词. - 通过正则表达式
/[^\w\s]/g去除标点符号. - 将文本转换为小写,以保证比较的一致性.
- 返回分词后的词语数组.
- Jaccard 相似度计算 (
jaccardSimilarityfunction):- 接收两个词语集合 (Set) 作为输入.
- 计算两个集合的交集大小和并集大小.
- 相似度 = (交集大小) / (并集大小).
- 如果并集大小为0,则相似度为0.
- 余弦相似度计算 (
cosineSimilarityfunction):- 接收两个分词后的词语数组作为输入.
- 构建包含两个文本所有词语的词汇表 (Set).
- 将输入文本转换为基于词汇表的词频向量.
- 计算向量的点积.
- 计算每个向量的模长.
- 相似度 = 点积 / (模长1 * 模长2).
- 如果任一模长为0,则相似度为0.
- 最终相似度评分 (
calculateSimilarityfunction):- 接收两个原始文本字符串作为输入.
- 对两个文本分别进行预处理,得到分词后的词语数组.
- 计算 Jaccard 相似度 (将分词数组转换为 Set 后计算).
- 计算余弦相似度 (使用分词数组计算).
- 最终相似度 = (Jaccard 相似度 * 0.4) + (余弦相似度 * 0.6).
- 结果保留两位小数.
- 主查重逻辑与文件操作 (
checkPlagiarismfunction):- 接收原文文件路径、抄袭版文件路径和输出文件路径作为参数.
- 使用
fs.readFileSync读取原文和抄袭版文件的内容 (UTF-8编码). - 调用
calculateSimilarity计算相似度得分. - 使用
fs.writeFileSync将计算得到的相似度结果写入指定的输出文件. - 在控制台打印查重结果和输出文件路径.
- 命令行接口:
- 脚本通过
process.argv接收命令行参数. - 期望参数为:原文文件路径、抄袭版文件路径、输出文件路径.
- 如果参数数量不正确,会打印用法提示并退出程序.
- 脚本通过
算法关键:
- 文本输入与读取:程序通过命令行参数获取原文和抄袭版论文的文件路径,以及一个用于保存结果的输出文件路径. 使用
fs.readFileSync读取文本内容. - 预处理:对读取的文本进行标准化处理,包括使用
segmentit进行中文分词、去除标点符号、统一转换为小写字母,以减少噪音对相似度计算的干扰. - 相似度计算:
- Jaccard 相似度:基于词语集合的比较,衡量的是两个文本词语的重合程度.
- 余弦相似度:将文本转换为词频向量,通过计算向量间的夹角余弦值来衡量文本在内容上的相似性.
- 加权融合:将 Jaccard 相似度和余弦相似度进行加权平均(Jaccard 权重0.4,余弦权重0.6)得到最终的相似度评分,该评分更能综合反映文本间的相似程度.
- 结果输出:将最终计算得到的相似度评分(保留两位小数)写入到指定的输出文件中.
计算模块接口部分的性能改进
根据项目 README.md 的开发日志,项目在相似度计算方面进行了迭代改进:
- 第一版:最初采用 Jaccard 相似度算法,但分词方式基于空格,这对于中文文本处理来说误差较大,效果不理想.
- 第二版:
- 分词优化:
README.md中提到“故更改为nodejieba进行分词”. 然而,当前提供的Paper_Check_Api.js代码中实际使用的是segmentit分词库. 无论具体库的选型如何变化,其核心目标是采用更适合中文处理的分词器来提高准确性。segmentit库被用于当前版本中进行分词. - 引入余弦相似度:为了更准确地度量文本相似性,引入了余弦相似度算法.
- 数据预处理增强:增加了去除标点符号、统一大小写的步骤,以减少文本噪音对计算结果的干扰.
- 综合评分:最终的相似度评分结合了 Jaccard 相似度和余弦相似度的结果,并赋予不同权重(Jaccard 0.4, Cosine 0.6).
- 分词优化:
这些改进旨在提升查重算法的准确性和鲁棒性,特别是针对中文文本的特性。
计算模块部分单元测试展示
本项目包含一个 Bash 脚本 testText.sh 用于自动化测试查重API的功能.
测试脚本 (testText.sh) 逻辑:
- 测试数据定义:脚本内置了10组预定义的中文原文句子和对应的“抄袭版”句子,用于模拟不同的查重场景.
original_sentences: 包含10条原文句子.plagiarized_sentences: 包含10条对应的疑似抄袭句子.
- 测试执行循环:脚本通过一个循环,遍历这10组测试数据.
- 在每次迭代中,脚本首先将当前的一对原文和抄袭版句子分别写入临时的
orig.txt和plagiarized.txt文件中. - 然后,调用核心查重脚本
node Paper_Check_Api.js orig.txt plagiarized.txt output.txt来处理这两个文件,并将结果输出到output.txt. - 脚本从
output.txt文件中读取计算出的相似度结果.
- 在每次迭代中,脚本首先将当前的一对原文和抄袭版句子分别写入临时的
- 结果展示:将原文、抄袭版和计算得到的重复率格式化后打印到控制台,形成一个清晰的表格视图.
- 环境清理:在每次测试迭代完成后,脚本会删除生成的临时文件 (
orig.txt,plagiarized.txt,output.txt),保持测试环境的整洁.
测试目标:
testText.sh 主要测试 Paper_Check_Api.js 的端到端功能,包括:
- 正确读取输入文件。
- 执行文本预处理、分词。
- 正确计算 Jaccard 和余弦相似度。
- 根据加权公式得出最终相似度。
- 将结果正确写入输出文件。
- 命令行参数的接收与处理。
测试输出示例 :
+-----------------+-----------------+----------+
| 原文 | 抄袭版 | 重复率 |
+-----------------+-----------------+----------+
| 今天,是星期天 | 今天是周天 | 0.xx |
| 天气很晴 | 天气很好 | 0.yy |
......
+-----------------+-----------------+----------+
这个测试脚本提供了一种简单有效的方式来验证查重 API 在不同输入下的行为和计算结果的合理性。
计算模块部分异常处理说明
Paper_Check_Api.js 中包含了基本的异常处理机制:
- 文件操作及核心逻辑错误:
- 在
checkPlagiarism函数中,文件读取 (fs.readFileSync)、相似度计算 (calculateSimilarity) 以及文件写入 (fs.writeFileSync) 的核心操作被包裹在一个try...catch块中. - 如果在这个过程中发生任何错误(例如,文件不存在、读取权限问题、计算过程中的意外错误等),
catch块会捕获这个错误. - 捕获到错误后,会在控制台打印错误信息
console.error('发生错误:', error);,帮助用户定位问题.
- 在
- 命令行参数校验:
- 在脚本的入口处,会检查接收到的命令行参数数量
process.argv.length是否为5(脚本名 + 3个路径参数). - 如果不等于5,说明用户提供的参数不符合要求,脚本会向控制台输出正确的用法提示:
console.log('用法: node Paper_Check_Api.js <原文文件路径> <抄袭版文件路径> <输出文件路径>');. - 随后,通过
process.exit(1)终止程序,表示执行出错.
- 在脚本的入口处,会检查接收到的命令行参数数量
目前,异常处理主要集中在I/O操作和参数合法性检查上。更细致的异常类型(如空文件内容、分词器初始化失败等)可以作为未来改进方向。
PSP表格
| PSP2.1 Personal Software Process Stages | 预估耗时(分钟) | 实际耗时(分钟) |
|---|---|---|
| Planning 计划 | ||
| · Estimate | 5 | 3 |
| · 估计这个任务需要多少时间 | ||
| Development 开发 | ||
| · Analysis | 5 | 8 |
| · 需求分析 (包括学习新技术) | ||
| · Design Spec | 15 | 20 |
| · 生成设计文档 | ||
| · Design Review | 5 | 4 |
| · 设计复审 | ||
| · Coding Standard | 5 | 2 |
| · 代码规范 (为目前的开发制定合适的规范) | ||
| · Design | 10 | 15 |
| · 具体设计 | ||
| · Coding | 30 | 40 |
| · 具体编码 | ||
| · Code Review | 10 | 20 |
| · 代码复审 | ||
| · Test | 15 | 35 |
| · 测试(自我测试,修改代码,提交修改) | ||
| Reporting 报告 | ||
| · Test Report | 10 | 5 |
| · 测试报告 | ||
| · Size Measurement | 5 | 3 |
| · 计算工作量 | ||
| · Postmortem & Process Improvement Plan | 30 | 35 |
| · 事后总结, 并提出过程改进计划 | ||
| · 合计 | 145 | 190 |
链接
- 项目代码库 (示例链接):
https://github.com/OokukiooO/thesisWeightingSystem.git

浙公网安备 33010602011771号