线性回归的Matlab代码实现详解
创作时间:
作者:
@小白创作中心
线性回归的Matlab代码实现详解
引用
CSDN
1.
https://blog.csdn.net/m0_72300717/article/details/142850982
一、前言
本教程将使用Matlab 2020a实现线性回归算法。虽然版本可能有所不同,但基本的.m代码应该都能运行。需要注意的是,Simulink对版本的要求可能更高一些。
二、任务描述
基于线性回归的理论推导,本教程将用代码实现线性回归,并分析预测结果。同时,我们将探讨学习率和迭代次数对系统收敛速度和代码运行速度的影响。
三、代码实现
我们将通过一个房价预测的案例来研究单变量线性回归,即输入特征只有一个(房屋面积)。首先,使用一次函数生成相关样本数据:
% ----------------------原始数据集---------------------- %
x = linspace(0, 1000, 200); % 生成横坐标(房屋面积)数据
y = 1.5 * x + 100; % 生成房价
data = [x; y]; % 组合成二维数据
为了模拟现实情况中的数据噪声,我们需要对样本添加噪声:
noise_level = 30; % 定义噪声参数
noise = noise_level * randn(size(data)); % 生成与数据相同大小的高斯噪声
noisy_data = data + noise; % 将噪声添加到数据中
noisy_x = noisy_data(1,:); % 添加噪声后的特征(房屋面积)
noisy_y = noisy_data(2,:); % 添加噪声后的结果(房价)
在进行梯度下降迭代之前,需要对样本数据进行归一化处理:
std_x = (noisy_x - mean(noisy_x)) / std(noisy_x); % 标准化x
std_y = (noisy_y - mean(noisy_y)) / std(noisy_y); % 标准化y
接下来是梯度下降迭代的核心代码:
% ------------------------------主循环代码-------------------------------
for i = 1 : iteration_num
y_pred = theta1 * std_x + theta0; % 预测值
% 计算梯度
d_theta1 = (1/m) * (theta1 * sum(std_x.^2) - sum((std_y - theta0) .* std_x));
d_theta0 = theta0 - (1/m) * sum(std_y - theta1 * std_x);
% 更新参数
theta1 = theta1 - alpha * d_theta1;
theta0 = theta0 - alpha * d_theta0;
loss = (1/m) * sum((y_pred - std_y).^2); % 计算损失
J_history(i) = loss;
end
迭代结束后,需要对参数进行反归一化处理:
% 反归一化后,才是真正的theta0和theta1
theta1 = theta1 * (std(noisy_y) / std(noisy_x)); % 恢复原始斜率
theta0 = mean(noisy_y) - theta1 * mean(noisy_x); % 恢复原始截距
四、输出结果与分析
下图展示了迭代500次后的预测结果,绿色的回归线与数据点基本吻合,说明模型预测效果较好。
此外,迭代500次的损失函数收敛图显示,损失值随着迭代次数的增加逐渐减小,呈现收敛状态。
以下是Matlab命令窗口打印的数据结果:
迭代次数:500次
loss损失:0.011024
最终线性回归方程:y = 1.49x + 104.89
theta1 = 1.49, theta0 = 104.89
通过绘制损失函数的图像,可以发现最终的损失函数J有一个全局最小点。
五、完整程序代码
clc;
clear;
close all;
% ----------------------原始数据集---------------------- %
x = linspace(0, 1000, 200); % 生成横坐标(房屋面积)数据
y = 1.5 * x + 100; % 生成房价
data = [x; y]; % 组合成二维数据
% -------------------------变量------------------------ %
iteration_num = 500; % 迭代次数
noise_level = 30; % 定义噪声参数
theta1 = 0; % 初始化斜率
theta0 = 0; % 初始化截距
alpha = 0.01; % 学习率
m = length(y); % 样本数量
J_history = zeros(iteration_num, 1); % 记录每次迭代的损失值
noise = noise_level * randn(size(data)); % 生成与数据相同大小的高斯噪声
noisy_data = data + noise; % 将噪声添加到数据中
noisy_x = noisy_data(1,:); % 添加噪声后的特征(房屋面积)
noisy_y = noisy_data(2,:); % 添加噪声后的结果(房价)
std_x = (noisy_x - mean(noisy_x)) / std(noisy_x); % 标准化x
std_y = (noisy_y - mean(noisy_y)) / std(noisy_y); % 标准化y
% ------------------------------主循环代码-------------------------------
for i = 1 : iteration_num
y_pred = theta1 * std_x + theta0; % 预测值
% 计算梯度
d_theta1 = (1/m) * (theta1 * sum(std_x.^2) - sum((std_y - theta0) .* std_x));
d_theta0 = theta0 - (1/m) * sum(std_y - theta1 * std_x);
% 更新参数
theta1 = theta1 - alpha * d_theta1;
theta0 = theta0 - alpha * d_theta0;
loss = (1/m) * sum((y_pred - std_y).^2); % 计算损失
J_history(i) = loss;
end
% ------------------------------绘制图像1------------------------------- %
subplot(2, 1, 1); % 创建两个子图
plot(noisy_data(1,:), noisy_data(2,:), '.b');
grid on; % 添加网格
xlim([0, 1000]); % 设置x轴范围
ylim([0, 1800]); % 设置y轴范围
hold on; % 保持图形,防止被后续图形覆盖
% 反归一化后,才是真正的theta0和theta1
theta1 = theta1 * (std(noisy_y) / std(noisy_x)); % 恢复原始斜率
theta0 = mean(noisy_y) - theta1 * mean(noisy_x); % 恢复原始截距
y_fit = theta1 * noisy_x + theta0; % 计算回归线的 y 值
plot(noisy_x, y_fit, '-g', 'LineWidth', 2); % 绘制回归线
title('运行结果'); % 标题
xlabel('房屋面积'); % 横坐标标签
ylabel('房屋价格'); % 纵坐标标签
legend('数据点', '回归线'); % 图例
hold off;
% ------------------------------绘制图像2------------------------------- %
subplot(2, 1, 2); % 创建两个子图
plot(1 : iteration_num, J_history, '-r', 'LineWidth', 2);
grid on; % 添加网格
title('损失函数收敛图'); % 标题
xlabel('迭代次数'); % 横坐标标签
ylabel('损失值'); % 纵坐标标签
% ------------------------------输出结果------------------------------- %
fprintf('迭代次数:%d次\n', iteration_num);
fprintf('loss损失:%.6f\n', loss);
fprintf('最终线性回归方程:y = %.2fx + %.2f\n', theta1, theta0);
fprintf('theta1 = %.2f, theta0 = %.2f\n', theta1, theta0);
% -----------------------------END OF FILE---------------------------- %
六、学习率的影响
学习率(α)对模型的收敛速度和效果有重要影响。以下是不同学习率下的实验结果:
- α = 0.01
- α = 0.002
- α = 5
通过实验可以发现,α越小,模型收敛的速度越慢,需要通过增加迭代次数来达到预期的效果。而当α取值不当时,模型可能无法收敛。因此,选择合适的学习率和迭代次数对于提高代码运行效率和预测结果至关重要。
热门推荐
中老年人健康饮食指南:天然高蛋白食物推荐
荨麻疹跟湿疹的区别
蜂胶有用吗?科学解读这种天然物质的功效
“好”胆固醇可能有助于预防脑萎缩和失智症
我需要补钙吗?营养师教你认识钙功效、摄入量与补充方式
维生素B族:好处与副作用全解析
遇到突然停气怎么办?别慌,自检方法这就奉上!
燃气灶延迟点火怎么办?多种原因及解决方案全解析
中国航母启航之路:勇士驭飞鲨佩剑守蓝天
如何预防他汀类药物导致的血糖升高
治疗痤疮的中药方剂
告别痘痘烦恼:青春痘治疗全攻略
养生新视角,如何通过中医调理改善皮肤?
药师说药丨他汀会升血糖,糖友还能吃吗?
药师说药丨他汀会升血糖,糖友还能吃吗?
六味地黄丸、杞菊地黄丸、知柏地黄丸适用于哪些人?注意什么?
中医治疗荨麻疹有效吗?科学验证与自然疗法
总是有荨麻疹,三个注意事情,避免反复发
服用他汀,影响了血糖怎么办,换药还是停药?
长期服用他汀,这4项检查一定要定期做
春节走亲访友礼仪指南:这五件事千万别做,否则容易惹人厌!
喝茶的时间有讲究没?黄金时间与适宜时间安排
立秋后,别再只喝绿茶啦!秋天喝茶的这些讲究你知道吗?
咖啡和茶提神的原理是什么?哪个更健康?
协同聚力,推动核领域基础研究高质量发展
血脂高,服用降血脂药物需要注意什么呢?
孜然羊肉:草原风味的美食传奇
烧烤撒料不会配?除了放孜然,还需牢记4种料,外焦里嫩肥而不腻
婴幼儿饮食参考来啦!每阶段应该怎么吃,一篇讲清楚
宝宝便秘吃什么蔬菜好排便