web-dev-qa-db-ja.com

どのファズ関数を使用して2つの文字列を比較するか

Pythonでfuzzywuzzyを学んでいます。

fuzz.ratiofuzz.partial_ratiofuzz.token_sort_ratio、およびfuzz.token_set_ratioの概念を理解しています。私の質問は、どの機能をいつ使用するかです。

  • 2つの文字列の長さを最初にチェックします。似ていない場合は、fuzz.partial_ratioを除外しますか?
  • 2つの文字列の長さが似ている場合、fuzz.token_sort_ratioを使用しますか?
  • 常にfuzz.token_set_ratioを使用する必要がありますか?

SeatGeekが使用する基準は誰でも知っていますか?

fuzzywuzzyを使用して住所を比較することを考えて、不動産Webサイトを構築しようとしています。

26
Pot

いい質問ですね。

私はSeatGeekのエンジニアなので、ここでお手伝いできると思います。素晴らしい ブログ投稿 があり、違いを非常によく説明していますが、さまざまなタイプをどのように使用するかについていくつかの洞察を要約して提供できます。

概要

ボンネットの下で、4つのメソッドはそれぞれ、両方の入力文字列のトークンの順序付け間の編集距離を計算します。これは、difflib.ratio関数を使用して行われます (will)

シーケンスの類似性の尺度を返します([0,1]に浮動)。

Tは両方のシーケンスの要素の総数であり、Mは一致の数です。これは2.0 * M/Tです。シーケンスが同一の場合は1、共通点がない場合は0であることに注意してください。

4つのfuzzywuzzyメソッドは、入力文字列のさまざまな組み合わせでdifflib.ratioを呼び出します。

fuzz.ratio

シンプル。 2つの入力文字列でdifflib.ratioを呼び出すだけです( code )。

fuzz.ratio("NEW YORK METS", "NEW YORK MEATS")
> 96

fuzz.partial_ratio

部分的な文字列の一致をより適切に説明する試み。大きい文字列のすべての長さnの部分文字列に対して最短文字列(長さn)を使用してratioを呼び出し、最高スコア( code )を返します。

ここでは、「ヤンキース」が最短の文字列(長さ7)であり、「ニューヨークヤンキース」の長さ7のすべてのサブストリングに対して「ヤンキース」との比率を実行します(「ヤンキース」に対するチェック、 ):

fuzz.ratio("YANKEES", "NEW YORK YANKEES")
> 60
fuzz.partial_ratio("YANKEES", "NEW YORK YANKEES")
> 100

fuzz.token_sort_ratio

同様の文字列を順不同で説明しようとします。各文字列のトークンをソートした後、両方の文字列でratioを呼び出します( code )。 fuzz.ratiofuzz.partial_ratioは両方とも失敗しますが、トークンを並べ替えると100%一致していることに注意してください。

fuzz.ratio("New York Mets vs Atlanta Braves", "Atlanta Braves vs New York Mets")
> 45
fuzz.partial_ratio("New York Mets vs Atlanta Braves", "Atlanta Braves vs New York Mets")
> 45
fuzz.token_sort_ratio("New York Mets vs Atlanta Braves", "Atlanta Braves vs New York Mets")
> 100

fuzz.token_set_ratio

文字列の違いを除外しようとします。 3つの特定の部分文字列セットの比率を呼び出し、最大値を返します( code ):

  1. 交差点のみと、ストリング1の残りの部分との交差点
  2. 交差点のみおよび文字列2の残りの部分との交差点
  3. 1の残りの部分と2つの残りの部分との交差点

2つの文字列の交差部分と残りの部分を分割することで、2つの文字列の類似性と相違点の両方を考慮していることに注意してください。

fuzz.ratio("mariners vs angels", "los angeles angels of anaheim at seattle mariners")
> 36
fuzz.partial_ratio("mariners vs angels", "los angeles angels of anaheim at seattle mariners")
> 61
fuzz.token_sort_ratio("mariners vs angels", "los angeles angels of anaheim at seattle mariners")
> 51
fuzz.token_set_ratio("mariners vs angels", "los angeles angels of anaheim at seattle mariners")
> 91

