【问题标题】:classifiers in scikit-learn that handle nan/nullscikit-learn 中处理 nan/null 的分类器
【发布时间】:2015-07-30 18:41:55
【问题描述】:

我想知道在 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 算法调用 predict 吗?

编辑。 现在想来,这也是有道理的。在训练期间这不是问题,但是当您预测变量为空时如何分支时?也许您可以将两种方式分开并平均结果?只要距离函数忽略空值,k-NN 似乎应该可以正常工作。

编辑 2(年长且聪明的我) 一些 gbm 库(例如 xgboost)正是为此目的使用三叉树而不是二叉树:2 个孩子用于是/否决策,1 个孩子用于缺失决策。 sklearn 是using a binary tree

【问题讨论】:

  • 我也遇到了这个问题,我想你需要删除nan 值和this class 也源this 但我仍然无法解决这个问题。可能this 会有所帮助。
  • 这里的问题是NaN应该如何在这里表示?这是一个常见问题,您需要决定如何处理它们,您可以删除它们或用平均值或其他指示值替换它们
  • 听说有些随机森林模型会忽略具有nan值的特征,使用随机选择的替代特征。不过,这似乎不是 scikit learn 中的默认行为。有没有人建议如何实现这种行为?它很有吸引力,因为您不需要提供估算值。
  • @Chogg - 看起来像“统计学习的要素”第 311 页建议(使用“代理变量”)作为添加缺失类别或估算值的替代方法,但我不知道有任何库不过这样做...
  • @anthonybell - 是的,同一本书也把我带到了这里。没有实现这种方法的库是否暗示使用代理变量不是一种有效的方法?

标签: python pandas machine-learning scikit-learn nan


【解决方案1】:

我做了一个例子,其中包含训练和测试集中的缺失值

我刚刚选择了一种策略,使用 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]

【讨论】:

  • 当值是真正的标签而不是连续的情况下,你如何处理?
  • 我真的很想看看插补如何适用于分类数据。
  • 适用于许多数据集的超粗略方法,尤其是在数据没有随机缺失或缺失率非常高的情况下。
  • 好的,正在估算。但是 RandomForest 必须在没有任何插补的情况下处理 nan 呢?
【解决方案2】:

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

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

【讨论】:

    【解决方案3】:

    简答

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


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

    this article 中所述,scikit-learn 的决策树和 KNN 算法不够 (yet) 稳健 无法处理缺失值。如果插补没有意义,请不要这样做。

    在估算没有意义时考虑情景。

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

    考虑一个包含汽车行(“Danho Diesel”、“Estal Electric”、“Hesproc Hybrid”)和列及其属性(重量、最高速度)的数据集, 加速度, 功率输出, 二氧化硫排放, 范围)。

    电动汽车不会产生废气 - 因此Estal Electric二氧化硫排放应该是NaN-值(缺失)。您可能会争辩说它应该设置为 0 - 但电动汽车不能产生二氧化硫。估算值会破坏您的预测。

    this article 中所述,scikit-learn 的决策树和 KNN 算法不够 (yet) 稳健 无法处理缺失值。如果插补没有意义,请不要这样做。

    【讨论】:

      【解决方案4】:

      对于位于 GeoTIFF 图像边缘的 NoData(显然不能使用相邻像素值的平均值进行插值),我用几行代码对其进行了屏蔽。请注意,这是在一个波段上执行的(Sentinel 1 图像的 VH 波段,它首先被转换为一个数组)。在对初始图像执行随机森林分类后,我执行了以下操作:

      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
      

      【讨论】:

        猜你喜欢
        • 2016-02-02
        • 2020-01-28
        • 2016-02-07
        • 2018-11-13
        • 2014-02-17
        • 2020-10-06
        • 1970-01-01
        • 2016-01-05
        • 2012-10-15
        相关资源
        最近更新 更多