当前位置: 首页 > news >正文

作业2-线性回归的Matlab代码实现

一、前言

        相关配置:Matlab 2020a(版本的影响应该不大,.m代码基本都能运行,个人感觉就是Simulink对版本的要求高一些)

二、任务描述

        基于近两节课的理论推导,用代码实现线性回归,并对预测结果进行分析。同时体会学习率、迭代次数对系统的影响(收敛速度、代码运行速度等)。

三、代码实现

        我们将任务假设为房价的预测,研究单变量的线性回归,即输入特征只有一个(房屋面积)。使用一次函数来生成相关样本(这里的一次函数为笔者随意设置,并不与现实的情况相符合)。

% ----------------------原始数据集---------------------- %
x = linspace(0, 1000, 200); % 生成横坐标(房屋面积)数据
y = 1.5 * x + 100; % 生成房价
data = [x; y]; % 组合成二维数据

        这样生成的样本(以50个样本为例)连起来就是一条直线。然而现实情况是,样本数据或多或少会存在“噪声”,房价与房屋面积也不会呈现完美的一次函数关系。所以我们需要对样本增加“噪声”。代码示例如下:

noise_level = 30;  % 定义噪声参数noise = noise_level * randn(size(data)); % 生成与数据相同大小的高斯噪声
noisy_data = data + noise; % 将噪声添加到数据中noisy_x = noisy_data(1,:); % 添加噪声后的特征(房屋面积)
noisy_y = noisy_data(2,:); % 添加噪声后的结果(房价)

        其中randn 函数用于生成符合标准正态分布(均值为 0,标准差为 1)的随机数。增加“噪声”后的样本示例如下图所示。我们可以发现,样本点出现了一定的变化,呈现一种“随机”的状态。

        在进行梯度下降迭代之前,我们还需要将样本数据进行归一化。对自变量和因变量进行归一化或标准化,使其值更为均衡,有利于帮助模型更快收敛。(笔者在之前的测试中发现,若不进行归一化,输出的截距θ0会为0或者其他奇奇怪怪的问题。)

        【特别注意】最终我们预测结果的那条线的相关参数需要进行反归一化才行!!!

std_x = (noisy_x - mean(noisy_x)) / std(noisy_x); % 标准化x
std_y = (noisy_y - mean(noisy_y)) / std(noisy_y); % 标准化y

        接下来就是进行梯度下降的迭代了。代码主要分为以下三步

①、依据输入特征,获得预测值(预测的房价)

②、计算梯度,获得当前的θ0和θ1(实际情况是需要对θ0和θ1求偏导,代码中直接给出了计算结果,详见《机器学习-周志华》P54的式3.5和式3.6)

③、更新参数,获取新的θ0和tθ1(这里需要注意学习率α不宜设置的过大。过大的α可能会导致损失函数J无法收敛)

④、计算损失值

         主循环代码如下所示:

% ------------------------------主循环代码-------------------------------
% GPT的例程是固定一个迭代次数,例如1000次,次数到了就退出循环,输出结果
% 笔者尝试固定一个损失值,当损失小于固定值时才退出循环,但运行效果不佳,
% 故放弃了这种方案
% ----------------------------------------------------------------------
for i = 1 : iteration_numy_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次的损失函数的收敛图如下图所示,我们可以发现,损失值随着迭代次数的增加逐渐减小,呈现一种收敛的状态。

        下图是迭代1000次的 损失函数的收敛图,我们可以发现,迭代次数超过500后,损失值几乎不再发生变化(本身“损失”就已经很小了),所以无脑的增加迭代次数并不一定是好的,适可而止,在大模型训练中也能节约计算时间。

         以下Matlab“命令窗口”打印的数据结果,我们可以发现,最终输出的线性回归方程与前文设置的一次方程y=1.5x+100相近似。

迭代次数:500次
loss损失:0.011024
最终线性回归方程:y = 1.49x + 104.89
theta1 = 1.49, theta0 = 104.89
>> 

         通过绘制J(\theta _{0},\theta _{1})的图像,我们也可以发现,最终的损失函数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% ------------------------------主循环代码-------------------------------
