加权搜索算法找到类似的联系人

时间:2009-01-28 00:59:38

标签: string algorithm comparison street-address

我需要编写一个算法,根据用户输入的名称和地址返回联系人最接近的匹配项。这两个都令人不安,因为有很多方法可以输入公司名称和地址,例如:

Company A, 123 Any Street Suite 200, Anytown, AK 99012
Comp. A, 123 Any St., Suite 200, Anytown, AK 99012
CA, 123 Any Street Ste 200, Anytown, AK 99012

我看过在名字上做Levenshtein距离,但这似乎不是一个好工具,因为他们可以缩写名称。我正在寻找符合最多可能信息的东西。

我最初的尝试是首先将结果限制为邮政编码的前5位,然后根据其他信息尝试过滤为1,但必须有更标准的方法才能完成此操作。我在.NET工作,但会查看您可以提供的任何代码,以了解如何实现这一目标。

8 个答案:

答案 0 :(得分:1)

我现在还不知道如何实现这一目标,但所有主要的交付公司(FedEx,USPS,UPS)似乎都有一种方法可以将您输入的地址与其数据库进行匹配,并将其转换为规范化形式。正如我在多个网站上看到的那样(亚马逊想到了),我假设这个功能有一个API,但我不知道在哪里寻找它以及它是否适合您的目的。 / p>

只是一个想法。

编辑:我找到了USPS API

答案 1 :(得分:1)

我已经通过地址归一化,Metaphone和Levenshtein距离的组合解决了这个问题。您需要将名称与地址分开,因为它们具有不同的特征。以下是您需要执行的步骤:

1)使用(邮编的前六个字符)缩小匹配列表。基本上,您需要计算两个弦的Levenshtein距离,并选择最多距离为1或2的弦。如果你真的需要加快搜索速度,你可以预先计算一个邮政编码表及其“Levenshtein邻居”。

http://en.wikipedia.org/wiki/Levenshtein_distance

2)使用USPS的官方前缀和后缀缩写列表将所有地址缩写转换为标准格式。这有助于确保下一步的结果更加统一:

https://www.usps.com/send/official-abbreviations.htm

3)使用Methaphone算法将地址转换为短代码。这将摆脱最常见的拼写错误。只需确保您的实现可以消除所有非单词字符,完整传递数字并处理多个单词(确保每个单词由单个空格分隔):

http://en.wikipedia.org/wiki/Metaphone

4)一旦你有使用Levenshtein距离比较地址字符串的Methaphone结果。通过将结果除以较长字符串中的字符数来计算更改分数的百分比。

5)重复步骤3和4,但现在使用名称而不是地址。

6)使用以下公式计算每个条目的分数:(地址的重量*地址分数)+(名称的重量*名称分数)。根据更重要的东西来选择你的重量。我会以.9开头的地址(因为地址更具体)和.1的名称,但权重可能取决于您的应用程序。选择得分最低的条目。如果分数太高(比如说.15,你可以声明没有匹配)。

答案 2 :(得分:0)

我认为首先基于邮政编码的过滤是最简单的,因为发现它是相当明确的。从那里你可以提取城市和街道。我不确定你会如何找到这个名字,但如果你已经有一个(名称,地址)对的数据库是可行的,它似乎与地址相匹配。

答案 3 :(得分:0)

Dun& Bradstreet这样做。他们收钱是因为这真的很难。没有“标准”解决方案。在D& B之类的服务或自己的服务之间,这主要是一个痛苦的选择。

答案 4 :(得分:0)

首先,我可能会进行单词索引搜索。这意味着两个阶段:

离线阶段:按关键字生成所有地址的索引。例如,“公司”,“A”和“123”都将成为您上面提供的地址的关键字。你可以做一些词干,这意味着像“街头”这样的词你也会在其索引中添加一个单词“st”。

在线阶段:用户为您提供搜索查询。将搜索查询细分为其所有关键字,并查找数据库中每个关键字的所有可能匹配项。计算每个地址上匹配关键字的数量。然后按匹配关键字的数量对结果进行排序。如果没有太多匹配,这应该可以很快完成,因为它只是几个排序列表合并和增量,最后是排序。

鉴于您知道问题的域,您可以专门使用该算法来使用有关域的知识 - 例如之前提到的邮政编码过滤。

另外,为了让我能够为您提供更好的答案,您是否正在使用SQL数据库?我问,因为我这样做的方法是将关键字索引存储在SQL数据库中,然后按关键字搜索的SQL查询变得非常简单,因为数据库可以完成所有工作。

答案 5 :(得分:0)

也许不仅仅使用Levenshtein作为名称,它可能在与联系人的整个字符串表示一起使用时很有用。例如,你的第一个例子到第二个例子的距离是7和第三个9.考虑到字符串的长度为54,50和45,这似乎是一个相对有用且非常简单的相似性度量。

答案 6 :(得分:0)

这就是我要做的。我不知道算法,所以我只是使用有意义的东西。

我假设这个人会提供姓名,街道地址,城市名称,州名和邮政编码。

如果邮政编码以9个数字提供,或者有连字符,我会将其删除为5个数字。我会在数据库中搜索具有该zipcode的所有地址。[查询1] 然后我会将状态字母与数据库中的状态字母进行比较。如果它不匹配,那么我会告诉用户。城市名称也是如此。

根据我的理解,街道名称不是数字,只有街道上的房子里面有数字。此外,房屋号码通常在开头,除非是房屋或套房号码。

所以我会用正则表达式搜索旁边的数字和下一个空格或逗号。然后找到没有句点(。)或以逗号结尾的第一个单词的位置。我有街道名称的一部分,所以我可以对之前提取的行进行比较,或者我会将查询更改为街道名称LIKE%streetName%。

我猜这个数据库有一个块上的房子的起始编号和结束编号。我会检查那条街道的行,看看所提供的街道号是否在那条街上。 到目前为止,您将知道要显示的正确数据,并且可以在不同的表中查找与该门牌号相关联的名称。我不确定你为什么要比较它。如果您想查找未提供地址的人,则仅用于名称比较。您可以在此处查看比较字符串方式Similar String algorithm

答案 7 :(得分:0)

如果你能够可靠地找出每个地址的一般结构(可能是通过其他答案中的建议),你最好的选择是通过USPS认证来运行数据(意思是:结果可靠,准确,并且符合联邦标准)解决验证服务。

@RyanDelucchi,它一个有趣的问题,但只有你解决了它。所以,@ SteveBering,我建议你将你的联系人列表提交到a list processing service,根据USPS指南,这些联系人将根据地址标记重复项。

由于我在地址验证领域工作,我建议使用SmartyStreets(我工作),因为它可以为您的特定需求提供最大的价值 - 但是,有一些CASS认证的供应商基本上会做类似的的东西。