本篇博文主要介绍单变量线性回归基本概念原理,包括梯度下降算法的理解,形象表示,核心公式以及其实现的两种方法:normal equations 和gradient descent方法,其中给出了其MATLAB程序及实现结果。具体的线性回归理解和算法公式推导将在下一篇博文给出,包括LMS,概率解释和局部加权等内容。
单变量线性回归:
m通常代表样本点的个数,i通常代表第i个样本点(索引)
我们要做的就是得出 θ0 和 θ1 这两个参数的值,来让假设函数h表示的直线尽量地与这些样本点很好的拟合
目标是为了使h预测的值与样本点真实值间的差值最小
由图可以看出在某个(θ0,θ1)处J达到最小值
首先初始化(θ0,θ1),我们要找到J的最优解,或者说局部最优,换句话来说我们要找到J的最小值,按照前面的权值更新法则,从最陡峭的地方,一步一步的改变(θ0,θ1)以使J达到最小值,注意在这个过程当中(θ0,θ1)是同时更新的计算的,对于(θ0, θ1, θ2, ...... ,θj...θn )也是如此,注意区分代表某个样本点的i的意义,最大为m个样本。
可以看出,随着权值不断的更新,当越来越接近最小值的时候或者说局部最小值,曲线会变得越来越平缓,即导数会变的越来越小,α如果固定不变的话表达式中被减去的部分本身就会变的越来越小,即下降的幅度在越来越小,从而确保可以到达局部最优值,所以也可以不必减小α。
使用normal equations的方法实现单变量线性回归:
<span style="font-family:Microsoft YaHei;font-size:12px;">x = load('ex2x.dat'); //数据为50个样本点,由年龄x预测身高y
y = load('ex2y.dat');
plot(x,y,'*')
xlabel('age')
ylabel('height')
x = [ones(50,1),x];
w=inv(x'*x)*x'*y //normal equations公式
hold on
plot(x(:,2),0.0639*x(:,2)+0.7502)</span>
采用gradient descend过程求解:
matlab中ones(size(x,1),1)表示生成一个行数与x一致,列数等于1且所有元素都是1的矩阵。也就是说生成一个元素为全为1的列向量,这个列向量的行数和矩阵x的行数一样。
详细解析:
-
size(x,1) 获取矩阵x沿着第一个维度的长度,也就是获取x的行数
-
ones(m,n) 生成一个m行n列且所有元素都是1的矩阵
zeros(size(x(1,:)))' 注意这个跟上面那个不一样,MATLAB中表达式所代表的意义如下( zeros(1,2)' ):
<span style="font-family:Microsoft YaHei;font-size:12px;">>> size(x(1,:))
ans =
1 2 //代表一行两列的意思
>> x(1,:)
ans =
1.0000 2.0659 //只取出了50行2列中的整个第一行部分
>> size(x)
ans =
50 2</span>
<span style="font-family:Microsoft YaHei;font-size:12px;">% Exercise 2 Linear Regression
% Data is roughly based on 2000 CDC growth figures
% for boys
% x refers to a boy's age
% y is a boy's height in meters
clear all; close all; clc
x = load('ex2x.dat'); y = load('ex2y.dat');
m = length(y); % number of training examples
% Plot the training data
figure; % open a new figure window
plot(x, y, 'o');
ylabel('Height in meters')
xlabel('Age in years')
% Gradient descent
x = [ones(m, 1) x]; % Add a column of ones to x
theta = zeros(size(x(1,:)))'; % initialize fitting parameters别忘了转置</span>
<span style="font-family:Microsoft YaHei;font-size:12px;">MAX_ITR = 1500;
alpha = 0.07;
for num_iterations = 1:MAX_ITR
grad = (1/m).* x' * ((x * theta) - y); %乘所有的Xj
theta = theta - alpha .* grad;
% Sequential update: The wrong way to do gradient descent
% grad1 = (1/m).* x(:,1)' * ((x * theta) - y);
% theta(1) = theta(1) + alpha*grad1;
% grad2 = (1/m).* x(:,2)' * ((x * theta) - y);
% theta(2) = theta(2) + alpha*grad2;
end
theta % print theta to screen
hold on; % keep previous plot visible
plot(x(:,2), x*theta, '-') %取第二列
legend('Training data', 'Linear regression') %标出图像中各曲线标志所代表的意义
hold off % don't overlay any more plots on this figure
% Closed form solution for reference
% You will learn about this method in future videos
exact_theta = (x' * x)\x' * y %normal equations公式
% Predict values for age 3.5 and 7
predict1 = [1, 3.5] *theta
predict2 = [1, 7] * theta
% Calculate J matrix
% Grid over which we will calculate J
theta0_vals = linspace(-3, 3, 100);
theta1_vals = linspace(-1, 1, 100);
% initialize J_vals to a matrix of 0's
J_vals = zeros(length(theta0_vals), length(theta1_vals));
for i = 1:length(theta0_vals)
for j = 1:length(theta1_vals)
t = [theta0_vals(i); theta1_vals(j)];
J_vals(i,j) = (0.5/m) .* (x * t - y)' * (x * t - y); //当前所有theta情况下的cost值
end
end
% Because of the way meshgrids work in the surf command, we need to
% transpose J_vals before calling surf, or else the axes will be flipped
J_vals = J_vals'; //因为surf作图的要求所以J_vals在命令中要转置
% Surface plot
figure;
surf(theta0_vals, theta1_vals, J_vals)
xlabel('\theta_0'); ylabel('\theta_1');
% Contour plot
figure;
% Plot J_vals as 15 contours spaced logarithmically between 0.01 and 100
contour(theta0_vals, theta1_vals, J_vals, logspace(-2, 2, 15)) //对数等分 行向量,画出指定值的等高线?
xlabel('\theta_0'); ylabel('\theta_1'); </span>
接下一篇:MachineLearning-Linear Regression(二)
参考资料:
http://openclassroom.stanford.edu/MainFolder/DocumentPage.php?course=DeepLearning&doc=exercises/ex2/ex2.html
http://blog.youkuaiyun.com/mydear_11000/article/details/50865085
http://www.cnblogs.com/tornadomeet/archive/2013/03/15/2961660.html