Ability — 实体解析
Ability 将混乱、重叠的记录转化为一个干净、可追溯的实体集。 它分五个阶段工作,且从不销毁原始数据:每一条合并记录都保留指向其来源原始记录的链接。
记录链接是匹配的数学问题(记录A与记录B是否匹配?)。 实体解析是完整的工作:匹配、将匹配项聚合成实体、评估置信度、并保留来源信息。完成整个工作。
开始之前:对齐检查
混乱的请求是正常的。请根据拼写错误和简写理解意图,切勿评论拼写。在开始实际工作之前,先陈述简明的三行,以便用户低成本纠正方向:
用户原话: <用户字面要求的>
推断问题: <实际需要解决的问题>
假设前提: <你正在做的主要假设——如果确实卡住,最多问一个>
对于快速问题可跳过此项;当你即将处理数据或设计管道时,请执行此检查。
五阶段管道
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后4位 + 邮政编码
- 电话或电子邮件
- 对于文本密集型数据:基于令牌集的MinHash LSH,或嵌入向量 + 最近邻搜索(FAISS/HNSW)
度量指标:
- 缩减率 = 1 − (比较的对数 ÷ 所有可能对数)——目标 > 99%
- 配对完备性 = 落入某个分块的真实匹配数 ÷ 所有真实匹配数——目标 ≥ 95%
4. 评分——三级级联
先执行廉价、确定的检查,仅在必要时才执行昂贵的检查。
- 确定性匹配:存在可靠的唯一ID一致(身份证号、税号、账号、已验证的电子邮件)→ 匹配。
- 模糊匹配:无ID匹配 → 按字段使用合适的算法(见下表)比较字段,并使用 Fellegi-Sunter 权重合并。
- 机器学习/人工审核:仍不明确 → 如果有标记数据,使用分类器(例如基于字段相似度特征的逻辑回归),否则转交人工审核队列。
| 字段类型 | 使用算法 |
|---|---|
| 人名 | Jaro-Winkler(奖励前缀匹配),配合昵称列表 |
| 公司名 | 清理后缀后使用 Token 排序比率(词语顺序不重要) |
| 地址 | 标准化后使用 Levenshtein;房屋编号和单元号必须精确匹配 |
| ID、电话、电子邮件 | 标准化后精确匹配 |
| 长文本 | 基于令牌的 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”时):暂停项目工作,简要回顾你最近的轮次。列出每个偏离用户明确约束的错误,说明其原因以及你将要采取的修复措施。然后继续。确保回顾内容不出现在交付物中——它属于对话本身,而非用户的数据或文档。
匹配任务的输出
完成一项匹配任务后,以如下格式结束:
实体数: <输入记录数> → <解析后的实体数> (<发现的重复数>)
频带分布: 自动匹配 <n> | 审核 <n> | 不匹配 <n>
质量指标: 精确率 <x> | 召回率 <x> | F1分数 <x> (或“未验证——无标记数据集”)
输出文件: <黄金记录、交叉映射表以及审核队列的保存位置>
隐私
匹配通常涉及个人数据。在本地处理,不要将标识符粘贴到 URL 或外部服务中。在跨组织链接时,建议使用隐私保护链接(对姓名进行 Bloom 过滤器编码,使用 Dice 相似度进行比较)——详情请参考 references/methods.md。