0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

【AWS Deep Cutsシリーズ】AWS Entity Resolutionって知ってる?データ統合で困りがちな、表記ゆれ重複レコードを効率的に特定しよう!

0
Posted at

AWS Deep Cutsは、AWS の中でも特に最新のサービスやニッチな機能など、多くの人が知らない「隠れた名曲 = Deep Cuts」を深くまで掘り下げる技術シリーズです。

このようなサービスは情報が少ないため、一部の有識者以外は触り方すら分からず、気軽にキャッチアップできないのが実情です。

そこでAWS Deep Cuts シリーズは「どんな人でも実際に触りながら理解できる」ことを目指し、できるだけ噛み砕いたサービス解説と簡単なハンズオンを提供します

ハンズオン教材はGitHubでも公開しています。
https://github.com/Kenta-Matsuda/AWS-Deep-Cuts

🔰 はじめに

AWS Entity Resolution (AWS ER) はまだ日本語の記事が少なく、知らないエンジニアも多いかもしれません。この記事では、サービスの概要や特徴をわかりやすく解説し、実際に触ってみるハンズオンも紹介します。データマッチングの課題に直面している方や、Customer 360やデータクレンジングに興味がある方は必見です!

1️⃣ Entity Resolutionとは?

Entity Resolution (ER) とは、異なるデータセットに散在するレコードの中から同一人物や同一企業などを特定して統合する技術です。データは重複や表記ゆれを含むことが多く、手動の照合作業は大変な工数がかかります。ER を活用すると、データ統合・分析・パーソナライゼーションの精度が向上し、ビジネス上の意思決定を支援します1

2️⃣ AWS Entity Resolutionとは?

AWS Entity Resolutionは、こうしたエンティティマッチングを完全マネージドで実行できるサービスです。特徴として、以下のような点が挙げられます。

  • プリセット済みアルゴリズムとインタラクティブな設定
    AWSが用意したマッチングアルゴリズムを選択でき、GUI上でルールを細かく調整できます2
  • ルールベース/機械学習ベース/外部データプロバイダー連携
    メールアドレスや電話番号など特定フィールドに対する明示的なルール、AWSが提供する機械学習モデル、さらにLiveRampやUID2などのIDサービスと連携したマッチングを選べます3
  • ファジーマッチング
    レーベンシュタイン距離やCosine類似度、Soundex などのアルゴリズムを利用し、スペルミスや文字順の違いでも高精度にマッチさせます3
  • ニアリアルタイム照合 API
    GetMatchID API により受信したレコードをハッシュ化し、既存のマッチIDを即座に返せます3。リアルタイムなパーソナライズや不正検知に利用できます。
  • セキュリティと地域性
    データはデフォルトでAWS管理のキーで暗号化され、必要に応じてKMSキーを指定できます。VPC内からPrivateLinkで安全に呼び出すことも可能です3
  • 料金
    ルール/MLマッチングは1,000レコードあたり約0.25 USD、外部プロバイダー連携は0.10 USDから課金されます3

このように、AWS ER はデータ統合に必要な複雑な処理をマネージド化してくれる頼もしいサービスです。実際の使い方を次章で見ていきましょう!

3️⃣ 主なユースケース

AWS ER はさまざまな業界や場面で利用されています4

  • Customer 360 / マーケティング
    CRMや購買履歴、Web行動など複数のチャネルで顧客情報を統合し、統一した顧客ビューを構築します。

Customer 360とは
企業が保有する顧客のあらゆるデータ(属性、購入履歴、問い合わせ状況、Web上の行動など)を統合し、1人の顧客の全体像を多角的(=360度)に把握する概念や仕組み

  • 不正検知
    金融機関では、複数口座にまたがる取引を結び付けて不審なパターンを検出します。
  • ヘルスケア
    病院や診療所に分散している患者情報を統合し、治療の一貫性を確保します。
  • 小売 / EC
    購買履歴や閲覧行動をまとめ、レコメンドやターゲティング精度を高めます。
  • データクレンジング・重複排除
    機械学習モデル作成やBI分析の前処理として、重複データを除去する。

4️⃣ ハンズオン:AWS Entity Resolutionを触ってみよう

ここでは、実際にAWS Entity Resolutionで「顧客データの名寄せ」をやってみましょう。

このハンズオンでは、2つのCSVに分かれている顧客データをAWS Entity Resolutionで照合し、同一顧客に同じMatch IDを付与することを行います。ただし今回は、ワークフローを1つだけ作るのではなく、同じ2つのCSVを使って、目的別に複数パターンのマッチングワークフローを試す構成にします。

具体的には、以下の5パターンを順番に試します。

Pattern 1: Raw Exact Matching
  生データのまま、email / phone の完全一致だけで名寄せする

Pattern 2: Cleansed Exact Matching
  クレンジング済みキー列を使い、確実な一致だけを拾う

Pattern 3: Conservative Fuzzy Matching
  表記ゆれを少し許容するが、誤統合しそうなものは拾わない

Pattern 4: Review Candidate Matching
  あえて緩い条件で「人手確認候補」まで拾う

Pattern 5: GetMatchId API
  バッチ実行後、新規レコードをリアルタイム照合する

AWS Entity Resolutionは、AWS Glueのテーブルを入力として読み込み、マッチングワークフローでレコードを比較し、マッチしたレコード集合にMatch IDを割り当てます。AWS公式ドキュメントでも、入力データはAWS Glueから読み込まれ、スキーママッピングを定義したうえでマッチングワークフローに利用すると説明されています。5

