4. 数据预处理实战
在保险理赔 Severity(损失金额)预测中,原始理赔数据往往来自报案系统、查勘系统、定损系统与第三方数据源,字段口径不一致、缺失普遍、长尾极端值频繁出现。模型效果的上限,很大程度上由这一步的数据预处理决定。本节围绕五个关键动作展开:缺失值填充、异常值处理、类别编码、数值标准化与特征对齐,并给出可直接落地的工程做法。
核心目标:把“脏、散、偏”的原始理赔表,转换为“完整、稳健、可训练、可复现”的特征矩阵,同时保证训练集与线上推理的特征顺序、类型、量纲完全一致。
一、核心原理:为什么预处理决定 Severity 预测成败
Severity 预测是典型的回归任务,目标变量通常是赔案总损失金额或案均赔付金额。这类变量具有三个显著特点:
- 右偏长尾:多数案件金额集中在数千元,但少量重大案件可达数十万甚至上百万元,直接建模会被极端值主导。
- 缺失非随机:高价值案件往往查勘信息更全,低价值小额案件可能缺失维修厂、伤情等字段,缺失本身携带信息。
- 类别高基数:车型、维修厂、事故原因、地区等类别字段取值多,独热编码会迅速膨胀维度。
因此,预处理不是“清洗脏数据”的机械劳动,而是把业务先验注入特征的过程。缺失值填充策略、异常值截断阈值、编码方式与标准化范围,都会直接影响模型对“大案”和“小案”的区分能力。
二、方法流程:五步预处理的标准动作
- 缺失值填充:数值字段优先用中位数或分组中位数(如按险种、地区分组);类别字段用“未知”占位;对缺失率高于 60% 的字段评估是否直接剔除,同时为重要字段增加
is_missing指示列。 - 异常值处理:对 Severity 目标与金额类特征先做
log1p变换,再用 IQR 或 1%/99% 分位数截断;业务上真实的大案不应被简单删除,而应保留并加“大案标记”。 - 类别编码:低基数用独热编码,高基数(车型、维修厂)用目标编码或频率编码,并配合 K 折平滑防止泄漏。
- 数值标准化:线性模型用 Z-score,含异常值时用 RobustScaler;树模型可跳过,但为统一流水线仍建议保留。
- 特征对齐:用
ColumnTransformer固化列顺序与变换器,训练集fit_transform,验证与线上只transform。
三、案例场景:车险理赔 Severity 预处理片段
假设原始表包含 claim_amount(目标)、vehicle_age、repair_shop、accident_cause、region 等字段。下面给出关键代码骨架:
from sklearn.compose import ColumnTransformer
from sklearn.pipeline import Pipeline
from sklearn.impute import SimpleImputer
from sklearn.preprocessing import RobustScaler, OneHotEncoder
from sklearn.preprocessing import FunctionTransformer
import numpy as np
num_cols = ["vehicle_age", "driver_age", "claim_amount"]
cat_cols = ["repair_shop", "accident_cause", "region"]
log_then_scale = Pipeline([
("log", FunctionTransformer(np.log1p, validate=True)),
("scale", RobustScaler())
])
preprocess = ColumnTransformer([
("num", Pipeline([
("imputer", SimpleImputer(strategy="median")),
("scaler", RobustScaler())
]), ["vehicle_age", "driver_age"]),
("amount", log_then_scale, ["claim_amount"]),
("cat", Pipeline([
("imputer", SimpleImputer(strategy="constant", fill_value="未知")),
("ohe", OneHotEncoder(handle_unknown="ignore", min_frequency=20))
]), cat_cols)
], remainder="drop")
X_train = preprocess.fit_transform(df_train)
X_valid = preprocess.transform(df_valid) # 只 transform,不重学
对高基数类别字段,可先用
min_frequency 合并低频类别,再对合并后的类别做目标编码,能显著降低维度并保留业务区分度。
四、误区与复盘:常见踩坑清单
| 误区 | 后果 | 正确做法 |
|---|---|---|
| 用全量数据计算填充值/标准化参数 | 数据泄漏,验证分数虚高 | 只在训练集 fit,验证与线上 transform |
| 直接删除大额赔案 | 模型低估大案,业务不可用 | log 变换 + 截断 + 大案标记 |
| 训练与线上列顺序不一致 | 推理结果错乱或报错 | 用 ColumnTransformer 固化列顺序 |
| 目标编码未做 K 折平滑 | 类别泄漏,过拟合 | 折内统计 + 平滑先验 |
| 忽略缺失指示变量 | 丢失“缺失即信息”的业务信号 | 为关键字段增加 is_missing 列 |
预处理流水线必须与模型一起保存(如 joblib 持久化整个 Pipeline),否则线上推理时极易出现“训练用 A 套参数、线上用 B 套参数”的隐性事故。
复盘时建议固定三件事:第一,记录每个字段的缺失率、异常截断阈值与编码映射;第二,在验证集上对比“原始 vs 预处理后”的 MAE 与分位数损失;第三,把预处理配置纳入版本管理,确保任何一次模型上线都能追溯到对应的数据变换逻辑。做到这三点,Severity 预测的稳定性与可解释性都会明显提升。