Java 与Soundex、Metaphone等功能类似的数值转换算法

Java 与Soundex、Metaphone等功能类似的数值转换算法,java,algorithm,language-agnostic,numbers,pattern-matching,Java,Algorithm,Language Agnostic,Numbers,Pattern Matching,我正在为个人记录搜索实现概率匹配。作为这项工作的一部分,我计划在得分之前先进行拦网。目前,有很多很好的转换字符串的选项,以便存储和搜索字符串,类似的字符串相互匹配(如soundex、metaphone等) 然而,对于纯数值,我很难找到类似的东西。例如,如果能够屏蔽一个社会保险号码,而不让关闭的号码或转置的数字从结果中删除,那就太好了。123456789应具有123456780或213456789的阻塞结果 现在,当然有一些方法可以简单地比较两个数值来确定它们有多相似,但是当数据库中有数百万个数字

我正在为个人记录搜索实现概率匹配。作为这项工作的一部分,我计划在得分之前先进行拦网。目前,有很多很好的转换字符串的选项,以便存储和搜索字符串,类似的字符串相互匹配(如soundex、metaphone等)

然而,对于纯数值,我很难找到类似的东西。例如,如果能够屏蔽一个社会保险号码,而不让关闭的号码或转置的数字从结果中删除,那就太好了。123456789应具有123456780或213456789的阻塞结果

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

好的是,上面的三个SSN可以以某种方式转换为其他存储的值。举个简单的例子,想象一下这三个数字在这个神奇的转变之后变成了aaabbcc。然而,类似987654321的东西将是ZZYYYXX,而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')

你能进一步说明你所说的阻塞是什么意思吗?阻塞函数是一种获取记录并返回候选键列表的函数吗?然后,这些候选键是否用于将成对比较限制为与至少一个阻塞候选键匹配的记录对?是的,听起来正确。因此,如果您有一个SSN为1234的记录,您希望为其查找匹配项,那么您希望排除相当明显的非匹配项,如5555。或者,如果某个性别是男性,则可以将女性排除在得分结果之外。然后,您应该有一小盒记录来评分或使用其他属性(如姓氏)应用进一步的阻塞轮。将当前记录与所有现有记录进行比较是不切实际的,因此需要进行阻塞。这回答了你的问题吗?这似乎与我想做的事情相似,似乎真的没有更好的解决方案,所以这就是我要做的。谢谢