パーセプトロンを実装してみた

実装力を磨くためと学習器への理解を深めるために、パーセプトロンを実装してみた。3時間ぐらいかかった。今のレベルはSVMの赤本に行く前ぐらいのレベル。

コードは以下にある。以下で参考にしたチュートリアル擬似コードをそのまま実装した。
https://github.com/akkikiki/nlp_tutorial/blob/master/train_perceptron.py

以下のチュートリアルを参考にした。詳しい事はこちらに書いてあるが、概要を述べてみる。
パーセプトロンアルゴリズムと文書分類

ちなみに、自分は昨年の春ぐらいにPRML4章(パーセプトロン含む)を輪読会で発表したのだが、完全に忘れていたうえ、読んだ時も機械学習の全体像(識別関数、生成モデル、識別モデルから成る)が掴めていなかったので、いきなりPRMLを読むのはオススメしない。
今PRML4.1.7節を見たら「すごい、わかりやすい!」と思うけど、直前のフィッシャーの識別関数あたりで全体力を消費して、命からがら、パーセプトロンを読んだ覚えがあるので、全然わからなかった。

以下パーセプトロンの概要である。

オンライン学習器である

すなわち、一つの学習事例に対して、重みを更新していく
更新式は


w = w + y *\eta*\phi(x)
φ(x)は入力データxの素性で、yは識別結果である。また、η>0は学習率と呼ばれる。
ηの値は「更新時にどのくらいの大きさで、重みを更新するか」である。ちなみにパーセプトロンは収束定理があり、対象データが線形分離可能ならば、どんな学習率でも収束が保証されているため*1、学習率は大抵1である。自分のコード(チュートリアル)でもそうした。

識別結果yは-1か1である

この制限により、学習データと比較した時に識別結果が間違っていた場合、重みが識別結果の符号に引っ張られる。イメージとしてはPRML、図4.7a(http://research.microsoft.com/en-us/um/people/cmbishop/PRML/prmlfigs-jpg/Figure4.7a.jpg)である。黒い矢印がwで赤い矢印で、緑色の丸に囲まれた点が、誤って識別されたため、点(赤いベクトル)の方へ境界を引っ張る。

識別関数である

echizen_tmさんのブログを読んでいて、気付いた。確率ないのは面倒でなくイイネ!

以下雑記

http://gihyo.jp/dev/serial/01/machine-learning/0017はnumpyを使ってパーセプトロンを実装しているので、今度やってみる。

ちなみにSVMパーセプトロンを発展させたもので、

パーセプトロンに導入した学習器である。Sequential Minimal Optimization(SMO)等により高次元のデータに対しても学習が早い、とかの特徴がある。

自分の実装で気を付けるべき、と思った点も述べてみる。

  • 疑似コードから書くこと
  • 全体像(大枠)を書き、詳しい処理は適当な関数の名前を付けて、後で詳細を書く。

当たり前のことだけど、複雑なアルゴリズムほど脳内だけでは処理仕切れなくなる。そして、つまずき、実装を諦める、と言った場合が自分の経験上多い。
疑似コードを書いておくと「ここ何を処理したいんだっけ?」と詰まった場合でも、確認して前に進める。