热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

MATLAB实现单变量线性回归

本文介绍了如何在MATLAB中实现单变量线性回归,这是基于Coursera上AndrewNg教授的机器学习课程中的一个实践项目。文章详细讲解了从数据可视化到模型训练的每一个步骤。
### MATLAB实现单变量线性回归

#### 1. 数据可视化

此部分是Coursera上Andrew Ng教授的《机器学习》课程中的一个作业,提供了一个完整的框架,只需实现几个关键函数即可。首先,我们需要绘制原始数据图。

```matlab
fprintf('绘制数据...
');
data = load('ex1data1.txt');
X = data(:, 1); y = data(:, 2);
m = length(y); % 训练样本数量

% 绘制数据点
% 注意:需要在plotData.m文件中完成绘图代码
plotData(X, y);

fprintf('程序暂停。按回车继续。
');
pause;
```

在这个步骤中,我们使用`load`函数加载数据,并调用自定义的`plotData`函数来绘制数据点。

```matlab
function plotData(x, y)
% PLOTDATA 绘制数据点x和y
% PLOTDATA(x, y) 绘制数据点,并设置坐标轴标签为人口和利润

figure; % 打开一个新的图形窗口
plot(x, y, 'rx', 'MarkerSize', 10);
ylabel('利润($10,000)'); % 设置y轴标签
xlabel('城市人口(10,000人)'); % 设置x轴标签
end
```

#### 2. 损失函数与梯度下降

绘制完原始数据图后,接下来是线性回归的核心部分——梯度下降算法。

```matlab
% =================== Part 2: 成本函数和梯度下降 ===================

X = [ones(m, 1), data(:, 1)]; % 在X前添加一列1
theta = zeros(2, 1); % 初始化拟合参数

% 梯度下降设置
iteratiOns= 1500;
alpha = 0.01;

fprintf('\n测试成本函数...
');

% 计算并显示初始成本
J = computeCost(X, y, theta);
fprintf('当theta = [0 ; 0]\n计算的成本 = %f\n', J);
fprintf('预期成本值(近似) 32.07\n');

% 进一步测试成本函数
J = computeCost(X, y, [-1 ; 2]);
fprintf('\n当theta = [-1 ; 2]\n计算的成本 = %f\n', J);
fprintf('预期成本值(近似) 54.24\n');

fprintf('程序暂停。按回车继续。
');
pause;

fprintf('\n运行梯度下降...
');

% 运行梯度下降
theta = gradientDescent(X, y, theta, alpha, iterations);

% 显示theta
fprintf('通过梯度下降找到的theta:\n');
fprintf('%f\n', theta);
fprintf('预期的theta值(近似)\n');
fprintf(' -3.6303\n 1.1664\n\n');

% 绘制线性拟合曲线
hold on; % 保持之前的图形可见
plot(X(:, 2), X * theta, '-');
legend('训练数据', '线性回归');
hold off; % 不再覆盖当前图形

% 预测人口规模为35,000和70,000时的利润
predict1 = [1, 3.5] * theta;
fprintf('对于人口 = 35,000,预测利润为 %f\n', predict1 * 10000);
predict2 = [1, 7] * theta;
fprintf('对于人口 = 70,000,预测利润为 %f\n', predict2 * 10000);

fprintf('程序暂停。按回车继续。
');
pause;
```

这段代码首先对输入的X进行了处理,添加了一列1,以便将常数项theta0与之相乘。然后,我们测试了损失函数`computeCost`的正确性。

```matlab
function J = computeCost(X, y, theta)
% COMPUTECOST 计算线性回归的成本
% J = COMPUTECOST(X, y, theta) 计算使用theta作为参数进行线性回归的成本

m = length(y); % 训练样本数量
J = 0;

for i = 1:m
J = J + ((X(i, :) * theta - y(i))^2) / (2 * m);
end

end
```

接下来,我们使用梯度下降函数`gradientDescent`来更新theta,并记录每次迭代的成本变化。

```matlab
function [theta, J_history] = gradientDescent(X, y, theta, alpha, num_iters)
% GRADIENTDESCENT 执行梯度下降以学习theta
% theta = GRADIENTDESCENT(X, y, theta, alpha, num_iters) 通过梯度下降更新theta

m = length(y); % 训练样本数量
J_history = zeros(num_iters, 1);

for iter = 1:num_iters
% 执行一次梯度下降步骤
temp0 = theta(1) - alpha * sum(X * theta - y) / m;
temp1 = theta(2) - alpha * (X(:, 2)' * (X * theta - y)) / m;
theta(1) = temp0;
theta(2) = temp1;

% 保存每次迭代的成本
J_history(iter) = computeCost(X, y, theta);
end

end
```

#### 3. 损失函数的可视化

最后,我们绘制损失函数和theta的关系图,并画出等高线,标记出最终得到的theta。

```matlab
% ============= Part 3: 可视化J(theta_0, theta_1) =============
fprintf('可视化J(theta_0, theta_1)...
');

% 创建网格以计算J
theta0_vals = linspace(-10, 10, 100);
theta1_vals = linspace(-1, 4, 100);

% 初始化J_vals为0矩阵
J_vals = zeros(length(theta0_vals), length(theta1_vals));

% 填充J_vals
for i = 1:length(theta0_vals)
for j = 1:length(theta1_vals)
t = [theta0_vals(i); theta1_vals(j)];
J_vals(i, j) = computeCost(X, y, t);
end
end

% 因为surf命令的工作方式,需要转置J_vals
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, 3, 20));
xlabel('\theta_0'); ylabel('\theta_1');
hold on;
plot(theta(1), theta(2), 'rx', 'MarkerSize', 10, 'LineWidth', 2);
```

通过这些步骤,我们完成了单变量线性回归的实现。整个过程相对简单,主要得益于提供的框架和详细的指导。
推荐阅读
author-avatar
游你精彩_980_469
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有