AWS Entity Resolutionでは、Schema mappingを事前に作成し、AWS Glueテーブルと対応するSchema mappingを入力にしてMatching workflowを作成します。Simple rule typeでは最大15個のルール、Advanced rule typeでは最大25個のルールを作成できます。AdvancedではCosine、Levenshtein、Soundexなどのファジー関数を使えますが、ファジー関数はExact系の条件とANDで組み合わせる必要があります。([AWS ドキュメント][5])

今回作成する主な設定は以下に固定します。

リージョン: ap-northeast-1
マッチング方式: Rule-based matching
ルールタイプ: Simple(Pattern 1, 2) / Advanced(Pattern 3, 4)
処理方式: Manual
入力データ: S3上のCSV 2ファイル
Glueデータベース: 1個
Glueテーブル: 2個
Schema mapping: 2個
Matching workflow: 4個(Pattern 1〜4)

Simpleは完全一致ベースで、リアルタイムワークフローにも対応します。表記ゆれを許容するファジーマッチングを使いたい場合は、Advanced rule typeが必要です。本ハンズオンでは、両方を体験するためにSimpleとAdvancedの両方を使います。([AWS ドキュメント][2])


このハンズオンで作るもの

今回のハンズオンで作成するリソース一覧は以下の通りです。

S3 bucket x 1: 
    Glue テーブルを作成するための元データや、AWS Entity Resolution の実行結果を格納します

AWS Glue: 
    AWS Glue database x 1:
    AWS Glue tables x 2:
        データ統合に利用する2つのテーブルを作成します

AWS Entity Resolution:
    AWS Entity Resolution schema mappings x 2:
    AWS Entity Resolution matching workflow x 4: 
        各テーブルのスキーママッピングと、目的別の4つの突合結果を作成します

アーキテクチャ図にすると以下のようになります。
名称未設定ファイル.jpg


1. 前提環境

  • ローカルにAWS CLIが導入されていること
  • AWS CLIに認証情報が設定されていること

2. 使用する環境

以下をそのまま実行します。

export AWS_REGION=ap-northeast-1
export AWS_ACCOUNT_ID=$(aws sts get-caller-identity --query Account --output text)
export RUN_ID=er$(date +%Y%m%d%H%M%S)

export BUCKET=aws-er-handson-${AWS_ACCOUNT_ID}-${RUN_ID}
export GLUE_DATABASE=aws_er_handson_${RUN_ID}

export SCHEMA_PRIMARY=customers_primary
export SCHEMA_SECONDARY=customers_secondary

export WORKFLOW_01=er-handson-01-raw-exact
export WORKFLOW_02=er-handson-02-cleansed-exact
export WORKFLOW_03=er-handson-03-conservative-fuzzy
export WORKFLOW_04=er-handson-04-review-candidates

echo "AWS_REGION=ap-northeast-1"
echo "AWS_ACCOUNT_ID=${AWS_ACCOUNT_ID}"
echo "RUN_ID=${RUN_ID}"
echo "BUCKET=${BUCKET}"
echo "GLUE_DATABASE=${GLUE_DATABASE}"
echo "SCHEMA_PRIMARY=${SCHEMA_PRIMARY}"
echo "SCHEMA_SECONDARY=${SCHEMA_SECONDARY}"
echo "WORKFLOW_01=${WORKFLOW_01}"
echo "WORKFLOW_02=${WORKFLOW_02}"
echo "WORKFLOW_03=${WORKFLOW_03}"
echo "WORKFLOW_04=${WORKFLOW_04}"

以降、コンソールで名前を入力する場面では、ここで表示された値をそのまま使います。


3. サンプルCSVを作成する

3.1 registration_data.csv を作成する

このCSVは、CRMや会員登録データを想定しています。

source_record_id,full_name,email,phone,address,city,email_key,phone_key,name_key,address_key,city_key
A001,Yamada Taro,taro.yamada@example.com,08011112222,1-1-1 Shibuya,Tokyo,taro.yamada@example.com,08011112222,yamada taro,1-1-1-shibuya,tokyo
A002,Sato Hanako,hanako.sato@example.com,09022223333,2-2-2 Umeda,Osaka,hanako.sato@example.com,09022223333,sato hanako,2-2-2-umeda,osaka
A003,Suzuki Ichiro,ichiro.suzuki@example.com,07033334444,3-3-3 Sakae,Nagoya,ichiro.suzuki@example.com,07033334444,suzuki ichiro,3-3-3-sakae,nagoya
A004,Tanaka Jiro,jiro.tanaka@example.com,08044445555,4-4-4 Tenjin,Fukuoka,jiro.tanaka@example.com,08044445555,tanaka jiro,4-4-4-tenjin,fukuoka
A005,YAMADA   TARO,Taro.Yamada@Example.com,080-1111-2222,1-1-1 Shibuya,Tokyo,taro.yamada@example.com,08011112222,yamada taro,1-1-1-shibuya,tokyo
A006,Sato Hana,h.sato@example.com,,2-2-2 Umeda,Osaka,h.sato@example.com,,sato hana,2-2-2-umeda,osaka
A007,山田 太郎,taro_yamada@example.com,08011112222,1-1-1 渋谷,東京,taro_yamada@example.com,08011112222,yamada taro,1-1-1-shibuya,tokyo
A008,No Match A,no.match.a@example.com,08055556666,5-5-5 Susukino,Sapporo,no.match.a@example.com,08055556666,no match a,5-5-5-susukino,sapporo

