Kaggleで勝つ本 -第3章

今日は最近読みだしているKaggle本のアウトプット。

f:id:kawam0t0:20200529181806p:plain



早速やっていきませう。


第3章の数値変換、というところだ。


数値変換せずとも、もちろんそのままモデルの学習に使うことはできるのだが、
実際は、数値変換を行って、モデルを学習させることが多々ある。
GBDTの様に、そこまで数値変換を必要としないモデルもあるはあるが、
場合によってはした方が精度の良いものが出来上がる場合もある。

では、下記よりその手法について書いていく。


標準化

これは一般的というか基本的な数値変換。
誰しもがまず行うものといっても過言ではない。

sklearnのLinerRegressionの様に、線形回帰を行う場合、
特徴量の値が非常に大小大きいと、うまく学習してくれない。
そんな時に、役立つのが、この標準化。
平均を0に、標準偏差を1にしてくれ、数値を変換してくれる。
そうすることで、学習しやすくなる。
注意しなければならないのは、単純に、線形変換を行っただけなので、
グラフの分布自体に変化はない、という点だ。

scaler = StandardScaler()
scaler.fit(train_x[num_cols])

train_x[num_cols] = scaler.transform(train_x[num_cols])
test_x[num_cols] = scaler.transform(test_x[num_cols])

**

非線形変換 Box-Cox変換 Yoe-Johnson変換

一方こちらは、分布さえも変換してしまう、というもの。
場合によってはこちらの方が精度が高く出る場合もある。

Box-Cox変換
こちらは、0ないしマイナスの値をとって数値変換をすることができない(標準化も同様である)点が特徴。

pos_cols = []
#Box_Cox変換
from sklearn.preprocessing import PowerTransformer
#正の値のみの変換になる
for c in num_cols:
    if (train_x[c] >0).all() and (test_x[c] > 0).all():
        pos_cols.append(c)
pt = PowerTransformer(method="box-cox")
pt.fit(train_x[pos_cols])

train_x[pos_cols] = pt.transform(train_x[pos_cols])
test_x[pos_cols] = pt.transform(test_x[pos_cols])

Yoe=Johnson変換
一方こちらの数値変換方法はマイナスの値も、0も取ることができる。

pt = PowerTransformer(method="yeo-johnson")
pt.fit(train_x[num_cols])
train_x[num_cols] = pt.transform(train_x[num_cols])
test_x[num_cols] = pt.transform(test_x[num_cols])
Clipping

外れ値の削除を行う方法。
上限と下限を設定することで、線形回帰等、外れ値に敏感に反応するのを防ぐ。
clip関数を使うことで、第一引数には下限を。第二引数には上限を持ってくる

train_x , test_x = load_data()
p01 = train_x[num_cols].quantile(0.01)
p99 = train_x[num_cols].quantile(0.99)

train_x[num_cols] = train_x[num_cols].clip(p01 , p99 , axis=1)
test_x[num_cols] = test_x[num_cols].clip(p01 , p99 , axis=1)
Bining

Biningとは、あえて連続的な数字をカテゴリー変数とすることで、
one-hot-encoadingしてもいいし、そのまま数字としての特徴量を持ってきてもOK。

train_x["test"] = pd.cut(train["height"],4,labels=False)
train_x.head()
Rank Gauss

これは単純に順位別に並べた後、無理やり正規分布で表す方法。
まさかの標準化、よりも精度がたかくなるらしい…

from sklearn.preprocessing import QuantileTransformer

transformer = QuantileTransformer(n_quantiles=100 ,random_state=42 , output_distribution="normal")
transformer.fit(train_x[num_cols])

train_x[num_cols] = transformer.transform(train_x[num_cols])
test_x[num_cols] = transformer.transform(test_x[num_cols])

ここでは色々な手法をご紹介したが、
個人的に、ClippingとBining、Rank Gaussを使ってみようと思う。


ではまた!