当前位置:首页 » 编程语言 » python最小二乘

python最小二乘

发布时间: 2022-10-28 10:59:03

‘壹’ python中如何使用最小二乘法

##最小二乘法
importnumpyasnp##科学计算库
importscipyassp##在numpy基础上实现的部分算法
importmatplotlib.pyplotasplt##绘图库
fromscipy.optimizeimportleastsq##引入最小二乘法算法

'''
设置样本数据,真实数据需要在这里处理
'''
##样本数据(Xi,Yi),需要转换成数组(列表)形式
Xi=np.array([6.19,2.51,7.29,7.01,5.7,2.66,3.98,2.5,9.1,4.2])
Yi=np.array([5.25,2.83,6.41,6.71,5.1,4.23,5.05,1.98,10.5,6.3])

'''
设定拟合函数和偏差函数
函数的形状确定过程:
1.先画样本图像
2.根据样本图像大致形状确定函数形式(直线、抛物线、正弦余弦等)
'''

##需要拟合的函数func:指定函数的形状
deffunc(p,x):
k,b=p
returnk*x+b

##偏差函数:x,y都是列表:这里的x,y更上面的Xi,Yi中是一一对应的
deferror(p,x,y):
returnfunc(p,x)-y

'''
主要部分:附带部分说明
1.leastsq函数的返回值tuple,第一个元素是求解结果,第二个是求解的代价值(个人理解)
2.官网的原话(第二个值):
3.实例:Para=>(array([0.61349535,1.79409255]),3)
4.返回值元组中第一个值的数量跟需要求解的参数的数量一致
'''

#k,b的初始值,可以任意设定,经过几次试验,发现p0的值会影响cost的值:Para[1]
p0=[1,20]

#把error函数中除了p0以外的参数打包到args中(使用要求)
Para=leastsq(error,p0,args=(Xi,Yi))

#读取结果
k,b=Para[0]
print("k=",k,"b=",b)
print("cost:"+str(Para[1]))
print("求解的拟合直线为:")
print("y="+str(round(k,2))+"x+"+str(round(b,2)))

'''
绘图,看拟合效果.
matplotlib默认不支持中文,label设置中文的话需要另行设置
如果报错,改成英文就可以
'''

#画样本点
plt.figure(figsize=(8,6))##指定图像比例:8:6
plt.scatter(Xi,Yi,color="green",label="样本数据",linewidth=2)

#画拟合直线
x=np.linspace(0,12,100)##在0-15直接画100个连续点
y=k*x+b##函数式
plt.plot(x,y,color="red",label="拟合直线",linewidth=2)
plt.legend(loc='lowerright')#绘制图例
plt.show()

‘贰’ 如何应用最小二乘法进行实验曲线拟合

打开Excel,先将数据绘成线性图,然后在图表中添加趋势线,然后勾选:显示公式,就可以拟合出数据的公式了。

‘叁’ 如何用python实现含有虚拟自变量的回归



参考资料:
DataRobot | Ordinary Least Squares in Python

DataRoboe | Multiple Regression using Statsmodels

AnalyticsVidhya | 7 Types of Regression Techniques you should know!



‘肆’ Python怎么做最优化