% GPT的例程是固定一个迭代次数,例如1000次,次数到了就退出循环,输出结果
% 笔者尝试固定一个损失值,当损失小于固定值时才退出循环,但运行效果不佳,
% 故放弃了这种方案
% ----------------------------------------------------------------------
for i = 1 : iteration_numy_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 

         通过 以上测试我们可以发现,α越小,模型收敛的速度越慢,需要通过增加迭代次数来达到预期的效果。而当α取值不当时,模型可能无法收敛。因此选取合适学习率α以及迭代次数至关重要,这影响到了代码运行的效率以及最终的预测结果。(迭代次数越多,代码循环的次数越多,耗费的时间越长。)

七、闲聊

        这只是一次课堂作业的学习记录。很遗憾的是,笔者未来的工作规划并不考虑机器学习方向,自己还是比较喜欢做硬件,所以大家并不需要因为这篇文章对我进行关注,后续也不一定会更新有关机器学习方向的内容,抱歉。

        此外,有关Matlab的代码笔者参考了GPT的例程,主要的逻辑框架为GPT生成,笔者只是对输入样本、一些运行参数、相关公式、整体代码风格以及输出图像的效果进行了修改,特此声明。(感叹:GPT太强大了,真的节约了很多的时间。)

2024-10-20-18:50,爽

相关文章:

作业2-线性回归的Matlab代码实现

一、前言 相关配置:Matlab 2020a(版本的影响应该不大,.m代码基本都能运行,个人感觉就是Simulink对版本的要求高一些) 二、任务描述 基于近两节课的理论推导,用代码实现线性回归,并对预测结果进…...

用jQuery在canvas上绘制绝对定位的元素

在Web开发中,我们经常需要在canvas上精确定位和绘制元素。虽然canvas本身不支持DOM元素的定位,但我们可以借助jQuery来实现这一功能。本文将介绍如何使用jQuery在canvas上实现元素的绝对定位。 1. 基本思路 我们的基本思路是: 创建一个包含canvas的容器div将需要定位的元素放…...

Android中 tools:text 和 android:text区别

首先引入命名空间 <androidx.constraintlayout.widget.ConstraintLayoutxmlns:android"http://schemas.android.com/apk/res/android"xmlns:tools"http://schemas.android.com/tools"/androidx.constraintlayout.widget.ConstraintLayout> tools:te…...

Wordpress GutenKit 插件 远程文件写入致RCE漏洞复现(CVE-2024-9234)

0x01 产品简介 GutenKit 是一个WordPress的页面构建器,在 Gutenberg 设计您的下一个 WordPress 网站。借助 Gutenberg 的原生拖放界面、50+ WordPress 块、14+ 多功能模块和 500+ 模板,您可以在几分钟内创建专业、响应迅速的 Web 内容。 0x02 漏洞概述 Wordpress GutenKit…...

Redis历史漏洞未授权RCE复现

Redis是一个开源的内存数据库&#xff0c;它用于存储数据&#xff0c;并提供高性能、可扩展性和丰富的数据结构支持。 Redis复现文章 Redisssrf漏洞利用探测内网 RedisInsight/RedisDesktopManager可视化连接工具 漏洞原理 &#xff08;1&#xff09;redis绑定在 0.0.0.0:…...

Greenhills学习总结

学习背景&#xff1a;近期参与xx项目过程中&#xff0c;遇到较多的关于代码集成编译的知识盲区&#xff0c;因此需要进行相关知识的学习和扫盲。 参考资料&#xff1a;GreenHills2017.7编译手册:本手册是GreenHills 2017.7.14版编译器的软件使用手册。该手册详细介绍了GreenHi…...

【深入学习Redis丨第八篇】详解Redis数据持久化机制

前言 Redis支持两种数据持久化方式&#xff1a;RDB方式和AOF方式。前者会根据配置的规则定时将内存中的数据持久化到硬盘上&#xff0c;后者则是在每次执行写命令之后将命令记录下来。两种持久化方式可以单独使用&#xff0c;但是通常会将两者结合使用。 一、持久化 1.1、什么…...

【27续】c++项目练习

定义一个或多个类&#xff0c;来描述以下需求&#xff1a; 汽车&#xff0c;有多个轮胎&#xff0c;一个发动机&#xff0c;品牌&#xff0c;型号, 价格&#xff0c; 行驶里程。 轮胎&#xff0c;有品牌&#xff0c;尺寸&#xff0c;气压。 发动机&#xff0c;有品牌&#x…...

Lazarus Query转EXCEL功能

Lazarus Query转EXCEL功能 需要用到控件XMLXSDExporter1 procedure SaveToExcel(AQuery:TSQLQuery); var SaveDialog: TSaveDialog; Ext:String; begin SaveDialog : TSaveDialog.Create(nil); SaveDialog.Filter:Excel 97-2003文件(*.xls)|*.XLS; if SaveDialog.Exec…...

