scikit-learnの「Input contains NaN」の原因と対処
モデルを学習させようとすると、scikit-learnがこう止める。
ValueError: Input contains NaN, infinity or a value too large for dtype('float64').多くのscikit-learnの推定器は、欠損値(NaN)や無限大(inf)をそのまま受け付けない。入力のどこかにそれらが混じっている、というサインだ。
まずどこにNaNがあるか見る
print(X.isna().sum()) # 列ごとの欠損数(pandas)import numpy as npprint(np.isinf(X.to_numpy()).sum()) # inf の数欠損を補完する
行を捨てたくないなら、平均や中央値で埋める。前処理として入れておくのが安全だ。
from sklearn.impute import SimpleImputerimp = SimpleImputer(strategy="median")X_clean = imp.fit_transform(X)inf を先にNaNへ変換する
infは補完の対象にならないので、いったんNaNにしてから埋める。
import numpy as npX = X.replace([np.inf, -np.inf], np.nan)行ごと落とす場合
数が少なく、捨ててよいなら削除する。
X = X.dropna()まとめ
- 原因は特徴量のNaNやinf
isna().sum()とisinfで場所を特定- 残すなら
SimpleImputerで補完、infは先にNaNへ変換 - 捨ててよいなら
dropna - 補完は学習用と本番で同じ基準を使う(fitした補完器を使い回す)