ニューラルネットワークなど、機械学習のパラメータラーニングをする際、教師データの値が大きくばらついていたり、範囲が極端に大きかったり、小さかったりすると、うまく学習できない場合があります。このため、データの規格化を行う必要があります。ここでは、このための関数について示します。

Min-Max規格化とは:
特徴量の最小を0、最大を1とする規格化です。行成分を個々のサンプル、列成分を特徴量とした、データセットを突っ込むと、この規格化が実施されます。返り値は、規格化済みデータ、各特徴量の最大値、最小値です。学習自体は規格化済みデータのみでできますが、新たなデータを学習済みモデルに入力し出力を得たいとき、ここで算出した最大値・最小値が必要になります。新たなデータの最大値・最小値を用いて規格化させる訳ではないので、注意してください。

教師データだけ規格化する関数:
メモ: 直下の関数は非推奨。教師・テストデータ2つを用意する場合、2つ目の関数を使用してください。

# ***
# 機械学習における教師データセットを、最小0、最大1に規格化する関数
# 入力: データセット(列成分: 個々の特徴量、行成分: 個々のデータ)
# 出力: MinMax規格化データ、特徴量の最大値、最小値

def MinMaxStandardization(dat):    
    import numpy as np
    
    # 各特徴量の最大値・最小値取得
    MaxVal, MinVal = [], []
    for i in range(0, len(dat[0, :])):
        MaxVal.append(np.max(dat[:,i]))
        MinVal.append(np.min(dat[:,i]))
        print(" +++++++++++++++++++++ ")
        print("   Expression for Feature", str(i), ":")
        print("   y = (x-", str(MinVal[i]), ") / (", MaxVal[i], "-", MinVal[i], ")"  )

    # 規格化データの生成
    newdat = np.zeros(np.shape(dat))
    for i in range(0, len(dat[:,0])):
         for j in range(0, len(dat[0, :])):
                newdat[i, j] = (dat[i, j] - MinVal[j]) / (MaxVal[j] - MinVal[j])

    # 規格化データ、最大値、最小値を返却
    return [newdat, MaxVal, MinVal]



教師・テストデータをまとめて規格化する関数:
テストデータとは、モデルの構築段階では知り得ない、未来において発生する未知のデータを想定したものになります。したがって、テストデータを使って規格化パラメータを得るのは不適切です。このため、既知であることを想定している教師データのみを使用して規格化パラメータ(最小・最大)を取得してから、それを使って教師データ、テストデータの規格化を実施することが標準的な方法です。上の関数では、それを実現しにくいという問題があります。そのため、以下の機能を有する関数を、ここで定義しておきます。

・入力: 教師データの特徴量、テストデータの特徴量
・出力: 規格化された教師データの特徴量、規格化されたテストデータの特徴量、教師データの最小値、教師データの最大値
・手続き1: 教師データの特徴量から、規格化パラメータを取得(最小値、最大値)
・手続き2: 教師データから得られた規格化パラメータで、教師データを規格化する。
・手続き3: 教師データから得られた規格化パラメータで、テストデータを規格化する。
・手続き4: 規格化されたデータと、規格化パラメータを返却する。

def MinMaxStand_Xtrain_Xtest(fX_train, fX_test):
    
    # trainデータについて、各特徴量の最大値・最小値取得
    MaxVal, MinVal = [], []
    for i in range(0, len(fX_train[0, :])):
        MaxVal.append(np.max(fX_train[:,i]))
        MinVal.append(np.min(fX_train[:,i]))

    # trainデータの規格化
    newX_train = np.zeros(np.shape(fX_train))
    for i in range(0, len(fX_train[:,0])):
         for j in range(0, len(fX_train[0, :])):
                newX_train[i, j] = (fX_train[i, j] - MinVal[j]) / (MaxVal[j] - MinVal[j])
                
    # testデータの規格化
    newX_test = np.zeros(np.shape(fX_test))
    for i in range(0, len(fX_test[:,0])):
         for j in range(0, len(fX_test[0, :])):
                newX_test[i, j] = (fX_test[i, j] - MinVal[j]) / (MaxVal[j] - MinVal[j])

    # 規格化trainデータ、規格化testデータ、train最大値、train最小値を返却
    return newX_train, newX_test, MaxVal, MinVal