Python调用实现最小二乘法的方法详解
作者:微小冷 发布时间:2022-07-04 16:31:00
所谓线性最小二乘法,可以理解为是解方程的延续,区别在于,当未知量远小于方程数的时候,将得到一个无解的问题。最小二乘法的实质,是保证误差最小的情况下对未知数进行赋值。
最小二乘法是非常经典的算法,而且这个名字我们在高中的时候就已经接触了,属于极其常用的算法。此前曾经写过线性最小二乘法的原理,并用Python实现:最小二乘法及其Python实现;以及scipy中非线性最小二乘法的调用方式:非线性最小二乘法(文末补充内容);还有稀疏矩阵的最小二乘法:稀疏矩阵最小二乘法。
下面讲对numpy和scipy中实现的线性最小二乘法进行说明,并比较二者的速度。
numpy实现
numpy中便实现了最小二乘法,即lstsq(a,b)用于求解类似于a@x=b中的x,其中,a为M×N的矩阵;则当b为M行的向量时,刚好相当于求解线性方程组。对于Ax=b这样的方程组,如果A是满秩仿真,那么可以表示为x=A−1b,否则可以表示为x=(ATA)−1ATb。
当b为M×K的矩阵时,则对每一列,都会计算一组x。
其返回值共有4个,分别是拟合得到的x、拟合误差、矩阵a的秩、以及矩阵a的单值形式。
import numpy as np
np.random.seed(42)
M = np.random.rand(4,4)
x = np.arange(4)
y = M@x
xhat = np.linalg.lstsq(M,y)
print(xhat[0])
#[0. 1. 2. 3.]
scipy封装
scipy.linalg同样提供了最小二乘法函数,函数名同样是lstsq,其参数列表为
lstsq(a, b, cond=None, overwrite_a=False, overwrite_b=False, check_finite=True, lapack_driver=None)
其中a, b即Ax=b,二者均提供可覆写开关,设为True可以节省运行时间,此外,函数也支持有限性检查,这是linalg中许多函数都具备的选项。其返回值与numpy中的最小二乘函数相同。
cond为浮点型参数,表示奇异值阈值,当奇异值小于cond时将舍弃。
lapack_driver为字符串选项,表示选用何种LAPACK中的算法引擎,可选'gelsd', 'gelsy', 'gelss'。
import scipy.linalg as sl
xhat1 = sl.lstsq(M, y)
print(xhat1[0])
# [0. 1. 2. 3.]
速度对比
最后,对着两组最小二乘函数做一个速度上的对比
from timeit import timeit
N = 100
A = np.random.rand(N,N)
b = np.arange(N)
timeit(lambda:np.linalg.lstsq(A, b), number=10)
# 0.015487500000745058
timeit(lambda:sl.lstsq(A, b), number=10)
# 0.011151800004881807
这一次,二者并没有拉开太大的差距,即使将矩阵维度放大到500,二者也是半斤八两。
N = 500
A = np.random.rand(N,N)
b = np.arange(N)
timeit(lambda:np.linalg.lstsq(A, b), number=10)
0.389679799991427
timeit(lambda:sl.lstsq(A, b), number=10)
0.35642060000100173
补充
Python调用非线性最小二乘法
简介与构造函数
在scipy中,非线性最小二乘法的目的是找到一组函数,使得误差函数的平方和最小,可以表示为如下公式
其中ρ表示损失函数,可以理解为对fi(x)的一次预处理。
scipy.optimize中封装了非线性最小二乘法函数least_squares,其定义为
least_squares(fun, x0, jac, bounds, method, ftol, xtol, gtol, x_scale, f_scale, loss, jac_sparsity, max_nfev, verbose, args, kwargs)
其中,func和x0为必选参数,func为待求解函数,x0为函数输入的初值,这两者无默认值,为必须输入的参数。
bound为求解区间,默认(−∞,∞),verbose为1时,会有终止输出,为2时会print更多的运算过程中的信息。此外下面几个参数用于控制误差,比较简单。
默认值 | 备注 | |
---|---|---|
ftol | 10-8 | 函数容忍度 |
xtol | 10-8 | 自变量容忍度 |
gtol | 10-8 | 梯度容忍度 |
x_scale | 1.0 | 变量的特征尺度 |
f_scale | 1.0 | 残差边际值 |
loss
为损失函数,就是上面公式中的ρ \rhoρ,默认为linear
,可选值包括
迭代策略
上面的公式仅给出了算法的目的,但并未暴露其细节。关于如何找到最小值,则需要确定搜索最小值的方法,method为最小值搜索的方案,共有三种选项,默认为trf
trf:即Trust Region Reflective,信赖域反射算法
dogbox:信赖域狗腿算法
lm:Levenberg-Marquardt算法
这三种方法都是信赖域方法的延申,信赖域的优化思想其实就是从单点的迭代变成了区间的迭代,由于本文的目的是介绍scipy中所封装好的非线性最小二乘函数,故而仅对其原理做简略的介绍。
其中r为置信半径,假设在这个邻域内,目标函数可以近似为线性或二次函数,则可通过二次模型得到区间中的极小值点sk。然后以这个极小值点为中心,继续优化信赖域所对应的区间。
来源:https://blog.csdn.net/m0_37816922/article/details/129845786