3.2 lead_list.csv を作成する

このCSVは、マーケティングにおける見込み顧客のリストを想定しています。

source_record_id,full_name,email,phone,address,city,email_key,phone_key,name_key,address_key,city_key
B001,Taro Yamada,taro.yamada@example.com,08099990000,1-1-1 Shibuya,Tokyo,taro.yamada@example.com,08099990000,yamada taro,1-1-1-shibuya,tokyo
B002,Hanako Sato,h.sato@example.com,09022223333,2-2-2 Umeda,Osaka,h.sato@example.com,09022223333,sato hanako,2-2-2-umeda,osaka
B003,Ichiro Suzuki,ichiro.suzuki@example.com,07033334444,3-3-3 Sakae,Nagoya,ichiro.suzuki@example.com,07033334444,suzuki ichiro,3-3-3-sakae,nagoya
B004,Jiro Tanaka,j.tanaka@example.com,08044445555,4-4-4 Tenjin,Fukuoka,j.tanaka@example.com,08044445555,tanaka jiro,4-4-4-tenjin,fukuoka
B005,No Match B,no.match.b@example.com,08077778888,5-5-5 Gion,Kyoto,no.match.b@example.com,08077778888,no match b,5-5-5-gion,kyoto
B006,Taro Yamada,taro.yamada+promo@example.com,08011112222,1-1-1 Shibuya,Tokyo,taro.yamada@example.com,08011112222,yamada taro,1-1-1-shibuya,tokyo
B007,Sato Hanoko,hanako.sato@example.com,090-2222-3333,2-2-2 Umeda,Osaka,hanako.sato@example.com,09022223333,sato hanoko,2-2-2-umeda,osaka
B008,Yamada T.,taro@example.com,08011112223,1-1-1 Shibuya,Tokyo,taro@example.com,08011112223,yamada t,1-1-1-shibuya,tokyo
B009,山田太郎,taro-yamada@example.com,08011112222,1-1-1 渋谷,東京,taro-yamada@example.com,08011112222,yamada taro,1-1-1-shibuya,tokyo
B010,Suzuki Ichirou,ichiro.suzuki@example.com,07033334444,3-3-3 Sakae,Nagoya,ichiro.suzuki@example.com,07033334444,suzuki ichirou,3-3-3-sakae,nagoya

3.3 期待するマッチング結果

このデータでは、以下のマッチを期待します。

期待Match ID レコードID 顧客像
M001 A001, A005, A007, B001, B006, B009 山田太郎 / Taro Yamada
M002 A002, A006, B002, B007 佐藤花子 / Hanako Sato
M003 A003, B003, B010 鈴木一郎 / Ichiro Suzuki
M004 A004, B004 田中次郎 / Jiro Tanaka
M005 A008 No Match A
M006 B005 No Match B
要レビュー B008 山田太郎の可能性はあるが自動統合しない

4. S3バケットを作成してCSVをアップロードする

以降のコマンドでは、{}で囲まれた部分を自環境用に修正してください。

4.1 S3バケットを作成する

{YYYYMMDD}を変更してください。

# 東京リージョンに、「aws-deepcuts-er-ACCOUNT_ID-YYYYMMDD」というS3を作成
aws s3 mb s3://aws-deepcuts-er-$(aws sts get-caller-identity --query Account --output text)-{YYYYMMDD} --region ap-northeast-1

4.2 バケット暗号化を有効化する

{YYYYMMDD}を変更してください。

aws s3api put-bucket-encryption \
  --bucket aws-deepcuts-er-$(aws sts get-caller-identity --query Account --output text)-{YYYYMMDD} \
  --server-side-encryption-configuration '{
    "Rules": [
      {
        "ApplyServerSideEncryptionByDefault": {
          "SSEAlgorithm": "AES256"
        }
      }
    ]
  }' \
  --region ap-northeast-1

4.3 CSVをアップロードする

{YYYYMMDD}を変更してください。

aws s3 cp registration_data.csv s3://aws-deepcuts-er-$(aws sts get-caller-identity --query Account --output text)-{YYYYMMDD}/input/registration_data/registration_data.csv --region ap-northeast-1
aws s3 cp lead_list.csv s3://aws-deepcuts-er-$(aws sts get-caller-identity --query Account --output text)-{YYYYMMDD}/input/lead_list/lead_list.csv --region ap-northeast-1

4.4 アップロード結果を確認する

{YYYYMMDD}を変更してください。

aws s3 ls s3://aws-deepcuts-er-$(aws sts get-caller-identity --query Account --output text)-{YYYYMMDD}/input/ --region ap-northeast-1 --recursive

以下のように2ファイルが表示されれば成功です。

registration_data.csv
lead_list.csv

5. AWS Glueデータベースを作成する

5.1 db.json を作成する

まず、Glueデータベースの定義ファイルを db.json として作成します。

{
  "Name": "aws-deepcuts-er-glue-db"
}

なお、db.json の内容は 5.2 Glue データベースを作成する でコマンドを実行する際に、直接引数として渡しても構いません。ただし実行環境によってJSONのエスケープ処理が異なるため、ここではファイル形式でコマンドに渡す方法を採用しています。

