scikit-learn に欠損値を持つことは可能ですか? それらはどのように表現されるべきですか?それに関するドキュメントは見つかりませんでした。
7 に答える
欠損値は、scikit-learn ではサポートされていません。これについては以前にメーリング リストで議論がありましたが、実際にそれらを処理するコードを書く試みはありませんでした。
何をするにしても、 NaN を使用して欠損値をエンコードしないでください。アルゴリズムの多くは、NaN を含むサンプルの処理を拒否するためです。
上記の回答は時代遅れです。scikit-learn の最新リリースには、Imputer
機能ごとの単純な欠損値代入を行うクラスがあります。NaN を含む配列をフィードして、対応する機能の平均、中央値、またはモードに置き換えることができます。
簡単な例を提供できればと思いますが、RandomForestRegressor がNaN を適切に処理しないことがわかりました。NaN のパーセンテージが増加する機能を追加すると、パフォーマンスは着実に悪化します。「多すぎる」 NaN を持つ機能は、nan が非常に有用な情報を示している場合でも、完全に無視されます。
これは、アルゴリズムが決定「isnan」または「ismissing」で分割を作成しないためです。アルゴリズムは、ツリーの特定のレベルにある特徴がサンプルのサブセットに単一の NaN を持つ場合、その特徴を無視します。ただし、ツリーの下位レベルでは、サンプル サイズが小さい場合、サンプルのサブセットが特定の特徴の値に NaN を持たない可能性が高くなり、その特徴で分割が発生する可能性があります。
この問題に対処するためにさまざまな代入手法を試しました (平均値/中央値に置き換える、別のモデルを使用して欠損値を予測するなど) が、結果はまちまちでした。
代わりに、これが私の解決策です: NaN を単一の明らかに範囲外の値 (-1.0 など) に置き換えます。これにより、「未知の値と既知の値」という基準でツリーを分割できます。ただし、このような範囲外の値を使用すると、奇妙な副作用があります。アルゴリズムが適切な場所を見つけようとするときに、範囲外の値に近い既知の値が範囲外の値と一緒にまとめられる可能性があります。分割します。たとえば、既知の 0 は、NaN を置き換えるために使用される -1 とひとまとめにすることができます。そのため、範囲外の値が最小値より小さいか最大値より大きいかによって、モデルが変わる可能性があります (それぞれ、最小値または最大値にまとめられる可能性があります)。これは、手法の一般化に役立つ場合とそうでない場合があります。
データに対してRandomForestRegressorを実行すると、非常によく似た問題に遭遇しました。NA 値の存在は、予測のために「nan」を捨てていました。いくつかの議論をスクロールして、Breiman によるドキュメントでは、連続データとカテゴリ データのそれぞれに対して 2 つのソリューションを推奨しています。
- 列(機能)からデータの中央値を計算し、これを使用します(連続データ)
- 最も頻繁に発生するカテゴリを決定し、これを使用します (カテゴリ データ)
Breiman 氏によると、アルゴリズムのランダムな性質と木の数により、予測の精度にあまり影響を与えずに修正が可能になります。これは、NA値の存在がまばらである場合に当てはまり、多くのNA値を含む機能が影響を与える可能性が最も高いと思います.
欠落している値を平均/中央値/その他の統計で置き換えても、値が欠落しているという事実が重要である可能性があるため、問題が解決しない場合があります。たとえば、身体的特徴に関する調査では、回答者が異常に背が高かったり小さかったりすることを恥ずかしく思う場合、身長を記入しない場合があります。これは、欠損値が、回答者が異常に背が高いか小さいことを示していることを意味します。これは、中央値の反対です。
必要なのは、欠損値に対して別のルールを持つモデルです。欠損値を推測しようとすると、モデルの予測力が低下する可能性があります。
例えば:
df['xvariable_missing'] = np.where(df.xvariable.isna(),1,0)
df.xvariable = df.xvariable.fillna(df.xvariable.median())