【Python×データ前処理】正規化・標準化による特徴量スケーリング方法解説・機械学習モデル適用

こんにちは、Kosei(@kay_diacc2)です!

機械学習のデータ前処理で実施される「特徴量スケーリング(Feature Scaling)って何?」「重要性とは?」「どうやってスケーリングするの?」本記事ではこれらの質問に回答します。特徴量スケーリングとして代表的な正規化および標準化や、sckit-learnを用いたPythonプログラミング手法も解説しています。

目次

特徴量スケーリング(Feature Scaling)とは?

特徴量のスケーリングとは、機械学習モデルを構築する上で広く用いられるデータの前処理手法であり、「特徴量が取りうる値の範囲を変える・異なる特徴量同士の尺度を統一すること」を意味します。

特徴量スケーリングの重要性

機械学習モデルを構築する上で特徴量のスケーリングは実施した方が良い場合としなくても良い場合があります。その見分け方は「特徴量の尺度の違いが機械学習アルゴリズムに影響を与えるかどうか」で判断します。下記の概念図をもとにイメージを掴んでみましょう。

図:クラスタリングの実例に基づくFeature Scalingの重要性解説

上図では教師なし学習であるクラスタリングを例に挙げています。概念的な例ですが、図の理想・現実を比較すると特徴量の尺度の違いによって異なるグループ分けになっていることが分かります。

クラスタリングや教師あり学習のk近傍方(KNN)・勾配降下法のように、データ間で計算された距離がアルゴリズムに適用される手法は、特徴量スケーリングを実施した前と後で学習モデルの精度改善が期待できるため、特徴量スケーリングが重要と言えるのです。

一方で、決定木やランダムフォレストといった機械学習アルゴリズムのように、特徴量の尺度の違いが学習モデルに影響を及ぼさないものは、Feature Scalingが不要と言えます

特徴量スケーリングの代表的手法

代表的な手法として下記があります。以下1つずつ特徴を見ていきましょう!

  • 正規化(normalization)
  • 標準化(standardization)

正規化(Normalization)

正規化とは特徴量を最小値0, 最大値1の範囲に変換することを意味します。特定の特徴量を正規化する際、下記のような計算を実行します。この方法はmin-maxスケーリングとも呼ばれます。

x(i) norm = x(i) xmin xmax xmin

  • x(i): i番目の変数
  • x(i)norm: 正規化された変数x(i)
  • xminxの最小値
  • xminxの最大値

標準化(Standardization)

標準化とは特徴量の平均値を0、標準偏差を1となるように変換することを意味します。計算方法は下記のように示されます。

x(i) std = x(i) μx σx

  • x(i): i番目の変数
  • x(i)std: 標準化された変数x(i)
  • μxxの平均値
  • σxxの標準偏差

正規化と標準化の使い分け

多くの機械学習アルゴリズムに対して特徴量スケーリングを適用する場合、標準化を行う方が実用的と言われています。理由は標準化の場合、外れ値に関する有益情報を保持できるためです。

正規化の場合は、最大・最小値をもとにスケーリングするため、外れ値の影響によって偏ったスケーリングになることがあります。そのため正規化は、最大値及び最小値が決まっている場合によく利用されます

標準化と正規化の違いを視覚的に理解するためには下記の表が役立ちます。簡易な0~5の数値からなるサンプルデータをスケーリングした結果を示しています。

サンプルデータ 正規化 標準化
0.00 0.00 -1.46
1.00 0.20 -0.88
2.00 0.40 -0.29
3.00 0.60 0.29
4.00 0.80 0.88
5.00 1.00 1.46

Python・scikit-learn|特徴量スケーリング(Feature Scaling)のプロセス

実際にscikit-learnを用いてPythonプログラミングを実行します。下記アプローチに従って実行することとします。

  1. データセットを準備
  2. 正規化・標準化

データセットを準備

データセットの例として下記を活用します。地域・性別・年齢・貯金額という属性情報によって、投資経験に特徴が表れるかを示したものです。適時コードを実行してみましょう。

コード

#ライブラリをインポート
import numpy as np
import matplotlib.pyplot as plt
import pandas as pd
from io import StringIO

#データセットを準備
csv_data = \
'''
Region,Sex,Age,Deposit,Investment
Tokyo,Male,21,200000,No
Osaka,Female,25,2400000,No
Tokyo,Female,30,3200000,Yes
Fukuoka,Male,46,4600000,No
Osaka,Male,57,6500000,Yes
Osaka,Female,60,12000000,Yes
Fukuoka,Male,44,8000000,No
Saitama,Female,18,100000,No
'''

