python機械学習プログラミング(2章24ページ~25ページ)

さて、初めてのpythonというプログラム、訳も分からずとりあえず触ってみて、入力してみてそもそも動かない。ターミナルが何なの?
プログラムを入力するけどその後どうするの?
実行はどうやって?
訳が全く分からない。
なんていう事が普通に起きています。
もう、パニックです。
でも、それをこのブログに書けるほど理解をしていません。
いつの間にかできるようになっていてなんとなく、プログラムを書いて、ターミナルの上で動かしたら動いた。っていう感じです。
アナコンダ?なんなんだ?
さて、そこまでは皆さんも試行錯誤お願いします。
ではプログラムの自分なりの理解をお話ししていきます。
自分なりの理解

import numpy as np
class Perceptron(object):
    def __init__(self, eta=0.01, n_iter=10):
        self.eta = eta
        self.n_iter = n_iter
    def fit(self, X, y):
        self.w_ = np.zeros(1 + X.shape[1])
        self.errors_ = []
        for _ in range(self.n_iter):
            errors = 0
            for xi, target in zip(X, y):
                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)
        return self
    def net_input(self, X):
        return np.dot(X, self.w_[1:]) + self.w_[0]
    def predict(self, X):
        return np.where(self.net_input(X) >= 0.0, 1, -1)

ちなみに機械学習をするので、何度か繰り返し学習してもらわないといけません。なので、何回学習したらいいの?とか思っちゃいます。それを28ページで実際試すので、とりあえず28ページで今から作るプログラムが活躍するので、そのプログラムを作成します。

まず、このプログラムでは何をしているのか?という事ですが、22ページの数式をプログラムにしたらこうなったという感じです。もちろん数式だけでは役に立ちません。なので、最低限必要な部分を作っていきます。その最低限必要な部分をまずはざっくり書いていきます。
まず、

  • 今から作る機械学習(このプログラム)の名前を決める。
  • 学習率\etaをどのぐらいにするか?(学習率は22ページ)
  • 何回学習を繰り返すか?

を決めないといけません。
そして、次に

  • どのデータを学習させるかデータを取り込めるようにします。
  • そのデータを数式に当てはめて分類します。
  • 分類した結果、正解か不正解かを分けて不正解をカウントします。

という感じです。

さて、ざっくりこんな感じとお話ししたところで、細かくプログラムを見ていきます。プログラムを見ながら読んでもらうとこんな感じで理解してるんだとわかるかと思います。

  1. numpyというところにアクセスします。今度アクセスするときはnpと書いたらアクセスしたことにしてね!!というpythonとのお約束。
  2. 次に機械学習の本体の名前をPerceptronと決めました!!
  3. """と"""に囲まれた部分はプログラムとして認識しないので、メモとして残します。なので、24ページはこれで終了
  4. 数式の\etaetaで基本0.01としておきます。何回学習させるかはn_iterとして基本10回として決めます。
  5. このPerceptronというプログラムの一部にデータを学習させるのための別プログラムを用意します。その名前をfitとしておきます。ここでデータの取り込みが行われます。

    z=w_0x_0+w_1x_1+...+w_mx_m=\mathbf{w^Tx}というこの数式、wは重みでxは特徴なので、仮にx_1が花びらの長さだとすると、x_2はがく片の長さ、x_3は○○・・・・・という感じでxの数と特徴の数が一緒という事です。

  6. 特徴と同じ数だけ重みがあるので、特徴と同じ数の重みを0として準備します。\left (000…000\right)(この後self.w_[0]という形でプログラムを作るのでその時の準備です)
  7. 分類を間違えたときはself.errors_という名前で個数を数えるので、配列として保存できるようにしておきます。(分類を間違えた時は1として記録され、うまく分類できた時は0として記録されます。後で合計を出せば間違えた個数がカウントできるようにしておきます。)
  8. n_iterの回数だけfor文を使用して繰り返します。
  9. errorsという名前の変数を作って中身に0を入れておきます。
  10. 再びfor文を作ります。(こっちのfor文はデータのサンプルXを1つずつ分類していくので、100個のデータがあったら100回分類をしていくためのfor文。)
  11. ここで数式登場。

    \Delta w_j = \eta(y^{(i)} - \hat{y}^{(i)})x^{(i)}_j
    update = self.eta * (target - self.predict(xi))

    この2つの式を見比べて見ると似ています。

    数式 \Delta w_j → プログラム update に対応
    数式 \eta → プログラム self.eta に対応
    数式 y^{(i)} → プログラム target に対応
    数式 \hat{y}^{(i)}_j → プログラム self.predict(xi) に対応

    となると、数式の最後のx^{(i)}_jは???となりますが、プログラムのその次の行を見てみると、、、
  12. self.w_[1:] += update*xiとなっています。つまり、このプログラムに使用されているupdateは先ほど示したself.eta * (target - self.predict(xi))です。これにxiをかけているので

    \Delta w_j = \eta(y^{(i)} - \hat{y}^{(i)})x^{(i)}_j
    update = self.eta * (target - self.predict(xi))*xi

    となるという事です。ここで出てきたself.predict(xi)はまた後で関数として作成するので、いったん保留しておきます。
  13. 次に21ページの式(2.1.6)を見てもらうと、\Delta w_0 = \eta (y^{(i)} - output^{(i)})となって、さらに、式(2.1.4)を見てもらうと、w_j := w_j + \Delta w_jとなっていて、この両式からself.w_[0] += update (これはself.w_[0] = self.w_[0] + updateと同じとなっています。
  14. 上で準備した変数errorsに誤って分類した数を足していきます。(updateが0の時に上手く分類できたと判断できる。)
  15. 別プログラムfitを終了するにあたり、ここで作ったデータを返します。
  16. もう一つ別プログラムを作成しておきます。19ページのw^T xは行列の内積になるので、ここで準備しておきます。
  17. 作成した値を返すので、returnの後にxx内積の式を入れます。ここで作る数式は19ページの、w_0x_0+w_1x_1+w_2x_2+...+w_mx_mを作成します。wはself.w_、xはXに対応するので、np(numpy)のdot関数を使用して内積を計算します。
  18. ここで、先ほど上の方でいったん保留にしておきますと言っていた、predict(xi)の部分を作成します。ここでも計算した値を返すので、returnの後にプログラムを書いていきます。
  19. ここで作成するプログラムは19ページの式(2.1.3)です。
    \phi(z) =\left\{\begin{matrix}1(z \geq 0)\\-1(z<0)\end{matrix}\right.

これで24ページから25ページにまとめられたプログラムが完成しました。
ちなみに、このプログラムを実行したところで今は何も動きません。
この後の流れとしては分類したいデータを作って、そのデータを今作った機械学習プログラムに学習させて、そのデータをきれいに分類が出来るかを見る。というのがこの後の流れになります。