Experiment 1 Linear Regression

本文详细介绍了如何在MATLAB中运用线性回归模型,通过梯度下降法求解参数θ,同时展示了如何计算和可视化代价函数J(θ)。作者展示了从数据导入、模型构建到参数优化的完整过程,并通过例子演示了如何预测新的数据点。
摘要由CSDN通过智能技术生成

Experiment 1: Linear Regression

2024/3/6

1.导入数据

figure % open a new figure window
plot(x, y, 'o');
ylabel( Height in meters )
xlabel( Age in years )

这里plot(x, y, o );里的o表示绘图里代表数据点的符号。

image-20240305084943288
 m = length(y); % store the number of training examples
 x = [ones(m, 1), x]; % Add a column of ones to x

语句 x = [ones(m, 1), x]; 表示将一个由 m 行、1列且所有元素均为1的矩阵(即向量)连接到矩阵 x 的左侧。这里的 m 代表的是训练样本的数量,因此 ones(m, 1) 生成了一个大小为 m×1 的列向量,每一行都是1。

image-20240305085806196

2.梯度下降求θ

% 梯度下降
theta = zeros(size(x(1,:)))';
alpha = 0.07; % given
All_its = 1500; % 共迭代1500次
for i_its = 1:All_its % 开始循环,从1迭代到指定的最大迭代次数
    grad = (1/m).* x' * ((x * theta) - y); % 计算梯度
    theta = theta - alpha .* grad; % 更新theta,采用梯度下降法逐步逼近最小化损失函数的目标
end

在 MATLAB 或 Octave 等数学软件中,. 符号用于元素级别的运算,也称为点运算符。在表达式 theta = theta - alpha .* grad 中,. 作用于两个矩阵或向量之间,指示要进行逐元素(element-wise)的乘法。

这里的 alpha 是一个标量值(学习率),而 grad 是一个与 theta 同型的向量或矩阵,表示梯度。通过点运算符 .*,程序将会分别计算 alphagrad 中每个对应元素的乘积,然后再将结果逐个地从 theta 对应的元素中减去。

此处对梯度的计算,来自于梯度下降算法:

image-20240306204708697

其中对 J ( θ ) J(θ) J(θ)求偏导的结果(实验中为求导)即为grad。grad = (1/m).* x' * ((x * theta) - y);

hold on % Plot new data without clearing old plot
plot(x(:, 2), x * theta, '-')
legend('Training data', 'Linear regression')
hold off
  • x * theta:这是一个矩阵乘法操作,x 是包含截距项的特征矩阵,theta 是线性回归模型的参数向量。经过矩阵乘法后,得到一个新的向量,它的每个元素是根据当前参数值计算出的对应训练样本的预测值
  • plot(x(:, 2), x * theta, '-')plot 函数用于绘制二维图形,第一个参数是 x 轴坐标(这里是年龄),第二个参数是 y 轴坐标(这里是根据当前 theta 计算出的高度预测值),最后一个字符串 '-' 表示绘制连续线段,即折线图。

这条命令实际上在图形上绘制了一条直线(或近似直线)。

image-20240305094129761

此时theta为一个包含两个参数的二维向量:

image-20240306193822007

测试样例:

predict1 = [1, 3.5] *theta;
predict2 = [1, 7] * theta; 

image-20240305094934282

3.对 J ( θ ) J(θ) J(θ)的理解

J_vals=zeros(100, 100); % 初始化一个零矩阵,目的是后续存储不同theta0和theta1的值下由J(θ)计算出的损失

theta0_vals = linspace(-3, 3, 100); 
theta1_vals = linspace(-1, 1, 100);
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
  • 在MATLAB中,linspace 函数是用来生成一系列等间距的数值向量。

    1linspace(start_value, end_value, num_of_points)
    
    • start_value:指定生成向量的第一个元素的值。
    • end_value:指定生成向量的最后一个元素的值。
    • num_of_points:指定生成向量包含的元素个数。

    对于 theta0_vals = linspace(-3, 3, 100); 这行代码,它意味着创建一个从 -3 开始到 3 结束的向量,并且在这个区间内均匀分配 100 个点。所以,theta0_vals 向量将包含 100 个介于 -33 之间的浮点数,它们之间的间隔是相同的:

    image-20240306202941164

    for i =1从向量的第一个索引开始遍历直到最后一个索引。

  • t = [theta0_vals(i); theta1_vals(j)];是用对应的theta0和theta1生成一个2*1的矩阵(二维列向量)。分号用来区分行。

  • J_vals(i, j) = (0.5 / m) * (x * t - y)' * (x * t - y);是根据代价函数计算出在该theta0与theta1下的损失。并存储在之前申请的矩阵的对应位置。

    % 画图
    J_vals = J_vals';
    figure;
    surf(theta0_vals, theta1_vals, J_vals)
    xlabel('\theta_0');
    ylabel('\theta_1');
    

因为J_vals最初是以列优先的方式存储的(MATLAB和Octave默认的存储方式),则它对应的应该是Y轴方向上的变化,而非X轴方向。为了使surf命令正确地按照预期展现三维曲面,即X轴方向变化对应Z值的第一维(行),Y轴方向变化对应Z值的第二维(列),就需要在调用surf函数之前,对J_vals矩阵进行转置操作。

image-20240306202433162

4.附录

本次实验代码如下:

x = load('ex1x.dat');
y = load('ex1y.dat');
figure;
plot(x, y, 'o');
ylabel('Height in meters');
xlabel('Age in years');
m = length(y);
x = [ones(m, 1),x];
theta = zeros(size(x(1,:)))';
alpha = 0.07; % given
All_its = 1500; % 共迭代1500次
for i_its = 1:All_its % 开始循环,从1迭代到指定的最大迭代次数
    grad = (1/m).* x' * ((x * theta) - y); % 计算梯度
    theta = theta - alpha .* grad; % 更新theta,采用梯度下降法逐步逼近最小化损失函数的目标
end

hold on % Plot new data without clearing old plot
plot(x(:, 2), x * theta, '-');
legend('Training data', 'Linear regression');
hold off
predict1 = [1, 3.5] *theta;
predict2 = [1, 7] * theta;

% understanding J(θ)
J_vals=zeros(100, 100);

theta0_vals = linspace(-3, 3, 100);
theta1_vals = linspace(-1, 1, 100);
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');
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值