3. 数据准备与探索

在车险赔付频率与案均损失的联合建模中,模型的上限往往不由算法决定,而由数据准备的质量决定。频率模型关注“是否出险、出险几次”,案均损失模型关注“每次出险赔多少”,两者共享同一份理赔与保单数据,但字段口径、粒度与异常处理策略并不完全相同。本节围绕数据来源、清洗、缺失值、异常值与描述性统计五个环节,建立可复用的数据准备流程。

一、核心原理:数据来源与建模粒度对齐

车险数据通常来自三个系统:承保系统提供保单、车辆、被保险人、险种与保额信息;理赔系统提供报案、立案、查勘、定损、赔付与结案信息;外部数据提供车型编码、零整比、地区风险与历史赔付参考。联合建模的关键是确定分析粒度:频率模型一般以“保单-年度”为一条记录,案均损失模型以“赔案”为一条记录。若粒度混淆,例如把多次赔案直接合并到保单层,案均损失就会被平均化,掩盖大额单次赔付的尾部特征。

实务建议:先建立“保单-赔案”两级宽表,再分别聚合为频率表与案均损失表,保证两模型可追溯到同一原始赔案。

二、方法流程:从原始表到建模宽表

  1. 数据抽取:按保单起期或赔案结案日期抽取观察窗口,明确事故年、承保年与日历年的区别。
  2. 字段统一:统一险种代码、车型编码、地区编码与赔款口径(已决、未决、含税/不含税)。
  3. 数据清洗:去重、格式转换、逻辑校验,如赔案金额不得为负、结案日期不得早于报案日期。
  4. 缺失值处理:区分随机缺失与系统性缺失,采用删除、填补或单独设“未知”类别。
  5. 异常值识别:结合业务规则与统计方法识别极端赔款、重复报案与错误录入。
  6. 描述性统计:输出频率分布、损失分布、交叉汇总与可视化,为模型假设提供依据。
车险理赔数据准备:来源 → 清洗 → 建模宽表 承保系统 保单号 / 车架号 险种 / 保额 / 起止期 被保险人 / 地区 理赔系统 报案号 / 赔案号 出险日期 / 结案日期 赔款金额 / 责任比例 外部数据 车型编码 / 零整比 地区风险等级 历史赔付参考 数据清洗与对齐:去重 · 逻辑校验 · 缺失值处理 · 异常值识别 统一赔款口径、日期口径、险种与车型编码 频率表:保单-年度 出险次数 / 是否出险 案均损失表:赔案级 单次赔款金额 / 险种

三、缺失值与异常值处理

缺失值处理要区分机制。若某字段缺失比例低于5%且为随机缺失,可考虑删除或均值/中位数填补;若缺失具有业务含义,例如“新车未投保车损险”导致车损保额为空,则应保留并单独编码为“不适用”,而不是简单填0。对于案均损失模型,赔款金额缺失通常意味着赔案未结案,应结合未决赔款准备金处理,不能直接删除,否则会低估尾部风险。

异常值识别建议采用“业务规则+统计阈值”双轨制。业务规则包括:赔款金额为负、结案日期早于出险日期、同一报案号重复赔付、责任比例超过100%。统计方法可用箱线图、分位数截断与对数变换后的Z分数。需要强调的是,异常不等于错误:大额人伤赔付可能是真实的高风险信号,直接删除会削弱模型对尾部风险的识别能力。合理做法是标记异常、分层建模或使用稳健损失函数。

常见误区:把“未决赔案”当作缺失值删除,会导致赔付频率被低估、案均损失被高估;正确做法是保留未决状态并单独建模或使用准备金估计。

四、描述性统计与质量清单

描述性统计的目标是回答三个问题:频率是否过度离散?案均损失是否右偏?关键变量之间是否存在明显分层?建议至少输出保单数、赔案数、出险频率、案均损失、赔款总额、分险种与分地区的交叉汇总,并绘制频率分布直方图与案均损失的对数分布图。

检查项 典型问题 处理建议
主键唯一性 保单号或赔案号重复 按最新状态去重,保留有效记录
日期逻辑 结案早于报案、起期晚于止期 标记并回查源系统修正
金额口径 含税与不含税混用、已决未决混用 统一为不含税已决+未决准备金
缺失值 车型、地区、保额缺失 随机缺失填补,系统性缺失单列类别
异常值 极端大额、负值、重复赔付 业务复核后标记,不盲目删除
分布特征 频率零膨胀、损失右偏 频率用泊松/负二项,损失用伽马/对数正态
# 示例:赔案级数据清洗与描述性统计(Python)
import pandas as pd
import numpy as np

df = pd.read_csv("claims.csv")

# 1. 去重与日期校验
df = df.drop_duplicates(subset=["claim_id"])
df["report_date"] = pd.to_datetime(df["report_date"])
df["close_date"] = pd.to_datetime(df["close_date"])
df = df[df["close_date"] >= df["report_date"]]

# 2. 缺失值处理
df["vehicle_type"] = df["vehicle_type"].fillna("UNKNOWN")
df["claim_amount"] = df["claim_amount"].fillna(df["reserve_amount"])

# 3. 异常值标记
q99 = df["claim_amount"].quantile(0.99)
df["is_large_loss"] = (df["claim_amount"] > q99).astype(int)

# 4. 描述性统计
print(df["claim_amount"].describe())
print(df.groupby("insurance_type")["claim_amount"].agg(["count", "mean", "median"]))

完成上述步骤后,数据准备才算真正闭环:频率表与案均损失表可追溯到同一原始赔案,缺失与异常均有明确标记,描述性统计为后续分布假设与变量筛选提供依据。数据准备不是一次性工作,而应随建模迭代持续复盘,尤其在新险种上线、赔付政策调整或外部数据更新时重新校验口径。