4. 数据准备与探索:数据质量检查、缺失值处理、异常值检测、特征分布分析

在金融风控模型开发中,数据准备与探索(Data Preparation & Exploration, DPE)是决定模型上限的关键环节。业界有句共识:“垃圾进,垃圾出”。本章将系统讲解数据质量检查、缺失值处理、异常值检测与特征分布分析四大核心步骤,确保后续建模与A/B分流实验建立在干净、可靠的数据基础上。

4.1 数据质量检查

数据质量检查是DPE的第一步,主要从完整性、准确性、一致性、时效性四个维度展开。金融风控数据通常包含用户基本信息、交易流水、征信记录、设备指纹等异构数据源,质量检查需覆盖以下清单:

检查维度 检查项 典型问题 检查方法
完整性 缺失率、空值、空字符串 收入字段缺失率 > 50% df.isnull().sum() / len(df)
准确性 值域、格式、逻辑校验 年龄 < 0 或 > 120 describe() + 业务规则
一致性 跨表主键、枚举值映射 性别字段同时存在 'M'/'男'/'1' value_counts() + 字典映射
时效性 时间戳范围、数据延迟 申请日期晚于当前日期 min/max + 业务容忍窗口
实战建议:在风控场景中,建议为每个字段建立数据质量监控看板,每日自动扫描缺失率、异常值比例、分布漂移等指标,并设置告警阈值(如缺失率突增 > 5% 时触发人工核查)。

4.2 缺失值处理

缺失值处理需区分随机缺失(MAR)、完全随机缺失(MCAR)和非随机缺失(MNAR)三种机制。金融数据中,收入、负债等敏感字段常呈现MNAR特征,直接删除或简单填充可能引入偏差。常用处理方法如下:

  • 删除法:适用于缺失率 < 5% 且为MCAR的字段。行删除(listwise deletion)或列删除(drop column)。
  • 统计填充:均值/中位数/众数填充。适用于数值型低缺失率字段,但会降低方差。
  • 模型预测填充:使用KNN、随机森林或XGBoost预测缺失值。精度高,但计算成本大。
  • 业务规则填充:如“收入缺失”用“公积金基数×系数”推算,保留业务可解释性。
  • 缺失指示变量:新增二值特征 is_missing,保留缺失模式信息,尤其适合MNAR场景。
风控特殊处理:对于“逾期天数”、“负债率”等强预测力字段,若缺失率 > 30%,建议先分析缺失模式是否与坏样本相关。若坏样本中该字段缺失率显著更高,则缺失本身即构成强信号,应保留缺失指示变量。

4.3 异常值检测

异常值在风控中可能代表欺诈、数据录入错误或极端信用行为。检测方法需结合业务理解与统计手段:

方法 适用场景 阈值/参数 金融案例
Z-Score 近似正态分布 |Z| > 3 交易金额偏离均值3σ以上
IQR(四分位距) 偏态分布 Q1 - 1.5×IQR 或 Q3 + 1.5×IQR 年龄字段的极端值
孤立森林 高维、非线性 异常分数 > 0.6 设备指纹异常检测
DBSCAN 密度聚类 eps=0.5, min_samples=10 团伙欺诈识别
注意:不要机械删除所有异常值。在风控中,某些异常值(如单笔大额转账、深夜登录)可能是欺诈的强特征。建议先标记异常,再结合业务标签(是否逾期/欺诈)分析其预测能力,决定保留、截尾或单独建模。
异常值检测与处理流程 原始数据 统计检测 业务规则 异常标记 保留/截尾/删除 建模数据 决策依据 坏样本占比 IV值变化 业务可解释性

4.4 特征分布分析

特征分布分析帮助理解数据形态、识别长尾分布、发现潜在的数据泄露或样本偏差。常用分析手段包括:

  • 单变量分布:直方图、核密度估计(KDE)、箱线图。关注偏度、峰度、多峰性。
  • 双变量关系:散点图、分组箱线图、相关性热力图。识别线性/非线性关系。
  • 分组对比:好样本 vs 坏样本的分布差异。使用KS检验、PSI(群体稳定性指标)量化。
  • 时间稳定性:按时间窗口(周/月)绘制特征分布,检测概念漂移。
风控关键指标:PSI < 0.1 表示特征稳定;0.1~0.25 需关注;> 0.25 表示严重漂移,需重新训练或调整模型。IV(信息量)用于衡量特征区分度:IV < 0.02 为弱特征,0.02~0.1 为中等,> 0.1 为强特征。
特征分布分析框架 特征分布分析 单变量分布 双变量关系 分组对比 时间稳定性 输出:特征稳定性报告(PSI)、区分度报告(IV)、分布漂移告警、异常值清单 决策:特征筛选、分箱策略、样本加权、模型重训

4.5 实战代码示例:数据质量检查与缺失值处理

以下代码展示使用Python进行数据质量检查与缺失值处理的典型流程:

import pandas as pd
import numpy as np

# 加载数据
df = pd.read_csv('credit_data.csv')

# 1. 数据质量检查
print("=== 数据概览 ===")
print(df.info())
print("\n=== 缺失率统计 ===")
missing_rate = df.isnull().mean().sort_values(ascending=False)
print(missing_rate[missing_rate > 0])

# 2. 异常值检测(IQR法)
def detect_outliers_iqr(series):
    Q1 = series.quantile(0.25)
    Q3 = series.quantile(0.75)
    IQR = Q3 - Q1
    lower = Q1 - 1.5 * IQR
    upper = Q3 + 1.5 * IQR
    return (series < lower) | (series > upper)

# 对数值型字段检测异常
num_cols = df.select_dtypes(include=[np.number]).columns
outlier_mask = pd.DataFrame()
for col in num_cols:
    outlier_mask[col] = detect_outliers_iqr(df[col])
print("\n=== 各字段异常值数量 ===")
print(outlier_mask.sum())

# 3. 缺失值处理
# 低缺失率字段:中位数填充
for col in ['income', 'age']:
    if df[col].isnull().mean() < 0.05:
        df[col].fillna(df[col].median(), inplace=True)

# 高缺失率字段:新增缺失指示变量 + 业务规则填充
if df['debt_ratio'].isnull().mean() > 0.3:
    df['debt_ratio_missing'] = df['debt_ratio'].isnull().astype(int)
    # 业务规则:用收入估算
    df['debt_ratio'].fillna(df['income'] * 0.3, inplace=True)

print("\n=== 处理完成 ===")
print(df.isnull().sum().sum(), "个缺失值剩余")
生产环境建议:将上述流程封装为数据质量管道,使用DVC(数据版本控制)管理数据快照,确保每次模型训练使用的数据版本可追溯。同时,将质量检查结果写入日志系统,便于后续审计与复盘。

4.6 本章小结