对话版的“也许”?程序化检测口误

大家好,
我是Mandai,Wild团队负责开发工作的成员。
在对话中,发音错误或听错是很常见的。
根据当时的气氛和情况,这往往能活跃气氛,所以我认为这未必是件坏事(尽管有时很明显只是记错了)。
这次,我将介绍一些可能(或许)可以实现的算法,这些算法出现在谷歌搜索结果中。
目录
莱文斯坦距离
首先是莱文斯坦距离,它量化了字符之间的距离。
莱文斯坦距离 -根据
它是一种表示两个字符串差异程度的距离,也称为编辑距离。
让我们来看看小猫坐下时的距离,维基百科上也有提到。
- 小猫
- sitten # k → s 替换
- 坐着 # 替换 e → i
- 添加座位 # g
通过这三个步骤,可以将小猫转换为坐着,在这种情况下,莱文斯坦距离为 3。
我们将这些操作的次数定义为字母之间的距离,并以此来衡量近似程度。
文本操作可能涉及添加、删除和替换,但有人认为,由于替换可以被视为同时添加和插入的操作,因此替换的成本本质上是 2。
在这种情况下,莱文斯坦距离变为 5。
虽然其实际应用价值尚待商榷,但正如您所读到的,它似乎应用于DNA研究。
事实上,由于DNA由A、G、C和T四个字母组合而成,因此粗略地说,莱文斯坦距离可以等同于基因的接近程度。
在 PHP 中可以轻松计算莱文斯坦距离,并且有一个专门的标准函数可以实现这一点。
echo levenshtein('kitten', 'sitting'); // 结果是 3 echo levenshtein('kitten', 'sitting', 1, 2, 1); // 替换的成本是 2 // 结果是 5 echo levenshtein('Yamada', 'Yamaguchi'); // 结果是 3
糟糕。看来它不支持多字节字符。
我是在 UTF-8 环境下运行的,所以汉字会被算作 3 个字节。因此,如果省略第二个参数及之后的参数,替换操作也会被算作 1 个字节,所以很可能实际更改了 3 个字节。我们
尝试插入一个不同的字符串,从外部看看它的内部工作原理。
echo bin2hex('Yama'); // e5b1b1 echo bin2hex('Kuchi'); // e58fa3 echo bin2hex('Ta'); // e794b0 echo bin2hex('Yamaguchi'); // e79480 只有最后两位数字与“Kuchi”不同 echo levenshtein('Yamada', 'Yamaguchi'); // 结果是 3 echo levenshtein('Yamada', 'Yamaguchi'); // 结果是 3
它不会逐字节地检查多字节字符,而是将它们识别为多字节字符,但似乎转换后的字符的最终数量是使用 strlen 或类似函数粗略检查的。
它似乎很容易实现,我找到了一个用 Python 和 Perl 实现的页面,所以我在这里附上了一个链接。
编辑距离(莱文斯坦距离) - naoya 的 Hatena 日记
Soundex
Soundex 算法采用与莱文斯坦距离不同的方法,更侧重于检测发音错误。
它似乎是专门为处理人名而设计的。
维基百科上没有日文条目,但有英文页面。→ Soundex - 维基百科
Soundex 会分析输入字符的发音,并将其转换为一个称为“Soundex 键”的四字符字符串。
它甚至将长字符串都简化为四个字符,这似乎有点粗糙……
由于 PHP 有现成的标准函数可以实现这个功能,我想尝试用最简单的方式来实现它。
我已经准备了一些用片假名拼写出来发音相同的英文单词。
echo soundex('rock'); // 结果为 R200 echo soundex('lock'); // 结果为 L200 echo soundex('free'); // 结果为 F600 echo soundex('flea'); // 结果为 F400 echo soundex('flee'); // 结果为 F400 echo soundex('aerosmith'); // 结果为 A625
我完全不明白返回值是什么意思,但我大概明白 rock 和 lock 的区别。free
和 flea 的区别仅仅在于第二个字母,而 flea 和 flee 的意思完全相同。
转换规则出奇地详细,“测量字符串相似度(2)聚焦发音 | Colorless Green Ideas”,但通过结合 soundex 和 Levenshtein 距离,似乎可以从发音的角度实现“您是不是要找……?”功能。
Soundex 也受 MySQL 支持,MySQL 提供了一个 soundex 函数。
MySQL :: MySQL 5.6 参考手册 :: 12.5 字符串函数 SOUNDEX(str)
需要注意的是,MySQL 的 soundex 与 PHP 的输出略有不同,并且长度并非固定为 4 个字符。
mysql> SELECT SOUNDEX('Quadraticly'); -> 'Q36324'
Soundex 功能不支持日语。
这或许也在意料之中,毕竟不同的语言不能采用相同的标准。
元音
Metaphone 是 Lawrence Philips 设计的一种算法,它与 Soundex 类似,都能根据发音输出一个名为 Metaphone 键的字符串。Soundex
通过依次检查字母来区分发音,而 Metaphone 则基于字母组合来定义发音,并且似乎比 Soundex 键能产生更准确的数据。
元音键仅由字母组成,不包括元音。
元音键由 16 个字符组成:“0BFHJKLMNPRSTWXY”。
,0 似乎代表“th”音,与单独的 T 和 H 区分开来。
例外情况是,只有当单词以元音开头时才会添加元音,例如“authentication”。此外
,元音键比 SoundEx 包含更多基于组合的转换规则,因此它提供的数据比 SoundEx 更准确。
PHP 还有一个名为 metaphone 的标准函数,让我们来看一个例子。
echo metaphone('authentication'); // 结果为 A0NTKXN echo metaphone('supercalifragilisticexpialidocious'); // 出自《欢乐满人间》的著名音符 // 结果为 SPRKLFRJLSTSKSPLTSS
从某种意义上说,它们代表了书写中的发音,类似于音标符号,但音标符号用于确保正确的发音,而音标符号和音标符号只是从发音中提取出来的声音,因此查看音标符号并不意味着你可以找到一个单词的发音。
获取多个单词的元音键并测量莱文斯坦距离可能比 soundex 提供更准确的近似值。
有关元音的信息可以在这里找到:劳伦斯·菲利普斯的元音算法(但是,许多链接已失效,并且该网站不再维护,因此信息可能已过时)。
此外,元音算法还有一个改进版本,称为双元音算法,它经过修改,可以输出两种类型的键:主键和辅助键。虽然
所用字符串的基本规则似乎保持不变,但内部实现却截然不同,因此元音算法和双元音算法的结果似乎无法直接比较。
有关双元音的信息PHP DoubleMetaPhone,其中还包括指向 PHP 以外的双元音实现的链接。
由于 `double metaphone` 不是标准的 PHP 函数,因此`PECL::Package::doublemetaphone`需要从
联系
这是 Jazzy(一个用于拼写检查的 Java API)的介绍页面,开头解释了 soundex、metaphone 和莱文斯坦距离。
令我惊讶的是,soundex 居然申请了专利。
我附上了一个链接,里面是一位正在利用这些技术进行一些有趣研究的人写的。
这是一篇研究论文,但内容比较通俗易懂。
就这样。
0
