R |数据分析中缺失值处理

8dc219a13a8769aa8da374846d1cea63.png

数据分析中缺失值处理

缺失值(NA)是一个非常常见的问题,特别是在大样本的研究中。与其删除整个被试的数据,不如试试插值的方法。本文简单介绍了几种缺失值处理的方法。

数据-Boston Housing

人为引入缺失值,这样就可以比较各种插值方法的结果和实际原始数据的差别。

data ("BostonHousing", package="mlbench")  # initialize the data  # load the data
original <- BostonHousing  # backup original data
# Introduce missing values
set.seed(100)
BostonHousing[sample(1:nrow(BostonHousing), 40), "rad"] <- NA
BostonHousing[sample(1:nrow(BostonHousing), 40), "ptratio"] <- NA
head(BostonHousing)
#>      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    18.7 394.12  5.21 28.7

使用mice的md.pattern可以快速获得缺失值的统计

library(mice)
md.pattern(BostonHousing)  # pattern or missing values in data.
#>     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)包含缺失值的样本(行)。

2.删除变量

如果某个变量包含过多缺失值并且删除该变量可以保存更多的样本,可以考虑删除该变量。

3.用均值/中位数/众数插值

最简单的方法,容易操作而且结果还不错。

library(Hmisc)
impute(BostonHousing$ptratio, mean)  # replace with mean
impute(BostonHousing$ptratio, median)  # median
impute(BostonHousing$ptratio, 20)  # replace specific number
# or if you want to impute manually
BostonHousing$ptratio[is.na(BostonHousing$ptratio)] <- mean(BostonHousing$ptratio, na.rm = T)  # not run
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.模型插值

4.1. kNN插值

DMwR :: knnImputation使用k-Nearest Neighbours方法来插补缺失值。对于要插值的每个观测值,它基于欧氏距离确定“ k”个最接近的观测值,并计算这些“ k”个观测值的加权平均值(基于距离加权)。简单的理解就是找到最近的几个邻居,使用它们的数据进行插值。

优点:一次插值所有缺失值 

缺点:无法处理factor类型的变量

注意:  计算kNN的时候不能包括响应变量(y)

library(DMwR)
knnOutput <- knnImputation(BostonHousing[, !names(BostonHousing) %in% "medv"])  # perform knn imputation.
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

rpart和mice都可以处理factor的变量,在调用rpart()时设置method = class。对于numeric,使用method = anova。

注意: 同样的不能在不能在响应变量(例子中的medv)上训练rpart。

library(rpart)
class_mod <- rpart(rad ~ . - medv, data=BostonHousing[!is.na(BostonHousing$rad), ], method="class", na.action=na.omit)  # since rad is a factor
anova_mod <- rpart(ptratio ~ . - medv, data=BostonHousing[!is.na(BostonHousing$ptratio), ], method="anova", na.action=na.omit)  # since ptratio is numeric.
rad_pred <- predict(class_mod, BostonHousing[is.na(BostonHousing$rad), ])
ptratio_pred <- predict(anova_mod, BostonHousing[is.na(BostonHousing$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

与knImputation相比,平均绝对百分比误差(mape)另外提高了约30%。

actuals <- original$rad[is.na(BostonHousing$rad)]
predicteds <- as.numeric(colnames(rad_pred)[apply(rad_pred, 1, which.max)])
mean(actuals != predicteds)  # compute misclass error.
#> 0.25

这会产生25%的误分类误差。

4.3. mice

Multivariate Imputation by Chained Equations

首先使用mice()构建模型,并使用complete()生成完成的数据。类似于sklearn里的fit + transform的操作。mice(df)函数可产生多组数据每组数据有对缺失数据的不同估算。complete()函数返回一个或多个这些数据集,默认为第一个。

library(mice)
miceMod <- mice(BostonHousing[, !names(BostonHousing) %in% "medv"], method="rf")  # perform mice imputation, based on random forests.
miceOutput <- complete(miceMod)  # generate the completed data.
anyNA(miceOutput)
#> FALSE
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

与rpart相比,平均绝对百分比误差(mape)另外提高了〜48%

actuals <- original$rad[is.na(BostonHousing$rad)]
predicteds <- miceOutput[is.na(BostonHousing$rad), "rad"]
mean(actuals != predicteds)  # compute misclass error.
#> 0.15

错误分类错误减少到15%,与rpart的25%相比,是一个很大的进步。

来源

http://r-statistics.co/Missing-Value-Treatment-With-R.html


d56c26ade984342ac2b31ec43f3095e4.png

c1cb77ce55b7007ed9f829d0dcab1d50.png

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值