クエリサービスでのファジーマッチ
Adobe Experience Platform データで「ファジー」一致を使用すると、同じ文字を持つ文字列を検索することなく、最も可能性の高い近似一致を返します。 これにより、データの検索がより柔軟になり、時間と労力を節約することでデータにアクセスしやすくなります。
検索文字列を一致させるために再フォーマットしようとするのではなく、ファジーマッチは2つのシーケンス間の類似度の比率を分析し、類似度の割合を返します。 FuzzyWuzzyはこのプロセスに推奨されます。関数は、regexやdifflibと比較して、より複雑な状況で文字列を一致させるのに適しています。
このユースケースで提供される例では、2つの異なる旅行代理店データセットをまたいで、ホテルの部屋の検索から類似した属性を照合することに焦点を当てています。 このドキュメントでは、大規模な個別データソースからの類似度によって文字列を一致させる方法を示します。 この例では、ファジーマッチは、LumaとAcmeの旅行代理店の部屋の特徴の検索結果を比較します。
はじめに getting-started
このプロセスの一環として、マシンラーニングモデルをトレーニングする必要があります。このドキュメントでは、1つ以上のマシンラーニング環境に関する実用的な知識を前提としています。
この例では、PythonとJupyter Notebook開発環境を使用しています。 利用可能なオプションは多数ありますが、Jupyter Notebookは計算要件が低いオープンソースのweb アプリケーションであるため、お勧めします。 これは公式Jupyter サイト からダウンロードできます。
開始する前に、必要なライブラリを読み込む必要があります。 FuzzyWuzzyは、difflib ライブラリの上に構築され、文字列の照合に使用されるオープンソースのPython ライブラリです。 Levenshtein Distanceを使用して、シーケンスとパターンの違いを計算します。 FuzzyWuzzyには次の要件があります。
- Python 2.4 (またはそれ以上)
- Python-Levenshtein
コマンドラインから、次のコマンドを使用してFuzzyWuzzyをインストールします。
pip install fuzzywuzzy
または、次のコマンドを使用してPython-Levenshteinもインストールします。
pip install fuzzywuzzy[speedup]
Fuzzywuzzyに関する詳細な技術情報については、公式ドキュメント を参照してください。
クエリサービスへの接続
接続資格情報を指定して、マシンラーニングモデルをQuery Serviceに接続する必要があります。 有効期限が切れている資格情報と期限切れでない資格情報の両方を指定できます。 必要な資格情報の取得方法について詳しくは、資格情報ガイド を参照してください。 Jupyter Notebookを使用している場合は、 クエリサービスへの接続方法に関する完全なガイドをお読みください。
また、線形代数を有効にするには、numpy パッケージをPython環境に必ず読み込んでください。
import numpy as np
次のコマンドは、Jupyter Notebookからクエリサービスに接続するために必要です。
import psycopg2
conn = psycopg2.connect('''
sslmode=require
host=<YOUR_ORGANIZATION_ID>
port=80
dbname=prod:all
user=<YOUR_ADOBE_ID_TO_CONNECT_TO_QUERY_SERVICE>
password=<YOUR_QUERY_SERVICE_PASSWORD>
''')
cur = conn.cursor()
これで、お使いのJupyter Notebook インスタンスがクエリサービスに接続されました。 接続が成功した場合、メッセージは表示されません。 接続が失敗した場合は、エラーが表示されます。
Luma データセットからのデータの描画 luma-dataset
分析用のデータは、次のコマンドを使用して最初のデータセットから取得されます。 簡潔に言うと、例は列の最初の10件の結果に限定されています。
cur.execute('''SELECT * FROM luma;
''')
luma = np.array([r[0] for r in cur])
luma[:10]
返された配列を表示するには、Outputを選択します。
| code language-console |
|---|
|
Acme データセットからのデータの描画 acme-dataset
次のコマンドを使用して、分析用のデータが2番目のデータセットから取得されるようになりました。 繰り返しますが、簡潔に言うと、この例は列の最初の10件の結果に限定されています。
cur.execute('''SELECT * FROM acme;
''')
acme = np.array([r[0] for r in cur])
acme[:10]
返された配列を表示するには、Outputを選択します。
| code language-console |
|---|
|
ファジースコアリング関数の作成 fuzzy-scoring
次に、FuzzyWuzzy ライブラリからfuzzを読み込み、文字列の部分比比較を実行する必要があります。 部分比関数を使用すると、部分文字列のマッチングを実行できます。 これは最短の文字列を取り出し、同じ長さの部分文字列と一致させます。 関数は、最大100%の類似度の割合を返します。 例えば、部分比関数は、次の文字列「Deluxe Room」、「1 King Bed」、「Deluxe King Room」を比較し、類似度スコアを69%として返します。
ホテル ルーム マッチのユースケースでは、次のコマンドを使用して行います。
from fuzzywuzzy import fuzz
def compute_match_score(x,y):
return fuzz.partial_ratio(x,y)
次に、SciPy ライブラリからcdistを読み込んで、2つの入力コレクション内の各ペア間の距離を計算します。 これにより、各旅行会社が提供するホテルの全てのペアのスコアを算出する。
from scipy.spatial.distance import cdist
pairwise_distance = cdist(luma.reshape((-1,1)),acme.reshape((-1,1)),compute_match_score)
ファジー結合スコアを使用して2つの列間にマッピングを作成します
列が距離に基づいてスコアリングされたので、ペアをインデックス化し、一定の割合を超えるスコアの一致のみを保持できます。 この例では、70%以上のスコアと一致するペアのみを保持します。
matched_pairs = []
for i,c1 in enumerate(luma):
idx = np.where(pairwise_distance[i,:] > 70)[0]
for j in idx:
matched_pairs.append((luma[i].replace("'","''"),acme[j].replace("'","''")))
結果は次のコマンドで表示できます。 簡潔に言うと、結果は10行に制限されています。
matched_pairs[:10]
Outputを選択して結果を表示します。
| code language-console |
|---|
|
次に、次のコマンドを使用してSQLを使用して結果を照合します。
matching_sql = ' OR '.join(["(e.luma = '{}' AND b.acme = '{}')".format(c1,c2) for c1,c2 in matched_pairs])
マッピングを適用して、クエリサービスでファジー結合を行う mappings-for-query-service
次に、SQLを使用して高スコアリングマッチングペアを結合し、新しいデータセットを作成します。
:
cur.execute('''
SELECT * FROM luma e
CROSS JOIN acme b
WHERE
{}
'''.format(matching_sql))
[r for r in cur]
Outputを選択して、この結合の結果を確認します。
| code language-console |
|---|
|
ファジーマッチの結果をExperience Platformに保存 save-to-platform
最後に、ファジィ一致の結果は、SQLを使用してAdobe Experience Platformで使用するデータセットとして保存できます。
cur.execute('''
Create table luma_acme_join
AS
(SELECT * FROM luma e
CROSS JOIN acme b
WHERE
{})
'''.format(matching_sql))