回帰
テンプレート
別にCフラフラ語のテンプレートシステムでも無く、テンプレート Haskellの事でも無い。 読書感想文をいかに書くかと言う書式の事を取り上げたい。
お子様の夏休みの宿題に、読書感想文ってのがある。対象に漫画を選んじゃったらいけないのだろうか? 漫画々と馬鹿にするなかれ。手塚さんの素晴らしい、考えさせる漫画とかあるから、それらを題材にしても一向に構わないと思うんだけど。
そこはそれ、頭の固い教育委員会の人達は、そんなの駄目と予防線を張っている事だろう。読む本を予め指定されたりして。いわゆる課題図書ってやつだ。その方が評価する方も楽って魂胆があるからね。大人の事情ってやつだ。
読書ぐらいは自由にさせてあげようよ。で、難関は読書感想文。どういう風に書いたらいいの? 某Tvで取り上げていた。それにそって書けば、悩む事は無い。
大きな命題は小さな物に分解してしまえ。そうすれば容易に問題を解決出来るぞ。これぞ、ソフトウェア開発の真髄ですな。
AIに、吾輩は猫であるって本の読書感想文を書けって指示しても、きっと発狂するだろう。 小さく分ければ、なんとかなるかな。
読書感想文 テンプレートとかで検索したら、出るわ出るは、皆さんお悩みの極みなんですな。
色々出て来たけど、一つだけ挙げておく。
オイラーの場合
オイラーも書いてみるか。課題は、 統計学が最強の学問である[数学編]
感想文テンプレートでは、選んだ理由をまず書くんだな。
図書館に置いてあったから。なんじゃいそれは? どうして山に登るんですかって質問に、そこに山が有ったからーーーって答えるのと一緒じゃん。
何時も巡らない書だなをぶらぶらしてたら、眼に止まった。同名のシリーズ本がもう一冊あったけど、なんとなく数学ってのに惹かれて、選んだ次第。
次は、あらすじを書くんだな。
そんなの上の目次を見ろ、以上。そんなの無いしょ。数学落ちこぼれの人が、統計と機械学習の本を読むのに必要な数学力を得るための本です。
オイラーさっぱり行列が分からんと言って、数学書を紐解くのは無駄。関係ない領域まで踏み込んで、更に分からなくのがおち。どんな場合に使えるねんってのが、ただの数学書には決定的に欠落してる。
この本は、そんな所を順番に丁寧に説明してるんで、ストンと腑におちる。いわゆる無味乾燥が無いんだ。
気になった所はどこってのも、感想文には重要なんだな。何故、機械学習には e が頻出してくるのか。微分が非常に楽だから。大人の事情ってか、ずる賢い方法なんだな。こういうのは常識なんだよってんで、省いてあるのが普通だけど、丁寧に説明してた。これで怖くなくなったぞ。 数学者と統計学者で、書き方が違っていたりするけど、そういうのも丁寧に説明されているんで、初学者にはありがたい。
有り難いと言えば、
y = b + ax y = Xβ
上の式は、入力xに係数aを掛けてから切片を加えると、予測値yが出て来るよって基本の式だ。 これを、シグマ記号とかベクター表記とか、更に発展させて行列で表すと、下の式のようになる。
それはいいんだけど、元々の式に有った切片bはどうなったの? βの中に吸収しました。そしたら、式がすっきりしたでしょ。答え一発、掛け算だけ。スパコン喜ぶ、オイラーも喜ぶ。 でも、項数が合わなくなって、行列演算が出来なくなるんじゃない。
それを防ぐ為Xに一列追加。その内容は、掛け算の単位元である1が並んだもの。さらっと書かれていたけど、素晴らしい工夫だ。これが分かっただけでも、この本のありがたさが発見出来たよ。
更に気になった所。ガウスの正規分布の式が、どうしてあんな数式になるんですかっていやな質問。
正規分布の事を英語では、Normal Distribution って言うそうな。素直に日本語にすると、ふつうのバラツキ方って事になる。正規分布って業界用語なんだな。権威の象徴語だ。
ガウスは、本当の値と観測値のずれに付いて、考えていた。そして仮設を立てた
1. 本当の値からのズレは、小さいズレの確率が大きく、大きくズレる確率は小さいだろう 2. ズレは、プラス側にずれる場合とマイナス側にズレる場合あるけど、それは対称だろう 3. 本当の値の推定方法としては、観測値の平均を感がるといいだろう
これ、妥当な仮定ですね。世の中の人々の資産の分布なんてのは、これに当てはまらないって事はすぐに分かる。
ここから、 ガウス分布の導出 のようになるとな。セカンドオピニオンで、正規分布の式の導出 なんてのもある。微分だとか積分を丁寧にやったので、拒絶反応なく、上記が読めたぞ。良かったなと。数学的準備 こういうのも平気だな。
最後の6章が、今まで説明してきたのの総まとめで、総合力を発揮する所だけど、オイラーの読書スタイル、取り合えず通読してみるで、軽く流してしまった。
借用を延長して、付箋を貼りつつ再読してみるか。
テンプレートでは、気持ちの変化や、本を読み終わって分かった事を書く事になってる。それに続いて、よその人がどうだったかにも注目するとな。
なんてのが有った。何でも調べられるのは良いんだか悪いんだか。。。
これが、一番良かった。
この本は、単回帰、重回帰を主に扱っている。回帰って何やねん? そんな説明は無かったように思う(見落としていたら、スマソ)。シリーズ本で多分説明してるんだろうね。ちょいとズルして調べてみると、
回帰は語源的には回帰効果(平均への回帰)に由来するらしい。そもそも回帰は、ある事が行われて、また元と同じ(ような)状態にもどること。なんだ、輪廻転生か、って、いつから和尚さんの弟子になったん?
実例探求
上記本の最後に、その先へって案内が出てた。Rは馬力は無いけど、色々な統計手法を試せる探求者向けだよ。pythonは、それ自体では遅いけど、色々な高速ライブラリーが有るんで、結構使えるよ。なら、オイラーも手を出してみる。
python
統計の基礎は回帰に有りって事なんで、回帰回帰と唱えたら、 Scikit-learn でロジスティック回帰 を紹介されたよ。
題材はお馴染みのやつ。いざ走らせてみると
ob$ python3 ir.py Traceback (most recent call last): File "ir.py", line 6, in <module> import seaborn as sns ModuleNotFoundError: No module named 'seaborn'
pythonでは、これまたお馴染みのエラーに遭遇。モジュールを入れないと何も出来ないって事です。そしてモジュールの整合性が取れていないと、意味不なエラーに見舞われる。モジュール地獄が待ってます。この点でもオイラーはpythonが嫌いになりました。はて、どうする?
sudo pip3 install xxx とかやって、エラーを潰して行きます。普通はanacondaを入れるんでしょうけど、余計な物がごっそり付いてくるので避けたい。ならばminicondaを入れる?
リナしか動かん、32Bitは切って棄てられたって厳しい現実があります。
32Bit機にpython3.8.3を入れ、上記のスクリプトが実行出来るようにしたら
debian:~$ cd /usr/local/lib/python3.8/ debian:python3.8$ du -sh site-packages/ 290M site-packages/
こんな具合になった。有名な numpy,matplotlib,scipy,pandas,seaborn,scikitlearn,sklearnあたりの 機械学習に必要そうな物が問題無く揃ったよ。
R
回帰で調べていたら、サポートベクターマシンなんて言う、カッコイイ用語が出てきた。昔やったような気がするんだけど、記憶が蒸発してしまっているんで、リフレッシュ。
着地した所は、どうやらRの陣地だった。RだったらOpenBSDに入っているぞ。 パッケージを取り合えずローカル環境に入れた。
コピペしたソースをどうやって実行するのかな? 奥村先生が教えてくれたよ。Rの初歩
ob$ R R version 3.6.3 (2020-02-29) -- "Holding the Windsock" Copyright (C) 2020 The R Foundation for Statistical Computing Platform: x86_64-unknown-openbsd6.7 (64-bit) > source("svm.R") Setting default kernel parameters Setting default kernel parameters Error in library(caret) : there is no package called 'caret'
図の文字が化けているなあ。ちゃんとロケール設定すればいいのかな。それより、追加のライブラリィーが必要とな。
debianだと、 r-base して、ベースのRを入れてから、 r-cran-* とかして、パッケージを追加するんだな。最新のパッケージを欲しいなら、自分で何とか(コンパイル)して下さいだな。 OpenBSDの時は、勝手にコンパイルが始まって、はらはらドキドキしたよ。
debianにcaretを入れたら320Mもdiskを消費してくれた。
octave
機械学習をゼロから1ヵ月間勉強し続けた結果 に尽きるでしょう。
Octave で OLS(最小2乗法)
動かすまでに、こういう苦労が有るよ。
;; octave-mode (setq auto-mode-alist (cons '("\\.m$" . octave-mode) auto-mode-alist))
言わずと知れたemacsの設定。C-c C-l で実行出来たり、 M-x octave-lookfor で、ファジィーな検索が出来る。
function pause input('','s'); end
octave 5.1.0 のpauseがBUGってるので、その代替Hack。
sakae@pen:~$ cat .octaverc graphics_toolkit('gnuplot');
グラフが表示されないので、間に合わせでgnuplotを使うとな。
scikit-learn
何と言っても、機械学習の事を要領よくまとめているのは、こちらだ。
Scikit-learnとは?5分で分かるScikit-learnのメリットや機能まとめ
ググル様やフェーズブックで公開してるやつをやる前の嗜みだな。
others
にも、機械学習に使われる数学 なんてのが有ったりして、本の内容を忘れてしまった時に 見ればいいな。基礎が出来てると、思い出せるだろう。
その他では、 統計学入門 が、網羅的に扱っていて良PDFだと思うぞ。これを読んで、p値なるものの概念がやっと分かった。
自由研究
なんてのが見つかった。これを肴にして、自由研究する。お第は、過去の私と今の私を区別出来るか? です。
今までずっと測り続けている血圧データ(最高血圧、最低血圧、脈拍)がある。
血圧は一般に年齢とともに高くなります。ただし、上の血圧は上昇を続けるのに対し、 下の血圧は高齢になるとむしろ下がってきます。 ~20歳未満では80+2x(mmHg:xは年齢)、20歳で120mmHgに達し、20歳以後は 120+(x-20/2)(mmHg)が一応の基準値あるいは平均的な値
らしいです。だったら、血圧データを提示するだけで、昔の自分か今の自分か分別(ゴミみたいな言い方だな)もとえ分類出来るんじゃなかろうか? ロジスティクス回帰ね。
実験計画法
2012年からのビッグデータが手元にある。2012年と今年の2020年を比べてみよう。朝と夜のデータが有るけど、標準偏差が小さい夜のデータを使おう。
日本には四季が有るというけど、そんなの嘘で、糞暑い夏と冬しか無いと思うぞ。気分的に夏の方が血圧が安定してると思う(仮定)ので、5,6,7月を対象にしよう。5,7月のデータをトレーニング用にする。間に挟まった6月のデータをテスト用とする事にした。
こんな条件で、データを用意する。まずはトレーニング用データ
sakae@pen:/tmp/my$ cat current.csv | egrep ^120[57]..2 > 12.txt sakae@pen:/tmp/my$ cat current.csv | egrep ^200[57]..2 > 20.txt sakae@pen:/tmp/my$ cat 12.txt 20.txt >tr.txt
仕様に則り、YYMMDDHH の日時を頼りに必要なデータを抽出。それを結合しておく
sakae@pen:/tmp/my$ cat tr.txt | sed 's/\(..\)......\(.*\)/\1\2/' | awk 'BEGIN{FS=","; OFS=","}{print $2,$3,$4,$1}' >tr.csv
測定年とデータだけをsedで抽出する。測定年が期待値になるんだけど、それを最後の列に移動したいので、awkで処理。
分析に入る前に、元データの概略を把握しておく。
octave:1> d12 = csvread ("12.txt"); octave:2> d20 = csvread ("20.txt"); octave:3> statistics (d12) ans = 12050121.00000 95.00000 52.00000 58.00000 12051646.00000 100.00000 60.00000 66.00000 12061621.00000 102.00000 64.00000 68.00000 12071596.00000 109.00000 67.75000 70.50000 12073121.00000 124.00000 76.00000 78.00000 12061621.00000 105.37097 63.96774 67.88710 10121.88021 7.11322 5.08926 3.55797 0.00000 0.91633 0.19195 -0.12672 1.03154 2.83087 2.69897 3.64384 octave:5> statistics (d20) ans = 20050121.000000 108.000000 56.000000 53.000000 20051721.000000 114.000000 61.000000 57.000000 20070121.000000 120.000000 62.000000 58.000000 20071621.000000 125.000000 65.000000 60.000000 20073121.000000 137.000000 73.000000 64.000000 20061799.688525 120.114754 62.606557 58.573770 10106.798286 7.035857 3.343046 2.432139 -0.032406 0.306495 0.592462 0.126799 1.032775 2.357868 3.425829 2.937580
最高血圧は年齢とともに上昇。最低血圧は横這い。脈拍は年齢と共に低下してるって言う大雑把な結果だな。
Bug潰し
これで回帰出来るか?
octave:1> bld learning_rate = 0.010000 iteration = 10000 cost = NaN :
計算不能? 与えたデータが過大過ぎて計算出来ないのか。試したコードはirisそのものだから、Bugは無いと思うからね。取り合えず、データが過大と仮定して20dBのアッテネーターを入れてみる。
D = csvread('tr.csv'); # Load iris.csv D = D ./ 100;
全要素を1/100に変換。行列ってのはデータの塊。それを一気に演算出来るって気持ちいい。
cost = 0.0019932 cost = 0.0017313 cost = 0.0015134 cost = 0.0013318 cost = 0.0011803 cost = 0.0010538 cost = 0.00094792 cost = 0.00085915 cost = 0.00078455 theta = -0.111983 0.091099 0.220021 0.047291 validationErrorRate = 0 validationTotalCost = 0.00078448
今度は上手くいったな。
さて、いよいよvalidation用のデータとして、6月分のデータを用意する。そしてそれを組み入れて実験。エラー無しで実行出来た。
本当に正しいデータを使っているのか? やや消極的ながら、変数の使いぷりを確認。
octave:2> whos Variables in the current scope: Attr Name Size Bytes Class ==== ==== ==== ===== ===== D 59x4 1888 double Dt 123x4 3936 double Dv 59x4 1888 double Xt 123x4 3936 double Xv 59x4 1888 double Yt 123x1 984 double Yv 59x1 472 double cost 1x1 8 double diff 59x1 472 double diffI 1x1 8 double error_data 0x0 0 double i 1x1 8 double iteration 1x1 8 double j 1x1 8 double learning_rate 1x1 8 double n 1x1 8 double numOfParam 1x1 8 double report_interval 1x1 8 double theta 1x4 32 double training_data_count 1x1 8 double update 1x4 32 double validationErrorRate 1x1 8 double validationTotalCost 1x1 8 double y 59x1 472 double
Xtが123行って事は、トレーニングデータだな。Xvが59ってのは、検証用のデータって事だ。 どうやら良さそう。
それにしても、最高血圧、最低血圧、脈拍の3つ組データから、ちゃんと過去と現在をより分けてくれるって素晴らしい。どういう頭の構造してるねん?
one hot vector by octave
octave:5> q = [3;2;6;5] q = 3 2 6 5 octave:6> q == 1:max(q) ans = 0 0 1 0 0 0 0 1 0 0 0 0 0 0 0 0 0 1 0 0 0 0 1 0
勉強はスパイラル