我有一个庞大的数据集,想使用如SVM或随机森林等机器学习算法来预测(而不是替换)其中的缺失值,使用的编程语言是Python。
我的数据集看起来像这样:
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.111 -0.61 -0.19 -0.10 -0.1 -0.21 0.63 NA NA NA NA NA NA2 -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应该是什么样的?
回答:
在你的情况中,你面对的是一个多输出回归问题:
- 一个回归问题 – 与分类相对 – 因为你试图预测一个值而不是一个类/状态变量/类别
- 多输出因为你试图为每个数据点预测6个值
你可以阅读sklearn文档中关于多类的更多信息。
在这里,我将向你展示如何使用sklearn.multioutput.MultiOutputRegressor和sklearn.ensemble.RandomForestRegressor来预测你的值。
构造一些虚拟数据
from sklearn.datasets import make_regressionX,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)# 转换为像你示例中的pandas数据框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)# 在其中引入一些np.nan值df.loc[0, jcols] = np.nandf.loc[10, jcols] = np.nandf.loc[100, jcols] = np.nandf.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
最初排除NaN值,并按75%训练和25%测试进行分割
进行分割是为了能够验证我们的模型。
notnans = df[jcols].notnull().all(axis=1)df_notnans = df[notnans]# 按75%训练和25%测试进行分割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 RandomForestRegressorfrom sklearn.multioutput import MultiOutputRegressorfrom sklearn.model_selection import train_test_splitregr_multirf = MultiOutputRegressor(RandomForestRegressor(max_depth=30, random_state=0))# 在训练数据上拟合regr_multirf.fit(X_train, y_train)# 检查预测分数score = regr_multirf.score(X_test, y_test)print("在测试数据上的预测分数是 {:.2f}%".format(score*100))Out: 在测试数据上的预测分数是 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