4. 缺失值处理:缺失值产生原因、统计缺失比例、常见填充策略

在坏样本归因任务中,缺失值不仅是数据质量问题,更可能隐藏着业务逻辑的断裂点。例如,用户“收入”字段缺失可能意味着该用户为无业或高风险群体。本章系统梳理缺失值的产生机制、量化评估方法以及三种主流填充策略,帮助你在 LightGBM 实战前完成高质量的数据清洗。

4.1 缺失值产生原因

理解缺失值的来源是选择填充策略的前提。根据缺失机制与业务场景,可将缺失原因归纳为以下四类:

类别 典型场景 示例
完全随机缺失(MCAR) 系统故障、传输丢包、人为误删 某批次传感器数据因网络波动全部丢失
随机缺失(MAR) 缺失概率与其他观测变量相关 女性用户更倾向于不填写“年龄”字段
非随机缺失(MNAR) 缺失值本身与缺失原因直接相关 高逾期用户故意隐藏“负债率”数据
业务逻辑缺失 字段在特定条件下无意义 未婚用户无“配偶收入”字段
实战提示:在坏样本归因中,非随机缺失(MNAR)往往是最需要警惕的信号。例如,缺失“最近一次还款日期”的用户,其坏账率可能显著高于有记录的用户。建议在填充前先对缺失模式做分组统计,验证缺失是否与目标变量(坏样本标签)存在关联。

4.2 统计缺失比例

在决定填充策略前,必须量化每个特征的缺失严重程度。以下代码展示了如何快速计算缺失比例并可视化:

import pandas as pd
import numpy as np

def missing_stats(df):
    """计算缺失比例并排序"""
    missing = df.isnull().sum()
    missing_pct = (missing / len(df)) * 100
    stats = pd.DataFrame({
        '缺失数量': missing,
        '缺失比例(%)': missing_pct
    }).sort_values('缺失比例(%)', ascending=False)
    return stats[stats['缺失数量'] > 0]

# 示例:假设 df 为原始数据集
stats_df = missing_stats(df)
print(stats_df.head(10))

根据缺失比例,通常将特征分为三个等级:

  • 低缺失(< 5%):可直接删除或简单填充,对模型影响极小。
  • 中缺失(5% - 30%):需要谨慎选择填充策略,建议尝试多种方法并交叉验证。
  • 高缺失(> 30%):填充风险较高,优先考虑删除特征或构造“是否缺失”的指示变量。
避坑指南:不要仅依赖缺失比例做决策。一个缺失比例仅 2% 但与非随机缺失强相关的特征,其信息价值可能远高于一个缺失 20% 但完全随机的特征。务必结合业务含义和缺失机制综合判断。

4.3 常见填充策略

以下从简单到复杂,介绍三种最常用的填充策略,并给出适用场景与代码实现。

4.3.1 均值/中位数填充

这是最基础的填充方法,适用于数值型特征且数据分布相对对称的场景。

  • 均值填充:适用于数据近似正态分布,无极端异常值。
  • 中位数填充:适用于数据偏态分布或存在明显异常值。
# 均值填充
df['age_filled'] = df['age'].fillna(df['age'].mean())

# 中位数填充
df['income_filled'] = df['income'].fillna(df['income'].median())
效果对比:在坏样本数据中,“负债率”通常呈右偏分布(少数人负债极高),此时使用中位数填充比均值填充更能保持整体分布形态,避免引入偏差。

4.3.2 模型预测填充

利用其他特征作为输入,训练模型预测缺失值。这种方法能捕捉特征间的复杂关系,但计算成本较高,且需要避免数据泄露。

常用模型包括:

  • 线性回归:适用于线性关系较强的数值特征。
  • KNN:基于相似样本的加权平均,适合局部结构明显的场景。
  • LightGBM:能处理非线性关系和类别特征,是实战中的首选。
from lightgbm import LGBMRegressor
from sklearn.model_selection import train_test_split

# 假设 'target_feature' 存在缺失,其他特征完整
train_data = df[df['target_feature'].notna()]
test_data = df[df['target_feature'].isna()]

X_train = train_data.drop(columns=['target_feature'])
y_train = train_data['target_feature']
X_test = test_data.drop(columns=['target_feature'])

model = LGBMRegressor(n_estimators=100, learning_rate=0.1)
model.fit(X_train, y_train)

# 预测并填充
predicted_values = model.predict(X_test)
df.loc[df['target_feature'].isna(), 'target_feature'] = predicted_values
关键注意:模型预测填充时,绝对不能将目标变量(坏样本标签)作为预测缺失值的输入特征,否则会造成严重的数据泄露,导致模型过拟合和评估结果虚高。

4.3.3 策略对比与选择

策略 优点 缺点 推荐场景
均值/中位数 简单快速,可解释性强 忽略特征间关系,可能引入偏差 低缺失比例、数据分布稳定
模型预测 利用多特征信息,精度高 计算成本高,需防数据泄露 中高缺失比例、特征间关联强
删除缺失行/列 完全避免填充误差 丢失样本或特征信息 缺失比例极低或极高(> 50%)
缺失值处理决策流程 原始数据含缺失值 统计缺失比例 < 5% 均值/中位数填充 5% - 30% 模型预测填充 > 30% 删除特征/构造指示变量 填充完成的数据集 决策要点: • 低缺失优先用简单填充,避免过度复杂化。 • 中缺失推荐模型预测,但需严格防止数据泄露。 • 高缺失时,构造“是否缺失”指示变量往往比盲目填充更有价值。
实战建议:在 LightGBM 建模前,建议对每个缺失特征同时尝试均值填充和模型预测填充,并对比两种方案在验证集上的 AUC 或 KS 指标。LightGBM 原生支持缺失值处理(默认将缺失值分到增益最大的方向),但在坏样本归因场景中,主动填充往往比依赖模型内部处理更能保留业务语义。