课程
距离度量为衡量对象之间的差异提供了基本方法。相比 欧氏距离 或 曼哈顿距离 这类衡量空间差异的度量,汉明距离采取了不同的思路:它统计两条序列在对应位置上不同的个数。这使其在错误检测、数据校验以及信息论中尤为有用。
汉明距离最早由理查德·汉明于 1950 年在贝尔实验室从事代码校验系统工作时提出,如今它的应用已超越电信领域。当前,它在以下诸多领域中都是关键度量:
- 数据校验与完整性检查
- 生物信息学中的 DNA 序列分析
- 信息检索中的模式匹配
- 机器学习中的特征比较
在本指南中,我们将解释汉明距离的工作原理,探讨其实际应用,并在 Python 与 R 中实现。通过这些概念与实现,您将更好地解决数据校验、生物信息学与机器学习中的相关问题。
什么是汉明距离?
汉明距离衡量的是两条等长字符串在对应位置上符号不同的个数。可以将其理解为把一个字符串转换为另一个字符串所需的最少替换次数。
例如,比较两条二进制字符串:

作者制图
此处汉明距离为 2,因为两条字符串在两个位置不同——第二位与第四位比特。
数学上,对于长度为 n 的两条等长字符串 x 和 y,汉明距离 D(x,y) 表达为:

该公式统计所有满足 xᵢ ≠ yᵢ 的位置。对于二进制字符串,这等价于统计比特不相同的位置。对于其他类型的序列(如 DNA 或文本),则统计符号不同的对应位置。
需要注意的两个关键性质:
- 要求字符串等长。
- 只统计替换,不考虑插入或删除。
这些性质使汉明距离非常适用于以下场景:
- 数据由定长代码或序列构成。
- 只关心替换错误。
- 需要快速的按位置比较。
汉明距离的工作原理
我们通过示例来说明如何计算汉明距离,从简单的二进制字符串开始,再扩展到更复杂的应用。
二进制字符串示例
最直接的应用是比较二进制字符串。来看两条 8 位字符串:

作者制图
逐步计算:
- 位置 1:1 = 1(相同)
- 位置 2:0 = 0(相同)
- 位置 3:1 ≠ 0(不同)
- 位置 4:1 = 1(相同)
- 位置 5:0 = 0(相同)
- 位置 6:1 ≠ 0(不同)
- 位置 7:0 = 0(相同)
- 位置 8:1 = 1(相同)
汉明距离为 2,因为有两个位置不同(第 3 位与第 6 位)。
DNA 序列示例
汉明距离在生物信息学中常用于比较基因序列。考虑以下两段 DNA 片段:

作者制图
逐步分析:
- 第 1、2、4、5、7、8 位碱基配对相同
- 第 3 位(C→G)与第 6 位(A→C)存在差异
- 汉明距离 = 2 次突变
这种比较有助于生物学家量化基因突变并分析 DNA 相似性。
文本字符串示例
汉明距离同样适用于等长的常规文本字符串:

作者制图
此处汉明距离为 1,唯一差异在最后一个位置(“T” 与 “D”)。
这类比较适用于:
- 拼写检查系统
- OCR(光学字符识别)校验
- 文本相似度分析
这些示例表明,无论比较的数据类型为何,汉明距离都能以简单而有效的方式量化序列之间的差异。关键在于它关注按位置的差异,而忽略具体变更的性质。
汉明距离的应用
错误检测与纠正
汉明距离为数字通信中的错误检测与纠错码奠定了基础。通过策略性地添加校验位,以在有效码字之间建立最小距离,系统可以在接收数据不匹配有效模式时进行检测,甚至通过映射到最近的有效码字来纠正错误。这一原理支撑了现代技术,如计算机中的 ECC(纠错码)内存、二维码的纠错机制,以及在数据完整性至关重要的深空通信系统。
信息论
信息论利用汉明距离来设计可靠的通信系统。构造错误处理码时,工程师会确保有效消息(码字)之间至少在若干位上不同。例如,若有效消息之间至少相差两位,系统即可检测到单比特在传输中被破坏的情况。若有效消息之间至少相差三位,系统甚至能够通过识别最近的有效消息来纠正单比特错误。这些原则帮助构建从卫星通信到数据存储等各类稳健的通信系统。
生物信息学
遗传学研究者使用汉明距离分析 DNA 序列并量化突变。通过逐位比较基因序列,科学家可以识别点突变、追踪进化变化,并研究遗传多样性。这在研究疾病突变时尤为重要,了解基因变化的具体位置有助于研究人员追踪疾病如何演化并在人群中传播。
机器学习
在机器学习中,汉明距离是用于二元或分类数据的相似度度量。它可用于模式识别任务中的特征向量比较、推荐系统中的相似度衡量,以及分类问题中的分类数据分析。该度量简单且计算高效,尤其适用于处理高维二元数据,或在大规模数据集上需要快速相似度计算的场景。
数学性质
度量空间性质
汉明距离构成一个数学度量空间,意味着它遵循四个基本规则。其一,距离总是不负的——两个字符串不同位置的数量不可能为负。其二,当且仅当两条序列完全相同时,距离为零。其三,距离具有对称性——比较序列 A 与 B 的结果与比较 B 与 A 相同。最后,它满足三角不等式:A 与 C 之间的距离不大于 A 与 B 与 B 与 C 距离之和。
二进制字符串性质
在处理二进制字符串时,汉明距离具有一些对错误检测尤为有用的特性。对于任意两条长度为 n 的二进制字符串,其汉明距离不可能超过 n,且只有当它们互为补码时才会达到该上限。两条随机二进制字符串之间出现特定汉明距离“d”的概率服从二项分布,最可能的距离为 n/2。该性质有助于设计能够识别传输过程中比特翻转的错误检测码。
Python 与 R 中的汉明距离
Python 实现
Python 既提供了库函数也支持自定义实现来计算汉明距离。SciPy 库通过其空间距离函数提供了最高效的方案:
from scipy.spatial.distance import hamming
# For working with strings
string1 = "1010101"
string2 = "1000101"
# Convert to list of integers for hamming function
arr1 = [int(bit) for bit in string1]
arr2 = [int(bit) for bit in string2]
# Calculate Hamming distance
distance = hamming(arr1, arr2) * len(arr1) # Multiply by length because SciPy returns fraction
print(f"Hamming distance: {int(distance)}") # Output: Hamming distance: 1
# For DNA sequences
sequence1 = "ATCGTACT"
sequence2 = "ATCGCACT"
distance = hamming(list(sequence1), list(sequence2)) * len(sequence1)
print(f"Hamming distance: {int(distance)}") # Output: Hamming distance: 1
如果您更偏好自定义实现:
def hamming_distance(str1: str, str2: str) -> int:
"""Calculate Hamming distance between two strings."""
if len(str1) != len(str2):
raise ValueError("Strings must be of equal length")
return sum(c1 != c2 for c1, c2 in zip(str1, str2))
# Example usage
print(hamming_distance("1010101", "1000101")) # Output: 1
R 实现
R 可通过基础函数简单计算汉明距离:
hamming_distance <- function(str1, str2) {
if (nchar(str1) != nchar(str2)) {
stop("Strings must be equal length")
}
sum(strsplit(str1, "")[[1]] != strsplit(str2, "")[[1]])
}
# Example usage
hamming_distance("1010101", "1000101")
# [1] 1
# For DNA sequences
hamming_distance("ATCGTACT", "ATCGCACT")
# [1] 1
若要在上述代码基础上进一步扩展,并探索距离度量在实践中的更多应用,请参考以下深度资源:
- Designing Machine Learning Workflows in Python - 学习如何在机器学习流水线中实现距离度量并将其集成到您的 ML 工作流
- Cluster Analysis in R - 了解如何应用基于距离的方法实现高效的数据聚类与分类
这些课程将帮助您超越基础实现,理解距离度量如何影响机器学习应用,无论您偏好哪种编程语言。
汉明距离与其他方法对比

