4. 数据预处理:缺失值处理、异常值检测、数据标准化与归一化技术在保险数据中的应用

在保险精算建模中,原始数据通常来自承保系统、理赔系统、第三方征信等异构源,存在大量缺失、异常和量纲不一致的问题。本章聚焦于数据预处理的核心环节,确保输入模型的数据质量满足坏样本归因分析的要求。

核心原则:保险数据预处理必须兼顾统计合理性(不引入偏差)与业务可解释性(保留风险区分度)。任何预处理操作都应记录转换参数,以便在模型上线时对生产数据执行相同的变换。

4.1 缺失值处理

保险数据中缺失值的产生原因包括:客户未填写、系统未采集、数据清洗异常等。处理策略需根据缺失机制(MCAR、MAR、MNAR)和变量重要性选择。

4.1.1 缺失机制与处理策略对比

缺失机制 定义 保险场景示例 推荐处理方式
完全随机缺失(MCAR) 缺失与观测数据无关 系统随机丢包导致的年龄字段缺失 删除或均值/中位数填充
随机缺失(MAR) 缺失与其他观测变量相关 高收入人群更倾向不填写职业信息 多重插补(MICE)或模型预测填充
非随机缺失(MNAR) 缺失与未观测到的因素相关 高风险客户故意隐瞒既往病史 单独编码为“未知”类别,或使用Heckman校正

4.1.2 常用填充方法

  • 统计填充:数值型用均值/中位数,分类型用众数。适用于MCAR且缺失率<5%的场景。
  • 模型预测填充:使用KNN、随机森林或线性回归预测缺失值。适用于MAR且变量间相关性较强的场景。
  • 多重插补(MICE):生成多个完整数据集,合并估计结果。适用于缺失率较高(5%~30%)且需要保留不确定性的场景。
  • 缺失指示变量:新增二值变量标记是否缺失,保留缺失信息。适用于MNAR或缺失本身具有预测意义的场景(如“是否填写收入”可能反映客户风险意识)。
保险业务避坑:对于“理赔金额”等关键响应变量,若缺失率超过30%,建议优先排查数据采集链路问题,而非盲目填充。对于“既往病史”等敏感字段,填充时需注意隐私合规要求。

4.2 异常值检测

保险数据中的异常值可能源于录入错误(如年龄200岁)、欺诈行为(如理赔金额异常高)或真实但极端的风险特征(如超高保额客户)。检测方法需区分全局异常与局部异常。

4.2.1 异常值检测方法对比

方法 适用场景 保险应用示例 优缺点
Z-Score(3σ原则) 近似正态分布的单变量 检测年龄字段中的极端值 简单快速,但对偏态分布不鲁棒
IQR(四分位距法) 偏态分布的单变量 检测理赔金额中的离群点 不受极端值影响,适合保险长尾分布
孤立森林(Isolation Forest) 高维数据、多变量 检测欺诈理赔组合模式 线性时间复杂度,适合大规模数据
DBSCAN聚类 密度分布不均的数据 检测异常保单组合 可发现局部异常,但参数敏感

4.2.2 异常值处理策略

  • 截尾(Winsorization):将异常值替换为指定百分位数的值(如1%和99%分位数)。适用于数值型变量,保留样本量。
  • 删除:仅当确认异常值由录入错误导致且占比<1%时使用。
  • 单独编码:将异常值归为“高/低风险”类别,保留业务含义。
  • 模型鲁棒化:使用对异常值不敏感的模型(如树模型、Huber回归),避免预处理过度修正。
精算实践建议:对于“保费/保额比”等比率变量,建议先进行对数变换再检测异常值,因为原始尺度下长尾分布会导致大量“假异常”。同时,异常值检测阈值应结合业务容忍度动态调整,而非机械套用统计规则。

4.3 数据标准化与归一化

保险数据中变量量纲差异巨大(如年龄20~80岁 vs 保额10万~1000万)。标准化与归一化确保不同量纲的变量在模型中具有可比性,尤其对距离敏感模型(如KNN、SVM、逻辑回归)至关重要。

4.3.1 标准化与归一化方法对比