5.2 Glue データベースを作成する

以下のコマンドで Glue データベースを作成します。

aws glue create-database --database-input file://db.json --region ap-northeast-1

Glue データベースが作成できたことを確認します。

aws glue get-databases --region ap-northeast-1

以下のように、 aws-deepcuts-er-glue-db のエントリが表示されれば成功です。

{
    "DatabaseList": [
        {
            "Name": "aws-deepcuts-er-glue-db",
            "CreateTime": "2026-05-29T03:15:43+09:00",
            "CreateTableDefaultPermissions": [
                {
                    "Principal": {
                        "DataLakePrincipalIdentifier": "IAM_ALLOWED_PRINCIPALS"
                    },
                    "Permissions": [
                        "ALL"
                    ]
                }
            ],
            "CatalogId": "663858476530"
        }
    ]
}

6. AWS Glueテーブルを作成する

AWS Entity Resolutionは、S3上のファイルを直接指定するのではなく、AWS Glueテーブルを入力として使います。AWS公式ドキュメントでも、AWS Entity ResolutionはAWS Glueからデータを読み取り、各行をレコードとして処理すると説明されています。([AWS ドキュメント][1])

6.1 registration_data 用のGlueテーブル定義を作成する

以下の内容で registration_data_table.json を作成してください。ただし StorageDescriptor.Locationを変更してください。

{
  "Name": "registration_data",
  "TableType": "EXTERNAL_TABLE",
  "Parameters": {
    "classification": "csv",
    "skip.header.line.count": "1"
  },
  "StorageDescriptor": {
    "Location": "s3://aws-deepcuts-er-{ACCOUNT_ID}-{YYYYMMDD}/input/registration_data/",
    "InputFormat": "org.apache.hadoop.mapred.TextInputFormat",
    "OutputFormat": "org.apache.hadoop.hive.ql.io.HiveIgnoreKeyTextOutputFormat",
    "SerdeInfo": {
      "SerializationLibrary": "org.apache.hadoop.hive.serde2.OpenCSVSerde",
      "Parameters": {
        "separatorChar": ",",
        "quoteChar": "\""
      }
    },
    "Columns": [
      { "Name": "source_record_id", "Type": "string" },
      { "Name": "full_name", "Type": "string" },
      { "Name": "email", "Type": "string" },
      { "Name": "phone", "Type": "string" },
      { "Name": "address", "Type": "string" },
      { "Name": "city", "Type": "string" },
      { "Name": "email_key", "Type": "string" },
      { "Name": "phone_key", "Type": "string" },
      { "Name": "name_key", "Type": "string" },
      { "Name": "address_key", "Type": "string" },
      { "Name": "city_key", "Type": "string" }
    ]
  }
}

6.2 lead_list 用のGlueテーブル定義を作成する

以下の内容で lead_list_table.json を作成してください。ただし StorageDescriptor.Locationを変更してください。

{
  "Name": "lead_list",
  "TableType": "EXTERNAL_TABLE",
  "Parameters": {
    "classification": "csv",
    "skip.header.line.count": "1"
  },
  "StorageDescriptor": {
    "Location": "s3://aws-deepcuts-er-{ACCOUNT_ID}-{YYYYMMDD}/input/lead_list/",
    "InputFormat": "org.apache.hadoop.mapred.TextInputFormat",
    "OutputFormat": "org.apache.hadoop.hive.ql.io.HiveIgnoreKeyTextOutputFormat",
    "SerdeInfo": {
      "SerializationLibrary": "org.apache.hadoop.hive.serde2.OpenCSVSerde",
      "Parameters": {
        "separatorChar": ",",
        "quoteChar": "\""
      }
    },
    "Columns": [
      { "Name": "source_record_id", "Type": "string" },
      { "Name": "full_name", "Type": "string" },
      { "Name": "email", "Type": "string" },
      { "Name": "phone", "Type": "string" },
      { "Name": "address", "Type": "string" },
      { "Name": "city", "Type": "string" },
      { "Name": "email_key", "Type": "string" },
      { "Name": "phone_key", "Type": "string" },
      { "Name": "name_key", "Type": "string" },
      { "Name": "address_key", "Type": "string" },
      { "Name": "city_key", "Type": "string" }
    ]
  }
}

6.3 Glueテーブルを作成する

aws glue create-table --database-name aws-deepcuts-er-glue-db --table-input file://registration_data_table.json --region ap-northeast-1
aws glue create-table --database-name aws-deepcuts-er-glue-db --table-input file://lead_list_table.json --region ap-northeast-1

6.4 Glueテーブルを確認する

aws glue get-tables --database-name aws-deepcuts-er-glue-db --region ap-northeast-1 --query 'TableList[].Name' --output table

以下のように表示されれば成功です。

-----------------------
|      GetTables      |
+---------------------+
|  lead_list          |
|  registration_data  |
+---------------------+

7. Schema mappingを作成する

AWS Entity Resolutionでは、入力テーブルのどの列を「名前」「メールアドレス」「電話番号」などとして扱うかをSchema mappingで定義します。Schema mappingではUnique ID列が必須で、Unique IDは単一テーブル内で一意である必要があります。今回はsource_record_idをUnique IDにします。AWS公式ドキュメントでは、Unique IDが未指定、一意でない、または不適切な場合、マッチングワークフロー実行時にレコードが拒否されると説明されています。([AWS ドキュメント][3])

