第二次软工作业

软件工程第二次作业_个人项目
Github连接: mocheen/se_homework: homework

](https://github.com/mocheen/se_homework)

这个作业属于哪个课程 https://edu.cnblogs.com/campus/gdgy/Class12Grade23ComputerScience
这个作业要求在哪里 https://edu.cnblogs.com/campus/gdgy/Class12Grade23ComputerScience/homework/13468
这个作业的目标 体会整个软件的开发过程,同时记录开发过程中的信息

PSP表格:

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

一. 模块与对应函数

模块 对应函数 作用
核心控制 main() 控制整个流程,处理命令行参数
文本处理 load_word_vectors() 加载预训练的中文词向量模型
相似度计算 calculate_similarity_with_embeddings() 使用词向量计算文本相似度
相似度计算 calculate_similarity_tfidf() 使用TF-IDF向量化和余弦相似度计算相似度
相似度计算 calculate_similarity() 主要相似度计算接口,自动选择算法
批量测试 batch_test() 批量测试相似度计算函数

二.计算模块接口的设计

1.接口设计:

项目采用Python实现,使用模块化设计,主要功能包括:

  • 词向量相似度计算:使用预训练的中文词向量模型(sgns.literature.bigram-char)
  • TF-IDF相似度计算:作为备选方案,当词向量模型不可用时使用
  • 中文分词:使用jieba分词库进行中文文本处理
  • 自动回退机制:如果词向量模型未加载,自动回退到TF-IDF方法

2.独到之处:

  • 多算法支持:支持词向量相似度和TF-IDF两种算法
  • 中文优化:使用jieba分词专门处理中文文本
  • 智能回退:当词向量模型不可用时自动使用TF-IDF方法
  • 批量测试:内置批量测试功能,便于性能评估

3.计算模块源代码:

词向量加载模块

def load_word_vectors():
    """
    加载预训练的中文词向量模型
    """
    global word_vectors

    # 模型路径(需要先下载模型)
    model_dir = os.path.join(os.path.dirname(os.path.abspath(__file__)), "models")
    os.makedirs(model_dir, exist_ok=True)
    model_path = os.path.join(model_dir, "sgns.literature.bigram-char")

    if os.path.exists(model_path):
        try:
            print("正在加载中文词向量模型...")
            word_vectors = KeyedVectors.load_word2vec_format(model_path, binary=False)
            print("中文词向量模型加载完成")
            return True
        except Exception as e:
            print(f"加载词向量模型出错: {e}")
    else:
        print(f"中文词向量模型不存在,请下载并保存到: {model_path}")

    return False

词向量相似度计算模块

def calculate_similarity_with_embeddings(original_text: str, plagiarized_text: str) -> float:
    """
    使用词向量计算文本相似度
    """
    # 使用jieba进行分词
    original_words = list(jieba.cut(original_text))
    plagiarized_words = list(jieba.cut(plagiarized_text))

    # 获取每个词的词向量
    original_vectors = [word_vectors[word] for word in original_words if word in word_vectors]
    plagiarized_vectors = [word_vectors[word] for word in plagiarized_words if word in word_vectors]

    # 如果没有有效的向量,返回0
    if not original_vectors or not plagiarized_vectors:
        return 0.0

    # 计算文档向量(词向量的平均值)
    original_doc_vector = np.mean(original_vectors, axis=0).reshape(1, -1)
    plagiarized_doc_vector = np.mean(plagiarized_vectors, axis=0).reshape(1, -1)

    # 计算余弦相似度
    similarity = cosine_similarity(original_doc_vector, plagiarized_doc_vector)

    return similarity[0][0] * 100  # 转换为百分比

TF-IDF相似度计算模块

def calculate_similarity_tfidf(original_text: str, plagiarized_text: str) -> float:
    """
    使用TF-IDF向量化和余弦相似度计算相似度(改进版,使用jieba分词)
    """
    # 使用jieba进行分词,提高中文处理能力
    original_words = " ".join(jieba.cut(original_text))
    plagiarized_words = " ".join(jieba.cut(plagiarized_text))

    vectorizer = TfidfVectorizer()
    tfidf_matrix = vectorizer.fit_transform([original_words, plagiarized_words])
    similarity = cosine_similarity(tfidf_matrix[0:1], tfidf_matrix[1:2])

    return similarity[0][0] * 100  # 转换为百分比

主要计算接口

def calculate_similarity(original_text: str, plagiarized_text: str) -> float:
    """
    计算原文与抄袭版论文的相似度
    如果可用,使用词向量;否则回退到TF-IDF方法
    """
    global word_vectors

    # 如果词向量模型未加载,尝试加载
    if word_vectors is None:
        load_word_vectors()

    # 如果词向量模型已加载,使用词向量方法
    if word_vectors is not None:
        return calculate_similarity_with_embeddings(original_text, plagiarized_text)
    # 否则回退到改进的TF-IDF方法
    else:
        return calculate_similarity_tfidf(original_text, plagiarized_text)

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

改进思路:

  1. 使用jieba分词:相比简单的字符分割,jieba分词能够更准确地识别中文词汇,提高相似度计算的准确性
  2. 支持词向量:词向量能够捕捉语义信息,比TF-IDF更能理解文本的深层含义
  3. 自动回退机制:确保在词向量模型不可用时仍能正常工作

技术栈优势:

  • gensim:提供高效的词向量处理能力
  • scikit-learn:提供成熟的TF-IDF实现
  • jieba:专门针对中文优化的分词工具
  • numpy:提供高效的数值计算能力

四.计算模块测试展示

测试用例设计:

项目包含《活着》小说原文和经过修改的抄袭版本进行测试:

  • 原文文件:orig.txt - 《活着》的完整文本
  • 抄袭版本:orig_08_add.txt - 在原文基础上添加了错误字符和干扰词

预期测试结果:

  • 完全相同的文本:100% 相似度
  • 部分修改的文本:约80-90% 相似度(根据添加的干扰程度)
  • 完全不同的文本:接近0% 相似度

五.异常处理

1.命令行参数异常

应用场景:当用户的输入参数不符合要求时

处理逻辑代码

if len(sys.argv) == 4:  # 包含脚本名称在内共4个参数
    original_file = sys.argv[1]
    plagiarized_file = sys.argv[2]
    answer_file = sys.argv[3]
    # ... 处理文件
else:
    # 如果没有传入命令行参数,执行批量测试
    batch_test()

2.文件读取异常

应用场景:当用户由于输入错路径或其他原因导致无法打开文件时

处理逻辑代码

try:
    # 读取文件内容
    with open(original_file, 'r', encoding='utf-8') as f:
        original_content = f.read()

    with open(plagiarized_file, 'r', encoding='utf-8') as f:
        plagiarized_content = f.read()

    # 计算相似度
    similarity = calculate_similarity(original_content, plagiarized_content)

    # 将结果写入答案文件
    with open(answer_file, 'w', encoding='utf-8') as f:
        f.write(f"{similarity:.2f}")

    print(f"重复率: {similarity:.2f}%")
    print(f"结果已写入: {answer_file}")

except Exception as e:
    print(f"处理文件时出错: {e}")

3.词向量模型异常

应用场景:当词向量模型文件不存在或加载失败时

处理逻辑

  • 自动检测模型文件是否存在
  • 捕获加载过程中的异常
  • 回退到TF-IDF方法
  • 提供清晰的错误信息

六.项目特色

  1. 中文优化:专门针对中文文本处理进行了优化
  2. 多算法支持:支持词向量和TF-IDF两种相似度计算方法
  3. 智能回退:确保系统在各种情况下都能正常工作
  4. 模块化设计:清晰的模块划分,便于维护和扩展
  5. 测试完整:包含完整的测试数据和测试用例

七.依赖环境

项目基于Python 3.12+开发,主要依赖包括:

  • gensim >= 4.3.2
  • jieba >= 0.42.1
  • numpy >= 1.0.0
  • scikit-learn >= 1.6.1
  • scipy == 1.12

posted on 2025-09-21 16:14  nʎuɐƃ  阅读(69)  评论(0)    收藏  举报

导航