• +86 400-9955-698
  • support@vinchin.com
logo
关于我们

技术分享

技术分享 数据预处理时如何处理丢失的数据

数据预处理时如何处理丢失的数据

2020-03-02

归罪的概念既诱人又危险”(RJA Little&DB Rubin)

 

我在数据清理/探索性分析中遇到的最常见问题之一是处理缺失值。首先,要了解没有好的方法来处理缺失的数据。我根据问题的类型遇到了不同的数据插补解决方案 - 时间序列分析,ML,回归等,很难提供一般解决方案。在这篇博客中,我试图总结最常用的方法并尝试找到结构解决方案。

 

插补与删除数据

在跳转到数据插补方法之前,我们必须了解数据丢失的原因。

  1. 随机丢失(MAR):随机丢失意味着数据点丢失的倾向与丢失的数据无关,但它与某些观察到的数据有关


  2. 完全缺失随机(MCAR):缺少某个值的事实与其假设值和其他变量的值无关。


  3. 缺少随机(MNAR):两个可能的原因是缺失值取决于假设值(例如,工资高的人通常不希望在调查中显示他们的收入)或缺失值取决于其他变量的值(例如让我们假设女性通常不想透露他们的年龄!这里年龄变量的缺失值受性别变量的影响)

在前两种情况下,根据其出现情况删除具有缺失值的数据是安全的,而在第三种情况下,删除具有缺失值的观察可能在模型中产生偏差。所以在删除观察之前我们必须非常小心。请注意,插补并不一定能提供更好的结果。

 

 

删除

  • 列表方式
    列表删除(完整案例分析)会删除具有一个或多个缺失值的观察的所有数据。特别是如果缺失的数据仅限于少量观察,您可以选择从分析中消除这些情况。但是在大多数情况下,使用逐列删除通常是不利的。这是因为MCAR(完全缺失随机)的假设通常很少得到支持。结果,列表删除方法产生有偏差的参数和估计。

newdata <- na.omit(mydata)
# In python
mydata.dropna(inplace=True)
  • Pairwise
    pairwise deletion analyses all cases in which the variables of interest are present and thus maximizes all data available by an analysis basis. A strength to this technique is that it increases power in your analysis but it has many disadvantages. It assumes that the missing data are MCAR. If you delete pairwise then you’ll end up with different numbers of observations contributing to different parts of your model, which can make interpretation difficult.

#成对删除
ncovMatrix <- cov(mydata, use="pairwise.complete.obs")
#列表删除
ncovMatrix <- cov(mydata, use="complete.obs")
  • 删除变量
    在我看来,保留数据总是比抛弃数据更好。有时,如果超过60%的观测数据缺失,您可以删除变量,但前提是该变量无关紧要。话虽如此,估算总是优先选择丢弃变量

df <- subset(mydata, select = -c(x,z) )
df <- mydata[ -c(1,3:4) ]
In python
del mydata.column_name
mydata.drop('column_name', axis=1, inplace=True)

 

时间序列特定方法

  • 最后观察结果(LOCF)和后续观察结果(NOCB)
    这是分析纵向重复测量数据的常用统计方法,其中可能缺少一些后续观察。纵向数据在不同时间点跟踪相同样本。当数据具有明显的趋势时,这两种方法都会在分析中引入偏差并且表现不佳


  • 线性插值
     此方法适用于具有某些趋势但不适合季节性数据的时间序列


  • 季节性调整+线性插值
    此方法适用于具有趋势和季节性的数据

 

 

 

数据:tsAirgap表单库(imputeTS),红色插值数据

 

library(imputeTS)
na.random(mydata)                  # Random Imputation
na.locf(mydata, option = "locf")   # Last Obs. Carried Forward
na.locf(mydata, option = "nocb")   # Next Obs. Carried Backward
na.interpolation(mydata)           # Linear Interpolation
na.seadec(mydata, algorithm = "interpolation") # Seasonal Adjustment then Linear Interpolation

 

平均值,中位数和模式

计算整体均值,中位数或模式是一种非常基本的插补方法,它是唯一没有利用时间序列特征或变量之间关系的测试函数。它非常快,但有明显的缺点。一个缺点是平均估算减少了数据集中的方差。

