4. 数据清洗与预处理:缺失值处理与异常值检测
在精算建模中,原始数据几乎不可能完美无缺。缺失值会破坏模型训练的连续性,异常值则会扭曲统计分布与参数估计。本章聚焦于两类核心预处理操作:缺失值填充与异常值检测,并给出精算场景下的实战选型建议。
4.1 缺失值处理
缺失值处理的目标是在不引入系统性偏差的前提下,为后续特征工程与模型训练提供完整的输入矩阵。根据数据缺失机制(MCAR、MAR、MNAR),选择不同的填充策略。
4.1.1 统计量填充(均值/中位数/众数)
这是最基础、计算开销最小的填充方法,适用于低缺失率(<5%)且数据分布相对稳定的场景。
| 填充方式 | 适用数据类型 | 精算场景示例 | 注意事项 |
|---|---|---|---|
| 均值填充 | 近似正态分布的连续变量 | 年龄、BMI、连续型医疗费用 | 易受极端值影响,需先做异常值截断 |
| 中位数填充 | 偏态分布的连续变量 | 理赔金额、住院天数、收入 | 对异常值鲁棒,精算中推荐优先使用 |
| 众数填充 | 分类变量或离散变量 | 性别、婚姻状况、保险产品类型 | 可能引入模式偏差,需结合业务验证 |
精算实战建议:对于理赔金额、医疗费用等长尾分布变量,优先使用中位数填充;对于年龄、保单年度等近似均匀分布变量,可使用均值填充;对于性别、地区等分类变量,使用众数填充,但需注意缺失组与填充组之间的风险差异。
4.1.2 模型预测填充
当缺失率较高(>10%)或变量之间存在强相关性时,统计量填充会严重低估方差、破坏变量间关系。此时应使用模型预测填充,将待填充变量作为目标变量,利用其他完整变量建立预测模型。
常用模型包括:
- 线性回归 / 逻辑回归:适用于线性关系明确的场景,可解释性强。
- 随机森林 / XGBoost:能捕捉非线性关系与交互效应,精算中最为常用。
- KNN 填充:基于相似样本的加权平均,适合局部结构明显的变量。
- MICE(链式方程多重插补):通过迭代生成多个填充版本,保留不确定性。
# Python 示例:使用随机森林预测填充缺失值
from sklearn.ensemble import RandomForestRegressor
import pandas as pd
import numpy as np
def rf_impute(df, target_col, feature_cols):
"""
使用随机森林对目标列进行预测填充
"""
# 划分缺失与非缺失样本
missing_idx = df[df[target_col].isna()].index
observed_idx = df[df[target_col].notna()].index
# 训练集:非缺失样本
X_train = df.loc[observed_idx, feature_cols]
y_train = df.loc[observed_idx, target_col]
# 预测集:缺失样本
X_pred = df.loc[missing_idx, feature_cols]
# 训练模型
model = RandomForestRegressor(n_estimators=100, max_depth=5, random_state=42)
model.fit(X_train, y_train)
# 预测并填充
df.loc[missing_idx, target_col] = model.predict(X_pred)
return df
注意:模型预测填充存在过拟合风险,尤其是在特征与目标变量高度相关时。建议使用交叉验证评估填充质量,并保留填充标记列(is_imputed)用于后续敏感性分析。
4.2 异常值检测
异常值在精算数据中普遍存在:巨额理赔、极端医疗费用、录入错误等。异常值检测的目标是识别而非自动删除,需结合业务判断决定处理方式(截断、分箱、单独建模)。
4.2.1 基于统计的方法:IQR 与 Z-score
| 方法 | 原理 | 阈值 | 适用场景 |
|---|---|---|---|
| IQR(四分位距) | 基于分位数,不受分布假设限制 | 下界:Q1 - 1.5×IQR 上界:Q3 + 1.5×IQR |
偏态分布、含离群点的连续变量 |
| Z-score | 基于均值与标准差,假设正态分布 | |Z| > 3(严格) |Z| > 2.5(宽松) |
近似正态分布、样本量较大时 |
精算选型:理赔金额、医疗费用等长尾变量优先使用 IQR 方法,因为 Z-score 会被极端值拉高标准差,导致异常值被掩盖。对于年龄、保单年度等边界明确的变量,Z-score 更简洁有效。
4.2.2 基于机器学习的方法:Isolation Forest
Isolation Forest(孤立森林)是一种高效的异常检测算法,不依赖分布假设,通过随机划分特征空间来隔离异常点。异常点更容易被“孤立”(路径长度更短),因此得分更高。
核心优势:
- 线性时间复杂度,适合高维数据
- 不需要定义正常样本的分布
- 对局部异常点敏感
# Python 示例:使用 Isolation Forest 检测异常值
from sklearn.ensemble import IsolationForest
import pandas as pd
def detect_outliers_iforest(df, feature_cols, contamination=0.05):
"""
使用 Isolation Forest 检测异常值
contamination: 预期异常比例,默认 5%
"""
model = IsolationForest(
n_estimators=100,
max_samples='auto',
contamination=contamination,
random_state=42
)
# 返回 -1 为异常,1 为正常
df['anomaly_score'] = model.fit_predict(df[feature_cols])
df['is_outlier'] = df['anomaly_score'] == -1
return df
实战对比:在精算理赔数据测试中,IQR 方法对单变量极端值检出率高但无法捕捉组合异常(如“低年龄 + 高理赔”);Isolation Forest 能发现多变量联合异常,但需要调整 contamination 参数。建议两种方法并行使用,取交集或并集根据业务容忍度决定。
4.3 实战流程总结
在精算模型坏样本归因项目中,数据清洗与预处理的推荐执行顺序如下:
- 缺失率评估:计算每个特征的缺失比例,区分低缺失率(<5%)、中缺失率(5%-15%)、高缺失率(>15%)。
- 缺失值填充:低缺失率使用中位数/众数填充;中高缺失率使用随机森林预测填充,并保留填充标记。
- 异常值检测:对连续变量使用 IQR 方法标记极端值;对多变量组合使用 Isolation Forest 检测联合异常。
- 业务确认:将检测到的异常值列表提交业务团队确认,区分“真实极端风险”与“数据录入错误”。
- 处理决策:真实极端值保留或截断;录入错误值修正或删除;无法确认的异常值单独分箱处理。
关键原则:缺失值填充与异常值检测不是一次性操作。在特征工程迭代过程中,每次新增特征或变换后都应重新评估数据质量,确保预处理结果与建模目标保持一致。