【机器学习 | 回归问题】超越直线:释放多项式回归的潜力 —— 详解线性回归与非线性 (含详细案例、源码)

news2024/11/17 7:28:11

在这里插入图片描述

🤵‍♂️ 个人主页: @AI_magician
📡主页地址: 作者简介:CSDN内容合伙人,全栈领域优质创作者。
👨‍💻景愿:旨在于能和更多的热爱计算机的伙伴一起成长!!🐱‍🏍
🙋‍♂️声明:本人目前大学就读于大二,研究兴趣方向人工智能&硬件(虽然硬件还没开始玩,但一直很感兴趣!希望大佬带带)

在这里插入图片描述

【深度学习 | 核心概念】那些深度学习路上必经的核心概念,确定不来看看? (一)
作者: 计算机魔术师
版本: 1.0 ( 2023.8.27 )

摘要: 本系列旨在普及那些深度学习路上必经的核心概念,文章内容都是博主用心学习收集所写,欢迎大家三联支持!本系列会一直更新,核心概念系列会一直更新!欢迎大家订阅

该文章收录专栏
[✨— 《深入解析机器学习:从原理到应用的全面指南》 —✨]

回归问题

线性回归的发展可以追溯到19世纪。以下是一些重要的里程碑:

  1. 1805年:卡尔·弗里德里希·高斯(Carl Friedrich Gauss)提出了最小二乘法的概念,为线性回归提供了数学基础。

  2. 1861年:弗朗西斯·高尔顿(Francis Galton)进行了一项关于遗传与身高之间关系的研究,这可以被认为是最早的线性回归应用之一。

  3. 1897年:弗朗西斯·埃杰顿(Francis Edgeworth)提出了一种用于估计回归系数的方法,称为最大似然估计。

  4. 1922年:罗纳德·费舍尔(Ronald Fisher)提出了最小二乘估计的统计性质,并发表了关于线性回归的经典论文。

  5. 1950年代:由于计算机技术的发展,线性回归在统计学和经济学中得到广泛应用。

  6. 1960年代:提出了多元线性回归,允许模型包含多个自变量。

  7. 1970年代:出现了岭回归和lasso回归等正则化方法,用于处理多重共线性和特征选择问题。

  8. 1990年代至今:随着机器学习和统计学的快速发展,线性回归仍然是许多预测建模和数据分析任务中的重要方法。同时,出现了更复杂的回归模型和非线性回归方法,如广义线性模型、多项式回归、支持向量回归等。

线性回归作为一种简单而强大的统计方法,在实际应用中得到广泛使用。它被应用于经济学、金融学、社会科学、医学、工程等领域,用于建立预测模型、探索变量之间的关系以及进行因果推断。

线性回归

线性回归是一种线性方法,用于建立自变量 X X X 和因变量 Y Y Y 之间的线性关系模型(这里的X可以是自变量矩阵)。这种关系通常形式化为以下等式:

Y = β 0 + β 1 X + ϵ Y = \beta_0 + \beta_1X + \epsilon Y=β0+β1X+ϵ

其中 β 0 \beta_0 β0 β 1 \beta_1 β1 是模型参数,代表截距和斜率, ϵ \epsilon ϵ 是误差项(不被训练)。

线性回归的目标是找到参数 β 0 \beta_0 β0 β 1 \beta_1 β1,使得模型预测的 Y Y Y 值与实际 Y Y Y 值之间的残差平方和最小。这被称为最小二乘法。这意味着我们想找到 β ^ 0 \hat{\beta}_0 β^0 β ^ 1 \hat{\beta}_1 β^1,使得

∑ i = 1 n ( y i − ( β ^ 0 + β ^ 1 x i ) ) 2 \sum_{i=1}^n (y_i - (\hat{\beta}_0 + \hat{\beta}_1 x_i))^2 i=1n(yi(β^0+β^1xi))2

最小,其中 ( x i , y i ) (x_i, y_i) (xi,yi) 是第 i i i 个观测值。

