【対数変換】Box-Cox変換とYeo-Johnson変換

##目次
[1.はじめに](#1-はじめに)
[2.対数変換とは](#2-対数変換とは)
[3.BoxCox変換](#3-boxcox変換)
[4.YeoJonson変換](#4-yeojonson変換)
[5.最後に](#5-最後に)

## 1. はじめに
特徴量エンジニアリングにおけるBox-Cox変換とYeo-Johnson変換の違いと活用方法について理解しにくかったので自分の備忘録としてまとめた記事です。
なるべく分かりやすくまとめたつもりなので参考にしていただければ幸いです。

## 2. 対数変換とは
対数変換とは、回帰分析（単回帰や重回帰）の中でよく出てくる手法です。
例えば、$y=ax+b$という単純な回帰モデルに対して最小二乗法を行う場合と
$y=ax+b$を対数変換した$log_ey=Alog_ex+B$の形で最小二乗法を行っている場合があります。
では、対数変換はどのような場合に使い、結果にどのような違いがあるのかを以下のデータを用いて確認していきます。


|Data No.  |x  |y  |
|----------|---|---|
|1  |100  |50  |
|2  |200  |100  |
|3  |300  |130 |
|4  |400  |180  |
|5  |500  |210  |
![plot.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/909180/d513bc0b-3c34-bb81-c0cc-86320e61fe14.png)

#### **対数変換をしない場合**
$y = ax+b$について最小二乗法で解いてみます
**最小二乗法の式**
$y-\hat{y}=\frac{σ_{xy}}{σ_x^2}(x-\hat{x})$

より、$y=0.4x+14$が導き出せます。

この回帰式において$x = 400$では$y=0.4×400+14 =174$と予測されます。

#### **対数変換をする場合**
データの対数変換

Data No.  |$log_ex$  |$log_ey$  |
|----------|---|---|
|1  |$log_e100$  |$log_e50$  |
|2  |$log_e200$  |$log_e100$  |
|3  |$log_e300$  |$log_e130$|
|4  |$log_e400$  |$log_e180$  |
|5  |$log_e500$  |$log_e210$  |

これを$log_ey=Alog_ex+B$について最小二乗法で解くと以下の式が求められます。
$log_ey=0.8892log_ex-0.1612$

この回帰式において$x = 400$では$log_ey=0.8892×log_e400-0.1612 =5.17$より$y=e^{5.17}=176$と予測されます。

先程の対数変換をしない場合の予測結果が174だったのに対して**結果が変わっている**ことが分かります。

#### **結果が異なる理由**
結論から言うと仮定したいたモデルが違うから結果が異なるということらしいです。
$y = ax+b$では、$x$と$y$が比例しているという:**直線モデル**を仮定して予測を行っています。
これに対して、$log_ey=Alog_ex+B$では、**弾力性が一定のモデル**を仮定して予測を行っています。
（弾力性：$x$と$y$の変化率の比のこと｜(ex)$x$が1%、$y$が2%増えたら弾力性は2となる）

対数変換式における係数Aが弾力性を表している証明を以下に記します。

**【証明】**
$Alog_ex+B=log_ey$について$log_ex$で微分を行う
$$A=\frac{dlog_ey}{dlog_ex}=\frac{\frac{d}{dy}log_eydy}{\frac{d}{dx}log_exdx}=\frac{\frac{dy}{y}}{\frac{dx}{x}}$$
$\frac{dx}{x}$は$x$の変化率、$\frac{dy}{y}$は$y$の変化率を表すため係数Aが変化率の比になっていることが確認できました。

#### **結論**
仮定するモデルによって予測結果が変わるのは分かるが、対数変換によって仮定するモデルがどのように変わるのかを今回確認できました。
また、対数変換を行うことで単位に依存しないという点で回帰分析で係数の比較で使用されることが多いらしいです。
では、**対数変換を一般化したboxcox変換**について次項からやっていきたいと思います。
##3. boxcox変換
box-cox変換は、データ構造を正規分布に変換するというものです。
正規分布に変換するメリットとして
**データ構造の分布を気にせず、正規分布を背後に仮定した回帰手法を用いることができる**という点が挙げられます。

<img width =700 src = "https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/909180/a4d62449-e29d-21b1-8959-6746f0b08ff2.png">


式は以下で表されます。

```math
x_i(λ) = \left\{
\begin{array}{ll}
\frac{x_i^λ-1}{λ} & (λ \neq 0)\\
log(x_i) & (λ = 0)
\end{array}
\right.
```
パラメータ$λ$によって以下のように変化します。
<img width = 600 src = "https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/909180/37a02bc4-6dd5-b33d-c9cc-3a8714f10e2c.png">

図のようにパラメータによって大きく変わることが分かります。このことから、分布測が正規則にできるだけ近づくようなパラメータの最適値を選択しなければいけません。
詳しい数式は以下の記事に乗っています。
[Box-Cox変換の詳細な式（MQL5）](https://www.mql5.com/ja/articles/363)

＊pythonのSciPyでは対数尤度を最大化するようなλを選択している

#### **実験**
![kai2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/909180/081c4ef2-ea26-f436-3f82-19ad87349ead.png)
この分布に対して様々なパラメータでBox-Cox変換を行ってみた。

![ダウンロード (2).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/909180/a1f6203e-9160-cb76-1d61-8ca7fd80fde6.png)
このように、$λ=0.3$のときに正規分布になっていることが確認できた。
*今回の最適パラメータはScipyの自動機能を用いた

## 4. yeojonson変換
Box-Cox変換では、負の値に対応できないという問題点ある。
これを解消したものがYeo-Jonson変換です。

式は以下で表されます。

```math
x_i(λ) = \left\{
\begin{array}{ll}
\frac{(x_i+1)^λ-1}{λ} & (λ \neq 0,x_i \geq0)\\
log(x_i+1) & (λ = 0,x_i\geq0)\\
-\frac{(x_i+1)^{2-λ}-1}{2-λ} & (λ = 0,x_i<0)\\
-log(-x_i+1) & (λ = 0,x_i<0)\\
\end{array}
\right.
```

同じように変換した結果以下のようになった

<img width = 600 src = "https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/909180/9fbfc744-73fe-50fb-071b-2d8f2d6f13a8.png">

## 5. 最後に
今回は、特徴量エンジニアリングで使われる対数変換・Box-Cox変換・Yeo-Jonson変換について取り扱いました。
ここでは、理論について主に話しましたが、調べている過程で、特徴量のスケーリングとして用いることでGBDTの精度があがることが確認されたりなど統計的に使用せずとも活用方法がたくさんある手法だというのが理解でき大変良かったです。

kaggleのHousePeiceで応用している記事を以下に載せておきます。
https://nehori.com/nikki/2019/12/31/post-14406/