R语言数据分析与挖掘(第一章):数据预处理(2)——缺失值常用的处理方法
- 2019 年 10 月 7 日
- 筆記
上一篇文章(缺失值处理)介绍了缺失值处理的判断方法,这一讲接着介绍缺失值常用的几种处理方法:删除法,替换法和插补法。不同的方法对应不同类型的缺失值。
1.删除法
如果缺失值的比例很小,且不影响整体的数据结构,即缺失值类型是完全随机缺失时,可以考虑将缺失值删除,该方法操作非常简单,使用函数na.omit()就可以将含有缺失值的行删除。其函数的基本书写格式为:
na .omit (object,....)
其中object即为需要处理的数据对象。下面我们对algae数据集进行处理:
> algae=na.omit(algae) > sum(is.na(algae)) [1] 0
上一篇文章中,我们介绍到该数据集有33个缺失值,删除后,现在为0了。
除了na.omit()函数外,还可以利用complete.cases函数来删除含有缺失值的行。
> # 因为上一句代码已经删除过,这里重新加载原始数据 > data(algae) > algae<-algae[complete.cases(algae),] > sum(!complete.cases(algae)) [1] 0
2.替换法
直接删除含有缺失值的行记录的代价和风险较大,故我们可以考虑将缺失值部分替换掉,如用均值去替换,即均值替换法,该方法根据变量的不同类型选择不同的替换,对数值型变量采用均值替换,对非数值型变量采用众数替换。
下面我们将对algae数据集采用均值替换处理缺失值:
> data(algae) > mean(complete.cases(algae)) [1] 0.92 > algae[is.na(algae)]<-mean(complete.cases(algae)) > sum(!complete.cases(algae)) [1] 0
但是均值替换法还是存在一些问题,因为该方法适用于处理完全随机缺失数据,且会改变整体数据的统计性质,比如方差变小,存在偏差等,因此在在实践中并不常用。
3.插补法
实战中常用的方法是插补法,随机插补的思想类似,利用非缺失数据的均值或者随机数来填补缺失值,下面我们详细介绍多重插补。
多重插补的主要思想是:利用蒙特卡洛模拟法(MCMC)将原始数据集插补成几个完整数据集,在每个新数据集中利用线性回归(lm)或广义线性回归(glm)等方法进行插补建模,再将这些完整的模型整合到一起,评价插补模型的优劣并返回完数据集。
该方法主要利用mice包中的函数mice进行,其函数的基本书写格式为,
mice(data,m=5,method=vector("character",length =ncol (data)),seed = NA, defaultMethod = c("pmm","logreg","polyreg","polr"),....)
参数介绍:
data一个包含完整数据和缺失数据的矩阵或数据框,其中各缺失数据用符号NA表示;
m:指定的多正插补数,默认值为5;
method:一个字符串,或者长度与数据集列数相同的字符串向量,用于指定数据集中的每一列采用的插补方法,单一字符串指定所有列用相同方法插补,字符串向量指定不同列采用不同方法插补,默认插补法取决需要插补的目标列,并由defaulmethod指定参数;
seed:一个整数,用于函数set.seed()的参数,指定产生固定的随机数的个数,默认值为NA;
defaultMethod:一个向量,用于指定每个数据集采用的插补建模方法,可供选者的方法有多种,“pmm”表示用预测的均值匹配,“logreg”表示用逻批回归拟合,“polyreg”表示多项式拟合,“polr”表示采用比例优势模型拟合等。
需要注意的是:选择不同的插补建模方法对数据有不同的要求,回归法适用于数值型数据集,“pmm”对数据格式没有特殊要求。在实战过程中我们还会用到函数pool()、函数compute()等。下面我们将用到一些回归知识, 有疑感的话先放着,后面分析数据时我们会深入了解。
> imp<-mice(algae[,4:11],seed=1234) iter imp variable 1 1 1 2 1 3 1 4 1 5 2 1 2 2 2 3 2 4 2 5 3 1 3 2 3 3 3 4 3 5 4 1 4 2 4 3 4 4 4 5 5 1 5 2 5 3 5 4 5 5 > fit <- with(imp,lm(mxPH~.,data = algae[,4:11])) > pool=pool(fit) > options(digits=3) # 设定输出结果保留3位小数。 > summary(pool) estimate std.error statistic df p.value (Intercept) 7.90e+00 2.49e-01 31.735 190 0.00e+00 mnO2 -1.43e-02 2.39e-02 -0.598 190 5.51e-01 Cl 2.20e-03 1.32e-03 1.669 190 9.68e-02 NO3 -2.15e-02 2.18e-02 -0.986 190 3.25e-01 NH4 -1.75e-05 4.08e-05 -0.429 190 6.69e-01 oPO4 1.36e-03 1.50e-03 0.908 190 3.65e-01 PO4 -5.96e-04 1.14e-03 -0.522 190 6.02e-01 Chla 1.31e-02 2.82e-03 4.654 190 6.10e-06
上述代码表示:
首先创建一个imp对象,该对象是包含4个插补对象的列表,使用的数据为algae数据集中含有缺失值的第4到11列数据,默认插补查补数据集为5个;然后创建fit对象,用于设定统计分析方法,这里指定线性回归,则fit是一个包含4个统计分析结果的列表对象;再创建pool 对象,该对象将前面的四个统计分析结果汇总;最后用summary函数显示pool的统计信息,指定输出结果保留3位小数。
插补完后,对插补数据和原始数据进行对比,利用mice包中的函数stripplot()对变量分布图进行可视化。
algae_complete=complete(imp,action=1) sum(is.na(algae_complete)) par(mfrow=c(3,3)) stripplot(imp,pch=c(1,8),col=c("grey","1")) par(mfrow=c(1,1)

缺失值处理是一个不容易的工程,我们在数据挖掘中可选择对缺失数据不敏感的方法,比如决策树,这样就省略了缺失值处理的步骤。如果对于数据敏感的方法,还是要处理的哦!!