如何在MS SQL Server 中将mdq.Similarity 分数转换为MDS 中的编辑操作数?

How to convert mdq.Similarity score to the number of edit operations in MDS, in MS SQL Server?

如何将 mdq.Similarity 的结果转换为两个单词匹配所需的 number of edits。此函数是 Microsoft SQL 服务器中主数据服务 (MDS) 的一部分,定义为:

USE [mds]
ALTER FUNCTION [mdq].[Similarity](@input1 [nvarchar](4000), @input2 [nvarchar](4000), @method [tinyint], @containmentBias [float], @minScoreHint [float])
RETURNS [float] WITH EXECUTE AS CALLER, RETURNS NULL ON NULL INPUT
AS EXTERNAL NAME [Microsoft.MasterDataServices.DataQuality].[Microsoft.MasterDataServices.DataQuality.SqlClr].[Similarity]

彼此相距 1 个编辑的两个词产生不同的 Levenshtein 距离,这似乎解释了它们的长度(词中的字符数)。

SELECT a=mds.mdq.Similarity('a','',0,0,0), 
ab=mds.mdq.Similarity('ab','a',0,0,0), 
abc=mds.mdq.Similarity('abc','ab',0,0,0), 
ac=mds.mdq.Similarity('ac','ab',0,0,0)

a   ab  abc     ac
0   0.5 0.67    0.5

而在每种情况下我都需要它 return 1,因为每对都有两个单词因一次编辑(插入、删除、替换)而不同。

你不能。

我无法使用此功能做任何有用的事情。我发布这篇文章的主要原因是人们可以访问 msdn documentation as it does not come up when doing a google search

根据 msdn,mdq.Similarity:

Returns a similarity score. This score indicates the similarity between two strings that are compared by a specified match algorithm.

我理解 Levenshtein、Jaro、LCSS,但是,在使用这个函数几个小时之后,很难用它做任何有用的事情。 mdq.Similarity IMO 是死胡同。

这个

--Using Levenshtein edit distance algorithm.
SELECT Lev = mdq.Similarity(N'Alexia Geogio', N'Alexandra George', 0, 0.0, 0.0);
--Using Jaccard similarity coefficient algorithm.
SELECT Jacc = mdq.Similarity(N'Alexia Geogio', N'Alexandra George', 1, 0.0, 0.0);
--Using Jaro-Winkler distance algorithm.
SELECT jaro = mdq.Similarity(N'Alexia Geogio', N'Alexandra George', 2, 0.0, 0.0);
--Using longest common subsequence algorithm.
SELECT lcss = mdq.Similarity(N'12345', N'93459', 3, 0.0, 0.0);

Returns

Lev
----------------------
0.5625

Jacc
----------------------
0.269230769230769

jaro
----------------------
0.878846153846154

lcss
----------------------
0.6

受艾伦回答的启发,我四处寻找归一化的 Levenshtein 距离。发现这个 answer 并且,显然,它工作得很好:非规范化 mdq.Similarity 输出编辑操作的数量。因此,MDS 函数计算

1- distance(a,b)/max(a.length, b.length)

因此,我们将原始 Levenshtein 距离逆向工程为(注意四舍五入!!):

CREATE FUNCTION fnLevDist(@a VARCHAR(100), @b VARCHAR(100), @minScoreHint FLOAT=0) 
RETURNS INT AS 
BEGIN
    DECLARE @scaler REAL = CASE WHEN LEN(@a)>LEN(@b) THEN LEN(@a) ELSE LEN(@b) END
    RETURN ROUND((1.0 - mds.mdq.Similarity(@a, @b, 0, 0, @minScoreHint)) * @scaler, 0)
END
GO

WITH txt AS(
SELECT a='a', b='' 
UNION ALL SELECT a='ab', b='a' 
UNION ALL SELECT a='abc', b='ab' 
UNION ALL SELECT a='ac', b='ab' )
SELECT *, Lev=dbo.fnLevDist(a,b,0), Lev_nmzd=mds.mdq.Similarity(a,b, 0, 0, 0) FROM txt

我在包装函数中保留了 @minScoreHint 参数,因为它可以大大提高性能 (see doc)。然后输出是:

a   b   Lev Lev_nmzd
a       1   0
ab  a   1   0.5
abc ab  1   0.667
ac  ab  1   0.5

所以,毕竟还不错。不过,我希望微软引用了他们构建机器学习工作的出版物。它已经成为 Python、R 和其他软件(GPL 或其他)中包文档的标准做法。