京公网安备 11010802034615号
经营许可证编号:京B2-20210330
在处理一些真实数据时,样本中往往会包含缺失值(Missing values)。我们需要对缺失值进行适宜的处理,才能建立更为有效的模型,使得后续预测分析能有更小的偏差。本文将罗列不同的缺失值处理方法,并进行具体应用。
数据准备和缺失模式设定
本文使用mlbench包中的BostonHousing数据集作为示例来演示不同的缺失值处理方法。由于原始的数据集并不包含缺失值,我们需要随机删除一些数据。通过这种方法,我们不仅可以评估由数据缺失带来的精度损失,也可以比较不同处理方式的效果好坏。让我们先加载这个数据集,并随机删除一些数据。
# 加载数据集
data ("BostonHousing", package="mlbench")
original <- BostonHousing # backup original data
# 引入缺失值
set.seed(100)
BostonHousing[sample(1:nrow(BostonHousing), 40), "rad"] <- NA
BostonHousing[sample(1:nrow(BostonHousing), 40), "ptratio"]
#> crim zn indus chas nox rm age dis rad tax ptratio b lstat medv
#> 1 0.00632 18 2.31 0 0.538 6.575 65.2 4.0900 1 296 15.3 396.90 4.98 24.0
#> 2 0.02731 0 7.07 0 0.469 6.421 78.9 4.9671 2 242 17.8 396.90 9.14 21.6
#> 3 0.02729 0 7.07 0 0.469 7.185 61.1 4.9671 2 242 17.8 392.83 4.03 34.7
#> 4 0.03237 0 2.18 0 0.458 6.998 45.8 6.0622 3 222 18.7 394.63 2.94 33.4
#> 5 0.06905 0 2.18 0 0.458 7.147 54.2 6.0622 3 222 18.7 396.90 5.33 36.2
#> 6 0.02985 0 2.18 0 0.458 6.430 58.7 6.0622 3 222
缺失值已经生成好了,尽管我们已经知道哪些位置的数据缺失,但还是用mice包中的md.pattern函数快速检查下。
# 缺失值的模式
library(mice)
md.pattern(BostonHousing) # 返回数据的缺失值的模式
#> crim zn indus chas nox rm age dis tax b lstat medv rad ptratio
#> 431 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0
#> 35 1 1 1 1 1 1 1 1 1 1 1 1 0 1 1
#> 35 1 1 1 1 1 1 1 1 1 1 1 1 1 0 1
#> 5 1 1 1 1 1 1 1 1 1 1 1 1 0 0 2
#> 0 0 0 0 0 0 0 0 0 0 0 0 40 40 80
缺失值处理方法
目前共有四种方法来处理缺失值:
1. 删除观测(记录)
如果你的数据集拥有大量观测,足以用来建立模型,那你可以把包含缺失值的观测删去(或者在建模时选择不纳入这些观测,如设定na.action=na.omit)。在删去相应观测后,请确保:
你有足够的样本点可以用来建模。
没有引入偏差(译者注:即认为这些缺失值是随机产生的,删除对应观测后,样本总体还是一个随机样本而非选择样本)。
# 例子
lm(medv ~ ptratio + rad, data=BostonHousing, na.action=na.omit)
2.删除变量(字段)
如果某个变量包含大量的缺失值,我们可以直接删除这个变量来保留更多的观测,除非这个变量对于模型而言特别重要。应用这个方法需要我们在变量的重要性和观测的数量之间做权衡。
3.用均值、中位数或众数插值
把缺失值用相应变量的均值、中位数或众数替换是一种比较粗糙的处理方法。其可行性也要取决于具体情境,如果变量的数值本身波动比较小或者对相应变量的影响较小,使用这种粗略的插值法才可以得到使人满意的结果。
library(Hmisc)
impute(BostonHousing$ptratio, mean) # 均值替代
impute(BostonHousing$ptratio, median) # 中位数替代
impute(BostonHousing$ptratio, 20) # 用特殊值替代(20)
# 也可以手动插值
BostonHousing$ptratio[is.na(BostonHousing$ptratio)] <- mean(BostonHousing$ptratio, na.rm = T)
让我们看看均值插值的效果
library(DMwR)
actuals <- original$ptratio[is.na(BostonHousing$ptratio)]
predicteds <- rep(mean(BostonHousing$ptratio, na.rm=T), length(actuals))
regr.eval(actuals, predicteds)
#> mae mse rmse mape
#> 1.62324034 4.19306071 2.04769644 0.09545664
4.用预测值插值
用预测值插值是一种比较前沿的方法,我们有很多模型可以实现这个过程,比如KNN插值,rpart还有mice。
4.1. KNN插值
DMwR包中的knnImputation函数会使用k近邻方法来填补缺失值。具体流程如下:对于每个需要插值的观测,先基于欧氏距离找到k个和它最近的观测。再将这k个近邻的数据利用距离逆加权得到插补值,最后用该值替代缺失值。
这种方式的优势在于你只要调用一次函数就能把所有缺失值插补好。该函数会把整个数据框作为参数,你不需要做其他设定。但在使用时请不要把响应变量也一并输入,因为在你对测试集做处理时,你无法用未知的响应变量来插值。
library(DMwR)
knnOutput <- knnImputation(BostonHousing[, !names(BostonHousing) %in% "medv"]) # 使用KNN插值.
anyNA(knnOutput)
#> FALSE
检验该方法的精度
actuals <- original$ptratio[is.na(BostonHousing$ptratio)]
predicteds <- knnOutput[is.na(BostonHousing$ptratio), "ptratio"]
regr.eval(actuals, predicteds)
#> mae mse rmse mape
#> 1.00188715 1.97910183 1.40680554 0.05859526
与均值插值相比,mape的值降低了39个百分点。总体还不错。
4.2 rpart
利用knn插值的局限在于它对于因子类变量的插补效果可能不尽如人意。这种情况下rpart和mice就提供了更灵活的解决方案。rpart的优势是你只需要一个未缺失值就可以插补整个样本。
插值思路是利用rpart(决策树)替代knn来预测缺失值。对于因子类变量而言,我们在调用rpart函数式可以把method设为class(译者注:即用分类树),数值型变量就设定method=anova(回归树)。当然,我们也要避免把响应变量传入函数。
library(rpart)
class_mod <- rpart(rad ~ . - medv, data=BostonHousing[!is.na(BostonHousing$rad), ], method="class", na.action=na.omit) # 因为rad是因子
anova_mod <- rpart(ptratio ~ . - medv, data=BostonHousing[!is.na(BostonHousing$ptratio), ], method="anova", na.action=na.omit) # ptratio是数值变量
rad_pred <- predict(class_mod, BostonHousing[is.na(BostonHousing$rad), ])
ptratio_pred <- predict(anova_mod, BostonHousing[is.na(BostonHousing$ptratio), ])
ptratio的插补精度
actuals <- original$ptratio[is.na(BostonHousing$ptratio)]
predicteds <- ptratio_pred
regr.eval(actuals, predicteds)
#> mae mse rmse mape
#> 0.71061673 0.99693845 0.99846805 0.04099908
与knn相比,mape值又额外下降了30%,可喜可贺。
rad的插补精度
actuals <- original$rad[is.na(BostonHousing$rad)]
predicteds <- as.numeric(colnames(rad_pred)[apply(rad_pred, 1, which.max)])
mean(actuals != predicteds) # 计算误分类比率
#> 0.25
仅有25%的缺失值被误分类,这个结果也不坏。
4.3 mice
mice是链式方程多元插值的简写(Multivariate Imputation by Chained Equations)。R中有个同名包提供了多种先进的缺失值处理方法。它使用一种颇不常见的方法来进行两步插值:先利用mice函数建模再用complete函数生成完整数据。mice(df)操作会返回df的多个完整副本,每个副本都对缺失的数据插补了不同的值。complete()函数则会返回这些数据集中的一个(默认)或多个。让我们看看如何对rad和ptratio两个变量插值:
library(mice)
miceMod <- mice(BostonHousing[, !names(BostonHousing) %in% "medv"], method="rf") # 基于随机森林模型进行mice插值
miceOutput <- complete(miceMod) # 生成完整数据
anyNA(miceOutput)
#> FALSE
计算ptratio的插值精度:
actuals <- original$ptratio[is.na(BostonHousing$ptratio)]
predicteds <- miceOutput[is.na(BostonHousing$ptratio), "ptratio"]
regr.eval(actuals, predicteds)
#> mae mse rmse mape
#> 0.36500000 0.78100000 0.88374204 0.02121326
mape值与rpart相比又提升了48个百分点,亦可赛艇。
再看看rad的插值效果:
actuals <- original$rad[is.na(BostonHousing$rad)]
predicteds <- miceOutput[is.na(BostonHousing$rad), "rad"]
mean(actuals != predicteds) # compute misclass error.
#> 0.15
误分类比率降低到了15%,也就是说40个缺失观测里插补错误的只有6个。相较于rpart的错误率(25%),这是一个了不起的提升。
如果你想了解的更深入,这里是mice包的 手册 和DataScience+上另一篇关于mice包的 文章 。
尽管通过本文你已经对各类处理方法有了初步了解,可这些还不足以帮助你判断每种方法的优劣。但当你下次处理缺失值的时候,逐一测试这些方法是值得一试的。数据分析师培训
数据分析咨询请扫描二维码
若不方便扫码,搜微信号:CDAshujufenxi
在数字化时代,用户是产品的核心资产,用户运营的本质的是通过科学的指标监测、分析与优化,实现“拉新、促活、留存、转化、复购 ...
2026-04-15在企业数字化转型、系统架构设计、数据治理与AI落地过程中,数据模型、本体模型、业务模型是三大核心基础模型,三者相互支撑、各 ...
2026-04-15数据分析师的一天,80%的时间花在表格数据上,但80%的坑也踩在表格数据上。 如果你分不清数值型和文本型的区别,不知道数据从哪 ...
2026-04-15在人工智能与机器学习落地过程中,模型质量直接决定了应用效果的优劣——无论是分类、回归、生成式模型,还是推荐、预测类模型, ...
2026-04-14在Python网络编程、接口测试、爬虫开发等场景中,HTTP请求的发送与响应处理是核心需求。Requests库作为Python生态中最流行的HTTP ...
2026-04-14 很多新人学完Python、SQL,拿到一张Excel表还是不知从何下手。 其实,90%的商业分析问题,都藏在表格的结构里。 ” 引言:为 ...
2026-04-14在回归分析中,因子(即自变量)的筛选是构建高效、可靠回归模型的核心步骤——实际分析场景中,往往存在多个候选因子,其中部分 ...
2026-04-13在机器学习模型开发过程中,过拟合是制约模型泛化能力的核心痛点——模型过度学习训练数据中的噪声与偶然细节,导致在训练集上表 ...
2026-04-13在数据驱动商业升级的今天,商业数据分析已成为企业精细化运营、科学决策的核心手段,而一套规范、高效的商业数据分析总体流程, ...
2026-04-13主讲人简介 张冲,海归统计学硕士,CDA 认证数据分析师,前云南白药集团资深数据分析师,自媒体 Python 讲师,全网课程播放量破 ...
2026-04-13在数据可视化与业务分析中,同比分析是衡量业务发展趋势、识别周期波动的核心手段,其核心逻辑是将当前周期数据与上年同期数据进 ...
2026-04-13在机器学习模型的落地应用中,预测精度并非衡量模型可靠性的唯一标准,不确定性分析同样不可或缺。尤其是在医疗诊断、自动驾驶、 ...
2026-04-10数据本身是沉默的,唯有通过有效的呈现方式,才能让其背后的规律、趋势与价值被看见、被理解、被运用。统计制图(数据可视化)作 ...
2026-04-10在全球化深度发展的今天,跨文化传播已成为连接不同文明、促进多元共生的核心纽带,其研究核心围绕“信息传递、文化解读、意义建 ...
2026-04-09在数据可视化领域,折线图是展示时序数据、趋势变化的核心图表类型之一,其简洁的线条的能够清晰呈现数据的起伏规律。Python ECh ...
2026-04-09在数据驱动的时代,数据分析早已不是“凭经验、靠感觉”的零散操作,而是一套具备固定逻辑、标准化流程的系统方法——这就是数据 ...
2026-04-09长短期记忆网络(LSTM)作为循环神经网络(RNN)的重要改进模型,凭借其独特的门控机制(遗忘门、输入门、输出门),有效解决了 ...
2026-04-08在数据分析全流程中,数据质量是决定分析结论可靠性的核心前提,而异常值作为数据集中的“异类”,往往会干扰统计检验、模型训练 ...
2026-04-08在数字经济飞速发展的今天,数据已渗透到各行各业的核心场景,成为解读趋势、优化决策、创造价值的核心载体。而数据分析,作为挖 ...
2026-04-08在数据分析全流程中,数据处理是基础,图形可视化是核心呈现手段——前者负责将杂乱无章的原始数据转化为干净、规范、可分析的格 ...
2026-04-07