7.1 生データ列とクレンジング済みキー列

今回のCSVは、生データ列に加えて、事前にクレンジングした「キー列」を持っています。

元列 クレンジング済み列
email email_key Taro.Yamada@Example.comtaro.yamada@example.com
phone phone_key 080-1111-222208011112222
full_name name_key YAMADA TAROyamada taro
address address_key 1-1-1 渋谷 / 1-1-1 Shibuya1-1-1-shibuya
city city_key 東京 / Tokyotokyo

email_keyphone_keyname_keyaddress_keycity_keyは、Glue ETLやPythonなどで事前に作ったクレンジング済み列を想定しています。AWS Entity Resolution自体にもNormalize dataがありますが、メールの+promo除去、漢字/ローマ字変換、住所表記の統一まで万能にやってくれる前提にはしないほうが安全です。実務では、AWS Entity Resolutionの前にGlueなどで照合用キーを作る設計にしておくと、期待結果が安定します。

7.2 AWS Entity Resolutionコンソールを開く

ブラウザで以下を開きます。

https://console.aws.amazon.com/entityresolution/

右上のリージョンが東京リージョン(ap-northeast-1)になっていることを確認します。

7.3 Schema mappingの共通設定

customers_primary(registration_data用)とcustomers_secondary(lead_list用)の2つを作成します。両方とも、Input fieldは以下のように設定します。

Input field Attribute type Match key name 用途
source_record_id Unique ID - レコード識別子
full_name Full name name_raw 生データ比較用
email Email address email_raw 生データ比較用
phone Phone number phone_raw 生データ比較用
email_key Email address email_key クレンジング済みメール
phone_key Phone number phone_key クレンジング済み電話番号
name_key Full name name_key クレンジング済み氏名
address_key Full address address_key クレンジング済み住所
city_key City city_key クレンジング済み都市
address Pass through - 結果確認用
city Pass through - 結果確認用

Advanced rule type(Pattern 3, 4)でも使えるよう、各入力フィールドには一意のMatch key nameを割り当てます。Advanced rule typeでは、グループ化したフィールドを除き、同じMatch keyを複数フィールドで使えないためです。([AWS ドキュメント][7])

7.4 customers_primary(registration_data)を作成する

左メニューで Data preparation > Schema mappings を選び、右上の Create schema mapping を押します。

Step 1: Specify schema details で以下を入力します。

項目 入力値
Schema mapping name customers_primary
Description Schema mapping for registration_data
Creation method Import from AWS Glue
AWS Region ap-northeast-1
AWS Glue database aws-deepcuts-er-glue-db
AWS Glue table registration_data
Unique ID source_record_id

Input fields で、Matching fieldsとして full_name / email / phone / email_key / phone_key / name_key / address_key / city_key を選びます。Add columns for pass through をチェックし、Pass throughとして address / city を追加します。

Next を押し、Step 2: Map input fields で前掲の「Schema mappingの共通設定」表のとおりにAttribute typeとMatch key nameを設定します。Hashedはすべてチェックしません。

Step 3: Group data では何も変更せず NextStep 4: Review and create で内容を確認して Create schema mapping を押します。

7.5 customers_secondary(lead_list)を作成する

再び Create schema mapping を押し、Step 1 で以下を入力します。

項目 入力値
Schema mapping name customers_secondary
Description Schema mapping for lead_list
Creation method Import from AWS Glue
AWS Region ap-northeast-1
AWS Glue database aws-deepcuts-er-glue-db
AWS Glue table lead_list
Unique ID source_record_id

以降のInput fields / Map input fields / Group dataの設定は、customers_primaryと同じです。Step 4 まで進めて Create schema mapping を押します。


8. 統合したい顧客(期待結果)を整理する

各パターンの結果を比較できるよう、最終的な業務上の期待結果を整理しておきます。

期待グループ レコード 顧客像
M001 A001, A005, A007, B001, B006, B009 山田太郎 / Taro Yamada
M002 A002, A006, B002, B007 佐藤花子 / Hanako Sato
M003 A003, B003, B010 鈴木一郎 / Ichiro Suzuki
M004 A004, B004 田中次郎 / Jiro Tanaka
M005 A008 単独顧客
M006 B005 単独顧客
Review B008 山田太郎っぽいが、自動統合は危険

B008はこのハンズオンの重要な教材です。

B008,Yamada T.,taro@example.com,08011112223,1-1-1 Shibuya,Tokyo

住所と都市は山田太郎系に近いですが、メールは弱く、電話番号も1桁違います。そのため、自動統合ではなくレビュー候補として扱うのが安全です。各パターンでこのB008がどう扱われるかに注目してください。


9. Pattern 1: Raw Exact Matching

9.1 目的

まずは、何もクレンジングしないとどこまでマッチするかを見るパターンです。「AWS Entity Resolutionを使えば何でも自動で名寄せできる」という誤解を防ぐための実験です。

9.2 ワークフロー設定

AWS Entity Resolutionコンソールの左メニューで Workflows > Matching を選び、Create matching workflow を押します。Step 1 のData inputには、registration_datacustomers_primary)とlead_listcustomers_secondary)の2つを設定します。以降の主な設定値は以下です。

項目 設定値
Workflow name er-handson-01-raw-exact
Matching method Rule-based matching
Rule type Simple
Processing cadence Manual
Normalize data Off(推奨)
Output s3://<BUCKET>/output/01-raw-exact/