一、概观scipy中的optimize子包中提供了常用的最优化算法函数实现。我们可以直接调用这些函数完成我们的优化问题。optimize中函数最典型的特点就是能够从函数名称上看出是使用了什么算法。下面optimize包中函数的概览:1.非线性最优化fmin -- 简单Nelder-Mead算法fmin_powell -- 改进型Powell法fmin_bfgs -- 拟Newton法fmin_cg -- 非线性共轭梯度法fmin_ncg -- 线性搜索Newton共轭梯度法leastsq -- 最小二乘2.有约束的多元函数问题fmin_l_bfgs_b ---使用L-BFGS-B算法fmin_tnc ---梯度信息fmin_cobyla ---线性逼近fmin_slsqp ---序列最小二乘法nnls ---解|| Ax - b ||_2 for x=03.全局优化anneal ---模拟退火算法brute --强力法4.标量函数fminboundbrentgoldenbracket5.拟合curve_fit-- 使用非线性最小二乘法拟合6.标量函数求根brentq ---classic Brent (1973)brenth ---A variation on the classic Brent(1980)ridder ---Ridder是提出这个算法的人名bisect ---二分法newton ---牛顿法fixed_point7.多维函数求根fsolve ---通用broyden1 ---Broyden’s first Jacobian approximation.broyden2 ---Broyden’s second Jacobian approximationnewton_krylov ---Krylov approximation for inverse Jacobiananderson ---extended Anderson mixingexcitingmixing ---tuned diagonal Jacobian approximationlinearmixing ---scalar Jacobian approximationdiagbroyden ---diagonal Broyden Jacobian approximation8.实用函数line_search ---找到满足强Wolfe的alpha值check_grad ---通过和前向有限差分逼近比较检查梯度函数的正确性二、实战非线性最优化fmin完整的调用形式是:fmin(func, x0, args=(), xtol=0.0001, ftol=0.0001, maxiter=None, maxfun=None, full_output=0, disp=1, retall=0, callback=None)不过我们最常使用的就是前两个参数。一个描述优化问题的函数以及初值。后面的那些参数我们也很容易理解。如果您能用到,请自己研究。下面研究一个最简单的问题,来感受这个函数的使用方法:f(x)=x**2-4*x+8,我们知道,这个函数的最小值是4,在x=2的时候取到。from scipy.optimize import fmin #引入优化包def myfunc(x):return x**2-4*x+8 #定义函数x0 = [1.3] #猜一个初值xopt = fmin(myfunc, x0) #求解print xopt #打印结果运行之后,给出的结果是:Optimization terminated successfully.Current function value: 4.000000Iterations: 16Function evaluations: 32[ 2.00001953]程序准确的计算得出了最小值,不过最小值点并不是严格的2,这应该是由二进制机器编码误差造成的。除了fmin_ncg必须提供梯度信息外,其他几个函数的调用大同小异,完全类似。我们不妨做一个对比:from scipy.optimize import fmin,fmin_powell,fmin_bfgs,fmin_cgdef myfunc(x):return x**2-4*x+8x0 = [1.3]xopt1 = fmin(myfunc, x0)print xopt1printxopt2 = fmin_powell(myfunc, x0)print xopt2printxopt3 = fmin_bfgs(myfunc, x0)print xopt3printxopt4 = fmin_cg(myfunc,x0)print xopt4给出的结果是:Optimization terminated successfully.Current function value: 4.000000Iterations: 16Function evaluations: 32[ 2.00001953]Optimization terminated successfully.Current function value: 4.000000Iterations: 2Function evaluations: 531.99999999997Optimization terminated successfully.Current function value: 4.000000Iterations: 2Function evaluations: 12Gradient evaluations: 4[ 2.00000001]Optimization terminated successfully.Current function value: 4.000000Iterations: 2Function evaluations: 15Gradient evaluations: 5[ 2.]我们可以根据给出的消息直观的判断算法的执行情况。每一种算法数学上的问题,请自己看书学习。个人感觉,如果不是纯研究数学的工作,没必要搞清楚那些推导以及定理云云。不过,必须了解每一种算法的优劣以及能力所及。在使用的时候,不妨多种算法都使用一下,看看效果分别如何,同时,还可以互相印证算法失效的问题。在from scipy.optimize import fmin之后,就可以使用help(fmin)来查看fmin的帮助信息了。帮助信息中没有例子,但是给出了每一个参数的含义说明,这是调用函数时候的最有价值参考。有源码研究癖好的,或者当你需要改进这些已经实现的算法的时候,可能需要查看optimize中的每种算法的源代码。在这里:https:/ / github. com/scipy/scipy/blob/master/scipy/optimize/optimize.py聪明的你肯定发现了,顺着这个链接往上一级、再往上一级,你会找到scipy的几乎所有源码!

‘伍’ python里面多元非线性回归有哪些方法

SciPy 里面的子函数库optimize, 一般情况下可用curve_fit函数直接拟合或者leastsq做最小二乘

‘陆’ Python怎么做最优化

