【机器学习】向量化使得简单线性回归性能提升
向量化使得简单线性回归性能提升
- 一、摘要
- 二、向量化运算概述
- 三、向量化运算在简单线性回归中的应用
- 四、性能测试与结果分析
一、摘要
本文主要讲述了向量化运算在简单线性回归算法中的应用。通过回顾传统for循环方式实现的简单线性回归算法,介绍了如何通过最小二乘法计算a的值。然而,这种方式在计算性能上存在效率较低的问题。为了提高性能,视频引入了向量化运算的概念,即将计算过程从循环方式转变为向量之间的计算。通过向量化运算,可以快速地计算出结果,相比传统的for循环方式,在性能上具有显著的优势。视频还强调了向量化运算需要基于推导的结果进行,对于入门级别的同学来说,可以先实现更清晰的程序版本,再基于这个版本进行向量化,以更好地理解算法的原理。
二、向量化运算概述
向量化概述:
- 向量化运算是一种重要的概念,可以提高计算性能。
- 通过将计算转换为向量之间的运算,可以大大提升性能。
向量化运算性能高的原因:
在计算机学科中,向量化运算通常比for循环等具有更好的计算性能,主要原因如下:
- 硬件层面
- 利用SIMD指令集:现代计算机的CPU通常支持单指令多数据(SIMD)指令集,如Intel的SSE、AVX等。向量化运算能够直接利用这些指令集,在一条指令中同时对多个数据元素进行相同的操作,例如可以同时对4个或8个单精度浮点数进行加法运算。而for循环每次只能处理一个数据元素,需要多条指令来完成相同数量数据的操作,这使得向量化运算在数据处理效率上有天然的优势。
- 提高缓存命中率:向量化运算通常会连续访问内存中的数据,这有利于提高CPU缓存的命中率。因为数据在内存中是连续存储的,当加载一个数据元素时,相邻的数据元素也很可能被加载到缓存中,后续对这些数据的访问就可以直接从缓存中获取,大大加快了访问速度。相比之下,for循环可能会以非连续的方式访问数据,导致缓存失效的情况更频繁,需要从内存中多次读取数据,增加了访问时间。
- 软件层面
- 减少指令开销:for循环需要在每次迭代时执行循环控制指令,如比较、跳转等,这些指令会增加额外的开销。而向量化运算将多个数据的处理合并为一个操作,减少了指令的数量和执行时间,从而提高了整体性能。
- 编译器优化:编译器对向量化运算的优化能力更强。编译器可以识别向量化的代码模式,并对其进行更高级的优化,如自动展开循环、调整指令顺序等,以充分利用硬件的特性。对于for循环,虽然编译器也能进行一些优化,但由于其灵活性较高,编译器很难像对向量化运算那样进行深度优化。
- 并行执行能力:向量化运算更适合并行计算。在多核处理器或GPU等并行计算环境中,向量化运算可以很容易地将数据划分到不同的核心或线程中进行并行处理,从而进一步提高计算速度。for循环虽然也可以通过一些方式实现并行化,但需要更多的代码调整和同步操作,实现起来相对复杂,且可能存在数据竞争等问题,影响性能。
三、向量化运算在简单线性回归中的应用
- 在简单线性回归中,a(斜率)的计算方式可以通过向量化运算来优化。
- 通过将计算转换为向量点乘,可以避免使用for循环,提高效率。
- 向量化运算的实现
- 基于上一篇博文中的SimpleLinearRegressionModel类所在工程中文件改名成为SimplyLearnRegressionDemo.py,然后在其中新建一个SimpleLinearRegressionVectorModel类,使得fit函数通过向量化运算来计算a和b。
- 通过使用numpy的dot方法,实现了向量点乘,提高了计算速度。
- 具体SimpleLinearRegressionVectorModel代码如下:
import numpy as npclass SimpleLinearRegressionModel:def __init__(self):# 初始化线性回归模型的参数a和b为Noneself.a_ = Noneself.b_ = Nonedef fit(self, x_train, y_train):"""根据训练数据集x_train,y_train训练Simple Linear Regression模型"""# 断言x_train的维度为1,确保是单特征训练数据assert x_train.ndim == 1, \"Simple Linear Regressor can only solve single feature training data."# 断言x_train和y_train的长度相等,确保数据匹配assert len(x_train) == len(y_train), \"the size of x_train must be equal to the size of y_train"# 先分别求出x和y的均值x_mean = np.mean(x_train)y_mean = np.mean(y_train)# 先求a的分子部分numerator = 0.0 # 分子denominator = 0.0 # 分母# 遍历训练数据,计算分子和分母for x_i, y_i in zip(x_train, y_train):numerator += (x_i - x_mean) * (y_i - y_mean)denominator += (x_i - x_mean) ** 2# 然后计算a的值self.a_ = numerator / denominator# 最后计算b的值self.b_ = y_mean - self.a_ * x_meanreturn selfdef predict(self, x_predict):"""给定待预测数据集x_predict,返回表示x_predict的结果向量"""# 断言x_predict的维度为1,确保是单特征数据assert x_predict.ndim == 1, \"Simple Linear Regressor can only solve single feature training data."# 断言模型已经训练过(a_和b_不为None)assert self.a_ is not None and self.b_ is not None, \"must fit before predict!"# 对每个待预测数据调用_predict方法,生成预测结果数组return np.array([self._predict(x) for x in x_predict])def _predict(self, x_single):"""给定单个待预测数据x_single,返回x_single的预测结果值"""# 根据训练得到的参数a_和b_进行预测计算return self.a_ * x_single + self.b_def __repr__(self):# 返回模型的字符串表示形式return "SimpleLinearRegressionModel()""""向量化的方式实现简单线性回归的算法"""class SimpleLinearRegressionVectorModel:def __init__(self):# 初始化线性回归模型的参数a和b为Noneself.a_ = Noneself.b_ = Nonedef fit(self, x_train, y_train):"""根据训练数据集x_train,y_train训练Simple Linear Regression模型"""# 断言x_train的维度为1,确保是单特征训练数据assert x_train.ndim == 1, \"Simple Linear Regressor can only solve single feature training data."# 断言x_train和y_train的长度相等,确保数据匹配assert len(x_train) == len(y_train), \"the size of x_train must be equal to the size of y_train"# 先分别求出x和y的均值x_mean = np.mean(x_train)y_mean = np.mean(y_train)# 先求a的分子部分# 向量化的方式实现numerator = (x_train - x_mean).dot(y_train - y_mean)denominator = (x_train - x_mean).dot(x_train - x_mean)# 然后计算a的值self.a_ = numerator / denominator# 最后计算b的值self.b_ = y_mean - self.a_ * x_meanreturn selfdef predict(self, x_predict):"""给定待预测数据集x_predict,返回表示x_predict的结果向量"""# 断言x_predict的维度为1,确保是单特征数据assert x_predict.ndim == 1, \"Simple Linear Regressor can only solve single feature training data."# 断言模型已经训练过(a_和b_不为None)assert self.a_ is not None and self.b_ is not None, \"must fit before predict!"# 对每个待预测数据调用_predict方法,生成预测结果数组return np.array([self._predict(x) for x in x_predict])def _predict(self, x_single):"""给定单个待预测数据x_single,返回x_single的预测结果值"""# 根据训练得到的参数a_和b_进行预测计算return self.a_ * x_single + self.b_def __repr__(self):# 返回模型的字符串表示形式return "SimpleLinearRegressionVectorModel()"
四、性能测试与结果分析
-
在jupyter中进行性能测试
# 导入在PyCharm中封装好的工程项目 import sys project_path = 'D:/PycharmProjects/pythonProject/' if project_path not in sys.path:sys.path.append(project_path)from SimpleLinearRegressionDemo import SimpleLinearRegressionModel from SimpleLinearRegressionDemo import SimpleLinearRegressionVectorModel# for循环实现的 sreg = SimpleLinearRegressionModel() # 向量化实现的 vreg = SimpleLinearRegressionVectorModel()# 定义一个随机的测试数据 num = 100000 # 自定义线性方程中的x,随机给定 big_x = np.random.random(size=num) # 定义线性方程中的y,其中np.random.normal(size=num)是给定了一个噪声 big_y = big_x * 2.0 + 3.0 + np.random.normal(size=num)# 使用魔法命令%timeit计算程序执行所花时间 %timeit sreg.fit(big_x,big_y) %timeit vreg.fit(big_x,big_y)执行结果如下:
51.9 ms ± 546 µs per loop (mean ± std. dev. of 7 runs, 10 loops each) 760 µs ± 11.9 µs per loop (mean ± std. dev. of 7 runs, 1,000 loops each)下面为你详细解释其含义:
第一行:51.9 ms ± 546 µs per loop (mean ± std. dev. of 7 runs, 10 loops each)51.9 ms:这是每次循环的平均执行时间,单位是毫秒(ms),也就是说该代码每次循环平均花费 51.9 毫秒来执行。± 546 µs:这表示测量结果的标准差,单位是微秒(µs)。标准差反映了多次测量结果的离散程度,这里说明每次循环执行时间在平均时间 51.9 毫秒左右波动,波动范围大约是正负 546 微秒。mean ± std. dev. of 7 runs, 10 loops each:这描述了测量的具体方式。7 runs表示进行了 7 次独立的测试运行;10 loops each表示每次运行中代码循环执行了 10 次。最终的平均时间和标准差是基于这 7 次运行,每次 10 个循环的所有测量结果计算得出的。
第二行:
760 µs ± 11.9 µs per loop (mean ± std. dev. of 7 runs, 1,000 loops each)760 µs:每次循环的平均执行时间,单位是微秒(µs),即该代码每次循环平均花费 760 微秒来执行。± 11.9 µs:测量结果的标准差,单位是微秒。说明每次循环执行时间在平均时间 760 微秒左右波动,波动范围大约是正负 11.9 微秒。mean ± std. dev. of 7 runs, 1,000 loops each:同样描述了测量方式。进行了 7 次独立的测试运行,每次运行中代码循环执行了 1000 次,平均时间和标准差是基于这些测量结果计算的。
对比分析
- 从这两组数据可以看出,第二组代码的执行效率明显高于第一组。第二组每次循环平均耗时 760 微秒,而第一组每次循环平均耗时 51.9 毫秒(即 51900 微秒)。你可以根据这些性能数据来优化代码或者选择更高效的实现方式。
在jupyter中执行过程:

