个人项目

Github地址

这个作业属于哪个课程 软工2班
这个作业要求在哪里 【作业2】个人项目
这个作业的目标 掌握 GitHub 及 Git 的使用方法, 积累个人编程项目的经验,掌握单元测试和性能分析的方法

一、PSP表格

PSP2.1 Personal Software Process Stages 预估耗时(分钟) 实际耗时(分钟)
计划 30 20
需求分析 40 50
设计 60 50
编码 200 220
代码复审 40 30
单元测试 100 60
性能优化 60 60
报告撰写 60 80
合计 590 540

二、设计方案

main.py:主程序,处理文件I/O,包含了similarity算法和readfile接口
similarity.py:
1. 预处理文本(去标点、转小写)
2. 分词(使用 jieba 进行中文分词)
3. 检查特殊情况
4. 计算 TF-IDF 余弦相似度
5. 短文本优化
6. 返回保留两位小数的相似度
readfile:读取文件接口
test.py:进行单元测试

三、核心代码实现

1. 预处理文本,只保留字母、数字、汉字

def preprocess(text):
  text = text.lower().strip()
  text = re.sub(r'[^\w\s]', '', text)  
  return text

2.计算TF-IDF余弦相似度

    # 初始化 TF-IDF 向量器
    vectorizer = TfidfVectorizer(
        tokenizer=tokenizer,
        lowercase=False,
        min_df=1,
        max_df=1.0,
        norm='l2',
        smooth_idf=True,  # IDF 平滑处理,避免极端值
    )

    # 计算 TF-IDF 矩阵
    tfidf_matrix = vectorizer.fit_transform([text1, text2])

    # 计算余弦相似度
    sim = cosine_similarity(tfidf_matrix[0:1], tfidf_matrix[1:2])[0][0]

四、算法优化与亮点

1.修复 tokenizer 预处理冲突(避免 TfidfVectorizer 额外调用 preprocessor)
2.调整 TF-IDF 平滑参数(smooth_idf=True 避免极端 IDF)
3.增强短文本相似度计算(结合 Jaccard 方法)

性能分析图

读取文件函数消耗较大

五、单元测试展示

测试用例涵盖

    def test_exact_match(self):
        """测试完全相同的文本"""
        self.assertAlmostEqual(tfidf_cosine_similarity("今天天气好", "今天天气好"), 1.0, places=2)

    def test_partial_match(self):
        """测试部分相同的文本"""
        self.assertAlmostEqual(tfidf_cosine_similarity("今天天气好", "今天好"), 0.58, places=2)

    def test_no_match(self):
        """测试完全不同的文本"""
        self.assertAlmostEqual(tfidf_cosine_similarity("今天天气好", "明天有雨"), 0.0, places=2)


    def test_similar_meaning_different_words(self):
        """测试含义相似但用词不同的文本"""
        self.assertAlmostEqual(tfidf_cosine_similarity("今天是星期天,天气晴,今天晚上我要去看电影。",
                                                 "今天是周天,天气晴朗,我晚上要去看电影。"), 0.87, places=2)

    def test_different_word_orders(self):
        """测试相同词不同顺序的文本"""
        self.assertAlmostEqual(tfidf_cosine_similarity("今天天气好,我想去公园散步。",
                                                 "我想去公园散步,今天天气好。"), 1.0, places=2)


    def test_punctuation(self):
        """测试标点符号的影响"""
        self.assertAlmostEqual(tfidf_cosine_similarity("今天天气好。", "今天天气好"), 1.0, places=2)
        self.assertAlmostEqual(tfidf_cosine_similarity("今天天气好!", "今天天气好"), 1.0, places=2)

总结

posted @ 2025-03-08 23:48  hihuang  阅读(40)  评论(0)    收藏  举报