70
57

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 Mean Encoding

Last updated at Posted at 2018-11-04

Target Mean Encodingとは

カテゴリカル変数はそのままでは、機械学習モデルの入力にすることができません。
普通は、One Hot Encoding(ダミー変数化)をするかと思います。(自分はこれしか知りませんでした。)

カテゴリカル変数のEncoding手法の一つであるTarget Mean Encoding(Likelihood Encoding)は、目的変数の情報を利用し、カテゴリカル変数を数値に変換する方法で、Kaggle等の機械学習コンペではよく用いられているようです。
目的変数がBoolean表現の場合、カテゴリごとの確率を、数値であればカテゴリごとの平均を特徴量とします。

実行例

例として、以下のようなデータセットでTarget Mean Encoding(以下、Target Encoding)を試してみます。

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]
                  })
  category  label
0        A      1
1        A      0
2        B      1
3        B      0
4        B      0
5        C      1
6        C      0
7        C      1
8        C      1
9        D      1

Pandasのgroupbyを使った実行方法を試してみます。
方法は以下の2つです。

# 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())

得られる結果はこちらです。

  category  label  target_enc  target_enc2
0        A      1    0.500000     0.500000
1        A      0    0.500000     0.500000
2        B      1    0.333333     0.333333
3        B      0    0.333333     0.333333
4        B      0    0.333333     0.333333
5        C      1    0.750000     0.750000
6        C      0    0.750000     0.750000
7        C      1    0.750000     0.750000
8        C      1    0.750000     0.750000
9        D      1    1.000000     1.000000

Target Encodingできていることが確認できました。

Leakageについて

Leakageとは、モデルを学習する際に、本来知らないはずの情報を不当に使ってしまうことです。
Kaggleのドキュメントには、Leakageについての項目が設けられています。
ここでは以下の具体例が挙げられています。

  • 患者が前立腺癌かどうかを予測するためのデータに「前立腺の手術を受けたか」という変数を含めていた

Target Encodingでは、学習データで得られた各カテゴリの特徴量をテストデータ内の各カテゴリに適用します。これが、Leakageが引き起こしてしまいます。
本記事では、Leakageによる過学習を防ぐための手法について、2つ紹介します。

Leave One Out(LOO)

この手法は、値を計算するときに、その行データ以外で計算するというものです。

通常のTarget Encoding

category label target_enc
0 A 1 0.50
1 A 0 0.50
2 B 1 0.33
3 B 0 0.33
4 B 0 0.33
5 C 1 0.75
6 C 0 0.75
7 C 1 0.75
8 C 1 0.75
9 D 1 1.00

Target Encoding with LOO

category label target_enc
0 A 1 0.00
1 A 0 1.00
2 B 1 0.00
3 B 0 0.50
4 B 0 0.50
5 C 1 0.66
6 C 0 1.00
7 C 1 0.66
8 C 1 0.66
9 D 1 0.00

Cについて見てみましょう。
5行目のCのtarget_encは

(0+1+1)/3 = 2/3 = 0.66

となります。
また、6行目のCのtarget_encは

(1+1+1)/3 = 3/3 = 1.00

となります。

ただ、この手法だと余計にLeakageを起こしているように見えます。
(例えばBについて、labelの0, 1がtarget_encの0.5, 0に対応してしまっている)

Smoothing

この手法は、データ数が少ないカテゴリを持つカテゴリカル変数に対して効果的にTarget Encodingを用いるための手法です。
データ数が十分あるカテゴリについては通常のTarget Encodingに近い値を示し、データ数が少ないカテゴリについてはデータセット全体での値に近づくようにスムージングを行います。
詳しく知りたい方は、こちらのブログがわかりやすいです。


S_i = λ(n_i)\frac{n_iy}{n_i}+(1−λ(n_i))\frac{n_y}{n_tr}\\

λ(n_i) = \frac{1}{1+exp(-\frac{n_i−k}{f})}

k=0, f=1(λは標準シグモイド関数になる)でカテゴリA,Bについて計算してみると、以下のようになります。


λ(2) = \frac{1}{1+exp(-2)} = 0.880\\

S_A = 0.880*\frac{1}{2} + (1−0.880)*\frac{6}{10} = 0.512


λ(3) = \frac{1}{1+exp(-3)} = 0.953\\

S_B = 0.953*\frac{1}{3} + (1−0.953)*\frac{6}{10} = 0.346

変換時の注意点

以下でも実行できますが、どちらも警告が出ます。

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

# 2
df['target_enc2'] = df.groupby('type')['label'].transform('mean')
SettingWithCopyWarning: 
A value is trying to be set on a copy of a slice from a DataFrame.
Try using .loc[row_indexer,col_indexer] = value instead

See the caveats in the documentation: 
http://pandas.pydata.org/pandas-docs/stable/indexing.html#indexing-view-versus-copy

ドキュメントの注意事項を参照しても、どう対応すればいいのかわからなかったのですが、
実行例で示したようにすることで警告は出なくなりました。

参考

[カテゴリカル変数のEncoding手法について]
(http://nami3373.hatenablog.com/entry/2018/07/26/230655)

[Feature Enginnering]
(https://www.slideshare.net/0xdata/feature-engineering-83511751)

[TargetEncodingのスムーシング]
(https://mikebird28.hatenablog.jp/entry/2018/06/14/172132)

70
57
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
70
57

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?