2

Lucene.NET 3.0.3 を使用しています

特定の関数を使用して SpellChecker (またはクエリ全般) のスコアを変更するにはどうすればよいですか?

具体的には、SpellChecker が検索された単語の順列である結果を残りの提案よりも高くスコア付けしたいのですが、どこでこれを行うべきかわかりません。

通常のクエリでこれを行う方法を説明する回答も受け入れます。私は関数を持っていますが、それをクエリにするか、フィルターにするか、または何か他のものにする方が良いかどうかはわかりません。

4

2 に答える 2

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();
于 2012-12-03T22:10:55.097 に答える
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

2 つの文字列を比較するために使用するアルゴリズムが既にある場合は、非常に単純なものを簡単に拡張できます。

次に、 SpellChecker.SetComparatorでコンパレータを使用するように設定できます

以前の質問で、これに Filter を使用する可能性について言及したと思いますが、それは本当に正しい方法ではないと思います。

編集 - -

実際、3.0.3 では Comparator は使用できないため、StringDistanceオブジェクトを介してスコアリングにアクセスする必要があると思います。Comparator は、スコアリングが既に適用されており、好きなことを行うために渡されるため、より優れています。StringDistance の拡張は、スコアの一部としてルールを適用する必要があるため、少し具体的ではない場合があります。

デフォルトの StringDistance 実装であるLevensteinDistance (ソース コード)を拡張したいと思うかもしれませんが、もちろん、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 つのアイデアにすぎませんが、アルゴリズムを多少調整する必要がある可能性があります。すべての順列に対して単純に 1.0 を返すことには注意が必要です。これは、'weiss' で検索するときに 'weis' よりも 'isews' を優先することが確実であり、異なる順列の近さをソートする機能も失うためです ('その場合、isews と wiess は weiss と等しく一致します)。

カスタム StringDistance を取得したら、コンストラクターを介して、または SpellChecker.setStringDistance を使用して SpellChecker に渡すことができます

于 2012-12-03T20:41:08.657 に答える