【问题标题】:How to do postal addresses fuzzy matching?如何进行邮政地址模糊匹配?
【发布时间】:2016-07-07 22:21:20
【问题描述】:

我想知道在格式不同或其中一个拼写错误时如何匹配邮政地址。

到目前为止,我已经找到了不同的解决方案,但我认为它们已经很老了,而且效率不高。我确信存在一些更好的方法,所以如果您有参考资料供我阅读,我相信这是一个可能会引起很多人兴趣的主题。

我找到的解决方案(示例在 R 中):

  • Levenshtein 距离,它等于您必须插入、删除或更改以将一个单词转换为另一个单词的字符数。

    agrep("acusait", c("accusait", "abusait"), max = 2, value = TRUE) ## [1] "accusait" "abusait"

  • 音位比较

    library(RecordLinkage) soundex(x<-c('accusait','acusait','abusait')) ## [1] "A223" "A223" "A123"

  • 使用拼写校正器(eventually a bayesian one like Peter Norvig's),但我猜对地址不是很有效。

  • 我想使用谷歌的建议,但同样,它在个人邮政地址上效率不高。

  • 您可以想象使用机器学习监督方法,但您需要存储用户拼写错误的请求才能这样做,这对我来说不是一个选项。

【问题讨论】:

  • 您能否更准确地说明您的问题/问题?您列出的(标准)方法有什么特别错误或问题?您必须从哪些数据开始/匹配?
  • @fnl 我有邮政地址,所以这些技术并不是很有效。例如,想象一个像“62 bvd Col Prevot”这样的法语地址,例如,您希望它与“62 boulevard Colonel de Prevot”相匹配。这比仅仅匹配两个随机字符串更难。
  • Stéphanie,您所描述的是一个缩写扩展问题。对此有很多研究。除此之外,只需将您的问题分解为较小的问题。例如,您还可以将该(特定)情况视为字符串对齐问题,例如与Smith-Waterman algorithm.
  • @fnl 你对缩写扩展问题有很好的参考吗?你会推荐吗?除非我去谷歌看看。感谢您的意见
  • Stéphanie,我的主要专业是 BioNLP,虽然我现在从事商业问题,但我没有任何与工作相关的问题让我研究医学和基因组学领域之外的 AE 技术。因此,我对您特定领域的优秀 AE 论文的猜测将与您的一样好。但是,如果您熟悉生物医学领域,并希望获得一些指导,请告诉我,我可以发布一长串相关文献。

标签: text-mining spelling misspelling


【解决方案1】:

我将此视为拼写纠正问题,您需要在某种字典中找到最接近匹配的单词。 我所说的“近”是指 Levenshtein 距离,除了最小数量的单字符插入、删除和替换过于严格。 其他类型的“拼写错误”也是可能的,例如转置两个字符。

我已经这样做了几次,但最近没有。 最近的病例与临床试验的伴随药物有关。 您会惊讶地发现“乙酰水杨酸”有多少种拼写错误的方法。

Here is an outline in C++ of how it is done.

简而言之,字典存储为 trie,您会看到一个可能拼写错误的单词,您尝试在 trie 中查找该单词。 当您搜索时,您会按原样尝试单词,并尝试在每个点对单词进行所有可能的更改。 随着您的进行,您有一个整数预算,说明您可以容忍多少更改,每次进行更改时都会递减。 如果您用尽了预算,则不允许进一步更改。

现在有一个顶级循环,您可以在其中调用搜索。 在第一次迭代中,您以 0 的预算调用它。 当预算为 0 时,不允许修改,所以只是直接查找。 如果它没有找到预算为 0 的单词,你会再次调用它,预算为 1,因此它将允许进行一次更改。 如果失败,请尝试预算 2,依此类推。

我没有尝试过的是部分预算。 例如,假设一个典型的改动将预算减少了 2,而不是 1,预算变为 0、2、4 等。 那么一些改动可以被认为是“更便宜的”。例如,一个元音替换可能只会将预算减少 1,因此对于一个辅音替换的成本,您可以进行两个元音替换。

如果单词没有拼错,所花费的时间与单词中的字母数成正比。 一般来说,所花费的时间是单词变化次数的指数。

如果你在 R 中工作(就像我在上面的示例中那样),我会让它调用 C++ 程序,因为你需要编译语言的速度。

【讨论】:

  • 您认为这就是 Google 自动完成地址的原因吗? developers.google.com/places/web-service/…
  • @StéphanieC:我不知道谷歌是怎么做到的。这可能是他们工作的一部分。
  • 感谢您的回答,我会检查代码,但我有点失望,因为作为一名统计学家,我认为您会尽量避免测试所有组合(我知道您有预算限制,但仍然如此)
  • @StéphanieC:预算是其运作方式的关键。这是branch-and-bound 搜索的一个简单变体。当预算为零时,它的行为类似于直接的 trie 搜索。当预算为 1 时,它允许进行一次更改,依此类推。多遍是可以的,因为时间以最后一遍所花费的时间为主。使用尝试还有一个优势——通过共享子尝试很容易放置公共前缀和后缀。这大大减少了字典的大小。
【解决方案2】:

扩展 Mike 所说的内容,并使用 R 中的字符串匹配库 stringdist 来匹配在 ARCGIS 的地理编码功能中出错的地址向量:

rows<-length(unmatched$addresses)
#vector to put our matched addresses in
matched_add<-rep(NA, rows)
score<-rep(NA, rows)

#for instructional purposes only, you should use sapply to apply functions to vectors

 for (u in c(1:rows)){
     #gives you the position of the closest match in an address vector

     pos<-amatch(unmatched$address[u],index$address, maxDist = Inf)
     matched_add[u]<-index$address[pos]

     #stringsim here will give you the score to go back and adjust your
     #parameters

     score[u]<-stringsim(unmatched$address[u],index$address[pos])
} 

Stringdist 有多种方法可用于查找近似匹配,包括 Levenshtein (method="lv")。您可能希望尽可能地修改这些以适应您的数据集。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2022-01-06
    • 1970-01-01
    • 1970-01-01
    • 2018-04-09
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多