Exercise2: Logistic Regression

一个月快过去了,总算是学完Coursera上的第三课了,其实我的进度比预期满了一周。这是第二次做Coursera的编程作业,对比大学课程的作业,Coursera的难度应该在中等甚至偏下,对我来说唯一的难度在于适应“新”,有以下几点:

  • 新语言
  • 新工具
  • 新的思考方式

对于一个Software Engineer来说以上都是最基础的技能,即保持学习态度,及时学习新技术、新知识。

第三周的课程内容主要讲分类、逻辑回归,与线性回归相比,也就是把Hypothesis函数用Sigmoid函数来表示,也就是:$设 g(z) = \frac{1} {1 + e ^{-z}}$,$令 z = θ^T x$,$则 h_θ(x) = g(θ^Tx)$

为什么要 $设 g(z) = \frac{1} {1 + e ^{-z}}$ 呢,因为它的值域为 $(0, 1)$,定义域为(-∞, +∞) 的单调连续增函数,这意味着可以用换元法把所有函数的值域压缩到$(0, 1)$,它的函数图像如下。

这非常适合作为二分类(01分类)函数,我们可以取 $ h_θ(x) >= 0.5$ 时 $y = 1$ ,$ h_θ(x) < 0.5$ 时 $y = 0$ 。

同时Cost函数和Gradient Descent方程也有些许改变,这种改变是换元法带来的(公式识别失败,用图代替了)

它们对应的矩阵形式是

① $J(θ) = \frac {1} {m} (- y ^T log(h) - (1 - y)^T log(1 - h)),h = g(Xθ)$

② $θ = θ - \frac {α} {m} X^T (g(Xθ) - y)$

注意其中$X、y、θ$ 都是矩阵

作业内容

*的是需要做的,没标的是作业中已经实现

数据可视化

* Sigdmoid函数

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
function g = sigmoid(z)
%SIGMOID Compute sigmoid function
% g = SIGMOID(z) computes the sigmoid of z.

% You need to return the following variables correctly
g = zeros(size(z));

% ====================== YOUR CODE HERE ======================
% Instructions: Compute the sigmoid of each value of z (z can be a matrix,
% vector or scalar).

g = 1 ./ (1 + exp(-z));

% =============================================================

end

传入的参数是一个矩阵,所以需要算出每一个元素的sigmoid函数值,这里用到的./操作符来对每一个元素进行取倒数操作。

* Cost函数和对应的Gradient Descent方程

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
function [J, grad] = costFunction(theta, X, y)
%COSTFUNCTION Compute cost and gradient for logistic regression
% J = COSTFUNCTION(theta, X, y) computes the cost of using theta as the
% parameter for logistic regression and the gradient of the cost
% w.r.t. to the parameters.

% Initialize some useful values
m = length(y); % number of training examples

% You need to return the following variables correctly
J = 0;
grad = zeros(size(theta));

% ====================== YOUR CODE HERE ======================
% Instructions: Compute the cost of a particular choice of theta.
% You should set J to the cost.
% Compute the partial derivatives and set grad to the partial
% derivatives of the cost w.r.t. each parameter in theta
%
% Note: grad should have the same dimensions as theta
%

J = 1/m * sum(-y .* log(sigmoid(X * theta)) - (1 - y) .* log(1 - sigmoid(X * theta)));

grad = 1/m * (X' * (sigmoid(X * theta) - y));


% =============================================================

end

在这个函数中需要同时计算代价和梯度,通过公式①、②不难得到上述两行代码

* Hypothesis函数

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
function p = predict(theta, X)
%PREDICT Predict whether the label is 0 or 1 using learned logistic
%regression parameters theta
% p = PREDICT(theta, X) computes the predictions for X using a
% threshold at 0.5 (i.e., if sigmoid(theta'*x) >= 0.5, predict 1)

m = size(X, 1); % Number of training examples

% You need to return the following variables correctly
p = zeros(m, 1);

% ====================== YOUR CODE HERE ======================
% Instructions: Complete the following code to make predictions using
% your learned logistic regression parameters.
% You should set p to a vector of 0's and 1's
%

s = sigmoid(X * theta);
p = floor(s + 0.5);

% =========================================================================

end

预测函数就比较简单的,由$则 h_θ(x) = g(θ^Tx)$,$g$ 是Sigmoid函数,可以得到上述两行代码,因为当函数值大于0.5时$y = 1$ ,又得到的 $s$ 其实是一个矩阵,所以使用floor(s + 0.5)来进行批量操作。

完成上述三个函数后,运行ex2函数可以得到一条预测线,如图。

* 正规化

正规化是为了防止过拟合,核心是保持 $ x$ 值不变, 减小 (惩罚) $θ$的值。

当然还有一种方式防止过拟合的方法是建立一个模型来去除用处不大的特征,保留作用相对较大的特征。

上图表示的预测函数,从左到右依次是欠拟合拟合 也叫刚好拟合过拟合,欠拟合一般是因为多项式的最高次太小,过拟合一般是因为多项式的最高次幂太大。

正规化后的代价函数如下,注意尾巴上对 $θ_j$ 的求和是从1开始,也就意味着跳过了 $θ_0$

值得注意的是梯度方程不需要对 $θ_0$ 进行正规化,所以方程变成了两部分:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
function [J, grad] = costFunctionReg(theta, X, y, lambda)
%COSTFUNCTIONREG Compute cost and gradient for logistic regression with regularization
% J = COSTFUNCTIONREG(theta, X, y, lambda) computes the cost of using
% theta as the parameter for regularized logistic regression and the
% gradient of the cost w.r.t. to the parameters.

% Initialize some useful values
m = length(y); % number of training examples

% You need to return the following variables correctly
J = 0;
grad = zeros(size(theta));

% ====================== YOUR CODE HERE ======================
% Instructions: Compute the cost of a particular choice of theta.
% You should set J to the cost.
% Compute the partial derivatives and set grad to the partial
% derivatives of the cost w.r.t. each parameter in theta

J = 1/m * sum(-y .* log(sigmoid(X * theta)) - (1 - y) .* log(1 - sigmoid(X * theta)));
J = J + lambda/(2*m) * sum(theta(2:size(theta)) .^ 2);

grad = 1/m * (X' * (sigmoid(X * theta) - y)) + lambda/m * theta;
grad(1) = grad(1) - lambda/m * theta(1);

% =============================================================

end

根据上述的三张图不难写出上述四行代码

调整λ参数的大小

λ = 1

λ = 10

λ = 0.0001

可以看出 $λ$ 越小,对训练样本的拟合程度越好,从而导致了整个曲线看起来比较扭曲,没有平滑感;而 $λ$ 越大,对训练样本的拟合程度越差,曲线越光滑。

坚持原创文章分享,您的支持将鼓励我继续创作!