MICE、KNNによる欠損値処理

参考資料:



欠損値処理時の注意点:

まず以下の点を確認すること

  • 欠損値の意味: 
     欠損値が必ずしも欠損値を示さず、ただの『該当無し』を示す場合がある。その場合は、欠損値として扱わず、該当なしであることを意味するように'None'とかの文字列とか、数値なら0で補完する。なので、まずは、変数毎にその欠損値の意味を確認すること!
  • 欠損値の数:
     欠損値が15~20%以上あるような変数は、補完せずに削除した方が無難。推定で保管しようとすると大分ズレる危険がある。
  • 欠損値は、ランダムに発生しているか、パターンがあるか?



MICE(連鎖方程式による多重代入法)とは:


利用ライブラリ:

from sklearn.experimental import enable_iterative_imputer # ※このライブラリも必要

from sklearn.impute import IterativeImputer

https://scikit-learn.org/stable/modules/generated/sklearn.impute.IterativeImputer.html


手順:

    1. 欠損値を除いたカテゴリカル変数を順序変数に数値化
    2. IterativeImputer()インスタンスで欠損値埋める
    3. データフレームに反映する


コード例:

※ 下記例では、訓練データとテストデータを合体したデータで欠損値を補完している。(なので、訓練データとテストデータどちらも一緒に補完している。


# 対象データ

# MICE imputation用に、categorical変数を数値化する

MICE_combined_data = combined_df.copy()

# Categoricalデータ(文字列)取り出し

Cat_data = MICE_combined_data[object_list]

・Cat_data の内容

# -- すべてのCategorcal変数を、欠損値のある状態でOrdinal Encodingする

# MICE imputation用に、categorical変数を数値化する

MICE_combined_data = combined_df.copy()


# Categoricalデータ(文字列)取り出し

Cat_data = MICE_combined_data[object_list]


# Ordinal Encodersインスタンス用の辞書作成

ordinal_enc_dict = {}


# -- 変数をすべてエンコーディング

for col_name in Cat_data:

  # 変数毎のordinal encoderインスタンス作成

  ordinal_enc_dict[col_name] = OrdinalEncoder()

  # 欠損値以外のデータ取り出し

  col = Cat_data[col_name]

  col_not_null = col[col.notnull()]

  reshaped_vals = col_not_null.values.reshape(-1, 1)

  # 欠損値以外のデータをエンコーディング

  encoded_vals = ordinal_enc_dict[col_name].fit_transform(reshaped_vals)

  # カテゴリ値をエンコーディング結果と入れ替え

  Cat_data.loc[col.notnull(), col_name] = np.squeeze(encoded_vals)

# dfに反映

MICE_combined_data[object_list] = Cat_data

# -- MICEで欠損値の補完(全データを渡すことで、欠損値が全て埋まる)

# MICEで欠損値補完

from sklearn.experimental import enable_iterative_imputer # ※このライブラリも必要

from sklearn.impute import IterativeImputer

MICE_imputer = IterativeImputer(max_iter=200)

# 上記のmax_iterのデフォルトは10だが、このサイトによるとモンテカルロ法による推定のため、200ぐらいはイテレーションをした方が良いらしい!!!

MICE_imputed_data = MICE_imputer.fit_transform(MICE_combined_data)

# ※カテゴリカル変数に補完する時は、整数を入れたいのでfit_transformの結果をnp.round()で丸めた値を使う。-> 補 参照

# dfに反映

MICE_combined_data.iloc[:,:] = MICE_imputed_data


補:np.round()で整数にして補完する場合

MICE_imputed_data = pd.DataFrame(np.round(MICE_imputer.fit_transform(MICE_combined_data)), columns=MICE_combined_data.columns)

欠損値補完状況の確認

ヒストグラムで補完前後の分布状況を確認

g = sns.kdeplot(combined_df['LotFrontage'], color='Red', shade=True)

g = sns.kdeplot(MICE_combined_data['LotFrontage'], color='Blue', shade=True)

g.set_xlabel('LotFrontage')

g.set_ylabel('Frequency')

g.set_title('imputation by MICE')

g = g.legend(['before imputation', 'after imputation'])

ちなみに、最頻値で補完した結果が以下のグラフ。

g2 = sns.kdeplot(combined_df['LotFrontage'], color='Red', shade=True)

g2 = sns.kdeplot(MeMo_combined_data['LotFrontage'], color='Blue', shade=True)

g2.set_xlabel('LotFrontage')

g2.set_ylabel('Frequency')

g2.set_title('imputation by Mode')

g2 = g2.legend(['before imputation', 'after imputation'])

最頻値で補完した方は、最頻値の頻度がおおきくなってしまっている。



KNNによる欠損値補完

利用ライブラリ

from sklearn.impute import KNNImputer

※1 kの数など、パラメーターが複数有るが、そのへんはマニュアル参照

※2 kの数を適切に設定しないと、いい具合に補完できない。kaggleの住宅価格予想で使ってみたら、中央値・最頻値で補完したものよりスコアが悪かった・・・。kの数の設定は色々試す必要があるので、MICE選んでた方がいいかのかもしれない。

コード例)

KNN_combined_dataは、pandas.DataFrameでカテゴリカル変数は数値変換済み。

# KNNで欠損値補完

KNN_imputer = KNNImputer() # デフォルトのkの数は5

KNN_imputed_data = KNN_imputer.fit_transform(KNN_combined_data)


機械学習Tips保管庫

データ解析、機械学習のための学習内容の保管庫。復習用。

0コメント

  • 1000 / 1000