Python 中分类变量的缺失值插补

Missing values imputation for categorical variables in Python

我正在为这种情况寻找一种好的插补方法。 我有一个包含分类变量和缺失数据的数据框,如下所示:

    import pandas as pd


var1 = ['a','a','a','c','e',None]
var2 = ['p1','p1','p1','p2','p3','p1']
var3 = ['o1','o1','o1','o2','o3','o1']

df = pd.DataFrame({'v1':var1,'v2':var2,'v3':var3})

我正在 python 中寻找一种仅支持分类变量的插补方法(也可以是 R)。这个想法是在给定 var2 和 var3 的情况下预测 var1。 例如,如果我们要预测 var1 中的 NONE 值。我们当然知道 var1='a' 给定 var2='p1' 和 var3 = 'o1' 的概率是 1。我的意思是,P(var1='a' / (var2='p1',var3='o1') = 3/3 = 1。我考虑过编写条件模式之类的程序,但也许有人已经对此进行了编程,或者对此有更好的算法。 我只有 3 个具有多个类别的分类变量,其缺失值为 MCAR。值得一提的是,我的数据集大约有超过一百万行(约占 NA 的 10%)。

你有什么可以推荐给我的吗?

提前致谢, 托马斯

您可以使用 K 最近邻插补。

这是 R 中的一个示例:

library(DMwR)

var1 = c('a','a','a','c','e',NA)
var2 = c('p1','p1','p1','p2','p3','p1')
var3 = c('o1','o1','o1','o2','o3','o1')

df = data.frame('v1'=var1,'v2'=var2,'v3'=var3)
df

knnOutput <- DMwR::knnImputation(df, k = 5) 
knnOutput

输出:

  v1 v2 v3
1  a p1 o1
2  a p1 o1
3  a p1 o1
4  c p2 o2
5  e p3 o3
6  a p1 o1

更新:

KNN 不适用于大型数据集。大型数据集的两个选项是多项式插补和朴素贝叶斯插补。多项插补要容易一些,因为您不需要将变量转换为虚拟变量。我在下面展示的朴素贝叶斯实现需要更多工作,因为它需要您转换为虚拟变量。下面,我展示了如何在 R 中适应这些中的每一个:

# make data with 6M rows
var1 = rep(c('a','a','a','c','e',NA), 10**6)
var2 = rep(c('p1','p1','p1','p2','p3','p1'), 10**6)
var3 = rep(c('o1','o1','o1','o2','o3','o1'), 10**6)
df = data.frame('v1'=var1,'v2'=var2,'v3'=var3)

####################################################################
## Multinomial imputation
library(nnet)
# fit multinomial model on only complete rows
imputerModel = multinom(v1 ~ (v2+ v3)^2, data = df[!is.na(df$v1), ])

# predict missing data
predictions = predict(imputerModel, newdata = df[is.na(df$v1), ])

####################################################################
#### Naive Bayes
library(naivebayes)
library(fastDummies)
# convert to dummy variables
dummyVars <- fastDummies::dummy_cols(df, 
                                     select_columns = c("v2", "v3"), 
                                     ignore_na = TRUE)
head(dummyVars)

dummy_cols 函数将虚拟变量添加到现有数据框中,因此现在我们将仅使用列 4:9 作为我们的训练数据。

#     v1 v2 v3 v2_p1 v2_p2 v2_p3 v3_o1 v3_o2 v3_o3
# 1    a p1 o1     1     0     0     1     0     0
# 2    a p1 o1     1     0     0     1     0     0
# 3    a p1 o1     1     0     0     1     0     0
# 4    c p2 o2     0     1     0     0     1     0
# 5    e p3 o3     0     0     1     0     0     1
# 6 <NA> p1 o1     1     0     0     1     0     0
# create training set
X_train <- na.omit(dummyVars)[, 4:ncol(dummyVars)]
y_train <- na.omit(dummyVars)[, "v1"]

X_to_impute <- dummyVars[is.na(df$v1), 4:ncol(dummyVars)]


Naive_Bayes_Model=multinomial_naive_bayes(x = as.matrix(X_train), 
                                          y = y_train)

# predict missing data
Naive_Bayes_preds = predict(Naive_Bayes_Model, 
                                  newdata = as.matrix(X_to_impute))


# fill in predictions
df$multinom_preds[is.na(df$v1)] = as.character(predictions)
df$Naive_Bayes_preds[is.na(df$v1)] = as.character(Naive_Bayes_preds)
head(df, 15)


#         v1 v2 v3 multinom_preds Naive_Bayes_preds
#    1     a p1 o1           <NA>              <NA>
#    2     a p1 o1           <NA>              <NA>
#    3     a p1 o1           <NA>              <NA>
#    4     c p2 o2           <NA>              <NA>
#    5     e p3 o3           <NA>              <NA>
#    6 <NA> p1 o1              a                 a
#    7     a p1 o1           <NA>              <NA>
#    8     a p1 o1           <NA>              <NA>
#    9     a p1 o1           <NA>              <NA>
#    10    c p2 o2           <NA>              <NA>
#    11    e p3 o3           <NA>              <NA>
#    12 <NA> p1 o1              a                 a
#    13    a p1 o1           <NA>              <NA>
#    14    a p1 o1           <NA>              <NA>
#    15    a p1 o1           <NA>              <NA>

如果您可以访问 GPU,则可以查看 DataWig from AWS Labs to do deep learning-driven categorical imputation. You can experiment with batch sizes (depending on the available GPU memory) and hyperparameter optimization. You can specifically choose categorical encoders with embedding

作为旁注,还有算法 MICE(链式方程的多元插补)。 Miceforest is one example of a library that runs on CPU's by default. However, the backend uses LightGBM (Gradient Boosting Machine) for random forests classification. You can pass a couple of parameters to the .tune_parameters() function from miceforest when LightGBM was built for GPU's. For example, device="gpu",gpu_platform_id=0,gpu_device_id=0, etc. More info on how to optimize GPU-performance can be found here https://lightgbm.readthedocs.io/en/latest/GPU-Performance.html.