ability — 實體解析 是做什麼的?
Ability 能將雜亂、重疊的記錄轉換為一個乾淨且可追蹤的實體集合。 它分為五個階段進行,並且絕不破壞原始資料:每條合併的記錄都會保留連結,指向其來源的原始記錄。
記錄連結是比對的數學計算(記錄 A 是否匹配記錄 B?)。 實體解析則是完整的工作:比對、將比對結果聚類為實體、評估信心度,並保存來源歷程。請完成整個工作。
開始之前:一致性確認
混亂的要求是正常的。請閱讀打字錯誤與簡寫以理解意圖,且絕不評論拼字。在實際工作開始前,請列出以下三行簡短說明,讓使用者能以低成本修正方向:
SAID: <使用者字面上的要求>
INFERRED: <實際要解決的問題>
ASSUMED: <你做出的主要假設 — 如果真的卡住,最多問一個問題>
對於快速問題可跳過此步驟;當你即將處理資料或設計管線時則必須使用。
五階段管線
1. 剖析
在進行任何比對之前,先檢視每個欄位。針對每個欄位報告:空值率、不重複計數、熱門值、格式模式,以及編碼問題(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 萬筆記錄約產生 5000 億個配對。分塊只比較共享相同鍵值的記錄。使用多輪不同鍵值的掃描,以免某個欄位的打字錯誤掩蓋了真正的匹配:
- 姓氏語音編碼(Soundex / NYSIIS)+ 出生年份
- 郵遞區號前綴 + 門牌號碼
- ID 末四碼 + ZIP
- 電話或電子郵件
- 對於文字密集的資料:基於 Token 集的 MinHash LSH,或嵌入向量 + 最近鄰居搜尋(FAISS/HNSW)
衡量指標:
- 縮減率 = 1 −(比較的配對數 ÷ 所有可能配對數)— 目標 > 99%
- 配對完整性 = 落在某個區塊中的真實匹配數 ÷ 所有真實匹配數 — 目標 ≥ 95%
4. 評分 — 三層級聯策略
先執行便宜且確定的檢查,只在需要時才執行昂貴的檢查。
- 確定性:可靠的唯一 ID 一致(國民 ID、稅號、帳號、驗證過的電子郵件)→ 匹配。
- 模糊:沒有 ID 匹配 → 使用正確的演算法(見下表)逐欄位比較,並以 Fellegi-Sunter 權重組合。
- 機器學習 / 人工審核:仍然不明確 → 若有標記資料則使用分類器(例如基於欄位相似度特徵的邏輯迴歸),否則導向人工審核佇列。
| 欄位類型 | 使用方式 |
|---|---|
| 人名 | Jaro-Winkler(獎勵前綴匹配),加上暱稱清單 |
| 公司名稱 | 後綴清理後的 token 排序比率(詞序不重要) |
| 地址 | 標準化後的 Levenshtein;房屋與單元號碼必須完全一致 |
| ID、電話、電子郵件 | 正規化後的精確比對 |
| 長文字 | Token 的 Jaccard / 餘弦相似度 |
Fellegi-Sunter 簡述 — 對於每個欄位 k:
- m = P(欄位一致 | 記錄真實匹配)— 該欄位的可靠性
- u = P(欄位一致 | 記錄不匹配)— 該欄位偶然一致的機率
- 一致權重 = log2(m/u);不一致權重 = log2((1−m)/(1−u))
- 總分 = 每個欄位結果的權重總和
罕見值攜帶更多證據:對「Lebowski」的一致(極小的 u)遠比對「Smith」的一致更強。在實務上,應使用值特定的 u。一個罕見的全名加上精確的出生日期是強有力的證據,即使地址、電話和電子郵件都變了(此人搬家了);一個常見名字加上出生日期則不是。
要對配對進行評分,請執行 scripts/fs_score.py 而非手動計算 — 它會套用權重、將分數轉換為給定先驗勝算下的匹配機率,並分配決策等級。執行 python scripts/fs_score.py --help 查看用法。
完整公式、範例計算以及 m/u 估計(包括 EM)請見 references/methods.md;當使用者需要數學細節或調整權重時請閱讀該文件。
分數本身無法捕捉的兩個陷阱:
- 家庭。 雙胞胎、配偶和室友共享姓氏、地址,有時甚至共享出生日期,因此他們的分數可能看起來像近乎確定的匹配。如果名字不同(且不是彼此的暱稱)且個人聯絡方式(電子郵件、電話)衝突,則將他們分開或送至審核 — 無論分數如何。
- 佔位值。 像 2000-01-01 或 1900-01-01 的日期、像 555-0000 的電話,以及像 [email protected] 的電子郵件都是填充內容,而非證據。剖析(階段 1)應標記可疑重複的值;不給予它們權重。
決策等級(根據標記資料調整;以下是起點):
| 匹配機率 | 動作 |
|---|---|
| ≥ 0.95 | 自動匹配 |
| 0.80 – 0.94 | 人工審核佇列 |
| < 0.80 | 不匹配 |
5. 合併 — 倖存者與黃金記錄
將匹配的配對分組為實體(連通分量 / 圖形聚類 — 注意鏈結,其中 AB 且 BC 但 A≁C;將這些拆分為審核)。為每個實體建立一條黃金記錄,使用陳述的規則為每個欄位選擇值:
- 最新(最新的時間戳)— 用於地址、電話
- 最完整(非空、最長)— 用於姓名、描述
- 可信來源(系統排名)— 用於 ID、法定名稱
絕不覆寫或刪除原始資料。儲存:黃金記錄 ID → 來源記錄 ID 清單、選取每個欄位的規則,以及將它們連接起來的匹配分數。
驗證結果
要求或協助建立一個小型標記集(數百個標記為匹配/不匹配的配對)。報告精確率、召回率與 F1 分數,以及分塊的縮減率與配對完整性。沒有驗證的門檻值只是猜測 — 當沒有標記集時請這麼說。
證據標籤
在聲明結果時,說明你如何得知:
- [DOC] — 來自規格或文件,尚未執行
- [RAN] — 在此工作階段中執行過
- [PASS] — 已針對標記/測試資料檢查過
檢查點回顧
在長時間工作時(大約每五個工作回合、使用者回報錯誤時,或使用者輸入「checkpoint」或「dream」時):暫停專案工作並簡短回顧你最近的回合。列出每個偏離使用者所述限制的錯誤或方向偏移、其原因,以及你將採取的修正措施。然後繼續。將回顧保留在對話中,不要放入交付物 — 它是給對話用的,而非使用者的資料或文件。
匹配工作的輸出
完成的工作應以下列內容結尾:
ENTITIES: <輸入記錄數> → <解析後的實體數> (<找到的重複數>)
BANDS: 自動 <n> | 審核 <n> | 不匹配 <n>
QUALITY: 精確率 <x> | 召回率 <x> | F1 <x> (或「未驗證 — 無標記集」)
FILES: <黃金記錄、交叉對照表與審核佇列的儲存位置>
隱私
匹配常涉及個人資料。請在本地處理,不要將識別碼貼到 URL 或外部服務中,且在跨組織連結時建議採用隱私保護連結方式(使用 Dice 相似度比較 Bloom 濾波編碼的姓名)— 詳見 references/methods.md。