Thanks to visit codestin.com
Credit goes to www.cnblogs.com

第一次个人编程作业

第一次个人编程作业

这个作业属于哪个课程 https://edu.cnblogs.com/campus/gdgy/Class34Grade23ComputerScience
这个作业要求在哪里 https://edu.cnblogs.com/campus/gdgy/Class34Grade23ComputerScience/homework/13477
这个作业的目标 通过设计论文查重系统,体会工程开发流程,实践工程化开发相关知识

1. github地址

https://github.com/Hermionie41111/Hermionie-s-Home/tree/main/3123002706

2. psp表格

PSP2.1 Personal Software Process Stages 预估耗时(分钟) 实际耗时(分钟)
Planning 计划 30 30
· Estimate · 估计这个任务需要多少时间 30 30
Development 开发 575 685
· Analysis · 需求分析(包括学习新技术) 70 90
· Design Spec · 生成设计文档 50 60
· Design Review · 设计复审 25 30
· Coding Standard · 代码规范 (为目前的开发制定合适的规范) 20 25
· Design · 具体设计 40 50
· Coding · 具体编码 190 220
· Code Review · 代码复审 50 60
· Test · 测试(自我测试,修改代码,提交修改) 130 150
Reporting 报告 85 110
· Test Report · 测试报告 35 45
· Size Measurement · 计算工作量 20 25
· Postmortem & Process Improvement Plan · 事后总结, 并提出过程改进计划 30 40
· 合计 690 825

3. 计算模块接口的设计与实现过程

3.1 设计:代码组织与模块关系

本论文查重系统的计算模块采用模块化拆分思想,按 “数据流向” 划分为「工具层」「算法层」和「入口层」,各模块职责清晰且低耦合。
(1)代码组织与模块划分
工具层:utils.py负责 “数据输入输出” 和 “文本预处理”,是算法层的基础支撑。包含两个核心功能:
文件读写(read_file):兼容 UTF-8/GBK 编码,处理文件不存在等异常;
文本分词(segment_text):使用 jieba 分词,过滤标点、停用词和空字符串。
算法层:similarity.py实现核心的相似度计算逻辑,仅依赖工具层的分词结果,与输入输出解耦。核心功能是 calculate_cosine_similarity 函数,通过 “词袋模型 + 余弦定理” 计算文本相似度。
入口层:main.py作为程序入口,负责解析命令行参数,串联工具层和算法层的调用流程(读取文件→计算相似度→输出结果),并处理全局异常。
(2)模块交互关系
各模块通过 “函数调用” 形成单向依赖,无循环依赖,流程清晰:
image
(3)关键函数流程图
calculate_cosine_similarity 是算法核心,负责将分词结果转换为相似度得分,流程如下:
calculate_cosine_similarity 函数执行流程
image
余弦相似度计算流程
image
calculate_cosine_similarity执行步骤
image
函数流程
image

3.2 实现:算法关键与独到之处

(1)算法关键逻辑
本系统采用 “词袋模型 + 余弦相似度” 作为核心算法,适合中文文本查重场景,关键步骤如下:
文本预处理(segment_text)
先通过正则过滤非中文 / 英文 / 数字的字符(如标点、特殊符号),避免无关字符干扰词频统计;
用 jieba 对中文分词(支持混合英文 / 数字的文本),再过滤停用词(如 “的”“是” 等无意义词汇),保留核心词汇。
词频向量构建
合并两个文本的分词结果,构建去重的 “词汇表”(如原文分词为["今天", "天气"],抄袭文为["今天", "晴朗"],词汇表为["今天", "天气", "晴朗"]);
为每个文本生成词频向量(如原文向量为[1, 1, 0],表示 “今天” 出现 1 次,“天气” 出现 1 次,“晴朗” 出现 0 次)。
余弦相似度计算
公式:相似度 = 向量点积 / (向量1模长 × 向量2模长),取值范围 [0,1];
点积:两个向量对应位置元素相乘的和(如1×1 + 1×0 + 0×1 = 1);
模长:向量各元素平方和的平方根(如原文模长为√(1²+1²+0²) = √2)。
(2)算法的独到之处
针对中文文本查重场景,本实现有三点优化设计:
多编码兼容的文件读取read_file 函数先尝试 UTF-8 编码读取,失败则自动切换为 GBK 编码,解决了 Windows 环境下中文文件常见的 “编码错误” 问题,确保不同格式的输入文件都能被正确解析。
精细化的文本清洗相比简单分词,segment_text 增加了 “标点过滤 + 停用词过滤” 双重处理:
正则过滤去除所有非内容字符(如逗号、感叹号),避免 “今天” 和 “今天,” 被视为不同词;
自定义停用词表过滤无意义词汇,减少噪音对相似度计算的干扰(如 “的” 在文本中高频出现但无实际意义)。
边界场景的鲁棒处理针对 “空文本”“纯符号文本” 等极端场景,算法在向量计算前增加判断:若任一文本分词后为空列表,直接返回 0.0,避免后续向量模长为 0 导致的除零错误,确保程序稳定运行。

4. 计算模块接口部分的性能改进

优化前
image
优化后
image

4.1 性能改进时间投入

在计算模块性能优化阶段,累计投入时间约 3 小时,时间分布如下:

瓶颈定位(分析性能图、调试代码):1 小时;
代码优化(缓存设计、向量化改造、数据结构重构):1.5 小时;
验证与复测(功能正确性验证 + 性能对比测试):0.5 小时。

4.2 性能改进思路

通过分析优化前的 SnakeViz 图,发现性能瓶颈集中在文本预处理(preprocess_text)及 jieba 分词的内部逻辑(如cut、_cut_DAG等函数耗时占比高)。结合代码逻辑,preprocess_text存在 “无缓存重复处理”“分词后冗余操作” 的问题,且cosine_similarity_score未利用向量化加速,导致整体处理效率低下。
优化围绕 “减少重复计算、利用高效库加速、优化算法复杂度” 展开,具体措施:

1.文本预处理的缓存优化:
为preprocess_text添加functools.lru_cache内存缓存(以文本内容为缓存键),避免对相同文本重复执行 “分词 + 清洗”。原本重复调用时的O(n)时间复杂度,优化后缓存命中时降至O(1)。

2.余弦相似度的向量化加速:
重构cosine_similarity_score,引入numpy库将 “词频统计→向量点积运算” 改为向量化操作。利用numpy底层 C 实现的矩阵运算,将纯 Python 循环的O(n²)时间复杂度优化为O(n)(n为词表长度),大幅提升大词表场景的运算速度。

3.同义词查询的哈希表优化:
将synonym_database中分散的四大词典(THEME_SYNONYMS等)合并为全局哈希表,使同义词查询从 “多词典遍历(O(4k)复杂度)” 变为 “单次哈希查询(O(1))”,消除冗余遍历开销。

posted @ 2025-09-24 00:29    阅读(21)  评论(0)    收藏  举报