Simple rule typeでは、Matching rulesでRule nameとMatch keysを設定します。([AWS ドキュメント][5])

9.3 Matching rules

優先度 Rule name Match keys Comparison type
1 raw_exact_email email_raw Single input field
2 raw_exact_phone phone_raw Single input field

設定後、Create and run でワークフローを作成・実行します。

9.4 期待結果

グループ レコード 理由
R001 A001, B001, B006, A007, B009 A001-B001はemail一致。A001/A007/B006/B009はphone一致
R002 A002, A006, B002, B007 A002-B002はphone一致。A006-B002はemail一致。A002-B007はemail一致
R003 A003, B003, B010 email/phone一致
R004 A004, B004 phone一致
R005 A005 単独。email大小文字、phoneハイフンにより漏れる想定
R006 A008 単独
R007 B005 単独
R008 B008 単独

このパターンで見せたいのは、表記ゆれやクレンジング不足があると、本来同一人物でも漏れるということです。特にA005は山田太郎ですが、以下のように表記が違うためRaw Exactでは漏れます。

A001: taro.yamada@example.com, 08011112222
A005: Taro.Yamada@Example.com, 080-1111-2222

10. Pattern 2: Cleansed Exact Matching

10.1 目的

次に、クレンジング済みキー列を使うと、確実な一致を安定して拾えることを確認します。実務で最も使いやすい基本形です。

10.2 ワークフロー設定

項目 設定値
Workflow name er-handson-02-cleansed-exact
Matching method Rule-based matching
Rule type Simple
Processing cadence Manual
Normalize data OffまたはOn(キー列を使うためどちらでもよい)
Output s3://<BUCKET>/output/02-cleansed-exact/

10.3 Matching rules

優先度 Rule name Match keys Comparison type
1 cleansed_exact_email email_key Single input field
2 cleansed_exact_phone phone_key Single input field

10.4 期待結果

グループ レコード 理由
M001 A001, A005, A007, B001, B006, B009 email_keyまたはphone_keyが一致
M002 A002, A006, B002, B007 email/phoneのクレンジング済みキーを介して一致
M003 A003, B003, B010 email/phone一致
M004 A004, B004 phone一致
M005 A008 単独
M006 B005 単独
M007 B008 単独

この結果が、本ハンズオンの基本的な正解です。B008はまだ単独で、これは意図通りです。

B008:
  name_key    = yamada t
  email_key   = taro@example.com
  phone_key   = 08011112223
  address_key = 1-1-1-shibuya
  city_key    = tokyo

住所と都市は近いですが、email/phoneが確定的に一致しないため、自動統合しません。


11. Pattern 3: Conservative Fuzzy Matching

11.1 目的

名前や住所の表記ゆれを少し許容します。ただし、誤統合を避けるため、ファジー条件だけではマッチさせません。AWS Entity ResolutionのAdvanced rule typeでは、Levenshtein、Cosine、Soundexなどの関数を使えますが、ファジー関数はExactまたはExactManyToManyとANDで組み合わせる必要があります。([AWS ドキュメント][7])

11.2 ワークフロー設定

項目 設定値
Workflow name er-handson-03-conservative-fuzzy
Matching method Rule-based matching
Rule type Advanced
Processing cadence Manual
Normalize data OffまたはOn
Output s3://<BUCKET>/output/03-conservative-fuzzy/

11.3 Matching rules

優先度 Rule name Rule condition 狙い
1 exact_email_key Exact(email_key, EmptyValues=Ignore) メール完全一致
2 exact_phone_city Exact(phone_key, EmptyValues=Ignore) AND Exact(city_key, EmptyValues=Ignore) 電話番号一致+都市一致
3 same_address_similar_name Exact(address_key, EmptyValues=Ignore) AND Exact(city_key, EmptyValues=Ignore) AND Levenshtein(name_key, 2) 同一住所・同一都市で名前が少し違う
4 same_phone_similar_name Exact(phone_key, EmptyValues=Ignore) AND Levenshtein(name_key, 2) 電話番号一致で名前のtypoを許容

11.4 期待結果

グループ レコード 理由
M001 A001, A005, A007, B001, B006, B009 email/phone一致。名前・住所の揺れも補助
M002 A002, A006, B002, B007 email/phone一致に加え、Hanako/Hana/Hanokoの揺れを吸収
M003 A003, B003, B010 Ichiro/Ichirouの表記ゆれを吸収
M004 A004, B004 phone一致
M005 A008 単独
M006 B005 単独
M007 B008 単独

Pattern 3でも、B008は単独にします。Yamada T.Yamada Taroは近いものの、メール不一致・電話番号1桁違いです。住所一致だけで自動統合すると危険だからです。つまりPattern 3は、顧客360の本番統合に近い、保守的な自動マッチングです。


12. Pattern 4: Review Candidate Matching

12.1 目的

このパターンでは、あえて条件を少し緩めて、自動統合してはいけないが、人間が確認すべき候補を拾います。本番運用では、このワークフローの結果をそのまま顧客マスタに反映しません。MatchRule = review_*のレコードだけを抽出して、レビュー用キューに回します。GetMatchId APIのレスポンスにはmatchIdだけでなく、どのルールにマッチしたかを示すmatchRuleも含まれます。ルール名を設計しておくと、後続処理で「自動統合」と「レビュー候補」を分けやすくなります。([AWS ドキュメント][6])

