4. 数据准备与探索性分析

信用风险参数分群与模型分段策略的成败,往往在建模之前就已决定。参数分群要求样本在业务含义上可解释、在统计分布上可区分,而模型分段则要求各段内的数据质量足以支撑稳定估计。因此,数据准备与探索性分析不是“跑个描述统计”的过场,而是把原始数据转化为可建模资产的关键工序。本节围绕数据来源、缺失值处理、异常值识别、变量筛选、单变量分析与多变量可视化六个环节,给出可落地的流程与判断标准。

一、核心原理:数据准备的目标是“可比、可信、可用”

信用风险建模的数据通常来自三类来源:一是内部业务系统,如信贷申请、还款流水、额度使用、催收记录;二是外部征信与三方数据,如征信报告、评分、司法与工商信息;三是衍生数据,如账龄滚动、逾期天数、滚动率与迁徙率。不同来源的数据在口径、时点、更新频率上差异很大,若直接合并,容易产生“时点错配”和“口径污染”。

数据准备的核心原理可以概括为三点:可比,即同一变量在不同时间、不同客群、不同渠道下定义一致;可信,即缺失与异常有明确处理规则且可追溯;可用,即变量与目标变量(如违约、逾期、损失)之间存在稳定且可解释的关系。参数分群尤其依赖“可比”,因为分群本质上是寻找风险特征差异显著的子集;模型分段则依赖“可信”,因为分段后样本量下降,任何数据缺陷都会被放大。

实务中建议先建立“数据字典+加工口径+时点规则”三件套,再进入清洗与探索。没有口径文档的清洗,等于把风险从数据层转移到模型层。

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

  1. 数据来源梳理与抽样:明确观察期、表现期、目标定义。例如以“申请时点”为观察点,表现期设为12个月,目标为“表现期内是否出现M3+逾期”。
  2. 缺失值处理:先区分“业务不适用”“未采集”“真缺失”。对缺失率高于阈值的变量优先剔除;对中等缺失变量可采用分箱后单独设“缺失”箱,保留其可能的风险信息。
  3. 异常值识别:结合业务边界与统计分布,识别年龄为负、收入过高、逾期天数超过表现期等异常。异常值不应直接删除,而应先判断是录入错误还是真实极端风险。
  4. 变量筛选:先做业务可解释性筛选,再做统计筛选,如IV、相关性、VIF、逐步回归或LASSO。
  5. 单变量分析:对每个候选变量做分箱、WOE与IV分析,观察单调性与区分度。
  6. 多变量可视化:用相关性热力图、散点矩阵、分组箱线图等识别共线性与交互效应,为分群与分段提供依据。

下面是一段典型的数据准备与IV计算示例,便于在项目中直接改造使用:

import pandas as pd
import numpy as np

# 1. 读取建模宽表
df = pd.read_csv("credit_model_base.csv")

# 2. 缺失值统计
miss = df.isnull().mean().sort_values(ascending=False)
print(miss[miss > 0.3])  # 缺失率超过30%的变量重点审查

# 3. 异常值处理:年龄与逾期天数
df = df[(df["age"] >= 18) & (df["age"] <= 70)]
df["dpd"] = df["dpd"].clip(lower=0, upper=180)

# 4. 分箱与WOE/IV
def calc_iv(data, feature, target, bins=10):
    data = data[[feature, target]].dropna()
    data["bin"] = pd.qcut(data[feature], q=bins, duplicates="drop")
    grouped = data.groupby("bin")[target].agg(["count", "sum"])
    grouped["bad"] = grouped["sum"]
    grouped["good"] = grouped["count"] - grouped["sum"]
    grouped["bad_rate"] = grouped["bad"] / grouped["bad"].sum()
    grouped["good_rate"] = grouped["good"] / grouped["good"].sum()
    grouped["woe"] = np.log(grouped["bad_rate"] / grouped["good_rate"])
    grouped["iv"] = (grouped["bad_rate"] - grouped["good_rate"]) * grouped["woe"]
    return grouped, grouped["iv"].sum()

grouped, iv = calc_iv(df, "credit_score", "is_bad")
print(grouped)
print("IV =", round(iv, 4))

三、案例/场景:参数分群前的数据体检

假设某消费金融公司准备对现金贷客群做参数分群,初步候选变量包括年龄、收入、征信查询次数、历史逾期次数、额度使用率、设备类型等。数据体检发现:收入缺失率42%,且缺失样本的违约率显著高于非缺失样本;征信查询次数存在极端值999;额度使用率与历史逾期次数高度相关。此时若直接建模,会出现两个问题:一是收入缺失被均值填充后掩盖了风险信号;二是共线性导致分群结果不稳定。

合理的处理是:将收入缺失单独设为一箱并保留;对查询次数做盖帽处理并检查其业务含义;对额度使用率与逾期次数先做相关性分析,若相关性超过0.7,则保留业务解释更强的一个,或通过主成分/因子方式降维。完成这些步骤后,再进行单变量IV排序与多变量聚类探索,分群边界会清晰得多。

环节关键动作判断标准常见输出
数据来源梳理内部、外部、衍生数据时点一致、口径可追溯数据字典、口径文档
缺失值区分缺失类型,设缺失箱或剔除缺失率阈值、缺失与目标关系缺失报告、处理规则
异常值业务边界+统计分布双重识别是否真实极端风险盖帽/截断/单独标记
变量筛选业务筛选+统计筛选IV、相关性、VIF候选变量清单
单变量分析分箱、WOE、IV、单调性IV>0.02且趋势合理分箱表、IV排序
多变量可视化热力图、散点矩阵、分组箱线图共线性与交互效应相关性矩阵、分群草图

四、误区/复盘:数据准备中最容易踩的坑

误区一:缺失值一律填充。在信用风险中,缺失本身可能是风险信号。例如“收入未填写”可能对应低收入或信息造假,直接均值填充会稀释区分度。

误区二:异常值一律删除。极端逾期天数可能正是高风险客群的特征,删除等于削弱模型对尾部风险的识别能力。

误区三:只看IV不看业务。IV高的变量可能来自未来信息或口径错误,例如用“催收次数”预测违约,若催收发生在表现期之后,就构成信息泄露。

误区四:忽略多变量共线性。分群与分段对共线性敏感,两个高度相关的变量同时入模,会导致分段边界漂移、参数估计不稳定。

复盘时建议做三件事:第一,保留完整的清洗日志,记录每一步删除了多少样本、多少变量;第二,对每个被剔除的变量给出业务或统计理由;第三,在分群前用多变量可视化复核一次,确认分群结果不是由某个单一异常变量驱动。只有把数据准备做扎实,后续的参数分群与模型分段才有稳定的基础。