Scipy 拟合
2021-10-13
| 2023-8-6
0  |  阅读时长 0 分钟
type
status
date
slug
summary
tags
category
icon
password
Property
在科学研究和工程应用中经常通过测量、采样、实验等方法获得各种数据。对一组已知数据点集,通过调整拟合函数(曲线)的参数,使该函数与已知数据点集相吻合,这个过程称为数据拟合,又称曲线拟合。
插值和拟合都是根据一组已知数据点,求变化规律和特征相似的近似曲线的过程。但是插值要求近似曲线完全经过所有的给定数据点,而拟合只要求近似曲线在整体上尽可能接近数据点,并反映数据的变化规律和发展趋势。因此插值可以看作是一种特殊的拟合,是要求误差函数为0的拟合。

数据拟合问题的分类

数据拟合问题,可以从不同角度进行分类:
  • 按照拟合函数分类,分为线性函数和非线性函数。非线性函数用于数据拟合,常用的有多项式函数、样条函数、指数函数和幂函数,针对具体问题还有自定义的特殊函数显示。
  • 按照变量个数分类,分为单变量函数和多变量函数。
  • 按照拟合模型分类,分为基于模型的数据拟合和无模型的函数拟合。基于模型的数据拟合,是通过建立数学模型描述输入输出变量之间的关系,拟合曲线不仅能拟合观测数据,拟合模型的参数通常具有明确的物理意义。而无模型的函数拟合,是指难以建立描述变量关系的数学模型,只能采用通用的函数和曲线拟合观测数据,例如多项式函数拟合、样条函数拟合,也包括机器学习和神经网络模型,这种模型的参数通常没有明确的意义。

数据拟合的原理和方法

数据拟合通过调整拟合函数中的待定参数,从整体上接近已知的数据点集。
这是一个优化问题,决策变量是拟合函数的待定参数,优化目标是观测数据与拟合函数的函数值之间的某种误差指标。典型的优化目标是拟合函数值与观测值的误差平方和;当观测数据的重要性不同或分布不均匀时,也可以使用加权误差平方和作为优化目标。
数据拟合的基本方法是最小二乘法。对于观测数据 ,将观测值 与拟合函数 的计算值的误差平方和最小作为优化问题的目标函数: 是拟合函数中的待定参数
对于线性拟合问题,设拟合函数为直线 , 由极值的必要条件 可以解出系数: 对于多变量线性最小二乘问题,设拟合函数为直线 , 类似地,可以解出系数
对于非线性函数的拟合问题,通常也是按照最小二乘法的思路,求解上述误差平方和最小化这个非线性优化问题,常用的具体算法有搜索算法和迭代算法两类
 

线性最小二乘拟合

线性最小二乘拟合是最简单和最常用的拟合方法。scipy.optimize 工具箱中的 leastsq()lsq_linear(),scipy.stats 工具箱中的 linregress(),都可以实现线性最小二乘拟合。

scipy.optimize.leastsq

leastsq()根据观测数据进行最小二乘拟合计算,只需要观测值与拟合函数值的误差函数和待定参数 的初值,返回拟合函数中的待定参数 ,但不能提供参数估计的统计信息。leastsq()可以进行单变量或多变量线性最小二乘拟合,对变量进行预处理后也可以进行多项式函数拟合。
scipy.optimize.leastsq(func, x0, args=(), Dfun=None, full_output=0, col_deriv=0, ftol=1.49012e-08, xtol=1.49012e-08, gtol=0.0, maxfev=0, epsfcn=None, factor=100, diag=None)
主要参数:
  • func:可调用的函数,描述拟合函数的函数值与观测值的误差,形式为error(p,x,y),具有一个或多个待定参数。误差函数的参数必须按照的顺序排列,不能改变
  • args:元组,线性拟合时提供观测数据值 ,观测数据可以是一维数组(单变量问题),也可以是多维数组(多变量问题)
