Communitygithub.com

croblade47/ability

エンティティ解決とレコードマッチング — 1つ以上のデータセット内のレコードから、同一の実在人物、企業、場所、事物を特定し、完全なソース履歴を保持した信頼できる「ゴールデンレコード」に統合します。リストの重複排除、顧客/患者/コンタクト/取引先ファイルのマージ、共有IDなしでのレコードマッチング、住所リンク、CRMクレンジング、MDMパイプライン構築、ファジー名スコアリング、ブロッキングキーの選択、マッチ閾値の設定などにご利用ください。

ability とは?

Abilityは、Entity Resolution(エンティティ解決)のための包括的なスキルです。CRMデータ、患者記録、取引先ファイルなど、複数のデータソースにまたがる重複・曖昧なレコードを、1つの信頼できる「ゴールデンレコード」に統合します。5段階のパイプライン(プロファイリング、標準化、ブロッキング、スコアリング、マージ)を実装しており、Fellegi-Sunterモデルによる確率的マッチングや、決定論的ルール、機械学習による分類、そして人間によるレビューキューを組み合わせて精度を高めます。元のソースデータは決して破壊せず、各ゴールデンレコードは元のレコードへのリンクを保持するため、完全なトレーサビリティを実現します。このスキルは、Claude CodeなどのAIエージェント上で動作し、複雑な重複排除やマスターデータ管理(MDM)のワークフローを自動化します。

対応~Claude Code~Codex CLI~Cursor
npx skills add https://github.com/croblade47/ability-skill/tree/HEAD/skill/ability

お気に入りのAIに質問する

このエージェントスキルを事前に読み込んだ状態で新しいチャットを開きます。

ドキュメント

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段階カスケード

安価で確実なチェックを最初に行い、高価なものは必要な場合のみ実行します。

  1. 決定論的: 信頼できる一意のID(国民ID、納税者番号、口座番号、確認済みメール)が一致 → マッチ。
  2. ファジー: IDが一致しない場合 → フィールドごとに適切なアルゴリズム(下表参照)でフィールドを比較し、Fellegi-Sunter重みで組み合わせます。
  3. 機械学習 / 人間によるレビュー: まだ曖昧な場合 → ラベル付きデータが存在すれば分類器(例:フィールド類似度特徴量に対するロジスティック回帰)、そうでなければ人間のレビューキューに回します。
フィールドタイプ使用アルゴリズム
人名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 にあります。

関連スキル