65.9K
CodeProject 正在变化。 阅读更多。
Home

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

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.74/5 (16投票s)

2003年7月26日

6分钟阅读

viewsIcon

314109

downloadIcon

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 命名空间导入到源文件中,并实例化 DoubleMetaphoneShortDoubleMetaphone 类,分别用于字符串和无符号短整数 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 键是通过 PrimaryKeyAlternateKey 属性获取的。

与 C++ 实现一样,通过调用 computeKeys 方法,可以使用 DoubleMetaphoneShortDoubleMetaphone 类的现有实例来计算新单词的 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 日 在系列文章之间添加了超链接

文章系列

© . All rights reserved.