个人项目--论文查重

这个作业属于哪个课程 https://edu.cnblogs.com/campus/gdgy/Class34Grade23ComputerScience
这个作业要求在哪里 https://edu.cnblogs.com/campus/gdgy/Class34Grade23ComputerScience/homework/13477
这个作业的目标 实现一个3000字以上论文查重程序
PSP 2.1 阶段 预估耗时 (h) 实际耗时 (h) 差值 (h)
计划 1.5 1.0 -0.5
› 明确需求 0.5 0.5 0.0
› 技术方案选择与评估 0.5 0.3 -0.2
› 制定开发计划与时间估算 0.5 0.2 -0.3
开发 9.5 10.5 +1.0
› 需求分析(细化) 0.5 0.5 0.0
› 技术方案设计 1.0 1.5 +0.5
› 设计复审 0.5 0.5 0.0
› 代码规范 (建立) 0.5 0.5 0.0
› 具体编码 5.5 6.0 +0.5
› 代码复审 0.5 0.5 0.0
› 测试(自我测试) 1.0 1.0 0.0

**计算模块接口的设计与实现过程
我设计并实现了一个基于多特征融合的文本查重系统,该系统采用模块化架构,主要包括文本预处理、特征提取和相似度计算三个核心模块。在预处理阶段,我们利用分词技术和同义词映射实现文本标准化;特征提取阶段结合TF-IDF向量化和关键词提取技术,构建文本的向量表示;相似度计算阶段融合余弦相似度、最长公共子序列和词频分布这几种方法,并采用动态权重分配策略以适应不同程度的抄袭行为。本系统的独到之处在于引入了语义级同义词映射和动态权重调整机制,有效提升了对于改写抄袭的检测能力,实现了从表层字符匹配到深层语义相似度的多层级检测。
项目架构
3123004739
│ calculate_lcs_similarity.py 计算基于最长公共子序列的相似度
│ calculate_similarity.py 计算余弦相似度
│ calculate_word_frequency_similarity.py 计算词频分布相似度
│ main.py 主函数
│ prepare_text.py 准备数据
│ replace_synonyms.py 同义词替换为标准词
│ requirements.txt 环境需要下载的包
│ similarity_calculator.py 计算相似度-集成


├─answers_to_tests 答案存放文件夹

├─tests 测试数据文件夹
项目模块架构图

输入层 → 预处理层 → 特征提取层 → 计算层 → 输出层
    ↓         ↓           ↓         ↓        ↓
命令行   分词/标准化   TF-IDF/关键词  多算法融合  报告生成
参数     同义词映射    N-gram特征   动态权重   文件/终端

计算模块接口部分的性能改进
在完成本项目过程中,针对相似度计算的逻辑修改,首先识别了初始TF-IDF余弦相似度计算对同义词和文本改写过于敏感的问题,导致不同抄袭程度的文本相似度均接近100%。为此,引入了同义词映射模块进行语义级标准化,减少表面改写偏差;结合关键词提取技术聚焦核心内容,降低高频词干扰;采用多特征融合策略,整合TF-IDF余弦相似度、最长公共子序列比例和词频分布相似度,并从静态权重调整为动态权重分配机制,根据初步相似度结果自适应调整各方法权重(如高度相似时降低TF-IDF权重、提高LCS权重),以区分直接复制和结构性改写;同时优化n-gram范围为1-2并增强预处理步骤,最终实现从表层字符匹配到深层语义相似度的多层级检测,提升对不同抄袭程度的区分能力。
性能图
image
image
**计算模块部分单元测试展示
构造测试数据思路
构造测试数据时,需围绕不同抄袭程度设计:以同一源文本为基准,高度抄袭用例保留大量原文长片段和核心结构,中度抄袭用例改写部分表述但保留关键短语,轻度抄袭用例大幅调整句式仅留少量通用词汇,同时确保各用例长度相近,并加入无抄袭的对照文本,以全面验证算法对不同抄袭场景的区分能力。
部分测试代码

  • 测试用例 1(对应 test1.txt→ans1.txt):
    python main.py tests/ori.txt tests/test1.txt answers_to_tests/ans1.txt
  • 测试用例 2(对应 test2.txt→ans2.txt):
    python main.py tests/ori.txt tests/test2.txt answers_to_tests/ans2.txt
    代码覆盖率截图
    image

部分测试数据展示

  • 源文本:“人工智能在教育领域的应用主要体现在个性化学习、智能辅导系统和教育数据挖掘三个方面。个性化学习通过分析学生学习数据,为每个学生定制学习路径;智能辅导系统则能实时解答学生疑问,模拟教师辅导过程。”
  • 高度抄袭(用例 4):仅修改少量虚词,保留完整长句结构,如 “人工智能在教育领域的应用主要体现在个性化学习、智能辅导系统及教育数据挖掘三个方面。个性化学习通过分析学生的学习数据,为每位学生定制学习路径;智能辅导系统可以实时解答学生疑问,模拟教师的辅导过程。”。
  • 轻度抄袭(用例 10):大幅调整结构和词汇,仅保留少量通用概念,如 “教育行业中,AI 技术的使用包括定制化学习方案、自动化答疑工具和学习数据分析等。系统通过收集学生的学习记录来设计个人学习方案,智能工具也能解答疑问,辅助教学工作。”
    **计算模块部分异常说明
  1. 空文本输入
    设计目标
    验证空文本输入不崩溃,返回0.0相似度。
    错误场景
    上传空文件、文件传输丢失内容。
