3. 数据准备与清洗:多源数据整合与质量治理

赔付率异常归因的起点是数据。精算模型对数据质量高度敏感,脏数据会直接导致归因方向错误。本章聚焦保单、理赔、财务三大核心数据源的整合策略与常见质量问题的清洗方案。

3.1 三大数据源的结构与关键字段

赔付率计算依赖三张基础表:保单表(承保信息)、理赔表(出险与赔付记录)、财务表(已赚保费与已发生损失)。下表列出各表的核心字段与关联键:

数据源 核心字段 关联键 典型粒度
保单表 保单号、起保/终保日期、险种、保费、保额、渠道、地区 保单号 每张保单一条记录
理赔表 报案号、保单号、出险日期、立案日期、结案日期、赔付金额、未决金额 保单号 → 保单表 每案一条或多条(多次赔付)
财务表 会计期间、保单号、已赚保费、已发生损失、IBNR、费用分摊 保单号 + 会计期间 每保单每期一条
精算提示: 保单号是三大数据源的核心关联键。若保单号在理赔表或财务表中缺失或格式不一致,将导致整条记录无法匹配,直接影响赔付率计算的分子或分母。

3.2 数据整合流程与常见问题

整合通常分为三步:字段对齐 → 键值匹配 → 聚合汇总。每一步都可能引入质量问题。

数据整合流程与质量风险点 字段对齐 统一字段名、类型、长度 键值匹配 保单号、报案号关联 聚合汇总 按保单/期间汇总赔付 字段名歧义 日期格式不统一 匹配失败/多对多 孤儿保单/理赔 重复汇总 未决/已决混淆 清洗策略 • 字段对齐:建立字段映射字典,统一日期为 YYYY-MM-DD,金额保留两位小数 • 键值匹配:去除保单号前后空格,大小写统一,处理空值保单号 • 聚合汇总:按保单号+会计期间去重,区分已决/未决金额

3.3 常见数据质量问题分类

根据项目经验,赔付率建模中高频出现的数据质量问题可归为以下五类:

问题类别 典型表现 影响环节 严重程度
缺失值 保单号为空、赔付金额为0或NULL 匹配、聚合 高
重复记录 同一理赔案在财务表中出现多次 赔付率计算 高
格式不一致 日期格式混用、金额含逗号/货币符号 字段对齐 中
逻辑异常 出险日期早于起保日期、赔付金额大于保额 数据验证 高
孤儿数据 理赔记录找不到对应保单 匹配 中
避坑提醒: 理赔表中的“赔付金额”字段常混入“已决金额”和“未决金额”两种口径。未做区分直接求和,会导致赔付率虚高或虚低。建议在清洗阶段新增字段 pay_type 标记已决/未决。

3.4 清洗策略与代码实现

以下给出针对上述问题的标准化清洗流程,使用 Python 伪代码示意:

# 步骤1:字段对齐与格式统一
def align_fields(df_policy, df_claim, df_finance):
    # 统一日期格式
    df_policy['start_date'] = pd.to_datetime(df_policy['start_date'])
    df_claim['loss_date'] = pd.to_datetime(df_claim['loss_date'])
    # 统一金额字段,去除逗号与货币符号
    df_finance['earned_premium'] = df_finance['earned_premium'].str.replace(',','').astype(float)
    return df_policy, df_claim, df_finance

# 步骤2:键值清洗与匹配
def clean_keys(df_policy, df_claim):
    # 保单号去空格、转大写
    df_policy['policy_id'] = df_policy['policy_id'].str.strip().str.upper()
    df_claim['policy_id'] = df_claim['policy_id'].str.strip().str.upper()
    # 删除保单号为空的记录
    df_policy = df_policy.dropna(subset=['policy_id'])
    df_claim = df_claim.dropna(subset=['policy_id'])
    # 左连接保留所有保单
    df_merged = df_policy.merge(df_claim, on='policy_id', how='left')
    return df_merged

# 步骤3:去重与逻辑校验
def dedup_and_validate(df):
    # 按保单号+报案号去重,保留最新记录
    df = df.drop_duplicates(subset=['policy_id', 'claim_id'], keep='last')
    # 逻辑校验:出险日期不能早于起保日期
    df = df[df['loss_date'] >= df['start_date']]
    return df

3.5 数据质量监控指标

清洗完成后,建议建立持续监控机制,跟踪以下指标:

  • 匹配率:理赔表与保单表成功匹配的记录占比,目标 ≥ 98%
  • 缺失率:关键字段(保单号、赔付金额)缺失比例,目标 < 1%
  • 重复率:同一保单-报案号组合出现次数 > 1 的比例,目标 < 0.5%
  • 逻辑异常率:出险日期早于起保日期、赔付金额为负等异常占比,目标 < 0.1%
实战要点: 在精算模型中,数据清洗不是一次性工作。每次模型迭代前都应重新执行清洗流程,并记录清洗前后的记录数、赔付率变化,形成数据质量报告,作为模型假设的支撑依据。

3.6 整合后的数据表结构示例

清洗整合后的最终数据表应包含以下字段,用于后续赔付率计算与归因分析:

字段名 类型 说明 来源
policy_id string 保单号(清洗后) 保单表
acc_period string 会计期间(YYYY-MM) 财务表
earned_premium float 已赚保费 财务表
incurred_loss float 已发生损失(已决+未决) 理赔表+财务表
claim_count int 出险次数 理赔表
loss_ratio float 赔付率 = incurred_loss / earned_premium 计算字段

至此,数据准备与清洗阶段完成。下一阶段将基于清洗后的数据表,构建赔付率异常检测与归因模型。