最⼩⼆乘法拟合(pythonscipy)
⾏⽂思路:
最⼩⼆乘法原理介绍
利⽤ leastsq() 函数进⾏最⼩⼆乘法拟合
拟合注意事项
利⽤curve_fit 进⾏最⼩⼆乘法拟合
总结:
参考⽂献
实现代码
⼀,最⼩⼆乘法拟合
最⼩⼆乘法是⼀种数学优化技术,它通过最⼩化误差的平⽅和寻数据的最佳函数匹配。优化是到最
⼩值或等式的数值解的问题。⽽线性回归就是要求样本回归函数尽可能好地拟合⽬标函数值,也就是说,这条直线应该尽可能的处于样本数据的中⼼位置。因此,选择最佳拟合曲线的标准可以确定为:使总的拟合误差(即总残差)达到最⼩。
假设有⼀组实验数据(xi,yi ), 事先知道它们之间应该满⾜某函数关系yi=f(xi),通过这些已知信息,需要确定函数f的⼀些参数。例如,如果函数f是线性函数f(x)=kx+b, 那么参数 k和b就是需要确定的值。
如果⽤p表⽰函数中需要确定的参数,那么⽬标就是到⼀组p,使得下⾯的函数S的值最⼩:
当误差最⼩的时候可以理解为此时的系数为最佳的拟合状态。
scipy.optimization ⼦模块提供了函数最⼩值(标量或多维)、曲线拟合和寻等式的根的有⽤算法。在optimize模块中可以使⽤ leastsq() 对数据进⾏最⼩⼆乘拟合计算。leastsq() 函数传⼊误差计算函数和初始值,该初始值将作为误差计算函数的第⼀个参数传⼊。计算的结果是⼀个包含两个元素的元组,第⼀个元素是⼀个数组,表⽰拟合后的参数;第⼆个元素如果等于1、2、3、4中的其中⼀个整数,则拟合成功,否则将会返回 mesg。下⾯是官⽅的⽂档介绍,只截取了主要的参数部分。
代码实现:
1,导⼊模块:
import numpy as np
import matplotlib.pyplot as plt
from scipy.optimize import leastsq
2,⼀元⼆次⽅程的参数拟合,⾸先创建拟合数据。
x = np.linspace(-10,10,100)          # 创建时间序列
p_value = [-2,5,10]                  # 原始数据的参数
noise = np.random.randn(len(x))      # 创建随机噪声
y = Fun(p_value,x)+noise*2            # 加上噪声的序列
3,通过函数定义拟合函数的形式。
这⾥可以拟合任意的函数形式,这要能把它的表达式给出。
def Fun(p,x):                        # 定义拟合函数形式
a1,a2,a3 = p
linspace函数python
return a1*x**2+a2*x+a3
4,定义残差项。
⼀般最⼩⼆乘法是求拟合函数和⽬标函数差的平⽅,这⾥之所以没有平⽅是应为在拟合函数的内部进⾏,这⾥不显式的表⽰。
def error (p,x,y):                  # 拟合残差
return Fun(p,x)-y
5,进⾏拟合。
其中参数p0 为最⼩⼆乘法拟合的初值,初值的选取对于拟合时间和计算量影响很⼤,有事并对结果产⽣⼀定的影响。args() 中是除了初始值之外error() 中的所有参数的集合输⼊。
para =leastsq(error, p0, args=(x,y))  # 进⾏拟合
y_fitted = Fun (para[0],x)            # 画出拟合后的曲线
返回参数为⼀个包含拟合后参数的元组,可以通过中括号[] 取值的⽅式得到。
6,完整的代码如下:
import numpy as np
import matplotlib.pyplot as plt
from scipy.optimize import leastsq
def Fun(p,x):                        # 定义拟合函数形式
a1,a2,a3 = p
return a1*x**2+a2*x+a3
def error (p,x,y):                    # 拟合残差
return Fun(p,x)-y
def main():
x = np.linspace(-10,10,100)  # 创建时间序列
p_value = [-2,5,10] # 原始数据的参数
noise = np.random.randn(len(x))  # 创建随机噪声
y = Fun(p_value,x)+noise*2 # 加上噪声的序列
p0 = [0.1,-0.01,100] # 拟合的初始参数设置
para =leastsq(error, p0, args=(x,y)) # 进⾏拟合
y_fitted = Fun (para[0],x) # 画出拟合后的曲线
plt.figure
plt.plot(x,y,'r', label = 'Original curve')
plt.plot(x,y_fitted,'-b', label ='Fitted curve')
plt.legend()
plt.show()
print (para[0])
if __name__=='__main__':
main()
最终拟合的参数结果:
[-1.99437662 5.03789895 10.00150115]
⼆,使⽤curve_fit() 进⾏拟合
Note:使⽤ curve_fit(),主要的区别在于拟合函数的定义不同def Fun(x, a1,a2,a3): # 定义拟合函数形式
return a1*x**2+a2*x+a3
完整的代码:
import numpy as np
import matplotlib.pyplot as plt
from scipy.optimize import curve_fit
def Fun(x,a1,a2,a3):                  # 定义拟合函数形式
return a1*x**2+a2*x+a3
def error (p,x,y): # 拟合残差
return Fun(p,x)-y
def main():
x = np.linspace(-10,10,100)      # 创建时间序列
a1,a2,a3 = [-2,5,10]              # 原始数据的参数
noise = np.random.randn(len(x))  # 创建随机噪声
y = Fun(x,a1,a2,a3)+noise*2      # 加上噪声的序列
para,pcov=curve_fit(Fun,x,y)
y_fitted = Fun(x,para[0],para[1],para[2]) # 画出拟合后的曲线
plt.figure
plt.plot(x,y,'r', label = 'Original curve')
plt.plot(x,y_fitted,'-b', label ='Fitted curve')
plt.legend()
plt.show()
print (para)
if __name__=='__main__':
main()
拟合结果
最终的拟合结果参数为:
[-2.00309373 5.00945061 10.30565526]
三,多项式拟合
代码实现:
def main():
x = np.linspace(-10,10,100) # 创建时间序列
a1,a2,a3 = [-2,5,10] # 原始数据的参数
noise = np.random.randn(len(x)) # 创建随机噪声
y = Fun(x,a1,a2,a3)+noise*2 # 加上噪声的序列
plt.plot(x,y)
para=np.polyfit(x, y, deg = 2)
y_fitted = Fun(x,para[0],para[1],para[2])
plt.figure
plt.plot(x,y,'ro', label = 'Original curve')
plt.plot(x,y_fitted,'-b', label ='Fitted curve')
plt.legend()
plt.show()
print(para)
if __name__=='__main__':
main()
拟合结果为:
[-2.00532192 5.01626878 10.07612899]
总结:
本⽂主要讲了最⼩⼆乘法拟合曲线的实现⽅法,使⽤ leastsq() 和 curve_fit(),最后讲解了多项式的拟合poly.fit(). 最⼩⼆乘法的两个拟合⼤体的步骤是⼀样的,定义拟合范式,传⼊拟合参数,开始拟合得出拟合结果。对于简单的拟合函数两者的差别很⼩,但是复杂的,需要具体的分析。⽂章还会继续的分析拟合结果的含义,让我们对拟合的结果有更加透彻的理解,随⼼拟合。
参考⽂献:

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。