我正在使用Lucene.NET 3.0.3
如何使用给定的函数修改SpellChecker(或一般查询)的评分?
具体来说,我希望SpellChecker能够将搜索到的单词的排列结果高于其他建议的结果,但我不知道应该在哪里进行。
我也会接受一个解释,解释如何使用普通查询执行此操作。我有这个功能,但我不知道将它作为查询或过滤器或其他东西会更好。
答案 0 :(得分:1)
我认为最好的解决方法是在SpellChecker对象中使用自定义Comparator。
在此处查看默认比较器的源代码:
非常简单的东西,如果您已经拥有要用来比较两个字符串的算法,那么应该很容易扩展。
然后您可以使用设置将您的比较器与SpellChecker.SetComparator
一起使用我想我曾提到过在上一个问题中使用过滤器的可能性,但我不认为这是正确的方法,再多看一下。
EDIT ---
确实,3.0.3中没有比较器,所以我相信你需要通过一个StringDistance对象访问得分。比较器会更好,因为评分已经应用并传递给它以随心所欲地做它。扩展StringDistance可能稍微具体一点,因为您必须将规则作为分数的一部分应用。
您可能希望扩展LevensteinDistance(source 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();