数据填补诊断图:用可视化结合数据分布检查缺失值填补质量

机器学习大数据算法

picture.image

背景

picture.image

picture.image

picture.image

picture.image

该篇文章灵感来自R中的mice包提供的一种诊断图,帮助检查插补后的数据质量。这些诊断图通常用于评估插补结果的可靠性和稳定性,以确保插补过程中的一致性和合理性。这些图形可能包括插补值的分布、插补前后的数据对比等。其主要思想是,好的插补数据应该具有和观测数据相同的分布。如果观测数据和插补数据的分布相差很大,那么缺失数据可能是非随机缺失,这是诊断图的核心思想

该包本身实现的是MICE(多重数据插补)方法。多重插补可以通过生成多个填补数据集,来对缺失值进行多次插补,从而得到多个不同的结果。这种方法允许不同的变量使用不同的插补方法进行处理,从而降低误差并获得更为准确的结果。不过,在此不深入介绍该方法的细节感兴趣的读者可以参考——stefvanbuuren.name/fimd/foreword.html,而是重点讲解如何通过诊断图的思想来评估插补效果。通过这些诊断图,可以评估插补效果,并在实际应用中,采用如 KNN 填补、随机森林(RF)填补等方法,通过相应的诊断图来进一步判断插补结果的质量,如这里的参考文献也考虑该种思想——填充数据分布与原始数据一致

代码实现

数据读取


          
import pandas as pd
          
import numpy as np
          
import matplotlib.pyplot as plt
          
plt.rcParams['font.family'] = 'Times New Roman'
          
plt.rcParams['axes.unicode_minus'] = False
          
import warnings
          
# 忽略所有警告
          
warnings.filterwarnings("ignore")
          
df = pd.read_excel('2025-2-5公众号Python机器学习AI.xlsx')
          
df
      

picture.image

读取一个 Excel 文件 2025-2-5公众号Python机器学习AI.xlsx,并将其加载到名为 df 的 DataFrame 中;同时设置了绘图的字体样式并忽略了所有警告。需要注意的是,该数据集只是模拟数据集,并没有任何现实意义

缺失值情况反馈


          
# 计算每个特征的缺失值数量和缺失率
          
missing_data = df.isnull().sum()  # 计算每列的缺失值数量
          
missing_rate = missing_data / len(df) * 100  # 计算每列的缺失率
          

          
# 构建结果 DataFrame
          
missing_summary = pd.DataFrame({
          
    '变量': missing_data.index,
          
    '缺失量(n)': missing_data.values,
          
    '缺失率(%)': missing_rate.values
          
})
          
# 按照缺失量(n)进行降序排序
          
missing_summary_sorted = missing_summary.sort_values(by='缺失量(n)', ascending=False)
          
missing_summary_sorted
      

picture.image

计算数据集中每个特征的缺失值数量和缺失率,并将其整理成一个 DataFrame,按缺失量降序排列,以便分析哪些特征缺失较严重

KNN数据填补


          
from sklearn.impute import KNNImputer
          
# 初始化KNNImputer
          
imputer = KNNImputer(n_neighbors=5)  # n_neighbors指定KNN算法中的K值,默认为5
          
# 对df_filtered进行KNN填补
          
df_imputed = pd.DataFrame(imputer.fit_transform(df), columns=df.columns)
          
df_imputed.head()
      

picture.image

使用 K 近邻(KNN)插补方法(KNNImputer)对数据集 df 进行缺失值填补,其中 n_neighbors=5 表示使用 5 个最近邻的均值来替代缺失值,并将填补后的数据转换回 DataFrame 格式

诊断图一


          
# 获取原始数据和填补后的数据
          
original_data = df['BMI']
          
imputed_data = df_imputed['BMI']
          

          
# 标记原始数据中的缺失值
          
missing_mask = original_data.isnull()
          

          
# 设置图形尺寸
          
plt.figure(figsize=(8, 6), dpi=1200)
          

          
# 设置抖动强度
          
jitter_strength = 0.05
          

          
# 绘制原始数据中的非缺失值(蓝色),x=0
          
plt.scatter(np.random.normal(0, jitter_strength, size=len(original_data[~missing_mask])), 
          
            original_data[~missing_mask], color='blue', alpha=0.5, facecolors='none', s=100, marker='o', label="Original Data")
          

          
# 绘制原始数据中的非缺失值(蓝色),x=1
          
plt.scatter(np.random.normal(1, jitter_strength, size=len(imputed_data[~missing_mask])), 
          
            original_data[~missing_mask], color='blue', alpha=0.5, facecolors='none', s=100, marker='o')
          

          
# 绘制填补后的数据(红色),x=1
          