一、概观
scipy中的optimize子包中提供了常用的最优化算法函数实现。我们可以直接调用这些函数完成我们的优化问题。optimize中函数最典型的特点就是能够从函数名称上看出是使用了什么算法。下面optimize包中函数的概览:
1.非线性最优化
fmin -- 简单Nelder-Mead算法
fmin_powell -- 改进型Powell法
fmin_bfgs -- 拟Newton法
fmin_cg -- 非线性共轭梯度法
fmin_ncg -- 线性搜索Newton共轭梯度法
leastsq -- 最小二乘
2.有约束的多元函数问题
fmin_l_bfgs_b ---使用L-BFGS-B算法
fmin_tnc ---梯度信息
fmin_cobyla ---线性逼近
fmin_slsqp ---序列最小二乘法
nnls ---解|| Ax - b ||_2 for x>=0
3.全局优化
anneal ---模拟退火算法
brute --强力法
4.标量函数
fminbound
brent
golden
bracket
5.拟合
curve_fit-- 使用非线性最小二乘法拟合
6.标量函数求根
brentq ---classic Brent (1973)
brenth ---A variation on the classic Brent(1980)ridder ---Ridder是提出这个算法的人名
bisect ---二分法
newton ---牛顿法
fixed_point
7.多维函数求根
fsolve ---通用
broyden1 ---Broyden’s first Jacobian approximation.
broyden2 ---Broyden’s second Jacobian approximationnewton_krylov ---Krylov approximation for inverse Jacobiananderson ---extended Anderson mixing
excitingmixing ---tuned diagonal Jacobian approximationlinearmixing ---scalar Jacobian approximationdiagbroyden ---diagonal Broyden Jacobian approximation8.实用函数
line_search ---找到满足强Wolfe的alpha值
check_grad ---通过和前向有限差分逼近比较检查梯度函数的正确性二、实战非线性最优化
fmin完整的调用形式是:
fmin(func, x0, args=(), xtol=0.0001, ftol=0.0001, maxiter=None, maxfun=None, full_output=0, disp=1, retall=0, callback=None)不过我们最常使用的就是前两个参数。一个描述优化问题的函数以及初值。后面的那些参数我们也很容易理解。如果您能用到,请自己研究。下面研究一个最简单的问题,来感受这个函数的使用方法:f(x)=x**2-4*x+8,我们知道,这个函数的最小值是4,在x=2的时候取到。
from scipy.optimize import fmin #引入优化包def myfunc(x):
return x**2-4*x+8 #定义函数
x0 = [1.3] #猜一个初值
xopt = fmin(myfunc, x0) #求解
print xopt #打印结果
运行之后,给出的结果是:
Optimization terminated successfully.
Current function value: 4.000000
Iterations: 16
Function evaluations: 32
[ 2.00001953]
程序准确的计算得出了最小值,不过最小值点并不是严格的2,这应该是由二进制机器编码误差造成的。
除了fmin_ncg必须提供梯度信息外,其他几个函数的调用大同小异,完全类似。我们不妨做一个对比:
from scipy.optimize import fmin,fmin_powell,fmin_bfgs,fmin_cgdef myfunc(x):
return x**2-4*x+8
x0 = [1.3]
xopt1 = fmin(myfunc, x0)
print xopt1
print
xopt2 = fmin_powell(myfunc, x0)
print xopt2
print
xopt3 = fmin_bfgs(myfunc, x0)
print xopt3
print
xopt4 = fmin_cg(myfunc,x0)
print xopt4
给出的结果是:
Optimization terminated successfully.
Current function value: 4.000000
Iterations: 16
Function evaluations: 32
[ 2.00001953]
Optimization terminated successfully.
Current function value: 4.000000
Iterations: 2
Function evaluations: 53
1.99999999997
Optimization terminated successfully.
Current function value: 4.000000
Iterations: 2
Function evaluations: 12
Gradient evaluations: 4
[ 2.00000001]
Optimization terminated successfully.
Current function value: 4.000000
Iterations: 2
Function evaluations: 15
Gradient evaluations: 5
[ 2.]
我们可以根据给出的消息直观的判断算法的执行情况。每一种算法数学上的问题,请自己看书学习。个人感觉,如果不是纯研究数学的工作,没必要搞清楚那些推导以及定理云云。不过,必须了解每一种算法的优劣以及能力所及。在使用的时候,不妨多种算法都使用一下,看看效果分别如何,同时,还可以互相印证算法失效的问题。
在from scipy.optimize import fmin之后,就可以使用help(fmin)来查看fmin的帮助信息了。帮助信息中没有例子,但是给出了每一个参数的含义说明,这是调用函数时候的最有价值参考。
有源码研究癖好的,或者当你需要改进这些已经实现的算法的时候,可能需要查看optimize中的每种算法的源代码。在这里:https:/ / github. com/scipy/scipy/blob/master/scipy/optimize/optimize.py聪明的你肯定发现了,顺着这个链接往上一级、再往上一级,你会找到scipy的几乎所有源码!

‘柒’ 怎么用Python将图像边界用最小二乘法拟合成曲线

本文实例讲述了Python基于最小二乘法实现曲线拟合。分享给大家供大家参考,具体如下:

这里不手动实现最小二乘,调用scipy库中实现好的相关优化函数。

考虑如下的含有4个参数的函数式:

希望本文所述对大家Python程序设计有所帮助。

‘捌’ Python 怎么用曲线拟合数据

Python中利用guiqwt进行曲线数据拟合。

示例程序:

‘玖’ 强烈推荐一款Python可视化神器!强烈必备!

Plotly Express 是一个新的高级 Python 可视化库:它是 Plotly.py 的高级封装,它为复杂的图表提供了一个简单的语法。

受 Seaborn 和 ggplot2 的启发,它专门设计为具有简洁,一致且易于学习的 API :只需一次导入,您就可以在一个函数调用中创建丰富的交互式绘图,包括分面绘图(faceting)、地图、动画和趋势线。 它带有数据集、颜色面板和主题,就像 Plotly.py 一样。

Plotly Express 完全免费:凭借其宽松的开源 MIT 许可证,您可以随意使用它(是的,甚至在商业产品中!)。

最重要的是,Plotly Express 与 Plotly 生态系统的其他部分完全兼容:在您的 Dash 应用程序中使用它,使用 Orca 将您的数据导出为几乎任何文件格式,或使用JupyterLab 图表编辑器在 GUI 中编辑它们!

用 pip install plotly_express 命令可以安装 Plotly Express。

一旦导入Plotly Express(通常是 px ),大多数绘图只需要一个函数调用,接受一个整洁的Pandas dataframe,并简单描述你想要制作的图。 如果你想要一个基本的散点图,它只是 px.scatter(data,x =“column_name”,y =“column_name”)。