方法 公式 输出范围 适用场景
Z-Score标准化 \( z = \frac{x - \mu}{\sigma} \) 无固定范围,均值为0,标准差为1 数据近似正态分布,或模型假设特征服从高斯分布
Min-Max归一化 \( x' = \frac{x - \min}{\max - \min} \) [0, 1] 数据有明确边界,或需要保持稀疏性(如神经网络输入层)
Robust标准化 \( x' = \frac{x - \text{median}}{\text{IQR}} \) 无固定范围,受异常值影响小 数据包含异常值,或分布严重偏态
MaxAbs归一化 \( x' = \frac{x}{\max(|x|)} \) [-1, 1] 稀疏数据或已中心化的数据

4.3.2 保险场景选择指南

  • 逻辑回归/线性模型:优先使用Z-Score标准化,确保系数可比。
  • 神经网络/深度学习:推荐Min-Max归一化到[0,1]或[-1,1],加速收敛。
  • 树模型(随机森林、XGBoost):通常不需要标准化,但若特征工程中包含距离计算(如聚类特征),则需标准化。
  • 聚类/降维(K-Means、PCA):必须标准化,否则量纲大的变量会主导距离计算。
实操注意:标准化参数(均值、标准差、最小值、最大值)必须从训练集计算,并保存为pickle或JSON文件,用于验证集和测试集的变换。切勿在全体数据上计算后再拆分,否则会导致数据泄露。

4.4 数据预处理流程总览

以下SVG图展示了保险数据预处理的完整流程,从原始数据到模型就绪数据的三个核心阶段:缺失值处理、异常值检测、标准化与归一化。

保险数据预处理流程总览 保险数据预处理流程总览 原始保险数据 阶段1:缺失值处理 统计填充(均值/众数) 模型预测填充(KNN/RF) 多重插补(MICE) 缺失指示变量 阶段2:异常值检测 Z-Score / IQR 孤立森林 DBSCAN聚类 截尾 / 删除 / 单独编码 阶段3:标准化与归一化 模型就绪数据

4.5 代码示例:保险数据预处理流水线

以下Python代码展示了使用scikit-learn构建保险数据预处理流水线的完整过程,包含缺失值填充、异常值截尾和标准化。

import pandas as pd
import numpy as np
from sklearn.model_selection import train_test_split
from sklearn.impute import SimpleImputer
from sklearn.preprocessing import StandardScaler, MinMaxScaler
from sklearn.pipeline import Pipeline
from sklearn.compose import ColumnTransformer

# 模拟保险数据
data = pd.DataFrame({
    'age': [25, 45, np.nan, 35, 60, 28, 52, np.nan, 40, 33],
    'income': [50000, 120000, 80000, np.nan, 200000, 45000, 150000, 95000, np.nan, 70000],
    'claim_amount': [2000, 5000, 15000, 3000, 100000, 2500, 8000, 4000, 6000, 3500],
    'is_fraud': [0, 0, 1, 0, 1, 0, 0, 0, 0, 0]
})

# 分离特征和标签
X = data.drop('is_fraud', axis=1)
y = data['is_fraud']

# 划分训练集和测试集
X_train, X_test, y_train, y_test = train_test_split(
    X, y, test_size=0.3, random_state=42, stratify=y
)

# 定义数值型特征的预处理流水线
numeric_features = ['age', 'income', 'claim_amount']
numeric_transformer = Pipeline(steps=[
    ('imputer', SimpleImputer(strategy='median')),          # 缺失值用中位数填充
    ('scaler', StandardScaler())                            # Z-Score标准化
])

# 组合预处理
preprocessor = ColumnTransformer(
    transformers=[
        ('num', numeric_transformer, numeric_features)
    ]
)

# 完整流水线(此处以逻辑回归为例)
from sklearn.linear_model import LogisticRegression
pipeline = Pipeline(steps=[
    ('preprocessor', preprocessor),
    ('classifier', LogisticRegression(random_state=42))
])

# 训练模型
pipeline.fit(X_train, y_train)

# 评估
score = pipeline.score(X_test, y_test)
print(f"测试集准确率: {score:.3f}")

# 保存预处理参数(用于生产环境)
import joblib
joblib.dump(pipeline.named_steps['preprocessor'], 'insurance_preprocessor.pkl')
关键要点:
  • 使用 ColumnTransformer 对不同类型特征应用不同预处理策略,避免“一刀切”。
  • 缺失值填充和标准化参数仅从训练集学习,测试集和验证集使用相同的变换。
  • 将预处理和模型封装在同一个 Pipeline 中,确保交叉验证时不会发生数据泄露。
  • 生产环境中使用 joblib 保存预处理对象,保证线上线下一致。

4.6 保险数据预处理避坑清单

常见错误 后果 正确做法
在全体数据上计算标准化参数后再拆分 数据泄露,模型评估过于乐观 先拆分,再在训练集上fit,在测试集上transform
对类别型变量直接标准化 破坏类别语义,引入虚假距离 先进行One-Hot编码或目标编码,再标准化数值部分
忽略时间序列顺序进行缺失值填充 使用未来信息填充过去,导致时序泄露 使用滚动窗口或前向填充,保持时间顺序
对理赔金额等长尾变量直接使用Z-Score 异常值导致均值和标准差失真 先进行对数变换或使用Robust标准化
删除大量缺失样本(缺失率>10%) 样本量减少,引入选择偏差 优先使用多重插补或缺失指示变量
精算合规提醒:在保险监管环境中(如IFRS 17、Solvency II),数据预处理步骤必须完整记录在模型文档中,包括缺失值填充方法的选择理由、异常值检测阈值、标准化参数来源。建议使用DVC(Data Version Control)或MLflow追踪每次预处理的参数变化。