下面是如何使用 Python 的 scikit-learn 库进行线性回归的一个例子。在这个例子中,我们使用波士顿房价数据集,这是一个典型的开源数据集。

from sklearn.datasets import load_boston
from sklearn.model_selection import train_test_split
from sklearn.linear_model import LinearRegression
from sklearn.metrics import mean_squared_error

# 加载数据集
boston = load_boston()
X = boston.data
y = boston.target

# 划分训练集和测试集
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)

# 使用线性回归模型
model = LinearRegression()
model.fit(X_train, y_train)

# 预测
y_pred = model.predict(X_test)

# 计算均方误差
mse = mean_squared_error(y_test, y_pred)
print('Mean Squared Error:', mse)

首先,我们导入必要的库和数据集,然后划分训练集和测试集。接着,我们创建一个线性回归模型实例,并使用训练数据对其进行拟合。然后,我们使用该模型预测测试数据,并计算均方误差来评估模型性能。

多项式回归(非线性)

多项式回归是一种基于多项式函数的回归分析方法,用于拟合非线性关系的数据。它通过引入多项式特征,可以拟合更复杂的数据模式。

原理和数学公式推导:

假设我们有一个简单的数据集,包含一个特征 X 和对应的目标变量 y。我们希望使用多项式回归来拟合这些数据。

多项式回归模型的基本假设是,目标变量 y 与特征 X 之间存在一个多项式关系。我们可以用以下公式表示多项式回归模型:

y = w0 + w1*X + w2*X^2 + ... + wn*X^n

其中,X 是原始特征,X^2 表示 X 的平方,X^3 表示 X 的立方,以此类推。w0, w1, ..., wn 是多项式回归模型的系数,需要通过训练拟合得到。

为了使用多项式回归拟合数据,我们可以将特征 X 转换为多项式特征。通过引入幂次组合,我们可以将原始特征的非线性关系纳入考虑。

具体地,我们可以将多项式回归问题转化为普通的线性回归问题。将多项式特征表示为新的特征向量 X_poly,然后使用线性回归模型进行训练。(将对应的多项式特征,即幂方组合当成多元线性来求解)

为了将特征 X 转换为多项式特征,我们可以使用 PolynomialFeatures 类。它可以生成包含原始特征幂次组合的新特征矩阵。

训练多项式回归模型的步骤如下:

  1. 准备数据集:将原始特征 X 和目标变量 y 划分为训练集和测试集。
  2. 特征转换:使用 PolynomialFeatures 类将训练集和测试集的特征 X 转换为多项式特征。可以指定多项式的次数(degree 参数)。

假设我们有一个简单的数据集,包含一个特征x和对应的目标变量y。原始数据如下:

x = [1, 2, 3]
y = [2, 4, 6]

使用PolynomialFeatures

[[1 1 1]
 [1 2 4]
 [1 3 9]]

可以看到,使用PolynomialFeatures对特征x进行多项式扩展后,生成了3列特征。第一列是常数项1,第二列是原始特征x,第三列是x的平方。这样,我们就得到了一个包含3个特征的新数据集x_poly。

当面对多个特征时,在多个特征上使用PolynomialFeatures。

假设我们有一个包含两个特征x1和x2的数据集,以及对应的目标变量y。原始数据如下:

x1 = [1, 2, 3]
x2 = [4, 5, 6]
y = [10, 15, 20]

的到如下

[[ 1  1  4  1  4 16]
 [ 1  2  5  4 10 25]
 [ 1  3  6  9 18 36]]

可以看到,使用PolynomialFeatures对特征x1和x2进行多项式扩展后,生成了6列特征。第一列是常数项1,接下来两列是原始特征x1和x2,然后是两列特征的乘积,最后两列是各特征的平方。这样,我们就得到了一个包含6个特征的新数据集x_poly。

  1. 训练模型:使用线性回归模型(如 LinearRegression)对转换后的训练集进行训练。模型会学习多项式回归方程的系数。
  2. 预测:使用训练好的模型对转换后的测试集进行预测。
  3. 评估:通过比较预测结果与实际目标变量的值,评估多项式回归模型的性能。

