スマレジエンジニアyushiのブログ

スマレジエンジニアのブログ

【機械学習入門 #5】Perceptron実装後半 学習ロジック

機械学習に入門しています。

yushi-dev.hatenablog.com

今回はPerceptronの実装後半です。

学習ロジックの実装

まずはコンストラクタの実装です。

class Perceptron(object):
    ...
    # コンストラクタ
    def __init__(self, eta=0.01, n_iter=10):
        # 学習率 0.0〜1.0
        self.eta = eta
        
        # トレーニング回数
        self.n_iter = n_iter

学習率とトレーニング回数は、詳しくは理解できていませんが、大きすぎると過学習になり小さすぎるとトレーニングが足りず、
どちらにしてもうまくいきません。

過学習とは、利用したトレーニングデータに特化してしまうような現象です。 トレーニングデータに対しては、高精度で判定できるようになります。 一方で、本来の目的であるそれ以外のデータに対してはうまく判定できなくなってしまいます。

続いて、学習ロジックの本体です。

class Perceptron(object):
    ...
    # トレーニング
    def fit(self, X, y):
        # X: トレーニング変数 今回は、2 x N
        # y: 目的変数

        # 重み(トレーニング結果)
        self.w_ = np.zeros(1 + X.shape[1])
        
        # トレーニングN回目のエラー回数(誤分類回数)
        self.errors_ = []
        
        for _ in range(self.n_iter):
            errors = 0
            for xi, target in zip(X, y):
                # 予測値が正解していたら0, 外していたら符号 * 2 * 学習率
                update = self.eta * (target - self.predict(xi))
                
                # 重みの更新
                self.w_[1:] += update * xi
                self.w_[0] += update
                
                errors += int(update != 0.0)
            self.errors_.append(errors)

重みは前記事で紹介した通りです。

具体的なロジック内容としては、まずself.n_iter回ループを回します。
ループの各回では、更に一つ一つのレコード(花ひとつ分の特徴量)について、ループを回します。
このループ内では、特徴量1つ1つを元にどちらの種類の花かを判定します。
この判定が正しかった場合は、何も行わず次のループに進みます。 この判定が間違っていた場合には、重みを補正し、エラー回数を加算します。
この重みの補正が繰り返されることで、段々と正しい判定ができるように改善されていく(学習)、という仕組みです。
この重みの補正は、self.etaの数値が大きいほど程度が大きくなります。

学習の実行

学習を実行します。この際の、エラー回数をグラフ表示します。

ppn = Perceptron(eta=0.1, n_iter=10)
ppn.fit(X, y)
plt.plot(range(1, len(ppn.errors_) + 1), ppn.errors_, marker='o')

このグラフでは、数値が大きいほど花の種類の判定に失敗していることがわかります。

見てわかる通り、6回目以降では判定間違いは0回になっています。
そもそも1回目時点でも2回しか判定間違いしていませんが、 それだけデータの傾向がはっきりしているということなのかなと考えています。 3回目で一度判定間違いが増えているのが興味深い所ですね。

まとめ

Perceptronの実装が完了しました。

次回は、完成したPercptronを使って、データの判定をしてみます。