以下是内置的 Gapminder 数据集的示例,显示2007年按国家/地区的人均预期寿命和人均GDP 之间的趋势:

如果你想通过大陆区分它们,你可以使用 color 参数为你的点着色,由 px 负责设置默认颜色,设置图例等:

这里的每一点都是一个国家,所以也许我们想要按国家人口来衡量这些点...... 没问题:这里也有一个参数来设置,它被称为 size:

如果你好奇哪个国家对应哪个点? 可以添加一个 hover_name ,您可以轻松识别任何一点:只需将鼠标放在您感兴趣的点上即可! 事实上,即使没有 hover_name ,整个图表也是互动的:

也可以通过 facet_col =”continent“ 来轻松划分各大洲,就像着色点一样容易,并且让我们使用 x轴 对数(log_x)以便在我们在图表中看的更清晰:

也许你不仅仅对 2007年 感兴趣,而且你想看看这张图表是如何随着时间的推移而演变的。 可以通过设置 animation_frame=“year” (以及 animation_group =“country” 来标识哪些圆与控制条中的年份匹配)来设置动画。

在这个最终版本中,让我们在这里调整一些显示,因为像“gdpPercap” 这样的文本有点难看,即使它是我们的数据框列的名称。 我们可以提供更漂亮的“标签” (labels),可以在整个图表、图例、标题轴和悬停(hovers)中应用。 我们还可以手动设置边界,以便动画在整个过程中看起来更棒:

因为这是地理数据,我们也可以将其表示为动画地图,因此这清楚地表明 Plotly Express 不仅仅可以绘制散点图(不过这个数据集缺少前苏联的数据)。

事实上,Plotly Express 支持三维散点图、三维线形图、极坐标和地图上三元坐标以及二维坐标。 条形图(Bar)有二维笛卡尔和极坐标风格。

进行可视化时,您可以使用单变量设置中的直方图(histograms)和箱形图(box)或小提琴图(violin plots),或双变量分布的密度等高线图(density contours)。 大多数二维笛卡尔图接受连续或分类数据,并自动处理日期/时间数据。 可以查看我们的图库 (ref-3) 来了解每个图表的例子。

数据 探索 的主要部分是理解数据集中值的分布,以及这些分布如何相互关联。 Plotly Express 有许多功能来处理这些任务。

使用直方图(histograms),箱形图(box)或小提琴图(violin plots)可视化单变量分布:

直方图:

箱形图:

小提琴图:

还可以创建联合分布图(marginal rugs),使用直方图,箱形图(box)或小提琴来显示双变量分布,也可以添加趋势线。 Plotly Express 甚至可以帮助你在悬停框中添加线条公式和R²值! 它使用 statsmodels 进行普通最小二乘(OLS)回归或局部加权散点图平滑(LOWESS)。

在上面的一些图中你会注意到一些不错的色标。 在 Plotly Express 中, px.colors 模块包含许多有用的色标和序列:定性的、序列型的、离散的、循环的以及所有您喜欢的开源包:ColorBrewer、cmocean 和 Carto 。 我们还提供了一些功能来制作可浏览的样本供您欣赏(ref-3):

定性的颜色序列:

众多内置顺序色标中的一部分:

我们特别为我们的交互式多维图表感到自豪,例如散点图矩阵(SPLOMS)、平行坐标和我们称之为并行类别的并行集。 通过这些,您可以在单个图中可视化整个数据集以进行数据 探索 。 在你的Jupyter 笔记本中查看这些单行及其启用的交互:

散点图矩阵(SPLOM)允许您可视化多个链接的散点图:数据集中的每个变量与其他变量的关系。 数据集中的每一行都显示为每个图中的一个点。 你可以进行缩放、平移或选择操作,你会发现所有图都链接在一起!

平行坐标允许您同时显示3个以上的连续变量。 dataframe 中的每一行都是一行。 您可以拖动尺寸以重新排序它们并选择值范围之间的交叉点。

并行类别是并行坐标的分类模拟:使用它们可视化数据集中多组类别之间的关系。

Plotly Express 之于 Plotly.py 类似 Seaborn 之于 matplotlib:Plotly Express 是一个高级封装库,允许您快速创建图表,然后使用底层 API 和生态系统的强大功能进行修改。 对于Plotly 生态系统,这意味着一旦您使用 Plotly Express 创建了一个图形,您就可以使用Themes,使用 FigureWidgets 进行命令性编辑,使用 Orca 将其导出为几乎任何文件格式,或者在我们的 GUI JupyterLab 图表编辑器中编辑它 。

主题(Themes)允许您控制图形范围的设置,如边距、字体、背景颜色、刻度定位等。 您可以使用模板参数应用任何命名的主题或主题对象:

有三个内置的 Plotly 主题可以使用, 分别是 plotly, plotlywhite 和 plotlydark。

px 输出继承自 Plotly.py 的 Figure 类 ExpressFigure 的对象,这意味着你可以使用任何 Figure 的访问器和方法来改变 px生成的绘图。 例如,您可以将 .update() 调用链接到 px 调用以更改图例设置并添加注释。 .update() 现在返回修改后的数字,所以你仍然可以在一个很长的 Python 语句中执行此操作:

