データの標準化とは(pythonコードあり)

標準化とは

あるデータを変換して、その平均を0、分散を1にすること

元のデータを$x$とおくと、以下の式で標準化後のデータ$x'$を求めることができる。
($\bar{x}$は平均値、$s$は標準偏差)

$$x'= \frac{x-\bar{x}}{s}$$

標準化した値をz値、あるいは標準化得点と呼ぶ

以下のような、10人の身長と体重があったとしてこのデータを標準化してみる。

身長体重
Aさん147.946.6
Bさん154.541.3
Cさん141.455.4
Dさん179.547.3
Eさん183.546.4
Fさん167.450.9
Gさん175.349.1
Hさん168.448.9
Iさん141.853.7
Jさん158.450.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.4031.667
Dさん1.216-0.459
Eさん1.491-0.696
Fさん0.3840.485
Gさん0.9270.013
Hさん0.453-0.039
Iさん-1.3751.221
Jさん-0.2340.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.4032321.667793
Dさん1.216226-0.459628
Eさん1.491235-0.696008
Fさん0.3843250.485892
Gさん0.9274670.013132
Hさん0.453077-0.039397
Iさん-1.3757311.221297
Jさん-0.2344450.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.946.6
Bさん154.541.3
Cさん141.455.4
Dさん179.547.3
Eさん183.546.4
Fさん167.450.9
Gさん175.349.1
Hさん168.448.9
Iさん141.853.7
Jさん158.450.9

以上

参考

参考書籍






udemy講座

【はじめての統計学】
エクセルで学ぶマーケティング統計分析&戦略