AnaTraf | 深入探讨DNS流量分析:保障网络稳定性的关键

目录 什么是DNS流量分析&#xff1f; DNS流量的组成 为什么进行DNS流量分析&#xff1f; DNS流量分析在IT运维中的应用 1. 故障排查 2. 性能监控与优化 3. 安全检测 AnaTraf 网络性能监控系统NPM | 全流量回溯分析 | 网络故障排除工具 在当今数字化时代&#xff0c;互联…...

P1017 [NOIP2000 提高组] 进制转换

题目是意思就是转化 负进制 题干给定内容确实看不懂 我是看了别人的题解才会的 注意点&#xff1a;进制中不能出现负数&#xff08;解决方法 向前借一位 这是核心代码&#xff09;抓住 被除数除数*商余数 if(tp<0){//模是负数 就要转化为正数tp-y;xy;}//自己在纸上模拟一…...

计算机网络—vlan(虚拟局域网)

内容补充 冲突域 如果两台设备同时发送数据&#xff0c;他们的数据会互相干扰&#xff0c;那么他们就处于同一冲突域&#xff0c;例如集线器&#xff08;总线型&#xff0c;所有设备共享带宽&#xff09;的所有端口都处于冲突域。 广播域 如果一台设备发送数据&#xff0c;…...

C++头文件大全及解释

在C编程中&#xff0c;头文件起到了非常重要的作用。它们包含了函数声明、类定义和其他预处理指令&#xff0c;为程序提供了所需的各种功能和库。本文将介绍一些常见的C头文件&#xff0c;并提供具体实例来说明它们的用途和解释。 1. <iostream> 这是C标准库中最常用的头…...

基于 Django 的电商比价系统

想在毕业设计中展示自己的开发能力吗&#xff1f;今天给大家推荐一个绝对能让你脱颖而出的项目——基于 Django 框架的电商比价系统&#xff01;主打实用创新&#xff0c;你一定能用它拿下好成绩&#xff5e;&#x1f929; ✨项目核心功能亮点&#xff1a; 完善的用户系统&…...

Excel重新踩坑2:Excel数据类型;自定义格式(设置显示格式);分列操作;其他常用操作;一些重要操作

0、Excel数据类型&#xff1a;文本、数字、逻辑值、错误值 文本数据类型&#xff1a;输入什么显示什么&#xff1b;常见错误值 VALUE&#xff1a;文本与数字运算&#xff1b; DIV/0&#xff1a;分母为0&#xff1b; NAME&#xff1a;公式名称错误&#xff1b; N/A&#xff1a;…...

python从0快速上手(十四)数据库操作

Python学习&#xff1a;数据库操作篇 在这个信息爆炸的时代&#xff0c;数据库就像是一个个巨大的宝藏库&#xff0c;里面藏着无数珍贵的数据宝石。而Python&#xff0c;就是那把能够打开这些宝藏库的神奇钥匙。在这一章中&#xff0c;我们将一起学习如何使用Python来操作数据…...

【热门主题】000004 案例 Vue.js组件开发

前言&#xff1a;哈喽&#xff0c;大家好&#xff0c;今天给大家分享一篇文章&#xff01;并提供具体代码帮助大家深入理解&#xff0c;彻底掌握&#xff01;创作不易&#xff0c;如果能帮助到大家或者给大家一些灵感和启发&#xff0c;欢迎收藏关注哦 &#x1f495; 目录 【热…...

Ingress-nginx中HTTPS的强制转发

文章目录 在使用aws 的NLB转发流量到ingress时&#xff0c;发现NLP上生成的转发配置不符合正常预期&#xff0c;如下图&#xff1a; ingress-nginx service 配置如下&#xff1a; apiVersion: v1 kind: Service metadata:annotations:service.beta.kubernetes.io/aws-load-b…...

C++深入探寻二叉搜索树:数据管理的智慧之选

✨✨小新课堂开课了&#xff0c;欢迎欢迎~✨✨ &#x1f388;&#x1f388;养成好习惯&#xff0c;先赞后看哦~&#x1f388;&#x1f388; 所属专栏&#xff1a;C&#xff1a;由浅入深篇 小新的主页&#xff1a;编程版小新-CSDN博客 前言&#xff1a; 我们在前面已经学习过有关…...