在这里,在使用 Plotly Express 生成原始图形之后,我们使用 Plotly.py 的 API 来更改一些图例设置并添加注释。

Dash 是 Plotly 的开源框架,用于构建具有 Plotly.py 图表的分析应用程序和仪表板。Plotly Express 产生的对象与 Dash 100%兼容,只需将它们直接传递到 dash_core_components.Graph,如下所示: dcc.Graph(figure = px.scatter(...))。 这是一个非常简单的 50行 Dash 应用程序的示例,它使用 px 生成其中的图表:

这个 50 行的 Dash 应用程序使用 Plotly Express 生成用于浏览数据集的 UI 。

可视化数据有很多原因:有时您想要提供一些想法或结果,并且您希望对图表的每个方面施加很多控制,有时您希望快速查看两个变量之间的关系。 这是交互与 探索 的范畴。

Plotly.py 已经发展成为一个非常强大的可视化交互工具:它可以让你控制图形的几乎每个方面,从图例的位置到刻度的长度。 不幸的是,这种控制的代价是冗长的:有时可能需要多行 Python 代码才能用 Plotly.py 生成图表。

我们使用 Plotly Express 的主要目标是使 Plotly.py 更容易用于 探索 和快速迭代。

我们想要构建一个库,它做出了不同的权衡:在可视化过程的早期牺牲一些控制措施来换取一个不那么详细的 API,允许你在一行 Python 代码中制作各种各样的图表。 然而,正如我们上面所示,该控件并没有消失:你仍然可以使用底层的 Plotly.py 的 API 来调整和优化用 Plotly Express 制作的图表。

支持这种简洁 API 的主要设计决策之一是所有 Plotly Express 的函数都接受“整洁”的 dataframe 作为输入。 每个 Plotly Express 函数都体现了dataframe 中行与单个或分组标记的清晰映射,并具有图形启发的语法签名,可让您直接映射这些标记的变量,如 x 或 y 位置、颜色、大小、 facet-column 甚至是 动画帧到数据框(dataframe)中的列。 当您键入 px.scatter(data,x ='col1',y='col2') 时,Plotly Express 会为数据框中的每一行创建一个小符号标记 - 这就是 px.scatter 的作用 - 并将 “col1” 映射到 x 位置(类似于 y 位置)。 这种方法的强大之处在于它以相同的方式处理所有可视化变量:您可以将数据框列映射到颜色,然后通过更改参数来改变您的想法并将其映射到大小或进行行分面(facet-row)。

接受整个整洁的 dataframe 的列名作为输入(而不是原始的 numpy 向量)也允许 px 为你节省大量的时间,因为它知道列的名称,它可以生成所有的 Plotly.py 配置用于标记图例、轴、悬停框、构面甚至动画帧。 但是,如上所述,如果你的 dataframe 的列被笨拙地命名,你可以告诉 px 用每个函数的 labels 参数替换更好的。

仅接受整洁输入所带来的最终优势是它更直接地支持快速迭代:您整理一次数据集,从那里可以使用 px 创建数十种不同类型的图表,包括在 SPLOM 中可视化多个维度 、使用平行坐标、在地图上绘制,在二维、三维极坐标或三维坐标中使用等,所有这些都不需要重塑您的数据!

在 API 级别,我们在 px 中投入了大量的工作,以确保所有参数都被命名,以便在键入时最大限度地发现:所有 scatter -类似的函数都以 scatter 开头(例如 scatter_polar, scatter_ternary)所以你可以通过自动补全来发现它们。 我们选择拆分这些不同的散点图函数,因此每个散点图函数都会接受一组定制的关键字参数,特别是它们的坐标系。 也就是说,共享坐标系的函数集(例如 scatter, line & bar,或 scatter_polar, line_polar 和 bar_polar )也有相同的参数,以最大限度地方便学习。 我们还花了很多精力来提出简短而富有表现力的名称,这些名称很好地映射到底层的 Plotly.py 属性,以便于在工作流程中稍后调整到交互的图表中。

最后,Plotly Express 作为一个新的 Python 可视化库,在 Plotly 生态系统下,将会迅速发展。所以不要犹豫,立即开始使用 Plotly Express 吧!

‘拾’ Python怎么做最优化

最优化
为什么要做最优化呢?因为在生活中,人们总是希望幸福值或其它达到一个极值,比如做生意时希望成本最小,收入最大,所以在很多商业情境中,都会遇到求极值的情况。
函数求根
这里“函数的根”也称“方程的根”,或“函数的零点”。
先把我们需要的包加载进来。import numpy as npimport scipy as spimport scipy.optimize as optimport matplotlib.pyplot as plt%matplotlib inline
函数求根和最优化的关系?什么时候函数是最小值或最大值?
两个问题一起回答:最优化就是求函数的最小值或最大值,同时也是极值,在求一个函数最小值或最大值时,它所在的位置肯定是导数为 0 的位置,所以要求一个函数的极值,必然要先求导,使其为 0,所以函数求根就是为了得到最大值最小值。
scipy.optimize 有什么方法可以求根?
可以用 scipy.optimize 中的 bisect 或 brentq 求根。f = lambda x: np.cos(x) - x # 定义一个匿名函数x = np.linspace(-5, 5, 1000) # 先生成 1000 个 xy = f(x) # 对应生成 1000 个 f(x)plt.plot(x, y); # 看一下这个函数长什么样子plt.axhline(0, color='k'); # 画一根横线,位置在 y=0

