个人项目
| 这个作业属于哪个课程 | 软工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)

浙公网安备 33010602011771号