# Box-cox変換を用いて正規分布に従わないデータを解析してみよう！

> 当サイト【スタビジ】の本記事では、正規分布に従っていないデータの変換に非常に便利なBox-cox変換について見ていきます。パラメトリック手法による解析を行う上ではBox-coxなどデータ構造を変化させるのは有用なのでぜひ学んでおきましょう！

- URL: https://toukei-lab.com/box-cox%e5%a4%89%e6%8f%9b%e3%82%92%e7%94%a8%e3%81%84%e3%81%a6%e6%ad%a3%e8%a6%8f%e5%88%86%e5%b8%83%e3%81%ab%e5%be%93%e3%82%8f%e3%81%aa%e3%81%84%e3%83%87%e3%83%bc%e3%82%bf%e3%82%92%e8%a7%a3%e6%9e%90
- 公開: 2022.11.29 / 更新: 2025.02.06
- サイト: スタビジ（https://toukei-lab.com）

:::talk{who="umatan"}
本記事では、正規分布に従っていないデータの変換に非常に便利なBox-cox変換（ボックスコックス変換）について見ていきます。パラメトリック手法による解析を行う上ではBox-coxなどデータ構造を変化させるのは有用なのでぜひ学んでおきましょう！
:::

こんにちは！

あるデータに対して<mark>**[線形回帰分析](/%e5%9b%9e%e5%b8%b0%e5%88%86%e6%9e%90)**（一般的に用いられる重回帰分析）を行ってみたけど上手くいかない・・・</mark>

そんなことよくありますよね！

:::talk{who="robotan"}
あるある！！
:::

:::talk{who="umatan"}
実はそれって**データの構造に問題がある**ことが多いんだ！
:::

<mark>なんでも線形回帰分析を適応していいわけではないんです。</mark>

この記事では、実際にデータによってはどのような問題が発生してしまうのか、どのように解決していけばよいのか見ていきましょう！

以下のYoutube動画でも詳しく解説しています！

