1.基本原理

海明距离(Hamming Distance)是一种简单而高效的度量方法,用于衡量两个等长字符串(或二进制序列)在相同位置上不同字符的数量。

  • 取值范围:非负整数(0到字符串/向量长度),值越大表示差异越显著;
  • 特殊说明:仅适用于等长的输入,若两个输入长度不同,通常需要先补零/截断至相同长度,否则无法计算(这是海明距离的核心约束)。

2.算法步骤

步骤1:确保两个输入长度相同

这是前提条件

步骤2:逐位对比,统计“不同位置”的数量

对两个输入的每一个对应位置进行比较,记录不同的位置数,这个数字就是海明距离。

3. 扩展:海明相似度

实际使用中也常计算海明相似度,通常定义为:相似度 = 1 - (海明距离 / 字符串长度),取值范围为[0,1],值越大表示越相似。比如上述示例1的海明相似度=1 - 2/5 = 0.6。

3.优缺点适用场景

特点 说明
✅ 核心优点 计算极快:( O(n) ) 时间,无复杂操作 。
内存高效:只需逐位比较,无需存储中间状态。
理论清晰:在编码理论中有严格数学基础。
适用于高维二值数据:如 simHash、LSH、特征哈希。
❌ 主要缺点 要求等长:无法直接比较 “abc” 和 “abcd”。
忽略语义与顺序:“abc” vs “cba” 距离=2,但可能语义相同。
不适用于非符号数据:不能直接用于实数向量(需先二值化)。
对局部敏感哈希外的文本效果有限:对自然语言拼写错误不如编辑距离鲁棒
🛠️ 典型使用场景 simHash / LSH 近似去重:将文档哈希为 64/128 位指纹,用海明距离判断是否相似(如网页去重)
错误检测码(ECC):检测/纠正通信中的比特错误(如 Hamming Code)
生物信息学:比较 DNA 序列(当已对齐且等长时)
密码学:分析加密算法的雪崩效应(输入微变 → 输出海明距离大)
机器学习特征比较:比较 one-hot 编码、二值化特征向量
实体对齐中的签名匹配:对实体生成属性签名(如“性别+城市+职业” → 二进制串),快速初筛

💡 关键洞察:海明距离不是为自然语言设计的,而是为结构化符号序列或哈希码服务的。在 NLP 中,它主要作为底层工具(如 simHash 的组成部分),而非直接用于句子相似度。

4.与其他距离的对比

方法 是否需等长 适合文本? 适合二值数据?
海明距离 ✅ 是 ❌ 否(除非哈希后) ✅ 是
编辑距离 ❌ 否 ✅ 是 ⚠️ 可但低效
余弦相似度 ❌ 否(向量可不同源) ✅ 是(配合 TF-IDF/BERT) ✅ 是(二值向量)
Jaccard ❌ 否 ✅ 是(词集) ✅ 是

5.主流库推荐

方案 性能 易用性 支持类型 推荐度
scipy.spatial.distance.hamming ⚡ 快(C 优化) 字符串、数组、布尔向量 ★★★★★
RapidFuzz ⚡ 快 字符串 ★★★★☆
python-Levenshtein ⚡ 快 字符串 ★★★☆
手写循环 / NumPy 慢 / 中 低 / 中 灵活但易错 ★★

工程 / 大规模计算:scipy / numpy
字符串 / 教学 / NLP:textdistance / jellyfish

6.使用


import numpy as np

# 定义两个二进制向量(等长)
vec1 = np.array([1, 0, 1, 1, 0], dtype=int)
vec2 = np.array([1, 0, 0, 1, 1], dtype=int)

# 计算海明距离:统计不同元素的数量
hamming_dist = np.sum(vec1 != vec2)
print(f"向量海明距离:{hamming_dist}")  # 输出:2

# 计算多个向量与目标向量的海明距离
vecs = np.array([[1,0,0,1,1], [1,0,1,0,0], [1,1,1,1,1]], dtype=int)
distances = np.sum(vecs != vec1, axis=1)
print(f"批量向量海明距离:{distances}")  # 输出:[2 2 1]
from scipy.spatial.distance import hamming
import numpy as np

# 字符串(需转为 list 或 array)
a = "karolin"
b = "kathrin"
dist = hamming(list(a), list(b)) * len(a)  # scipy 返回比例,乘以长度得整数距离
print(dist)  # → 3.0

# 二进制数组(更常见)
x = np.array([1, 0, 1, 1, 0])
y = np.array([1, 1, 1, 0, 0])
print(hamming(x, y) * len(x))  # → 2.0

# 布尔向量
print(hamming([True, False, True], [True, True, False]) * 3)  # → 2.0
import rapidfuzz
from rapidfuzz import distance

# 计算字符串的海明距离(需等长)
hamming_dist = distance.Hamming.distance("10110", "10011")
hamming_sim = distance.Hamming.similarity("10110", "10011")  # 相似性(长度 - 距离)
print(f"海明距离:{hamming_dist},海明相似性:{hamming_sim}")
# 输出:海明距离:2,海明相似性:3

# 批量处理(从候选列表中找最相似的字符串)
candidates = ["10011", "10100", "11111"]
matches = rapidfuzz.process.extract("10110", candidates, scorer=distance.Hamming.distance, limit=2)
print(f"批量匹配结果:{matches}")
# 输出:[('10011', 2, 0), ('10100', 2, 1)](元组为:候选字符串、海明距离、索引)
Logo

中国智能体开发者社区,聚焦智能体与大模型开发,提供前沿资讯、实用工具链、开源项目及行业案例。通过技术沙龙、开发者大赛等活动,促进经验交流与协作,助力开发者快速构建创新智能应用。

更多推荐