前回に続いて、ロジスティック回帰で遊ぶ。
まだ線形の特徴量しか試していなかったので、二次項や RBF (距離に基づく特徴)も追加し、イテレーションももっとたくさん行うようにし、また初期値や学習順によって結果が変わるから、テスト自体も複数回行えるようにした。
そうなると、さすがに対話式インターフェースでコピペ実行というわけにもいかないので、スクリプトにて記述。
分布図を吐かせるかどうか、テストを何回行うかはコマンドラインから指定できる。
R -q --vanilla --slave --args --chart -i 5 < lr.r
--args の後に --chart を書くと分布図を出力し、-i でテスト回数を指定する。
ここの実際の処理はこのように書いている。エラー処理? なにそれおいしいの?
commandline <- commandArgs(TRUE) chart <- "--chart" %in% commandline i <- match("-i", commandline) if (is.na(i)) { I <- 1 } else { I <- as.numeric(commandline[i + 1]) }
このくらいのコマンドライン処理のモジュールは標準で付いていてもいいがするのだが、R は対話で使うもの、という確固たる信念でもあるんだろうか。
ちなみに -q や --vanilla などは R 本体のオプション。詳しくは説明しないが、付けておかないといろいろめんどくさい……
"R -q --vanilla --slave --args" までを小文字の r などに alias してしまって、普段はそちらを使う、などするのが便利かもしれない(苦笑)。
話をロジスティック回帰に戻す。
iris はもともと4次元のデータなので、それらを で表すと、今回実装してみた特徴は次の通り。括弧内は特徴空間の次元。
- 線形(5)
- 1, x_1, ..., x_4
- 二次(15)
- 1, x_1, ..., x_4, x_1^2, x_1x_2, ..., x_3x_4, x_4^2 (全ての2次以下の項)
- RBF(1297=6^4+1)
- , ただし μ_j は 各 x_i ∈{-2.5, -1.5, -0.5, 0.5, 1.5, 2.5} である格子点、s=1, ..., 10
RBF にはいわゆるガウス基底を持ってきた。ただし尺度のパラメータは単純に整数値を選んでいる。
学習率は 0.1 から始めて、1周するごとに 0.95 倍しながら、0.0001 を下回るまで学習を繰り返す。
これらの特徴についてそれぞれ5回ずつ実行し、誤差(交差エントロピー)の平均を取ってみたのがこちら。
Linear Features: error=11.4314 Quadratic Features: error=6.888 RBF Features (s=1): error=8.6134 RBF Features (s=2): error=6.706 RBF Features (s=3): error=6.3842 RBF Features (s=4): error=6.1398 RBF Features (s=5): error=6.256 RBF Features (s=6): error=6.244 RBF Features (s=7): error=6.5798 RBF Features (s=8): error=7.6184 RBF Features (s=9): error=7.8868 RBF Features (s=10): error=8.5274
実は RBF で大量に素性を増やして、過学習的振る舞いを起こす => よし正則化しましょう! という流れになる予定だったのだが、2次でほぼ精度が頭打ちになってしまっている(そもそも線形でもそんなに悪くない)というのが痛い(苦笑)。まあ、iris データセットはお行儀が良すぎるので、だいたい予想していたとおりではあるんだけど。
ガウス基底の尺度で精度にそれなりに差が出ることを見て取れることくらいが救いかな。
というわけで目論見を外してしまったのだけど、めげずに当初のストーリー通りに進める。
次回はこのロジスティック回帰+確率的勾配降下法に対して、そもそも今回の主目的である FOBOS を使った L1/L2 正則化を適応してみる。データセットもちょっと他のを見繕ってみる。