5
5

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

Target Encodingを使ってみた

Posted at

背景

あるテーブルデータのコンペに参加していて、特徴量が少なく、Target Encodingなるものを使って特徴を増やそうと思い、色々探しました。
qiitaには以下の記事があります。

Target Mean Encoding

によると、以下の方法でtarget encodingできるらしいとのこと

# 1
label_mean = df.groupby('category').label.mean()
df = df.assign(target_enc=df['category'].map(label_mean).copy())

# 2
df = df.assign(target_enc2=df.groupby('category')['label'].transform('mean').copy())

やってみると簡単にできました。
ただ、テーブルデータ初心者の私はあるところでつまづきます。そうテストデータです。
テストデータでも同様にgroupbyしてトレインデータと同じようにラベルの平均値を振る必要がありますが、
スマートに行う方法が思いつきません。
変換表を逐一つくるのも面倒です。

適したライブラリを発見する

(個人的に)使いやすいライブラリを見つけました。
Category Encoders

使ってみる

まず、Category Encodersをインストールします。

pip install category_encoders

使ってみましょう

from category_encoders.target_encoder import TargetEncoder
import pandas as pd

df = pd.DataFrame({ 'category': ['A','A','B','B','B','C','C','C','C','D'],
                    'label': [1,0,1,0,0,1,0,1,1,1]
                  })

TE = TargetEncoder()
df["target_enc"] = TE.fit_transform(df["category"],df["label"])

|   | category | label | target_enc|
| 0 |    A     |  1    | 0.526894  |
| 1 |    A     |  0    | 0.526894  |
| 2 |    B     |  1    | 0.365121  |
| 3 |    B     |  0    | 0.365121  |
| 4 |    B     |  0    | 0.365121  |
| 5 |    C     |  1    | 0.742886  |
| 6 |    C     |  0    | 0.742886  |
| 7 |    C     |  1    | 0.742886  |
| 8 |    C     |  1    | 0.742886  |
| 9 |    D     |  1    | 0.600000  |

よくみると結果が少しおかしいですね。というのも、Aは1と0の平均なので0.5にならなければなりません。

これは、自動でsmoothingのデータの水増しが行われているためです。おそらくこのほうがLeakしないのかと思われます。
試しに、smoothingを0.1にしてみます(0にはできないらしいです。)

from category_encoders.target_encoder import TargetEncoder
import pandas as pd

df = pd.DataFrame({ 'category': ['A','A','B','B','B','C','C','C','C','D'],
                    'label': [1,0,1,0,0,1,0,1,1,1]
                  })

TE = TargetEncoder(smoothing=0.1)
df["target_enc"] = TE.fit_transform(df["category"],df["label"])

このように返ってきます

|   | category | label | target_enc |
| 0 |    A     |   1   | 0.500005   |
| 1 |    A     |   0   | 0.500005   |
| 2 |    B     |   1   | 0.333333   |
| 3 |    B     |   0   | 0.333333   |
| 4 |    B     |   0   | 0.333333   |
| 5 |    C     |   1   | 0.750000   |
| 6 |    C     |   0   | 0.750000   |
| 7 |    C     |   1   | 0.750000   |
| 8 |    C     |   1   | 0.750000   |
| 9 |    D     |   1   | 0.600000   |

そして、テストデータに適用する場合は簡単です。transformするだけ。

df_test = pd.DataFrame({ 'category': ['A','B','C','C','D']
                  })
df_test["target_enc"] = TE.transform(df_test)

上記のデータと同じようにエンコーディングされていますね。

  category	target_enc
0	A	    0.500005
1	B	    0.333333
2	C	    0.750000
3	C	    0.750000
4	D	    0.600000
5
5
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
5
5

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?