数值的变换算法类似于Soundex,Metaphone等的功能

时间:2014-01-07 19:13:03

标签: java algorithm language-agnostic numbers pattern-matching

我正在为人员记录搜索实施可能性匹配。作为其中的一部分,我计划在任何评分完成之前执行阻止。目前,有很多很好的选项可以转换字符串,以便它们可以存储然后搜索,相似的字符串相互匹配(如soundex,metaphone等)。

然而,我一直在努力为纯粹的数值找到类似的东西。例如,能够阻止社会安全号码并且没有关闭数字或从结果中删除转置数字将是很好的。 123456789应具有123456780或213456789的阻止结果。

现在,有一些方法可以简单地比较两个数值来确定它们的相似程度,但是当数据库中有数百万个数字时,我该怎么办?将它们全部进行比较显然是不切实际的(这肯定会使阻塞点失效)。

什么是好的将是上面的三个SSN可以某种方式转换成将存储的其他值。仅举例来说,想象这三个数字在这次神奇转变之后最终成为AAABBCCC。但是,像987654321这样的东西是ZZZYYYYXX,123547698就是AAABCCBC或类似的东西。

所以,我的问题是,对于数字值是否存在良好的转换,例如字母值是否存在?或者,是否有其他方法可能有意义(除了一些高度复杂或低性能的SQL或逻辑)?

1 个答案:

答案 0 :(得分:1)

首先要意识到的是,社会安全号码基本上是数字串。你真的想要像对待字符串而不是数字一样对待它们。

要实现的第二件事是你的阻塞函数从一个记录映射到一个字符串列表,这些字符串可以识别比较有价值的项目集。

这里有一些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')