3. 数据探索:描述性统计,缺失值分布分析

拿到一份信用评分卡的原始数据,别急着建模。我个人的习惯是先花半小时做数据探索。这一步急不得,你做得多仔细,后面的坑就少多少。说白了,数据探索就是跟数据“混个脸熟”——看看它长什么样,有哪些毛病,值不值得信任。

3.1 描述性统计:先摸清数据的底细

描述性统计是最基础的操作。用Pandas一行代码就能搞定:

import pandas as pd
df.describe(include='all')

但这行代码背后,你得看懂几个关键指标。

指标 数值型特征 类别型特征
count 非缺失样本数 非缺失样本数
mean / std 均值 / 标准差 —
min / 25% / 50% / 75% / max 分位数,看分布范围和异常值 —
unique / top / freq — 唯一值个数 / 频数最高的值 / 频数

嗯,这里要注意一点:describe()默认只处理数值列。如果你想看类别列,得加上include='object'或者include='all'。我曾经遇到过一位同事,只看了数值列的统计就下结论,结果漏掉了几个类别变量里出现了“未知”或“-999”这种脏数据,后期数据清洗白忙了一场。

3.2 每个特征都要单独“体检”

光看一张表还不够。我建议你逐个特征打印直方图或频数表。比如对年龄字段,你可能会发现最小值是0岁,最大值是120岁——明显不合理。对收入字段,看看均值和中位数差得多不多。如果均值远大于中位数,说明存在严重的右偏,可能有一些高收入异常值。

# 快速检查异常值
df['age'].value_counts().sort_index().head(10)
df['income'].describe(percentiles=[.01, .05, .95, .99])

你想想看,信用评分卡里如果混入一个年龄为150岁的样本,模型会怎么学?它会把超高年龄当作一种“特殊信号”,导致评分逻辑荒谬。所以这个步骤不能省。

核心原则:描述性统计不是为了生成报告,而是为了发现数据质量问题。每一个异常的统计量背后,都可能藏着一个需要处理的样本或特征。

3.3 缺失值分布:数据缺失不是随机的

信用评分卡数据最让人头疼的就是缺失值。缺失的原因五花八门:客户没填、系统没录、字段在某个时间段后才增加……缺得没有规律,但一定有模式。

首先,算一下整体缺失率和每列的缺失率:

# 总体缺失率
df.isnull().sum().sum() / len(df)
# 按列缺失率
df.isnull().sum() / len(df) * 100

我曾经接手过一个信贷项目,客户收入字段缺失率高达70%。一开始我以为直接删掉这列算了,后来发现收入缺失的客户往往是自由职业或小企业主,他们的逾期率比有收入的客户高出整整一倍。你看,缺失值本身就是一个重要的“标签”——它隐含着客户群体的信息。所以缺失处理不能一删了之。

3.4 缺失模式分析:看“谁跟谁一起缺”

表格里散落着缺失值,并不是独立的。比如“就业状态”和“收入”经常一起缺失。我们可以用缺失矩阵或热力图来观察。不过手工也可以用交叉表:

# 两个字段的缺失交叉情况
df['income_missing'] = df['income'].isnull().astype(int)
df['employ_status_missing'] = df['employ_status'].isnull().astype(int)
pd.crosstab(df['income_missing'], df['employ_status_missing'])

为什么要注意共缺失?因为如果两个强相关字段一起缺失,它们背后的业务含义可能是同一种客户类型(比如刚毕业无固定收入)。处理时可以考虑同时填充或构造衍生特征。

我的习惯:把缺失率超过50%的字段单独拎出来,跟业务方确认这是“无效字段”还是“有含义的缺失”。很多时候,缺失率高恰恰说明这个字段有筛选价值。

3.5 缺失值的可视化探索

用代码看数字还不够直观。我喜欢画一张缺失值占比的柱状图,或者用missingno库的矩阵图。这里给出一个简单的缺失率排序条形图代码:

import matplotlib.pyplot as plt
missing_rate = df.isnull().sum() / len(df) * 100
missing_rate.sort_values(ascending=False).plot(kind='barh')
plt.xlabel('缺失率 (%)')
plt.show()

这张图能帮你一眼识别出“问题特征”。通常缺失率低于5%的字段,直接删除或简单填充问题不大;5%-30%的字段需要慎重处理;超过30%的字段得考虑是否保留或做二次编码。

3.6 本章知识结构图

为了让你对整个数据探索流程有清晰的框架感,我画了一张流程图。它把描述性统计和缺失值分析串联起来,标出了每个环节需要关注的关键点。

数据探索流程 —— 描述性统计与缺失值分析 原始数据集 描述性统计 缺失值分布分析 数值型:均值/分位数 类别型:频数/唯一值 单列缺失率 共缺失模式 数据清洗与预处理决策 缺失处理策略示例: 删除(<5%) / 均值/中位数填充 / 模型预测填充 构建“是否缺失”指示特征(缺失率5%~30%)

这张图把数据探索拆成了两条并行的线。左边是描述性统计,右边是缺失值分析。最终它们都汇聚到“数据清洗与预处理决策”上,也就是下一章我们会动手做的事情。不过在进入清洗之前,你得把这两个环节跑透。

3.7 实战中的几个小提醒

  • 描述统计只看一行不够:对于类别很多的特征,describe()只显示top值,你得value_counts()看清全部分布。我见过有人把“性别”列误认为二值变量,实际多了个“未知”类别,导致模型多了一个无意义的特征。
  • 缺失率不是唯一指标:一个字段缺失5%但缺失样本全是高风险客户,那这5%的缺失就是“黄金信息”。别只看数字,要结合业务理解。
  • 不要一开始就填充缺失:先理解缺失原因,再决定填充方式。我曾经傻乎乎地直接用均值填充收入缺失,结果把一群自由职业者的收入拉到平均水平,模型严重偏差。
避坑提醒:缺失值不要跟特殊值混淆。有些数据集中“-1”“-999”“unknown”是业务自定义的缺失标记,不是真正的数值。记得先转换成np.nan再分析,否则描述性统计会被这些假数值拖偏。

好了,这章的内容就是这些。数据探索环节虽然看起来琐碎,但它是整个信用评分卡模型的基础。你花的时间越多,后面建模就越顺。别急着跳过这一步,相信我,值。