文字列の類似性に最適なアルゴリズムは何ですか?


23

アドレスに基づいてさまざまなWebページのコンテンツを一意に識別するプラグインを設計しています。

したがって、次のようなアドレスを1つ持つことができます。

1 someawesome street, anytown, F100 211

後で、このアドレスがわずかに異なる形式で見つかる場合があります。

1 someawesome street, F100 211,

またはおそらく曖昧な

someawesome street F100

これらは技術的には同じアドレスですが、ある程度の類似性があります。a)検索を実行するために各アドレスに一意の識別子を生成し、b)非常に類似したアドレスがいつ表示されるかを把握したいと思います。

どのアルゴリズム/テクニック/文字列メトリクスを見るべきですか?レーベンシュタイン距離は明らかな選択のように見えますが、ここで役立つ他のアプローチがあるかどうかは興味があります。


「レーベンシュタイン距離」はアルゴリズムではありません。
gnasher729

基本的な解析を導入しない限り、生のレーベンシュタイン距離はそれほど良くありません。少なくとも、通りや町の名前などの単語や、通りの番号や郵便番号などの単語を特定するようにしてください。次に、実際の場所/通りの名前を入力する統計ファジーマッチャーを使用して、これらにLevensteinを適用します。簡単なことではありません:)

7
@gnasher:しかし、レーベンシュタイン距離を計算する関数アルゴリズムです。そのような機能がなければ、レーベンシュタイン距離は単なる知的好奇心に過ぎません。
ロバートハーベイ

私はここで例を使って非常に実用的な説明を見つけました:アルゴリズムの比較。結論として、Levensteinのアルゴリズムは文字列の長さに依存するため、Jaro-Winklerの類似性を使用することを推奨しているため、比較することは有用ではありません。
サンドラメネセス

回答:


14

Levensteinのアルゴリズムは、文字列の挿入、削除、および置換の数に基づいています。

残念ながら、2文字の転置である一般的なつづりの間違いは考慮されていません(例:素晴らしくて不愉快な)。したがって、より堅牢なDamerau-Levensteinアルゴリズムを好むでしょう。

時間は比較される弦の長さとともに急激に増加するため、弦全体に距離を適用することは良い考えではないと思います。さらに悪いことに、ZIPなどの住所コンポーネントを削除すると、完全に異なる住所がよりよく一致する場合があります(オンラインレーベンシュタインカルキュレーターを使用して測定)。

1 someawesome street, anytown, F100 211       (reference) 
1 someawesome st.,anytown                     (difference of 15, same address)     
1 otherplaces street,anytown,F100211          (difference of 13, different ddress) 
1 sameawesome street, othertown, CA98200      (difference of 13, different ddress)
anytown, 1 someawesome street                 (28 different same address)
anytown, F100 211, 1 someawesome street       (37 different same address)

これらの効果は、ストリート名が短いほど悪化する傾向があります。

したがって、よりスマートなアルゴリズムを使用した方がよいでしょう。たとえば、Arthur Ra​​tzはCodeProjectでスマートテキスト比較のアルゴリズムを公開しました。アルゴリズムは距離を出力しません(確かにそれに応じて豊かにすることができます)が、テキストブロックの移動(たとえば、最初の例と最後の例の間の町と通りの間のスワップ)などのいくつかの難しいものを識別します。

そのようなアルゴリズムがあなたの場合にはあまりにも一般的である場合、実際にコンポーネントごとに作業し、比較可能なコンポーネントのみを比較する必要があります。世界のアドレス形式を解析する場合、これは簡単なことではありません。しかし、ターゲットがより具体的である場合、たとえば米国の場合、それは確かに実行可能です。たとえば、「street」、「st。」、「place」、「plazza」、およびそれらの通常のスペルミスは、アドレスのストリート部分を明らかにする可能性があり、その先頭部分は原則として番号になります。郵便番号は町を見つけるのに役立ちます。あるいは、住所の最後の要素である可能性があります。または、推測が気に入らない場合は、都市名のリストを検索できます(無料の郵便番号データベースのダウンロードなど)。その後、関連するコンポーネントのみにDamerau-Levenshteinを適用できます。


比較の前に両方の比較文字列をソートするのはどうですか?これが移調に役立つことがわかった。
オープンウォンク

2

レーベンシュタイン距離は単語の方が良い

単語の綴りが(主に)正しい場合は、bag of wordsを見てください。私は過剰殺害のように見えるかもしれませんが、TF-IDFコサイン類似性

または、無料のLuceneを使用できます。それらはコサインの類似性を持っていると思います。


1

