LoginSignup
20
41

More than 5 years have passed since last update.

機械学習のための前処理 (scikit-learn Preprocessing)

Last updated at Posted at 2018-03-22

機械学習の前処理とは

AIは生のデータから学習すると思っていたけれども、実施はデータの前処理が必要になるケースが多々あるようです。

Should I standardize the input variables (column vectors)?

上のサイトによると、機械学習への寄与が入力の大きさに影響するようなので、使用する機械学習のアルゴリズムごとに、入力を適切にスケーリング (標準化) することが必要らしいです。 (理解が間違っていなければ、、、)

Scikit learnによる前処理

PythonのライブラリのScikit learnでは、この前処理を一括で行う関数が用意されています。下記のサイトにも、具体例が載っていますが、具体例で使用されている3x3行列では、いまいちイメージが沸かなかったので、どのような前処理が行われているのか、試してみました。

処理の対象とする行列の作成

10x3行列を使って、Scikit learnの前処理でどのような処理が行われるのか確認します。

test.py

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に標準化されます。

test2.py

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 に標準化されます。

test3.py

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関数と同じ結果を返すようです。

test4.py

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, 統計, 機械学習とか
Github sinhrks/pandas-ml

どの前処理を用いるか?

前回行った試行によると、LSTMで予測を行う場合は、平均値0のデータの場合が予測精度が高かった。その場合、Scale関数を使って前処理を行うと良いかもしれない (未検証)。

LSTMの予測精度に対するサンプルデータ絶対値の影響

20
41
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
20
41