作者制图
莱文斯坦距离(编辑距离)
莱文斯坦距离表示将一个字符串变为另一个字符串所需的最少单字符编辑操作数。与汉明距离不同,它可通过考虑插入和删除(以及替换)来处理不同长度的字符串。这种灵活性使其在拼写检查、DNA 序列比对和模糊字符串匹配中尤为有用,但也以更高的计算复杂度为代价。比如比较 "planet" 与 "plan" 时,莱文斯坦距离会把删除 'e' 与 't' 计为两次操作,而汉明距离则无法进行该比较。
Damerau–Levenshtein 距离
在标准莱文斯坦距离的基础上,Damerau–Levenshtein 距离将相邻字符对调作为一种有效操作。此项补充使其对常见的字符交换式输入错误格外敏感。例如比较 "form" 与 "from" 时,它会将其视为一次对调而非两次替换。该度量广泛应用于自然语言处理,尤其是自动拼写纠正系统中,字符对调是常见的输入错误。
Jaro–Winkler 距离
Jaro–Winkler 距离采取独特方法,强调字符位置权重,尤其偏好字符串开头的匹配。它不统计编辑操作,而是给出 0 到 1 的相似度分数,1 表示完全匹配。该度量在比较专有名词和短字符串方面表现突出,适用于记录关联与去重任务。例如比较 "Martha" 与 "Marhta" 时,由于差异出现在字符串后部,它会给出较高的相似度。
如何选择合适的距离度量
不同场景适用不同的距离度量。选择时可考虑以下关键因素:
速度与效率要求
- 汉明距离计算最快
- 莱文斯坦距离需要更多算力
- Jaro–Winkler 在速度上介于两者之间
字符串长度考量
- 定长字符串(如二进制数据、哈希码):汉明距离
- 变长字符串(用户输入、自然文本):莱文斯坦距离
- 短字符串与姓名:Jaro–Winkler 距离
需要处理的错误类型
- 仅替换:汉明距离
- 完整编辑操作:莱文斯坦距离
- 字符交换:Damerau–Levenshtein 距离
- 姓名变体:Jaro–Winkler 距离
应用领域
- 数字通信与错误检测:汉明距离
- 文本处理与拼写检查:莱文斯坦距离
- 数据库去重与记录匹配:Jaro–Winkler 距离
- 自然语言处理:Damerau–Levenshtein 距离
上述结构化对比表明,各类距离度量各有所长;当需要对定长数据进行比较且重视简洁与速度时,汉明距离尤为合适。
结语
汉明距离的优雅之处在于其简洁。通过统计序列在对应位置上的差异,它为度量不相似性提供了可靠方法——无论是检测传输数据中的错误,还是分析基因突变。在每个位置同等重要、且主要关心替换的领域,它尤为出色。
在您的工作中选择距离度量时,若满足以下条件可优先考虑汉明距离:
- 处理定长序列
- 涉及二元或分类数据
- 构建错误检测系统
- 分析基因序列
- 开发模式匹配算法
若要继续提升您在距离度量及其他数据科学基础概念方面的能力,欢迎探索我们的 数据科学家认证 项目(提供 Python 与 R 两种路径)。
Vinod Chugani 的职业生涯始于东京,曾任摩根大通最年轻的对冲基金销售台负责人,随后在雷曼兄弟创下个人销售纪录,之后又打造了覆盖 30 个国家的电子分销业务,营收突破 1 亿新元,随后转向数据领域。他毕业于杜克大学经济学专业,亦为 NYC Data Science Academy 校友,并在 100 多名申请者中成为Hugo Bowne-Anderson 在 Maven 开设的 “Building AI Applications” 课程的三位奖学金获得者之一。目前,他为 DataCamp、KDnuggets、Machine Learning Mastery 和 Statology 撰稿,内容涵盖从统计学到代理式 AI 等主题,并在 NYC Data Science Academy 指导数据从业者,已完成超过 1,000 场一对一辅导。
FAQs
什么是汉明距离?
汉明距离是一种度量,用于统计两条等长字符串在对应位置上不同的个数。例如,"cat" 与 "hat" 的汉明距离为 1,因为它们只在一个位置不同。
汉明距离能用于不同长度的字符串吗?
不可以。汉明距离只能用于等长字符串之间的比较。若需要比较不同长度的字符串,您应考虑莱文斯坦距离或编辑距离等其他度量。
在比较文本字符串时,汉明距离是否区分大小写?
是的,默认情况下汉明距离区分大小写。例如,'A' 与 'a' 会被视为不同字符。若您希望不区分大小写,需要在计算前将所有字符转换为相同大小写。
汉明距离如何处理特殊字符和空格?
汉明距离一视同仁地处理所有字符,包括空格与特殊字符。它仅逐位置比较字符是否相同,而不关心字符的具体类型。
汉明距离能用于非文本数据吗?
可以。凡是能表示为等长序列的数据都可使用汉明距离,包括二进制数据、DNA 序列和数字信号。唯一要求是被比较的序列必须等长。
两条字符串之间可能的最大汉明距离是多少?
两条字符串之间的最大汉明距离等于它们的长度。仅当两条字符串在每个位置都不同时时,才会达到该上限。
