標準化とは
あるデータを変換して、その平均を0、分散を1にすること
元のデータを$x$とおくと、以下の式で標準化後のデータ$x'$を求めることができる。
($\bar{x}$は平均値、$s$は標準偏差)
$$x'= \frac{x-\bar{x}}{s}$$
標準化した値をz値、あるいは標準化得点と呼ぶ
例
以下のような、10人の身長と体重があったとしてこのデータを標準化してみる。
身長 | 体重 | |
---|---|---|
Aさん | 147.9 | 46.6 |
Bさん | 154.5 | 41.3 |
Cさん | 141.4 | 55.4 |
Dさん | 179.5 | 47.3 |
Eさん | 183.5 | 46.4 |
Fさん | 167.4 | 50.9 |
Gさん | 175.3 | 49.1 |
Hさん | 168.4 | 48.9 |
Iさん | 141.8 | 53.7 |
Jさん | 158.4 | 50.9 |
まずは、身長と体重それぞれの平均と標準偏差を求める
それぞれの平均と標準偏差は、
身長(height)
$$\bar{x}_{height} = \frac{147.9 +154.5+\cdots+158.4}{10} = 161.81$$
$$s_{height} = \sqrt{\frac{(147.9-161.8)^2+(154.5-161.8)^2+\cdots+(158.4-161.8)^2}{10}} = 14.54$$
体重(weight)
$$\bar{x}_{weight} = \frac{46.6 +41.3+\cdots+50.9}{10} = 49.05$$
$$s_{weight} = \sqrt{\frac{(46.6-49.05)^2+(41.3-49.05)^2+\cdots+(50.9-49.05)^2}{10}} = 3.807$$
この値を使ってAさんの標準化した身長、体重を求めてみると
$$x_{height}' = \frac{147.9 - 161.8}{14.54} = -0.956$$
$$x_{weight}' = \frac{46.6 - 49.05}{3.807} = -0.644$$
これをA〜Jさん全てのデータに適用すると標準化された変数が以下のように求められる。
身長 | 体重 | |
---|---|---|
Aさん | -0.956 | -0.643 |
Bさん | -0.502 | -2.035 |
Cさん | -1.403 | 1.667 |
Dさん | 1.216 | -0.459 |
Eさん | 1.491 | -0.696 |
Fさん | 0.384 | 0.485 |
Gさん | 0.927 | 0.013 |
Hさん | 0.453 | -0.039 |
Iさん | -1.375 | 1.221 |
Jさん | -0.234 | 0.485 |
その他
なぜ標準化が必要なのか
- 異なる項目、単位のデータを比較できるようになる。
(例えば、Aさんの身長と体重のどちらが平均から離れているかを比べることができる) - 重回帰分析において切片(定数項)を0と置くことができる。
その他注意点など(データ解析時の)
- 分散が0(全てのサンプルで同じ値を取る変数など)のデータ、変数は標準化ができないため、あらかじめ削除しておく必要がある。
- 機械学習を用いた解析などで、データをトレーニングセットとテストセットに分ける場合には、トレーニング用データの平均と標準偏差を用いて、両セットの標準化を行う必要がある。(参考)
- PCA(主成分分析)を行う場合も基本的に標準化は行った方が良い。(参考)
- センタリング(平均を0)にする操作は必須であり、各変数のデータのスケールが異なる場合には必ずスケーリング(分散を1にする)も行うべき。
python での実行
scikit-learnのメソッドStandardScaler
を使用する
from sklearn.preprocessing import StandardScaler
scaler = StandardScaler()
# 標準化
x_standardized = scaler.fit_transform(df[['身長','体重']])
df_x_standardized = pd.DataFrame(x_standardized,
columns=df.columns,
index=df.index)
df_x_standardized
身長 | 体重 | |
---|---|---|
Aさん | -0.956343 | -0.643479 |
Bさん | -0.502578 | -2.035495 |
Cさん | -1.403232 | 1.667793 |
Dさん | 1.216226 | -0.459628 |
Eさん | 1.491235 | -0.696008 |
Fさん | 0.384325 | 0.485892 |
Gさん | 0.927467 | 0.013132 |
Hさん | 0.453077 | -0.039397 |
Iさん | -1.375731 | 1.221297 |
Jさん | -0.234445 | 0.485892 |
#もとに戻すときは inverse_transform メソッドを使用する。
x_inverse = scaler.inverse_transform(df_x_standardized)
df_inverse = pd.DataFrame(x_inverse,
index=df.index,
columns=df.columns)
df_inverse
身長 | 体重 | |
---|---|---|
Aさん | 147.9 | 46.6 |
Bさん | 154.5 | 41.3 |
Cさん | 141.4 | 55.4 |
Dさん | 179.5 | 47.3 |
Eさん | 183.5 | 46.4 |
Fさん | 167.4 | 50.9 |
Gさん | 175.3 | 49.1 |
Hさん | 168.4 | 48.9 |
Iさん | 141.8 | 53.7 |
Jさん | 158.4 | 50.9 |
以上
参考
- データを標準化してみよう(統計WEB)
- 標準化したデータの使い方(統計WEB)
- クロスバリデーションのとき、変数の標準化はどうするか?(金子研究HP)
- 主成分分析の前に変数の標準化をしたほうがよいのか?(金子研究HP)
参考書籍