惹人厌的缺失值,如何巧妙地弥补上去?

2020-07-17  本文已影响0人  科研猫_2020


作者:科研猫 | 西红柿

责编:科研猫 | 馋猫

数据处理中经常遇到缺失值,也就是NA值,遇到这样的值我们该怎么处理呢?很多人往往就直接筛掉这样的数据,造成了一定程度的浪费。那么能否对缺失值进行补充呢?这是一个非常复杂的问题。首先,读者必须考虑是否有必要对缺失值进行插补,可插补数据集的前提是数据的删除是随机删除。此外,我们必须考虑一些实际情况。例如,只有5%的数据丢失。因为这个比例很小,你可以直接从原始数据中去掉它。但是,如果有20%的数据丢失,在它们全部被消除后,我们将会丢失很多信息;因此,我们应该尝试在此时插入缺少的值。如果你的原始数据中有50%的缺失值,那么你就能体会到这个“先天缺陷”的弥补方法有多强大。当发现数据集含有缺失值时,我们必须从数据收集的源头上找到原因。然而,在现实世界中,经常很难重复地收集丢失的数据。因此,读者需要考虑的问题是:在缺失值不可用的情况下,可以使用什么方法来插补缺失值?你可以使用什么方法最大程度地恢复缺失值的原始外观?

有许多类型的数据丢失,总结如下三种情况 :

(I) 完全随机缺失(MCAR):缺失的形成与其他变量(包括观察到的和未观察到的值)无关,没有系统的原因。

(II) 随机缺失(MAR):缺失与其他变量相关,与自身未测量值无关。

(III)不随机丢失(NMAR):排除MCAR和MAR

对于缺失值有各种插补方法。简单的插补方法,如直接填充均值或中值,而稍微复杂的插补方法,如回归插补。然而,无论采用哪种方法,都很难测量插补的质量。因为在现实世界中,我们无法得到缺失的值,因此无法验证插补的正确性。然而,在计算机上,我们可以通过仿真来评估不同的插补方法,并且这种评估在以后是有效的。

在这一部分中,笔者将介绍几种缺失值插补方法供读者参考。为了更好地演示如何插补数据,我们在第一次虚构了200个观测值。数据框架包含三个变量:性别(sex)、平均动脉压(map)和乳酸含量(lac)。为了使读者能够得到与本文相同的结果,我们为每个随机模拟设置了种子值。这里我们使用每个变量的平均值来填充缺失的值。

在这些数据中,假设lac与map有关。根据临床知识可以知道,血乳酸值反映了组织的灌注情况,与map相关。我们假设lac与map呈负相关。为了增加随机性,我们使用rnorm()函数生成截距。我们假设性别变量的缺失符合MCAR。以下步骤可以使用summary()函数观察数据集并计算其标准差。

在上述结果中,我们发现有55个乳酸缺失值,平均值为2.015,标准差为0.401277。使用平均值、特殊值或中值来估计缺失值是一种快速而简单的方法。R软件中VIM软件包中的initialise()函数完成此项工作。但是,它主要在一些函数中内部使用,与其他执行单个插入的方法相比,它没有任何优势。例如,我们希望将缺失值插入具有平均值的连续变量中。下面的R代码返回一个包含完整数据信息的lac.mean变量,在这个变量中,使用平均值取代了lac.miss变量中的缺失值。round()函数将结果保留一位小数。

接下来,我们使用一个可视化的方法来检查使用平均值替换缺失值后的数据分布情况。

不出所料,插入的所有值均为2.1 mmol/L(图36),因此新样本的平均值和标准差与实际样本相比存在偏差。模式和中值的插入也是以相同的方式插入,这可以留给读者。虽然这些粗糙方法为缺失值插值提供了方便,但这种方法低估了方差值(小于实际值),忽略了变量之间的关系,最终导致构建一些统计值(如平均标准差)。因此,这些粗略估计只能用来处理少量缺失的数据,不能广泛应用。因此,我们需要进一步掌握复杂问题的处理。接下来,我将使用mlbench包中的BostonHousing数据集来演示各种常见的缺失值填充方法。

波士顿住房数据集包含506个观察值和14个变量,这些变量反映了波士顿城市居民的基本情况,包括每个城镇的犯罪率和非零售企业的数量。由于BostonHousing数据集本身没有缺失值,所以我们随机生成一些缺失值。

这里我们为rad和ptratio设置了80个缺失值。前者是一个因子变量,后者是一个数值变量。接下来,我们使用mice包md.pattern()函数观察缺失模式,并决定如何进一步处理缺失值。

在上一次推送中,我们讲过该函数。根据以上结果,0表示删除,1表示不删除。可以看出,“rad”和“ptratio”中分别有80个缺失值,有362个观测值没有丢失,rad变量和ptratio变量单独各丢失了64个观测值,共同丢失了19个观测值。类似地,我们用一种简单的方法插补缺失值。首先,我们需要预先下载并加载Hmisc包。我们可以使用这个包中的impute()函数来执行缺失值的自动插补。

在上面的代码中,作者使用了三种简单的方法来插补缺失值。右上角带星号的数字表示数据是插补的,而不是原始数据。显然,这种方法只适用于连续数据,而不适用于分类数据。然后重点介绍了mice包中缺失值的高级插补方法。mice包是通过链式方程进行多元插补的。mice包提供了多种高级缺失值处理方法。它对两步插值使用了一种不同寻常的方法:首先使用mice()函数建模,然后使用complete()函数生成完整的数据。mice(df)返回df的多个完整副本,每个副本为丢失的数据插入不同的值。complete()函数的作用是返回一个(默认)或多个数据集。下面演示如何使用此方法插补两个变量

这里可以使用随机森林算法。我们在这里向您展示如何使用高级统计方法来插补缺失值。至于在这里选择随机森林算法,还是简单的线性回归算法,虽然原理不同,但目标是一样的。Miceoutput()函数的作用是插补数据集。anyNA()函数的作用是查看插补后的数据集是否含有缺失值。如果我们有原始的没有缺失值的数据集,我们就可以使用它去处理缺失值。这种方法计算的插补值更为精确。

读者可以看到,插值的误差率为12.5%,这意味着大部分缺失值都被正确插补,这显然比单纯使用平均值插补要精确得多。需要强调的是,回归方法考虑了数据之间的相关性,但对默认值变化的估计并不准确,可以通过增加回归模型的随机误差来调整变异程度。除了mice包,前面描述的VIM包也可以插补缺失值,并提供高级方法,如hotdack、K-nearest neighbor、线性回归等。更多的内容读者可以自己探索。

更多科研新鲜资讯、文献精读和生物信息技能

请关注科研猫公众号

上一篇下一篇

猜你喜欢

热点阅读