我正在尝试使用Jellyfish来处理模糊字符串。我注意到了jaro_distance算法的一些奇怪的行为。
我之前遇到过damerau_levenshtein_distance算法的一些问题,这似乎是代码中的一个错误,然后堆栈用户在github上提出了一个问题。
我不确定我是否在考虑错误的措施,或者它是否是真正的错误。我查看了源代码(http://goo.gl/YVMl8k),但我不熟悉C,所以我很难知道这是一个实现问题,还是我错了。
请注意以下事项:
In [1]: S1 = Poverty
In [2]: S2 = Poervty
In [3]: jf.jaro_distance(S3, S4)
Out[3]: 0.95238095
现在,如果我对jarrow距离测量的理解是正确的,我相信结果应该是0.9285714285
我已经确定了为什么计算出错了。为了计算度量,我认为以下是正确的:
(7.0/7.0 + 7.0/7.0 + ((7.0 - (3.0/2.0))/7.0) * (1.0/3.0) = 0.9285714285
该表达式中的关键数字是3.0。此数字必须表示“匹配的数量(但不同的序列顺序)”(维基百科)。在S1和S2中,我认为匹配但是顺序不同的字符是'e','r','v'。
但是,JellyFish似乎只能识别两个换位:
(7.0/7.0 + 7.0/7.0 + ((7.0 - (2.0/2.0))/7.0) * (1.0/3.0) = 0.95238095
我错了,或者功能上有什么不好的东西?
答案 0 :(得分:3)
如果查看Jellyfish source code jaro.c
,您会看到转置的数量存储在变量trans_count
中,其类型为long
。这意味着当它除以2时:
trans_count /= 2;
这使用C&C的整数除法,它会截断结果。因此,在您的示例(POVERTY / POERVTY)中,换位次数为3,但除以2时变为1。
这是对的吗?好吧,我尝试了以下研究途径:
Wikipedia article没有帮助,因为所有示例都有偶数个转置。 (它给予MARTHA-MARHTA的Jaro得分为0.944,Jaro-Winkler得分为0.961。)
Jaro's 1989 paper无权开放。
Winkler's 1990 paper含糊不清。他所说的只是:
将不匹配的字符数除以2以产生转置次数。
没有迹象表明该除法是否后跟截断。虽然Winkler给出了很多例子,但我发现使用他在论文中描述的算法不可能重现这些值。例如,他将MARTHA-MARHTA的J-W得分设为0.9667(见表1),我无法看到如何解释文本以使其正确。所以这篇论文没有用。也许值得写给Winkler作出解释?
如果您查看" official string comparator to be used for matching during the 1995 Test Census"的代码(这是基于" Bill Winkler,George McLaughlin和Matt Jaro编写的代码,由Maureen Lynch修改#34;)然后你会发现它在变量N_trans
中计算转置,类型为long
,因此截断分割,同意Jellyfish。
(此代码将MARTHA-MARHTA得分归为0.9708,原因是额外的"长字符串调整"。)
因此,我认为水母的行为至少在历史资料的基础上是合理的。但这似乎是一个错误,因为它没有原则性的理由而丢失了有关换位数量的信息。