其实之前我也介绍过缺失值的处理:[[28-R数据整理03-缺失值NA的处理]]。
当时的方法也比较简单:
但有没有更高级一些的操作呢?
比如multivariate imputation by chained equations (MICE) 方法:
这里首先利用自带数据集airquality
制造假数据。
library(mice)
my_data <- airquality
my_data[sample(153, 10), ]$Wind <- NA
my_data[sample(153, 10), ]$Temp <- NA
> head(my_data)
Ozone Solar.R Wind Temp Month Day
1 41 190 7.4 67 5 1
2 36 118 8.0 72 5 2
3 12 149 12.6 74 5 3
4 18 313 11.5 62 5 4
5 NA NA 14.3 56 5 5
6 28 NA 14.9 66 5 6
除了mice 以外,这里介绍两种查看缺失值的方法。
> summary(my_data)
Ozone Solar.R Wind
Min. : 1.00 Min. : 7.0 Min. : 1.700
1st Qu.: 18.00 1st Qu.:100.0 1st Qu.: 7.400
Median : 30.00 Median :194.0 Median : 9.700
Mean : 41.51 Mean :182.3 Mean : 9.892
3rd Qu.: 63.25 3rd Qu.:259.0 3rd Qu.:11.500
Max. :168.00 Max. :334.0 Max. :20.700
NA's :33 NA's :10 NA's :10
Temp Month Day
Min. :56.00 Min. :5.000 Min. : 1.00
1st Qu.:72.00 1st Qu.:6.000 1st Qu.: 8.00
Median :78.00 Median :7.000 Median :16.00
Mean :77.36 Mean :6.928 Mean :15.88
3rd Qu.:84.00 3rd Qu.:8.000 3rd Qu.:23.00
Max. :97.00 Max. :9.000 Max. :31.00
NA's :10
shipunov::Missing.map(my_data)
Legend: '_' no, ':' some, '!' all
var missing.map total
1 Ozone _::___:::::::!!_:::_:___:::_::_____:_:_ 33
2 Solar.R _::___:___:____________:::__________:__ 10
3 Wind ________:_:__________:__::__:___:__:___ 10
4 Temp _________:_:___:____:_:__:_:___:____:__ 10
5 Month _______________________________________ 0
6 Day _______________________________________ 0
percent
1 21.6
2 6.5
3 6.5
4 6.5
5 0.0
6 0.0
比较直观的展示缺失值的占比以及在整理样本中缺失值的位置。
此外就是mice 的可视化方法了:
> md.pattern(my_data)
Month Day Solar.R Wind Temp Ozone
99 1 1 1 1 1 1 0
28 1 1 1 1 1 0 1
7 1 1 1 1 0 1 1
1 1 1 1 1 0 0 2
6 1 1 1 0 1 1 1
2 1 1 1 0 1 0 2
5 1 1 0 1 1 1 1
2 1 1 0 1 1 0 2
1 1 1 0 1 0 1 2
1 1 1 0 0 1 1 2
1 1 1 0 0 0 1 3
0 0 10 10 10 33 63
这张图除了提供了每列数据的缺失值汇总情况,还对不同位置发生的缺失情况以方块图进行展示,比如横向来看,第一排就是在所有列都没有缺失值情况,一共有99 个样本符合。
还有一个包VIM 也提供了函数:
aggr_plot <- aggr(my_data,
numbers=TRUE,
sortVars=TRUE,
labels=names(my_data),
cex.axis=.7,gap=3,
ylab=c('Missing data','Pattern'))
Variables sorted by number of missings:
Variable Count
Ozone 0.21568627
Solar.R 0.06535948
Wind 0.06535948
Temp 0.06535948
Month 0.00000000
Day 0.00000000
以及marginplot,但缺点是仅能展示两个变量,:
VIM::marginplot(my_data[,c(1,2)])
下图是一个说明图:
主要分为三类:
在前两种情况下可以根据其出现情况删除缺失值的数据,而在第三种情况下,删除包含缺失值的数据可能会导致模型出现偏差。因此我们需要对删除数据非常谨慎。而且,插补数据并不一定能提供更好的结果。
以我们的数据为例:
直接删除有缺失值的样本,比如na.omit
。
删除存在大面积缺失值的变量。如果研究的问题只涉及到全部变量中的一部分变量,这部分变量是完整的,那么可以只分析这几个完整变量之间的关系。
此外还有成对删除法等。
简单随机填补:对于每一个缺失值,从已有的该变量数据中随机抽样作为填补值,填补进缺失位置。仅仅考虑到了缺失变量本身,而并没有考虑到相关变量的信息。因此,信息量的利用少。
虚拟变量填补:把缺失值设定为一个新的变量,一般适用于分类数据统计。
均值/中位数/分位数填补:用存在缺失值的变量的已有值的均值/中位数/分位数,作为填补值。这种方法显然会导致方差偏小。
回归填补:将缺失变量作为因变量,相关变量(其他变量)作为自变量,进行回归拟合,用预测值作为填补值。用于作为自变量的变量最好是具有完全数据(无缺失)。
热平台法:热平台法又称匹配插补法,思路是在完全数据样本中,找到一个和具有缺失值的样本相似的完全数据样本,用完全数据样本值作为填充值,其过程有点类似于K阶近邻的思想。
冷平台法:又称条件均值插补法,思路是先将总体分层(聚类),采用样本所在层(类)的完全数据的均值来替代缺失值。
可见这里的热平台法和冷平台法就已经涉及到了机器学习的内容了。这里就不展开说了。
还有一本书:Van Buuren, S. (2012). Flexible Imputation of Missing Data. Chapman & Hall/CRC, Boca Raton, FL. Chapters 1–6, 10. http://www.crcpress.com/product/isbn/978143986824
多重填补法(Multiple Imputation Missing Data),其核心思想有点类似于回归填补,是基于各种模型(如回归、决策树、贝叶斯估计等方法)。简单而言:该方法认为缺失值是随机的,它的值可以通过已观测到的值进行预测与插值。
多重插补方法分为三个步骤:
碍于我的能力有限,这里贴上mice 的部分模型:
以及某个讲义:Handling Missing Data in R with MICE (amices.org)[5]
比如:
mice_data <- mice(my_data,
meth='pmm', seed=500)
我们可以查看数据框每列采用的插补方法,如果不存在NA 值,则不会进行任何的插补:
> mice_data$meth
Ozone Solar.R Wind Temp Month Day
"pmm" "pmm" "pmm" "pmm" "" ""
多重插补的方法包括:
> methods(mice)
[1] mice.impute.2l.bin
[2] mice.impute.2l.lmer
[3] mice.impute.2l.norm
[4] mice.impute.2l.pan
[5] mice.impute.2lonly.mean
[6] mice.impute.2lonly.norm
[7] mice.impute.2lonly.pmm
[8] mice.impute.cart
[9] mice.impute.jomoImpute
[10] mice.impute.lasso.logreg
[11] mice.impute.lasso.norm
[12] mice.impute.lasso.select.logreg
[13] mice.impute.lasso.select.norm
[14] mice.impute.lda
[15] mice.impute.logreg
[16] mice.impute.logreg.boot
[17] mice.impute.mean
[18] mice.impute.midastouch
[19] mice.impute.mnar.logreg
[20] mice.impute.mnar.norm
[21] mice.impute.norm
[22] mice.impute.norm.boot
[23] mice.impute.norm.nob
[24] mice.impute.norm.predict
[25] mice.impute.panImpute
[26] mice.impute.passive
[27] mice.impute.pmm
[28] mice.impute.polr
[29] mice.impute.polyreg
[30] mice.impute.quadratic
[31] mice.impute.rf
[32] mice.impute.ri
[33] mice.impute.sample
以下图中:洋红色为插补的数据,蓝色为原始数据。
两组数据的不同列的散点图:
xyplot(mice_data,Ozone + Solar.R ~Wind+Temp,
pch=18,cex=1)
Ozone + Solar.R ~Wind+Temp 在两个数据框中的对应点。
密度图:
densityplot(mice_data)
我们一共有五个插入数据:
带状图:
stripplot(mice_data, pch = 20, cex = 1.2)
返回的mice_data
为一个列表类型的对象,我们可以从中提取填补了缺失值后的结果:
myce_data_df <- complete(mice_data)
> shipunov::Missing.map(myce_data_df)
Legend: '_' no, ':' some, '!' all
var missing.map total
1 Ozone _______________________________________ 0
2 Solar.R _______________________________________ 0
3 Wind _______________________________________ 0
4 Temp _______________________________________ 0
5 Month _______________________________________ 0
6 Day _______________________________________ 0
percent
1 0
2 0
3 0
4 0
5 0
6 0
默认下,complete
函数获得我们得到的多重插入结果的第一个数据集,我们可以指定某个数据框,比如3
选择第二个。
也可以指定输出的数据框类型:"all"
, "long"
, "broad"
and "repeated"
,比如 long
是长数据框。
这里我们比较一下前后的密度图:
library(gridExtra)
p1 <- densityplot(my_data$Temp)
p2 <- densityplot(myce_data_df$Temp)
p3 <- densityplot(my_data$Ozone, col = "red")
p4 <- densityplot(myce_data_df$Ozone, col = "red")
grid.arrange(p1, p2, p3, p4,
ncol = 2)
我自己并不是很明白这一步的操作。比如为何要进行线性拟合,以及总结多重插补的不同数据集,汇总总结结果:
fit <- with(mice_data,
lm(Temp~Ozone+Solar.R+Wind))
# fit_before <- with(my_data,
# lm(Temp~Ozone+Solar.R+Wind))
summary(pool(fit))
term estimate std.error statistic df
1 (Intercept) 73.35159260 2.799793583 26.198929 127.55240
2 Ozone 0.15730791 0.026806721 5.868226 34.38749
3 Solar.R 0.01034206 0.007462813 1.385813 58.93774
4 Wind -0.37208249 0.202425181 -1.838124 137.77557
p.value
1 0.000000e+00
2 1.226326e-06
3 1.710255e-01
4 6.819801e-02
一个小小的总结,来自数据汪:
可以参考:amices/mice: Multivariate Imputation by Chained Equations (github.com)[6]
Vignettes
以及一本书:
Van Buuren, S. (2012). Flexible Imputation of Missing Data. Chapman & Hall/CRC, Boca Raton, FL. Chapters 1–6, 10. http://www.crcpress.com/product/isbn/978143986824
最后为什么要拟合接着pool 一下呢?
如此之多的基于mice 包中的方法,究竟该如何选择呢?
[1]
amices/mice: Multivariate Imputation by Chained Equations (github.com): https://github.com/amices/mice
[2]
R中数据缺失值的处理--基于mice包 - 知乎 (zhihu.com): https://zhuanlan.zhihu.com/p/21549898
[3]
一种挽救你缺失数据的好方法——多重补插_处理 (sohu.com): https://www.sohu.com/a/275318909_777125
[4]
没有完美的数据插补法,只有最适合的 - 知乎 (zhihu.com): https://zhuanlan.zhihu.com/p/47366879
[5]
Handling Missing Data in R with MICE (amices.org): https://amices.org/Winnipeg/Lectures/Winnipeg.pdf
[6]
amices/mice: Multivariate Imputation by Chained Equations (github.com): https://github.com/amices/mice
[7]
Handling Missing Data in R
with mice
: https://amices.github.io/Winnipeg/
[8]
Statistical Methods for combined data sets: https://stefvanbuuren.github.io/RECAPworkshop/
[9]
Ad hoc methods and the MICE algorithm: https://gerkovink.github.io/miceVignettes/Ad_hoc_and_mice/Ad_hoc_methods.html
[10]
Convergence and pooling: https://gerkovink.github.io/miceVignettes/Convergence_pooling/Convergence_and_pooling.html
[11]
Inspecting how the observed data and missingness are related: https://gerkovink.github.io/miceVignettes/Missingness_inspection/Missingness_inspection.html
[12]
Passive imputation and post-processing: https://gerkovink.github.io/miceVignettes/Passive_Post_processing/Passive_imputation_post_processing.html
[13]
Imputing multilevel data: https://gerkovink.github.io/miceVignettes/Multi_level/Multi_level_data.html
[14]
Sensitivity analysis with mice
: https://gerkovink.github.io/miceVignettes/Sensitivity_analysis/Sensitivity_analysis.html
[15]
Generate missing values with ampute
: https://rianneschouten.github.io/mice_ampute/vignette/ampute.html