当前位置: 首页 > 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;是一项非常重…...

以下是对华为 HarmonyOS NETX 5属性动画(ArkTS)文档的结构化整理,通过层级标题、表格和代码块提升可读性:

一、属性动画概述NETX 作用&#xff1a;实现组件通用属性的渐变过渡效果&#xff0c;提升用户体验。支持属性&#xff1a;width、height、backgroundColor、opacity、scale、rotate、translate等。注意事项&#xff1a; 布局类属性&#xff08;如宽高&#xff09;变化时&#…...

工程地质软件市场:发展现状、趋势与策略建议

一、引言 在工程建设领域&#xff0c;准确把握地质条件是确保项目顺利推进和安全运营的关键。工程地质软件作为处理、分析、模拟和展示工程地质数据的重要工具&#xff0c;正发挥着日益重要的作用。它凭借强大的数据处理能力、三维建模功能、空间分析工具和可视化展示手段&…...

论文浅尝 | 基于判别指令微调生成式大语言模型的知识图谱补全方法(ISWC2024)

笔记整理&#xff1a;刘治强&#xff0c;浙江大学硕士生&#xff0c;研究方向为知识图谱表示学习&#xff0c;大语言模型 论文链接&#xff1a;http://arxiv.org/abs/2407.16127 发表会议&#xff1a;ISWC 2024 1. 动机 传统的知识图谱补全&#xff08;KGC&#xff09;模型通过…...

【配置 YOLOX 用于按目录分类的图片数据集】

现在的图标点选越来越多&#xff0c;如何一步解决&#xff0c;采用 YOLOX 目标检测模式则可以轻松解决 要在 YOLOX 中使用按目录分类的图片数据集&#xff08;每个目录代表一个类别&#xff0c;目录下是该类别的所有图片&#xff09;&#xff0c;你需要进行以下配置步骤&#x…...

ardupilot 开发环境eclipse 中import 缺少C++

目录 文章目录 目录摘要1.修复过程摘要 本节主要解决ardupilot 开发环境eclipse 中import 缺少C++,无法导入ardupilot代码,会引起查看不方便的问题。如下图所示 1.修复过程 0.安装ubuntu 软件中自带的eclipse 1.打开eclipse—Help—install new software 2.在 Work with中…...

[Java恶补day16] 238.除自身以外数组的乘积

给你一个整数数组 nums&#xff0c;返回 数组 answer &#xff0c;其中 answer[i] 等于 nums 中除 nums[i] 之外其余各元素的乘积 。 题目数据 保证 数组 nums之中任意元素的全部前缀元素和后缀的乘积都在 32 位 整数范围内。 请 不要使用除法&#xff0c;且在 O(n) 时间复杂度…...

智能分布式爬虫的数据处理流水线优化:基于深度强化学习的数据质量控制

在数字化浪潮席卷全球的今天&#xff0c;数据已成为企业和研究机构的核心资产。智能分布式爬虫作为高效的数据采集工具&#xff0c;在大规模数据获取中发挥着关键作用。然而&#xff0c;传统的数据处理流水线在面对复杂多变的网络环境和海量异构数据时&#xff0c;常出现数据质…...

JS设计模式(4):观察者模式

JS设计模式(4):观察者模式 一、引入 在开发中&#xff0c;我们经常会遇到这样的场景&#xff1a;一个对象的状态变化需要自动通知其他对象&#xff0c;比如&#xff1a; 电商平台中&#xff0c;商品库存变化时需要通知所有订阅该商品的用户&#xff1b;新闻网站中&#xff0…...

动态 Web 开发技术入门篇

一、HTTP 协议核心 1.1 HTTP 基础 协议全称 &#xff1a;HyperText Transfer Protocol&#xff08;超文本传输协议&#xff09; 默认端口 &#xff1a;HTTP 使用 80 端口&#xff0c;HTTPS 使用 443 端口。 请求方法 &#xff1a; GET &#xff1a;用于获取资源&#xff0c;…...

STM32---外部32.768K晶振(LSE)无法起振问题

晶振是否起振主要就检查两个1、晶振与MCU是否兼容&#xff1b;2、晶振的负载电容是否匹配 目录 一、判断晶振与MCU是否兼容 二、判断负载电容是否匹配 1. 晶振负载电容&#xff08;CL&#xff09;与匹配电容&#xff08;CL1、CL2&#xff09;的关系 2. 如何选择 CL1 和 CL…...