最近、Wikipediaの疑似コードからDamerau-Levenshtein距離アルゴリズムを実装しました。私はそれがどのように機能するかの正確な説明を見つけることができませんでした、そして疑似コードはDA
、DB
、i1
、およびj1
のような完全に情報のない変数名を使用するため、頭を悩ませました。
これがPythonでの私の実装です: https://Gist.github.com/badocelot/5327337
Pythonの実装は、プログラムをウォークスルーして、変数の名前をよりわかりやすい名前に変更し、何が起こっているのかを理解するのに役立ちました。ワベナー-フィッシャーのアプローチを十分に理解して、参照のフレームがありました。
過度に長くなるリスクがあるので、ダメラウ・レヴェンシュタインを理解する方法は次のとおりです。
謎の変数:
DA
(私のコードではlast_row
)は、各要素が表示された最後の行を保持する一種のマップです。私のコードでは実際のPython辞書ですDB
(last_match_col
)は、b
の文字が現在の行のa
の文字と一致した最後の列を保持しますi1
(last_matching_row
)は、DA
の現在の文字のb
からの行番号ですj1
は、更新される前のDB
/last_match_col
の値の単なるコピーです。私のコードでは、last_match_col
が更新されている場所に移動し、この変数を削除しました転置コスト:
H[i1][j1] + (i-i1-1) + 1 + (j-j1-1)
b
の現在の文字をb
にあることがわかっているa
の最後の文字(最後の一致)と交換するコストを計算し、その間のすべての文字を追加または削除として扱います。
コストの構成要素:
H[i1][j1]
転置を見つけると以前の作業が無効になるため、基本コストを転置前の計算のポイントに戻します。(i-i1-1)
は、現在の行と現在の文字に一致する最後の行の間の距離です。これは、必要な削除の数です(j-j1-1)
は、現在の列と一致する最後の列の間の距離であり、追加の数です+ 1
は、転置自体のコストですこの分析が正しくない場合は、どこに問題があるのかを知りたいです。言ったように、アルゴリズムがオンラインでどのように機能するかについての詳細な説明は見つかりませんでした。
改良バージョン?
しかし、それを理解したので、転置された文字間のbothの追加と削除のコストを計算することには欠陥があるように見えました:1つの追加と1つの削除は置換に相当します。これはチェックしていません。
すべてが正しい場合、解決策は簡単です:転置された文字間の文字のコストは、追加と削除の高いである必要があります。できるだけ多くを置換に変換して追加してください残された追加または削除。
したがって、コストは次のようになります。
H[i1][j1] + max((i-i1-1), (j-j1-1)) + 1
これがこのバージョンの私のコードです: https://Gist.github.com/badocelot/5327427
いくつかの簡単なテストから、これは正しいようです。たとえば、 "abcdef"-> "abcfad"は編集距離を2(転置 "d"と "f"、 "e"を "a"に変更)しますが、元のアルゴリズムは距離を3(最後の3つ)にします。文字は置換、または1つの転置+ 1つの追加+ 1つの削除です)。
今、私はこれを最初に考えた人にすることはできません。それで、なぜ私はそれに遭遇しなかったのですか?私は十分に長く検索しなかったのですか?または、これが実際に機能しないようにする微妙な欠陥がありますか?
私はウィキペディアでダメラウとレヴェンシュタインの距離を調べなければならなかったので、これが間違っていても許してください。しかし、それは隣接する文字の転置のみを可能にし、任意の文字の転置はできないように見えます。したがって、dとfを転置した "abcdef"-> "abcfad"の例は機能しません。アルゴリズムの定義を変更し、Damerau-Levenshtein距離を計算しなくなったようです。