3. 数据质量评估:缺失值处理、异常值检测、数据一致性检查、数据完整性评估

在保险精算建模中,数据质量直接决定模型效果的可靠性与业务决策的有效性。原始数据通常包含缺失、异常、不一致或不完整记录,若不加以处理,将导致参数估计偏误、预测失真甚至模型失效。本章系统讲解数据质量评估的四大核心环节:缺失值处理、异常值检测、数据一致性检查与数据完整性评估,并提供精算场景下的实操指南。

3.1 缺失值处理

缺失值是精算数据中最常见的问题,来源包括:投保单填写遗漏、系统传输故障、历史数据迁移丢失等。处理缺失值需先识别缺失模式,再选择合适策略。

3.1.1 缺失模式分类

缺失模式 定义 精算示例
完全随机缺失(MCAR) 缺失与观测数据无关 随机抽样的保单中部分年龄字段丢失
随机缺失(MAR) 缺失依赖于其他观测变量 高保额保单更易缺失健康告知信息
非随机缺失(MNAR) 缺失依赖于缺失值本身 理赔金额极高的案件故意隐瞒损失细节

3.1.2 常用处理方法

  • 删除法:适用于MCAR且缺失比例<5%的场景,直接删除含缺失的样本或变量。
  • 均值/中位数填充:连续变量用均值或中位数填充,离散变量用众数填充。简单但会降低方差。
  • 回归插补:利用其他变量建立回归模型预测缺失值,适用于MAR模式。
  • 多重插补(MICE):生成多个完整数据集,合并分析结果,保留不确定性。
  • 模型内置处理:如XGBoost、LightGBM等树模型可自动处理缺失值,精算中常用。
精算提示: 在准备金评估或死亡率建模中,若缺失比例超过30%,建议优先检查数据采集流程,而非仅依赖统计填充。

3.2 异常值检测

异常值指显著偏离正常分布的数据点,可能源于录入错误、欺诈行为或真实极端事件。精算模型中异常值会扭曲损失分布、高估风险资本。

3.2.1 检测方法对比

方法 适用场景 优点 缺点
Z-Score 近似正态分布 计算简单,阈值明确 对极端值敏感,不适用于偏态分布
IQR(四分位距) 任意分布 稳健,不受极端值影响 无法区分轻度与重度异常
孤立森林 高维数据 线性时间复杂度,适合大数据 结果可解释性较弱
DBSCAN聚类 空间密度分布 可发现簇状异常 参数敏感,调参复杂

3.2.2 精算场景处理策略

  • 识别后标记:不直接删除,新增异常标记变量,保留原始信息。
  • 截尾处理(Winsorization):将极端值替换为指定百分位值(如99%分位),常用于损失分布建模。
  • 分组建模:将异常值单独分组建模,如高额理赔单独拟合极值模型。
实操建议: 在车险定价中,单次理赔金额超过保额3倍以上应优先核实是否为录入错误,而非直接截尾。

3.3 数据一致性检查

一致性检查确保同一实体在不同数据源或不同字段间逻辑自洽。精算数据常涉及多系统整合(核保、理赔、财务),不一致将导致模型信号冲突。

3.3.1 常见不一致类型

  • 字段内矛盾:如性别为“男”但疾病代码为“子宫肌瘤”。
  • 跨表不一致:保单生效日期早于投保人出生日期。
  • 时间逻辑错误:理赔申请日期早于事故发生日期。
  • 汇总层级不匹配:保单保费总和与财务系统对账不平。

3.3.2 检查流程

  1. 定义业务规则(如:生效日期 >= 投保日期)。
  2. 编写SQL或Python脚本批量校验。
  3. 记录不一致记录并生成质量报告。
  4. 与业务方确认修正规则(以哪个系统为准)。
注意: 一致性检查应优先于缺失值处理,因为不一致数据可能通过逻辑推导直接修正,无需插补。

3.4 数据完整性评估

完整性评估关注数据是否覆盖了建模所需的所有维度、时间段和业务范围。缺失维度可能导致模型偏差(如只包含健康体保单,忽略次标体)。

3.4.1 评估维度

