【问题标题】:Lucene SpellChecker Prefer Permutations or special scoringLucene SpellChecker 首选排列或特殊评分
【发布时间】:2012-11-21 07:20:49
【问题描述】:

我正在使用 Lucene.NET 3.0.3

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

具体来说,我希望 SpellChecker 对搜索词排列的任何结果的评分高于其他建议,但我不知道应该在哪里完成。

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

【问题讨论】:

    标签: lucene lucene.net spell-checking


    【解决方案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();
    

    【讨论】:

      【解决方案2】:

      我认为解决此问题的最佳方法是在 SpellChecker 对象中使用自定义的比较器。

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

      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

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

      编辑---

      确实,3.0.3 中没有 Comparator 可用,所以我相信您需要通过 StringDistance 对象访问评分。 Comparator 会更好,因为评分已经被应用并被传递给它来做你喜欢的事情。扩展 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;
          }
      }
      

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

      一旦您有了自定义 StringDistance,就可以通过构造函数或 SpellChecker.setStringDistance 将其传递给 SpellChecker

      【讨论】:

      • 我会在那里询问更多细节,但这似乎是一个单独的问题。谢谢你告诉我去哪里看!
      • 啊。 Lucene.NET 3.0.3 贡献中不存在 SpellCheck.SetComparator。这可以通过其他方式完成吗?我很想尝试移植它,但我可能没有足够的时间去做。
      • 对,我在看 3.6.0,看起来 Spellchecker 上的比较器是自 3.0.3 以来的新功能。让我们看看。
      • 太棒了! :) 我最终实现了 StringDistance ` PermutationDistance: SpellChecker.Net.Search.Spell.StringDistance` 而不是从 Levenshtein distance 继承,因为它不可覆盖,但否则你的答案正是我所需要的。我会为其他人发布我的代码。谢谢!
      猜你喜欢
      • 2012-11-19
      • 1970-01-01
      • 1970-01-01
      • 2016-10-08
      • 1970-01-01
      • 1970-01-01
      • 2011-05-03
      • 2011-04-04
      相关资源
      最近更新 更多