opt.bisect(f, -5, 5) # 求取函数的根0.7390851332155535plt.plot(x, y)plt.axhline(0, color='k')plt.scatter([_], [0], c='r', s=100); # 这里的 [_] 表示上一个 Cell 中的结果,这里是 x 轴上的位置,0 是 y 上的位置

求根有两种方法,除了上面介绍的 bisect,还有 brentq,后者比前者快很多。%timeit opt.bisect(f, -5, 5)%timeit opt.brentq(f, -5, 5)10000 loops, best of 3: 157 s per loopThe slowest run took 11.65 times longer than the fastest. This could mean that an intermediate result is being cached.10000 loops, best of 3: 35.9 s per loop
函数求最小化
求最小值就是一个最优化问题。求最大值时只需对函数做一个转换,比如加一个负号,或者取倒数,就可转成求最小值问题。所以两者是同一问题。
初始值对最优化的影响是什么?
举例来说,先定义个函数。f = lambda x: 1-np.sin(x)/xx = np.linspace(-20., 20., 1000)y = f(x)
当初始值为 3 值,使用 minimize 函数找到最小值。minimize 函数是在新版的 scipy 里,取代了以前的很多最优化函数,是个通用的接口,背后是很多方法在支撑。x0 = 3xmin = opt.minimize(f, x0).x # x0 是起始点,起始点最好离真正的最小值点不要太远plt.plot(x, y)plt.scatter(x0, f(x0), marker='o', s=300); # 起始点画出来,用圆圈表示plt.scatter(xmin, f(xmin), marker='v', s=300); # 最小值点画出来,用三角表示plt.xlim(-20, 20);

初始值为 3 时,成功找到最小值。
现在来看看初始值为 10 时,找到的最小值点。x0 = 10xmin = opt.minimize(f, x0).xplt.plot(x, y)plt.scatter(x0, f(x0), marker='o', s=300)plt.scatter(xmin, f(xmin), marker='v', s=300)plt.xlim(-20, 20);

由上图可见,当初始值为 10 时,函数找到的是局部最小值点,可见 minimize 的默认算法对起始点的依赖性。
那么怎么才能不管初始值在哪个位置,都能找到全局最小值点呢?
如何找到全局最优点?
可以使用 basinhopping 函数找到全局最优点,相关背后算法,可以看帮助文件,有提供论文的索引和出处。
我们设初始值为 10 看是否能找到全局最小值点。x0 = 10from scipy.optimize import basinhoppingxmin = basinhopping(f,x0,stepsize = 5).xplt.plot(x, y);plt.scatter(x0, f(x0), marker='o', s=300);plt.scatter(xmin, f(xmin), marker='v', s=300);plt.xlim(-20, 20);

当起始点在比较远的位置,依然成功找到了全局最小值点。
如何求多元函数最小值?
以二元函数为例,使用 minimize 求对应的最小值。def g(X): x,y = X return (x-1)**4 + 5 * (y-1)**2 - 2*x*yX_opt = opt.minimize(g, (8, 3)).x # (8,3) 是起始点print X_opt[ 1.88292611 1.37658521]fig, ax = plt.subplots(figsize=(6, 4)) # 定义画布和图形x_ = y_ = np.linspace(-1, 4, 100)X, Y = np.meshgrid(x_, y_)c = ax.contour(X, Y, g((X, Y)), 50) # 等高线图ax.plot(X_opt[0], X_opt[1], 'r*', markersize=15) # 最小点的位置是个元组ax.set_xlabel(r"$x_1$", fontsize=18)ax.set_ylabel(r"$x_2$", fontsize=18)plt.colorbar(c, ax=ax) # colorbar 表示颜色越深,高度越高fig.tight_layout()

画3D 图。from mpl_toolkits.mplot3d import Axes3Dfrom matplotlib import cmfig = plt.figure()ax = fig.gca(projection='3d')x_ = y_ = np.linspace(-1, 4, 100)X, Y = np.meshgrid(x_, y_)surf = ax.plot_surface(X, Y, g((X,Y)), rstride=1, cstride=1, cmap=cm.coolwarm, linewidth=0, antialiased=False)cset = ax.contour(X, Y, g((X,Y)), zdir='z',offset=-5, cmap=cm.coolwarm)fig.colorbar(surf, shrink=0.5, aspect=5);

