我应该使用 StringMetric 还是 MultisetMetric 将这些字符串与 simmetric 进行比较
Should I use StringMetric or MultisetMetric for comparing these Strings with simmetric
我一直在使用 [Simmetrics][1] Java 库来成功地比较两个字符串。但是似乎有两种方法,我需要将两者结合起来用于我的场景。
目前我正在使用 CosineSimilarity(我确实使用了一些简化器,但在这里省略以保持代码简单)
StringMetric metric = with(new CosineSimilarity<String>())
.tokenize(Tokenizers.whitespace()).build();
score = metric.compare(string1, string2);
这很好用,除非我有一个简单的拼写错误,我本以为会得到比我得到的更高的分数
例如仅比较 mony honey 和 money honey returns 0.5 (分数从 0.0 到 1.0,1.0 是完美匹配),我本来期望更高。
有了 Levenshtein,它 return 更好 0.9090909
但我在阅读文档时注意到的一件事是,这是一个 MultiSet 指标,实际上需要 whitespace() 将输入分成几部分,而 StringMetric如Levenshtein不
StringMetric metric = with(new Levenshtein())
.build();
这意味着 Levenshtein 没有特别考虑空格,这是一个问题,因为我想匹配单词并基本上忽略空格或顺序。
所以例如使用 CosineSimilarity 它 returns 1.0 比较 honey trap 和 trap honey 但 Levenshtein return 0.0,这对我没有好处。
理想情况下,我想要的是词序不重要,然后如果词中只有细微的变化,那么单个词就能很好地匹配,例如 money/mony
字符串可以是任何语言,但最常见的是英文,它们是歌曲名称,因此长度通常少于十个单词,通常约为 5 个单词。
Simmetrics 是否提供另一种可以提供这两个部分的算法?
可以将 RefinedSoundex 等简化器应用于输入,但由于语言可能不是英语,因此认为它不会很好用。
您认为最好的算法是什么?
Simmetrics 包含用于比较字符串、列表、集合和多重集合的指标。
两个单词之间的Levenshtein 距离是单个字符编辑的最小数量。空格也是一个字符,所以空格的不同会导致相似度的不同。
余弦相似度是两个零向量之间的相似度(为方便起见,表示为多重集)。因此,如果没有某种形式的处理余弦相似度,根本不适合比较字符串。
根据您拆分字符串的方式,您最终可能会比较完全不同的事物。如果你在空格上拆分字符串,你最终会通过它们在单词用法上的相似性来比较文档。如果您在 n-gram 上拆分字符串,您将比较它们的字母对上的字符串,这往往可以很好地防止拼写错误。
对于您的特定用例,您可能希望研究对空格进行标记化,然后对 q-gram 进行标记化。然后尝试 CosineSimilarity、Tanimoto、Dice、SimonWhite、Jaccard。
例如:
/**
* Tokenizers can also be chained.
*
* `chilperic ii son of childeric ii`
*
* By splitting on whitespace is tokenized into:
*
* `[chilperic, ii, son, of, childeric, ii]`
*
* After using a q-gram with a q of 2:
*
* `[ch,hi,il,il,lp,pe,er,ri,ic, ii, so,on, of, ch,hi,il,ld,de,er,ri,ic,
* ii]`
*
*/
public static float example04() {
String a = "A quirky thing it is. This is a sentence.";
String b = "This sentence is similar; a quirky thing it is.";
StringMetric metric =
with(new CosineSimilarity<String>())
.tokenize(Tokenizers.whitespace())
.tokenize(Tokenizers.qGram(3))
.build();
return metric.compare(a, b); // 0.8292
}
要做出决定,您可以进行一些有代表性的查询,然后比较 precision and recall 的结果。然后您就可以很好地决定使用哪个指标。
完全披露:我是 Simmetrics 项目的当前维护者。
我一直在使用 [Simmetrics][1] Java 库来成功地比较两个字符串。但是似乎有两种方法,我需要将两者结合起来用于我的场景。
目前我正在使用 CosineSimilarity(我确实使用了一些简化器,但在这里省略以保持代码简单)
StringMetric metric = with(new CosineSimilarity<String>())
.tokenize(Tokenizers.whitespace()).build();
score = metric.compare(string1, string2);
这很好用,除非我有一个简单的拼写错误,我本以为会得到比我得到的更高的分数
例如仅比较 mony honey 和 money honey returns 0.5 (分数从 0.0 到 1.0,1.0 是完美匹配),我本来期望更高。
有了 Levenshtein,它 return 更好 0.9090909
但我在阅读文档时注意到的一件事是,这是一个 MultiSet 指标,实际上需要 whitespace() 将输入分成几部分,而 StringMetric如Levenshtein不
StringMetric metric = with(new Levenshtein())
.build();
这意味着 Levenshtein 没有特别考虑空格,这是一个问题,因为我想匹配单词并基本上忽略空格或顺序。
所以例如使用 CosineSimilarity 它 returns 1.0 比较 honey trap 和 trap honey 但 Levenshtein return 0.0,这对我没有好处。
理想情况下,我想要的是词序不重要,然后如果词中只有细微的变化,那么单个词就能很好地匹配,例如 money/mony
字符串可以是任何语言,但最常见的是英文,它们是歌曲名称,因此长度通常少于十个单词,通常约为 5 个单词。
Simmetrics 是否提供另一种可以提供这两个部分的算法?
可以将 RefinedSoundex 等简化器应用于输入,但由于语言可能不是英语,因此认为它不会很好用。
您认为最好的算法是什么?
Simmetrics 包含用于比较字符串、列表、集合和多重集合的指标。
两个单词之间的Levenshtein 距离是单个字符编辑的最小数量。空格也是一个字符,所以空格的不同会导致相似度的不同。
余弦相似度是两个零向量之间的相似度(为方便起见,表示为多重集)。因此,如果没有某种形式的处理余弦相似度,根本不适合比较字符串。
根据您拆分字符串的方式,您最终可能会比较完全不同的事物。如果你在空格上拆分字符串,你最终会通过它们在单词用法上的相似性来比较文档。如果您在 n-gram 上拆分字符串,您将比较它们的字母对上的字符串,这往往可以很好地防止拼写错误。
对于您的特定用例,您可能希望研究对空格进行标记化,然后对 q-gram 进行标记化。然后尝试 CosineSimilarity、Tanimoto、Dice、SimonWhite、Jaccard。
例如:
/**
* Tokenizers can also be chained.
*
* `chilperic ii son of childeric ii`
*
* By splitting on whitespace is tokenized into:
*
* `[chilperic, ii, son, of, childeric, ii]`
*
* After using a q-gram with a q of 2:
*
* `[ch,hi,il,il,lp,pe,er,ri,ic, ii, so,on, of, ch,hi,il,ld,de,er,ri,ic,
* ii]`
*
*/
public static float example04() {
String a = "A quirky thing it is. This is a sentence.";
String b = "This sentence is similar; a quirky thing it is.";
StringMetric metric =
with(new CosineSimilarity<String>())
.tokenize(Tokenizers.whitespace())
.tokenize(Tokenizers.qGram(3))
.build();
return metric.compare(a, b); // 0.8292
}
要做出决定,您可以进行一些有代表性的查询,然后比较 precision and recall 的结果。然后您就可以很好地决定使用哪个指标。
完全披露:我是 Simmetrics 项目的当前维护者。