高速スペルチェッカーを構築するための効率的なデータ構造


41

私はかなり大きな辞書で動作するはずのスペルチェッカーを書こうとしています。Damerau-Levenshtein距離を使用して、スペルミスの単語に最も近い単語を判断するために使用する辞書データを効率的にインデックス化する方法が本当に必要です。

私は、スペースの複雑さとランタイムの複雑さとの間の最適な妥協点を提供するデータ構造を探しています。

インターネットで見つけたものに基づいて、使用するデータ構造のタイプに関していくつかのリードがあります。

トライ

trie-500px

これは私の最初の考えであり、実装が非常に簡単に見えるため、高速なルックアップ/挿入を提供するはずです。Damerau-Levenshteinを使用した近似検索は、ここでも簡単に実装できるはずです。しかし、ポインタストレージでは多くのオーバーヘッドが発生する可能性が高いため、スペースの複雑さに関してはあまり効率的ではありません。

パトリシア・トライ

trie-500px

基本的にポインターを保存するコストを回避しているため、これは通常のトライよりもスペースを消費しないようですが、私が持っているような非常に大きな辞書の場合、データの断片化が少し心配です。

サフィックスツリー

サフィックス-500px

これについては定かではありませんが、テキストマイニングで便利だと思う人もいるようですが、スペルチェッカーのパフォーマンスの面で何が得られるのかはよくわかりません。

三項検索ツリー

tst

これらはかなり見栄えがよく、複雑さの点ではパトリシアトライスに近い(より良い?)はずですが、パトリシアトライスよりも良いか悪いかは分からないでしょう。

バーストツリー

バースト

これは一種のハイブリッドのようであり、トライスなどに比べてどのような利点があるかはわかりませんが、テキストマイニングには非常に効率的であると何度か読みました。


このコンテキストで使用するのに最適なデータ構造と、他のデータ構造よりも優れている点についてフィードバックを受け取りたいと思います。スペルチェッカーにさらに適切なデータ構造が不足している場合、私も非常に興味があります。


パトリシアトライは、ポインターを保存するコストをどのように回避しますか?それは単にen.wikipedia.org/wiki/Radix_treeですか?その場合は、その後、私はそれがまだポインタの多くを保存すると思いますが、共通の接頭辞が一度だけ保存されているので、あなたは巨大なスペースを節約する必要があります
ジョー

n

1
@linker:辞書のすべてのバリエーションを試しましたか?固定されたユースケースを考えると、それはおそらく、どのデータ構造がどのくらいのスペースを消費しているかを見つける最も速い方法です。
ラファエル

1
これは単なる基本的な辞書であり、正しいスペルの単語の既知のリストです。
チャールズメンガイ

1
この最も密接に関連した質問も参照してください。
ラファエル

回答:


4

私は同じ問題に遭遇しましたが、異なるアプローチを取りました。ある種の「ハッシュ」関数を作成できます。これは、類似した単語に対して同じまたは近い数を与えるものです。

問題は、挿入/削除で単語に「良い」結果を与える関数、遷移に「悪い」を与える関数、およびその逆です。例:文字を数字にマップし、同様の文字を隣接する数字にマップし、単語内のすべての文字についてそれらを合計します。次に、各キーのセットでハッシュテーブルを作成し、単語の共通部分を見つけます。

単語の「スペース」を見ると、いくつかの結果が得られるかもしれません。Xは文字を変更するため、Yは追加/削除するため、Yは遷移などのために。

しかし、これは抽象的なアイデアに過ぎず、それらを実装するのに十分な時間がありません。


これはSoundexが行うことですen.wikipedia.org/wiki/Soundex
rgrig

4

O(log(n))O

メトリックツリーに文字列を保存しないでください。インデックスを保存し、文字列をPatriciaツリーに保存するだけです。

どのツリーを使用すべきかわかりません。データと要件に依存します(高速挿入が必要ですか?)。1つのツリーが他のツリーよりも効率的であることがわかった場合は、質問を更新してください。

luceneのような特殊なツールもご覧ください。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.