返回值:
  • x:一维数组,待定参数 的最小二乘估计值
 

scipy.stats.linregress

linregress() 根据两组观测数据进行线性最小二乘回归,不仅返回拟合函数中的待定参数,而且可以提供参数估计的各种统计信息,但只能进行单变量线性拟合
scipy.stats.linregress(x, y=None, alternative=‘two-sided’)
主要参数:
  • x, y是长度相同的一维数组。或者 是二维数组,且,则二维数组相当于长度相同的一维数组
返回值:
  • intercept:截距,直线 中的
  • rvalue值,统计量
  • pvalue值,P检验的统计量
  • stderr:标准差,统计量
 

单变量线性拟合

notion image
notion image
  1. scipy.optimize.leastsq()scipy.stats.linregress()都可以进行单变量线性拟合。leastsq() 既可以用于单变量也可以用于多变量问题;linregress() 只能用于单变量问题,但可以给出很多参数估计的统计结果
  1. leastsq()要以子函数来定义观测值与拟合函数值的误差函数,例程中分别定义了拟合函数 fitfunc1(p, x) 与误差函数error1(p, x, y),是为了方便调用拟合函数计算拟合曲线在数据点的函数值。注意 p 为数组 。
  1. leastsq() 中误差函数的函数名可以任意定义,但误差函数的参数必须按照 的顺序排列,不能改变次序。
  1. leastsq() 中观测数据 (x, yObs) 是以动态参数 args 的方式进行传递的。这种处理方式非常独特,没有为什么, leastsq() 就是这样定义的。
  1. linregress() 只要将观测数据 (x,yObs) 作为参数,默认单变量线性拟合,不需要定义子函数。
  1. leastsq() 与 linregress() 进行线性拟合,得到的参数估计结果是相同的
 
 
 

多变量线性拟合

notion image
notion image
notion image
 
 

非线性函数数据拟合

非线性函数是非常广泛的概念。这里讨论指数函数、多项式函数和样条函数三种常用的通用形式的非线性函数拟合问题,分别使用了 Scipy 工具包中的 scipy.optimize.leastsq()scipy.linalg.lstsq()scipy.interpolate.UnivariateSpline()
lstsq() 函数只要传入观测数据 (x,yObs),并将 x 按多项式阶数转换为 X,即可求出多项式函数的系数,不需要定义拟合函数或误差函数,非常适合比较不同阶数的多项式函数拟合的效果。
scipy.linalg.lstsq(a, b, cond=None, overwrite_a=False, overwrite_b=False, check_finite=True, lapack_driver=None)
主要参数:
  • a:(m,n) 数组,表示方程 Ax=b 的左侧。
  • b:(m,) 数组,表示方程 Ax=b 的右侧。
返回值:
  • x:最小二乘的解,指多项式函数的系数。
注意:lstsq() 函数中求解方程 Ax=b,A 是指由观测数据 按多项式阶数转换为矩阵 是指 ,而 x 是指多项式函数的系数
 

指数函数拟合

notion image
notion image
  1. scipy.optimize.leastsq() 本质上是求解带有待定参数的误差函数最小化问题,因此可以用于指数函数的最小二乘拟合。类似地,原理上 leastsq() 也可以用于其它形式非线性函数的拟合问题,但对于某些函数拟合误差可能会比较大
  1. leastsq() 以子函数 error3(p, x, y) 来定义观测值与拟合函数值的误差函数,以动态参数 args 的方式传递观测数据 (x, yObs) 。
  1. leastsq() 中误差函数的函数名可以任意定义,但误差函数的参数必须按照 (p,x1,x2,y) 的顺序排列,不能改变次序
 
 

多项式函数拟合