维度 检查内容 精算示例
时间完整性 是否覆盖完整保单年度/日历年度 只包含2020-2023年数据,缺少2019年
业务线完整性 是否包含所有产品线或险种 缺少意外险数据,无法评估整体风险
变量完整性 建模所需变量是否全部存在 缺少“职业类别”字段,无法进行风险分级
样本完整性 是否覆盖低风险与高风险群体 高保额保单占比过低,模型外推风险大

3.4.2 评估方法

  • 覆盖率统计:计算各维度缺失比例,设定阈值(如<5%为完整)。
  • 分布对比:将样本分布与总体分布(如行业经验表)进行KS检验或卡方检验。
  • 业务专家评审:对关键变量(如既往病史)进行人工抽样核查。
精算提示: 完整性评估结果应作为模型开发前的准入条件,不完整的数据集需先进行数据补充或调整建模范围。

3.5 数据质量评估流程总览

以下SVG图展示了数据质量评估的完整流程,从原始数据输入到最终生成质量报告,涵盖四大核心环节及其输出。

数据质量评估流程总览 数据质量评估流程总览 原始精算数据 缺失值处理 识别模式 → 选择策略 异常值检测 统计方法 → 标记处理 数据一致性检查 业务规则 → 批量校验 数据完整性评估 维度覆盖 → 分布检验 数据清洗与整合 数据质量报告 缺失率 | 异常比例 | 一致率 | 完整度评分 进入模型开发阶段 说明:四个评估环节可并行执行,最终汇总为统一的数据质量报告,作为模型开发的准入依据。

3.6 代码示例:Python数据质量评估流水线

以下代码展示了使用Python进行数据质量评估的完整流水线,涵盖缺失值统计、异常值检测(IQR法)、一致性校验和完整性评分。

import pandas as pd
import numpy as np

def data_quality_pipeline(df, id_col='policy_id'):
    """
    精算数据质量评估流水线
    参数:
        df: DataFrame,包含精算数据
        id_col: 保单唯一标识列名
    返回:
        quality_report: dict,包含各项评估指标
    """
    report = {}
    
    # 1. 缺失值评估
    missing_ratio = df.isnull().mean()
    report['missing_fields'] = missing_ratio[missing_ratio > 0].to_dict()
    report['overall_missing_rate'] = df.isnull().sum().sum() / (df.shape[0] * df.shape[1])
    
    # 2. 异常值检测(IQR法,仅数值列)
    numeric_cols = df.select_dtypes(include=[np.number]).columns.tolist()
    outlier_records = {}
    for col in numeric_cols:
        Q1 = df[col].quantile(0.25)
        Q3 = df[col].quantile(0.75)
        IQR = Q3 - Q1
        lower = Q1 - 1.5 * IQR
        upper = Q3 + 1.5 * IQR
        outliers = df[(df[col] < lower) | (df[col] > upper)]
        if len(outliers) > 0:
            outlier_records[col] = {
                'count': len(outliers),
                'ratio': len(outliers) / len(df),
                'lower_bound': lower,
                'upper_bound': upper
            }
    report['outlier_summary'] = outlier_records
    
    # 3. 一致性检查示例(生效日期 >= 投保日期)
    if 'effective_date' in df.columns and 'application_date' in df.columns:
        df['effective_date'] = pd.to_datetime(df['effective_date'])
        df['application_date'] = pd.to_datetime(df['application_date'])
        inconsistency = df[df['effective_date'] < df['application_date']]
        report['consistency_issues'] = {
            'rule': 'effective_date >= application_date',
            'violation_count': len(inconsistency),
            'violation_ratio': len(inconsistency) / len(df)
        }
    
    # 4. 完整性评估(变量覆盖率)
    required_fields = ['age', 'gender', 'sum_insured', 'premium', 'claim_amount']
    available = [f for f in required_fields if f in df.columns]
    report['completeness'] = {
        'required_fields': required_fields,
        'available_fields': available,
        'coverage_rate': len(available) / len(required_fields)
    }
    
    return report

# 使用示例
# report = data_quality_pipeline(insurance_data)
# print(report['overall_missing_rate'])
扩展阅读: 实际精算项目中,建议将上述流水线封装为Airflow或Prefect任务,实现数据质量的自动化监控与告警。