Lucene SpellChecker喜欢排列或特殊得分

时间:2012-12-03 18:56:54

标签: lucene lucene.net spell-checking

我正在使用Lucene.NET 3.0.3

如何使用给定的函数修改SpellChecker(或一般查询)的评分?

具体来说,我希望SpellChecker能够将搜索到的单词的排列结果高于其他建议的结果,但我不知道应该在哪里进行。

我也会接受一个解释,解释如何使用普通查询执行此操作。我有这个功能,但我不知道将它作为查询或过滤器或其他东西会更好。

2 个答案:

答案 0 :(得分:1)

我认为最好的解决方法是在SpellChecker对象中使用自定义Comparator。

在此处查看默认比较器的源代码:

http://grepcode.com/file/repo1.maven.org/maven2/org.apache.lucene/lucene-spellchecker/3.6.0/org/apache/lucene/search/spell/SuggestWordScoreComparator.java?av=f

非常简单的东西,如果您已经拥有要用来比较两个字符串的算法,那么应该很容易扩展。

然后您可以使用设置将您的比较器与SpellChecker.SetComparator

一起使用

我想我曾提到过在上一个问题中使用过滤器的可能性,但我不认为这是正确的方法,再多看一下。

EDIT ---

确实,3.0.3中没有比较器,所以我相信你需要通过一个StringDistance对象访问得分。比较器会更好,因为评分已经应用并传递给它以随心所欲地做它。扩展StringDistance可能稍微具体一点,因为您必须将规则作为分数的一部分应用。

您可能希望扩展LevensteinDistancesource code),这是默认的StringDistance实现,但当然也可以尝试JaroWinklerDistance。不太熟悉算法。

首先,在获得与标准(父)实现的getDistance调用的基线距离之后,您将要覆盖getDistance并在那里应用您的评分规则。

我可能会实现类似的东西(假设你有一个辅助方法boolean isPermutation(String, String)

class CustomDistance() extends LevensteinDistance{
    float getDistance(String target, String other) {
        float distance = super.getDistance();
        if (isPermutation(target, other)) {
            distance = distance + (1 - distance) / 2;
        }
        return distance;
    }
}

对于作为置换的结果,再次计算得分的一半(即,如果默认算法给出距离= .6,则返回距离= .8等)。返回的距离必须介于0和1之间。我的示例只是一个可能得分的想法,但您可能需要稍微调整算法。我对于简单地为所有排列返回1.0都要谨慎,因为当用'weiss'查看时,肯定会更喜欢'isews'而不是'weis',并且它也会失去对不同排列的接近程度进行排序的能力('在这种情况下,isews'和'wiess'将与'weiss'相等。)

获得Custom StringDistance后,可以通过构造函数或SpellChecker.setStringDistance

将其传递给SpellChecker

答案 1 :(得分:1)

从femtoRgon的建议来看,这就是我最终做的事情:

    public class PermutationDistance: SpellChecker.Net.Search.Spell.StringDistance
    {

    public PermutationDistance()
    {

    }

    public float GetDistance(string target, string other)
    {
        LevenshteinDistance l = new LevenshteinDistance();
        float distance = l.GetDistance(target, other);

        distance = distance  + ((1 - distance) * PermutationScore(target, other));

        return distance;
    }

    public bool IsPermutation(string a, string b)
    {
        char[] ac = a.ToLower().ToCharArray();
        char[] bc = b.ToLower().ToCharArray();

        Array.Sort(ac);
        Array.Sort(bc);

        a = new string(ac);
        b = new string(bc);

        return a == b;
    }

    public float PermutationScore(string a, string b)
    {
        char[] ac = a.ToLower().ToCharArray();
        char[] bc = b.ToLower().ToCharArray();

        Array.Sort(ac);
        Array.Sort(bc);

        a = new string(ac);
        b = new string(bc);

        LevenshteinDistance l = new LevenshteinDistance();
        return l.GetDistance(a, b);
    }
}

然后:

_spellChecker.setStringDistance(new PermutationDistance());
 List<string> suggestions = _spellChecker.SuggestSimilar(word, 10).ToList();
相关问题