Coursera 機械学習 - プログラミング課題1解答例
By Huy Van
課題のページ
https://www.coursera.org/learn/machine-learning/programming/8f3qT/linear-regression
プログラミング課題はちょっと重いので今回の解答例を上げます。 わからないことや別の解答がありましたらコメントをお願いします。
必須課題
1. Computing Cost (for One Variable)
Gradient DescentのCost function $J(\theta)$ は以下の通り
$$ J(\theta) = \frac{1}{2m}\sum_ {i=1}^m (h_ \theta(x^{(i)}) - y^{(i)} )^2 $$
ここで、仮定関数 $ h_ \theta(x) $は
$$ h_ \theta(x) = \theta^T x = \theta_ 0 + \theta_ 1x_ 1 $$
それで、
$$ J(\theta) = \frac{1}{2m}\sum_ {i=1}^m (\theta^T x^{(i)} - y^{(i)} )^2 $$
注意したいのは $\theta$ と $x^{(i)}$ はベクトルで、$ y^{(i)} $は実数です。 課題はこの関数をOctaveで書くことです。以下は解答例です。
function J = computeCost(X, y, theta)
m = length(y); % number of training examples
% 97 examplesがあるのでここで m == 97
% size(X) == [97 2]
% size(y) == [97 1]
% size(theta) == [2 1]
% Xは97x2行列。1行は1つのtraining example [x0 x1] (x0はいつも1)
% yは97次元ベクトル
% thetaは2次元ベクトル
J = 0;
% まずは和の部分を計算します
for i = 1:m
J += (theta' * X(i,:)' - y(i))^2;
end
% X(i,:)は1つの行、つまりtraining exampleです。ベクトルに変換するので転置を取りました。
% 最後に2mを割るだけです
J = J / (2*m);
end
実行した結果、cost functionの値は32.073になるはずです。
2. Gradient Descent (for One Variable)
Gradient descentアルゴリズムはcost function Jの最小値を求める手法の一つです。一つのステップは以下のように$\theta$の値を更新します
$$ \theta_ j := \theta_ j - \alpha\frac{1}{m}\sum_ {i=1}^{m} ( h_ \theta(x^{(i)}) - y^{(i)} )x_ j^{(i)} $$
ベクトル化すると、
$$ \theta := \theta - \alpha\delta $$
ここで、
$$ \delta = \frac{1}{m}\sum_ {i=1}^{m} ( \theta ^Tx^{(i)}- y^{(i)} ) x^{(i)} $$
注意したいのは$\delta,x^{(i)}$はベクトルで、$ \theta ^Tx^{(i)}- y^{(i)}$は実数です。 課題はOctaveでgradient descentによって最小値をとる$\theta$を求めることです。以下は解答例です。
function [theta, J_history] = gradientDescent(X, y, theta, alpha, num_ iters)
m = length(y); % number of training examples
J_history = zeros(num_ iters, 1);
for iter = 1:num_ iters
% deltaを初期化
delta = zeros(2,1);
for i = 1:m
x = X(i,:)';
delta += (theta' * x - y(i)) * x;
end
delta = delta / m;
theta = theta - alpha * delta;
J_history(iter) = computeCost(X, y, theta);
end
end
実行した結果:
Theta found by gradient descent: -3.630291 1.166362
For population = 35,000, we predict a profit of 4519.767868
For population = 70,000, we predict a profit of 45342.450129
任意課題
3. Feature Normalization
j番目のフィーチャのi番目のtraining exampleに対して
$$ x_ j^{(i)} := \frac{x_ j^{(i)} - \mu_ j}{\sigma_ j} $$
ここで、$\mu_ j$はjフィーチャの平均値、$\sigma_ j$はjフィーチャの標準偏差です。
Octaveで書くと、
function [X_norm, mu, sigma] = featureNormalize(X)
X_norm = X;
mu = zeros(1, size(X, 2));
sigma = zeros(1, size(X, 2));
% size(X) == [47 2]
% size(mu) == [1 2]
% size(sigma) == [1 2]
mu = mean(X);
sigma = std(X);
% X_norm = (X - mu) ./ sigma;
% これも結果正しいですが、実行すると
% warning: operator -: automatic broadcasting operation applied
% warningを出ないようにするならbsxfunを使う
X_norm = bsxfun(@rdivide, bsxfun(@minus, X, mu), sigma);
% またはXのサイズに合わせる
% o = ones(size(X,1),1);
% X_norm = (X .- o*mu ) ./ (o*sigma);
end
参考:http://stackoverflow.com/questions/17094753/octave-operator-automatic-broadcasting-operation-applied
4. Computing Cost (for Multiple Variables)
複数変数の場合、cost functionは以下のようになります(だれか証明してくれませんか?)
$$ J(\theta) = \frac{1}{2m}(X\theta-y)^T(X\theta-y) $$
Octaveで書くと、
function J = computeCostMulti(X, y, theta)
m = length(y); % number of training examples
J = 0;
J = 1 / (2*m) * (X*theta - y)' * (X*theta - y);
end
5. Gradient Descent (for Multiple Variables)
1変数の場合と同様です。違うのは$\delta$の次元は2ではなくフィーチャ数+1となります。だから、上のコード(1変数の時)を$\delta$の初期化の行だけ変更すれば動くはずです。
delta = zeros(size(X, 2),1);
それから、面積1650 square feet、3つのルームの値段を予測には
xt = [1650 3];
% 値段を計算する前にxtをnormalizeすることが必要
price = [1 (xt-mu)./sigma ] * theta;
実行結果:
Normalizing Features ...
Running gradient descent ...
Theta computed from gradient descent:
334302.063993
100087.116006
3673.548451
Predicted price of a 1650 sq-ft, 3 br house (using gradient descent):
$289314.620338
6. Normal Equations
$\theta = (X^TX)^{-1}X^Ty$をOctaveで書くと、
function [theta] = normalEqn(X, y)
theta = zeros(size(X, 2), 1);
theta = pinv(X' * X) * X' * y;
end
面積1650 square feet、3つのルームの値段を予測にはfeature normalizeが必要ないので
price = [1 1650 3] * theta;
実行結果:
Solving with normal equations...
Theta computed from the normal equations:
89597.909542
139.210674
-8738.019112
Predicted price of a 1650 sq-ft, 3 br house (using normal equations):
$293081.464335
発展課題:Gradient Descentのlearning rateの考察
Gradient Descentの結果はNormal Equationsとちょっと違うので、learning rate $\alpha$ の調整の余地があります。
現在は$\alpha = 0.01$、ステップの回数は400です。
- $\alpha = 0.03, num\_ iters = 400$
Theta computed from gradient descent:
340410.918973
110308.113371
-6326.538108
Predicted price of a 1650 sq-ft, 3 br house (using gradient descent):
$293149.994329
- $\alpha = 0.1, num\_ iters = 400$
Theta computed from gradient descent:
340412.659574
110631.048958
-6649.472950
Predicted price of a 1650 sq-ft, 3 br house (using gradient descent):
$293081.464622
Cost Jのグラフ:
グラフを見ればわかるように$\alpha = 0.1$のとき, ステップ数は50だけでも良さそうです。
もっと$\alpha$を上げてみると、$\alpha=3$のときは発散することがわかります。