library(imputeTS)
na.mean(mydata, option = "mean")   # Mean Imputation
na.mean(mydata, option = "median") # Median Imputation
na.mean(mydata, option = "mode")   # Mode Imputation
In Python
from sklearn.preprocessing import Imputer
values = mydata.values
imputer = Imputer(missing_values=’NaN’, strategy=’mean’)
transformed_values = imputer.fit_transform(values)
# strategy can be changed to "median" and “most_frequent”

 

线性回归

首先,使用相关矩阵识别具有缺失值的变量的若干预测变量。选择最佳预测变量并将其用作回归方程中的独立变量。具有缺失数据的变量用作因变量。具有预测变量的完整数据的情况用于生成回归方程; 然后使用该等式来预测不完整案例的缺失值。在迭代过程中,插入缺失变量的值,然后使用所有情况来预测因变量。重复这些步骤,直到从一步到下一步的预测值之间几乎没有差异,即它们收敛。 
它“理论上”提供了对缺失值的良好估计。然而,该模型有几个缺点往往超过优点。首先,因为替换值是从其他变量预测的,所以它们倾向于“太好”地组合在一起,因此标准误差被缩小。还必须假设在可能没有回归方程时,回归方程中使用的变量之间存在线性关系。

 

多重归因

  1. 插补:将不完整数据集的缺失条目计算m次(图中m = 3)。请注意,估算值是从分布中提取的。模拟随机抽取不包括模型参数的不确定性。更好的方法是使用马尔可夫链蒙特卡罗(MCMC)模拟。此步骤将生成完整的数据集。


  2. 分析:分析每个完成数据集。


  3. 合并:将m分析结果整合到最终结果中

 

资料来源:http//www.stefvanbuuren.nl/publications/mice%20in%20r%20-%20draft.pdf

 

# We will be using mice library in r
library(mice)
# Deterministic regression imputation via mice
imp <- mice(mydata, method = "norm.predict", m = 1)

# Store data
data_imp <- complete(imp)
# Multiple Imputation
imp <- mice(mydata, m = 5)
#build predictive model
fit <- with(data = imp, lm(y ~ x + z))
#combine results of all 5 models
combine <- pool(fit)

这是迄今为止最优选的插补方法,原因如下:
- 易于使用
- 无偏差(如果插补模型正确)

 

分类变量的估算

  1. 模式插补是一种方法,但肯定会引入偏见


  2. 缺失值可以单独视为单独的类别。我们可以为缺失值创建另一个类别,并将它们用作不同的级别。这是最简单的方法。


  3. 预测模型:在这里,我们创建一个预测模型来估计将替代缺失数据的值。在这种情况下,我们将数据集分为两组:一组没有变量(训练)的缺失值,另一组缺少值(测试)。我们可以使用逻辑回归和ANOVA等方法进行预测


  4. 多重归因

 

KNN(K最近的邻居)

还有其他机器学习技术,如XGBoost和Random Forest,用于数据插补,但我们将讨论KNN,因为它被广泛使用。在该方法中,基于一些距离测量来选择k个邻居,并且将它们的平均值用作插补估计。该方法需要选择最近邻居的数量和距离度量。KNN可以预测离散属性(k个最近邻居中最常见的值)和连续属性(k个最近邻居之间的平均值)
距离度量根据数据类型而变化:
1。连续数据:常用距离度量连续数据是欧几里德,曼哈顿和余弦
2.分类数据:在这种情况下通常使用汉明距离。它采用所有分类属性,如果两个点之间的值不相同,则计算每个属性。然后,汉明距离等于值不同的属性数。
KNN算法最吸引人的特点之一是它易于理解且易于实现。KNN的非参数性质使其在某些设置中具有优势,其中数据可能非常“不寻常”。
KNN算法的一个明显缺点是,在分析大型数据集时会变得非常耗时,因为它会在整个数据集中搜索类似的实例。此外,由于最近和最远邻居之间几乎没有差别,因此高维数据会严重降低KNN的准确性。

library(DMwR)
knnOutput <- knnImputation(mydata)
In python
from fancyimpute import KNN    

# Use 5 nearest rows which have a feature to fill in each row's missing features
knnOutput = KNN(k=5).complete(mydata)

在上面讨论的所有方法中,广泛使用多个插补和KNN,并且通常优选多个插补更简单。

 

  • 标签:
  • 技术分享

您可能感兴趣的新闻 换一批

现在下载,可享30天免费试用

立即下载