3. 信贷数据集介绍:特征含义与数据预处理
在构建拒贷原因解释模型之前,必须深入理解信贷数据集的结构与质量。本章将系统介绍数据集中各特征的含义、目标变量的定义以及标准的数据预处理流程,为后续的 LightGBM 建模与 SHAP 解释奠定基础。
3.1 数据集概览
本教程使用的信贷数据集来源于真实信贷场景的脱敏样本,共包含 10,000 条 申请记录,每条记录由 12 个特征 和 1 个目标变量 组成。数据集覆盖了申请人的收入水平、负债状况、信用历史、查询行为等多个维度。
💡 数据来源说明: 本数据集已进行脱敏处理,所有个人身份信息(如姓名、身份证号、联系方式)均已移除。特征数值经过标准化缩放,仅用于教学演示,不代表真实信贷机构的业务数据。
3.2 特征含义详解
下表列出了数据集中所有特征的名称、类型、含义及其在风控场景中的业务逻辑:
| 特征名称 | 数据类型 | 含义 | 业务解释 |
|---|---|---|---|
income |
连续型 | 月收入(元) | 反映申请人的还款能力,收入越高,违约风险通常越低 |
debt |
连续型 | 总负债(元) | 包括房贷、车贷、信用卡欠款等,负债越高,还款压力越大 |
credit_score |
连续型 | 信用评分(300-850) | 征信机构给出的综合信用评分,分数越高代表信用越好 |
inquiry_count |
离散型 | 近6个月征信查询次数 | 查询次数过多可能意味着申请人急需资金,违约风险上升 |
loan_amount |
连续型 | 本次申请贷款金额(元) | 贷款金额越大,潜在损失越高,审批标准通常更严格 |
loan_term |
离散型 | 贷款期限(月) | 期限越长,不确定性越大,违约概率可能增加 |
employment_years |
连续型 | 当前工作年限(年) | 工作越稳定,收入持续性越好,违约风险越低 |
age |
离散型 | 申请人年龄(岁) | 不同年龄段的收入水平和消费习惯不同,影响还款能力 |
marital_status |
分类型 | 婚姻状况(已婚/未婚/离异) | 已婚人群通常家庭收入更稳定,违约率相对较低 |
education |
分类型 | 教育程度(高中/本科/硕士/博士) | 教育水平与收入水平正相关,影响还款能力 |
house_ownership |
分类型 | 房产状况(自有/按揭/租房) | 自有房产代表资产实力,租房人群稳定性相对较弱 |
purpose |
分类型 | 贷款用途(购车/教育/医疗/装修/其他) | 不同用途对应不同的还款意愿和资金流向 |
3.3 目标变量:是否违约
目标变量 default 是一个二分类变量,用于标识申请人是否发生违约行为:
- 0 — 未违约(正常还款或已结清)
- 1 — 违约(逾期超过90天或已核销)
数据集中违约样本占比约为 8.3%,属于典型的类别不平衡问题。在后续建模中,我们将通过 LightGBM 的 scale_pos_weight 参数或采样策略来处理这一不平衡。
⚠️ 注意: 目标变量的定义必须与业务规则严格对齐。不同金融机构对“违约”的定义可能不同(如逾期30天、60天或90天),本教程采用90天逾期作为违约标准。
3.4 数据预处理流程
数据预处理是机器学习建模的关键步骤。下图展示了本教程采用的完整预处理流程:
3.5 预处理步骤详解
3.5.1 缺失值处理
检查各特征的缺失情况,并采用合适的填充策略:
| 特征 | 缺失率 | 填充策略 | 填充值 |
|---|---|---|---|
income |
1.2% | 中位数填充 | 8,500 |
debt |
0.8% | 中位数填充 | 12,000 |
credit_score |
0.5% | 均值填充 | 680 |
employment_years |
2.1% | 中位数填充 | 3.0 |
marital_status |
0.3% | 众数填充 | 已婚 |
education |
0.6% | 众数填充 | 本科 |
3.5.2 异常值处理
使用 IQR(四分位距) 方法检测连续型特征的异常值,并进行截断处理:
# 异常值检测与截断示例
def cap_outliers(df, column):
Q1 = df[column].quantile(0.25)
Q3 = df[column].quantile(0.75)
IQR = Q3 - Q1
lower_bound = Q1 - 1.5 * IQR
upper_bound = Q3 + 1.5 * IQR
df[column] = df[column].clip(lower_bound, upper_bound)
return df
# 对收入、负债、贷款金额进行截断
for col in ['income', 'debt', 'loan_amount']:
df = cap_outliers(df, col)
3.5.3 类别特征编码
对于分类型特征,采用 Label Encoding 或 One-Hot Encoding:
| 特征 | 类别数 | 编码方式 | 说明 |
|---|---|---|---|
marital_status |
3 | Label Encoding | 已婚=0, 未婚=1, 离异=2 |
education |
4 | Label Encoding | 高中=0, 本科=1, 硕士=2, 博士=3 |
house_ownership |
3 | One-Hot Encoding | 生成3个二值特征 |
purpose |
5 | One-Hot Encoding | 生成5个二值特征 |
3.5.4 特征缩放
LightGBM 基于树模型,对特征尺度不敏感,但为了后续 SHAP 解释的一致性,建议对连续型特征进行 标准化(Z-score):
from sklearn.preprocessing import StandardScaler
# 需要缩放的连续特征
continuous_features = ['income', 'debt', 'credit_score',
'inquiry_count', 'loan_amount',
'loan_term', 'employment_years', 'age']
scaler = StandardScaler()
df[continuous_features] = scaler.fit_transform(df[continuous_features])
3.6 预处理后的数据特征
经过上述预处理后,数据集的特征维度从原始的 12 个 扩展至 18 个(因 One-Hot 编码增加了 6 个二值特征)。下图展示了预处理后各特征与目标变量的关系概览:
3.7 数据划分
将预处理后的数据集按以下比例划分为训练集、验证集和测试集:
- 训练集(70%):用于模型训练,共 7,000 条样本
- 验证集(15%):用于超参数调优和早停,共 1,500 条样本
- 测试集(15%):用于最终模型评估,共 1,500 条样本
📌 关键点: 划分时需使用
stratify 参数保持各集合中违约样本的比例一致,避免因随机划分导致训练集与测试集分布差异过大。
from sklearn.model_selection import train_test_split
X = df.drop('default', axis=1)
y = df['default']
# 分层抽样划分
X_train, X_temp, y_train, y_temp = train_test_split(
X, y, test_size=0.3, random_state=42, stratify=y
)
X_val, X_test, y_val, y_test = train_test_split(
X_temp, y_temp, test_size=0.5, random_state=42, stratify=y_temp
)
print(f"训练集: {X_train.shape}, 违约率: {y_train.mean():.3f}")
print(f"验证集: {X_val.shape}, 违约率: {y_val.mean():.3f}")
print(f"测试集: {X_test.shape}, 违约率: {y_test.mean():.3f}")
3.8 本章小结
通过本章的学习,我们完成了以下工作:
- 理解了信贷数据集中 12 个特征 的业务含义与数据类型
- 明确了目标变量
default的定义与分布情况 - 掌握了完整的 数据预处理流程:缺失值填充、异常值截断、类别编码、特征缩放
- 完成了数据集的 分层划分,为后续建模做好准备