曲线拟合
曲线拟合和最优化有什么关系?
曲线拟合的问题是,给定一组数据,它可能是沿着一条线散布的,这时要找到一条最优的曲线来拟合这些数据,也就是要找到最好的线来代表这些点,这里的最优是指这些点和线之间的距离是最小的,这就是为什么要用最优化问题来解决曲线拟合问题。
举例说明,给一些点,找到一条线,来拟合这些点。
先给定一些点:N = 50 # 点的个数m_true = 2 # 斜率b_true = -1 # 截距dy = 2.0 # 误差np.random.seed(0)xdata = 10 * np.random.random(N) # 50 个 x,服从均匀分布ydata = np.random.normal(b_true + m_true * xdata, dy) # dy 是标准差plt.errorbar(xdata, ydata, dy, fmt='.k', ecolor='lightgray');

上面的点整体上呈现一个线性关系,要找到一条斜线来代表这些点,这就是经典的一元线性回归。目标就是找到最好的线,使点和线的距离最短。要优化的函数是点和线之间的距离,使其最小。点是确定的,而线是可变的,线是由参数值,斜率和截距决定的,这里就是要通过优化距离找到最优的斜率和截距。
点和线的距离定义如下:def chi2(theta, x, y): return np.sum(((y - theta[0] - theta[1] * x)) ** 2)
上式就是误差平方和。
误差平方和是什么?有什么作用?
误差平方和公式为:
误差平方和大,表示真实的点和预测的线之间距离太远,说明拟合得不好,最好的线,应该是使误差平方和最小,即最优的拟合线,这里是条直线。
误差平方和就是要最小化的目标函数。
找到最优的函数,即斜率和截距。theta_guess = [0, 1] # 初始值theta_best = opt.minimize(chi2, theta_guess, args=(xdata, ydata)).xprint(theta_best)[-1.01442005 1.93854656]
上面两个输出即是预测的直线斜率和截距,我们是根据点来反推直线的斜率和截距,那么真实的斜率和截距是多少呢?-1 和 2,很接近了,差的一点是因为有噪音的引入。xfit = np.linspace(0, 10)yfit = theta_best[0] + theta_best[1] * xfitplt.errorbar(xdata, ydata, dy, fmt='.k', ecolor='lightgray');plt.plot(xfit, yfit, '-k');

最小二乘(Least Square)是什么?
上面用的是 minimize 方法,这个问题的目标函数是误差平方和,这就又有一个特定的解法,即最小二乘。
最小二乘的思想就是要使得观测点和估计点的距离的平方和达到最小,这里的“二乘”指的是用平方来度量观测点与估计点的远近(在古汉语中“平方”称为“二乘”),“最小”指的是参数的估计值要保证各个观测点与估计点的距离的平方和达到最小。
关于最小二乘估计的计算,涉及更多的数学知识,这里不想详述,其一般的过程是用目标函数对各参数求偏导数,并令其等于 0,得到一个线性方程组。具体推导过程可参考斯坦福机器学习讲义 第 7 页。def deviations(theta, x, y): return (y - theta[0] - theta[1] * x)theta_best, ier = opt.leastsq(deviations, theta_guess, args=(xdata, ydata))print(theta_best)[-1.01442016 1.93854659]
最小二乘 leastsq 的结果跟 minimize 结果一样。注意 leastsq 的第一个参数不再是误差平方和 chi2,而是误差本身 deviations,即没有平方,也没有和。yfit = theta_best[0] + theta_best[1] * xfitplt.errorbar(xdata, ydata, dy, fmt='.k', ecolor='lightgray');plt.plot(xfit, yfit, '-k');

非线性最小二乘
上面是给一些点,拟合一条直线,拟合一条曲线也是一样的。def f(x, beta0, beta1, beta2): # 首先定义一个非线性函数,有 3 个参数 return beta0 + beta1 * np.exp(-beta2 * x**2)beta = (0.25, 0.75, 0.5) # 先猜 3 个 betaxdata = np.linspace(0, 5, 50)y = f(xdata, *beta)ydata = y + 0.05 * np.random.randn(len(xdata)) # 给 y 加噪音def g(beta): return ydata - f(xdata, *beta) # 真实 y 和 预测值的差,求最优曲线时要用到beta_start = (1, 1, 1)beta_opt, beta_cov = opt.leastsq(g, beta_start)print beta_opt # 求到的 3 个最优的 beta 值[ 0.25525709 0.74270226 0.54966466]
拿估计的 beta_opt 值跟真实的 beta = (0.25, 0.75, 0.5) 值比较,差不多。fig, ax = plt.subplots()ax.scatter(xdata, ydata) # 画点ax.plot(xdata, y, 'r', lw=2) # 真实值的线ax.plot(xdata, f(xdata, *beta_opt), 'b', lw=2) # 拟合的线ax.set_xlim(0, 5)ax.set_xlabel(r"$x$", fontsize=18)ax.set_ylabel(r"$f(x, \beta)$", fontsize=18)fig.tight_layout()