応用

これは魔法が起こるところです。 SeatGeekでは、基本的に各データポイント(会場、イベント名など)の各比率でベクトルスコアを作成し、それを使用して、問題のドメインに固有の類似性をプログラムで決定します。

そうは言っても、真実はFuzzyWuzzyのように聞こえないということは、ユースケースに役立ちます。 2つのアドレスが類似しているかどうかを判断するのは非常に困難です。 SeatGeek HQの2つの住所を考えてみましょう。「235 Park Ave Floor 12」と「235 Park Ave S. Floor 12」:

fuzz.ratio("235 Park Ave Floor 12", "235 Park Ave S. Floor 12")
> 93
fuzz.partial_ratio("235 Park Ave Floor 12", "235 Park Ave S. Floor 12")
> 85
fuzz.token_sort_ratio("235 Park Ave Floor 12", "235 Park Ave S. Floor 12")
> 95
fuzz.token_set_ratio("235 Park Ave Floor 12", "235 Park Ave S. Floor 12")
> 100

FuzzyWuzzyはこれらの文字列に高い一致スコアを与えますが、1つの住所はユニオンスクエア近くの実際のオフィスで、もう1つの住所はグランドセントラルの反対側にあります。

問題を解決するには、 Google Geocoding API を使用することをお勧めします。

55
Rick Hanlon II

2017年6月現在、fuzzywuzzyには他の比較関数も含まれています。受け入れられた答えから欠落しているものの概要は次のとおりです( ソースコード から取得)。

fuzz.partial_token_sort_ratio

token_sort_ratioと同じアルゴリズムですが、トークンのソート後にratioを適用する代わりに、partial_ratioを使用します。

fuzz.token_sort_ratio("New York Mets vs Braves", "Atlanta Braves vs New York Mets")
> 85
fuzz.partial_token_sort_ratio("New York Mets vs Braves", "Atlanta Braves vs New York Mets")
> 100    
fuzz.token_sort_ratio("React.js framework", "React.js")
> 62
fuzz.partial_token_sort_ratio("React.js framework", "React.js")
> 100

fuzz.partial_token_set_ratio

token_set_ratioと同じアルゴリズムですが、ratioをトークンのセットに適用する代わりに、partial_ratioを使用します。

fuzz.token_set_ratio("New York Mets vs Braves", "Atlanta vs New York Mets")
> 82
fuzz.partial_token_set_ratio("New York Mets vs Braves", "Atlanta vs New York Mets")
> 100    
fuzz.token_set_ratio("React.js framework", "Reactjs")
> 40
fuzz.partial_token_set_ratio("React.js framework", "Reactjs")
> 71   

fuzz.QRatio、fuzz.UQRatio

fuzz.ratioのラッパーで、検証とショートサーキットがあり、完全を期すためにここに含まれています。 UQRatioQRatioのUnicodeバージョンです。

fuzz.WRatio

重み付けの試行(名前は「重み付け比」を意味します)は、「最良の」スコアを計算するためのさまざまなアルゴリズムの結果です。ソースコードの説明:

1. Take the ratio of the two processed strings (fuzz.ratio)
2. Run checks to compare the length of the strings
    * If one of the strings is more than 1.5 times as long as the other
      use partial_ratio comparisons - scale partial results by 0.9
      (this makes sure only full results can return 100)
    * If one of the strings is over 8 times as long as the other
      instead scale by 0.6
3. Run the other ratio functions
    * if using partial ratio functions call partial_ratio,
      partial_token_sort_ratio and partial_token_set_ratio
      scale all of these by the ratio based on length
    * otherwise call token_sort_ratio and token_set_ratio
    * all token based comparisons are scaled by 0.95
      (on top of any partial scalars)
4. Take the highest value from these results
   round it and return it as an integer.

fuzz.UWRatio

WRatioのUnicodeバージョン。

9