4. 数据准备与ETL:回放验证所需数据源
精算模型规则命中回放验证的核心在于“真实数据驱动”。本章聚焦于如何从生产环境中提取、清洗、标准化并脱敏保单与理赔数据,构建可供回放引擎直接消费的高质量数据集。数据准备的质量直接决定回放验证的可信度与效率。
核心原则:回放验证数据应尽可能贴近生产环境真实分布,同时严格遵循数据安全与隐私合规要求。ETL 过程需保证可追溯、可复现。
4.1 所需数据源全景
回放验证需要至少三类数据源:保单数据(承保时点快照)、理赔数据(出险及结案记录)、模型输入输出(原始模型评分与规则命中日志)。下表列出各数据源的核心字段与用途:
| 数据源类别 | 核心字段示例 | 回放验证用途 |
|---|---|---|
| 保单数据 | 保单号、险种代码、起保/终保日期、保额、保费、缴费方式、被保人年龄/性别/职业、渠道代码 | 构建承保时点特征,还原模型输入上下文 |
| 理赔数据 | 理赔号、关联保单号、出险日期、报案日期、结案日期、赔付金额、事故类型、损失描述 | 验证规则命中后的理赔表现,评估规则有效性 |
| 模型输入输出 | 模型版本、输入特征向量(JSON/Parquet)、模型评分、规则ID、规则命中结果(0/1)、命中时间戳 | 直接回放规则引擎,对比新旧规则命中差异 |
数据源对齐检查:务必确保保单数据与理赔数据通过“保单号”字段建立关联,且模型输入输出中的保单号与保单数据一致。建议在 ETL 阶段建立统一的主键映射表。
4.2 数据清洗与标准化
原始生产数据通常包含空值、异常值、格式不一致等问题。清洗与标准化是保证回放结果可比较的前提。以下为关键清洗步骤:
- 空值处理:对数值型字段(如保额、保费)使用中位数或业务默认值填充;对类别型字段(如渠道代码)使用“未知”标记;对关键关联字段(如保单号)空值行直接剔除并记录日志。
- 异常值过滤:年龄字段限制在 0-120 岁;保额字段剔除负数及超过业务上限(如 1 亿元)的记录;日期字段校验逻辑顺序(出险日期不得早于起保日期)。
- 格式标准化:日期统一为
YYYY-MM-DD;金额统一为浮点数,保留两位小数;类别代码统一为大写字母+数字格式(如CHN001)。 - 时间窗口对齐:回放验证通常需要固定观察期(如 2023-01-01 至 2023-12-31),需将保单与理赔数据裁剪至该窗口内,并剔除窗口外记录。
常见陷阱:不要直接在生产库上执行清洗操作。应通过 ETL 工具(如 Apache Spark、Airflow)将数据抽取至独立回放环境,避免影响在线业务。
4.3 数据脱敏处理
回放验证环境通常为非生产环境,必须对敏感个人信息(PII)进行脱敏。脱敏策略需在保留数据分布特征的前提下,消除可识别性。常用脱敏方法如下:
| 字段类型 | 脱敏方法 | 示例 |
|---|---|---|
| 姓名 | 保留姓氏,名字替换为“某” | 张三 → 张某某 |
| 身份证号 | 保留前6位和后4位,中间掩码 | 110101199001011234 → 110101********1234 |
| 手机号 | 保留前3位和后4位,中间掩码 | 13812345678 → 138****5678 |
| 地址 | 保留到市级,详细地址替换为“***” | 北京市海淀区中关村大街1号 → 北京市海淀区*** |
| 保单号/理赔号 | 保留业务前缀,后接哈希值(SHA-256截断) | POL20230001 → POLa3f2b1 |
脱敏验证:脱敏完成后,应抽样检查是否仍能通过组合字段(如出生日期+性别+地区)反推个人身份。若存在重识别风险,需增加泛化或随机扰动。
4.4 ETL 流程架构
下图展示回放验证数据准备的 ETL 流程架构,涵盖从生产数据源到回放数据集的完整链路:
4.5 数据质量校验清单
ETL 完成后,需执行以下质量校验,确保数据可用于回放验证:
- 完整性:保单数据与理赔数据的关联匹配率应 ≥ 95%;模型输入输出中每条记录均有对应的保单号。
- 一致性:脱敏后的保单号在保单数据、理赔数据、模型输入输出中保持一致(使用同一哈希算法)。
- 时效性:数据时间窗口覆盖回放验证所需的完整观察期,无缺失月份。
- 分布保真:脱敏后关键字段(如保额、年龄)的统计分布(均值、分位数)与生产数据偏差 ≤ 5%。
自动化校验脚本示例:可使用 Python 脚本快速验证数据质量。以下为检查保单-理赔关联率的代码片段:
import pandas as pd
policy_df = pd.read_parquet("policy_cleaned.parquet")
claim_df = pd.read_parquet("claim_cleaned.parquet")
merged = pd.merge(policy_df, claim_df, on="policy_id", how="inner")
match_rate = len(merged) / len(claim_df) * 100
print(f"保单-理赔关联匹配率: {match_rate:.2f}%")
assert match_rate >= 95, "关联匹配率低于95%,请检查数据源"
4.6 数据版本管理
回放验证通常需要多次迭代,每次 ETL 生成的数据集应附带版本标签。建议采用以下命名规范:
| 版本标识 | 格式 | 示例 |
|---|---|---|
| 数据日期 | YYYYMMDD | 20231231 |
| ETL 批次号 | BATCH_YYYYMMDD_HHMMSS | BATCH_20240101_143000 |
| 脱敏算法版本 | MASK_V1 / MASK_V2 | MASK_V2 |
将版本信息写入数据集的元数据文件(如 _metadata.json),便于后续追溯与回滚。
推荐实践:使用数据湖(如 Delta Lake)或对象存储(如 S3/MinIO)管理回放数据集,利用分区(如 dt=20231231)实现高效查询与版本控制。