1. ホーム
  2. python

scikit-learnでカテゴリカルな欠損値をインプットする

2023-09-27 22:11:01

質問

pandasのデータで、テキスト型のカラムがいくつかあります。これらのテキストカラムと一緒にいくつかのNaN値があります。私がやろうとしていることは、これらのNaNを次の方法でインプットすることです。 sklearn.preprocessing.Imputer (NaNを最も頻度の高い値で置き換える)ことです。問題は実装にあります。 30カラムのPandasデータフレームdfがあり、そのうち10カラムはカテゴリカルな性質を持っているとします。 一度実行すると

from sklearn.preprocessing import Imputer
imp = Imputer(missing_values='NaN', strategy='most_frequent', axis=0)
imp.fit(df) 

Pythonは error: 'could not convert string to float: 'run1'' ここで、'run1'はカテゴリデータを持つ最初の列からの通常の(欠損のない)値です。

どのようなヘルプも非常に歓迎されます。

どのように解決するのですか?

数値列には平均値を、非数値列には最頻値を使うには、次のようにすればよいでしょう。さらに、整数と浮動小数点数を区別することもできます。整数の列には代わりに中央値を使うのが理にかなっているかもしれませんね。

import pandas as pd
import numpy as np

from sklearn.base import TransformerMixin

class DataFrameImputer(TransformerMixin):

    def __init__(self):
        """Impute missing values.

        Columns of dtype object are imputed with the most frequent value 
        in column.

        Columns of other types are imputed with mean of column.

        """
    def fit(self, X, y=None):

        self.fill = pd.Series([X[c].value_counts().index[0]
            if X[c].dtype == np.dtype('O') else X[c].mean() for c in X],
            index=X.columns)

        return self

    def transform(self, X, y=None):
        return X.fillna(self.fill)

data = [
    ['a', 1, 2],
    ['b', 1, 1],
    ['b', 2, 2],
    [np.nan, np.nan, np.nan]
]

X = pd.DataFrame(data)
xt = DataFrameImputer().fit_transform(X)

print('before...')
print(X)
print('after...')
print(xt)

というように印刷します。

before...
     0   1   2
0    a   1   2
1    b   1   1
2    b   2   2
3  NaN NaN NaN
after...
   0         1         2
0  a  1.000000  2.000000
1  b  1.000000  1.000000
2  b  2.000000  2.000000
3  b  1.333333  1.666667