plt.scatter(np.random.normal(1, jitter_strength, size=len(imputed_data[missing_mask])), 
          
            imputed_data[missing_mask], color='red', alpha=0.5, facecolors='none', s=100, marker='o', label="Imputed Data")
          

          
# 设置x轴刻度
          
plt.xticks([0, 1], ['Original Data', 'Imputed Data'])
          

          
# 设置图形的标签和标题,字体加大和加粗
          
plt.xlabel('Data Type', fontsize=14, fontweight='bold')
          
plt.ylabel('BMI', fontsize=14, fontweight='bold')
          
plt.title('BMI: Original vs Imputed Data', fontsize=16, fontweight='bold')
          
# 显示图例,并将图例位置设置为左上角
          
plt.legend(fontsize=12, loc='upper left')
          
plt.savefig("BMI: Original vs Imputed Data.pdf", format='pdf', bbox_inches='tight')
          
plt.show()
      

picture.image

绘制了原始数据与填补后的数据(BMI)的对比图,原始数据的非缺失值以蓝色显示,填补后的数据以红色显示,当插补的数据和观测数据的重合度非常高时,说明插补质量好,下面为所有特征的诊断图

picture.image

诊断图二


          
import seaborn as sns
          

          
# 获取原始数据和填补后的数据
          
original_data = df['BMI']
          
imputed_data = df_imputed['BMI'] 
          

          
# 设置图形尺寸
          
plt.figure(figsize=(10, 6), dpi=1200)
          

          
# 绘制填补后的数据的密度曲线(红色)
          
sns.kdeplot(imputed_data, color='red', legend=False)
          

          
# 绘制原始数据的密度曲线(蓝色),放在最上层
          
sns.kdeplot(original_data.dropna(), color='blue', legend=False)
          

          
# 设置图形的标签和标题,字体加粗
          
plt.xlabel('bmi', fontsize=14, fontweight='bold')
          
plt.ylabel('Density', fontsize=14, fontweight='bold')
          
plt.title('bmi: Original vs Imputed Data (Density Curves)', fontsize=16, fontweight='bold')
          
plt.savefig("bmi Original vs Imputed Data (Density Curves).pdf", format='pdf', bbox_inches='tight')
          
plt.show()
      

picture.image

绘制原始数据与填补后的数据的密度曲线对比图。通过对比蓝色(原始数据)和红色(填补数据)的曲线,可以看出填补后的数据在分布上与原始数据相似,表明填补结果较为合理且质量较好,未明显偏离原始数据的分布,下面为所有特征的诊断图

picture.image

按照 插补数据应该具有和观测数据相同的分布的思想所以可以不局限于这些可视化,只要能反馈数据的分布都可以作为“诊断图”,同时也可以绘制不同的数据缺失填补方法在一个诊断图上来比较各自的填补效果,如下图

picture.image

picture.image

这里就同时把KNN、RF填补数据集的方法绘制在一个诊断图上,以此来判断不同填补方法对于填补效果也就是原始数据和插补数据分布是否一致,从而选出相对来说在此规则下最好的填补方法,和下面文献描述的思想一致,实际上可以发现对于特征AGR在第一种诊断图上明显存在一定的偏离群体说明可以着重考虑且RF填补偏离高于KNN填补,完整 代码与数据集获取:如需获取本文的源代码和数据集,请添加作者微信联系

picture.image

往期推荐

SHAP值+模型预测概率解读机器学习模型的决策过程

聚类与解释的结合:利用K-Means聚类辅助SHAP模型解释并可视化

期刊配图:RFE结合随机森林与K折交叉验证的特征筛选可视化

期刊配图:变量重要性排序与顺序正向选择的特征筛选可视化

期刊配图:SHAP可视化改进依赖图+拟合线+边缘密度+分组对比

期刊配图:SHAP蜂巢图与柱状图多维组合解读特征对模型的影响

基于mRMR筛选和递归特征选择的多模型性能评估与AUC可视化对比

期刊配图:SHAP可视化进阶蜂巢图与特征重要性环形图的联合展示方法

期刊配图:基于t-sne降维与模型预测概率的分类效果可视化

期刊配图:多种机器学习算法在递归特征筛选中的性能变化图示

picture.image

如果你对类似于这样的文章感兴趣。

欢迎关注、点赞、转发~

个人观点,仅供参考

0
0
0
0
关于作者

文章

0

获赞

0

收藏

0

相关资源
字节跳动 XR 技术的探索与实践
火山引擎开发者社区技术大讲堂第二期邀请到了火山引擎 XR 技术负责人和火山引擎创作 CV 技术负责人,为大家分享字节跳动积累的前沿视觉技术及内外部的应用实践,揭秘现代炫酷的视觉效果背后的技术实现。
相关产品
评论
未登录
看完啦,登录分享一下感受吧~
暂无评论