df = pd.read_csv(StringIO(csv_data))
print(df)

初期データイメージ

Region
(地域)
Sex
(性別)
Age
(年齢)
Savings
(貯金額[円])
Investment
(投資経験)
0 Tokyo Male 21 200000 No
1 Osaka Female 25 2400000 No
2 Tokyo Female 30 3200000 Yes
3 Fukuoka Male 46 4600000 No
4 Osaka Male 57 6500000 Yes
5 Osaka Female 60 12000000 Yes
6 Fukuoka Male 44 8000000 No
7 Saitama Female 18 100000 No

特徴量の正規化

特徴量(Age・Savings)をmin-maxスケーリングした場合を示します。下記のように記述してみましょう。

コード

#min-maxスケーリング
from sklearn.preprocessing import MinMaxScaler

#インスタンス
minmax_sc = MinMaxScaler()

#AgeとSavingsを正規化
X = df.loc[:, 'Age':'Savings']

#演算・データ変換
X = minmax_sc.fit_transform(X)

#正規化後のデータ出力
df_norm = df.copy()
df_norm.loc[:, 'Age':'Savings'] = X
print(df_norm)

正規化後出力イメージ

Region
(地域)
Sex
(性別)
Age
(年齢)
Savings
(貯金額[円])
Investment
(投資経験)
0 Tokyo Male 0.07 0.01 No
1 Osaka Female 1.67 0.19 No
2 Tokyo Female 0.29 0.26 Yes
3 Fukuoka Male 0.67 0.37 No
4 Osaka Male 0.92 0.53 Yes
5 Osaka Female 1.00 1.00 Yes
6 Fukuoka Male 0.62 0.66 No
7 Saitama Female 0.00 0.00 No

上記コード個別解説

min-maxスケーリングは、scikit-learnライブラリに実装されているMinMaxScalerクラスを用い、下記のようにインスタンスを生成して実行します。

#min-maxスケーリング
from sklearn.preprocessing import MinMaxScaler

#インスタンス
minmax_sc = MinMaxScaler()

インスタンス生成後、fit_transform()関数に特徴量を渡して正規化します。

#AgeとSavingsを正規化
X = df.loc[:, 'Age':'Savings']
X = minmax_sc.fit_transform(X)

ここでfit_transform()関数とは、特徴量をスケーリングするために必要な統計情報を計算するfit()関数と、fit()関数で計算した結果をもとにデータ変換(正規化)するtransform()関数が一体となったものです。

特徴量の標準化

特徴量(Age・Savings)を標準化した場合を示します。下記のようにコードを記述してみましょう。

コード

from sklearn.preprocessing import StandardScaler

#インスタンス (平均=0, 標準偏差=1)
standard_sc = StandardScaler()

#AgeとSavingsを標準化
X = df.loc[:, 'Age':'Savings']
X = standard_sc.fit_transform(X)

#標準化後のデータ出力
df_std = df.copy()
df_std.loc[:, 'Age':'Savings'] = X
print(df_std)

標準化後出力イメージ

Region
(地域)
Sex
(性別)
Age
(年齢)
Savings
(貯金額[円])
Investment
(投資経験)
0 Tokyo Male -1.08 -1.16 No
1 Osaka Female -0.83 -0.58 No
2 Tokyo Female -0.50 -0.37 Yes
3 Fukuoka Male -0.55 -0.01 No
4 Osaka Male 1.27 0.49 Yes
5 Osaka Female 1.47 1.93 Yes
6 Fukuoka Male 0.42 0.89 No
7 Saitama Female -1.29 -1.19 No

上記コード個別解説

標準化には、scikit-learnのStandardScaler()クラスを用い、下記のようにインスタンスを生成して実行しています。

from sklearn.preprocessing import StandardScaler

#インスタンス
standard_sc = StandardScaler()

まとめ

本記事をご覧いただきありがとうございました!当サイトでは機械学習で用いる前処理手法を多数解説しています。ご覧いただけますと幸甚です。

欠損値の処理について

カテゴリー変数のエンコーディングについて

最後に

この記事が気に入ったら
フォローしてね!

本記事をシェア!
URLをコピーする
URLをコピーしました!
目次
閉じる