经典案例:

以下是一个使用多项式回归拟合波士顿房价的经典案例的 Python 代码实现。

import numpy as np
import matplotlib.pyplot as plt
from sklearn.linear_model import LinearRegression
from sklearn.preprocessing import PolynomialFeatures
from sklearn.metrics import mean_squared_error
from sklearn.model_selection import train_test_split
from sklearn.datasets import load_boston
from sklearn.pipeline import Pipeline

# 加载数据集
boston = load_boston()
X = boston.data
y = boston.target

# 划分训练集和测试集
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)

# 管道
pipeline = Pipeline([
    ("PolynomialFeatures", PolynomialFeatures(degree=2)),# 多项式特征转换
    ("LinearRegression",LinearRegression())# 线性回归模型训练
])

pipeline.fit(X_train, y_train)

# 预测结果
y_pred = pipeline.predict(X_test)


# 计算均方误差
mse = mean_squared_error(y_test, y_pred)
print('Mean Squared Error:', mse)

plt.scatter(y_test, y_pred, c='blue', alpha=0.6)
plt.plot([y_test.min(), y_test.max()], [y_test.min(), y_test.max()], 'r--')  # 绘制对角线

plt.title('Actual vs. Predicted')
plt.xlabel('Actual Values')
plt.ylabel('Predicted Values')
plt.show()

# 计算残差
residuals = y_test - y_pred

# 绘制残差图 
plt.scatter(y_test, residuals)
plt.axhline(y=0, color='r', linestyle='--')
plt.xlabel('Actual Values')
plt.ylabel('Residuals')
plt.title('Residual Plot')

在这里插入图片描述

相关学习文档或优秀博客:

以下是一些关于多项式回归的学习资源和优秀博客,可以帮助你更深入地理解多项式回归算法和其应用:

  • Polynomial Regression - Wikipedia
SLSQP 优化训练算法

SLSQP(Sequential Least Squares Programming)算法是一种用于求解带有约束条件的非线性优化问题的算法。它是一种迭代算法,通过不断迭代来逼近问题的最优解。下面我将详细介绍SLSQP算法的整体流程,并以优化带有约束条件的多项式为例进行说明。

SLSQP算法的整体流程如下:

  1. 确定优化目标函数和约束条件:首先,需要明确需要优化的目标函数和约束条件。在本例中,我们假设我们要最小化一个多项式函数,同时满足一些约束条件。

  2. 初始化:给定初始解,可以是随机选择的或者根据问题的特点选择的一个可行解。

  3. 构建拉格朗日函数:将目标函数和约束条件结合起来构建拉格朗日函数。拉格朗日函数是由目标函数和约束条件通过引入拉格朗日乘子所得到的一个函数。

  4. 求解子问题:通过求解拉格朗日函数的子问题来更新变量的值。子问题是通过将拉格朗日函数对变量进行最小化求解得到的。

  5. 更新约束条件:根据当前变量的值更新约束条件。如果约束条件中包含不等式约束,可能需要使用一些方法来将其转化为等式约束。(引入罚函数或者松弛变量,运筹学)

  6. 判断终止条件:判断当前解是否满足终止条件。终止条件可以是达到一定的迭代次数、目标函数的变化量小于某个阈值或者满足约束条件的程度达到一定的要求等。

  7. 迭代更新:如果终止条件不满足,则返回第4步继续迭代更新。

  8. 输出结果:当终止条件满足时,输出最优解的变量值以及对应的目标函数值。

以上是SLSQP算法的整体流程。下面我们以优化带有约束条件的多项式为例进行说明。

