web-dev-qa-db-ja.com

nan / nullを処理するscikit-learnの分類子

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を呼び出すことはできませんか?

編集。これについて考えると、理にかなっています。トレーニング中は問題になりませんが、変数がnullのときにどのように分岐するかを予測するとき多分あなたは両方の方法を分割して結果を平均化できますか?ただし、距離関数がヌルを無視する限り、k-NNは正常に機能するようです。

Edit 2(older and wiser me)一部のgbmライブラリ(xgboostなど)は、この目的のために、二分木ではなく三分木を使用します。 yes/noの決定と、行方不明の決定に対する1人の子に対して。 sklearnは バイナリツリーを使用

35
anthonybell

トレーニングの欠損値とテストセットの両方を含む例を作成しました

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]
27
bakkal

短い答え

欠損値は単に適用できない場合があります。それらを代入することは無意味です。これらの場合、欠損値を処理できるモデルを使用する必要があります。 Scitkit-learnのモデルは欠損値を処理できません。 XGBoostはできます。


Scikit-learnとXGBoostの詳細

この記事 で述べたように、scikit-learnの決定木とKNNアルゴリズムはnot( yet )十分に堅牢です欠損値を処理します。代入が意味をなさない場合は、実行しないでください。

代入が意味をなさない場合の状況を考慮してください。

これは構成例であることに留意してください

車の列(「Danho Diesel」、「Estal Electric」、「Hesproc Hybrid」)およびプロパティの列(重量、最高速度、加速度、出力、二酸化硫黄排出、範囲)。

電気自動車は排気ガスを生成しません-Estal Electricの二酸化硫黄排出量はNaN- value(欠落)。 0に設定する必要があると言えますが、電気自動車は二酸化硫黄を生成できません。値を代入すると、予測が台無しになります。

この記事 で述べたように、scikit-learnの決定木とKNNアルゴリズムはnot( yet )十分に堅牢です欠損値を処理します。代入が意味をなさない場合は、実行しないでください。

7
DannyDannyDanny

DataFrameを使用している場合は、fillnaを使用できます。ここで、不足しているデータをその列の平均に置き換えました。

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