1. 缺失值概述
缺失值是数据预处理中最常见的问题之一。在真实业务场景中,几乎不存在完全干净的数据集。理解缺失值的定义、产生原因及类型,是后续选择填充策略、避免数据偏差的前提。
1.1 缺失值的定义
缺失值(Missing Value)指数据集中某个或某些特征在特定样本上未被记录、不可用或不确定的值。在结构化数据中,通常以 NaN、None、null 或特定占位符(如 -999、Unknown)表示。
关键区分:缺失值 ≠ 零值或空字符串。零值是有意义的数值(如收入为0),空字符串是长度为0的字符数据,而缺失值表示该数据“不存在”或“未观测到”,三者不可混为一谈。
1.2 缺失值的产生原因
缺失原因可归纳为两大类:机械原因与人为原因。下表列出了常见场景及典型示例。
| 类别 | 子类 | 典型场景 | 示例 |
|---|---|---|---|
| 机械原因 | 设备故障 | 传感器失灵、存储介质损坏 | 温度传感器在12:00-13:00期间无读数 |
| 传输中断 | 网络丢包、API超时 | 用户行为日志因网络波动未上传 | |
| 存储限制 | 数据库字段截断、磁盘空间不足 | 长文本被截断导致后半部分缺失 | |
| 人为原因 | 拒绝回答 | 敏感信息(收入、疾病史)被受访者隐瞒 | 问卷调查中“年收入”字段大量空白 |
| 录入错误 | 人工输入遗漏、格式错误后被丢弃 | 身份证号少输一位导致整条记录作废 | |
| 设计缺陷 | 字段可选、条件跳转逻辑不完整 | “配偶姓名”在未婚者中为空(合理缺失) |
实践提示:机械原因导致的缺失通常具有随机性,对模型影响较小;人为原因尤其是“拒绝回答”和“设计缺陷”往往带有系统性偏差,需要结合业务逻辑判断。
1.3 缺失值的三种类型
根据缺失机制与观测数据之间的关系,统计学家将缺失值分为三类。这是选择缺失值处理方法的核心依据。
1.3.1 完全随机缺失(MCAR)
数据缺失的概率与自身取值无关,也与其他任何变量无关。缺失完全由外部随机因素造成。
- 判断标准:缺失组与非缺失组在其他特征上的分布无显著差异。
- 常见场景:实验室样本在运输途中随机打翻;传感器因雷击随机失效。
- 处理方法:可直接删除缺失样本(若比例较小),或使用均值/中位数填充。
1.3.2 随机缺失(MAR)
数据缺失的概率依赖于其他已观测变量,但与缺失变量本身的值无关。这是实际数据中最常见的类型。
- 判断标准:缺失概率可由其他特征预测(如高收入人群更可能隐瞒收入)。
- 常见场景:年龄越大的人越不愿填写“体重”字段;女性更倾向于不回答“吸烟量”。
- 处理方法:利用其他特征进行多重插补、回归填充或模型预测。
1.3.3 非随机缺失(MNAR)
数据缺失的概率与缺失变量本身的值直接相关。即使观测到其他变量,也无法完全解释缺失机制。
- 判断标准:缺失值往往集中在极端值或敏感值上(如极高收入者不填收入)。
- 常见场景:重度抑郁症患者跳过“情绪评估”量表;高负债者不填写“负债金额”。
- 处理方法:最棘手的一类,需引入外部信息、敏感度分析或构建缺失指示变量。
⚠️ 常见误区:很多初学者默认所有缺失都是 MCAR,直接删除或简单填充。若实际为 MAR 或 MNAR,这种做法会引入严重偏差,导致模型估计失真。务必先做缺失模式分析。
1.4 三种缺失类型对比
| 特征 | MCAR | MAR | MNAR |
|---|---|---|---|
| 缺失与自身值的关系 | 无关 | 无关 | 有关 |
| 缺失与其他变量的关系 | 无关 | 有关 | 可能有关,但不足以解释 |
| 可预测性 | 完全随机 | 可由其他变量预测 | 不可完全预测 |
| 处理难度 | 低 | 中 | 高 |
| 典型处理方法 | 删除、简单填充 | 多重插补、模型填充 | 敏感度分析、外部数据 |
1.5 缺失机制分类图
下图展示了三种缺失类型在数据空间中的关系,帮助直观理解缺失机制与观测数据之间的依赖结构。
1.6 缺失模式分析代码示例
在 Python 中,可使用 pandas 和 missingno 快速识别缺失模式。以下代码展示了如何生成缺失矩阵和相关性热图。
import pandas as pd
import numpy as np
import missingno as msno
import matplotlib.pyplot as plt
# 模拟包含缺失值的数据集
np.random.seed(42)
df = pd.DataFrame({
'age': np.random.randint(18, 70, 100).astype(float),
'income': np.random.normal(50000, 15000, 100).astype(float),
'education_years': np.random.randint(6, 22, 100).astype(float),
'credit_score': np.random.randint(300, 850, 100).astype(float)
})
# 人为制造缺失(MCAR:随机删除10%)
for col in df.columns:
mask = np.random.random(100) < 0.1
df.loc[mask, col] = np.nan
# 缺失矩阵可视化
msno.matrix(df)
plt.title('缺失值矩阵(白色=缺失)')
plt.show()
# 缺失相关性热图
msno.heatmap(df)
plt.title('缺失值相关性热图')
plt.show()
# 统计缺失比例
print("各特征缺失比例:")
print(df.isnull().mean().round(3))
💡 分析建议:缺失相关性热图中,若两个特征的缺失区域高度重叠(相关系数接近1),说明它们可能由同一原因导致缺失,应合并处理。若缺失与某个非缺失特征强相关,则提示可能存在 MAR 机制。