程序说明:
  1. scipy.optimize.leastsq() 本质上是求解带有待定参数的误差函数最小化问题,因此可以用于多项式函数的最小二乘拟合,使用方法与线性拟合、指数拟合类似。
  1. 由于 leastsq() 要以子函数 error(p, x, y) 来定义观测值与拟合函数值的误差函数,在比较不同阶数的多项式函数拟合时需要定义多个对应的误差函数,比较繁琐。
  1. scipy.linalg.lstsq() 只要传入观测数据 (x,yObs),并将 x 按多项式阶数转换为 X,即可求出多项式函数的系数,不需要定义拟合函数或误差函数,非常适合比较不同阶数的多项式函数拟合的效果。
  1. 对于相同阶数的多项式函数,leastsq() 与 lstsq() 的参数估计和拟合结果是相同的。
  1. 增大多项式的阶数,可以减小拟合曲线与观测数据的误差平方和,但也更容易导致过拟合,虽然能更好地拟合训练数据,但并不能真实反映数据的总体规律,因而对于训练数据以外的测试数据的拟合效果反而降低了。
notion image
notion image
 
 
 
 

样条曲线拟合

  1. scipy.interpolate.UnivariateSpline() 类是一种基于固定数据点创建函数的方法,使用样条曲线拟合到给定的数据点集。
  1. UnivariateSpline 类由已知数据点集生成样条插值函数 y=spl(x),通过调用样条插值函数可以计算指定 x 的函数值 f(x)。
  1. UnivariateSpline 类既可以进行数据插值,也可以进行拟合。参数 s=0 表示数据插值,样条曲线必须通过所有数据点;s>0 表示数据拟合,默认 s= len(w)。
  1. 通过 set_smoothing_factor(sf) 设置光滑因子,可以对样条拟合函数进行调节,使拟合曲线更好地反映观测数据特征,避免过拟合
notion image
notion image
 
 
 

自定义函数曲线拟合

curve_fit() 使用非线性最小二乘法将自定义的拟合函数拟合到观测数据,不仅可以用于直线、二次曲线、三次曲线的拟合,而且可以适用于任意形式的自定义函数的拟合,使用非常方便。curve_fit() 允许进行单变量或多变量的自定义函数拟合。
scipy.optimize.curve_fit(f,xdata,ydata,p0=None,sigma=None,absolute_sigma=False,check_finite=True,bounds=(-inf,inf),method=None,jac=None,kwargs)
主要参数:
  • f:可调用的函数,自定义的拟合函数,具有一个或多个待定参数。拟合函数的形式为 ,其中参数必须按照 的顺序排列, 是标量不能表达为数组。
  • xdata:n*m数组,n 为观测数据长度,m为变量个数。观测数据 xdata 可以是一维数组(单变量问题),也可以是多维数组(多变量问题)。
  • ydata:数组,长度为观测数据长度 n。
  • p0:可选项,待定参数 的初值,默认值无。
返回值:
popt:待定参数 的最小二乘估计值
pcov:参数 的估计值 popt 的协方差,其对角线是各参数的方差
 

单变量自定义函数曲线拟合

notion image
notion image
  1. 不同于 leastsq() 定义观测值与拟合函数值的误差函数,scipy.optimize.curve_fit() 直接定义一个自定义的拟合函数,更为直观和便于理解。
  1. curve_fit() 定义一个拟合函数,函数名可以任意定义,但拟合函数的参数必须按照 (x,p1,p2,…) 的顺序排列,不能改变次序。p1, p2,… 是标量,不能写成数组。注意 leastsq() 中误差函数的参数必须按照 (p,x,y) 的顺序排列,与 curve_fit() 不同。
  1. leastsq() 也可以对自定义的拟合函数进行最小二乘拟合。
  1. 由于本例程中自定义拟合函数使用了观测数据的实际模型,而不是通用的多项式函数或样条函数,因此拟合结果不仅能很好的拟合观测数据,而且能更准确地反映实际模型的趋势。
 
 
 
 

多变量自定义函数曲线拟合

 
  • Scipy
  • SciPy 插值Scipy linalg
    目录