假设我们要最小化一个二次多项式函数 f(x) = x^2 + 2x + 1,同时满足约束条件 g(x) = x >= 0。

  1. 确定优化目标函数和约束条件:目标函数为 f(x) = x^2 + 2x + 1,约束条件为 g(x) = x >= 0。
  2. 引入罚函数:将不等式约束转化为罚函数惩罚项,即将原始的不等式约束 g(x) = x >= 0 转化为 g(x) - ρ,其中 ρ 是罚函数的惩罚参数,通常为非负数。
  3. 初始化:选择一个初始解,例如 x = 0。
  4. 构建拉格朗日函数:构建拉格朗日函数 L(x, λ) = f(x) + λ*g(x),其中 λ 是拉格朗日乘子。
  5. 求解子问题:通过最小化拉格朗日函数 L(x, λ) 对 x 进行求解,得到更新后的 x 值。
  6. 更新约束条件:根据当前的 x 值和约束条件 g(x) 的情况,更新罚函数参数 ρ。通常情况下,如果当前解满足约束条件,可以减小 ρ 的值,以使罚函数的惩罚项对目标函数的影响减小;如果当前解不满足约束条件,可以增大 ρ 的值,以加大罚函数的惩罚项。
  7. 判断终止条件:判断当前解是否满足终止条件,例如目标函数的变化量小于某个阈值。
  8. 迭代更新:如果终止条件不满足,返回第4步继续迭代更新。
  9. 输出结果:当终止条件满足时,输出最优解的变量值以及对应的目标函数值。

通过以上流程,我们可以使用SLSQP算法找到满足约束条件下的多项式的最小值。需要注意的是,实际应用中,可能需要根据具体问题对SLSQP算法进行一些调整和优化,以提高求解效率和准确性。

代码案例:

我们首先需要目标函数和损失函数,所以需要先定义以实现

import numpy as np
from sklearn.datasets import load_boston
from sklearn.preprocessing import PolynomialFeatures
from scipy.optimize import minimize
from sklearn.metrics import mean_squared_error, r2_score
from time import time

start = time()

# 加载波士顿数据集
boston = load_boston()
X = boston.data  # 特征矩阵
y = boston.target  # 目标变量

# 划分训练集和测试集
X_train, X_test, y_train, y_test = train_test_split(
    X, y, test_size=0.2, random_state=42)

# 创建PolynomialFeatures对象,生成多项式特征
poly_features = PolynomialFeatures(degree=2)
X_poly = poly_features.fit_transform(X_train)

# 定义损失函数(均方误差)
def loss_function(theta):
    y_pred = np.dot(X_poly, theta)
    mse = mean_squared_error(y_train, y_pred)
    return mse

# 定义约束条件(无约束)
constraints = ()

# 定义优化问题 初始参数x0(全零向量)
optimization_problem = minimize(loss_function, x0=np.zeros(X_poly.shape[1]), constraints=constraints, method='SLSQP')

# 获取优化结果
theta_optimized = optimization_problem.x

# 在测试集上进行预测
X_test_poly = poly_features.transform(X_test)
y_pred = np.dot(X_test_poly, theta_optimized)

# 计算测试集上的均方误差和决定系数
mse_train = mean_squared_error(y_test, y_pred)
r2_train = r2_score(y_test, y_pred)

# 输出结果
print("多项式回归模型拟合结果:")
print("均方误差(MSE):", mse_train)
print("决定系数(R2 Score):", r2_train)
print("运行时间(duration):", time() - start)

plt.scatter(y_test, y_pred, c='blue', alpha=0.6)
plt.plot([y_test.min(), y_test.max()], [y_test.min(), y_test.max()], 'r--')  # 绘制对角线

plt.title('Actual vs. Predicted')
plt.xlabel('Actual Values')
plt.ylabel('Predicted Values')
plt.show()

# 计算残差
residuals = y_test - y_pred

# 绘制残差图 
plt.scatter(y_test, residuals)
plt.axhline(y=0, color='r', linestyle='--')
plt.xlabel('Actual Values')
plt.ylabel('Residuals')
plt.title('Residual Plot')

在这里插入图片描述

可以看时间是比较久的,整体精度更高但是时间较慢,还有便是该算法在面对非常数据能够有着非常良好的效果!比如六个点拟合(带约束)

