Python

Pythonで機械学習を学ぶ ニューラルネットワーク

Deep Learning(深層学習)の基本でもあるニューラルネットワークを学びます。

パーセプトロン

値を1つ以上入力し、条件式を通して1つ値を出力する。ANDやORといった論理回路で説明されることが多いです。複数つないでニューラルネットワークを構築できる。

ニューラルネットワーク

パーセプトロンとは異なり、条件式ではなく、活性化関数の計算結果を出力する。活性化関数は、シグモイド関数などがよく使われる。

誤差関数を最小化する

誤差関数を最小化するアプローチを3つ紹介します。

勾配法

初期値を設定し、値が小さくなる方向の勾配(傾き)を求め(偏微分)、最小値を探索する方法。最小値を求め、下向きに値を収束させることが多いため、勾配降下法とも呼ばれる。

確率的勾配降下法

ミニバッチ学習(訓練データを1つか1部)で、勾配降下法でパラメータを更新する。局所解のリスクを抑える。

誤差逆伝播法

確率的勾配降下法で計算時間がかかる場合の解決法。逆伝播(出力から入力)に向かって誤差情報を伝播させることで効率よく勾配の計算を行う。

サンプルコード

以前に書いたワインの分類をscikit-learnに用意されている、ニューラルネット( MLPClassifier )で実装してみます。

import pandas as pd
import requests
import io
from sklearn.neural_network import MLPClassifier
from sklearn.model_selection import train_test_split

# 読み込み
url_red = 'https://archive.ics.uci.edu/ml/machine-learning-databases/wine-quality/winequality-red.csv'
res_red = requests.get(url_red).content
data_red = pd.read_csv(io.StringIO(res_red.decode('utf-8')),
                       header=None, skiprows=1, delimiter=";")
# 赤を0, 白を1とする
data_red['type'] = [0] * data_red.shape[0]
data_red.columns = ['fixedacidity', 'volatileacidity', 'citricacid', 'residualsugar', 'chlorides',
                    'freesulfurdioxide', 'totalsulfurdioxide', 'density', 'pH', 'sulphates', 'alcohol', 'quality', 'type']

url_white = 'https://archive.ics.uci.edu/ml/machine-learning-databases/wine-quality/winequality-white.csv'
res_white = requests.get(url_white).content
data_white = pd.read_csv(io.StringIO(res_white.decode(
    'utf-8')), header=None, skiprows=1, delimiter=";")
# 赤を0, 白を1とする
data_white['type'] = [1] * data_white.shape[0]
data_white.columns = ['fixedacidity', 'volatileacidity', 'citricacid', 'residualsugar', 'chlorides',
                      'freesulfurdioxide', 'totalsulfurdioxide', 'density', 'pH', 'sulphates', 'alcohol', 'quality', 'type']

# 結合
data = pd.concat([data_red, data_white])

# 目的変数、説明変数
X = data[['fixedacidity', 'volatileacidity', 'citricacid', 'residualsugar', 'chlorides',
          'freesulfurdioxide', 'totalsulfurdioxide', 'density', 'pH', 'sulphates', 'alcohol']]
y = data['type']

# 訓練データとテストデータに分ける
X_train, X_test, y_train, y_test = train_test_split(
    X, y, test_size=0.2, random_state=0)

# 学習
model = MLPClassifier(solver="sgd", random_state=0, max_iter=3000)
model.fit(X_train, y_train)
pred = model.predict(X_test)

# 結果
print('train:{:.3f}'.format(model.score(X_train, y_train)))
print('test:{:.3f}'.format(model.score(X_test, y_test)))

実行結果

train:0.953
test:0.948