When we compare hotel room price between different websites, we must make sure we compare apples to apples
コンピュータサイエンスにおいて、ファジー文字列マッチングはパターンと(正確にではなく)ほぼ一致する文字列を見つけ出す技術である。 別の言葉で言うと、ファジー文字列マッチングは、ユーザーが単語のスペルを間違えたり、検索対象の単語の一部だけを入力したりしても、マッチを見つけることができる検索の一種です。
Fuzzy string search は、次のようなさまざまなアプリケーションで使用できます:
- A spell checker and spelling-error, typos corrector. 例えば、ユーザがGoogleに「ミシサガ」と入力すると、「Showing results for mississauga」と共にヒットしたリストが返されます。 つまり、ユーザー入力に追加文字や欠落文字、その他の種類のスペルミスが含まれていても、検索クエリは結果を返します。
- 重複レコードのチェックにソフトウェアを使用することができます。 たとえば、名前のスペルが異なる (Abigail Martin と Abigail Martinez など)、新しい住所、または誤って入力された電話番号などの理由で、顧客がデータベース内の異なる購入品目で複数回リストされている場合などです。 Expedia でさえ、100% 正しいとは言えません:
Source: Expedia この投稿では、ファジー文字列マッチングとは何か、その使用例と Python の Fuzzywuzzy ライブラリを使った例を説明します。
各ホテルは部屋の名前に独自の名称を持っていますが、同じシナリオは Online Travel Agency (OTA) にも当てはまります。 たとえば、同じホテルのある部屋を Expedia は「Studio, 1 King Bed with Sofa bed, Corner」と呼び、Booking.com は単に「Corner King Studio」として部屋を表示することが安全であると判断します。
ここに問題はありませんが、OTA 間の宿泊料金を比較したい場合、またはある OTA が他の OTA が料金同等協定に従っているかどうかを確認したい場合には混乱につながることがあります。 別の言葉で言うと、価格を比較できるようにするには、リンゴとリンゴを比較していることを確認する必要があります。
価格比較サイトやアプリにとって最も一貫してイライラする問題の1つは、2つのアイテム(またはホテルの部屋)が自動的に同じものの価格かどうかを判断しようとすることです。
Fuzzywuzzy は、レーベンシュタイン距離を使用して、使いやすいパッケージでシーケンス間の差異を計算する Python ライブラリです。
デモンストレーションとして、私自身のデータセットを作成します。つまり、同じホテル施設について、Expedia から部屋のタイプ、たとえば「スイート、1 キング ベッド (応接間)」を取って、それを Booking.com で部屋のタイプ、「キング 応接間」に合わせます。 少し経験を積めば、ほとんどの人がこの2つが同じものだとわかるはずです。 この方法論に従って、私はGithubにある100以上の部屋タイプのペアを含む小さなデータセットを作成しました。
import pandas as pddf = pd.read_csv('room_type.csv')
df.head(10)Figure 1 このデータセットが自分で作ったので非常にきれいな状態です。
Fuzzywuzzyで2つの文字列を比較する方法はいくつかありますが、一つずつ試してみましょう。
-
ratio
, 文字列全体の類似度を順に比較します。
from fuzzywuzzy import fuzz
fuzz.ratio('Deluxe Room, 1 King Bed', 'Deluxe King Room')これは、「デラックスルーム、キングベッド1台」と「デラックスキングルーム」のペアが約62%同じであることを示しています。
fuzz.ratio('Traditional Double Room, 2 Double Beds', 'Double Room with Two Double Beds')
「トラディショナルダブルルーム、ダブルベッド2台」と「ダブルルーム、ダブルベッド2台」のペアは約69%同じであることを示しています。
fuzz.ratio('Room, 2 Double Beds (19th to 25th Floors)', 'Two Double Beds - Location Room (19th to 25th Floors)')
「ルーム、2ダブルベッド(19~25階)」と「2ダブルベッド-ロケーションルーム(19~25階)」は約74%同じです。
-
partial_ratio
, 部分文字列の類似度を比較します。
我々はまだ同じデータペアを使用しています。
fuzz.partial_ratio('Deluxe Room, 1 King Bed', 'Deluxe King Room')
fuzz.partial_ratio('Traditional Double Room, 2 Double Beds', 'Double Room with Two Double Beds')
fuzz.partial_ratio('Room, 2 Double Beds (19th to 25th Floors)', 'Two Double Beds - Location Room (19th to 25th Floors)')
私のデータセットでは、部分文字列を比較しても全体として良い結果は出ません。
-
token_sort_ratio
, 語順を無視。
fuzz.token_sort_ratio('Deluxe Room, 1 King Bed', 'Deluxe King Room')
fuzz.token_sort_ratio('Traditional Double Room, 2 Double Beds', 'Double Room with Two Double Beds')
fuzz.token_sort_ratio('Room, 2 Double Beds (19th to 25th Floors)', 'Two Double Beds - Location Room (19th to 25th Floors)')
これまでのベスト。
-
token_set_ratio
, 重複する単語を無視。
fuzz.token_set_ratio('Deluxe Room, 1 King Bed', 'Deluxe King Room')
fuzz.token_set_ratio('Traditional Double Room, 2 Double Beds', 'Double Room with Two Double Beds')
fuzz.token_set_ratio('Room, 2 Double Beds (19th to 25th Floors)', 'Two Double Beds - Location Room (19th to 25th Floors)')
私のデータには
token_set_ratio
が一番合っているようです。 この発見により、私はデータセット全体にtoken_set_ratio
を適用することにしました。。
-