Pythonと機械学習

Pythonも機械学習も初心者ですが、頑張ってこのブログで勉強してこうと思います。

パーセプトロン

10年くらい前にニューラルネットワークに興味を持ち、本を買って勉強したことがありましたが、非常に難しくて挫折した覚えがあります。

その本にもパーセプトロンが一番最初のニューラルネットワークモデルとして紹介されていました。

トレーニングサンプルをパーセプトロンに入力してやるとYesまたはNoが出力されます。

あるデータを元に、YesかNoかに分類する問題を2値分類問題と言います。

医者が患者の症状を診て、この人は風邪か又は別の病気か?を判断するのに似ています。

機械学習の考え方のベースとなるモデルなので、基礎知識として持っておくと良いです。

例えば風邪をひいた人の特徴として、体温が上がる、咳の回数が増える等があります。

トレーニングサンプル{\boldsymbol{x}}として、この特徴となる量を指定してやります。

この体温{T}や一時間当たりの咳の回数{N}特徴量と言います。

{ \displaystyle
\boldsymbol{x}=[T,N] \tag{1}
}

一組のトレーニングサンプルがパーセプトロンに入力されると、まずそれぞれの特徴量に対して重みがかけられます。

重みは特徴量の個数だけ用意されます。

重みをかけた後は、それぞれの和を取り、更にしきい値(バイアス){w_0}を付加したデータ{z}が用意されます。

算数の表記で書くと、

{ \displaystyle
z = \sum_{j=0}^{n} w_jx_j \tag{2}
}

※形式的に{x_0=1}と置いてます。{n}は特徴量の個数です。

この{z}に対して活性化関数{\phi(z)}を作用させたものがパーセプトロンの出力になります。

{\phi(z)}は、{z\geq0}で1になり、{z\lt0}で-1になる2値関数です。

要するに連続値である{z}を無理やり1か-1に変換しています。

こうゆう変な関数の事を超関数と言ってやります。無理やり編み出した関数に見えますが、ある連続関数の極限的な関数として数学的に扱われておりヘビサイド関数という名前がついています。

パーセプトロンの出力に対して、教師データ(この場合、風邪を本当に引いていれば1。引いていなければ-1)が違っていれば、重みを更新します。

{ \displaystyle
w_j^{(i+1)} = w_j^{(i)} + \Delta w^{(i)}_j \tag{3}
}

右上の{i}は学習の回数を表しています。

ここで、パーセプトロンの出力を{\hat{y^{(i)}}}、それに対する教師データを{y^{(i)}}としてやると、

{ \displaystyle
\Delta w^{(i)}_j = \eta(y^{(i)} - \hat{y^{(i)}})x_j^{(i)} \tag{4}
}

{\eta} (イータと読みます)は学習率といい、0以上1以下の適当な係数です。

学習を重ねるごとにパーセプトロン内部で重みを更新していき、学習回数がある程度多くなると、重みは一定値に収束していきます。

学習回数が用意したトレーニングサンプル数(トレーニングサンプルと教師データのセット数)まで達した後は、再度また最初から同じ事を繰り返します。この繰り返しをエポックと言います。

重みが更新されなくなったとき、入力されたトレーニングサンプルに対する全てのパーセプトロンの出力が教師データと一致していることになり、学習が完了します。

一般的に、あるトレーニングサンプルを特定の値(今の場合は-1か1)にクラス分けする操作をクラス分類と言います。また、この-1とか1というクラス分類された値をクラスラベルと言います。

覚えておく用語

  • 2値分類問題:トレーニングサンプルからYesかNoを判断する問題
  • 特徴量:個々のトレーニングサンプルを特徴づける量
  • 特徴量の個数:一組のトレーニングサンプルに含まれる特徴量の個数
  • トレーニングサンプル数:トレーニングサンプルと教師データのセット数
  • 重み:トレーニングサンプル内のそれぞれの特徴量にかけられる量
  • しきい値:活性化関数への入力を調整する値
  • 活性化関数:パーセプトロンの最終的な出力を決定する関数
  • 学習率:重みを更新する割合
  • エポック:学習の1ターン
  • クラス分類:トレーニングサンプルを特定の値にクラス分けすること
  • クラスラベル:クラス分類された値