::youtube{#HutemEzOFbY}

## どんな問題があるの？

一般的に良く用いられる線形回帰分析というのは、<mark>データが**正規分布に従う**という仮定を置いているんですね！</mark>

※厳密には残差が正規分布に従う

正規分布というのはこんな分布！

![](/wp-content/uploads/2018/01/gaus.png)

[統計学](/statistics)で最も良く出てくる分布ですね！

データの分布がこのようになっていないと<mark>**上手く線形回帰分析が当てはまらない**んです！</mark>

でも実際世の中のデータはこんなきれいな正規分布に従っていないものばかり！

## Box-Cox変換で解決！

![](/wp-content/uploads/2019/03/a94310ed4de4a08528a026f0badfdb2f_s-e1556972696222.jpg)

それでは、どうすればよいのでしょうか？

このようにデータの従う分布が決められているような<mark>線形回帰分析などの手法を**パラメトリックモデル**と呼びます。</mark>

これに対して、最近流行りの機械学習手法は**ノンパラメトリックモデル**と呼ばれ、背後に分布を想定していないものが多いです。

だから[ランダムフォレスト](/%e3%83%a9%e3%83%b3%e3%83%80%e3%83%a0%e3%83%95%e3%82%a9%e3%83%ac%e3%82%b9%e3%83%88)や[サポートベクター回帰](/svm)などのノンパラメトリックモデル手法を使って解析することは一つの手でしょう！

ただ、<mark>やはりデータの構造が分かるならそれに沿った解析を行いたいし、パラメトリックモデルの方が解析結果の解釈が容易です。</mark>

そこで大きく分けて二つの方法が存在します。

一つは、**正規分布でない分布を背後に仮定した回帰手法を用いること。**

[ポアソン回帰](/poisson-regression)などがその例ですね。

あとはそれらの回帰分析を混合した一般化線形混合モデルなども存在します。

これらに関しては、以下の記事で詳しく取り上げておりますので良かったら見てみてください！

<https://toukei-lab.com/%E7%B5%B1%E8%A8%88%E3%83%A2%E3%83%87%E3%83%AB>

そして二つ目は、**データの構造を無理やり正規分布に変換しちゃう**というもの！

**Box-Cox変換**と呼びます。

定義は以下の通りです。

\begin{eqnarray}\
{y}^\lambda\
\=\
\begin{cases}\
\frac{ {y}^\lambda-1 }{ \lambda } & ( \lambda \neq 0 ) \\\\\
log{(y_i)} & ( \lambda = 0 )\
\end{cases}\
\end{eqnarray}

でもこのBox-cox変換はなんでもかんでも変換しちゃえば良いというものではなくて<mark>**説明変数がある程度正規分布に従わないと目的変数を正規変換してもあまり意味ない**んです。</mark>

また、Box-cox変換の弱点は定義をみれば分かると思いますが、負の値は変換できないということ。

これを改善してくれたのが**Yeo-Johnson変換**です。

定義は以下の通り。

\begin{eqnarray}\
{y}^\lambda\
\=\
\begin{cases}\
\frac{{y+1}^\lambda-1}{\lambda} & ( \lambda \neq 0 , y\geq0) \\\\\
log{(y+1)} & ( \lambda = 0 , y\geq0)\\\\\
\frac{-\[(-y+1)^{2-\lambda}-1]}{(2-\lambda)}& ( \lambda \neq 2 , y\lt0)\\\\\
-log{(-y+1)} & ( \lambda = 2 , y\lt0)\\\\\
\end{cases}\
\end{eqnarray}

複雑そうに見えますが、そんなこともないですよー！

でもあんまり使わないかなーという印象です。

ちなみにBox-cox変換は、Rで簡単に実装できます。最適な$\lambda$もRで一発で求めることができちゃうんです！

具体的には、carパッケージのpowerTransformという関数を用いて、$\lambda$を推定し、bcPower関数で変換を行います。

Yeo-Johnson変換もパッケージありますが、ここでは取り上げません。

それでは、<mark>実際に実データを用いて解析を行ってみましょう！</mark>

:::talk{who="umatan"}
Let’s 実装！！
:::

## Box-Cox変換を用いて実データ解析

今回用いるデータは北京における**大気汚染PM2.5**です。

中国における大気汚染の問題は日に日に深刻になっていますが、過去のデータから将来のPM2.5の値は予測することができるのでしょうか？

解析するデータの構造は以下の通り。

:::box
12個の変数、41757個のサンプル

Year\:年\
Month：月\
Day：日\
Hour：時間\
DEWP：露点\
TEMP：気温\
PRES：気圧\
Cbwd：風向き\
Iws：風速\
Is：降雪量\
Ir：降雨量\
Pm2.5：PM2.5の濃度
:::

このデータでは、PM2.5の濃度を目的変数、年を除いた他の10の変数を説明変数として解析を行います。

先ほども申し上げましたが、解析の目的としては<mark>現状観測されているPM2.5の濃度から将来のPM2.5を予測する</mark>というもの。

サンプルは、2010年1月1日～2014年12月31日まで存在し、1時間ごとに測定されています。

2010年1月1日～2013年12月31日の4年間のデータから2014年1月1日～2014年12月31日までの各時間のpm2.5の濃度を予測します。

まず、データを取り込み、学習データと予測データに分けます。

その後回帰分析を行い、予測値と観測値の差を計算します。

ここで用いる評価指標はRMSEと呼ばれるもので、予測値と観測値の差の二乗和の平均に平方根をとったものです。

予測精度の評価指標としてよく用いられます。

```text title="Beijing1"
library(dplyr)
library(car)

data<-read.csv("Beijing_PM2.5.csv")
data2<-data%>%filter(pm2.5!="NA")#欠損値削除
data2<-data2[,-1]
data.train<-data2%>%filter(year!="2014")#学習データ作成
data.test<-data2%>%filter(year=="2014")#テストデータ作成

#スタンダードな回帰
result<-lm(pm2.5~.,data=data.train[,-1])#回帰モデル作成
pre<-predict(result,data.test)#予測値
rmse1<-sqrt(mean((data.test$pm2.5-pre)^2))#RMSEを計算
```

RMSEの値は**81.098**となりました。

うーん、PM2.5に関して詳しく見てみると、最小の値が0で、最大の値が994、標準偏差が92であるため、<mark>相当ばらつきの大きいデータとなっていることがわかります。</mark>

ここで、ヒストグラムを描いてみると以下のようになります。

![](/wp-content/uploads/2018/01/b28f2bb7be234e1ef7c2ca59975470d6.png)

全く正規分布になっていませんね！**カイ二乗分布**に近いようです。

ここで、**Box-cox変換の出番**！！<mark>変換を施し再度計算してみましょう！</mark>

```text title="Beijing2"
#Box-cox変換を施した回帰
y1=(data.train$pm2.5+0.1)#0を無くすためのの補正
p1<-powerTransform(y1)
data.train[,5]<-bcPower(y1,p1$lambda)
result<-lm(pm2.5~.,data=data.train[,-1])#回帰モデル作成
pre<-predict(result,data.test)#予測値
pre2<-((pre*p1$lambda)+1)^(1/p1$lambda)
rmse2<-sqrt(mean(data.test$pm2.5-pre2)^2)#RMSEを計算
```

この時、RのpowerTransformだと0の値に対して計算をしてくれないので、0.1をプラスして補正をかけてます。

そんで最終的には定義に従って逆変換を施してます！

この逆変換に関しては、パッケージはないので自分で定義から定式化してみましょう！

実際にRMSEを計算してみると**23.03**になりました！大幅な改善！

ぶっちゃけ他の機械学習手法使った方が予測精度的には良くなるかもしれませんが、アルゴリズムわからずとりあえず使うよりも、<mark>データの構造を把握した上で基本的な手法を用いたほうが解釈容易性も高く、相手に伝えやすかったりします！</mark>

時と場合によって使いわけましょう！

## Box-cox変換　まとめ

![An illustration representing the Box-Cox transformation, a statistical technique used to normalize data. The image features a side-by-side comparison of a skewed dataset before and after transformation, with histograms and probability distributions. Mathematical equations for the Box-Cox transformation are subtly integrated into the background. The design is modern, educational, and visually clear, emphasizing statistical data transformation and normalization.](https://files.oaiusercontent.com/file-88KMoMHVTmzm5MZqLVKAh6?se=2025-02-06T14%3A41%3A21Z\&sp=r\&sv=2024-08-04\&sr=b\&rscc=max-age%3D604800%2C%20immutable%2C%20private\&rscd=attachment%3B%20filename%3D74c1ca2d-5987-4a4a-96e3-692c807c56d2.webp\&sig=cqE8Sbm5jVSmVCCG9H/K/NninRK7BUuZq7xrAOGUk1c%3D)

ここまでご覧いただきありがとうございました！

**Box-cox変換を使ってこんなことができるよ**！というお話でした！

Box-cox変換を行わずに単純なLog変換でも問題ないこともあります。

:::talk{who="robotan"}
簡単にできて、こんなに威力あるのか！！
:::

:::talk{who="umatan"}
簡単でしょ！変換後に分析しているから回帰係数などをそのまま使わないようにね！
:::

データの構造に偏りが見られたときは変換してみましょう！

よりさらに深く統計学や機械学習を学びたい人のために勉強法を以下にまとめていますのでぜひチェックしてみてください！

<https://toukei-lab.com/statistics-freshman>

<https://toukei-lab.com/machine-learning-fresh>

また、当メディアではデータサイエンティストになるための分野を体系的に学ぶスクールを運営しておりますので、データサイエンス全般に興味のある方は是非チェックしてみてください！

:::box
AI/データサイエンス特化スクール：[スタビジアカデミー（スタアカ）](https://toukei-lab.com/achademy/)
:::