Python 文件 I/O 入门指南

Python 文件 I/O 入门指南 文章目录 Python 文件 I/O 入门指南一、文件的打开与关闭二、文件的读取三、文件的写入四、文件的定位五、文件的属性六、处理不同类型的文件七、错误处理八、总结 在 Python 编程中&#xff0c;文件输入输出&#xff08;I/O&#xff09;是一项非常重…...

工业安全零事故的智能守护者:一体化AI智能安防平台

前言&#xff1a; 通过AI视觉技术&#xff0c;为船厂提供全面的安全监控解决方案&#xff0c;涵盖交通违规检测、起重机轨道安全、非法入侵检测、盗窃防范、安全规范执行监控等多个方面&#xff0c;能够实现对应负责人反馈机制&#xff0c;并最终实现数据的统计报表。提升船厂…...

初学 pytest 记录

安装 pip install pytest用例可以是函数也可以是类中的方法 def test_func():print()class TestAdd: # def __init__(self): 在 pytest 中不可以使用__init__方法 # self.cc 12345 pytest.mark.api def test_str(self):res add(1, 2)assert res 12def test_int(self):r…...

AI病理诊断七剑下天山,医疗未来触手可及

一、病理诊断困局&#xff1a;刀尖上的医学艺术 1.1 金标准背后的隐痛 病理诊断被誉为"诊断的诊断"&#xff0c;医生需通过显微镜观察组织切片&#xff0c;在细胞迷宫中捕捉癌变信号。某省病理质控报告显示&#xff0c;基层医院误诊率达12%-15%&#xff0c;专家会诊…...

推荐 github 项目:GeminiImageApp(图片生成方向,可以做一定的素材)

推荐 github 项目:GeminiImageApp(图片生成方向&#xff0c;可以做一定的素材) 这个项目能干嘛? 使用 gemini 2.0 的 api 和 google 其他的 api 来做衍生处理 简化和优化了文生图和图生图的行为(我的最主要) 并且有一些目标检测和切割(我用不到) 视频和 imagefx 因为没 a…...

【网络安全】开源系统getshell漏洞挖掘

审计过程&#xff1a; 在入口文件admin/index.php中&#xff1a; 用户可以通过m,c,a等参数控制加载的文件和方法&#xff0c;在app/system/entrance.php中存在重点代码&#xff1a; 当M_TYPE system并且M_MODULE include时&#xff0c;会设置常量PATH_OWN_FILE为PATH_APP.M_T…...

给网站添加live2d看板娘

给网站添加live2d看板娘 参考文献&#xff1a; stevenjoezhang/live2d-widget: 把萌萌哒的看板娘抱回家 (ノ≧∇≦)ノ | Live2D widget for web platformEikanya/Live2d-model: Live2d model collectionzenghongtu/live2d-model-assets 前言 网站环境如下&#xff0c;文章也主…...

恶补电源:1.电桥

一、元器件的选择 搜索并选择电桥&#xff0c;再multisim中选择FWB&#xff0c;就有各种型号的电桥: 电桥是用来干嘛的呢&#xff1f; 它是一个由四个二极管搭成的“桥梁”形状的电路&#xff0c;用来把交流电&#xff08;AC&#xff09;变成直流电&#xff08;DC&#xff09;。…...

Win系统权限提升篇UAC绕过DLL劫持未引号路径可控服务全检项目

应用场景&#xff1a; 1、常规某个机器被钓鱼后门攻击后&#xff0c;我们需要做更高权限操作或权限维持等。 2、内网域中某个机器被钓鱼后门攻击后&#xff0c;我们需要对后续内网域做安全测试。 #Win10&11-BypassUAC自动提权-MSF&UACME 为了远程执行目标的exe或者b…...

【QT控件】显示类控件

目录 一、Label 二、LCD Number 三、ProgressBar 四、Calendar Widget QT专栏&#xff1a;QT_uyeonashi的博客-CSDN博客 一、Label QLabel 可以用来显示文本和图片. 核心属性如下 代码示例: 显示不同格式的文本 1) 在界面上创建三个 QLabel 尺寸放大一些. objectName 分别…...

第2课 SiC MOSFET与 Si IGBT 静态特性对比

2.1 输出特性对比 2.2 转移特性对比 2.1 输出特性对比 器件的输出特性描述了当温度和栅源电压(栅射电压)为某一具体数值时,漏极电流(集电极电流...