TT Lab
开始
学习 学习路径 课程

保险领域进阶

导出理赔数据,却认不出是谁

在 TT Lab 中继续学习

目标

把合成的实损型索赔数据导出用于分析。去除直接标识符,泛化日期,归并小地区和罕见的值,使 k 提高到 5 以上,然后亲自尝试重新识别,并留下导出记录。

为什么重要

即使删掉姓名和会员编号,只要出生日期、性别、邮政编码还在,大多数人都能找到自己的那一行。在统计出准标识符组合指向多少人(k)之前,什么都没有得到证明。 提高 k 的办法只有把值模糊化或者去掉行,而顺序颠倒的话,被舍弃的行会像滚雪球一样增加。所以先做泛化,抑制放到最后。 作为检查清单的范本,使用的是美国 HIPAA 的 45 CFR 164.514 Safe Harbor 的 18 类,但这项规定并不直接适用于韩国的保险公司。韩国的标准是《个人信息保护法》,其中健康信息作为敏感信息,要求更严格地处理。

步骤

  1. 创建并运行 /root/deid/gen_claims.py,生成 /root/deid/claims.csv(700 笔以上,会员 300 名以上)和 /root/deid/zip_pop.csv。要包含:90 岁以上投保人的索赔 5 笔以上、出现次数不足 5 次的诊断代码 3 种以上、人口在 20000 人以下的地区 2 个以上。
  2. 用 /root/deid/strip.py 去除直接标识符,生成 /root/deid/stripped.csv。rec_id 按原始顺序从 R-000001 开始编号。
  3. 用 /root/deid/kcount.py 统计准标识符组合的 k,并写入 /root/deid/k_before.json(qi、rows、groups、k_min、unique_rows、lt5_rows)。
  4. 用 /root/deid/generalize.py 泛化日期,生成 /root/deid/generalized.csv。出生日期只保留年份,以基准年份 2026 计算的年龄超过 89 的,连年份也删除,并把 age_over_89 设为 Y。索赔日期只保留年份,入院日期去掉。
  5. 用 /root/deid/suppress.py 生成 /root/deid/suppressed.csv。邮政编码只保留前三位,但人口在 20000 人以下的地区改为 000,出现次数不足 5 次的诊断代码改为 RARE,并去掉城市名称。
  6. 用 /root/deid/kanon.py 抑制组合不足 5 笔的行,生成 /root/deid/export.csv 和 /root/deid/k_after.json。剩余的行必须在 70% 以上。
  7. 用 /root/deid/reidentify.py 尝试重新识别,生成 /root/deid/attack.json。对象是导出文件中 rec_id 最小的那一行。
  8. 留下 /root/deid/export_record.json 和 /root/deid/checklist.md。哈希和笔数要从实际文件中测得,检查清单中要同时写出依据和适用范围。

参考

创建合成索赔快照和地区人口表

创建并运行 /root/deid/gen_claims.py,生成 /root/deid/claims.csv 和 /root/deid/zip_pop.csv。

让同一个人多次提出索赔,并把出生日期散布到具体的日。这样才会出现组合中只有自己一个人的行。还要放入 90 岁以上的投保人、人口较少的地区,以及只偶尔出现的诊断代码,后面的步骤才有可处理的对象。

去除直接标识符

用 /root/deid/strip.py 生成 /root/deid/stripped.csv。去掉姓名、会员编号、索赔编号、医院名称,并加上 rec_id。

要读取的文件是第 1 步生成的 /root/deid/claims.csv。不要舍弃任何一行。rec_id 必须按原始顺序编号,日后才能指向同一行。去掉医院名称,是因为小医院会缩小居住地的范围。

统计一个组合指向多少人

用 /root/deid/kcount.py 统计 birth_date、sex、zip5 组合的 k,并写入 /root/deid/k_before.json。

要读取的文件是 /root/deid/stripped.csv。统计每个组合的行数,其最小值就是 k。同时统计只有自己一行的(k 为 1)有多少,以及不足五人的行有多少。这些数字是后续各步骤的起点。

把日期缩减为年份并合并高龄

用 /root/deid/generalize.py 生成 /root/deid/generalized.csv。超过 90 岁的,连出生年份也删除。

要读取的文件是 /root/deid/stripped.csv。不保留年份以外的日期要素,这是 Safe Harbor 的规则。年龄按 2026 减去出生年份来计算。极高的年龄仅凭一个年份就能缩小到某个人,所以合并为一个类别。

归并小地区和罕见的诊断代码

用 /root/deid/suppress.py 生成 /root/deid/suppressed.csv。人口在 20000 人以下的地区为 000,出现次数不足 5 次的诊断代码为 RARE。

要读取的文件是 /root/deid/generalized.csv 和 /root/deid/zip_pop.csv。只有当该地区人数足够多时,才保留邮政编码前三位。请读取人口表来判断。诊断代码的出现次数,要在这次导出的数据范围内统计。

把 k 提高到 5 并测量损失量

用 /root/deid/kanon.py 抑制组合不足 5 笔的行,生成 /root/deid/export.csv 和 /root/deid/k_after.json。

要读取的文件是 /root/deid/suppressed.csv。抑制是最后的手段。前面的泛化足够的话,舍弃的行就很少。如果剩余比例低于 70%,不应当增加抑制,而是应当回头检查前面的步骤。

亲自尝试重新识别

用 /root/deid/reidentify.py 生成 /root/deid/attack.json。对象是导出文件中 rec_id 最小的那一行。

要读取的文件是 /root/deid/export.csv 和 /root/deid/stripped.csv。攻击者所知道的只有泛化后的值(出生年份、性别、地区、索赔年份)。把同一个人在只去掉了直接标识符的版本中能缩小到几行,与此作比较,用数字就能看出泛化实际阻止了什么。

留下导出记录和检查清单

留下 /root/deid/export_record.json 和 /root/deid/checklist.md。哈希和笔数从实际文件中测得。

哈希和笔数从 /root/deid/claims.csv 和 /root/deid/export.csv 中测得。记录中要包含原始文件和导出文件的哈希、所应用的规则、目的与批准人、保存期限。检查清单中除了依据条文,还要写明该标准是否直接适用于我们。如果把原始日期抄进清单,清单就成了又一份泄露的文件。