使用机器学习预测 NA(缺失值)

Posted

技术标签:

【中文标题】使用机器学习预测 NA(缺失值)【英文标题】:Predict NA (missing values) with machine learning 【发布时间】:2017-04-21 03:11:08 【问题描述】:

我有一个庞大的数据集,并希望使用机器学习算法(如 python 中的 svm 或随机森林)来预测(而不是替换)缺失值。

我的数据集如下所示:

ID i0   i1    i2    i3    i4   i5     j0    j1   j2   j3    j4    j5    

0  0.19 -0.02 -0.20 0.07 -0.06 -0.06  -0.06 1.48 0.33 -0.46 -0.37 -0.11
1 -0.61 -0.19 -0.10 -0.1 -0.21  0.63   NA    NA   NA   NA    NA    NA
2 -0.31 -0.14 -0.64 -0.5 -0.20 -0.30  -0.08 1.56 -0.2 -0.33  0.81 -0.03
.
.

我想做什么: 在 ID 0 和 2 的基础上,我想用 i0 到 i5 训练 j0 到 j5 的值。随后应该会预测 ID 1 的 j0-j5 的 NA。

问题: 由于数据不是连续的(时间步在 i5 处结束并在 j0 处重新开始),是否可以使用某种回归?

.fit(X, y) 和 .predict(X) 函数的 X 和 y 在此示例中应该如何?

【问题讨论】:

您是否认为有某种“物理”原因您可能会期望 NaN,您可以以某种方式将其合并到模型中?另一个想法:也许你可以做两个单独的回归; (i) 仅使用数字(不包括 NaN)和 (ii) 将 NaN 替换为 1,将数字替换为 0。如果 (ii) 说它是一个 NaN,它就是一个 NaN,如果 (ii) 说它是一个数字,它的值由 (i) 给出。这行得通吗? NaN 是故意添加的,不是在随机位置,而是仅在 j0-j5 中。我没有得到您的想法,因为它会使 NaN 保持原样,并且仅适用于其他值。 【参考方案1】:

就您而言,您正在研究多输出回归问题:

回归问题 - 与分类相反 - 因为您试图预测一个值而不是类/状态变量/类别 多输出,因为您尝试为每个数据点预测 6 个值

您可以在 sklearn 文档中阅读有关 multiclass 的更多信息。

在这里,我将向您展示如何使用 sklearn.multioutput.MultiOutputRegressor 和 sklearn.ensemble.RandomForestRegressor 来预测您的值。

构造一些虚拟数据

from sklearn.datasets import make_regression

X,y = make_regression(n_samples=1000, n_features=6,
                                 n_informative=3, n_targets=6,  
                                 tail_strength=0.5, noise=0.02, 
                                 shuffle=True, coef=False, random_state=0)

# Convert to a pandas dataframe like in your example
icols = ['i0','i1','i2','i3','i4','i5']
jcols = ['j0', 'j1', 'j2', 'j3', 'j4', 'j5']
df = pd.concat([pd.DataFrame(X, columns=icols),
                pd.DataFrame(y, columns=jcols)], axis=1)

# Introduce a few np.nans in there
df.loc[0, jcols] = np.nan
df.loc[10, jcols] = np.nan
df.loc[100, jcols] = np.nan

df.head()

Out:
     i0    i1    i2    i3    i4    i5     j0     j1     j2     j3     j4  \
0 -0.21 -0.18 -0.06  0.27 -0.32  0.00    NaN    NaN    NaN    NaN    NaN   
1  0.65 -2.16  0.46  1.82  0.22 -0.13  33.08  39.85   9.63  13.52  16.72   
2 -0.75 -0.52 -1.08  0.14  1.12 -1.05  -0.96 -96.02  14.37  25.19 -44.90   
3  0.01  0.62  0.20  0.53  0.35 -0.73   6.09 -12.07 -28.88  10.49   0.96   
4  0.39 -0.70 -0.55  0.10  1.65 -0.69  83.15  -3.16  93.61  57.44 -17.33   

      j5  
0    NaN  
1  17.79  
2 -77.48  
3 -35.61  
4  -2.47  

最初排除 nans,分成 75% 的训练和 25% 的测试

拆分是为了能够验证我们的模型。

notnans = df[jcols].notnull().all(axis=1)
df_notnans = df[notnans]

# Split into 75% train and 25% test
X_train, X_test, y_train, y_test = train_test_split(df_notnans[icols], df_notnans[jcols],
                                                    train_size=0.75,
                                                    random_state=4)

使用基于随机森林回归器的多输出回归

from sklearn.ensemble import RandomForestRegressor
from sklearn.multioutput import MultiOutputRegressor
from sklearn.model_selection import train_test_split

regr_multirf = MultiOutputRegressor(RandomForestRegressor(max_depth=30,
                                                          random_state=0))

# Fit on the train data
regr_multirf.fit(X_train, y_train)

# Check the prediction score
score = regr_multirf.score(X_test, y_test)
print("The prediction score on the test data is :.2f%".format(score*100))

Out: The prediction score on the test data is 96.76%

预测 nan 行

df_nans = df.loc[~notnans].copy()
df_nans[jcols] = regr_multirf.predict(df_nans[icols])
df_nans

输出:

           i0        i1        i2        i3        i4        i5         j0  \
0   -0.211620 -0.177927 -0.062205  0.267484 -0.317349  0.000341 -41.254983   
10   1.138974 -1.326378  0.123960  0.982841  0.273958  0.414307  46.406351   
100 -0.682390 -1.431414 -0.328235 -0.886463  1.212363 -0.577676  94.971966   

            j1         j2         j3         j4         j5  
0   -18.197513 -31.029952 -14.749244  -5.990595  -9.296744  
10   67.915628  59.750032  15.612843  10.177314  38.226387  
100  -3.724223  65.630692  44.636895 -14.372414  11.947185  

【讨论】:

谢谢,成功了!我在我的数据集上对其进行了测试,得到了约 35% 的分数。现在我不太确定这意味着什么,以及您如何设法获得 96% 的随机值。我会尝试在我的测试数据中添加另一列,也许它会改变我的结果。 我没有创建随机值,我使用了sklearn.datasets.make_regression,噪音很小,所以难怪我得到了高分。 只是一个小评论。使用随机森林回归器时,不需要多输出元估计器,因为随机森林算法默认支持多个目标。

以上是关于使用机器学习预测 NA(缺失值)的主要内容,如果未能解决你的问题,请参考以下文章

机器学习数据预处理之缺失值:预测填充(回归模型填充分类模型填充)

[机器学习与scikit-learn-9]:数据预处理-2-缺失数据na的预处理

机器学习基础:缺失值的处理技巧(附Python代码)

机器学习决策树(划分选择算法流程剪枝处理,连续值与缺失值处理)

机器学习包Scikit-learn

scikits 机器学习中的缺失值