Chapter 07

標準化StandardScaler の実装

(株)ディープブラック
(株)ディープブラック
2022.05.16に更新

ここからは、アイオワ州エイムズ市の住宅のデータセットを用い、
データに対して、標準化を行うことで、その効果を確かめることとする。

データセットの詳細については、Kaggleのこのページ.

Kaggleのページ ダウンロードボタンをクリックします。 これにより、データを含むCSVファイルがダウンロードされます。

課題
アメリカ合州国 アイオワ州 エイムズ市の戸建て住宅の価格を約80個の説明変数から選択し、その価格を予測する。

因みに、赤いエリアがアメリカ合州国 アイオワ州だ。

import pandas as pd
import numpy as np

df = pd.read_csv('AmesHousing.csv')
print(df.columns)

print(df.columns)でデータセットのカラムをみてみよう。

目的変数は、赤線で引っ張った
SalePrice : 住宅価格
であろう。

住宅価格に大きく影響しそうな変数はなんだろう。
LotArea : 敷地面積
GrLivArea: 生活居住面積
OverallQual:素材と仕上がりの総合的な品質
YearBuilt : 建築年
このあたりかな。

今回は、
GrLivArea: 生活居住面積
OverallQual:素材と仕上がりの総合的な品質
を説明変数(特徴量としての入力x)とする。


x = df[['Gr Liv Area', 'Overall Qual']].values  # 説明変数(Numpyの配列)
y = df['SalePrice'].values  # 目的変数(Numpyの配列)

本書のテーマは標準化と正規化であるが、
今回は、sklearn.preprocessingからStandardScalerを標準化として用いる。
標準化は手持ちデータを平均値±1の範囲内に丸めるものだ。
sklearnからStandardScalerをインポートし、インスタス化させてみよう。

from sklearn.preprocessing import StandardScaler
scaler = StandardScaler()

xに対してfit_transformを使ってStandardScalerを適用

x = scaler.fit_transform(x)

xには標準化後の変換された値が入っている。

データをtrain_test_split()を使って分割する。

from sklearn.model_selection import train_test_split
X_train, X_test, Y_train, Y_test = train_test_split(x, y)

次にモデルの訓練を行います。 scikit-learn に用意されている手法の多くは、共通して fit() というメソッドを持っており、 再利用可能なコードが書きやすくなっています。 訓練を実行するには、fit() の引数に入力値 x と目標値 t を与えます。

SGDRegressorを使って回帰問題を解いてみる。
modelと言う変数名で、SGDRegressor()をインスタンス化し、
X_train, Y_trainで学習を開始する。

from sklearn.linear_model import SGDRegressor
model = SGDRegressor()
model.fit(X_train, Y_train)

モデルの精度を確かめる為、X_testを用い、predict()を適用することで、
Y_pred 変数に予想値を格納する。
score()を使用し、X_train, Y_trainでモデルの当てはまりがどの程度あるか、
モデルの精度評価を行う。

モデルの訓練が完了したら、精度の検証を行います。SGDRegressor()クラスは score() メソッドを提供しており、入力値と目標値を与えると訓練済みのモデルを用いて計算した決定係数 (coefficient of determination) という指標を返します。

これは、使用するデータセットのサンプルサイズを
決定係数の最大値は 1 であり、値が大きいほどモデルが与えられたデータに当てはまっていることを表します。

Y_pred = model.predict(X_test)
print('Score', model.score(X_train, Y_train))

score()から出力した値は、
であった。

score()はその値が1に近づけば近づく程、
モデルの当てはまりの良さを表している。

Score 0.7407871483565374
はまずまずの値だと言える。

では、標準化の適応箇所を削除したら、
モデルは上手く学習が行えるのか試してみたい。

from sklearn.preprocessing import StandardScaler
scaler = StandardScaler()
x = scaler.fit_transform(x)

上記3行を削除し、ターミナルで実行してみよう。

Scoreの値は、大幅に下方修正され、データに対してモデルは上手く学習が行えていないことがわかる。

このことから、
手持ちデータに対して、標準化や正規化の前処理を施す必要性を感じていただけたのではないだろうか。

全体のコード

import pandas as pd
import numpy as np
from sklearn.preprocessing import StandardScaler

df = pd.read_csv('AmesHousing.csv')

x = df[['Gr Liv Area', 'Overall Qual']].values
y = df['SalePrice'].values

from sklearn.preprocessing import StandardScaler
scaler = StandardScaler()
x = scaler.fit_transform(x)

from sklearn.model_selection import train_test_split
X_train, X_test, Y_train, Y_test = train_test_split(x, y)

from sklearn.linear_model import SGDRegressor
model = SGDRegressor()
model.fit(X_train, Y_train)

Y_pred = model.predict(X_test)
print('Score', model.score(X_train, Y_train))