机器学习数据清洗实战当银行贷款数据遇到x1-x6缺失我用均值填充还是中位数在金融风控领域数据质量直接决定模型预测的可靠性。当我们拿到一份包含x1-x6数值型变量的银行贷款审批数据时面对缺失值的第一反应往往是用均值填充。但真实业务场景中这种直觉选择可能暗藏陷阱——某银行风控团队曾因盲目使用均值填充收入字段导致模型低估了高净值客户的违约风险造成数百万损失。本文将带您穿透统计概念的表面从数据分布、业务逻辑和代码实现三个维度彻底掌握缺失值填充的策略选择艺术。1. 为什么填充策略不能一刀切金融数据的复杂性在于其非对称性和业务敏感性。以常见的收入x1、负债比x2变量为例收入分布通常呈现右偏态少数高收入客户会显著拉高均值负债比集中在某个区间但极端低值可能反映数据采集错误业务影响收入填充过高会导致风险被低估填充过低则影响优质客户审批import seaborn as sns import matplotlib.pyplot as plt # 加载示例数据 df pd.read_excel(银行贷款审批数据.xlsx) # 绘制x1-x6的分布特征 fig, axes plt.subplots(2, 3, figsize(15,8)) for i, col in enumerate(df.columns[:6]): sns.histplot(df[col], kdeTrue, axaxes[i//3, i%3]) axes[i//3, i%3].set_title(f{col} Distribution) plt.tight_layout()提示在Jupyter Notebook中运行上述代码时若发现某个变量的偏度(skewness)绝对值大于1就需要警惕均值填充的适用性2. 均值vs中位数从数学原理到业务选择2.1 统计特性对比指标均值中位数计算方式所有值的算术平均排序后的中间值优点充分利用所有数据信息不受极端值影响缺点对异常值敏感忽略数值间的实际差异适用场景对称分布数据偏态分布数据金融案例信用卡平均消费额个人年度收入报告2.2 Python实现决策流程from scipy import stats import numpy as np def choose_filler(series): 智能选择填充策略 # 检查缺失比例 missing_rate series.isna().mean() if missing_rate 0.3: raise ValueError(缺失率超过30%建议考虑删除该特征) # 分析分布特征 skew stats.skew(series.dropna()) if abs(skew) 1: print(f检测到偏度系数{skew:.2f}推荐使用中位数填充) return series.median() else: print(分布相对对称使用均值填充) return series.mean() # 应用示例 for col in [x1, x2, x3, x4, x5, x6]: filler choose_filler(df[col]) df[col].fillna(filler, inplaceTrue)3. 名义变量的陷阱当mode不止一个对于x7-x15这类名义变量如职业类型、教育程度最频繁值(mode)填充看似简单但实际操作中会遇到多众数问题多个值出现频率相同隐含排序如学历名义上无序但业务上存在隐含等级稀有类别某些类别样本极少填充可能引入偏差改进方案# 改进的mode填充方案 for col in df.columns[6:15]: modes df[col].mode() if len(modes) 1: # 选择与目标变量y相关性最强的mode corr [df[df[col]mode][y].mean() for mode in modes] best_mode modes[np.argmax(corr)] else: best_mode modes[0] df[col].fillna(best_mode, inplaceTrue)4. 高级技巧基于模型的智能填充对于追求极致效果的数据科学家可以考虑更高级的填充策略KNN填充基于相似样本的特征值进行填充from sklearn.impute import KNNImputer imputer KNNImputer(n_neighbors5) df[[x1,x2,x3]] imputer.fit_transform(df[[x1,x2,x3]])随机森林填充利用特征间的非线性关系from sklearn.ensemble import RandomForestRegressor # 以x1为例用其他特征预测缺失值 known df[df[x1].notna()] unknown df[df[x1].isna()] model RandomForestRegressor().fit(known[[x2,x3]], known[x1]) df.loc[df[x1].isna(), x1] model.predict(unknown[[x2,x3]])多重插补通过多次模拟生成更稳健的填充值from sklearn.experimental import enable_iterative_imputer from sklearn.impute import IterativeImputer imp IterativeImputer(max_iter10) df[[x1,x2]] imp.fit_transform(df[[x1,x2]])5. 业务验证填充后的数据质量检查完成填充后必须进行三层次验证分布一致性检验# 比较填充前后分布变化 plt.figure(figsize(10,4)) plt.subplot(121) sns.histplot(df[x1].dropna(), colorblue, labelOriginal) plt.subplot(122) sns.histplot(df[x1], colorred, labelAfter Imputation)变量关系验证# 检查填充值与y的关系是否合理 pd.crosstab(df[x7], df[y]).plot(kindbar)业务逻辑校验检查填充后的极端值是否符合业务常识验证关键指标如平均收入是否在合理范围内与业务专家讨论特殊案例的处理方式在一次消费金融项目中我们通过上述方法发现使用中位数填充收入字段后模型在20-30万收入区间的预测准确率提升了7个百分点这正是因为避免了少数超高收入者对均值的扭曲影响。