import unittest
from similarity_calculator import calculate_plagiarism_similarity
import jieba

class TestEmptyText(unittest.TestCase):
    def test_empty_input(self):
        empty1 = jieba.lcut("")
        empty2 = jieba.lcut("   ")
        normal = jieba.lcut("人工智能教育")
        
        # 两侧空文本
        self.assertAlmostEqual(calculate_plagiarism_similarity(empty1, empty2), 0.0, delta=0.05)
        # 一侧空文本
        self.assertAlmostEqual(calculate_plagiarism_similarity(empty1, normal), 0.0, delta=0.05)

if __name__ == "__main__":
    unittest.main()

2. 极短文本(过滤后<10词)
设计目标
避免短文本因少量词重合虚高,返回0.05-0.1相似度。
错误场景
上传单句文本、摘要片段。

import unittest
from similarity_calculator import calculate_plagiarism_similarity
import jieba
from word_filter import filter_stop_words

class TestShortText(unittest.TestCase):
    def test_short_input(self):
        short1 = filter_stop_words(jieba.lcut("人工智能助力教育发展"))
        short2 = filter_stop_words(jieba.lcut("人工智能推动教育进步"))
        
        sim = calculate_plagiarism_similarity(short1, short2)
        self.assertTrue(0.05 <= sim <= 0.1)

if __name__ == "__main__":
    unittest.main()

3. 文件路径不存在
设计目标
捕获路径错误并提示,不崩溃。
错误场景
输错文件名、文件被删除。

import unittest
import sys
from main import main
from io import StringIO

class TestFileNotFound(unittest.TestCase):
    def test_invalid_path(self):
        # 模拟错误参数
        sys.argv = ["main.py", "tests/ori.txt", "tests/test99.txt", "answers_to_tests/ans99.txt"]
        sys.stdout = StringIO()
        
        # 验证退出与提示
        with self.assertRaises(SystemExit) as cm:
            main()
        self.assertEqual(cm.exception.code, 1)
        self.assertIn("错误:文件不存在 - tests/test99.txt", sys.stdout.getvalue())

if __name__ == "__main__":
    unittest.main()

4. 文本全为停用词
设计目标
全停用词文本返回0.15-0.2相似度,不报错。
错误场景
上传无意义虚词文本(如“的了在和”)。
单元测试样例

import unittest
from similarity_calculator import calculate_plagiarism_similarity
import jieba
from word_filter import filter_stop_words

class TestAllStopWords(unittest.TestCase):
    def test_all_stop(self):
        stop1 = filter_stop_words(jieba.lcut("的 了 在 和 与"))
        stop2 = filter_stop_words(jieba.lcut("了 的 和 在 及"))
        
        sim = calculate_plagiarism_similarity(stop1, stop2)
        self.assertTrue(0.15 <= sim <= 0.2)

if __name__ == "__main__":
    unittest.main()

5. 文本编码不匹配
设计目标
捕获编码错误(如GBK文件用UTF-8读)并提示。
错误场景
上传GBK编码的TXT文件。

import unittest
from main import read_and_cut
import os

def create_gbk_file(path, content):
    with open(path, "w", encoding="gbk") as f:
        f.write(content)

class TestEncodingMismatch(unittest.TestCase):
    def test_gbk_utf8(self):
        gbk_path = "tests/test_gbk.txt"
        create_gbk_file(gbk_path, "人工智能教育")
        
        # 验证编码错误
        with self.assertRaises(UnicodeDecodeError) as cm:
            read_and_cut(gbk_path)  # 默认UTF-8读取
        self.assertIn("'utf-8' codec can't decode", str(cm.exception))
        
        os.remove(gbk_path)  # 清理临时文件

if __name__ == "__main__":
    unittest.main()

6. 极端重复(全重复/全不重复)
设计目标
全重复返回≥90%相似度,全不重复返回5%-15%。
错误场景
直接复制源文件、上传无关领域文本。

import unittest
from similarity_calculator import calculate_plagiarism_similarity
import jieba
from word_filter import filter_stop_words

class TestExtremeRepeat(unittest.TestCase):
    def setUp(self):
        self.orig = filter_stop_words(jieba.lcut("AI在教育领域应用于个性化学习"))
        self.full_copy = self.orig  # 全重复
        self.no_copy = filter_stop_words(jieba.lcut("AI在医疗领域应用于疾病诊断"))  # 全不重复

    def test_full_repeat(self):
        self.assertGreaterEqual(calculate_plagiarism_similarity(self.orig, self.full_copy), 0.9)

    def test_no_repeat(self):
        sim = calculate_plagiarism_similarity(self.orig, self.no_copy)
        self.assertTrue(0.05 <= sim <= 0.15)

if __name__ == "__main__":
    unittest.main()

github链接
https://github.com/Adilistic7/Adilistic7

posted @ 2025-09-17 20:10  Adilistic  阅读(102)  评论(0)    收藏  举报