我正在为人员记录搜索实现概率匹配。作为其中的一部分,我计划在完成任何评分之前执行阻塞。目前,有很多不错的转换字符串的选项,以便可以存储和搜索它们,相似的字符串相互匹配(例如 soundex、metaphone 等)。
但是,我一直在努力寻找与纯数值类似的东西。例如,如果能够阻止社会安全号码并且没有关闭的号码或从结果中删除已转位的数字,那就太好了。 123456789 应该有 123456780 或 213456789 的阻塞结果。
现在,当然有一些方法可以简单地比较两个数值以确定它们的相似程度,但是当数据库中有数百万个数字时我该怎么办?将它们全部进行比较显然是不切实际的(这肯定会使阻塞点无效)。
如果上面的三个 SSN 可以以某种方式转换为可以存储的其他值,那就太好了。纯粹举例来说,想象一下这三个数字在这个神奇的转变之后最终变成了 AAABBCCC。然而,像 987654321 将是 ZZZYYYYXX 而 123547698 将是 AAABCCBC 或类似的东西。
所以,我的问题是,是否有像字母值那样的良好转换?或者,是否有其他一些可能有意义的方法(除了一些高度复杂或低性能的 SQL 或逻辑之外)?
最佳答案
首先要认识到,社会安全号码基本上是一串数字。您确实希望像对待字符串而不是数字一样对待它们。
要意识到的第二件事是,您的阻塞函数从一条记录映射到一个字符串列表,该字符串列表标识值得比较的项目集。
这里有一些 Python 代码可以帮助您入门。 (我知道您要求使用 Java,但我认为 Python 很清楚,您付给我的钱不足以让我用 Java 编写它 :P )。基本思想是获取您的输入记录,模拟以多种方式对其进行粗略处理(以获取您的阻塞键),然后根据这些阻塞键上的任何匹配项进行分组。
import itertools
def transpositions(s):
for pos in range(len(s) - 1):
yield s[:pos] + s[pos + 1] + s[pos] + s[pos + 2:]
def substitutions(s):
for pos in range(len(s)):
yield s[:pos] + '*' + s[pos+1:]
def all_blocks(s):
return itertools.chain([s], transpositions(s), substitutions(s))
def are_blocked_candidates(s1, s2):
return bool(set(all_blocks(s1)) & set(all_blocks(s2)))
assert not are_blocked_candidates('1234', '5555')
assert are_blocked_candidates('1234', '1239')
assert are_blocked_candidates('1234', '2134')
assert not are_blocked_candidates('1234', '1255')
关于java - 类似于 Soundex、Metaphone 等功能的数值转换算法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20979844/