🐍

【Python】カテゴリ変数をターゲットエンコーディングする方法

2024/02/19に公開

はじめに

この記事ではカテゴリ変数をターゲットエンコーディングする方法を紹介します。

ライブラリのインポート

まずはライブラリをインポートします。
※ここにはコード実行に必要なライブラリしか載せていませんので注意してください

from sklearn.model_selection import KFold

カテゴリ変数をターゲットエンコーディングする

それではカテゴリ変数をターゲットエンコーディングしていきます。

%%time

"""
categorical_columns:カテゴリ変数を格納したリスト
"""
# 目的変数を置き換える数値をディクショナリで用意しておく
target_mapper = {'A' : 0,
                 'B' : 1,
                 'C' : 2,
                }

# 絶対コピーが必要なわけではなく、念のためコピー先で実行しています
train_copy = train.copy(deep = True)
test_copy  = test.copy(deep = True)
    
# 目的変数を数値に変換する
train_copy["target_column"] = train_copy["target_column"].map(target_mapper)\
                                                         .astype(np.uint8)

for c in categorical_columns:
        
    # まずは学習データ全体を使って「テストデータ」のtarget encodingを行う
    data_tmp    = pd.DataFrame({c : train_copy[c], 'target' : train_copy["target_column"]})
    # tmp:temporary(一時的な)の略

    # 学習データ全体で各カテゴリにおけるtargetの平均を計算
    target_mean = data_tmp.groupby(c)['target'].mean()
    # 「テスト」データのカテゴリを置換 ※今回は置換ではなく列名を変えて新しく作った
    test_copy[f'{c}_target_enc'] = \
                   test_copy[c].map(target_mean)
            
            
    # 次に、「学習データ」をout of foldを用いてtarget encodingを行う
    # 「学習データ」の変換後の値を格納する配列を準備
    tmp         = np.repeat(np.nan, train.shape[0])
    # 学習データを分割
    kf          = KFold(n_splits = 4, shuffle = True, random_state = 0)
    for idx_1, idx_2 in kf.split(train_copy):
        # out of foldで各カテゴリにおける目的変数の平均を計算
        target_mean = data_tmp.iloc[idx_1].groupby(c)['target'].mean()
        # 変換後の値を一時配列に格納
        tmp[idx_2]  = train_copy[c].iloc[idx_2].map(target_mean)

    #※今回は置換ではなく列名を変えて新しく作った        
    train_copy[f'{c}_target_enc'] = tmp
print()
collect()

参考にした書籍

※この記事は技術評論社の「Kaggleで勝つデータ分析の技術」を読んで私がアレンジしたコードを記載しています。Kaggleのコンペディションに参加している人であればみんな持っているといっても過言ではない名著だと思います。分析において必要とされる基本的な知識からこれまでのコンペディションの中で蓄積された様々なテクニックまでが丁寧にまとめられています。買って損をしない良質な参考書なので、コンペに挑戦したい!という人も、データサイエンスに興味があるという人もお手に取ってみてください。※画像をクリックするとリンクに飛びます

記事が役に立ったという方は「いいね」を押していただけると、すごく喜びます 笑
ご協力のほどよろしくお願いします

Discussion