第2章 数据探索与可视化:EDA、分布分析、相关性分析
拿到一份信用评分建模的数据集,你会先干什么?很多新手上来就调参数、跑模型,结果往往是一顿操作猛如虎,一看效果原地杵。我个人的习惯是:先不急,沉下心来做一遍EDA。说白了,数据探索就是给你的模型打个“地基”,地基不稳,后面再怎么调参都没用。
这一章我们就聊聊信用评分场景下,EDA到底怎么做、分布分析和相关性分析能发现哪些坑。我会结合实际项目经验,把那些书上不写但实战常见的雷区给你指出来。
2.1 为什么EDA是建模的第一道滤网
EDA(探索性数据分析)不光是画几张图、算几个统计量。它真正的价值是帮你回答三个问题:
- 数据长什么样?(类型、缺失、异常)
- 变量之间有什么关系?(线性?非线性?共线?)
- 数据质量够不够建模?(脏数据、样本偏差)
记得有一次我在做一个信贷申请评分卡项目,特征有40多个。直觉告诉我“工作类型”这个变量应该很有区分度,但一画分布图发现:有个类别占比不到0.5%,而且坏账率极高。如果不做EDA就直接建模,这个变量会被模型当作强信号,但实际推广时遇到这个小众群体就崩了。嗯,这就是EDA该发现的坑。
2.2 单变量分布分析:摸清每个特征的脾气
单变量分析是EDA的起点。我通常会分成两步:
- 描述统计量:均值、中位数、标准差、偏度、峰度、最小最大值。
- 可视化:直方图 + 箱线图 + 密度曲线。
信用评分里有个经典场景:收入变量。收入分布通常是右偏的(长尾巴朝右),少数高收入者把均值拉得很高。如果直接用均值填充缺失,或者不进行变换就放进逻辑回归,模型会很难看。
看一个简单的Python代码片段:
import pandas as pd
import numpy as np
# 假设 df 是训练数据,'income' 是收入特征
desc = df['income'].describe()
skew = df['income'].skew()
kurt = df['income'].kurtosis()
print("偏度:", skew, " | 峰度:", kurt)
# 如果偏度 > 1 或 < -1,通常需要做变换
| 分布形态 | 典型场景 | 常用处理方式 |
|---|---|---|
| 右偏(正偏) | 收入、申请金额 | log变换、Box-Cox、分箱 |
| 左偏(负偏) | 信用评分本身(高分集中) | 平方根、指数变换 |
| 双峰 | 年龄(年轻人+中年人峰值) | 分群建模或哑变量化 |
2.3 相关性分析:找共线、找冗余、找线索
单变量看完,就要看变量之间的关系了。信用评分模型里,最忌讳的就是强共线性。如果两个变量相关系数超过0.8,模型解释性就会打架,而且逻辑回归的系数估计会不稳定。
我一般同时算三种相关系数:
- 皮尔逊:适合连续且大致正态分布的变量。
- 斯皮尔曼:顺序变量或非线性单调关系。
- 点双列:二分类目标与连续变量之间的相关性(信用评分常用)。
项目里我习惯先画一个热力图(用seaborn),一眼看出成对的相关性。然后算VIF(方差膨胀因子),把VIF > 10的变量逐一排查。
import seaborn as sns
import matplotlib.pyplot as plt
from statsmodels.stats.outliers_influence import variance_inflation_factor
# 热力图
corr = df.corr()
sns.heatmap(corr, annot=True, cmap='coolwarm')
plt.show()
# VIF计算
X = df.drop('target', axis=1)
vif_data = pd.DataFrame()
vif_data['feature'] = X.columns
vif_data['VIF'] = [variance_inflation_factor(X.values, i) for i in range(X.shape[1])]
你想想看,假如发现“月收入”和“年收入”相关系数0.98,你果断删掉一个——这不光是消除共线,更是防止模型过拟合。我在一个车贷评分项目中就遇到过“贷款金额”和“车辆价格”VIF高达15,保留两个变量反而让模型的泛化能力下降,去掉一个后AUC还微涨了0.005。
2.4 多变量探索与交叉验证
单变量和成对分析之后,还要做分层探索。比如在信用评分里,我常做“按违约标签分组”看各特征的均值差异,或者用交叉表看“职业 x 教育程度”下的违约率。这能帮你发现特征交互的线索。
举个具体案例:在某个消费贷项目中,单独看“逾期次数”对违约的区分度很高,但按“还款方式”分组后发现,自动扣款的用户逾期次数几乎不影响违约率,而手动还款的用户逾期1次违约风险就翻倍。这个交互如果不做分层探索,建模时就会错失信息。
下面这张图是我在实际项目中常用的数据探索流程框架,你也可以直接用在工作流里:
EDA做到这个程度,你手里基本就有了一张“变量健康检查表”。后面做特征工程和调参时,哪些变量该保留、哪些需要变换、哪些高度冗余,心里都清楚。比起盲目调参,这才是更高效的建模方式。