Ability — エンティティ解決
Abilityは、散らかった重複レコードを1つのクリーンで追跡可能なエンティティセットに変換します。 5段階のプロセスで動作し、ソースデータを決して破壊しません。マージされたすべてのレコードは、その元となったオリジナルへのリンクを保持します。
レコードリンケージはマッチングの計算(レコードAはレコードBと一致するか?)です。 エンティティ解決はそれ全体の仕事です。マッチング、マッチのクラスタリングによるエンティティ化、信頼度のスコアリング、来歴の保持。全体の仕事を行います。
開始前: アライメントチェック
曖昧なリクエストは普通です。意図を読み取り、スペルミスを指摘しないでください。実際の作業の前に、3行の短い文を提示してユーザーが簡単に軌道修正できるようにします。
SAID: <ユーザーが文字通り尋ねた内容>
INFERRED: <実際に解決すべき問題>
ASSUMED: <あなたが行っている主な仮定 — 本当に止まっている場合のみ、最大1つの質問をする>
簡単な質問の場合はこれをスキップし、データを処理したりパイプラインを設計したりする際に使用します。
5段階パイプライン
1. プロファイリング
マッチングの前に、すべてのフィールドを確認します。フィールドごとに、null率、ユニーク値数、上位の値、フォーマットパターン、エンコーディングの問題(UTF-8 vs Latin-1)を報告します。プロファイリングにより、どのフィールドがマッチングに十分信頼できるか、またどの値が非常に一般的(例:「Smith」「123 Main St」)で一致してもあまり意味がないかがわかります。
2. 標準化
比較する前に正規化しないと、スコアが正しくありません。小文字化、句読点の削除、略語の展開(St → Street)、名前のパーツへの分割、電話番号の数字への正規化、会社の接尾辞(Inc.、Ltd、LLC)の標準化、住所の標準化(可能な場合は郵便検証)を行います。
実際のデータでは、ほぼ常に以下も必要です。
- ニックネームテーブル(Bob/Robert、Peggy/Margaret、Sasha/Alexander、Trish/Patricia)とイニシャル(「J.」)は、その文字で始まる任意の名前と互換性があるものとして扱います。
- 入れ替わった名前フィールド — 姓と名を逆にして比較も行います。
- 曖昧な日付 — 「04/05/1990」は4月5日か5月4日の可能性があります。両方の読みを保持し、日月の入れ替えは矛盾ではなく部分一致として扱います。
3. ブロッキング
すべてのレコードをすべての他のレコードと比較するとN²になります。100万レコードでは約5,000億ペアになります。ブロッキングでは、キーを共有するレコードのみを比較します。異なるキーで複数のパスを使用することで、1つのフィールドのタイプミスが真のマッチを見逃すことを防ぎます。
- 音声的な姓(Soundex / NYSIIS)+ 生年
- 郵便番号プレフィックス + 番地
- IDの下4桁 + ZIP
- 電話番号またはメールアドレス
- テキストが多いデータの場合: トークンセットに対するMinHash LSH、または埋め込み + 最近傍探索(FAISS/HNSW)
測定指標:
- 削減率 = 1 − (比較したペア数 ÷ すべての可能なペア数) — 99%超を目標
- ペア完全性 = いずれかのブロックに含まれる真のマッチ数 ÷ すべての真のマッチ数 — 95%以上を目標
4. スコアリング — 3段階カスケード
安価で確実なチェックを最初に行い、高価なものは必要な場合のみ実行します。
- 決定論的: 信頼できる一意のID(国民ID、納税者番号、口座番号、確認済みメール)が一致 → マッチ。
- ファジー: IDが一致しない場合 → フィールドごとに適切なアルゴリズム(下表参照)でフィールドを比較し、Fellegi-Sunter重みで組み合わせます。
- 機械学習 / 人間によるレビュー: まだ曖昧な場合 → ラベル付きデータが存在すれば分類器(例:フィールド類似度特徴量に対するロジスティック回帰)、そうでなければ人間のレビューキューに回します。
| フィールドタイプ | 使用アルゴリズム |
|---|---|
| 人名 | Jaro-Winkler(プレフィックス一致を重視)、ニックネームリストも使用 |
| 会社名 | 接尾辞クリーンアップ後、トークンソート比(語順を無視) |
| 住所 | 標準化後、Levenshtein距離。番地と部屋番号は完全一致が必要 |
| ID、電話、メール | 正規化後、完全一致 |
| 長文テキスト | トークンに対するJaccard / コサイン類似度 |
Fellegi-Sunter概要 — 各フィールドkについて:
- m = P(フィールドが一致|レコードが真のマッチ) — フィールドの信頼性
- u = P(フィールドが一致|レコードが不一致) — 偶然に一致する頻度
- 一致重み = log2(m/u)。不一致重み = log2((1−m)/(1−u))
- 合計スコア = 各フィールドの結果に対する重みの合計
稀な値はより多くの証拠を持ちます。「Smith」で一致するよりも「Lebowski」(uが非常に小さい)で一致する方がはるかに強力です。可能であれば値固有のuを使用します。実際には、稀なフルネームと正確な生年月日の一致は、住所、電話、メールがすべて変わっていても(転居した場合)、強い証拠となります。一方、一般的な名前と生年月日の一致はそれほど強力ではありません。
ペアのスコアリングには、手計算ではなく scripts/fs_score.py を実行します。これは重みを適用し、事前オッズを考慮してスコアをマッチ確率に変換し、決定バンドを割り当てます。python scripts/fs_score.py --help で使い方を確認できます。完全な数式、計算例、m/uの推定(EMを含む)は references/methods.md にあります。ユーザーが数学的な詳細を求めたり、重みを調整する必要がある場合に参照してください。
スコアだけでは見逃す2つの落とし穴:
- 同じ世帯。双子、配偶者、ルームメイトは姓、住所、時には生年月日を共有するため、スコアがほぼ確実なマッチに見えることがあります。名が異なり(互いのニックネームでない場合)、個人の連絡先(メール、電話)が矛盾する場合は、スコアが何と言おうと、それらを分離するかレビューに回します。
- プレースホルダー値。2000-01-01や1900-01-01のような日付、555-0000のような電話番号、[email protected]のようなメールアドレスは、埋め草であり証拠ではありません。プロファイリング(ステージ1)で不自然に繰り返される値をフラグし、それらに重みを与えないようにします。
決定バンド(ラベル付きデータで調整。以下は開始点):
| マッチ確率 | アクション |
|---|---|
| ≥ 0.95 | 自動マッチ |
| 0.80 – 0.94 | 人間のレビューキュー |
| < 0.80 | 非マッチ |
5. マージ — サバイバーシップとゴールデンレコード
マッチしたペアをエンティティにグループ化します(連結成分 / グラフクラスタリング — ABかつBCだがA≁Cという連鎖に注意。それらはレビューに分割します)。各エンティティに対して、各フィールドを指定されたルールで選択して1つのゴールデンレコードを構築します。
- 最新のもの(最新タイムスタンプ) — 住所、電話番号向け
- 最も完全なもの(nullでない、最長) — 名前、説明向け
- 信頼できるソース(システムランキング) — ID、正式名称向け
オリジナルを上書きしたり削除したりしないでください。保存するもの: ゴールデンレコードID → ソースレコードIDのリスト、各フィールドを選択したルール、それらを結合したマッチスコア。
結果の検証
小さなラベル付きセット(数百ペアのマッチ/非マッチのマーク)を作成するよう依頼するか、その作成を支援します。そのセットに対する適合率、再現率、F1値を報告し、さらにブロッキングの削減率とペア完全性も報告します。ラベル付きセットがない場合の閾値は推測に過ぎません — ラベル付きセットがない場合はその旨を伝えてください。
証拠タグ
結果を主張する際は、どのようにしてそれを知ったかを示します。
- [DOC] — 仕様書やドキュメントからの情報。実行していない。
- [RAN] — このセッション内で実行した。
- [PASS] — ラベル付き/テストデータに対してチェック済み。
チェックポイントレビュー
長時間のジョブでは(おおむね5作業ターンごと、またはユーザーが間違いを報告した時、または「checkpoint」や「dream」と入力した時): プロジェクト作業を一時停止し、自分の最近のターンを簡単にレビューします。それぞれの間違いや、ユーザーが指定した制約からの逸脱、その原因、および今後適用する修正を列挙します。その後、再開します。レビューは成果物の外に保持します — それは会話のためのものであり、ユーザーのデータやドキュメントのためのものではありません。
マッチングジョブの出力
完了したジョブは以下で終了します。
ENTITIES: <入力レコード数> → <解決されたエンティティ数> (<見つかった重複数>)
BANDS: 自動 <n> | レビュー <n> | 非マッチ <n>
QUALITY: 適合率 <x> | 再現率 <x> | F1 <x> (または「未検証 — ラベル付きセットなし」)
FILES: <ゴールデンレコード、クロスウォーク、レビューキューの保存先>
プライバシー
マッチングには個人データが含まれることがよくあります。ローカルで処理し、識別子をURLや外部サービスに貼り付けず、組織間でリンクする場合はプライバシー保護リンケージ(名前のブルームフィルターエンコーディングとDice類似度による比較)を提案します。詳細は references/methods.md にあります。