単語の候補を伴うスペルチェッカーを実装する場合、通常どのようなアルゴリズムが使用されますか?
最初に、入力した新しい単語(辞書に見つからない場合)を、辞書の他のすべての単語からのレーベンシュタイン距離と比較して上位の結果を返すことを確認することは理にかなっていると思いました。ただし、これは非常に効率が悪く、辞書全体を繰り返し評価する必要があるようです。
これは通常どのように行われますか?
単語の候補を伴うスペルチェッカーを実装する場合、通常どのようなアルゴリズムが使用されますか?
最初に、入力した新しい単語(辞書に見つからない場合)を、辞書の他のすべての単語からのレーベンシュタイン距離と比較して上位の結果を返すことを確認することは理にかなっていると思いました。ただし、これは非常に効率が悪く、辞書全体を繰り返し評価する必要があるようです。
これは通常どのように行われますか?
回答:
スペリングコレクターの実装方法については、ピーターノービッグによる優れたエッセイがあります。これは基本的に、指定された編集距離で候補文字列を試すブルートフォースアプローチです。(ここでは、使用してスペル訂正のパフォーマンス向上させることができますどのようにいくつかのヒントがありブルームフィルタと高速化の候補ハッシュを。)
スペルチェッカーの要件は弱いです。単語が辞書にないことを知るだけでよい。ブルームフィルターを使用して、メモリ消費量の少ないスペルチェッカーを構築できます。古代バージョンは、英語の辞書に64 kbを使用して、Jon Bentleyによって 『Programming Pearls』で説明されています。
A BK-Treeの代替的なアプローチです。素敵な記事はこちらです。
レーベンシュタインの距離は、スペルチェッカーの正確な編集距離ではありません。挿入、削除、置換のみを認識します。転置が欠落しており、1文字の転置に対して2が生成されます(1つの削除と1つの挿入です)。Damerau–Levenshtein距離は、正しい編集距離です。
私が正常に使用したがどこにも説明されていない提案を生成するためのアプローチは、「悪い」ハッシュ関数を使用して提案を事前に計算することです(辞書を構築するとき)。
アイデアは、ユーザーが行うスペルミスの種類を調べ、正しいスペルと同じバケットに誤ったスペルを割り当てるハッシュ関数を設計することです。
たとえば、よくある間違いは、definiteの代わりにdefinateなどの誤った母音を使用することです。したがって、すべての母音を同じ文字として扱うハッシュ関数を設計します。これを行う簡単な方法は、最初に入力単語を「正規化」し、次に正規化された結果を通常のハッシュ関数で処理することです。この例では、正規化関数はすべての母音を削除する可能性があるため、になります。次に、「正規化された」単語は、一般的なハッシュ関数でハッシュされます。definite
dfnt
この特別なハッシュ関数を使用して、すべての辞書の単語を補助インデックス(ハッシュテーブル)に挿入します。この表のバケットは、ハッシュ関数が「悪い」ため、長めの衝突リストを持っていますが、これらの衝突リストは基本的に事前に計算された提案です。
次に、スペルミスのある単語を見つけたら、スペルミスがマッピングされているバケットの衝突リストを補助インデックスで検索します。多田:あなたは提案リストを持っています!あなたがしなければならないすべてはそれに言葉をランク付けすることです。
実際には、転置された文字、単一/二重の文字、さらには音声のスペルミスをキャッチする単純なSoundexのようなエラーなど、他のタイプのエラーを処理するために、他のハッシュ関数を使用したいくつかの補助インデックスが必要です。実際には、単純な発音の発音は長い道のりであり、些細なタイプミスを見つけるために設計された発音の一部は基本的に時代遅れになっています。
したがって、各補助インデックスのスペルミスを調べ、ランク付けの前に衝突リストを連結します。
衝突リストには、辞書にある単語のみが含まれていることに注意してください。(Peter Norvigの記事のように)代替スペルを生成しようとするアプローチを使用すると、最初に辞書に対してフィルタリングする必要がある(数万)数千の候補を取得できます。事前に計算されたアプローチを使用すると、おそらく数百の候補が得られ、それらのスペルがすべて正しいことがわかっているため、そのままスキップしてランキングに進むことができます。
更新:これに似たアルゴリズムの説明であるFAROO Distributed Searchを見つけました。これはまだ編集距離に制限のある検索ですが、事前計算ステップが私の「悪いハッシュ関数」のアイデアのように機能するため、非常に高速です。FAROOは、悪いハッシュ関数という限られた概念を使用しています。
スペルチェッカーは、Unixのスペルプログラムと同様に、非常に簡単に実装できます。ソースコードは公開されています。修正が含まれる場合があります。1つの手法は、編集を行い、この新しい単語が辞書にあるかどうかを再度確認することです。このような新しい編集をグループ化してユーザーに表示できます。
UnixシステムはMc IllRoyによって書かれたプログラムを使用します。別の方法は、巨大なファイルの場合に役立つTrieを使用することです。
UNIXのアプローチは、分散ハッシュアルゴリズムを使用するため、巨大な辞書に必要なスペースが非常に少なくて済みます。