はじめに
機械学習では,変数の「標準化」というものが出てきますが,この標準化についてよく理解できなかったので調べてみました.また,実際に標準化がある時とない時で比較してみました.
Feature Scalingについて
Feature Scaling とは,特徴量の取りうる値のスケールを変えることであり,その種類として「標準化」と「正規化」があります.データセットの特徴量間でスケールが異なることは多くあります.例えば,体重と慎重,家の価格と部屋数ではその単位と値の範囲が異なります.そのような異なるスケールのデータセットを学習させると,うまく学習できなくなるので,学習前の前処理で特徴量間のスケールを揃える必要があります.
標準化とは
標準化とは,特徴量を標準正規分布(平均を0,分散を1)のスケーリングに合わせる処理のことです.変換の式は,次式となります.
$$x_{std, i} = \frac{x_i-\mu}{\sigma}$$
$$(x_i: 元データ, \mu:平均, \sigma:標準偏差)$$
正規化とは
正規化とは,特徴量の値の範囲を一定の範囲に収める変換で,その範囲は主に[0, 1],または [-1, 1]となります.範囲を[0, 1]にするときの変換式は,次式となります.
$$x_{norm, i}=\frac{x_i - x_{min}}{x_{max}-x_{min}}$$
$$(x_i:元データ, x_{min}:最小値, x_{max}:最大値)$$
標準化と正規化の使い分け
正規化は外れ値の影響が大きいので,基本は標準化を使います.以下が使い分けの例です.
標準化
- ロジスティック回帰、SVM、NNなど勾配法を用いたモデル
- kNN, k-meansなどの距離を用いるモデル
- PCA, LDA(潜在的ディリクレ配分法), kernel PCA などのfeature extractionの手法
正規化
- 画像処理における RGBの強さ [0, 255]
- sigmoid, tanhなどの活性化関数を用いる,NNのいくつかのモデル
使わない時
決定木,ランダムフォレスト
標準化した時としてない時の比較
最後に,irisデータのSVMによる分類において,標準化した時としてない時の正答率を比較していきます.
実行したプログラム
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
% matplotlib inline
# irisデータセットの読み込み
from sklearn.datasets import load_iris
iris = load_iris()
X = iris.data[50:150, [2,3]]
y = iris.target[50:150]
# データの標準化
from sklearn.preprocessing import StandardScaler
scaler = StandardScaler()
scaler.fit(X)
X_std = scaler.transform(X)
from sklearn.model_selection import train_test_split
X_1_train, X_1_test, y_1_train, y_1_test = train_test_split(X, y, test_size=0.3, random_state=0)
X_2_train, X_2_test, y_2_train, y_2_test = train_test_split(X_std, y, test_size=0.3, random_state=0)
# 線形SVCの学習
from sklearn.svm import SVC
svc_1_slack = SVC(kernel='linear', C=1.0)
svc_2_slack = SVC(kernel='linear', C=1.0)
svc_1_slack.fit(X_1_train, y_1_train)
svc_2_slack.fit(X_2_train, y_2_train)
# 正答率を出力
print('標準化なしの場合: %f' % svc_slack.score(X_1_test, y_1_test))
print('標準化ありの場合: %f' % svc_slack.score(X_2_test, y_2_test))
実行結果
標準化なしの場合: 0.500000
標準化ありの場合: 0.966667
以上のように,特徴量を標準化した時の方が,実際に正答率が高くなることを確認することができました.