猜你喜欢
- 接触 Python 不久,看到很多人写2048,自己也捣鼓了一个,主要是熟悉Python语法。程序使用Python3 写的,代码150行左右
- smtp是直接调用163邮箱的smtp服务器,需要在163邮箱中设置一下。outlook发送就是Python直接调用win32方式。调用程序
- 1. os.listdir()概述os.listdir() 方法用于返回指定的文件夹包含的文件或文件夹的名字的列表。例如:dir ='
- '************************************* '读取文件 &
- 一、模块TypeScript 与ECMAScript 2015 一样,任何包含顶级 import 或
- 本文较为详细的介绍了python中raw_input的用法,使用raw_input 能够很方便的丛控制台读入数据。具体用法示例如下:1.输入
- 1. 简介在 Go 语言中,new 和 make 是用于创建对象的两个内建函数,它们的使用方式和作用有所不同。正确理解 new 和 make
- 语法JavaScript的语法和Java语言类似,每个语句以;结束,语句块用{...}。但是,JavaScript并不强制要求在每个语句的结
- 关于电子邮件 大学之前,基本不用邮箱,所以基本感觉不到它的存在,也不知道有什么用;然而大学之后,随着认识的人越来越多,知识越来越广
- Laravel 的上一个 LTS(长期支持)版本是 Laravel 5.1,发布于 2015 年 6 月,按照对 LTS 版本的约定,两年的
- 1、XML 是什么?XML仅仅是一种数据存放格式,这种格式是一种文本(虽然XML规范中也提供了存放二进制数据的解决方案)。事实上有很多文本格
- 笔者日积月累了许多精彩、实用的Web特效的制作,这些特效几乎都是比较常用的网页特效。现在我就把这些经过
- 1 数据准备1.1 新建数据表CREATE TABLE `player` ( `id` bigint(20) NOT NULL
- 我就废话不多说了,大家还是直接看代码吧~from keras.applications.vgg16 import VGG16#直接导入已经训
- 包 packageGo 包是 Go 语言的基本组成单元,一个 Go 程序就是一组包的集合,所有 Go 代码都位于包中Go 源码可以导入其他
- <script type="text/vbscript">
- 本文实例讲述了Python实现对不原生支持比较操作的对象排序算法。分享给大家供大家参考,具体如下:问题:想在同一个类的实例之间做排序,但是它
- 方法一:登录MySQL,先做 set names latin1 ,然后在更新语句或者执行SQL语句mysql> set names l
- 本文为大家分享了mysql 8.0.15 安装配置图文教程,供大家参考,具体内容如下1.进官网,选择适合自己版本的linux下的MYSQL版
- 今天运行程序时报了SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSess