Coursera Machine Learning 受講ノート 6

f:id:blackawa:20171218110601p:plain

Week2 / Normal Equision

正規方程式。最急降下法で漸近的に得ていた最適値を一発で出すための方程式。

偏微分解析学わからないとわからない領域に入ってきたが、後でフォローしてもらえるらしい。

訓練データとその答えを別の行列とベクトルとして扱って、それをある方法で解くと最適なθが手に入るらしい。

具体的には

pinv(x' * x) * x' * y

この式を使う場合、前に説明したFeature Scaling(すべてのパラメータをだいたい同じ値に揃えること)は必要ない。

正規方程式と最急降下法の使い分け

最急降下法では、学習レートを選んで何度もイテレーションを回す必要があるが、特徴が何個あってもちゃんと動く。 正規方程式では特徴の行列をその転置行列と掛け算して逆行列を求める必要があるので、特徴が増えるとめちゃめちゃ遅くなる。 具体的には、10,000個の特徴を計算するくらいまでは正規方程式でも良い。

正規方程式と非可逆性

Octavepinv関数は、x' * x が非可逆でもθを計算できる。 非可逆な時は

  • 冗長な特徴がある
  • 特徴が多すぎる

ことを疑うと良い。

課題提出システム

すごい。 Octaveって ファイル名()すると中身を実行できるのか。

submit() で提出できるのクールだな。

添字つきの変数が混乱してきた。

右上と右下にそれぞれ変数がつくやつ、最初分かってたけど読み方忘れてきた。

Week2 / Octave/Matlab Tutorial

Refs

Coursera Machine Learning 受講ノート 5

f:id:blackawa:20171218110601p:plain

Week 2 / Multivariate Linear Regression

多変量線形回帰について取り扱う。多分ここからOctaveをガツガツつかっていくんだろうなー。

ここまでで取り扱ってきた線形回帰は、ひとつの入力値にくわえてθ(0)とθ(1)を扱うことで予測を行ってきた。 しかし入力値をもっと増やしたら?

これからx(i)は、i行目の入力値のベクトルとする。

すると今まで使っていた

hθ(x) = θ(0) + θ(1)x

の式は

hθ(x) = θ(0) + θ(1)x(1) + θ(2)x(2) + θ(3)x(3) ...

転じて

hθ(x) = θ(0)x(0) + θ(1)x(1) + θ(2)x(2) + θ(3)x(3) ...
// ただし x(0) = 1

と表現でき、これはつまり

hθ(x) = θTx
// θTはθを転置した行列
// x = [x(0) x(1) x(2)...]というベクトル

と表現できる。

多変量の線形回帰を解くには、これまでに扱った1変数の線形回帰と同じような式が出てくる。 値を少しずつ変えて最適解に近づく式もそのひとつで、今まで1つのパラメーターについてやればよかったことを複数のパラメーターについてやれば良い。

実践的なテクニック

入力値の値の範囲を調節して収束を早める

すべての変数を同じような値の範囲になるように調整する。 つまり、等高線が真円に近づくような値にするとより早く収束する。

だいたい-1から1の間らへんになるようにすると良い。

  • -3 < x(i) < 2 -> OK
  • 0 < x(i) < 2 -> OK
  • -100 < x(i) < 100 -> NG
  • -0.0001 < x(i) < 0.0001 -> NG

具体的には、すべての訓練データの入力値に適切な値を加えて、平均値がだいたい0になるようにする。 ただしx(0)は必ず1なのでそれをやらない。

mean normalizationは

x(i) - μ(i) / s(i)
// μ(i) = 訓練データxの平均
// s(i) = 値の範囲。max(x) - min(x) もしくはxの標準偏差

で表現できる。

適切な学習レートを見つけ出す

話変わって、今度はどうやって学習レートを調整するか?の話。 学習レートは、学習を繰り返すごとにコスト関数の値が0に近づいていくような値を設定すべき。

何回くらいイテレーションを繰り返せばよいかは予測が難しいので、コスト関数が常に収束に向かうことで学習レートの正しさを推測する。

予測に使う変数を選出する

必要なら、与えられた値セットを加工して新しい特徴を作り出してそれを予測に使用しても良い。 あるいは、1つの変数しかないがそれを3次関数としたい(上昇し続けるグラフになる)場合、1つの変数を累乗した値を2つめ以降のパラメータに使っても構わない。 累乗でなく平方根をとったりしても良い。

Coursera Machine Learning 受講ノート 4

f:id:blackawa:20171218110601p:plain

Week 1 / Linear Algebra Reviewの続きから

行列の掛け算は、行の要素と列の要素をそれぞれ掛け算して結果をすべて足した値を結合した行列になる。

[[1 2]
 [3 4]
 [5 6]]

かける

[7 8]

[23 53 83]

となる。

これをふまえて、複数の値x(10, 15, 20)に対する以下の式のyを求めたい時、

y = b + ax
[[1 10]
 [1 15]
 [1 20]]

[b a]

をかけると、答えのセットが手に入る。

行列と行列の掛け算は、行列とベクトルの掛け算の拡張版。

ただし行列の掛け算は、Commutativeではない。つまり、A * BB * A は同じ値にならないことがある。

Identity Matrix(単位行列)っていうのもある。こいつと任意の行列の掛け算は、結合則(I * A = A * I)を満たす。

行列の逆数を取るとどうなる?つまり、A * inverse of A = Identity Matrixとなるような行列は何だろう。 逆行列を持てる m x m の行列Aにおいて、 A * A(-1) = Identity Matrix が成り立つ。 これはOctaveでは pinv(A) と表現できる。

また行列は転置できる。 f:id:blackawa:20171218110601p:plain

Week 1 / Linear Algebra Reviewの続きから

行列の掛け算は、行の要素と列の要素をそれぞれ掛け算して結果をすべて足した値を結合した行列になる。

[[1 2]
 [3 4]
 [5 6]]

かける

[7 8]

[23 53 83]

となる。

これをふまえて、複数の値x(10, 15, 20)に対する以下の式のyを求めたい時、

y = b + ax
[[1 10]
 [1 15]
 [1 20]]

[b a]

をかけると、答えのセットが手に入る。

行列と行列の掛け算は、行列とベクトルの掛け算の拡張版。

ただし行列の掛け算は、Commutativeではない。つまり、A * BB * A は同じ値にならないことがある。

Identity Matrix(単位行列)っていうのもある。こいつと任意の行列の掛け算は、結合則(I * A = A * I)を満たす。

行列の逆数を取るとどうなる?つまり、A * inverse of A = Identity Matrixとなるような行列は何だろう。 逆行列を持てる m x m の行列Aにおいて、 A * A(-1) = Identity Matrix が成り立つ。 これはOctaveでは pinv(A) と表現できる。

また行列は転置できる。 f:id:blackawa:20171218110601p:plain

Week 1 / Linear Algebra Reviewの続きから

行列の掛け算は、行の要素と列の要素をそれぞれ掛け算して結果をすべて足した値を結合した行列になる。

[[1 2]
 [3 4]
 [5 6]]

かける

[7 8]

[23 53 83]

となる。

これをふまえて、複数の値x(10, 15, 20)に対する以下の式のyを求めたい時、

y = b + ax
[[1 10]
 [1 15]
 [1 20]]

[b a]

をかけると、答えのセットが手に入る。

行列と行列の掛け算は、行列とベクトルの掛け算の拡張版。

ただし行列の掛け算は、Commutativeではない。つまり、A * BB * A は同じ値にならないことがある。

Identity Matrix(単位行列)っていうのもある。こいつと任意の行列の掛け算は、結合則(I * A = A * I)を満たす。

行列の逆数を取るとどうなる?つまり、A * inverse of A = Identity Matrixとなるような行列は何だろう。 逆行列を持てる m x m の行列Aにおいて、 A * A(-1) = Identity Matrix が成り立つ。 これはOctaveでは pinv(A) と表現できる。

また行列は転置できる。

生IntegrantでHTTPサーバーを立てる

Integrantといえばductのバックエンドにある状態管理ライブラリだが、ductを触っているとチラ見えしてくるので、一度生で触ってなんとなく雰囲気が分かるようにしておこうと思う。

Explicity vs Implicity(magic)

Java界に君臨するSpringBootを触ったことがある人は、「これ(だけしか書いてないのに)、なんで動くんだ?」と思ったことがあるはず。なぜなら、SpringBootは裏にあるSpringFrameworkをImplicitにうまいこと設定してくれる仕組みだから。

@SpringBootApplication とか @Controller って書けばWebアプリケーションが起動するって普通に考えてやばい。

HTTPリクエストに応答できるWebアプリケーションを立てるなら、まず確実にTomcatなりJettyが必要だし、DBにつなぐならConnectionインスタンスを生成しておかないと接続ができないはずなのに、起動できてしまう。 やばく便利だし、やばい学習コストがかかる。

いっぽうIntegrantやその他のClojure製状態管理ライブラリはExplicityに重心を置いているものが多いように思う。 つまり、明示的に指定しないとアプリケーション内で使えるようにならないし、そこには明示的に渡した引数しか渡せない。

Getting Started of Integrant

というわけでIntegrantを使ってみる。

lein new app gs-integrant

IntegrantはClojure 1.9.0が必要なのでClojureのバージョンを上げる。 そしてIntegrantと、HTTPリクエストに応答できるようにringを依存関係に追加する。

(defproject gs-integrant "0.1.0-SNAPSHOT"
  ;; ...
  :dependencies [[org.clojure/clojure "1.9.0"]
                 [integrant "0.6.2"]
                 [ring "1.6.3"]]
  ;; ...
  )

REPLを起動してエディターから接続する。

GitHub - weavejester/integrant: Micro-framework for data-driven architecture

公式のREADMEに書いてあるとおりにdefmethodする。

(ns gs-integrant.core
  (:gen-class)
  (:require [integrant.core :as ig]
            [ring.adapter.jetty :as jetty]
            [ring.util.response :as resp]))

(defn -main
  "I don't do a whole lot ... yet."
  [& args]
  (println "Hello, World!"))

(def config
  {:adapter/jetty {:port 8080 :handler (ig/ref :handler/greet)}
   :handler/greet {:name "alice"}})

(defmethod ig/init-key :adapter/jetty [_ {:keys [handler] :as opts}]
  (jetty/run-jetty handler (-> opts (dissoc :handler) (assoc :join? false))))

(defmethod ig/halt-key! :adapter/jetty [_ server]
  (.stop server))

(defmethod ig/init-key :handler/greet [_ {:keys [name]}]
  (fn [_] (resp/response (str "Hello " name))))

gs-integrant.core名前空間を評価して、REPLで移動して

(def system
  (ig/init config))

を評価するとHTTPサーバーが起動し、localhost:8080 にアクセスすると Hello alice と表示される。 同じ名前空間(ig/halt! system) すると終了する。

ここではinit-keyとhalt-keyしか書いていないが、それ以外にもsuspend-key!とresume-keyがあって、それぞれ中断時の振る舞い、restart時の振る舞いを定義できる。特に中断時は、引数を一度atomを経由して持つことで、サーバーの再起動なしにその内容を変更することができたりする。やばい。

これでhandlerにrouter機能をもつcompojureなりbidiなりを放り込めばルーティングができるんだろうし、cljsのコンパイルタスクを追加すればrestartするたびにコンパイルされるんだろうし、なんてシンプルなんだろう。

小さなモジュールがシーケンスを通して連携し合う世界観を活用しているし、またその世界観を拡張もしているクールなライブラリ。

Coursera Machine Learning 受講ノート 3

f:id:blackawa:20171218110601p:plain

ななめよみしてなんとかテストにパスした Week 1 / Parameter Learning

線形回帰以外に最急降下法というのがある。 ある目的関数Jに対して、その最小値を取りたい。 そこで、θ(0)とθ(1)を少しずつずらして最小値、あるいは局所的最小値を探す。 最急降下法(Gradient Descent)は、開始地点によってまったく違う局所的最適解にたどり着くことがある。

:= は代入を示す。

最急降下法は、すべてのパラメーターθ(j)に対して同時に計算を行い、同時に更新を行う。

理解を助けるためにθ(1)だけを扱う。 するとJ(θ(1))は二次関数になる。 であればJ(θ(1))の微分をとってそれが0になる箇所を探せば、それは必ず最適解である。

導関数とは、2次関数である限りは、目的関数の微分なのかな?

適切な学習率を指定された最急降下法では、イテレーションを繰り返すほどにステップが小さくなっていく。

ではこれを二乗誤差の目的関数に適用したらどうなるだろうか?

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

f:id:blackawa:20171218110601p:plain

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

f:id:blackawa:20171218110601p:plain

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も良い難易度(いまのところ)。 前提要件に「基本的な線形代数学と確率論への理解」が含まれることに一抹の不安を禁じ得ないけど頑張っていこう。