使用 Double Metaphone 实现语音(“听起来像”)姓名搜索 第五部分:.NET 实现






4.74/5 (16投票s)
2003年7月26日
6分钟阅读

314109

5224
展示了 Double Metaphone 的 C# 实现,可与任何 .NET 语言一起使用。
摘要
简单的信息搜索——姓名查找、单词搜索等——通常是根据精确匹配标准来实现的。然而,考虑到同音(发音相同)单词和名称的多样性,以及人类拼错姓氏的倾向,这种简单的标准通常会产生不尽人意的结果,表现为结果集减少、记录缺失(因为字母错位或不同国家/地区的拼写差异)。
本系列文章讨论了 Lawrence Phillips 的 Double Metaphone 语音匹配算法,并提供了几个有用的实现,可用于各种解决方案,从而在数据库和其他集合中创建更有用、更有效的专有名称搜索。
引言
本系列文章讨论了 Double Metaphone 算法在语音搜索名称数据中的实际应用,使用了作者为 C++、COM (Visual Basic 等)、脚本客户端 (VBScript、JScript、ASP)、SQL 和 .NET (C#、VB.NET 和任何其他 .NET 语言) 编写的实现。有关 Double Metaphone 算法本身和 Phillips 原始代码的讨论,请参阅 Phillips 在 2000 年 6 月 CUJ 上发表的文章,可在此处获取。
第一部分介绍了 Double Metaphone 并描述了作者的 C++ 实现及其用法。第二部分讨论了在 Visual Basic 中使用作者的 COM 实现。第三部分演示了在 ASP 中使用 COM 实现和 VBScript。第四部分展示了如何使用作者的扩展存储过程在 SQL Server 中执行语音匹配。第五部分演示了作者的 .NET 实现。最后,第六部分总结了语音匹配替代方案的调查,以及其他资源的链接。
背景
本系列文章的第一部分讨论了 Double Metaphone 算法、其起源和用途,以及作者的 C++ 实现。虽然本节总结了该文章的关键信息,但仍鼓励读者通读整篇文章,即使读者没有 C++ 经验。
Double Metaphone 算法由 Lawrence Phillips 开发,并发表在 2000 年 6 月的 C/C++ Users Journal 上,属于一类称为“语音匹配”或“语音编码”算法的算法。这些算法试图检测单词之间的语音(“听起来像”)关系。例如,语音匹配算法应该检测“Nelson”和“Nilsen”之间存在很强的语音关系,而“Adam”和“Nelson”之间没有语音关系。
Double Metaphone 的工作原理是,给定一个单词,生成一个或可能两个语音键。这些键代表单词的“发音”。典型的 Double Metaphone 键长度为四个字符,因为这往往能在结果的特异性和通用性之间产生理想的平衡。
第一个(主)Double Metaphone 键代表源单词的美式发音。所有单词都有一个主 Double Metaphone 键。
第二个,即备用 Double Metaphone 键,代表一种备用、民族化的发音。例如,许多波兰姓氏被“美国化”,产生两种可能的发音,原始的波兰发音和美国发音。因此,Double Metaphone 为某些单词计算备用键。请注意,绝大多数(粗略地说,90%)单词不会产生备用键,但当计算出备用键时,它在匹配单词方面可能至关重要。
要比较两个单词的语音相似度,需要计算它们各自的 Double Metaphone 键,然后比较每种组合:
- 单词 1 主键 - 单词 2 主键
- 单词 1 主键 - 单词 2 备用键
- 单词 1 备用键 - 单词 2 主键
- 单词 1 备用键 - 单词 2 备用键
显然,如果给定的单词没有生成上面某个比较中的键,那么涉及该键的比较就不会执行。
根据上述哪个比较匹配,计算匹配强度。如果第一个比较匹配,则两个单词具有很强的语音相似性。如果第二个或第三个比较匹配,则两个单词具有中等语音相似性。如果第四个比较匹配,则两个单词具有最小语音相似性。根据特定的应用程序要求,一个或多个匹配级别可能会从匹配结果中排除。
.NET 实现
Double Metaphone 的 .NET 实现在设计和使用上与第一部分中介绍的 C++ 实现非常相似。要使用 .NET 实现,只需将 Metaphone.NET.dll 程序集添加到 Visual Studio .NET 中的项目引用中,将 nullpointer.Metaphone
命名空间导入到源文件中,并实例化 DoubleMetaphone
或 ShortDoubleMetaphone
类,分别用于字符串和无符号短整数 Metaphone 键。
例如,要计算名称“Nelson”的 Metaphone 键,可以使用类似于下面列出的代码(列出的是 C# 代码;.NET 实现可从 VB.NET、J# 和所有其他 .NET 语言调用)
using nullpointer.Metaphone;
DoubleMetaphone mphone = new DoubleMetaphone("Nelson");
System.Console.WriteLine(String.Format("{0} {1}",
mphone.PrimaryKey,
mphone.AlternateKey));
请注意,Metaphone 键是通过 PrimaryKey
和 AlternateKey
属性获取的。
与 C++ 实现一样,通过调用 computeKeys
方法,可以使用 DoubleMetaphone
或 ShortDoubleMetaphone
类的现有实例来计算新单词的 Metaphone 键。
using nullpointer.Metaphone;
DoubleMetaphone mphone = new DoubleMetaphone();
mphone.computeKeys("Nelson");
System.Console.WriteLine(String.Format("{0} {1}",
mphone.PrimaryKey,
mphone.AlternateKey));
与本系列文章中介绍的所有实现一样,为了演示 .NET 实现的用法,我们提供了一个用 C# 编写的示例应用程序——CS Word Lookup。CS Word Lookup 使用 Hashtable
集合类将 Metaphone 语音键映射到 ArrayList
类,其中包含生成上述 Metaphone 键的单词。
性能说明
虽然 .NET CLR 的性能相当不错,但必须指出,Double Metaphone 的 C++ 实现可能比 .NET 版本快得多,这主要是因为 C++ 版本谨慎地避免了内存分配和缓冲区复制,而 .NET 实现无法避免此类构造。鼓励有抱负的读者优化 .NET 实现,也许可以通过使用 unsafe
关键字来执行直接内存访问,但代价是牺牲 CLR 合规性。
结论
这篇简短的文章介绍了作者的 Double Metaphone 的 .NET 实现,包括代码片段和对性能问题的简要讨论。请继续阅读第六部分,了解替代语音匹配技术的综述,以及语音匹配资源列表,包括其他 Double Metaphone 实现的链接。
历史
- 2003 年 7 月 22 日首次发布
- 2003 年 7 月 31 日 在系列文章之间添加了超链接
文章系列
- 实现语音(“听起来像”)
姓名搜索, 使用 Double Metaphone 第 I 部分: 介绍与 C++ 实现 - 使用 Double Metaphone 实现语音(“听起来像”)姓名搜索 第二部分:Visual Basic 和关系数据库解决方案
- 实现语音(“听起来像”)姓名搜索,采用 Double Metaphone 第三部分:VBScript 和 ASP & 数据库解决方案
- 实现语音(“听起来像”)名称搜索,使用 Double Metaphone 第四部分:SQL Server 和高级数据库主题
- 使用 Double Metaphone 实现语音(“听起来像”)姓名搜索 第五部分:.NET 实现
- 使用 Double Metaphone 实现语音(“听起来像”)姓名搜索 第六部分:其他方法和附加资源