レーベンシュタイン距離をすばやく計算する


24

許可された単語(アルファベット順)と単語の巨大なデータベースが与えられた場合、レーベンシュタイン距離に関して与えられた単語に最も近いデータベースから単語を見つけます。

単純なアプローチは、もちろん、指定された単語と辞書内のすべての単語間のレベンシュタイン距離を単純に計算することです(実際に距離を計算する前にデータベースでバイナリ検索を実行できます)。

この問題に対するより効率的な解決策があるのだろうか。おそらく、検索する単語の数を減らすヒューリスティック、またはレベンシュタイン距離アルゴリズムの最適化が可能です。

このテーマに関する論文へのリンクは歓迎です。

回答:


16

あなたが尋ねているのは、編集距離の下での近傍検索の問題です。理論的な結果に興味があるのか​​、発見的手法に興味があるのか​​は言及しなかったので、前者に答えます。

編集距離は、近傍検索構造を構築するためにやや厄介です。主な問題は、メトリックとして、次元の削減と近似の目的で、などの他のよく知られている悪いメトリックと同様にすることです。このトピックについて読むにはかなり膨大な作業があり、あなたの最良の情報源はAlex Andoniによる一連の論文です:ポインターを後方にたどることにより(たとえば、FOCS 2010の論文から)、優れた情報源のセットが得られます。1


1
メトリック空間について私が知っているのはセマンティクスだけなので、質問:レーベンシュタインメトリックのウルトラメトリックへの適切な(まともな値の)埋め込みはありますか?オフハンド、それはバイナリツリーのようなアルゴリズムを生み出すかもしれません。
ニールクリシュナスワミ

よくわかりません。一般的に答えはノーだと思いますが、指摘するものは何もありません。
スレシュヴェンカト

boytsov.info/pubsに関する2番目の論文は、レーベンシュタインとダメロー-レーベンシュタインの編集距離の下での近傍検索の可能な解決策の良い調査です。
a3nm

ultrametricに埋め込む@NeelKrishnaswami Anが少なくとも歪みを有することになる文字列の長さです。これは、中に埋め込むための下限歪から次起因しKrauthgamerとRabani ultrametricsが等角に埋め込むユークリッド空間に等角埋め込むので、。d L 1 L 1Ω(logd)dL1L1
サショニコロフ


5

許容する編集ミスが少ない場合は、ドット付き接尾辞ツリーを使用してみてください。免責事項:私はその論文を書きましたが、それはあなたが望むものを解決します:それは高いディスクスペースコストを持っていますが、クエリは本当に速いです。

一般的には、逆に見た方が良いです。辞書のすべての単語のインデックスがあります。ここで、入力語wについて、辞書にある場合は停止します。それ以外の場合、距離1ですべてのバリエーションを生成し、それらを探します。存在しない場合は、距離2でのバリエーションを探します...

この基本的な考え方にはいくつかの改善点があります。


1
論文の再現可能な研究アーカイブへのリンクを含める必要があります。
ダンD.


4

私はcs.stackexchange.com(/cs//a/2096/1490)で非常によく似た質問への回答を書いた後、この質問を見つけました。そこにある答えは、編集距離での近似近傍検索です(つまり、アルゴリズムはクエリ文字列の最近傍とほぼ同じクエリ文字列に近い文字列を出力します)。ここに投稿したのは、ここで与えられた回答でそこに挙げた参考文献が見つからないからです。


3

あなたが望むのはワーグナー・フィッシャーのアルゴリズムだと思います:https : //en.wikipedia.org/wiki/Wagner%E2%80%93Fischer_algorithm重要な洞察は、あなたが通っている辞書がソートされているので、2つの連続した単語長いプレフィックスを共有する可能性が非常に高いため、距離計算ごとにマトリックス全体を更新する必要はありません。


2

使用できますか?

そして、「Did you mean」で返された回答とダイナミックプログラミングを使用した入力文字列の間のレーベンシュタイン距離を見つけます。


この答えがわかりません。質問は、レーベンシュタイン距離を計算する方法やブラックボックススペルチェッカーの出力との比較ではなく、特定の入力に近いレーベンシュタイン距離を持つ大きな辞書で単語を効率的に見つける方法を尋ねます...
Huck Bennett

@Huck Bennett:@Grigory JavadyanがDid you mean?機能を構築していると思いました。その上Did you mean?、与えられた入力に非常に近い単語を返し、かなり効率的にそれをします。:)
プラティックデオガレ

