Python機械学習ライブラリScikit-learn その18:ボストン住宅価格のデータを使って、標準化・正規化の両方をやるとどうなるのか試してみる

目次

機械学習ライブラリScikit-learn

前回、機械学習ライブラリScikit-learnのボストンの住宅価格を予想するのにデータを標準化、正規化をした時の予想値と正解値をプロットし、標準化、正規化の効果を可視化してみました。

今回は前回浮かんだ疑問、標準化と正規化の両方をやったらどうなるのか?ということを試してみたいと思います。

もちろんやっていいことなのか、やっていけないことなのか理論はあるのでしょうが、現状ではまだまだ理解が進んでいないので、こういう場合はやってみるのが一番です。

ということで今回もデータのインポートから。

<セル1>

from sklearn.datasets import load_boston
import pandas as pd

boston = load_boston()

df = pd.DataFrame(boston.data, columns=boston.feature_names)

df["MEDV"] = boston.target

df

実行結果

今回は標準化、正規化のやり方を変えていくので事前準備はここまでです。

標準化→正規化、正規化→標準化

ということで標準化と正規化をしていきますが、最初はそれぞれ別に使うプログラムから書いていきましょう。

使うライブラリは標準化と正規化のためのこちらの2つ。

from sklearn.preprocessing import StandardScaler
from sklearn.preprocessing import MinMaxScaler

次に機械学習させるデータとその結果のデータを変数xとyに格納します。

x = df.loc[:, ["CRIM", "RM", "LSTAT"]]
y = df.loc[:, "MEDV"]

機械学習で使うデータはこれまでと同様「CRIM(犯罪率)」、「RM(平均部屋数)」、「LSTAT(低所得者層の割合)」の3つです。

そして標準化、正規化していきます。

std_model = StandardScaler()
x_std = std_model.fit_transform(x)

norm_model = MinMaxScaler()
x_norm = norm_model.fit_transform(x)

最後に使いやすいようpandasのデータフレームに変換します。

std = pd.DataFrame(x_std, columns=["CRIM_std", "RM_std", "LSTAT_std"])
norm = pd.DataFrame(x_norm, columns=["CRIM_norm", "RM_norm", "LSTAT_norm"])

ここまでは標準化、正規化をしただけのもの。

次に標準化→正規化、逆に正規化→標準化し、こちらもpandasのデータフレームに変換します。

x_std_norm = norm_model.fit_transform(x_std)
x_norm_std = std_model.fit_transform(x_norm)

std_norm = pd.DataFrame(x_std_norm, columns=["CRIM_std_norm", "RM_std_norm", "LSTAT_std_norm"])
norm_std = pd.DataFrame(x_norm_std, columns=["CRIM_norm_std", "RM_norm_std", "LSTAT_norm_std"])

これで標準化したもの、正規化したもの、標準化→正規化したもの、正規化→標準化したものの4種類のデータが得られました。

全体としてはこんな感じです。

<セル2>

from sklearn.preprocessing import StandardScaler
from sklearn.preprocessing import MinMaxScaler

x = df.loc[:, ["CRIM", "RM", "LSTAT"]]
y = df.loc[:, "MEDV"]

std_model = StandardScaler()
x_std = std_model.fit_transform(x)

norm_model = MinMaxScaler()
x_norm = norm_model.fit_transform(x)

x_std_norm = norm_model.fit_transform(x_std)
x_norm_std = std_model.fit_transform(x_norm)

std = pd.DataFrame(x_std, columns=["CRIM_std", "RM_std", "LSTAT_std"])
norm = pd.DataFrame(x_norm, columns=["CRIM_norm", "RM_norm", "LSTAT_norm"])
std_norm = pd.DataFrame(x_std_norm, columns=["CRIM_std_norm", "RM_std_norm", "LSTAT_std_norm"])
norm_std = pd.DataFrame(x_norm_std, columns=["CRIM_norm_std", "RM_norm_std", "LSTAT_norm_std"])

グラフ表示してみる

それぞれどう違うのかグラフ表示してみましょう。

まずは「matplotlib」のインポートとマジックコマンドを記述します。

from matplotlib import pyplot as plt
%matplotlib inline

そしてグラフエリアの設定とクリア。

fig=plt.figure(figsize=(8,6))
plt.clf()

それぞれのデータのうち”CRIM(犯罪率)”を散布図として表示してみます。

plt.scatter(y, std["CRIM_std"], label="CRIM_std")
plt.scatter(y, norm["CRIM_norm"], label="CRIM_norm")
plt.scatter(y, std_norm["CRIM_std_norm"], label="CRIM_std_norm")
plt.scatter(y, norm_std["CRIM_norm_std"], label="CRIM_norm_std")

plt.legend()

ということでこんな感じになります。

<セル3>

from matplotlib import pyplot as plt
%matplotlib inline

fig=plt.figure(figsize=(8,6))
plt.clf()

plt.scatter(y, std["CRIM_std"], label="CRIM_std")
plt.scatter(y, norm["CRIM_norm"], label="CRIM_norm")
plt.scatter(y, std_norm["CRIM_std_norm"], label="CRIM_std_norm")
plt.scatter(y, norm_std["CRIM_norm_std"], label="CRIM_norm_std")

plt.legend()

実行結果

あれ?赤と緑の点しか見えません。

つまり標準化→正規化したデータ、正規化→標準化したデータの2種類しか見えていないということです。

一つ一つ見てみましょう。

まずは標準化したデータから。

次に正規化したデータ。

次に標準化→正規化したデータ。

最後に正規化→標準化したデータ。

気づきましたでしょうか?

実は標準化したデータと正規化→標準化したデータは同じグラフになっています。

そして正規化したデータと標準化して正規化したデータが同じグラフになっています。

ということでそれぞれ2つずつグラフ化すると、1つのプロットしか見えなくなってしまっているわけです。

標準化したデータと正規化→標準化したデータ。

正規化したデータと標準化→正規化したデータ。

ちなみに”RM(平均部屋数)”でやっても、”LSTAT(低所得者層の割合)”でやっても同じでした。

本当はこの後、機械学習して予想値の精度を比較しようと考えていたのですが、同じになってしまったので、予想精度も同じになることでしょう。

ということで今回は残念ながら実験失敗となってしまいましたが、色々試していく上でこういうことは多々ありますし、こういった失敗を記事にするのも面白いかなと思います。

そろそろこのボストン住宅価格のデータセットも結構使ってきましたし、次回からは新しいデータセットを使って、さらに機械学習を学んでいきたいと思います。

ではでは今回はこんな感じで。

よかったらシェアしてね!

コメント

コメントする

目次
閉じる