-
结果显示,向量化运算实现的SimpleLinearRegressionVectorModel性能大幅提升,达到了68倍的速度提升。
相关文章:
【机器学习】向量化使得简单线性回归性能提升
向量化使得简单线性回归性能提升 一、摘要二、向量化运算概述三、向量化运算在简单线性回归中的应用四、性能测试与结果分析 一、摘要 本文主要讲述了向量化运算在简单线性回归算法中的应用。通过回顾传统for循环方式实现的简单线性回归算法,介绍了如何通过最小二乘…...
【kafka系列】消费者
目录 获取消息 1. 消费者获取消息的流程逻辑分析 阶段一:消费者初始化 阶段二:分区分配与重平衡(Rebalance) 阶段三:消息拉取与处理 阶段四:偏移量提交 核心设计思想 2. 流程 关键点总结 常见参数…...
HackerRank C++面试,中等难度题目 - Attribute Parser
去除字符串首尾的空白字符(包括空格、制表符、换行符和回车符) void trim(string &s) {size_t start s.find_first_not_of(" \t\n\r");size_t end s.find_last_not_of(" \t\n\r");if (start string::npos) {s ""…...
【ARM】解决ArmDS Fast Models 中部分内核无法上电的问题
1、 文档目标 解决ArmDS Fast Models 中部分内核无法上电的问题。 2、 问题场景 在调用ArmDS的Fast Models中的Cortex-A55的模型,只有Core 0是上电状态,而Core 1处于掉电状态,如图2-1所示: 图2-1 3、软硬件环境 1)…...
节目选择器安卓软件编写(针对老年人)
文章目录 需求来源软件界面演示效果源码获取 对爬虫、逆向感兴趣的同学可以查看文章,一对一小班教学:https://blog.csdn.net/weixin_35770067/article/details/142514698 需求来源 由于现在的视频软件过于复杂,某客户想开发一个针对老年人、…...
蓝桥杯之图
图: 对于图来说,重点在于之后的最短路径算法,这边简单做一下了解即可 代码: #include<iostream> #include<string> #include<vector> #include<list> #include<queue> using namespace std; clas…...
中兴光猫修改SN,MAC,修改地区,异地注册,改桥接,路由拨号
前言 请先阅读上一篇博客获取到光猫超级密码电信光猫获取超级密码 电信光猫天翼网关4.0获取超级密码教程 四川电信光猫 中兴 F1855V2 ZXHN F1855V2 telent权限 实战 实测_天翼4.0光猫超级密码-CSDN博客 修改SN-修改地区,光猫异地注册,设置桥接模式&#…...
【kafka系列】Kafka如何保证消息不丢失?
目录 1. 生产者端:确保消息成功发送到Broker 核心机制: 关键步骤: 2. Broker端:持久化与副本同步 核心机制: 关键源码逻辑: 3. 消费者端:可靠消费与Offset提交 核心机制: 关…...
AtCoder Beginner Contest 393 —— E - GCD of Subset 补题 + 题解 python
AtCoder Beginner Contest 393 E - GCD of Subset Problem Statement You are given a sequence A ( A 1 , A 2 , … , A N ) A (A_1, A_2, \dots, A_N) A(A1,A2,…,AN) of length N N N and a positive integer K K K (at most N N N). For each i 1 , 2 , … …...
vue3响应式丢失解决办法(三)
vue3的响应式的理解,与普通对象的区别(一) vue3 分析总结响应式丢失问题原因(二) 经过前面2篇文章,知道了响应式为什么丢失了,但是还是碰到了丢失情况,并且通过之前的内容还不能解…...
BY组态:构建灵活、可扩展的自动化系统
引言 在现代工业自动化领域,BY组态(Build Your Own Configuration)作为一种灵活、可扩展的解决方案,正逐渐成为工程师和系统集成商的首选。BY组态允许用户根据具体需求自定义系统配置,从而优化生产效率、降低成本并提…...
2025 (ISC)²CCSP 回忆录
2025.1.20 广州,周一,我一次性通过了CCSP的考试。 为什么要考证? 个人成长所需 职业热情:做一行爱一行,既然我投入了美好的青春年华到网络安全行业当中,那么对于这个行业最有权威的认证,是肯定…...
强化学习笔记7——DDPG到TD3
前提:基于TD 的方法多少都会有高估问题,即Q值偏大。原因两个:一、TD目标是真实动作的高估。 二:自举法高估。 DDPG 属于AC方法:异策略,适合连续动作空间,因为他的策略网络直接输出的动作&#…...
win10 系统 自定义Ollama安装路径 及模型下载位置
win10 系统 自定义Ollama安装路径 及模型下载位置 由于Ollama的exe安装软件双击安装的时候默认是在C盘,以及后续的模型数据下载也在C盘,导致会占用C盘空间,所以这里单独写了一个自定义安装Ollama安装目录的教程。 Ollama官网地址࿱…...
-bash:/usr/bin/rm: Argument list too long 解决办法
问题概述 小文件日志太多导致无法使用rm命令,因为命令行参数列表的长度超过了系统允许的最大值。 需要删除/tmp目录下的所有文件,文件数量比较多。 ls -lt /tmp | wc -l 5682452 解决方法如下: 使用find -exec 遍历,然后执行删…...
内容中台重构企业内容管理流程驱动智能协作升级
内容概要 内容中台作为企业数字化转型的核心基础设施,通过技术架构革新与功能模块整合,重构了传统内容管理流程的底层逻辑。其核心价值在于构建动态化、智能化的内容生产与流转体系,将分散的创作、存储、审核及分发环节纳入统一平台管理。基…...
python实现YouTube关键词爬虫(2025/02/11)
在当今数字化时代,YouTube作为全球最大的视频分享平台之一,拥有海量的视频资源。无论是进行市场调研、内容创作还是学术研究,能够高效地获取YouTube上的相关视频信息都显得尤为重要。今天,我将为大家介绍一个基于Python实现的YouT…...
【效率技巧】怎么做思维导图||数学思维||费曼学习法
目录标题 常见问题:认知误区和建议:思维导图按照功能分类思维导图好处步骤(拆解的步骤) 常见问题: 1、做好的思维导图浪费时间 2、做简单的思维导图没有效果 认知误区和建议: 1、做思维导图工具…...
LabVIEW与USB设备开发
开发一台USB设备并使用LabVIEW进行上位机开发,涉及底层驱动的编写、USB通信协议的实现以及LabVIEW与设备的接口设计。本文将详细介绍如何开发USB设备驱动、实现LabVIEW与USB设备的通信以及优化数据传输,帮助用户顺利完成项目开发。下面是一个详细的说明&…...
动态规划LeetCode-416.分割等和子集
给你一个 只包含正整数 的 非空 数组 nums 。请你判断是否可以将这个数组分割成两个子集,使得两个子集的元素和相等。 示例 1: 输入:nums [1,5,11,5] 输出:true 解释:数组可以分割成 [1, 5, 5] 和 [11] 。 示例 2&…...
后进先出(LIFO)详解
LIFO 是 Last In, First Out 的缩写,中文译为后进先出。这是一种数据结构的工作原则,类似于一摞盘子或一叠书本: 最后放进去的元素最先出来 -想象往筒状容器里放盘子: (1)你放进的最后一个盘子(…...
网络六边形受到攻击
大家读完觉得有帮助记得关注和点赞!!! 抽象 现代智能交通系统 (ITS) 的一个关键要求是能够以安全、可靠和匿名的方式从互联车辆和移动设备收集地理参考数据。Nexagon 协议建立在 IETF 定位器/ID 分离协议 (…...
为什么要创建 Vue 实例
核心原因:Vue 需要一个「控制中心」来驱动整个应用 你可以把 Vue 实例想象成你应用的**「大脑」或「引擎」。它负责协调模板、数据、逻辑和行为,将它们变成一个活的、可交互的应用**。没有这个实例,你的代码只是一堆静态的 HTML、JavaScript 变量和函数,无法「活」起来。 …...
Monorepo架构: Nx Cloud 扩展能力与缓存加速
借助 Nx Cloud 实现项目协同与加速构建 1 ) 缓存工作原理分析 在了解了本地缓存和远程缓存之后,我们来探究缓存是如何工作的。以计算文件的哈希串为例,若后续运行任务时文件哈希串未变,系统会直接使用对应的输出和制品文件。 2 …...
负载均衡器》》LVS、Nginx、HAproxy 区别
虚拟主机 先4,后7...
大模型——基于Docker+DeepSeek+Dify :搭建企业级本地私有化知识库超详细教程
基于Docker+DeepSeek+Dify :搭建企业级本地私有化知识库超详细教程 下载安装Docker Docker官网:https://www.docker.com/ 自定义Docker安装路径 Docker默认安装在C盘,大小大概2.9G,做这行最忌讳的就是安装软件全装C盘,所以我调整了下安装路径。 新建安装目录:E:\MyS…...
数据挖掘是什么?数据挖掘技术有哪些?
目录 一、数据挖掘是什么 二、常见的数据挖掘技术 1. 关联规则挖掘 2. 分类算法 3. 聚类分析 4. 回归分析 三、数据挖掘的应用领域 1. 商业领域 2. 医疗领域 3. 金融领域 4. 其他领域 四、数据挖掘面临的挑战和未来趋势 1. 面临的挑战 2. 未来趋势 五、总结 数据…...
简约商务通用宣传年终总结12套PPT模版分享
IOS风格企业宣传PPT模版,年终工作总结PPT模版,简约精致扁平化商务通用动画PPT模版,素雅商务PPT模版 简约商务通用宣传年终总结12套PPT模版分享:商务通用年终总结类PPT模版https://pan.quark.cn/s/ece1e252d7df...
STL 2迭代器
文章目录 1.迭代器2.输入迭代器3.输出迭代器1.插入迭代器 4.前向迭代器5.双向迭代器6.随机访问迭代器7.不同容器返回的迭代器类型1.输入 / 输出迭代器2.前向迭代器3.双向迭代器4.随机访问迭代器5.特殊迭代器适配器6.为什么 unordered_set 只提供前向迭代器? 1.迭代器…...
Electron简介(附电子书学习资料)
一、什么是Electron? Electron 是一个由 GitHub 开发的 开源框架,允许开发者使用 Web技术(HTML、CSS、JavaScript) 构建跨平台的桌面应用程序(Windows、macOS、Linux)。它将 Chromium浏览器内核 和 Node.j…...