在这里插入图片描述

						  🤞到这里,如果还有什么疑问🤞
					🎩欢迎私信博主问题哦,博主会尽自己能力为你解答疑惑的!🎩
					 	 🥳如果对你有帮助,你的赞是对博主最大的支持!!🥳

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1073332.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

对自动化测试的一些见解

1、手工测试和自动化测试用例 手工测试用例是针对功能测试人员的,而自动化测试用例是针对自动化测试用例框架或工具的。 1)手工测试用例特点 较好的异常处理能力,能通过人为的逻辑判断校验当前步骤是否正确实现; 人工执行用例具有…

startsWith()方法的使用

startsWith()方法一般用于检测某请求字符串是否以指定的前缀开始的。 例如:服务器要判断某个请求是否合规,首先确定协议,比如http、ftp等,这时,就可以用startsWith()。 startsWith 是则返回true,否则返回…

css自学框架之面板

面板是我们开发中经常用到,也就是页面版面中一块一块的板块,效果如下图: 一、css代码 .myth-panel {background-color: var(--white);border: solid 1px transparent;}.myth-panel .myth-panel-header {border-bottom: solid 1px transpar…

一种重要的天然氨基酸L-Homopropargylglycine(HPG)|CAS:942518-19-6

产品简介:L-Homopropargylglycine是一种重要的天然氨基酸,具有多种生物活性和医学应用价值。它广泛应用于生物学、药学、化学等多个领域。在生物学中,HPG被用作蛋白质合成的标记物,可以通过其特殊的化学反应与蛋白质中的半胱氨酸残…

使用HHDBCS管理MongoDB

1 连接MongoDB 打开HHDBCS,在数据库类型中选择mongodb,填入相关信息,点击“登陆”即可。 也可以使用SSH通道进行登陆。 2 命令窗口 点击命令窗口,可以对数据库发出指令。 可以根据个人习惯,对命令窗口进行设置…

基于springboot实现自习室预订系统的设计与实现项目【项目源码+论文说明】

基于springboot实现自习室预订系统的设计与实现演示 摘要 在网络高速发展的时代,众多的软件被开发出来,给学生带来了很大的选择余地,而且人们越来越追求更个性的需求。在这种时代背景下,学院只能以学生为导向,所以自习…

verdi显示OVM/UVM Hierarchy View

verdi显示OVM/UVM Hierarchy View 背景 使用vcsverdiUVM进行UVM debug的时候,verdi加载的时候看不到UVM树形结构图 解决办法 simv UVM_VERDI_TRACE“UVM_AWAREHIER” -guiverdi 2023-10-9 打开界面后,并不会直接显示树形层级 需要先仿真一定时间&#x…

工资「喂饱肚子」,副业「养活灵魂」!职场人的生存之道

文章目录 工资:生计的基础1. 收入局限性2. 缺乏多样性3. 有限的时间投入 副业:充实生活的机会1. 增加收入2. 提升技能3. 追求兴趣4. 增强创造力5. 实现梦想 如何找到适合的副业?1. 确定兴趣和技能2. 市场需求3. 时间和资源4. 资金投入5. 建立…

vue elementui <el-date-picker>日期选择框限制只能选择90天内的日期(包括今天)

之前也写过其他限制日期的语句,感觉用dayjs()的subtract()和add()也挺方便易懂的,以此记录 安装dayjs npm install dayjs --save dayjs().add(value : Number, unit : String); dayjs().add(7, day); //在当前的基础上加7天dayjs().subtract(value : N…

ElasticSearch搜索引擎常见面试题总结

一、ElasticSearch基础: 1、什么是Elasticsearch: Elasticsearch 是基于 Lucene 的 Restful 的分布式实时全文搜索引擎,每个字段都被索引并可被搜索,可以快速存储、搜索、分析海量的数据。全文检索是指对每一个词建立一个索引&am…

“微信多账号聚合聊天:轻松管理,高效沟通“

一、什么是微信多账号聚合聊天? 微信多账号聚合聊天,顾名思义,就是将多个微信账号聚合在一个聊天窗口中进行管理,实现一键切换,快速沟通。这不仅省去了频繁切换微信账号的麻烦,还提高了沟通效率。 二、微…

可拓展的低代码全栈框架

尽管现在越来越多的人开始对低代码开发感兴趣,但已有低代码方案的局限性仍然让大家有所保留。其中最常见的担忧莫过于低代码缺乏灵活性以及容易被厂商锁定。 显然这样的担忧是合理的,因为大家都不希望在实现特定功能的时候才发现低代码平台无法支持&…

竞赛 深度学习 python opencv 火焰检测识别

文章目录 0 前言1 基于YOLO的火焰检测与识别2 课题背景3 卷积神经网络3.1 卷积层3.2 池化层3.3 激活函数:3.4 全连接层3.5 使用tensorflow中keras模块实现卷积神经网络 4 YOLOV54.1 网络架构图4.2 输入端4.3 基准网络4.4 Neck网络4.5 Head输出层 5 数据集准备5.1 数…

.NET ABP.Zero 项目疑似内存排查历程

当前项目是 .NET 5 EentityFrameworkCore,疑似内存泄漏,之所以说是疑似是因为到目前位置还没有能准确的定位到问题。当前这个框架从 .NET Core 2.1 就开始用,期间有升级到 3.1、5.0、6.0,在排查过程中还把 5.0 分支升级到了 7.0 。…

NanoPC-T4 RK3399:移植U-Boot

一:启动流程 瑞芯微平台目前支持两种启动方式,本系列只针对完全开源方式做详细讲解: 1、完全开源方式:使用 U-Boot TPL/SPL,源码可来自主流U-boot开源代码或瑞芯微SDK(在主流源码上做针对性优化) 2、不开源方式:使用rockchip idbloader,由rockchip ddr init bin和min…

delphi调用edge的截图功能

一、设置edge中截图的快捷键。 二、代码: constVK_CONTROL $11;VK_4 $34;procedure SendCtrl4ToDesktopVirtualKeyboard; begin// 模拟Ctrl键按下keybd_event(VK_CONTROL, 0, 0, 0);// 模拟4键按下keybd_event(VK_4, 0, 0, 0);// 模拟4键释放keybd_event(VK_4, 0…

JVM监控及诊断工具-GUI篇

文章目录 JVM监控及诊断工具-GUI篇工具概述JConsoleVisual VM再谈内存泄漏Java中内存泄漏的8种情况Arthas(阿尔萨斯) JVM监控及诊断工具-GUI篇 工具概述 使用上一章命令行工具或组合能获取目标Java应用性能相关的基础信息,但它们存在下列局…

JavaScript入门——基础知识(4)

一、for语句 1.1 for语句的基本使用 1.1.1 for循环语法 作用&#xff1a;重复执行代码 好处&#xff1a;把声明起始值、循环条件、变化值写到一起&#xff0c;让人一目了然&#xff0c;它是最常使用的循环形式 for(变量起始值;终止条件;变量变化量){// 循环体 } <script&g…

gici-open示例数据运行(ground_truth坐标的转换)

1. 坐标系转换说明 涉及的两个坐标转换&#xff1a; nmea_pose_to_pose &#xff1a;激光IMU中心到数据集IMU中心&#xff0c;主要是杆臂误差&#xff0c;转换关系为&#xff1a; //坐标转换的主要步骤(若发现有错误的地方&#xff0c;请评论指出) //定义激光IMU和数据集IMU之…

springboot项目做成公共项目

一&#xff1a;引言 最近碰到个需求&#xff0c;就是把我项目做成一个公共的提供jar包给别人使用&#xff0c;我也是捣鼓了一段时间去研究这个问题&#xff0c;这个东西其实就是A 项目提供jar包给B项目&#xff0c;B项目只要引入A项目的jar包就可以使用A项目的功能。 问题一&…