本站分享:AI、大数据、数据分析师培训认证考试,包括:Python培训Excel培训Matlab培训SPSS培训SAS培训R语言培训Hadoop培训Amos培训Stata培训Eviews培训

R语言-缺失值处理1_r语言缺失值处理

r语言 cdadata 7841℃

R语言中缺失值处理

前言

在处理数据的过程中,样本往往会包含缺失值。我们有必要对缺失值进行处理,这样不但可以降低预测分析的数据偏差,而且还可以构建有效的模型。本文将简要介绍几种常见的数据缺失值处理方法。

目录

1. 数据准备和模式设定

2. 删除记录

3. 删除变量

4. 用均值/中位数/众数进行插补

5. 预测法

1. 数据准备和模式设定

本文所涉及到的几种数据缺失值处理方法都是使用mlbench包中的BostonHousing数据集作为演示数据。由于BostonHousing数据集没有缺失值,为了演示需要,在数据集中随机插入缺失值。通过这种方法,我们不仅可以评估由数据缺失带来的精度损失,也可以比较不同处理方式的效果好坏。

    # 初始化数据
    # install.packages('mlbench')
    library(mlbench)
    data ("BostonHousing", package="mlbench")
    original <- BostonHousing
    
    # 填充缺失值
    set.seed(100)
    BostonHousing[sample(1:nrow(BostonHousing), 40), "rad"] <- NA
    BostonHousing[sample(1:nrow(BostonHousing), 40), "ptratio"] <- NA

在插入缺失值之后,我们可以使用mice包中md.pattern函数查看缺失值的“数据模式”

    # 缺失值的模式
    library(mice)
    md.pattern(BostonHousing)
    
        crim zn indus chas nox rm age dis tax ptratio b lstat medv rad   
    466    1  1     1    1   1  1   1   1   1       1 1     1    1   1  0
     40    1  1     1    1   1  1   1   1   1       1 1     1    1   0  1
           0  0     0    0   0  0   0   0   0       0 0     0    0  40 40

以下是处理缺失值数据的常见四种方法:

2. 删除记录

如果训练数据集包含有大量的观测值,那么你可以尝试删除包含缺失值的观测行(或者是在构建模型的时候不包含缺失值,例如设置na.action=na.omit)。在删除含有缺失值的观测行之前请确保满足以下两个条件:

  • 有足够样本点
  • 不会引入偏差

举例如下:

    lm(medv ~ ptratio + rad, data=BostonHousing, na.action=na.omit)

3. 删除变量

如果数据集中的某个特定变量包含许多的缺失值,并且通过删除这个特定变量你可以保留许多的观测值。除非该变量是一个非常重要的预测指标,否则我建议你删除它。应用这个方法需要我们在变量的重要性和观测的数量之间做权衡。

4. 用均值/中位数/众数进行插补

处理缺失值数据的一种简单粗暴方法是插补均值、中位数或者众数。在具体环境下,如果该自变量对因变量的影响比较小,那么这种粗略的估计是可以接受的,并且有可能会产生令人满意的结果。

举例如下:

    library(Hmisc)
    impute(BostonHousing$ptratio, mean)  # 插补均值
    impute(BostonHousing$ptratio, median)  # 插补中位数
    impute(BostonHousing$ptratio, 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.65000000 3.91387214 1.97835086 0.09577013 

5. 预测法

用预测值来处理缺失值的一种高级的方法,主要包括:KNN插值,rpart包,mice包

 5.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 
    #>  0.90718277 1.77887569 1.33374499 0.05469914 

与均值插值法相比,mape的值降低了42.8个百分点。

 5.2 rpart

knn插值法的缺点是对因子类变量的插补效果不好。rpart包和mice包提供了更灵活的解决方案。rpart的优点是只需一个未缺失值就可以填充整个数据样本。

对因子变量而言,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.61655453 0.74165850 0.86119597 0.03643275 

与knn插值法相比,mape值又额外下降了33.3%。好极了。

rad的插补精度

    actuals <- original$rad[is.na(BostonHousing$rad)]
    predicteds <- as.numeric(colnames(rad_pred)[apply(rad_pred, 1, which.max)])
    mean(actuals != predicteds)  # 计算误分类比率
    #> 0.2179487

仅有21.7%的缺失值被误分类,这个结果也不坏。

 5.3 mice

mice是链式方程多元插值的简写(Multivariate Imputation by Chained Equations)。mice包提供了多种先进的缺失值处理方法。它使用一种不同寻常的方法来进行两步插值:首先利用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.31000000 0.62950000 0.79341036 0.01984801 

mape值与rpart相比提升了45.8个百分点。

rad的插补精度:

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

误分类比率为30%,也就是说40个缺失观测里插补错误的只有12个。相对rpart方法的错误率(25%)来说,有点稍微的下降。

如果你想更深入的了解,可以查看mice包的手册和DataScience+网站上的另一篇文章。

尽管通过本文你已经对各类处理方法有了初步了解,但这还不足以帮助你判断每种方法的优劣。当你下次处理缺失值的时候,这些方法是值得一试的。

转载请注明:数据分析 » R语言-缺失值处理1_r语言缺失值处理

喜欢 (5)or分享 (0)