R语言数据分析与挖掘(第一章):数据预处理(2)——缺失值常用的处理方法

2019-09-25 10:09:52 浏览数 (1)

上一篇文章(缺失值处理)介绍了缺失值处理的判断方法,这一讲接着介绍缺失值常用的几种处理方法:删除法,替换法和插补法。不同的方法对应不同类型的缺失值。

1.删除法

如果缺失值的比例很小,且不影响整体的数据结构,即缺失值类型是完全随机缺失时,可以考虑将缺失值删除,该方法操作非常简单,使用函数na.omit()就可以将含有缺失值的行删除。其函数的基本书写格式为:

代码语言:javascript复制
na .omit (object,....)

其中object即为需要处理的数据对象。下面我们对algae数据集进行处理:

代码语言:javascript复制
> algae=na.omit(algae)
> sum(is.na(algae))
[1] 0

上一篇文章中,我们介绍到该数据集有33个缺失值,删除后,现在为0了。

除了na.omit()函数外,还可以利用complete.cases函数来删除含有缺失值的行。

代码语言:javascript复制
> # 因为上一句代码已经删除过,这里重新加载原始数据
> data(algae)
> algae<-algae[complete.cases(algae),]
> sum(!complete.cases(algae))
[1] 0

2.替换法

直接删除含有缺失值的行记录的代价和风险较大,故我们可以考虑将缺失值部分替换掉,如用均值去替换,即均值替换法,该方法根据变量的不同类型选择不同的替换,对数值型变量采用均值替换,对非数值型变量采用众数替换。

下面我们将对algae数据集采用均值替换处理缺失值:

代码语言:javascript复制
> 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进行,其函数的基本书写格式为,

代码语言:javascript复制
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()等。下面我们将用到一些回归知识, 有疑感的话先放着,后面分析数据时我们会深入了解。

代码语言:javascript复制
> 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()对变量分布图进行可视化。

代码语言:javascript复制
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)

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

0 人点赞