SimHash文本相似度计算个人编程作业
markdown
SimHash文本相似度计算个人编程作业
这个作业属于哪个课程
计科24级78班 软件工程
作业目标
使用SimHash算法实现文本指纹生成,计算海明距离,判断两段中文文本相似度;练习单元测试、Git版本管理、GitHub代码托管,使用Markdown撰写技术随笔。
PSP个人软件过程
| 阶段 | 预估时间(min) | 实际时间(min) | 备注 |
|---|---|---|---|
| 需求分析 | 30 | 理解SimHash算法,确定程序输入输出 | |
| 方案设计 | 40 | 设计文本处理、哈希生成、海明距离计算函数 | |
| 编码实现 | 60 | 编写main.py主程序 | |
| 单元测试 | 30 | 编写test.py,设计3组测试用例 | |
| 文档编写 | 25 | 编写README.md、PSP记录 | |
| 代码上传 | 15 | 文件上传GitHub仓库 | |
| 合计 | 200 |
核心代码
main.py
import sys
def simhash(text):
words = text.replace(","," ").replace("。"," ").split()
v = [0]*64
for word in words:
h = hash(word)
for i in range(64):
bit = (h >> i) & 1
if bit == 1:
v[i] +=1
else:
v[i] -=1
fingerprint = 0
for i in range(64):
if v[i]>0:
fingerprint |= (1 << i)
return fingerprint
def hamming_distance(h1,h2):
xor = h1 ^ h2
return bin(xor).count("1")
def calc_similarity(d):
return ((64-d)/64)*100
def main():
if len(sys.argv) !=3:
print("用法:python main.py file1.txt file2.txt")
return
with open(sys.argv[1],"r",encoding="utf-8") as f:
t1 = f.read().strip()
with open(sys.argv[2],"r",encoding="utf-8") as f:
t2 = f.read().strip()
h1 = simhash(t1)
h2 = simhash(t2)
dist = hamming_distance(h1,h2)
sim = calc_similarity(dist)
print(f"文本1: {t1}")
print(f"文本2: {t2}")
print("-"*60)
print(f"SimHash指纹1:{h1}")
print(f"SimHash指纹2:{h2}")
print(f"海明距离:{dist}")
print(f"相似度:{sim:.2f}%")
if dist <=16:
print("判断:两段文本相似")
else:
print("判断:两段文本不相似")
if __name__ == "__main__":
main()
from main import simhash, hamming_distance, calc_similarity
def test_case():
s1 = "软件工程是一门研究用工程化方法构建和维护有效的、实用的和高质量的软件的学科。"
s2 = "软件工程是一门研究用工程化方法构建和维护有效的、实用的和高质量的软件的学科。"
f1 = simhash(s1)
f2 = simhash(s2)
d = hamming_distance(f1,f2)
print("测试用例1:完全相同文本")
print(f"海明距离:{d},相似度:{calc_similarity(d):.2f}%")
assert d == 0
print("用例1测试通过\n")
s3 = "今天天气很好,适合出门散步。"
s4 = "数据结构包含链表、二叉树、图、算法等内容"
f3 = simhash(s3)
f4 = simhash(s4)
d2 = hamming_distance(f3,f4)
print("测试用例2:完全不同文本")
print(f"海明距离:{d2}")
assert d2 > 20
print("用例2测试通过\n")
s5 = "软件工程是一门研究用工程化方法构建和维护有效的、实用的和高质量的软件的学科。"
s6 = "软件工程是一门利用工程化手段开发并维护高效、可用、高质量软件的学科。"
f5 = simhash(s5)
f6 = simhash(s6)
d3 = hamming_distance(f5,f6)
print("测试用例3:相似软件工程文本")
print(f"海明距离:{d3}")
print("用例3测试通过\n")
print("=====所有单元测试执行完毕!全部通过=====")
if __name__ == "__main__":
test_case()
## 运行结果

单元测试:3组用例全部通过
- 用例1:完全相同文本,海明距离0,相似度100%
- 用例2:完全不同文本,海明距离21
- 用例3:相似软件工程文本,海明距离35
主程序运行输出:
文本1: 软件工程是一门研究用工程化方法构建和维护有效的、实用的和高质量的软件的学科。
文本2: 软件工程是一门利用工程化手段开发并维护高效、可用、高质量软件的学科。
------------------------------------------------------------
SimHash指纹1:353567892769874851
SimHash指纹2:13738759018414675363
海明距离:26
相似度:59.38%
判断:两段文本不相似
## 结果分析
SimHash将文本映射为64位二进制指纹,海明距离表示两个指纹之间不同二进制位的数量。海明距离越小代表文本相似度越高,一般以16作为判定阈值,距离≤16判定文本相似。本次两段文本语义相近,但用词有改动,海明距离为26,判定为不相似。
## GitHub仓库地址
https://github.com/wang1580/whysoftware

浙公网安备 33010602011771号