第二周的课程在理论方面主要是多变量线性回归Multivariate Linear Regression,基本上是对第一周内容的泛化。另外讲解了Octave软件的使用,Octave是一个遵从GNU General Public License的自由软件Free Software,它对Matlab具有很好的兼容性,基本上能在Matlab上运行的m文件都能在Octave上运行。
顾名思义,在多变量线性回归中,变量将不止一个。以下表所示数据为例:
面积/ m2 | 卧室数量 | 楼层 | 楼龄/年 | 价格/万元 |
---|---|---|---|---|
210 | 5 | 1 | 45 | 460 |
140 | 3 | 2 | 40 | 232 |
150 | 3 | 2 | 30 | 315 |
85 | 2 | 1 | 36 | 178 |
… | … | … | … | … |
共有4个输入变量和1个输出变量。
n= 变量数量;
x(i)j= 第 j 个变量在第 i 个训练集中的值;
y(i)= 第 i 个训练集中输出变量的值。
针对上面示例数据就有:
n=4 ;
x(3)4=30 ;
y(3)=315 。
对单变量线性回归的假设函数进行更改可得到 :
多变量线性回归的损失函数对应为:
进行多变量线性回归时,会遇到一个新的问题,就是不同的输入变量之间的数值范围可能会相差很多,比如上面表格中的例子:
x1 范围为(0-200 m2 ); x2 范围为(1-5)个卧室。
为了使梯度下降收敛得更快,对每个变量进行数据规范化操作:
这里使用的示例数据是课程作业提供的数据,点击这里获取,提取码doh3。
这里的输入参数 X 代表训练集输入变量矩阵:
function [X_norm, mu, sigma] = featureNormalize(X)
X_norm = X;
mu = zeros(1, size(X, 2));
sigma = zeros(1, size(X, 2));
mu = mean(X_norm);
sigma = std(X_norm);
X_norm = (X - repmat(mu, size(X, 1), 1)) ./ repmat(sigma, size(X, 1), 1);
end
输入参数 X 代表训练集输入变量矩阵, y 代表训练集输出变量列向量,theta代表 θ 列向量。
function J = computeCostMulti(X, y, theta)
J = sum((X * theta - y) .^ 2) / (2 * length(y)); % 一行代码搞定
end
计算前需要提前指定学习速率alpha和迭代次数num_iters。
function [theta, J_history] = gradientDescentMulti(X, y, theta, alpha, num_iters)
J_history = zeros(num_iters, 1);
for iter = 1:num_iters
theta = theta - alpha * (X' * (X * theta - y)) / length(y);
J_history(iter) = computeCostMulti(X, y, theta);
end
end
调用上述各函数,使用链接中的示例数据,按照以下程序可进行多变量线性回归的练习。
clear ; close all; clc
% Load Data
data = load('ex1data2.txt');
X = data(:, 1:2);
y = data(:, 3);
m = length(y);
% Scale features and set them to zero mean
[X mu sigma] = featureNormalize(X);
% Add intercept term to X
X = [ones(m, 1) X];
% Choose some alpha value
alpha = 0.1;
num_iters = 50;
% Init Theta and Run Gradient Descent
theta = zeros(3, 1);
[theta, J_history] = gradientDescentMulti(X, y, theta, alpha, num_iters);
% Plot the convergence graph
figure;
plot(1:numel(J_history), J_history, '-b', 'LineWidth', 2);
xlabel('Number of iterations');
ylabel('Cost J');
% Display gradient descent's result
fprintf('Theta computed from gradient descent: \n');
fprintf(' %f \n', theta);
fprintf('\n');
% Estimate the price of a 1650 sq-ft, 3 br house
X_predit = [1, ([1650 3] - mu) ./ sigma];
price = X_predit * theta;
对于多变量线性回归,除了使用梯度下降法外,还可以使用正规方程进行直接求解。方程比较简单,直接给出:
Gradient Dscent | Normal Equation |
---|---|
需要选择 alpha | 不必选择 alpha |
需要很多次迭代 | 不需要迭代 |
当输入变量数 n 很大时效果也很好 | 需要计算 (XTX)−1 , n 很大时速度会很慢 |
如果训练集的输入变量 n 过多,此时计算 (XTX)−1 比较慢,使用Gradient Descent比较好。对于 n 的取值,Andrew Ng老师给了一个参考: n=10,000
这个比较简单
theta = pinv(X' * X) * X' * y
使用正规方程计算上面给的例子,得到的 θ 和使用梯度下降法应该是一样的,不过根据迭代次数的不同也会略有差别。
最近对GNU倡导的自由软件非常着迷。之前用LibreOffice和LibreCAD分别代替了MSoffice和AutoCAD后,这次又因为学习Andrew Ng老师的机器学习课程遇到了GNU Octave,真是高兴啊,终于找到可以替代Matlab的自由软件了。好吧,其实我更在乎的是Free Software中free的“免费”之义。可以看出来,被替代的这三款软件若是使用正版的话,花费可是相当大哦。作为一个不想接着用盗版软件的穷diao丝,这些免费自由软件简直就是解放之光啊!
说回Octave,目前最新的版本已经支持图形界面,和Matlab比较相像,使用起来感觉也差不多,兼容性很好,目前还没有遇到什么问题。先睹为快:
版权声明:署名-非商业性使用-相同方式共享 3.0 中国大陆 (CC BY-NC-SA 3.0 CN)
发表日期:2016年4月17日