实验目的
根据给出的例子和数据,实现线性回归算法,可以使用 matlab(或者 octave)进行实现。 使用梯度下降的方式实现线性回归,并最终将结果展示出来。
实验数据
实验步骤与内容
1. 数据加载
该数据是 2-8 岁小孩身高和年龄内容。
ex1x:小孩的年龄
ex1y:小孩的身高
一共有 50 个训练样本,训练集实例为
(
x
(
i
)
,
y
(
i
)
)
(x^{(i)},y^{(i)})
(x(i),y(i))
2.有监督学习问题
a. 在该问题中,使用梯度下降方式实现线性回归,在 Matlab/Octave 中,使用如下方式加 载训练集
x = load('ex1x.dat');
y = load('ex1y.dat');
b. 该训练数据集有 n=1 个特征(加上 a 0 a_0 a0 ,所以 x ∈ R 2 x∈R^2 x∈R2)在 Matlab/Octave 中,运行如下命令 绘制训练集。可以得到以下结果图
% Plot the training data figure;
% open a new figure window
plot(x, y, 'o');
ylabel('Height in meters')
xlabel('Age in years')
结果图
在进行梯度下降计算之前,需要先加入截距
x
0
=
1
x_0=1
x0=1 , 在 Matlab/Octave 中,使用如下命令
m = length(y); % number of training examples
x = [ones(m, 1) x]; % Add a column of ones to x
//x 的第二列是年龄的数据,针对该数据,进行线性回归模型训练
3. 二维线性回归的实现
针对该问题,实现线性回归:
h
θ
(
x
)
=
θ
T
x
=
∑
i
=
0
n
θ
i
x
i
h_θ(x)=\theta^Tx=\sum_{i=0}^n\theta_ix_i
hθ(x)=θTx=i=0∑nθixi
线性回归模型公式原理:
θ
j
:
=
θ
j
−
a
1
m
∑
i
=
1
m
(
h
θ
(
x
i
)
−
y
(
i
)
)
x
j
(
i
)
\theta_j:=\theta_j-a\frac{1}{m}\sum_{i=1}^m(h_θ(x^{i})-y^{(i)})x_j^{(i)}
θj:=θj−am1i=1∑m(hθ(xi)−y(i))xj(i)
梯度下降: 使用学习率 实现梯度下降,由于 matlab 的矢量索引从 1 开始,而不是 0,因此在 matlab 中使用 theta1 和 theta2 表示 θ 0 \theta_0 θ0和 θ 1 \theta_1 θ1
初始化参数
θ
0
=
0
\theta_0=0
θ0=0,
θ
1
=
0
\theta_1=0
θ1=0
,然后从初始化值开始进行梯度下降的一次迭代计算,记录下这 次迭代计算的结果
θ
0
\theta_0
θ0和
θ
1
\theta_1
θ1
。 继续进行多次的梯度下降迭代计算,直到 θ收敛(大概需要进行着 1500 次左右的迭代计 算), θ收敛后,记录下最后的
θ
0
\theta_0
θ0和
θ
1
\theta_1
θ1
当找到 θ后,绘制满足训练集的直线。使用如下命令进行绘制
hold on; % keep previous plot visible
plot(x(:,2), x*theta, 'r-')
legend('Training data', 'Linear regression')
hold off
结果图
4. 对梯度下降的理解
为了更好的理解梯度下降机制,下面对
θ
∈
R
2
\theta∈R^2
θ∈R2 和
J
(
θ
)
J(\theta)
J(θ) 的关系进行可视化的处理。在该
问题中,
J
(
θ
)
J(\theta)
J(θ)绘制出来是一个 3D 曲面图(在应用机器学习算法时,通常并不会去绘制
J
(
θ
)
J(\theta)
J(θ) ,因为
θ
∈
R
2
\theta∈R^2
θ∈R2的维度非常高,以致我们无法使用简单的方法进行绘制可视化的
J
(
θ
)
J(\theta)
J(θ) 由于在本实例中,
θ
∈
R
2
\theta∈R^2
θ∈R2 是 2 维的,因此,我们绘制 3 维的
J
(
θ
)
J(\theta)
J(θ) 来对线性回归算法进行直观的理解。
从线性回归原理可知公式为:
为了获得最佳的观测效果,theta 的值的范围使用如下建议的值 3D 曲面图绘制 Matlab 代码 如下
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);
end
end
J_vals = J_vals';
figure;
surf(theta0_vals, theta1_vals, J_vals) xlabel('\theta_0');
ylabel('\theta_1');
figure;
contour(theta0_vals, theta1_vals, J_vals, logspace(-2, 2, 15))
xlabel('\theta_0');
ylabel('\theta_1');
结果图
结论分析与体会
在本实验中,可以通过实验结果图之一来展现,如下图,可以清晰地观察到梯度下降算法: 步长为 0.2,靠近极小值时收敛速度较慢。
Code
x = load('ex1x.dat'); %加载数据
y = load('ex1y.dat');
% Plot the training data
figure; % open a new figure
plot(x, y, 'o'); %描点,画出散点图
ylabel('Height in meters')
xlabel('Age in years')
% Gradient descent
m = length(y); % number of training examples
x = [ones(m, 1) x]; % Add a column of ones to x
theta = zeros(size(x(1,:)))'; % initialize fitting parameters
alpha = 0.07;
All_its = 1500;%numbers of iterations
for i_its = 1:All_its
grad = (1/m).* x' * ((x * theta) - y);%x'向量乘
theta = theta - alpha .* grad;
end
% print theta to screen theta
hold on;
% keep previous plot visible
plot(x(:,2), x*theta, 'r-')
legend('Training data', 'Linear regression')
hold off
exact_theta = (x' * x)\x' * y ;
predict1 = [1, 3.5] *theta;
predict2 = [1, 7] * theta;
theta0_vals = linspace(-3, 3, 100);
theta1_vals = linspace(-1, 1, 100);
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);
end
end
J_vals = J_vals';
figure;
surf(theta0_vals, theta1_vals, J_vals) xlabel('\theta_0');
ylabel('\theta_1');
figure;
contour(theta0_vals, theta1_vals, J_vals, logspace(-2, 2, 15))
xlabel('\theta_0');
ylabel('\theta_1');