4. 数据准备与ETL:回放验证所需数据源

精算模型规则命中回放验证的核心在于“真实数据驱动”。本章聚焦于如何从生产环境中提取、清洗、标准化并脱敏保单与理赔数据,构建可供回放引擎直接消费的高质量数据集。数据准备的质量直接决定回放验证的可信度与效率。

核心原则:回放验证数据应尽可能贴近生产环境真实分布,同时严格遵循数据安全与隐私合规要求。ETL 过程需保证可追溯、可复现。

4.1 所需数据源全景

回放验证需要至少三类数据源:保单数据(承保时点快照)、理赔数据(出险及结案记录)、模型输入输出(原始模型评分与规则命中日志)。下表列出各数据源的核心字段与用途:

数据源类别 核心字段示例 回放验证用途
保单数据 保单号、险种代码、起保/终保日期、保额、保费、缴费方式、被保人年龄/性别/职业、渠道代码 构建承保时点特征,还原模型输入上下文
理赔数据 理赔号、关联保单号、出险日期、报案日期、结案日期、赔付金额、事故类型、损失描述 验证规则命中后的理赔表现,评估规则有效性
模型输入输出 模型版本、输入特征向量(JSON/Parquet)、模型评分、规则ID、规则命中结果(0/1)、命中时间戳 直接回放规则引擎,对比新旧规则命中差异
数据源对齐检查:务必确保保单数据与理赔数据通过“保单号”字段建立关联,且模型输入输出中的保单号与保单数据一致。建议在 ETL 阶段建立统一的主键映射表。

4.2 数据清洗与标准化

原始生产数据通常包含空值、异常值、格式不一致等问题。清洗与标准化是保证回放结果可比较的前提。以下为关键清洗步骤:

  1. 空值处理:对数值型字段(如保额、保费)使用中位数或业务默认值填充;对类别型字段(如渠道代码)使用“未知”标记;对关键关联字段(如保单号)空值行直接剔除并记录日志。
  2. 异常值过滤:年龄字段限制在 0-120 岁;保额字段剔除负数及超过业务上限(如 1 亿元)的记录;日期字段校验逻辑顺序(出险日期不得早于起保日期)。
  3. 格式标准化:日期统一为 YYYY-MM-DD;金额统一为浮点数,保留两位小数;类别代码统一为大写字母+数字格式(如 CHN001)。
  4. 时间窗口对齐:回放验证通常需要固定观察期(如 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 流程架构,涵盖从生产数据源到回放数据集的完整链路:

回放验证数据 ETL 流程架构 保单数据源 理赔数据源 模型输入输出 数据抽取(增量/全量) 数据清洗与标准化(空值/异常值/格式/时间窗口) 数据脱敏(PII掩码/哈希/泛化) 回放验证数据集(Parquet/CSV)

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)实现高效查询与版本控制。