Week 3

Classification and Representation

分類問題には二種類ある。

  • バイナリ分類
  • マルチクラス分類

線形回帰を分類問題に適用させてしまうと、ラベルの値が決まっているにも関わらず関係ない値になってしまうので、これを解決するためにロジスティクス回帰を使う。(分類問題なのに「回帰」という単語を使っているのは歴史的経緯に寄るものなので気にしなくていい。)

ロジスティクス回帰では仮説関数を次のように定義する。

h(x) = g(theta' * x)
g(z) = 1 / (1 + e^(-z)) // sigmoid関数

sigmoid関数を使っているのは、なんか良い感じに z=0g(z) がちょうどg(z)=0.5を境に良い感じに線対象になるからっぽい。(要確認)

これをよくよく見てみると、仮に g(z)=0.5 を判定基準として線を引いてみると、その実は中身の h(x)=0 が判定基準となる。 したがって、 h(x)=0 の線がうまくサンプルを分類するように theta を調整してあげる必要がある。

Logistic Regression Model

theta をうまく調整するのには、線形回帰でやったように、コスト関数を用意して、何らかの最適化手法(たとえば最急降下法)を使ってあげればよい。

まずコスト関数は次のように定義してあげると良い。

J(theta) = 1/m * sum(Cost(h(x), y)^2)

ここで Cost(h(x), y) は次のように定義する。(これは統計学の最尤法推定にもとづいているが、そういうものだと理解しておく)

Cost(h(x), y) = -log(h(x)) (y=1)
Cost(h(x), y) = -log(1 - h(x)) (y=0)

yはバイナリ分類問題のとき必ず0か1なのでこれを1つの式で表すと次のようになる。

Cost(h(x), y) = -y * log(h(x)) - (1 - y)*log(1 - h(x))

これを最急降下法で解くためには各θに対して偏微分をした関数を求めて、Jの値が最小になるように繰り返しθを更新していく。 実はこの関数を使ってJの偏微分を求めると、線形回帰のときと同じような形で書ける。すなわちベクトルで書くと

theta := theta - alpha/m * X' * (g(X*theta) - y)

θ の最適化については最急降下法以外にも幾つかの手法がある。

  • Conjugate Descent (共役勾配法)
  • BFGS
  • L-BFGS

各々の実装は複雑なので、自前実装はせずに、すでに実装済みの効率の良いライブラリを使うべきである。(自前で sqrt()rand() などを実装せずに既存の物を利用するのと同様)

これらの最適化手法の利点としては、最急勾配法にあった学習率(α)の調整をしなくてよいというところにある。

Octaveでこれらを利用するときは fminunc という関数を利用すると良い。

function [jVal, gradient] = costFunction(theta)
  jVal = [...code to compute J(theta)...];
  gradient = [...code to compute derivative of J(theta)...];
endfunction

を用意してあげて、

options = optimset('GradObj', 'on', 'MaxIter', 100);
initialTheta = zeros(2, 1);
[optTheta, functionVal, exitFlag] = fminunc(@costFunction, initialTheta, options);

と呼んであげれば良い。