3. 数据准备与清洗:案例数据集介绍
数据质量是精算模型稳定性的基石。在赔付率异常波动检测中,原始数据通常来自核心业务系统、理赔系统和再保系统,存在字段缺失、记录重复、极端值干扰等问题。本节以车险和非车险两个典型数据集为例,说明数据准备与清洗的标准流程。
3.1 案例数据集概览
本课程使用两个精算实务中具有代表性的数据集:车险数据集(高频低损、保单量大)和非车险数据集(低频高损、风险异质性高)。两个数据集均经过脱敏处理,保留核心精算字段。
| 维度 | 车险数据集 | 非车险数据集 |
|---|---|---|
| 保单数量 | 120,000 条 | 8,500 条 |
| 时间跨度 | 2019Q1 – 2023Q4 | 2018Q1 – 2023Q4 |
| 平均赔付率 | 62.3% | 48.7% |
| 赔付率标准差 | 18.5% | 35.2% |
| 主要风险因子 | 驾驶年龄、车型、地区、NCD等级 | 行业、保额、免赔额、巨灾指数 |
关键提示:非车险赔付率标准差约为车险的1.9倍,说明非车险数据中极端值对整体波动的影响更大,异常检测时需要更谨慎的阈值设定。
3.2 数据字段说明
两个数据集共享部分通用字段,同时包含各自特有的精算变量。以下为关键字段清单:
3.2.1 通用字段
| 字段名 | 类型 | 说明 | 示例 |
|---|---|---|---|
policy_id |
字符串 | 保单唯一标识 | POL2021001234 |
underwrite_date |
日期 | 承保日期 | 2022-06-15 |
earned_premium |
浮点数 | 已赚保费(元) | 3,250.00 |
incurred_loss |
浮点数 | 已发生赔款(元) | 1,890.50 |
loss_ratio |
浮点数 | 赔付率 = incurred_loss / earned_premium | 0.5817 |
claim_count |
整数 | 理赔次数 | 2 |
3.2.2 车险特有字段
| 字段名 | 类型 | 说明 |
|---|---|---|
driver_age |
整数 | 驾驶人年龄(岁) |
vehicle_type |
分类 | 轿车/SUV/MPV/货车 |
ncd_level |
整数 | 无赔款优待等级(0–5) |
region_code |
分类 | 地区编码(A–E) |
3.2.3 非车险特有字段
| 字段名 | 类型 | 说明 |
|---|---|---|
industry_code |
分类 | 行业分类(制造业/建筑业/服务业等) |
sum_insured |
浮点数 | 保险金额(万元) |
deductible |
浮点数 | 绝对免赔额(元) |
cat_index |
浮点数 | 巨灾风险指数(0–100) |
精算实务建议:在建模前,建议对
loss_ratio 字段做截断处理(如限制在 [0, 3] 区间),避免分母过小导致的极端值干扰。同时检查 earned_premium 是否出现零值或负值,这类记录应单独标记并评估。
3.3 缺失值处理
对两个数据集的缺失情况进行统计,发现以下模式:
- 车险数据集:缺失主要集中在
driver_age(缺失率 3.2%)和ncd_level(缺失率 1.8%),属于随机缺失(MAR)。 - 非车险数据集:
cat_index缺失率高达 12.5%,且缺失样本的赔付率均值显著高于非缺失样本(62.1% vs 46.3%),属于非随机缺失(MNAR),需要谨慎处理。
本案例采用以下策略:
| 缺失类型 | 处理方法 | 适用字段 |
|---|---|---|
| 随机缺失(MAR)< 5% | 中位数填充(连续变量)或众数填充(分类变量) | driver_age, ncd_level |
| 非随机缺失(MNAR) | 单独标记为“缺失类”,保留缺失指示变量 | cat_index |
| 关键字段缺失 > 20% | 删除该字段或使用多重插补(MI) | — |
# Python 缺失值处理示例
import pandas as pd
import numpy as np
# 车险:中位数填充
df_car['driver_age'].fillna(df_car['driver_age'].median(), inplace=True)
df_car['ncd_level'].fillna(df_car['ncd_level'].mode()[0], inplace=True)
# 非车险:保留缺失指示变量
df_noncar['cat_index_missing'] = df_noncar['cat_index'].isna().astype(int)
df_noncar['cat_index'].fillna(df_noncar['cat_index'].median(), inplace=True)
3.4 异常值初步筛查
异常值筛查采用领域规则 + 统计方法双通道策略,避免单一方法误判。
3.4.1 领域规则筛查
- 赔付率上限:车险赔付率超过 200% 视为异常(通常由大额人伤案件或未决估损偏差导致);非车险赔付率超过 500% 视为异常(考虑巨灾或集中出险)。
- 保费合理性:车险年保费低于 500 元或高于 50,000 元需复核;非车险保费低于 1,000 元或高于 5,000,000 元需复核。
- 理赔次数:单一保单年度理赔次数超过 5 次标记为高频出险。
3.4.2 统计方法筛查
使用 IQR(四分位距) 和 Z-score 两种方法交叉验证:
| 方法 | 阈值 | 车险异常比例 | 非车险异常比例 |
|---|---|---|---|
| IQR 法 | Q1 – 1.5×IQR 或 Q3 + 1.5×IQR | 2.3% | 4.1% |
| Z-score 法 | |Z| > 3 | 1.8% | 3.6% |
| 两种方法交集 | 同时满足 IQR 和 Z-score 异常 | 1.2% | 2.5% |
注意:非车险的异常比例显著高于车险,这与非车险的厚尾分布特征一致。在后续建模中,建议对非车险数据采用稳健统计量(如中位数、MAD)替代均值、标准差,降低异常值对模型参数的偏移影响。
3.5 数据清洗结果汇总
经过上述步骤,两个数据集的最终清洗结果如下:
| 指标 | 车险 | 非车险 |
|---|---|---|
| 原始记录数 | 120,000 | 8,500 |
| 缺失值填充记录 | 4,560(3.8%) | 1,275(15.0%) |
| 异常值标记记录 | 1,440(1.2%) | 213(2.5%) |
| 最终有效记录 | 118,560 | 8,287 |
| 赔付率均值(清洗后) | 61.8% | 47.2% |
| 赔付率标准差(清洗后) | 16.9% | 31.4% |
结论:数据清洗后,两个数据集的赔付率标准差均有所下降(车险从18.5%降至16.9%,非车险从35.2%降至31.4%),说明异常值筛查有效降低了噪声干扰。清洗后的数据集将用于后续的赔付率波动特征分析和异常检测模型构建。