まず、Webページのアドレスを解析する必要があります。RegExは取るように書かれたものですが、RegExを使用してアドレスを解析することは非常に困難です。おそらく、潜在的なアドレス指定形式のリストと、それらに一致する優れた1つ以上の式を調べる必要があります。私はあまりアドレス解析に精通していませんが、似たような考え方に沿ったこの質問をご覧になることをお勧めします:フリーフォームテキスト用の一般的なアドレスパーサー。

レーベンシュタイン距離は便利ですが、住所をその部分に分離した後にのみ有効です。次のアドレスを検討してください。123 someawesome st.そして124 someawesome st.これらのアドレスは、全く異なる場所がありますが、彼らのレーベンシュタイン距離はこれもようなものに適用することができ1である8th st.9th st.一般的に同じウェブページ上に表示されていない同様の通りの名前が、それは前代未聞ではありません。学校のウェブページには、たとえば通りの向こう側にある図書館の住所が表示されたり、教会が数ブロック下にある場合があります。これは、レーベンシュタイン距離が簡単に使用できるデータは、2つのデータポイント間の距離(通りと都市間の距離など)だけであることを意味します。

異なるフィールドを分離する方法を理解する限り、アドレス自体を取得すれば非常に簡単です。ありがたいことに、ほとんどのアドレスは非常に特殊な形式で提供されており、RegExウィザードを少し使用することで、アドレスを異なるデータフィールドに分けることができるはずです。アドレスが適切にフォーマットされていなくても、まだいくつかの希望があります。アドレスは常に(ほぼ)大きさの順序に従います。提供される情報の量とその内容に応じて、住所はこのような線形グリッドのどこかにあるはずです。

StreetNumber < Street < City < State < Country

アドレスが1つのフィールドから隣接していないフィールドにスキップする場合はほとんどありません。ストリート、次に国、またはストリート番号、そして市を頻繁に見ることはありません。


2
番地が規則的ではなく、正規表現で確実に解析できないことを除きます。フリーテキストに埋め込まれているだけでは、確実に正確に識別することはできません。もちろん、探している場所が既にわかっている場合は、いくつかの異なる正規表現を記述して、さまざまな一般的な形式に一致させることができます。
役に立たない

@Uselessそれは本当です。理論的には実行可能ですが、それに必要な作業量を過小評価しました。特に、潜在的に優れたオプションが利用可能な場合。これを反映するために回答を修正しました。
Ucenna

1

文字列の類似性アルゴリズムについて尋ねますが、文字列はアドレスです。Google Place SearchなどのLocation APIに住所を送信し、それformatted_addressを比較のポイントとして使用します。それが最も正確なアプローチのようです。

APIを介して見つけることができないアドレス文字列の場合、類似性アルゴリズムにフォールバックできます。


1
+1アウトソースして、専門家の力を借りて作業を行えるようにします。いくつかのサービスプロバイダーが存在するため、Googleである必要はありません。アドレスマッチングがコアビジネスでない限り、これを行う時間を無駄にしないでください。
LoztInSpace

0

便利ですが、事前の回答のプリセットデータベースを必要とするクールなアルゴリズムの1つは、ライン編集距離と呼ばれます。

関数としての行編集距離は、「これら2つの単語の違い」を返すことができます。

「dogma」や「dog」などの単語の場合、値3(余分な3文字)が返されます。

または、「cat」と「hat」、1の値(1つの異なる文字)を取得します。

(ソース:https : //en.wikipedia.org/wiki/Edit_distance


2
OPが言及したLevensthteinに勝る利点は何ですか?
クリストフ

-1

確かに、いくつかの距離関数を使用することは良いアプローチのようです。しかし問題は、与えられたアドレスから最も近い文字列を見つけることであり、これは決して簡単ではありません。

ここでは、アルゴリズムの幅広いカテゴリについて説明しています。最近傍検索をご覧ください

コメントで述べたように、住所のコンポーネント(通りの名前、番号など)を分離する方法を見つけた場合、タスクがはるかに簡単になります。


-1

LongestCommonSubsequence(Apache commons-textから)は、アドレスを試すもう1つの方法です。「共通サブシーケンスの長さ/最大(アドレスの長さ)」の比として2の類似性を定義する場合、許容しきい値を適用できます。たとえば、0.8は一致/不一致を定義します。このようにして、「1 someawesome st。、anytown」や「1 someawesome street。、anytown」などのアドレスを照合できます。

超高速アルゴリズムではないため、比較を最小限に抑えるためにクイックフェールバックを適用することをお勧めします。たとえば、郵便番号が一致しない場合、または抽出された数字のみのシーケンスが異なる場合は、比較を避けます。

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