除了使用最小二乘,还可以使用曲线拟合的方法,得到的结果是一样的。beta_opt, beta_cov = opt.curve_fit(f, xdata, ydata)print beta_opt[ 0.25525709 0.74270226 0.54966466]
有约束的最小化
有约束的最小化是指,要求函数最小化之外,还要满足约束条件,举例说明。
边界约束def f(X): x, y = X return (x-1)**2 + (y-1)**2 # 这是一个碗状的函数x_opt = opt.minimize(f, (0, 0), method='BFGS').x # 无约束最优化
假设有约束条件,x 和 y 要在一定的范围内,如 x 在 2 到 3 之间,y 在 0 和 2 之间。bnd_x1, bnd_x2 = (2, 3), (0, 2) # 对自变量的约束x_cons_opt = opt.minimize(f, np.array([0, 0]), method='L-BFGS-B', bounds=[bnd_x1, bnd_x2]).x # bounds 矩形约束fig, ax = plt.subplots(figsize=(6, 4))x_ = y_ = np.linspace(-1, 3, 100)X, Y = np.meshgrid(x_, y_)c = ax.contour(X, Y, f((X,Y)), 50)ax.plot(x_opt[0], x_opt[1], 'b*', markersize=15) # 没有约束下的最小值,蓝色五角星ax.plot(x_cons_opt[0], x_cons_opt[1], 'r*', markersize=15) # 有约束下的最小值,红色星星bound_rect = plt.Rectangle((bnd_x1[0], bnd_x2[0]), bnd_x1[1] - bnd_x1[0], bnd_x2[1] - bnd_x2[0], facecolor="grey")ax.add_patch(bound_rect)ax.set_xlabel(r"$x_1$", fontsize=18)ax.set_ylabel(r"$x_2$", fontsize=18)plt.colorbar(c, ax=ax)fig.tight_layout()

不等式约束
介绍下相关理论,先来看下存在等式约束的极值问题求法,比如下面的优化问题。
目标函数是 f(w),下面是等式约束,通常解法是引入拉格朗日算子,这里使用 ββ 来表示算子,得到拉格朗日公式为
l 是等式约束的个数。
然后分别对 w 和ββ 求偏导,使得偏导数等于 0,然后解出 w 和βiβi,至于为什么引入拉格朗日算子可以求出极值,原因是 f(w) 的 dw 变化方向受其他不等式的约束,dw的变化方向与f(w)的梯度垂直时才能获得极值,而且在极值处,f(w) 的梯度与其他等式梯度的线性组合平行,因此他们之间存在线性关系。(参考《最优化与KKT条件》)
对于不等式约束的极值问题
常常利用拉格朗日对偶性将原始问题转换为对偶问题,通过解对偶问题而得到原始问题的解。该方法应用在许多统计学习方法中。有兴趣的可以参阅相关资料,这里不再赘述。def f(X): return (X[0] - 1)**2 + (X[1] - 1)**2def g(X): return X[1] - 1.75 - (X[0] - 0.75)**4x_opt = opt.minimize(f, (0, 0), method='BFGS').xconstraints = [dict(type='ineq', fun=g)] # 约束采用字典定义,约束方式为不等式约束,边界用 g 表示x_cons_opt = opt.minimize(f, (0, 0), method='SLSQP', constraints=constraints).xfig, ax = plt.subplots(figsize=(6, 4))x_ = y_ = np.linspace(-1, 3, 100)X, Y = np.meshgrid(x_, y_)c = ax.contour(X, Y, f((X, Y)), 50)ax.plot(x_opt[0], x_opt[1], 'b*', markersize=15) # 蓝色星星,没有约束下的最小值ax.plot(x_, 1.75 + (x_-0.75)**4, '', markersize=15)ax.fill_between(x_, 1.75 + (x_-0.75)**4, 3, color="grey")ax.plot(x_cons_opt[0], x_cons_opt[1], 'r*', markersize=15) # 在区域约束下的最小值ax.set_ylim(-1, 3)ax.set_xlabel(r"$x_0$", fontsize=18)ax.set_ylabel(r"$x_1$", fontsize=18)plt.colorbar(c, ax=ax)fig.tight_layout()

scipy.optimize.minimize 中包括了多种最优化算法,每种算法使用范围不同,详细参考官方文档。

热点内容
欢乐斗地主的密码在哪里显示 发布:2025-01-04 05:58:48 浏览:910
比亚迪唐dmi哪个配置值得买 发布:2025-01-04 05:50:17 浏览:169
内存储器的功能 发布:2025-01-04 05:50:11 浏览:679
sqlcountsum 发布:2025-01-04 05:49:24 浏览:233
linux怎么改ip 发布:2025-01-04 05:39:32 浏览:477
c语言mallocfree 发布:2025-01-04 05:38:49 浏览:267
台式电脑在哪里设置密码锁 发布:2025-01-04 05:36:27 浏览:631
msg编译路径 发布:2025-01-04 05:36:26 浏览:666
雷霆战机电脑脚本 发布:2025-01-04 05:26:43 浏览:995
原神在哪里下载安卓手机 发布:2025-01-04 05:21:50 浏览:378