SQL - 两个不同长度的字符串之间的相似性

Posted

技术标签:

【中文标题】SQL - 两个不同长度的字符串之间的相似性【英文标题】:SQL - Similarity between two strings of varying length 【发布时间】:2013-09-08 14:25:22 【问题描述】:

我有一个 SQL Server 产品表,每个产品都有一个可在我们的网站上公开获得的描述。我想防止或至少在描述与另一个产品的描述过于相似时警告我们的用户。每个产品的描述长度可能会有很大差异。

我想查询描述中包含重复/相似段落/文本块的产品。即字符串 A 有一堆独特的内容,但与字符串 B 共享一个相似/相同的段落。但是,我不确定哪种相似性算法最适合使用:

Levenshtein distance 和 Jaro-Winler distance 算法似乎只适用于短字符串。

我不确定longest common subsequence algorithm 是否能很好地考虑到较大的差异。即它似乎忽略了两个字符之间的潜在空间,寻找任何相似的组合序列。

Fuzzy hashing 听起来像是我在寻找的东西,但我不仅仅是在寻找具有细微差异的重复内容。我也在寻找重复的内容,在独特的文本块中注入了细微的差异。而且我不知道如何在 SQL 中实现模糊哈希。 SOUNDEX() 和 DIFFERENCE() 似乎使用模糊散列,但对于我的用例来说相当不精确。

理想情况下,相似性 SQL 函数会很快,但我可以将缓存的相似性值存储在另一个表中,并安排一个作业偶尔更新。

实现此目的的最佳算法/SQL(或 CLR 集成)实现是什么?

【问题讨论】:

你为什么限制自己在 SQL 中实现这个? 好吧,我想它不需要在 SQL 中。但是,我假设纯 SQL 实现会更高效。我可能会使用像 this similarity library 这样的 .NET CLR 集成......但我没有 SQL Server CLR 集成的经验,我仍然不知道要使用什么算法。 您可以尝试的一件事是获取字符串并仅考虑某些字母的实例,然后再考虑这些字符串。例如,以“Lorem ipsum dolor sit amet”之类的文本为例,只考虑 e's 和 t's 的实例。生成的字符串将是 etet,您可以针对另一个过滤的字符串进行 Levenshtein。显然需要一些调整,但希望你能明白。 @kevmo314 很有趣。我假设删除字母表的重要部分的目的是为了帮助匹配单个段落匹配? @DavidBudiac Sorta。一般的想法是,因为 Levenshtein 是 O(n^2),所以减少 75% 的 n 会产生 94% 的性能提升,我们希望利用这一点。我们也知道很多时候,即使缺少字符,您也可以插入单词,因此通过删除字符,我们生成了一个压缩版本,它更像是文本的签名,而不是 deflate 式压缩。这也滥用了我们不需要“解压缩”签名的事实。 :) 【参考方案1】:

我最近不得不通过模糊字符串匹配来加入组名。 我已经尝试了大约 40 种不同的算法,但没有一个能做到这一点,即使组名的不同之处仅在于一些拼写错误、缺少空格以及偶尔在末尾添加 _mLF。

因此,如果您尝试类似的事情,我强烈建议您现在停止,并将数据(在我的情况下为 Excel 文件)发送回用户以进行更正,它所属的位置。

如果您真的只是对比较字符串感兴趣,此链接可能正是您所需要的:http://anastasiosyal.com/POST/2009/01/11/18.ASPX

我发现 Jaro-Winkler 函数可以在我的案例中产生最佳结果,但您可以自己测试。

【讨论】:

是的,理想情况下我会告诉用户停止输入重复的文本。但无论如何,有些人会继续这样做......我需要能够追溯发现内容何时重复/相似。那篇文章肯定有帮助。 我还发现这种模糊搜索算法的性能相当不错:sites.google.com/site/sqlblindman/fuzzysearchalgorithm

以上是关于SQL - 两个不同长度的字符串之间的相似性的主要内容,如果未能解决你的问题,请参考以下文章

python中是不是有用于计算两个字符串相似度的函数

sql 替换 两特定字符(含特定字符)之间的字段

文本去重算法——simhash简介

如何在 Python 中比较两个字符串(英语除外)之间的相似性

不同长度向量的余弦相似度?

Informix SQL 查询:返回不同结果的两个相似查询