本文解读 CMU "Subword Modeling" (Spring 2026) 第22讲:Phonological Similarity and Cognate Detection。
上一节课把每个音素表示成了发音特征向量。这节课在此基础上回答两个问题:怎么度量两个音素之间的「距离」,以及怎么度量两个词之间的「语音相似度」。最终落脚到一个实际应用:同源词检测。
1. 为什么要度量语音相似度
先给出直觉:有些音比另一些音更「像」。/m/ 和 /n/ 的距离比 /m/ 和 /t/ 近,因为前者只差一个发音部位,后者在发音方式、浊音性等维度上都不同。同样,tin 和 teen 比 tin 和 mood 更相似。
这种直觉有什么用?Mortensen 列了一长串 NLP 应用场景,挑几个最核心的:
-
同源词和借词检测。 两种语言里发音相似、意义相关的词很可能是同源词,有共同的祖先形式,或者是借词。这是历史语言学和计算语言学的经典问题。
-
跨语言命名实体识别。 人名、地名在不同语言里通常是音译的,发音相似但拼写可能完全不同。语音相似度可以帮助跨语言 NER 做实体对齐。
-
拼写纠错。 很多拼写错误是「写了一个发音相似的词」。如果 embedding 里编码了发音信息,就更容易找到正确的候选词。
-
诗歌生成。 押韵和音律需要精确的语音相似度信息。
-
口语理解。 语音识别的错误往往是把一个词听成了发音相似的另一个词。如果下游模型知道两个词发音相似,就可以减少这类错误的传播。
2. 音素之间的距离:两种思路
2.1 先验方法:Hamming 距离
最直接的做法:把两个音素的发音特征向量拿出来,算 Hamming 距离,也就是逐位比较,不同的位数之和就是距离。
比如 /t/ 和 /n/ 的特征向量只在 [voice] 和 [sonorant] 两个位上不同,所以 Hamming 距离是 2。/t/ 和 /a/ 在十几个特征上都不同,距离大得多。
这个方法的好处是完全不需要数据,只要有特征表就能算。缺点是默认所有特征同等重要,但现实中 [voice] 的区分度和 [round] 的区分度可能差很多。
2.2 经验方法:音素 embedding
另一种思路是从数据中学。跟 word2vec 的逻辑一样,出现在相似上下文中的音素应该是相似的。用类似 word2vec 的算法在音素序列上训练,就能得到音素 embedding。两个音素的相似度直接用 embedding 的余弦距离衡量。
这个方法可以自动从数据中学到哪些特征更重要,但需要大量的发音标注数据。
3. 词之间的距离:从 Levenshtein 到 embedding
音素级别的距离解决了之后,怎么扩展到词级别?
3.1 先验方法:Feature Edit Distance
标准的 Levenshtein 编辑距离把每次插入、删除、替换都算作代价 1,不管你是把 /p/ 替换成 /b/ 还是替换成 /a/,代价一样。这显然不合理。
Feature Edit Distance 的改进是:替换代价不再是固定的 1,而是两个音素特征向量之间的 Hamming 距离除以特征总数。 把 /p/ 换成 /b/ 只改了一个 [voice] 特征,代价很低;把 /p/ 换成 /a/ 改了十几个特征,代价很高。
公式上仍然是动态规划,只是替换代价 s 变成了:
s(x, x') = (1/24) × Σ|a(x)_i - a(x')_i|
这种距离度量直觉上很合理,但有两个实际问题:不可微分,没法直接用在端到端训练里;计算效率低,是动态规划而不是矩阵乘法,无法利用 GPU。
3.2 Phonetic Word Embeddings
既然 Feature Edit Distance 不可微分也不够快,自然的想法是:能不能把整个词映射成一个稠密向量,让发音相似的词在向量空间里也靠近?
这就是 Phonetic Word Embedding 的目标。Mortensen 介绍了好几种方法:
-
Poetic Sound Similarity。 先把每个音素转成特征集合,再对相邻音素的特征做笛卡尔积生成 bigram 特征,用 TF-IDF 计数后做 PCA 降维。整个过程不需要训练数据,只依赖特征表和 PCA。而且可以处理训练时没见过的新词。
-
phoneme2vec。 用 LSTM encoder-decoder 架构。给模型一个正确的音素序列和一个带噪声的音素序列,让模型从噪声版本重建正确版本。训练过程中联合学习的音素 embedding 矩阵就是最终产物。
-
Phonetic Similarity Embeddings。 先用一个自定义的音素相似度函数算出所有词对之间的相似度矩阵,再用非负矩阵分解把这个矩阵压缩成低维 embedding。缺点是不能处理新词,加入新词就得重新分解整个矩阵。
-
Count-based Vectors。 最朴素的方案:对词的音素序列提取 1/2/3-gram,用 TF-IDF 向量化。简单、快速、可解释。
-
Autoencoder。 用 LSTM encoder-decoder 做自编码器,bottleneck 向量就是词的 embedding。理想情况下这个向量包含了重建整个音素序列所需的全部信息。
-
Metric Learning。 用 LSTM 编码词,然后训练损失函数要求 embedding 空间中的欧氏距离跟 Feature Edit Distance 成正比。也就是直接把不可微分的 Feature Edit Distance「蒸馏」进一个可微分的 embedding 空间。
-
Triplet Margin Loss。 比 Metric Learning 更宽松,不要求距离精确匹配,只要求排序正确:对于 anchor 词 a,正例 p 应该比负例 n 更近。这个约束更容易满足,训练也更稳定。
4. 同源词检测:把距离用起来
4.1 什么是同源词
同源词 cognate 是指从同一个祖先词演变而来的词对。
Mortensen 用了一个非常好的例子:Ukhrul 和 Huishu,两种亲缘关系很近的藏缅语,都来自印度曼尼普尔邦的乌赫鲁尔地区。
| Ukhrul | Huishu | 含义 |
|---|---|---|
| ʃa | se | 厚 |
| ka | ke | 爬 |
| riŋ | rɐŋ | 活着 |
| tsik | tsoʔ | 黑 |
| tsa | tse | 吃 |
| rit | rejʔ | 重 |
| paj | pej | 跳/飞 |
| cap | tsaʔ | 哭/泣 |
4.2 同源词的三个特点
-
语音相似。 这是最直观的特征,同源词发音接近。
-
存在系统性的对应关系。 不是随机的相似,而是有规律的。比如 Ukhrul 词尾的 /a/ 系统性地对应 Huishu 词尾的 /e/;Huishu 的 /ʔ/ 系统性地对应 Ukhrul 的 /t/ 或 /k/。这种系统性正是历史语言学用来确认同源关系的核心依据。
-
意义相关但不一定完全相同。 比如一种语言里是「跳」,另一种里是「飞」;一种是「哭」,另一种是「泣」。意义在相关的语义域里漂移是正常的。
4.3 两个 baseline
最简单的同源词检测方法:
- 按字符串编辑距离排序,编辑距离越小越可能是同源词
- 按释义的 bag-of-words 相似度排序,释义重叠越多越可能是同源词
更好的方法自然是把语音相似度和语义相似度结合起来。而语音相似度的度量,不管是 Feature Edit Distance 还是 Phonetic Word Embedding,就是这节课前半部分建立的工具。
5. 总结
| 层次 | 先验方法 | 数据驱动方法 |
|---|---|---|
| 音素距离 | Hamming 距离 on 特征向量 | 音素 embedding |
| 词距离 | Feature Edit Distance | Phonetic Word Embedding 的各种变体 |
| 方法 | 核心思路 | 能否处理新词 | 可微分 |
|---|---|---|---|
| Feature Edit Distance | 用特征 Hamming 距离替代 Levenshtein 的固定代价 | 能 | 否 |
| Poetic Sound Similarity | 特征 bigram + TF-IDF + PCA | 能 | 否 |
| phoneme2vec | LSTM 从噪声序列重建正确序列 | 能 | 是 |
| Metric Learning | 训练 embedding 距离逼近 Feature Edit Distance | 能 | 是 |
| Triplet Margin Loss | 只要求距离排序正确,不要求精确匹配 | 能 | 是 |
核心 takeaway:
语音相似度的度量经历了一条清晰的演进路径:从基于特征向量的 Hamming 距离,到基于动态规划的 Feature Edit Distance,再到基于 embedding 的可微分度量。每一步都在解决前一步的局限,先是让距离对语音差异敏感,再让距离可以端到端训练。同源词检测是这条路径的一个直接应用:它需要的恰好就是一个既懂语音结构、又能大规模计算的相似度函数。