octaveの使い方
ひょんな事から機械学習をnode上で始めた。nodeって、ぐぐる製のブラウザに載ってる Javascriptエンジン(V8)を、サーバー側でも使えるように拡張したものだ。
そいつに機械学習用のsyapticと言うパッケージを入れたら、その保存場所が目につく home上だったので、容易に手をのばす事が出来た。
世の機械学習を見てると、この分野はPythonが鉄板のようだね。 Pythonで機械学習/Deep Learningを始めるなら知っておきたいライブラリ/ツール7選
お勧めのライブラリーを全て組み込んだ、 Anacondaなんてのが提供されてる。 ボタン一発で、環境が揃うみたいで現代風だな。こうでないと、受け入れられないのかな。 ちょいと使うには良いシステムだと思うぞ。そのうちに、Windows7機にでも入れてみるか。
でも、オイラーみたいな人は、それで何かをするより、それがどうなってるか分解してみたい なって気分がある。
時計を使うんじゃなくて、その時計を分解してどうなってるか調べて満足するような餓鬼の 気分がずーと続いているのさ。
アカデミアでは
ただ使うだけならいいけど、どう動くとなるとやはりアカデミアだな。以前調べておいた 人工知能の学習理論あたりが、取っ掛かりには最適だろう。
学生用の説明とコードが提供されてる。なんでもMATLABってのが有名らしい。
ディープラーニング (深層学習): MATLAB で始める上で知っておきたい7 つの役立つリソースへ行って調べてみると、お試し版がある。気にいったら購入して ください。一体幾らするんや? ご家庭で使うには15000円ですって。 学生さんは、5000円。一回、合コンを我慢してくださいって価格だな。
ああ、思い出した。これってラズパイに付属してた気がするぞ(ひょっとしたら、Maximaだった かも)。でも、ラズパイユーザーは、 Pythonに流れてしまって、見向きもしないでしょう。
こういう事情はCommonLisp界のブランド、アレグロと同じだな。まあ、手厚いサポートが有るんでしょうけど、ちょっと試すには敷居が高すぎる。
こういう場合は、有志が作った、貧者のための同様ソフトが有るはず。上のURLにもちらっと 出てたけど、 GNU Octave を使えばいいよ。ブランド品になるべく合うように作ってあるからね。同等品にScilabってのも 有るようだけど、こちらはMATLABとの互換性を余り重視していない模様。
Octave
有名なのでLinuxは勿論の事BSDにもWindowsにも対応してる。ここで、ちょっと 資料を探ってみた。
OctaveでFitting (最小二乗法, 線形) (Using CSV file)
色々出てくるなあ。行列って、表現がテーブルみたいだけど、その演算に対しては、深遠な 数学の知恵が詰まっている。
私の研究開発ツール(前編) とか (後編) も、面白いな。
ああ、行列演算のススメに、高速化の話が載ってる。for文を無くせとな。これPythonなんかでも唱えていたな。 そのためには、内包表記を使えと。octaveに有るのかしら?
使ってみる
Windows7機に入れてみたら、4.2.0と言う最新のやつが入った。グラフ書きとか、変数の 参照とかeditorとかdebuggerが付いた、総合開発環境だったよ。QtでGUIを担当させてる ようで、随分太った構成になってる。
OpenBSDのやつはパッケージに有ったけど、ちょっと古くて4.0.2。普通に使うには、これで 十分だろう。
octave:3> m = magic(5) m = 17 24 1 8 15 23 5 7 14 16 4 6 13 20 22 10 12 19 21 3 11 18 25 2 9
これ、魔法陣だそうです。縦に足しても、横に足しても、斜めに足しても、同じ数値に なるというやつ。こんな遊び心が有るんですなあ。
octave:4> size(m) ans = 5 5 octave:5> m(1, :) ans = 17 24 1 8 15 octave:6> m(:, 1) ans = 17 23 4 10 11
マトリックス(行列)のサイズは、文字通りsizeコマンドで得られます。結果は、行数、列数の 順で表示されます。また、行列の要素は、行番号、列番号で指定する約束。それぞれは、1から 始まるのが約束事項になってます。(他の言語で2次元配列とかを扱っている身としては、 ちょっと違和感が有りますが、いにしえの言語Fortran由来と言う事で、諦めましょう)
ある行数だけ、あるいは列だけを取り出したい時は、全部を表す : を、数値の代わりに 指定します。
octave:7> m' ans = 17 23 4 10 11 24 5 6 12 18 1 7 13 19 25 8 14 20 21 2 15 16 22 3 9
行と列を入れ替える(縦のものを横にする、横のものを縦にする)場合は、変数名の後に アポストロフィーを付けるそうです。
上の資料で出てきた、最小2乗法によるフィッテングをやってみます。データは、例によって 血圧データです。
octave:2> m = csvread('mornig.csv') ; octave:3> size(m) ans = 50 4
csvファイルからも簡単に読み込めます。普通にコマンドを叩くと、読み込んだデータが 表示されるので、それが必要ない場合、セミコロンを最後に入力して、抑止します。
octave:4> hi = m(:, 2); octave:5> lo = m(:, 3); octave:6> p = polyfit(hi, lo, 1); octave:7> p p = 0.18661 52.36735
pには、係数と切片が得られています。
octave:14> x = linspace(50,150); octave:15> y = p(1) * x + p(2); octave:16> plot(hi,lo,'r.') octave:17> hold all octave:18> plot(x,y)
linspaceで、X軸用のベクター(数値列)を発生させます。そのベクターに対して、係数と 切片を適用して、フィットした直線を生成しておきます。
次は、赤色の・で、実データの散布図を書きます。holdで図を更新しないように指定(こう すると重ね書きになります)、続いて、先ほどの直線を書きます。
何か困った事が有ったら、helpで調べられます。(コマンドを知ってる事が前提で、 初心者は、これが辛いのよね。だから、サンプルをパクるんです。help --listして、当たりを付けるって言う手もあるけどね。)
octave:2> help linspace 'linspace' is a built-in function from the file libinterp/corefcn/data.cc -- Built-in Function: linspace (BASE, LIMIT) -- Built-in Function: linspace (BASE, LIMIT, N) Return a row vector with N linearly spaced elements between BASE and LIMIT. : For compatibility with MATLAB, return the second argument (LIMIT) if fewer than two values are requested. See also: logspace.
linって、リニアな列なんだな。ログスケールが欲しけりゃ、logspaceを使えとな。 MATLABを強く意識してますって書いてあるな。詳しくは、doc hogeすれば、オンラインで 参照出来るよって、決まり文句もこの後、続いている。
なお、helpの冒頭に、ソースの所在地が示されている。関数一つが同名のファイルに するってのが、Octaveの流儀だそうなので、読んで読んで読みまくると、詳しくなるでしょう。 これがオープンソースの醍醐味だと、マジに思うぞ。
スクリプトにする
上でやったセッションを、ファイルに書き出しておくと、実行ファイルになる。で、OpenBSD でやっていると、フォントが入っていないせいか、ワーニングが出て、セグフォする事が 有るんだ。
[ob: bld]$ octave z.m warning: ft_render: unable to set font size to 10 warning: called from axes at line 66 column 10 gca at line 58 column 9 newplot at line 148 column 8 plot at line 221 column 9 z.m at line 9 column 2 warning: ft_render: unable to set font size to 10 : warning: called from z.m at line 12 column 1 panic: Segmentation fault -- stopping myself... attempting to save variables to 'octave-workspace'... save to 'octave-workspace' complete octave exited with signal 11
本当はワーニングを潰して、セグフォが消えるか調べるのが筋だろうけど、面倒なので Fedoraに乗り換える。(こういう時、色々なOSを入れていると楽だ。一つのOSに固執する 事無いよな)
[sakae@fedora bld]$ egrep '^......0.' current.csv | tail -n 100 > mornig.csv [sakae@fedora bld]$ cat z.m # plot test m = csvread('mornig.csv') ; hi = m(:, 2); lo = m(:, 3); p = polyfit(hi, lo, 1); x = linspace(90,150); y = p(1) * x + p(2); plot(hi,lo,'r.') hold all plot(x,y) keyboard("debug>> ") # fall to debug, dbcont to leave dmy=input('Hit any key to fin ')
egrepを使って、血圧データの測定日時から、起床時のデータだけを抜き出し、直近の 100データだけのファイルを作成。
スクリプトは最後の行のdmyを入れておかないと、すぐに実行が終了してしまい、グラフを味わえない。 それを入れても、表示のタイミングかしらないけど、グラフの内容が表示されない事が あった。
しょうがないので、keyboardってコマンドで、deubggerに落ちるようにしたら、ちゃんと 表示するようになった。debuggerから抜けるには、dbcontとすれば良い。
[sakae@fedora bld]$ octave z.m stopped in /home/sakae/bld/z.m at line 12 12: keyboard("debug>> ") # fall to debug, dbcont to leave debug>> p p = 0.12319 57.57598 debug>> corr(hi,lo) ans = 0.26653 debug>> dbcont Hit any key to fin dmy = [](0x0)
debuggerが起動すると、replが動き出すようなので、変数の値を確認したり、新たな式 (この場合は、相関)を評価したり出来る。
[sakae@fedora bld]$ octave-cli z.m stopped in /home/sakae/bld/z.m at line 12 12: keyboard("debug>> ") # fall to debug, dbcont to leave debug>> dbcont Hit any key to fin dmy = [](0x0)
octabe-cliで、CUIモードとしても起動出来るけど、この場合は、出てきたグラフを マウスでぐりぐり拡大したり回転したりは出来ないようだ。
スクリプトを指定せずに、octaveを起動すると、GUIの総合開発環境が立ち上がって しまいイラっとするんだけど、スクリプトを喰わせる場合は、グラフが(もし指定してれば) 出て来るだけで、かつ上記のようにdebuggerと併用すれば、新たな評価も出来て好都合。
多変量解析とoctave
ふと、上の例題をやっていて、行列やベクトルの演算が得意なOctaveなら、多変量解析も 難なくやってくれるだろって思った。で、検索してみたよ。
リンク集(ニューラルネットワーク理論・応用、インテリジェントシステム、ビッグデータ解析)
Octave-Forge - Extra packages for GNU Octave
emacsからoctaveを使う
最新のマニュアルを見ると、emacsからも使えるようだ。で、サフィックスがmならoctave-modeねって設定を書いて起動するも、Fundamentalなモードになってしまう。そればかりか、emacsが発狂して、カーソル移動でも頓珍漢な事を抜かすようになった。
設定がoctave-modじゃん、これ間違いじゃんて訂正しても、相変わらず発狂。 よくよく考えたら、autoloadって、pkgを使う時の設定じゃん。この設定が有るんで、 デフォで入っているoctave-mode.elが読み込まれず、無いものねだりしてemacsが発狂してた。 誰も文句を言わない所を見ると、emacsなんて使っていないのかな? 最新のmanualでは 付録になってたemacsの使い方も削除されてる。
後のために、設定だけ載せておく。
;; octave-mode (setq auto-mode-alist (cons '("\\.m$" . octave-mode) auto-mode-alist))
兎も角、第一関門をクリア。M-x run-octave して、octaveを走らせる。そしてプロンプトの 所で、サフィックスを省いたスクリプトファイル名を入力すると、スクリプトが実行され、 プロンプトに戻ってくる。上でやったように、debuggerで一時停止するとか、面倒な事は 不要。これは便利。
もっと手抜きしたかったら、編集画面に居る時、C-c C-l すれば、いちいちファイル名を 入力する事なく、実行される。結果が気にいらないなら編集、保存、C-c C-l のサイクルを 回すだけ。
そして、もう一つ便利なのは、M-x octave-lookfor を使って、うろ覚えの関数を検索 出来る事。例えば、csvって入力すると、
csvread Read the comma-separated-value file FILENAME into the matri x X. csvwrite Write the matrix X to the file FILENAME in comma-separated- value format. Retry with '-all'. [back]
こんな風に検索してくれる。そしてそれぞれにリンクが貼られているので、リンクの所で RETを叩くと、その関数のhelpが見られる。そこから抜けるには、q を叩く。
この機能、octave自身を使っているようで、 プロセスが走っていないと使えないので注意の事。
emacsが使えるので、手軽に実験。forは使うなの検証。
tic(); N = 1000000; a = rand(1,N); b = zeros(1,N); for ii = 1:N if a(ii) > 0.3 b(ii) = 1; else b(ii) = 0; end end toc()
こんな bad.mを走らせる。
octave> bad Elapsed time is 16.0361 seconds. octave> bad Elapsed time is 16.1651 seconds.
今度は、forブロックをやめて、b = a > 0.3; にした良い子ちゃん。
octave> good Elapsed time is 0.0247869 seconds. octave> good Elapsed time is 0.032742 seconds.
劇的に違うな。これって、内包表記をやった事になるのかな? 簡単過ぎて笑っちゃうぞ。
所で、時間を測ってくれるマクロってないのかなあ、と、scheme方面から 来た人は思っております。
で、 いよいよ深層学習かと思ったけど、長くなりそうなので次回に回す。 octaveは深層学習のために有るかと思ったら、もっと一般的なのも大得意なのね。
が、面白い。