3、数据准备与清洗:数据源选择、缺失值处理与异常值初步过滤
赔付率尖峰检测的可靠性,80% 取决于底层数据的质量。本章聚焦于如何从保单、理赔、财务三大核心系统中提取数据,并完成缺失值填补与异常值初步过滤,为后续阈值设定和模型训练提供干净、一致的数据基础。
3.1 数据源选择与核心字段
赔付率计算需要将保费与赔款在时间、产品、渠道维度上对齐。三个数据源的角色与关键字段如下:
| 数据源 | 核心用途 | 关键字段(示例) |
|---|---|---|
| 保单系统 | 提供已赚保费分母,以及风险暴露量 | 保单号、起保日期、终保日期、险种代码、保费、渠道、核保人 |
| 理赔系统 | 提供已发生赔款分子,含已决与未决 | 报案号、保单号、出险日期、立案日期、已决赔款、未决赔款准备金 |
| 财务系统 | 校准实际资金流出,消除准备金估计偏差 | 会计期间、保单号、实付金额、付款日期、费用类型 |
对齐原则: 三个数据源必须通过 保单号 或 统一业务编号 进行关联。建议在数据仓库层建立以保单号为主键的宽表,避免在分析阶段频繁跨库 JOIN。
3.2 缺失值处理策略
缺失值在保险数据中普遍存在,处理不当会直接扭曲赔付率曲线。按缺失类型采取不同策略:
- 关键标识缺失(如保单号、险种代码):直接剔除该记录,无法补全。
- 金额字段缺失(如已决赔款、未决赔款):优先使用财务实付数据回填;若无,则按同险种、同渠道的平均赔付额插补。
- 日期字段缺失(如出险日期、立案日期):使用报案日期或保单起保日期推算,并在字段中标记为“推算值”。
- 分类字段缺失(如渠道、核保人):单独归为“未知”类别,不参与分组对比分析。
# 缺失值处理伪代码示例(Python 风格)
import pandas as pd
# 剔除关键标识缺失
df = df.dropna(subset=['policy_no', 'risk_code'])
# 金额字段:按险种均值插补
df['paid_loss'] = df.groupby('risk_code')['paid_loss'].transform(
lambda x: x.fillna(x.mean())
)
# 日期字段:用报案日期推算
df['loss_date'].fillna(df['report_date'] - pd.Timedelta(days=3), inplace=True)
# 分类字段:归为未知
df['channel'].fillna('UNKNOWN', inplace=True)
3.3 异常值初步过滤
异常值会制造虚假的赔付率尖峰,必须在上游过滤。采用 分位数 + 业务规则 双重过滤:
- 单变量分位数截断: 对单笔赔款金额、单张保单保费,剔除超过 99.5% 分位数或低于 0.5% 分位数的极端值。
- 业务规则过滤: 剔除赔款金额大于保额 120% 的记录(通常为录入错误);剔除已赚保费为 0 或负数的保单。
- 时间连续性检查: 剔除出险日期早于保单起保日期 30 天以上、或晚于保单终保日期 90 天以上的理赔。
注意: 异常值过滤不能过度。赔付率尖峰本身可能由真实巨灾或大额案件引起,过滤阈值应保留业务解释空间。建议将过滤后的异常值单独存储为“待复核”数据集,而非直接丢弃。
3.4 数据清洗流程总览
下图展示了从三个数据源到清洗后宽表的完整流程,以及每个环节的关键动作:
3.5 清洗后数据质量检查清单
在进入赔付率计算前,建议逐项确认以下检查点:
- 完整性: 保单与理赔的匹配率 ≥ 98%(按保单号关联后无缺失)。
- 一致性: 财务实付赔款总额与理赔系统已决赔款总额差异 ≤ 2%。
- 时效性: 数据截止日期统一,避免混入不同会计期间的记录。
- 去重: 同一报案号仅保留一条理赔记录,重复报案已合并。
实践建议: 将清洗逻辑封装为可重复执行的 Python 或 SQL 脚本,每次跑赔付率监测前自动运行,并输出清洗报告(含缺失率、异常值剔除数量、匹配率等指标),便于审计与回溯。