機械学習の前処理とは
AIは生のデータから学習すると思っていたけれども、実施はデータの前処理が必要になるケースが多々あるようです。
Should I standardize the input variables (column vectors)?
上のサイトによると、機械学習への寄与が入力の大きさに影響するようなので、使用する機械学習のアルゴリズムごとに、入力を適切にスケーリング (標準化) することが必要らしいです。 (理解が間違っていなければ、、、)
Scikit learnによる前処理
PythonのライブラリのScikit learnでは、この前処理を一括で行う関数が用意されています。下記のサイトにも、具体例が載っていますが、具体例で使用されている3x3行列では、いまいちイメージが沸かなかったので、どのような前処理が行われているのか、試してみました。
処理の対象とする行列の作成
10x3行列を使って、Scikit learnの前処理でどのような処理が行われるのか確認します。
import numpy as np
from sklearn import preprocessing
a = [i**2 - 420 for i in range(30)]
a = np.array(a)
a = a.reshape(10,3)
print(a)
print(a.max(axis=0)) # 各列の最大値 [309 364 421]
print(a.min(axis=0)) # 各列の最小値 [-420 -419 -416]
print(a.mean(axis=0)) # 各列の平均 [-163.5 -135.5 -105.5]
print(a.var(axis=0)) # 各列の分散 [58405.05 66721.05 75631.05]
"""
行列 a:
[[-420 -419 -416]
[-411 -404 -395]
[-384 -371 -356]
[-339 -320 -299]
[-276 -251 -224]
[-195 -164 -131]
[ -96 -59 -20]
[ 21 64 109]
[ 156 205 256]
[ 309 364 421]]
"""
Scale関数による前処理
各列は、平均 0 、分散 1に標準化されます。
a_scaled = preprocessing.scale(a)
print(a_scaled.max(axis=0)) # [1.95513438 1.93376661 1.91446888]
print(a_scaled.min(axis=0)) # [-1.06135866 -1.09754321 -1.12904575]
print(a_scaled.mean(axis=0)) # [ 2.22044605e-17 -8.88178420e-17 6.66133815e-17]
print(a_scaled.var(axis=0)) # [1. 1. 1.]
MinMaxScaler関数による前処理
各列は、最大値 1 、最小値 0 に標準化されます。
min_max_scaler = preprocessing.MinMaxScaler()
a_minmax = min_max_scaler.fit_transform(a)
print(a_minmax.max(axis=0)) # [1. 1. 1.]
print(a_minmax.min(axis=0)) # [0. 0. 0.]
print(a_minmax.mean(axis=0)) # [0.35185185 0.36206897 0.37096774]
print(a_minmax.var(axis=0)) # [0.10989941 0.10882767 0.1079566 ]
MaxAbsScaler関数による前処理
各列は、最大、最小の絶対値が 1 に標準化されます。
各列の要素がすべて正の値の場合は、MaxMinScaler関数と同じ結果を返すようです。
max_abs_scaler = preprocessing.MaxAbsScaler()
a_maxabs = max_abs_scaler.fit_transform(a)
print(a_maxabs.max(axis=0)) # [0.73571429 0.86873508 1. ]
print(a_maxabs.min(axis=0)) # [-1. -1. -0.98812352]
print(a_maxabs.mean(axis=0)) # [-0.38928571 -0.32338902 -0.25059382]
print(a_maxabs.var(axis=0)) # [0.33109439 0.38004483 0.42671306]
Pandasに対して前処理を行いたい
上記のScikit-learnの前処理は、前処理結果がndarrayに変換されてしまいます。
このため、元DataがPandasである場合、前処理結果がPandasでなくなってしまうことが面倒です。
その面倒を回避するには、下記のライブラリを使用すると良さそうです。作ってくれた人、ありがとうございます。
[StatsFragments Python, R, Rust, 統計, 機械学習とか] (http://sinhrks.hatenablog.com/entry/2015/03/18/003954)
Github sinhrks/pandas-ml
どの前処理を用いるか?
前回行った試行によると、LSTMで予測を行う場合は、平均値0のデータの場合が予測精度が高かった。その場合、Scale関数を使って前処理を行うと良いかもしれない (未検証)。
- Scale関数で標準化している例
- MaxMinScaler関数で標準化している例
- 標準化していない(?)例 | 絶対値が小さければ標準化しなくてもよい?