Coursera Machine Learning 受講ノート 3
ななめよみしてなんとかテストにパスした Week 1 / Parameter Learning
線形回帰以外に最急降下法というのがある。 ある目的関数Jに対して、その最小値を取りたい。 そこで、θ(0)とθ(1)を少しずつずらして最小値、あるいは局所的最小値を探す。 最急降下法(Gradient Descent)は、開始地点によってまったく違う局所的最適解にたどり着くことがある。
:=
は代入を示す。
最急降下法は、すべてのパラメーターθ(j)に対して同時に計算を行い、同時に更新を行う。
理解を助けるためにθ(1)だけを扱う。 するとJ(θ(1))は二次関数になる。 であればJ(θ(1))の微分をとってそれが0になる箇所を探せば、それは必ず最適解である。
適切な学習率を指定された最急降下法では、イテレーションを繰り返すほどにステップが小さくなっていく。
ではこれを二乗誤差の目的関数に適用したらどうなるだろうか?
Week 1 / Linear Algebra Review (Optional)
行列とベクトルについての復習。ありがてぇ...。
行列 == Matrix。
行列は2次元以下の数字の並びを指す。
R(2 x 3)のように書いて、2行 x 3列の行列を示すことがある。
行列の要素は1から始まるインデックスで参照できる。
ベクトルはn x 1の行列。 nは次元の数で、R(n)と書いてそれを示すことができる。
行列は普通1-indexed(1はじまりのインデックス)で、大文字アルファベットに定義する。
行列同士は足し算できる。同じ次元の行列しか足せない。 行列に実数を掛け算・割り算することもできる。起こることは想像どおり。 (行列に実数を加減算はできるのかな?)
Cousera Machine Learning受講ノート 2
Week 1 / Model and Cost Function
教師あり学習の周辺の用語定義回っぽい。
あるデータ群からモデルを作り、そのモデルを使って何かを推測する時、それは教師あり学習。
データの属性を表すnoteには - m: データ数 - x: 入力に使う特徴 - y: 求めたい値
の3つがある。
普通
(x(i), y(i))
というように1行に1つのデータを書く。
教師あり学習では、訓練データのxとyを使って、任意のxを入れるとそれらしいyが出るような仮説hを立てる。
このhをまずは
y = θ(0) + θ(1)x
と表現する。これはあるデータセットを分割できる直線を探すことを意味する。 これを単回帰と呼ぶ。
目的関数
次に、目的関数を定義する。 仮説に出てくるθをパラメーターと呼ぶ。パラメーターが変わると仮説関数の形が変わる。(単回帰の場合なら切片と傾きが変わる。)
式でこれを表現することで、この線形回帰の目的関数の計算式を導出できる。
仮説hのグラフの形とは別に、あるパラメーターの時の目的関数の値をプロットして、それが最小となる地点を調べることで、最適なパラメーターを決定できる。
課題も良い難易度だし、文系卒で線形代数わからなくてもまだ一応耐えられる。 今、高校数学・大学教養レベルの数学を学び直せばプログラミングで得た知識を使ってもう少し理解を深められそうだなぁ〜。
Cousera Machine Learning受講ノート 1
Week 1 / Introduction
ミッシェルいわく、機械学習の定義とは
A computer program is said to learn from experience E with respect to some class of tasks T and performance measure P, if its performance at tasks in T, as measured by P, improves with experience E.
コンピューターは、もしあるタスクTの効率Pが、経験Eによって向上しているならば、効率Pで行うタスクTの経験Eから学んでいるといえる。
教師あり問題には回帰問題と分類問題がある。 回帰問題は連続値から何かの値を推測するもの。 分類問題は値セットを何種類かに分類するもの。
教師なし学習とは、たんにデータセットだけがあり、それを分類する問題。 これを行うアルゴリズムはクラスタリング・アルゴリズムといわれる。
たとえば背景の雑音から特定の話し声だけを分離することができる。 すごい! これ使えばカラオケを簡単に作れるのでは...。
日本語字幕もあるしReviewも良い難易度(いまのところ)。 前提要件に「基本的な線形代数学と確率論への理解」が含まれることに一抹の不安を禁じ得ないけど頑張っていこう。
ななめよみ・高卒でもわかる機械学習(2)
CouseraのMachine Learningコース受講前に日本語でざっくり情報を入れるために、高卒でもわかる機械学習 (0) 前置き | 頭の中に思い浮かべた時にはを読む。
今回はその2から。 パーセプトロンなるものについて解説するらしい。
単純パーセプトロン
前回学んだ、メールがスパムかどうかを判定するグラフを指す。 複数の入力に重みをかけあわせて、結果が0より大きければ1を返し、0以下なら0を返す。
これがニューラルネットワークの基本単位。 そしてこの「重み」をベクトルにして自動計算するのが機械学習というわけか。
どうやって重みを更新するのか?
その手順は、 - 最初はランダムな値を設定する - その重みを使って教師データを解いてみる - 間違いに対して、正しそうな方向に重みを微修正してリトライ - 繰り返し
である。
まずある関数がどれくらい教師データに対して期待はずれだったかを表す「損失関数」を想定する。 この関数の最小値を取れれば、そいつが単純パーセプトロンの最も期待どおりに振る舞う重みだと判定できる。
最小値を求めるためには、今の座標での関数の傾きを求め、それが正なら小さく、負なら大きくなるように少しずつ調整していくと良い。 (とはいえこれだと、谷が複数ある損失関数が書ける場合に失敗する気がする。)
この「少しずつ」の割合はそのままだと大きすぎて収束しないので「学習率」と呼ばれる定数をかけあわせてうまく収束するように調整する。
これを勾配降下法と呼ぶ。
これを使って重みを微調整した結果、最終的に重みの更新が全くなくなれば学習が終了する。
出力する
勾配降下法を使って重みを調整し学習したモデルは、与えられた入力に対して何か別の値を出力する。 たとえばスパム判定なら1 or -1、みたいな。 「○○らしさ」を数値化したものを入力に使って、外部に公開する値を生成する関数を「活性化関数」と呼ぶ。
スパム判定は二値判定であり、スパムなら0より大きく、そうでないなら0より小さい値がモデルから返るので、 - モデルの返却値 >= 0 ならば 1 - モデルの返却値 < 0 ならば -1
となる関数を定義するとわかりやすい。
多分多層パーセプトロンっていうのは、神経回路みたいに単純パーセプトロンを何層も積み重ねて活性化関数で出力された値を次のパーセプトロンに引き継ぐモノなんだろうな。
多層パーセプトロン
単純パーセプトロンにはできないことがあって、それがXOR問題である。つまり、単純に1本のグラフで分けられないような集合に対しては何もできないのだ。 これは前に学んだ言葉でいう「線形識別不可能」なデータだといえる。
これを解決するのが多層パーセプトロンである。 XORに代表される線形識別不可能なデータは、線形識別可能な関数を複数個組み合わせることで実現できる。 こうして積み重ねられた複数の単純パーセプトロンを組み合わせたものが、多層パーセプトロンである。
この多層パーセプトロンにおいて、最初の層を入力層、最後の層を出力層、そして間のすべてを中間層と呼ぶ。
ではこの重みはどう計算するのかだが、ここから先は計算式が多すぎて理解できない。 今回は雰囲気を知るのが目的なので、微積分・ベクトルの知識を仕入れてリトライすることとして読み飛ばす。 ただ、多層パーセプトロンの重みを更新するためには「逆伝播」と呼ばれる方法を使うことはわかった。つまり計算時は入力層から順番に計算を進めるが、重みの更新時は出力層から順番に更新していくらしい。
斜め読み - 高卒でもわかる機械学習
とうとう機械学習を使えるようになろうと思うので、手始めに
をざっと読んで全体像をつかむことにした。
1回目なのでまずは斜め読みして、2回目以降もう少し知識がついた時に詳しく読むことにする。 斜め読みはするが、筆者の方には勿論感謝と敬意を払っている。
記事自体は2年前のものなので今はまた違うのかもしれないが、なんにせよ基礎を知るのは悪いことではないはず。
機械学習を学ぶ最終目標
たとえばあるスキルセットをもったエンジニアに対してどれくらいの給与を提示するのが市場の相場か?を算定してみたい。 つまり 0 or 1 ではなく具体的な数値をアウトプットする機械学習アプリケーションを構築したい。
機械学習が解決してくれる問題の種類
- 分類問題: 入力が何かに分類できると判断する(ex. 猫画像判定)
- 回帰問題: 入力から新しい情報を生成する(ex. 降水確率予想)
どっちを解決するかはアルゴリズムの「評価関数」によって決まる。
機械学習の種類
種類があるらしい。そりゃそうか。ニューラルネットワークとか?と思ったけど違うらしい。
- 識別関数: 入力があるものに分別できるか判定する(ex. スパム判定)
- 識別モデル: ???
- 生成モデル: 入力を使って新しい情報を生成する(ex. 自然な日本語の文章を自動生成する)
識別関数が一番初歩的でとっつきやすいらい。
機械学習の成果の正しさ
学習の仕方が間違っている時と、判定が間違っている時がある。 たとえばある入力値がA,B,Cのどれに所属するか調べる時に以下のような表が組める。
No | Aの確率 | Bの確率 | Cの確率 | 正解 |
---|---|---|---|---|
1 | 0.36 | 0.30 | 0.33 | A |
2 | 0.9 | 0.06 | 0.04 | B |
No.1では確率がバラけないので、学習が間違っているかもしれない。 No.2では確率はバラけているが、判定結果が間違っている。
識別関数とは
入力値を「素性」と呼ばれるデータにバラす。 そして真な結果に何回出現したか調べる。 それに従ってテストデータを解析し、真な結果に多く見られるデータが何回出てきたかでテストデータの真偽判定を行う。 メールのスパム判定機とかが作れる。
数学的には、ある平面にプロットされた学習用データのうち、真と判定されるものと偽と判定されるものをキレイに2分する関数を導出することといえる。
線形分離可能とは、ある関数によってスッパリ分けられること
上述のように、ある空間上にプロットされたテストデータ郡をスッパリと2つに分けられる関数が存在する場合、それを「線形分離可能」と呼ぶことができる。
これができない問題は「線形分離不可能」と呼ばれる。点がめちゃめちゃに入り混じっている問題は線形分離可能な問題と同じ手法では解くことができない。
参考文献
今度こそ受け切るCoursera Machine Learning
来たる12/11から、また新学期が始まるようです。
これまで2度受講してそのうちどちらも最初のIntroductionの課題を先送りにして挫折した僕も、もうさすがに自分のスキルセットに機械学習の基礎がほしいので、今度こそ受けきってみせる。
ductとataraxyでふつうのWebサイトを作る
「ふつう」には全く深い意味はなくて、ただただHTMLをGETできてPOSTリクエストを受け付けられるふつうのWebサイトを作ろうとしてみた。 ふつうすぎて逆に情報がなかったのでまとめてみる。
バージョン情報
- duct: 0.6.1
前提知識
やったこと
とりあえずプロジェクト生成する
lein new duct sample +site +example
DBは置いておく。作者が書いたAPIサーバーを作れるブログエントリがあるのでそれを見れば触れるようになると思う。ここで出てくるboundaryという概念もクールだなーと思ったけどそれはまたいつか。
とりあえずエディターからREPLにつなぐ
おもむろにEmacsを立ち上げてcider-jackinする。
動かしてみる
この時点で localhost:3000/example にアクセスするとサンプルページが出る。
formを書く
[hiccup "1.0.5"]
を依存に追加して以下のようなコードを書いてみる
[::response/ok (html [:h1 "hello"] (form-to [:post "/example"] [:p (label {} "username" "username") (text-field {:placeholder "username"} "username")] [:p (label {} "email" "email") (email-field {:placeholder "foo@example.com"} "email")] [:p (label {} "password" "password") (password-field {:placeholder "your password"} "password")] (anti-forgery-field) [:p (submit-button {} "submit")]))]
すると localhost:3000/example で
みたいな画面が見える。
POSTする
ルーティングをいじる。
:duct.module/ataraxy {"/example" {[:get] [:example/new] [:post {user :params}] [:example/create user]}} :sample.handler.example/new {} :sample.handler.example/create {}
で、関数のnamespaceとかも書き換える。
(defmethod ig/init-key ::new [_ options] (fn [what-is-this] (println what-is-this) [::response/ok (html ;; 省略 )])) (defmethod ig/init-key ::create [_ options] (fn [{[_ user] :ataraxy/result}] (println user) [::response/ok "created"]))
この状態で localhost:3000/example にアクセスしてformを送信すると画面遷移するし、REPLにリクエスト情報が出てくる。 やったぜ。
リクエスト自体をもらいたくなったらどうする?
routing時点でのデスラクチャリングはataraxyの強みだけど、もしもっとガツッとほしくなったら? その時はhandlerの無名関数が受け取る引数を、バラさずにそのまま受け取れば中にリクエスト内容が全部入ってる。
anti-forgeryとかのミドルウェアどこで差し込まれてるの?
がconfig.ednに差し込まれてて、うまいことデフォルト値を定義してくれているよ。 定義内容が知りたければREPLで
(prep) (pprint config)
したらわかる。
感想
しばらく前にClojure始めてよかったなーという気持ちしか沸かないくらい過去の資産をうまーく組み合わせて実現されてた。 これだけのエコシステムを数年かけて作ってきたring / ductのコミュニティとそれを牽引したweavejester本当にすごいな。