12.2 ワークフロー設定

項目 設定値
Workflow name er-handson-04-review-candidates
Matching method Rule-based matching
Rule type Advanced
Processing cadence Manual
Normalize data OffまたはOn
Output s3://<BUCKET>/output/04-review-candidates/

12.3 Matching rules

優先度 Rule name Rule condition 扱い
1 auto_exact_email_key Exact(email_key, EmptyValues=Ignore) 自動統合OK
2 auto_exact_phone_city Exact(phone_key, EmptyValues=Ignore) AND Exact(city_key, EmptyValues=Ignore) 自動統合OK
3 review_same_address_similar_name Exact(address_key, EmptyValues=Ignore) AND Exact(city_key, EmptyValues=Ignore) AND Cosine(name_key, 0.65, EmptyValues=Ignore) 要レビュー
4 review_same_city_soundex_name Exact(city_key, EmptyValues=Ignore) AND Soundex(name_key, EmptyValues=Ignore) 要レビュー

12.4 期待結果

グループ レコード 扱い
M001 A001, A005, A007, B001, B006, B009 自動統合OK
M001候補 B008 要レビュー
M002 A002, A006, B002, B007 自動統合OK
M003 A003, B003, B010 自動統合OK
M004 A004, B004 自動統合OK
M005 A008 単独
M006 B005 単独

Pattern 4では、B008が山田太郎グループの候補として拾われる可能性があります。ただし、記事では必ず次のように説明するのが安全です。

B008は「同一人物の可能性がある」だけであり、
自動でM001に統合すべきではない。

理由は以下です。

項目 B008 M001系 評価
名前 Yamada T. Yamada Taro / 山田太郎 近い
email taro@example.com taro.yamada@example.com 弱い
phone 08011112223 08011112222 1桁違い
address 1-1-1 Shibuya 1-1-1 Shibuya 一致
city Tokyo Tokyo 一致

このようなレコードは、CRM統合や顧客360では非常に現実的です。緩いルールは「マッチ確定」ではなく「レビュー候補抽出」に使う、という設計が重要です。


13. Pattern 5: GetMatchId APIによるリアルタイム照合

13.1 目的

バッチでMatching workflowを実行したあと、新しく入ってきた顧客レコードが既存のどのMatch IDに属するかを同期的に確認します。GetMatchId APIは、ルールベースMatching workflowで処理済みのレコードに対して、対応するMatch IDを返します。リクエストではworkflowNamerecordを渡し、レスポンスにはmatchIdmatchRuleが含まれます。([AWS ドキュメント][6])

13.2 対象ワークフロー

まずはer-handson-02-cleansed-exactを使います。各ワークフローの Last job metricsStatusCompleted になってから実行してください。

13.3 API実行例1: 山田太郎系に一致

aws entityresolution get-match-id \
  --workflow-name er-handson-02-cleansed-exact \
  --apply-normalization \
  --record '{
    "email_key": "taro.yamada@example.com",
    "phone_key": "08011112222",
    "name_key": "taro yamada",
    "city_key": "tokyo"
  }' \
  --region ap-northeast-1

期待結果です。

{
  "matchId": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
  "matchRule": "cleansed_exact_email"
}

13.4 API実行例2: 佐藤花子系に一致

aws entityresolution get-match-id \
  --workflow-name er-handson-02-cleansed-exact \
  --apply-normalization \
  --record '{
    "email_key": "h.sato@example.com",
    "phone_key": "09022223333",
    "name_key": "hanako sato",
    "city_key": "osaka"
  }' \
  --region ap-northeast-1

期待結果です。

{
  "matchId": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
  "matchRule": "cleansed_exact_email"
}

13.5 API実行例3: B008相当の曖昧レコード

aws entityresolution get-match-id \
  --workflow-name er-handson-02-cleansed-exact \
  --apply-normalization \
  --record '{
    "email_key": "taro@example.com",
    "phone_key": "08011112223",
    "name_key": "yamada t",
    "address_key": "1-1-1-shibuya",
    "city_key": "tokyo"
  }' \
  --region ap-northeast-1

Pattern 2(er-handson-02-cleansed-exact)に対しては、期待結果は「既存Match IDなし」です。一方、Pattern 4のレビュー候補ワークフロー(er-handson-04-review-candidates)に対して実行した場合は、以下のような結果になる可能性があります。

{
  "matchId": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
  "matchRule": "review_same_address_similar_name"
}

このmatchRuleを見て、後続処理で以下のように分岐します。

auto_* ルール:
  自動統合してよい

review_* ルール:
  顧客マスタには反映せず、人手レビューに回す

14. 全パターンの結果まとめ

Pattern Workflow 目的 M001 山田太郎 M002 佐藤花子 M003 鈴木一郎 M004 田中次郎 B008
1 01-raw-exact 生データ完全一致の限界を見る A005が漏れる 統合される 統合される 統合される 単独
2 02-cleansed-exact 本番基本形。確実な一致だけ拾う 統合される 統合される 統合される 統合される 単独
3 03-conservative-fuzzy 表記ゆれを少し吸収する 統合される 統合される 統合される 統合される 単独
4 04-review-candidates 人手確認候補も拾う 統合される 統合される 統合される 統合される M001候補
5 GetMatchId 新規レコードをリアルタイム照合 既存Match IDを返す 既存Match IDを返す 既存Match IDを返す 既存Match IDを返す ワークフロー次第

