Java 我应该使用StringMetric还是MultisetMetric将这些字符串与simmetric进行比较

Java 我应该使用StringMetric还是MultisetMetric将这些字符串与simmetric进行比较,java,string-matching,string-metric,Java,String Matching,String Metric,我一直在使用[Simmetrics][1]Java库,成功地比较了两个字符串。但似乎有两种方法,我的场景需要两者的结合 目前,我正在使用cosinismilarity(我确实使用了一些简化程序,但为了保持代码简单,这里省略了) 这意味着Levenshtein不考虑空白,这是一个问题,因为我想匹配单词,并且基本上忽略空白或顺序。 例如,当比较蜂蜜陷阱和陷阱蜂蜜时,使用CosineSimilarity返回1.0,但Levenshtein返回0.0,这对我没有好处 理想情况下,我希望词序不重要,如果单

我一直在使用[Simmetrics][1]Java库,成功地比较了两个字符串。但似乎有两种方法,我的场景需要两者的结合

目前,我正在使用cosinismilarity(我确实使用了一些简化程序,但为了保持代码简单,这里省略了)

<>这意味着Levenshtein不考虑空白,这是一个问题,因为我想匹配单词,并且基本上忽略空白或顺序。 例如,当比较蜂蜜陷阱和陷阱蜂蜜时,使用CosineSimilarity返回1.0,但Levenshtein返回0.0,这对我没有好处

理想情况下,我希望词序不重要,如果单词中有细微的变化,例如money/mony,那么单个单词就可以很好地匹配

字符串可以是任何语言,但通常是英语,它们是歌曲标题,因此通常不到10个单词长,通常约5个单词长

Simmetrics是否提供了另一种可以同时提供这两个部分的算法

有一些简化程序,比如RefinedSoundex,可以应用于输入,但是因为语言可能不是英语,所以我认为这不会很好


您认为使用哪种算法最好?

Simmetrics包含用于比较字符串、列表、集合和多集合的度量

两个单词之间的Levenshtein距离是单个字符编辑的最小数量。空格也是一个字符,所以空格的不同会导致相似性的不同

余弦相似性是两个零向量之间的相似性(为方便起见,将其表示为多集)。因此,如果没有某种形式的处理,余弦相似性根本不适合比较字符串

根据您分割字符串的方式,最终可能会比较完全不同的内容。如果在空白处拆分字符串,最终将根据文档在单词使用方面的相似性来比较文档。如果你在n-grams上拆分字符串,你会比较字母对上的字符串,这对防止拼写错误很有效

对于您的特定用例,您可能需要研究在空格上标记化,然后在q-grams上标记化。然后试一下Cossinsimilarity,Tanimoto,Dice,SimonWhite,Jaccard

例如:

/**
*标记化器也可以链接。
* 
*“chilperic ii childeric ii的儿子`
* 
*通过在空格上拆分,标记为:
* 
*`[chilperic,ii,childeric,ii的儿子]`
* 
*使用q为2的q-gram后:
* 
*`[ch,hi,il,il,lp,pe,er,ri,ic,ii,so,on,of,ch,hi,il,ld,de,er,ri,ic,
*二]`
* 
*/
公共静态浮点示例04(){
String a=“这是一件怪事。这是一个句子。”;
String b=“这句话很相似;这是一件怪事。”;
StringMetric=
使用(新余弦相似性())
.tokenize(Tokenizers.whitespace())
.tokenize(Tokenizers.qGram(3))
.build();
返回度量。比较(a,b);//0.8292
}
为了做出决定,您可以进行一些有代表性的查询,并根据它们的结果进行比较。然后您就可以很好地决定使用哪种度量


充分披露:我是Simmetrics项目的当前维护者。

Simmetrics包含用于比较字符串、列表、集合和多集合的度量

两个单词之间的Levenshtein距离是单个字符编辑的最小数量。空格也是一个字符,所以空格的不同会导致相似性的不同

余弦相似性是两个零向量之间的相似性(为方便起见,将其表示为多集)。因此,如果没有某种形式的处理,余弦相似性根本不适合比较字符串

根据您分割字符串的方式,最终可能会比较完全不同的内容。如果在空白处拆分字符串,最终将根据文档在单词使用方面的相似性来比较文档。如果你在n-grams上拆分字符串,你会比较字母对上的字符串,这对防止拼写错误很有效

对于您的特定用例,您可能需要研究在空格上标记化,然后在q-grams上标记化。然后试一下Cossinsimilarity,Tanimoto,Dice,SimonWhite,Jaccard

例如:

/**
*标记化器也可以链接。
* 
*“chilperic ii childeric ii的儿子`
* 
*通过在空格上拆分,标记为:
* 
*`[chilperic,ii,childeric,ii的儿子]`
* 
*使用q为2的q-gram后:
* 
*`[ch,hi,il,il,lp,pe,er,ri,ic,ii,so,on,of,ch,hi,il,ld,de,er,ri,ic,
*二]`
* 
*/
公共静态浮点示例04(){
String a=“这是一件怪事。这是一个句子。”;
String b=“这句话很相似;这是一件怪事。”;
StringMetric=
使用(新余弦相似性())
.tokenize(Tokenizers.whitespace())
.tokenize(Tokenizers.qGram(3))
.build();
返回度量。比较(a,b);//0.8292
}
为了做出决定,您可以进行一些有代表性的查询,并根据它们的结果进行比较。然后您就可以很好地决定使用哪种度量


充分披露:我目前是Simmetrics项目的维护者。

简单方法:同时使用这两种方法,并获得更高的分数。@ammoQ刚刚认为自己肯定是一个可能的黑客,但这是相当cpu密集型的,我希望其他一种方法已经达到了我想要的效果。简单方法:同时使用这两种方法,“AMOQ的想法确实是一个可能的黑客,但这是CPU密集型的,我希望其他度量之一已经做了我想要的。所以我使用各种简化器,但余弦系数基本上只是计算出在SET2中SET1中的令牌比例是多少,它是否考虑了顺序?(我想不会吧),我读了这本书后也不能理解
StringMetric metric = with(new CosineSimilarity<String>())
                .tokenize(Tokenizers.whitespace()).build();
 score = metric.compare(string1, string2);
 StringMetric metric = with(new Levenshtein())
                .build();
/**
 * 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
}