【问题标题】:I need an address matching algorithm我需要一个地址匹配算法
【发布时间】:2011-05-20 22:47:16
【问题描述】:

我已经在网上四处寻找,但实际上并没有找到太多。基本上我需要比较一堆地址,看看它们是否匹配。地址可以以各种不同的方式写入。例如:1345 135th st NE、1345 NE 135TH ST 等。此外,它们也可以使用不同的语言。在我尝试自己编写一些解析匹配算法之前,有人知道我可以轻松做到这一点的任何库或方法吗?我的朋友虽然使用谷歌或必应地图网络服务并将地址传递给他们并取回地理坐标并使用坐标而不是字符串匹配进行比较。但是我必须为我拥有的所有这些地址调用网络服务数千次,这不是很优雅;)任何帮助都会很好:)

【问题讨论】:

    标签: regex street-address


    【解决方案1】:

    我认为这不是 REGEX 类型的问题。您正在考虑先转换为可比较的格式。

    有多种网络服务/产品可以为您标准化地址。必应“USPS 地址标准化 API”,您会发现大量信息。一旦地址标准化,比较就应该很简单了。

    http://www.bing.com/search?q=usps+address+standardization+api&go=&form=QBRE&qs=n&sk=&sc=1-32

    或者,您可以对地址进行地理编码以获得一组坐标,然后进行比较。

    http://code.google.com/apis/maps/documentation/geocoding/

    【讨论】:

    • 谷歌代码还允许你返回一个“格式正确的地址”,但我认为在这么多 API 调用之后你必须付费或其他东西。
    【解决方案2】:

    美国地址(通常)可以用一个称为交货点 (DPBC) 的 12 位数字唯一表示。此号码由完整的 9 位邮政编码和 3 位送货点编号组成。这是用于在邮件上形成条形码以加快交付速度的方法。使用 CASS 认证的服务可以为您提供 12 位数的交货点,甚至可以标记重复。

    为了全面披露,我为 SmartyStreets 工作,该地址以前是合格地址,Mowgli 在另一个答案中提到。

    我们提供可查询的 API 以及批处理服务(如上所述,它将标记重复项)。

    请记住,即使是 12 位 DPBC 也并不总是唯一标识特定地址。当特定街区或 9 位邮政编码有很长一段具有相似主号码的房屋时,这种情况经常发生。在这些情况下,最好使用 CASS 服务来标准化和验证地址,然后对它们进行哈希处理以便于比较。 (但如前所述,某些 CASS 服务已经标记了重复项。)

    更新:SmartyStreets 现在提供international address verification

    【讨论】:

    • 分配邮政编码加 5 码可能是随后进行比较的最佳方式。分配代码需要匹配并查找完整的地址数据库。
    • 不,仅使用 ZIP+4 代码(9 位数字)还远远不够。可能存在仅在 12 位交付点条形码(由 9 位邮政编码加上交付点和一个校验位)中找到的辅助信息(公寓编号、描述符等)。 (当然,这是针对美国地址的)
    【解决方案3】:

    我不会认为这是一个正则表达式问题。

    一个可能有用的免费工具是 usaddress,这是一个用于解析地址的 Python 库。它在各种地址格式上都表现得很好,b/c 它使用概率方法而不是正则表达式方法(尽管它是为美国地址制作的,并且可能不适用于其他语言的地址) http://usaddress.readthedocs.org/en/latest/

    解析地址不会 100% 解决您的问题,但是如果将地址拆分为各自的组成部分,比较两个地址,尤其是具有不同格式的地址会容易得多(这样您就可以比较街道 # 和街道 # ,城市对城市等)

    然后,要比较记录,您可以使用 dedupe - 另一个免费的 Python 库。 http://dedupe.readthedocs.org/en/latest/

    【讨论】:

      【解决方案4】:

      我找到了 2 个选项。

      首先,也许您不接受任何输入,而是让用户从有限数量的选项中进行选择,类似于 facebook 处理地址的方式。如果您使用自动完成 api,当他们键入时,可能的地址将被 api 缩小。这是来自谷歌的一个:

      http://code.google.com/p/geo-autocomplete/

      其次,地址查找和限定(但它们不是免费的):

      https://www.craftyclicks.co.uk/

      https://smartystreets.com/(以前的限定地址)

      https://www.alliescomputing.com/(以前提供的世界地址)

      【讨论】:

        【解决方案5】:

        有一个用于记录重复数据删除/实体解析的开源python库,可应用于地址匹配:Dedupe

        它是免费的,可以在笔记本电脑上运行,而不是大型服务器。

        【讨论】:

          【解决方案6】:

          这需要智能才能正确执行;计算机不智能。

          一个简单的算法可以告诉您哪些地址有共同点,例如,“1345 135th st NE”和“1345 NE 135TH ST”有共同的数字“1345”。

          这样你就可以比较少了。它还会减少您进行地理定位的数量。

          【讨论】:

            【解决方案7】:

            这绝对不是 REGEX 问题。这是 2018 年,我们还掌握了更先进的方法。 R 和 python 都为这类问题提供了解决方案

            在 R 中:https://cran.r-project.org/web/packages/RecordLinkage/index.html

            在 python 中:https://recordlinkage.readthedocs.io/en/latest/about.html

            【讨论】:

              【解决方案8】:

              1.使用地址字符串相似度

              由于地址可以用许多不同的方式编写,因此应用模糊逻辑和计算地址字符串的相似性是很有用的。我曾经用一个fuzzywuzzy Python 库来解决这个任务。它具有将 Levenshtein 距离计算为字符串之间差异的函数。

              from fuzzywuzzy import fuzz
              
              addr1 = "USA AZ 850020 Phoenix Green Garden street, 283"
              addr2 = "850020, USA AZ Phoenix Green Garden, 283, 3a"
              addr3 = "Canada VC 9830 Vancouver Dark Ocean street, 283"
              
              addr_similarity12 = fuzz.token_set_ratio(addr1, addr2)
              addr_similarity13 = fuzz.token_set_ratio(addr1, addr3)
              
              print(f"Address similarity 1 <-> 2: {addr_similarity12}")
              print(f"Address similarity 1 <-> 3: {addr_similarity13}")
              

              输出将是:

              Address similarity 1 <-> 2: 96
              Address similarity 1 <-> 3: 55
              

              确实,前两个地址几乎相同,后两个地址不同。重要的任务是选择一个合适的阈值来表示地址相等。

              2。使用谷歌地图地理编码 API

              地理编码是将地址(例如“1600 Amphitheatre Parkway, Mountain View, CA”)转换为地理坐标(例如纬度 37.423021 和经度 -122.083739)的过程。然后可以计算两个地址之间的数字“距离”。

              【讨论】:

                【解决方案9】:

                解决此问题的一种方法是将两个地址转换为相同的格式。使用 Google Map Geocoding API 的一种简单方法是简单地将两个地址传递给 API 并获取输出。 Geocoding API 的输出类似于:

                FORMAT OF GOOGLE'S GEODIRECTORY API (for reference):
                    {'results': [{'address_components': [{'long_name': '22',
                         'short_name': '22',
                         'types': ['street_number']},
                        {'long_name': 'Rue de Berri',
                         'short_name': 'Rue de Berri',
                         'types': ['route']},
                        {'long_name': 'Paris',
                         'short_name': 'Paris',
                         'types': ['locality', 'political']},
                        {'long_name': 'Département de Paris',
                         'short_name': 'Département de Paris',
                         'types': ['administrative_area_level_2', 'political']},
                        {'long_name': 'Île-de-France',
                         'short_name': 'IDF',
                         'types': ['administrative_area_level_1', 'political']},
                        {'long_name': 'France',
                         'short_name': 'FR',
                         'types': ['country', 'political']},
                        {'long_name': '75008', 'short_name': '75008', 'types': ['postal_code']}],
                       'formatted_address': '22 Rue de Berri, 75008 Paris, France',
                       'geometry': {'location': {'lat': 48.8728822, 'lng': 2.3054154},
                        'location_type': 'ROOFTOP',
                        'viewport': {'northeast': {'lat': 48.8743208802915,
                          'lng': 2.306719730291501},
                         'southwest': {'lat': 48.8716229197085, 'lng': 2.304021769708497}}},
                       'place_id': 'ChIJWxDbRsFv5kcRRcfu62JSRog',
                       'plus_code': {'compound_code': 'V8F4+55 Paris, France',
                        'global_code': '8FW4V8F4+55'},
                       'types': ['establishment', 'lodging', 'point_of_interest']}],
                     'status': 'OK'}
                

                请注意 google 如何为您提供地址的不同组成部分,例如街道号码、位置等。现在您可以在这些组成部分之间进行加权/模糊匹配。由您决定是否要全部匹配,或者某些规则(例如街道号码或数字)应该始终匹配,如果 5 个匹配项中有 4 个匹配,则可以。您也可以考虑坐标之间的距离(注意:使用 Haversine 函数,而不仅仅是欧几里得参考:https://towardsdatascience.com/calculating-distance-between-two-geolocations-in-python-26ad3afe287b)。然后,您可以获得一个大于阈值的加权分数,以便他们被视为同一个地方。

                【讨论】:

                  猜你喜欢
                  • 2011-02-21
                  • 2020-04-17
                  • 1970-01-01
                  • 1970-01-01
                  • 2012-06-26
                  • 2010-12-13
                  • 1970-01-01
                  • 1970-01-01
                  • 1970-01-01
                  相关资源
                  最近更新 更多