15. 記事での説明方針

この流れにすると腹落ちしやすいです。

1. Raw Exactでやる
   → 思ったより漏れる。クレンジングが必要だと分かる。

2. Cleansed Exactでやる
   → 顧客360の基本グループがきれいに作れる。

3. Conservative Fuzzyでやる
   → typoや表記ゆれにも少し強くなる。

4. Review Candidateでやる
   → B008のような「似ているが危険」な候補を拾える。

5. GetMatchIdでやる
   → バッチ統合済みの顧客360に対して、新規流入レコードを即時照合できる。

最終的なメッセージは、こうです。

AWS Entity Resolutionは「全部いい感じに自動統合する魔法」ではない。
むしろ、確実な一致・曖昧な一致・人手確認候補を、
ワークフローとルールで分離できるところに価値がある。

16. 後片付け

検証後は課金や不要リソースを避けるため、以下を実行します。

16.1 AWS Entity Resolutionリソースを削除する

for wf in ${WORKFLOW_01} ${WORKFLOW_02} ${WORKFLOW_03} ${WORKFLOW_04}; do
  aws entityresolution delete-matching-workflow \
    --workflow-name ${wf} \
    --region ap-northeast-1
done

aws entityresolution delete-schema-mapping \
  --schema-name ${SCHEMA_PRIMARY} \
  --region ap-northeast-1

aws entityresolution delete-schema-mapping \
  --schema-name ${SCHEMA_SECONDARY} \
  --region ap-northeast-1

16.2 GlueテーブルとGlueデータベースを削除する

aws glue delete-table \
  --database-name aws-deepcuts-er-glue-db \
  --name registration_data \
  --region ap-northeast-1

aws glue delete-table \
  --database-name aws-deepcuts-er-glue-db \
  --name lead_list \
  --region ap-northeast-1

aws glue delete-database \
  --name aws-deepcuts-er-glue-db \
  --region ap-northeast-1

16.3 S3バケットを空にして削除する

{YYYYMMDD} を変更してください。

aws s3 rm s3://aws-deepcuts-er-$(aws sts get-caller-identity --query Account --output text)-{YYYYMMDD} --recursive --region ap-northeast-1
aws s3 rb s3://aws-deepcuts-er-$(aws sts get-caller-identity --query Account --output text)-{YYYYMMDD} --region ap-northeast-1

16.4 ローカルファイルを削除する

rm -f registration_data.csv lead_list.csv db.json registration_data_table.json lead_list_table.json

これでハンズオン用リソースの削除は完了です。

✅ ベストプラクティス

  • 前処理の徹底 – データを揃え、欠損値を補完することでマッチ精度が向上します。
  • コスト管理 – 課金は処理レコード数に比例するため、不要なレコードを含めないようにフィルタリングしましょう3
  • プライバシー保護 – 個人情報は可能な限りハッシュ化・暗号化し、アクセス制御やKMSキーの運用を徹底します3

まとめ

AWS Entity Resolutionは、データの重複や表記ゆれに悩む企業にとって強力なソリューションです。プリセット済みのアルゴリズムと柔軟なルール設定により、データ統合の手間を大幅に削減し、Customer 360や不正検知など多様なユースケースに活用できます3。日本語情報が少ない今こそ、ぜひこのサービスを試して記事や事例をシェアしてみてください。この記事がその第一歩になれば幸いです。

  1. AWS Entity Resolution | AWS re:Post
    https://repost.aws/questions/QUoNOxleL_Q3eFejpdnGBL6Q/aws-entity-resolution

  2. The Power of Entity Resolution
    https://www.bigdatatheory.com/2024/06/the-power-of-entity-resolution.html

  3. AWS Entity Resolution
    https://tutorialsdojo.com/aws-entity-resolution/ 2 3 4 5 6 7 8

  4. AWS Entity Resolution: Streamlining Data Matching and Linking Across Systems
    https://www.linkedin.com/pulse/aws-entity-resolution-streamlining-data-matching-joseph-sibychen--t8llc

  5. https://docs.aws.amazon.com/entityresolution/latest/userguide/what-is-service.html "What is AWS Entity Resolution? - AWS Entity Resolution"
    [2]: https://docs.aws.amazon.com/entityresolution/latest/userguide/creating-matching-workflow-rule-based.html "Creating a rule-based matching workflow - AWS Entity Resolution"
    [3]: https://docs.aws.amazon.com/entityresolution/latest/userguide/create-schema-mapping.html "Creating a schema mapping - AWS Entity Resolution"
    [4]: https://docs.aws.amazon.com/entityresolution/latest/userguide/create-matching-workflow.html "Match input data using a matching workflow - AWS Entity Resolution"
    [5]: https://docs.aws.amazon.com/entityresolution/latest/userguide/rule-based-mw-simple.html "Creating a rule-based matching workflow with the Simple rule type - AWS Entity Resolution"
    [6]: https://docs.aws.amazon.com/entityresolution/latest/apireference/API_GetMatchId.html "GetMatchId - AWS Entity Resolution"
    [7]: https://docs.aws.amazon.com/entityresolution/latest/userguide/rule-based-mw-advanced.html "Creating a rule-based matching workflow with the Advanced rule type - AWS Entity Resolution"

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?