LoginSignup
3
5

More than 1 year has passed since last update.

【データ処理】boxcox変換で正規分布に近づける

Last updated at Posted at 2022-05-22

はじめに

機械学習ではデータの分布を正規分布に近づけると、予測精度が改善する場合が多々あります。正規分布に近づける手法の一つとして、boxcox変換が存在します。

boxcox変換

boxcox変換は対数変換などと異なり、多様な分布を正規分布に近づけることが可能であるため、様々なデータに応用可能です。本記事では以下の処理をPythonで実行します。

  • Pythonでboxcox変換を行う
  • boxcox変換後のデータをもとに戻す

boxcox変換の詳細な説明は省略しますが、下記のサイトで分かりやすく説明されています。
Box-cox変換を用いて正規分布に従わないデータを解析をしてみよう!
Box-Cox変換を理解してみる

環境

  • Google Colaboratory Pro

コード

モジュールのimport・変換前のデータ

import pandas as pd
from sklearn.datasets import load_boston
import seaborn as sns
from statistics import mean, median, variance, stdev
from scipy.stats import boxcox
from scipy.special import inv_boxcox

データとしてscikit-learnのBoston house-prices (ボストン市の住宅価格)を使用します。

boston = load_boston()
y = boston.target

変換前の各指標を計算します。

m = mean(y)
med = median(y)
vari = variance(y)
std = stdev(y)
print("平均: ", m)
print("中央値: ", med)
print("分散: ", vari)
print("標準偏差: ", std)
#実行結果
平均:  22.532806324110673
中央値:  21.2
分散:  84.58672359409854
標準偏差:  9.197104087379817

変換前のpriceの分布をヒストグラムで描画します。

sns.distplot(y)

変換前.png

boxcox変換・変換後のデータ

boxcox変換を実行します。

y_boxcox = boxcox(y)

boxcox()の戻り値について調べます。

print(type(y_boxcox),"要素数:",len(y_boxcox))
print("変換後のデータ: \n",y_boxcox[0][:10])
print("λ値: ",y_boxcox[1])
#実行結果
<class 'tuple'> 要素数: 2
変換後のデータ: 
 [4.57293637 4.36558166 5.33694273 5.25495447 5.42860689 4.93592663
 4.48001683 4.81796329 3.85654088 4.10949441]
λ値:  0.2166209012915364

boxcox()の戻り値は要素数2のタプルです。1つ目の要素が変換後の値(リスト)で、2つ目の要素がλ値というboxcox変換にて使用されるパラメータです。このλ値を参照することで変換前の分布に戻すことも可能です。

変換後の各指標を計算します。

m_boxcox = mean(y_boxcox[0])
med_boxcox = median(y_boxcox[0])
vari_boxcox = variance(y_boxcox[0])
std_boxcox = stdev(y_boxcox[0])
print("平均: ", m_boxcox)
print("中央値: ", med_boxcox)
print("分散: ", vari_boxcox)
print("標準偏差: ", std_boxcox)
#実行結果
平均:  4.326198793674132
中央値:  4.329286356920582
分散:  0.6132144144256096
標準偏差:  0.7830800817449066

平均値≒中央値となり正規分布に近づいています。

変換後の分布をヒストグラムで描画します。

sns.distplot(y_boxcox[0])

変換後.png
中央値を中心として左右対称となり、正規分布に近づいています。

inv_boxcox変換・変換後のデータ

変換後のデータを変換前の分布に戻します。戻すにはinv_boxcoxモジュールを使用します。(invはinverseの略で反対の意味です。)

y_inv = inv_boxcox(y_boxcox[0],y_boxcox[1])

inv_boxcox変換後の各指標を計算します。

m_inv = mean(y_inv)
med_inv = median(y_inv)
vari_inv = variance(y_inv)
std_inv = stdev(y_inv)
print("平均: ", m_inv)
print("中央値: ", med_inv)
print("分散: ", vari_inv)
print("標準偏差: ", std_inv)
#実行結果
平均:  22.532806324110673
中央値:  21.199999999999992
分散:  84.58672359409854
標準偏差:  9.197104087379817

boxcox変換前の値に戻っています。

inv_boxcox変換後の分布をヒストグラムで描画します。

sns.distplot(y_inv)

inv変換後.png
分布もboxcox変換前に戻っています。

3
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
3
5