Scikit 中的分类器-学习处理 nan/null 的分类器

我想知道在 scikit-learn 中是否有处理 nan/null 值的分类器。我以为随机森林回归处理这一点,但我得到了一个错误,当我调用 predict

X_train = np.array([[1, np.nan, 3],[np.nan, 5, 6]])
y_train = np.array([1, 2])
clf = RandomForestRegressor(X_train, y_train)
X_test = np.array([7, 8, np.nan])
y_pred = clf.predict(X_test) # Fails!

我不能用任何具有缺失值的 scikit-learn 算法调用预测吗?

剪辑。 现在我想起来了,这就说得通了。在训练期间这不是问题,但是当你预测变量为空时如何进行分支?也许你可以两边均分,然后取平均结果?看起来 k-NN 应该可以正常工作,只要距离函数忽略空值。

编辑2(更年长更睿智的我) 有些 gbm 库(比如 xgost)使用三叉树而不是二叉树就是为了达到这个目的: 2个子元素代表 yes/no decision,1个子元素代表丢失的 decision。Sklearn 是使用二叉树的一个 href = “ https://github.com/scikit-learn/blob/master/sklearn/tree/_ tree.pyx # L70-L74”rel = “ noReferrer”>

74733 次浏览

我制作了一个示例,其中包含训练和测试集中缺少的值

我只是选择了一个策略来用平均值替换丢失的数据,使用 SimpleImputer类。

from __future__ import print_function


import numpy as np
from sklearn.ensemble import RandomForestClassifier
from sklearn.impute import SimpleImputer




X_train = [[0, 0, np.nan], [np.nan, 1, 1]]
Y_train = [0, 1]
X_test_1 = [0, 0, np.nan]
X_test_2 = [0, np.nan, np.nan]
X_test_3 = [np.nan, 1, 1]


# Create our imputer to replace missing values with the mean e.g.
imp = SimpleImputer(missing_values=np.nan, strategy='mean')
imp = imp.fit(X_train)


# Impute our data, then train
X_train_imp = imp.transform(X_train)
clf = RandomForestClassifier(n_estimators=10)
clf = clf.fit(X_train_imp, Y_train)


for X_test in [X_test_1, X_test_2, X_test_3]:
# Impute each test item, then predict
X_test_imp = imp.transform(X_test)
print(X_test, '->', clf.predict(X_test_imp))


# Results
[0, 0, nan] -> [0]
[0, nan, nan] -> [0]
[nan, 1, 1] -> [1]

如果使用 DataFrame,则可以使用 fillna。在这里,我用该列的平均值替换了缺失的数据。

df.fillna(df.mean(), inplace=True)

长话短说

有时缺少的值根本不适用。归咎于他们毫无意义。在这些情况下,您应该使用一个能够处理缺失值的模型。Scitkit-learn 的模型无法处理缺失的值。XGBoost 可以。


更多关于 scikit-learn 和 XGBoost 的信息

正如在 这篇文章中提到的,scikit-learn 的决策树和 KNN 算法是 还不够健壮,用于处理缺失的值。如果归咎没有意义,那就不要这么做。

当插补没有意义时,考虑情景插补。

请记住,这是一个虚构的例子

考虑使用 成排的汽车(“ Danho 柴油”,“ Estal Electric”,“ Hesproc 混合”)和 列及其属性(重量,最高速度,加速度,功率输出,二氧化硫排放,范围)的数据集。

电动汽车不产生废气-所以 二氧化硫排放量 < em > Estal Electric 应为 NaN值(缺失)。你可以争辩说它应该设置为0-但是电动汽车不能产生二氧化硫。计算价值会毁了你的预测。

正如在 这篇文章中提到的,scikit-learn 的决策树和 KNN 算法是 还不够健壮,用于处理缺失的值。如果归咎没有意义,那就不要这么做。

对于位于 GeoTIFF 图像边缘的 NoData (显然不能使用邻近像素值的平均值进行插值) ,我用几行代码掩盖了它。请注意,这是在一个波段(VH 波段的哨兵1图像,这是首先转换成一个阵列)。在对初始图像执行了 Random Forest 分类之后,我执行了以下操作:

image[image>0]=1.0
image[image==0]=-1.0
RF_prediction=np.multiply(RF_prediction,image)
RF_prediction[RF_prediction<0]=-9999.0 #assign a NoData value

保存时,不要忘记分配 NoData 值:

class_ds = gdal.GetDriverByName('GTiff').Create('RF_classified.tif',img_ds.RasterXSize,\
img_ds.RasterYSize,1,gdal.GDT_Float32)


RF_ds.SetGeoTransform(img_ds.GetGeoTransform())
srs = osr.SpatialReference()
srs.ImportFromEPSG(32733)
RF_ds.SetProjection(srs.ExportToWkt()) # export coords to file
RF_ds.GetRasterBand(1).SetNoDataValue(-9999.0) #set NoData value
RF_ds.GetRasterBand(1).WriteArray(RF_prediction)
RF_ds.FlushCache()                     # write to disk
RF_ds = None