R语言学习系列15缺失值处理方法.docx
- 文档编号:23912665
- 上传时间:2023-05-22
- 格式:DOCX
- 页数:13
- 大小:175.96KB
R语言学习系列15缺失值处理方法.docx
《R语言学习系列15缺失值处理方法.docx》由会员分享,可在线阅读,更多相关《R语言学习系列15缺失值处理方法.docx(13页珍藏版)》请在冰豆网上搜索。
R语言学习系列15缺失值处理方法
15.缺失值处理方法
目录:
一.直接删除法
二.用均值/中位数/众数填补
三.探索变量的相关性插补
四.探索样本的相似性填补
五.分类树与回归树预测法插补(rpart包)
六.多重插补法(mice包)
正文:
一、直接删除法
即直接删除含有缺失值的样本,有时最为简单有效,但前提是缺失数据的比例较少,且缺失数据是随机出现的,这样删除缺失数据后对分析结果影响不大。
1.向量删除缺失值
x<-c(1,2,3,NA,5)
mean(x)#默认不忽略NA值或NaN值,注意与NULL的区别
[1]NA
mean(x,na.rm=TRUE)#忽略缺失值
[1]2.75
x1<-x[!
is.na(x)]#去掉向量中的NA值
x1
[1]1235
x2<-na.omit(x)#返回去掉NA值的向量
x2
[1]1235
attr(,"na.action")
[1]4
attr(,"class")
[1]"omit"
na.fail(x)#若向量有NA值,则返回Error
Errorinna.fail.default(x):
对象里有遺漏值
na.fail(x1)#若向量不含NA值,则返回该向量
[1]1235
attr(na.omit(x),"na.action")#返回向量中NA值的下标
[1]4
attr(,"class")
[1]"omit"
x[is.na(x)]<-0#将向量x中的NA值替换为0
x
[1]12305
2.删除含缺失值的样本数据
用DMwR包实现。
library(DMwR)#用自带数据集algae,18个变量,200个观测值
library(VIM)
sum(!
complete.cases(algae))#查看含有缺失值的样本个数
[1]16
algae1<-na.omit(algae)#直接删除所有含缺失值的样本
sum(!
complete.cases(algae1))
[1]0
#只删除缺失值过多的样本:
缺失值个数大于列数的20%
algae2<-algae[-manyNAs(algae,0.2),]#数据框的“删除行”操作
sum(!
complete.cases(algae2))
[1]14
其中,函数manyNAs(x,nORp)用来查找数据框x中缺失值过多(≥缺失比例nORp)的行;nORp默认为0.2,即缺失值个数≥列数的20%
注:
当删除缺失数据会改变数据结构时,通过对完整数据按照不同的权重进行加权,可以降低删除缺失数据带来的偏差。
3.删除变量
若数据的某变量(列)有较多的缺失值且对研究目标影响不大时,可以将整列删除,这需要在变量的重要性和观测的数量之间做权衡。
4.做统计分析时排除缺失值
例如,做线性回归时,设置na.action=na.omit即可:
lm(medv~ptratio+rad,data=BostonHousing,na.action=na.omit)
二、用均值/中位数/众数填补
其优点在于不会减少样本信息,处理简单;其缺点在于当缺失数据不是随机出现时会产成偏误。
若某自变量对因变量的影响比较小,那么这种粗略的估计是可以接受的,且有可能会产生令人满意的结果。
使用mlbench包中的BostonHousing数据集作为演示数据。
由于BostonHousing数据集没有缺失值,为了演示需要,在数据集中随机插入缺失值。
通过这种方法,不仅可以评估由数据缺失带来的精度损失,也可以比较不同处理方式的效果好坏。
#初始化数据集
library(mlbench)
data("BostonHousing",package="mlbench")
treated<-BostonHousing#14个变量,506个观测值
#填充缺失值(随机替换两个变量各40个NA)
set.seed(100)
treated[sample(1:
nrow(treated),40),"rad"]<-NA
treated[sample(1:
nrow(treated),40),"ptratio"]<-NA
#查看缺失状况
sum(!
complete.cases(treated))#查看缺失值数目
[1]75
library(mice)
md.pattern(treated)#查看缺失模式
crimzninduschasnoxrmagedistaxblstatmedvradptratio
431111111111111110
35111111111111011
35111111111111101
5111111111111002
000000000000404080
用均值/中位数/众数填补的代码实现:
library(Hmisc)
treated$ptratio=impute(treated$ptratio,mean)#插补均值
treated$ptratio=impute(treated$ptratio,median)#插补中位数
treated$ptratio=impute(treated$ptratio,20.2)#填充特定值
treated$ptratio[is.na(treated$ptratio)]
<-mean(treated$ptratio,na.rm=T)#手动插补均值
#计算均值和中位数插补的准确度
library(DMwR)
actuals<-BostonHousing$ptratio[is.na(treated$ptratio)]
predicteds1<-rep(mean(treated$ptratio,na.rm=TRUE),length(actuals))
regr.eval(actuals,predicteds1)
maemsermsemape
1.623240344.193060712.047696440.09545664
predicteds2<-rep(median(treated$ptratio,na.rm=TRUE),length(actuals))
regr.eval(actuals,predicteds2)
maemsermsemape
1.635000004.786000002.187692850.09933331
注1:
R语言中没有直接求众数的函数,可用sort(table(x))先求频数再排序观察到,再用特定值填充。
注2:
函数regr.eval()用来返回真实值与预测值差异的若干统计量:
mae为平均绝对误差;mse为均方误差;rmse为均方根误差;mape为平均绝对百分误差。
另外,DMwR包中提供了函数centralImputation(),可以用数据的中心趋势值来填补缺失值:
数值型变量使用中位数,名义变量使用众数。
三、探索变量的相关性插补
探寻变量之间的相关关系,找到相关性较高的两个变量后,再寻找他们之间的线性回归关系,最后通过线性回归关系计算缺失值进行填补。
1.探寻变量之间的相关关系
使用上一篇中的方法,或者
library(DMwR)
symnum(cor(algae[,4:
18],use="complete.obs"))
mPmOClNONHoPCha1a2a3a4a5a6a7
mxPH1
mnO21
Cl1
NO31
NH4,1
oPO4..1
PO4..*1
Chla.1
a1...1
a2..1
a31
a4...1
a51
a6...1
a71
attr(,"legend")
[1]0‘’0.3‘.’0.6‘,’0.8‘+’0.9‘*’0.95‘B’1
注:
函数cor()的用来产生变量之间的相关值矩阵,设定参数use="complete.obs"可以使R在计算相关值时忽略含有NA值的样本。
函数symnum()是用来改善结果的输出形式的。
可见变量oPO4和PO4,a1和a4可能有较强的线性相关关系。
2.先得到回归关系
lm(PO4~oPO4,data=algae,na.action=na.omit)
Coefficients:
(Intercept)oPO4
42.8971.293
可见变量PO4与oPO4之间的线性回归关系为:
PO4=1.293*oPO4+42.897
3.利用回归关系计算缺失值进行插补
#构造函数计算缺失值
fillPO4<-function(x)
{
if(is.na(x))return(NA)else
return(1.293*x+42.897)
}
#使用sapply函数对缺失值进行插补
algae[is.na(algae$PO4),"PO4"]<-sapply(algae[is.na(algae$PO4),"oPO4"],fillPO4)
四、探索样本的相似性填补
利用多个样本(行)之间的相似性填补缺失值。
度量相似性的指标有很多,常用的是欧氏距离。
DMwR包中的函数knnImputation()使用k近邻方法来填充缺失值。
具体过程如下:
对于需要插值的记录,基于欧氏距离计算k个和它最近的观测;再将这k个近邻的数据利用距离逆加权算出填充值,最后用该值替代缺失值。
该方法的优点是只需调用一次函数就能对所有缺失值进行填充。
该函数的参数是除了因变量之外所有变量组成的数据框,因为你无法对未知的因变量进行插值。
函数knnImputation()的基本格式:
knnImputation(data,k=10,meth="weighAvg",...)
其中,data为数据框格式的数据集;k设定近邻数,默认为10;meth指定计算缺失值的方法,默认为weighavg(加权平均),也可选median(中位数)。
knnOutput<-knnImputation(treated[,!
names(treated)%in%"medv"])#KNN插值,剔除因变量medv
sum(is.na(knnOutput))#检查是否插补所有NA值
[1]0
actuals<-BostonHousing$ptratio[is.na(treated$ptratio)]
predicts<-knnOutput[is.na(treated$ptratio),"ptratio"]
regr.eval(actuals,predicts)
maemsermsemape
1.001887151.979101831.406805540.05859526
可见,与均值插补法相比,mape值从0.095降到0.059,降低了约38%.
knn插值法的缺点是,对因子类变量的插补效果不好。
rpart包和mice包提供了更灵活的解决方案:
五、分类树与回归树预测法插补——rpart包
rpart的优点是只需一个未缺失值就可以填充整个数据样本。
对因子型变量,rpart函数可把method设为class(分类树);对数值型变量就设定method=anova(回归树)。
当然,也要剔除因变量。
函数rpart()的基本格式为:
rpart(formula,data,na.action,method,parms,...)
其中,formula为回归方程的形式,如y~x1+x2;data为数据框;na.action指定缺失值处理方式,默认为na.rpart;method根据树的末端的数据类型选择相应变量分割方法,有四种取值:
连续型取anova,离散型取class,计数型取poisson,生存分析型取exp;parms用来设置三个参数:
先验概率、损失矩阵、分类纯度的度量方法。
library(rpart)
#rad为因子型变量
class_mod<-rpart(rad~.-medv,data=treated[!
is.na(treated$rad),],na.action=na.omit,method="class")
#ptratio为数值型变量
anova_mod<-rpart(ptratio~.-medv,data=treated[!
is.na(treated$ptratio),],na.action=na.omit,method="anova")
#预测插补值
rad_pred<-predict(class_mod,treated[is.na(treated$rad),])
ptratio_pred<-predict(anova_mod,treated[is.na(treated$ptratio),])
#计算ptratio的插补精度
ptratio_actu<-BostonHousing$ptratio[is.na(treated$ptratio)]
regr.eval(ptratio_actu,ptratio_pred)
maemsermsemape
0.710616730.996938450.998468050.04099908
#计算rad的插补精度
rad_actu<-BostonHousing$rad[is.na(treated$rad)]
predicteds<-as.numeric(colnames(rad_pred))[apply(rad_pred,1,which.max)]#归到概率取最大值的那一类
mean(rad_actu!
=predicteds)#计算误分类比例
[1]0.25
可见,与KNN法插补法相比,回归树预测法插补的mape又从0.059下降到0.041,降低了约30.5%;对于因子型变量,仅有21.7%的缺失值被误分类,这个结果也不坏。
六、多重插补法——mice包
1.多值插补的思想来源于贝叶斯估计,认为待插补的值是随机的,且来自于已观测到的值。
多重插补法的步骤:
(1)为每个缺失值进行插补(用其它变量的数据对有缺失值的某变量进行回归拟合),生成若干个完整数据集(存入imp);
(2)依次对imp应用统计模型,如线性模型或广义线性模型(with函数);
(3)将分析结果进行整合(pool函数);
(4)评价插补模型优劣(模型系数的t统计量);
(5)输出完整数据集(complete函数)
2.使用mice包实现
函数mice()的基本格式:
mice(data,m=5,method,predictorMatrix,maxit=5,...)
其中,data为数据集;m为多重插补的重数(生成几个完整数据集);method指定插补方法,默认为PMM(预测均值匹配),还有其它插补方法,比如norm(贝叶斯线性回归)、norm.boot(基于bootstrap的线性回归)、norm.predict(线性回归预测值)、cart(分类回归树)、rf(随机森林)等,用methods(mice)可以看到有哪些可用的方法;
predictorMatrix用来指定参与回归的变量;maxit指定最大迭代次数,默认为5次。
注:
可初始化参数,并设置不参与回归拟合的自变量,以及不做缺失值填充的变量:
init=mice(data,maxit=0)
meth=init$method
predM=init$predictorMatrix
predM[,c("x1")]=0#排除变量x1,不作为回归的自变量,但仍作为因变量进行缺失值填充
meth[c("x2")]="logreg"#指定变量x2的回归拟合方法为logit回归
meth[c("x3")]=""#设置变量x3不作缺失值填充
设置完成后,执行
mice(data,method=meth,predictorMatrix=predM)
即可。
3.基于随机森林法的简单多重插补的实例:
library(mice)
miceMod<-mice(treated[,!
names(treated)%in%"medv"],method="rf")#基于随机森林模型进行多重插补
miceOutput<-complete(miceMod)#生成完整数据
sum(is.na(miceOutput))
[1]0
#计算ptratio的插补精度
ptratio_actu<-BostonHousing$ptratio[is.na(treated$ptratio)]
ptratio_pred<-miceOutput[is.na(treated$ptratio),"ptratio"]
library(DMwR)
regr.eval(ptratio_actu,ptratio_pred)
maemsermsemape
0.695000002.357000001.535252420.04252331
#计算rad的插补精度
rad_actu<-BostonHousing$rad[is.na(treated$rad)]
rad_pred<-miceOutput[is.na(treated$rad),"rad"]
mean(rad_actu!
=rad_pred)
[1]0.1
注:
一般来说,mice的多重插补更适合数值型变量;因子型变量建议采用rpart法。
4.多重插补的一般过程实例
library(mice)
data(sleep,package="VIM")
impdatas<-mice(sleep,seed=2016)
#随机数种子保证每次的随机数都相同
#impdatas包含m个插补数据集(默认m=5),以及插补过程的信息
fit<-with(impdatas,lm(Dream~Span+Gest))
#fit为包含m个单独统计分析结果的列表,with函数的第2个参数为线性回归或广义线性回归的表达式
pooled<-pool(fit)#对fit的m个统计分析结果进行汇总
summary(pooled)
estsetdfPr(>|t|)
(Intercept)2.5769849100.2733439129.427628735.084393.781619e-11
Span-0.0057413920.011932214-0.481167355.731876.322814e-01
Gest-0.0039179330.001513346-2.588921552.477571.242947e-02
lo95hi95nmisfmilambda
(Intercept)2.0221149773.1318548432NA0.215094490.17159061
Span-0.0296470270.018164244440.052387420.01898071
Gest-0.006954025-0.000881840540.084135950.04988369
impdatas#输出impdatas的信息(略)
impdatas$imp$Dream#查看填充矩阵中变量Dream的填充值
12345
10.51.20.60.50.5
31.81.31.42.61.4
42.02.63.63.91.2
140.60.50.81.00.9
241.91.21.51.00.9
262.22.71.22.02.8
306.10.00.52.61.2
311.93.40.01.91.9
473.11.31.84.11.8
530.60.60.50.50.5
550.53.40.52.81.5
623.40.52.03.46.1
#第1列为被填充的样本序号,之后5列分别为5次填充的值
impdatas$method#查看每个变量采用的填充方法
BodyWgtBrainWgtNonDDreamSleepSpanGestPred
"""""pmm""pmm""pmm""pmm""pmm"""
ExpDanger
""""
completeSleep<-complete(impdatas,1)
#"1"表示用completeSleep$imp中的第1个矩阵来填充,也可指定为其它矩阵
附录:
主要参考文献:
《R语言-缺失值处理1-6》,银河统计学,博客园
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 语言 学习 系列 15 缺失 处理 方法