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()

## 运行结果

![image](https://img2024.cnblogs.com/blog/3847037/202609/3847037-20260912181332874-1449769102.png)


单元测试: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
posted @ 2026-09-12 18:17  王昊圆  阅读(39)  评论(0)    收藏  举报