あなたのアイデアは良いと思いますが、グリゴリーはより深く、より具体的な何かを求めているようです。
ハックベネット

@ハック・ベネット:はい、そうです!:)
プラティックデオガレ

-1

1つの方法は、機械学習モデルをトレーニングして、単語をベクトルにマッピングし、レベンシュタイン距離をユークリッド距離にマッピングすることです。次に、使用する辞書のベクトルからKDTreeを構築できます。ここでこれを行うjupyterノートブックを作成しました:https ://gist.github.com/MichaelSnowden/9b8b1e662c98c514d571f4d5c20c3a03

DWのコメントによると:

  1. トレーニング手順=適応勾配を伴う確率的勾配降下
  2. 損失関数=真の編集距離とユークリッド距離の平均二乗誤差
  3. トレーニングデータ= 1〜32文字のランダムな文字列(一般的なタイプミスの実際の分布と一致するデータで改善できます)
  4. 定量的結果:バッチサイズ2048(壁時間=約1分)で約150エポックのトレーニングを行った後、512次元のワード埋め込みを使用し、1つの隠しレイヤー、真の編集距離と予測編集距離の間の平均絶対誤差0.75付近に位置します。これは、予測される編集距離が約1文字ずれていることを意味します

モデル構造の要約:

  1. ヌル文字を含む各文字の学習済み埋め込みを作成します(後で文字制限の下でテキストを右詰めするために使用されます)
  2. 文字の制限(32)になるまで、テキストの右側にヌル文字を埋め込みます。
  3. これらの埋め込みを連結します
  4. フィードフォワードニューラルネットを介して埋め込みを実行し、低次元の単語埋め込み(512次元)を生成します。
  5. 両方の単語に対してこれを行います
  6. ベクトル間のユークリッド距離を見つける
  7. 損失を真のレーベンシュタイン距離とユークリッド距離の間の平均二乗誤差に設定します

私のトレーニングデータは単なるランダムな文字列ですが、トレーニングデータが(typo / correct word)ペアであった場合、結果は本当に改善されると思います。/usr/share/dict/wordsそれが一般的に利用可能であるため、私はちょうど使用することになりました。


2
レーベンシュタイン距離の近くにある単語が同様のベクトルにマップされるように、MLモデルをどのようにトレーニングしますか?そのためにどのようなトレーニング手順と損失関数を使用していますか?リンクが機能しなくなっても答えが役立つように、また、使用しているメソッドを理解するためにノートブックを掘り下げる必要がないように、メソッドを回答に要約できますか?また、定量的にどのように機能するかを評価できますか?これは他の選択肢よりも優れていますか?
DW

現状では、これは(私は)CSTheoryにはあまり適合していません。つまり、具体的に何が提案されているのか、それを理論的に正当化するものがないということです。
クレメントC.

@DWそれについてすみません-リンクがダウンした場合(またはノートブックを突っ込みたくない場合)に包括的な包括的な編集を行いました。これは研究ではないので実際にはCS理論ではありませんが、トレーニングと推論の両方で高速かつ簡単であるため、実用的なアプローチだと思います。
マイケルズノウデン

1
ランダムな文字列でトレーニングしています。このような2つの弦の間の予想されるレーベンシュタイン距離は、おおよそ長い弦の長さになります。したがって、ランダムな文字列でこの距離を推定するのは非常に簡単ですが、実際のデータを扱うのには役立ちません。埋め込みは文字列の長さをエンコードするだけである可能性があるため、些細で役に立たない何かを行うための素晴らしい方法を構築している可能性があります。これはMLの使用に関する問題です。使用する損失関数に非常に敏感です。
DW

@DWノートブックで結果を見ると、検索では、同じ長さの文字列だけでなく、適切な結果が返されました。私はあなたがそれをスキミングすることを本当にお勧めします。些細で役に立たないとは言いません。
マイケルズノウデン
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.