python拟合函数_Python-最小二乘法曲线拟合
行文思路:最小二乘法原理介紹
利用 leastsq() 函數(shù)進(jìn)行最小二乘法擬合
擬合注意事項(xiàng)
利用curve_fit 進(jìn)行最小二乘法擬合
總結(jié):
參考文獻(xiàn)
實(shí)現(xiàn)代碼
一,最小二乘法擬合
最小二乘法是一種數(shù)學(xué)優(yōu)化技術(shù),它通過最小化誤差的平方和尋找數(shù)據(jù)的最佳函數(shù)匹配。優(yōu)化是找到最小值或等式的數(shù)值解的問題。而線性回歸就是要求樣本回歸函數(shù)盡可能好地?cái)M合目標(biāo)函數(shù)值,也就是說,這條直線應(yīng)該盡可能的處于樣本數(shù)據(jù)的中心位置。因此,選擇最佳擬合曲線的標(biāo)準(zhǔn)可以確定為:使總的擬合誤差(即總殘差)達(dá)到最小。
假設(shè)有一組實(shí)驗(yàn)數(shù)據(jù)(xi,yi ), 事先知道它們之間應(yīng)該滿足某函數(shù)關(guān)系yi=f(xi),通過這些已知信息,需要確定函數(shù)f的一些參數(shù)。例如,如果函數(shù)f是線性函數(shù)f(x)=kx+b, 那么參數(shù) k和b就是需要確定的值。
如果用p表示函數(shù)中需要確定的參數(shù),那么目標(biāo)就是找到一組p,使得下面的函數(shù)S的值最小:
當(dāng)誤差最小的時(shí)候可以理解為此時(shí)的系數(shù)為最佳的擬合狀態(tài)。
scipy.optimization 子模塊提供了函數(shù)最小值(標(biāo)量或多維)、曲線擬合和尋找等式的根的有用算法。在optimize模塊中可以使用 leastsq() 對(duì)數(shù)據(jù)進(jìn)行最小二乘擬合計(jì)算。leastsq() 函數(shù)傳入誤差計(jì)算函數(shù)和初始值,該初始值將作為誤差計(jì)算函數(shù)的第一個(gè)參數(shù)傳入。計(jì)算的結(jié)果是一個(gè)包含兩個(gè)元素的元組,第一個(gè)元素是一個(gè)數(shù)組,表示擬合后的參數(shù);第二個(gè)元素如果等于1、2、3、4中的其中一個(gè)整數(shù),則擬合成功,否則將會(huì)返回 mesg。下面是官方的文檔介紹,只截取了主要的參數(shù)部分。
代碼實(shí)現(xiàn):
1,導(dǎo)入模塊:
import numpy as np
import matplotlib.pyplot as plt
from scipy.optimize import leastsq
2,一元二次方程的參數(shù)擬合,首先創(chuàng)建擬合數(shù)據(jù)。
x = np.linspace(-10,10,100) # 創(chuàng)建時(shí)間序列
p_value = [-2,5,10] # 原始數(shù)據(jù)的參數(shù)
noise = np.random.randn(len(x)) # 創(chuàng)建隨機(jī)噪聲
y = Fun(p_value,x)+noise*2 # 加上噪聲的序列
3,通過函數(shù)定義擬合函數(shù)的形式。
這里可以擬合任意的函數(shù)形式,這要能把它的表達(dá)式給出。
def Fun(p,x): # 定義擬合函數(shù)形式
a1,a2,a3 = p
return a1*x**2+a2*x+a3
4,定義殘差項(xiàng)。
一般最小二乘法是求擬合函數(shù)和目標(biāo)函數(shù)差的平方,這里之所以沒有平方是應(yīng)為在擬合函數(shù)的內(nèi)部進(jìn)行,這里不顯式的表示。
def error (p,x,y): # 擬合殘差
return Fun(p,x)-y
5, 進(jìn)行擬合。
其中參數(shù)p0 為最小二乘法擬合的初值,初值的選取對(duì)于擬合時(shí)間和計(jì)算量影響很大,有事并對(duì)結(jié)果產(chǎn)生一定的影響。args() 中是除了初始值之外error() 中的所有參數(shù)的集合輸入。
para =leastsq(error, p0, args=(x,y)) # 進(jìn)行擬合
y_fitted = Fun (para[0],x) # 畫出擬合后的曲線
返回參數(shù)為一個(gè)包含擬合后參數(shù)的元組,可以通過中括號(hào)[] 取值的方式得到。
6,完整的代碼如下:
import numpy as np
import matplotlib.pyplot as plt
from scipy.optimize import leastsq
def Fun(p,x): # 定義擬合函數(shù)形式
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) # 創(chuàng)建時(shí)間序列
p_value = [-2,5,10] # 原始數(shù)據(jù)的參數(shù)
noise = np.random.randn(len(x)) # 創(chuàng)建隨機(jī)噪聲
y = Fun(p_value,x)+noise*2 # 加上噪聲的序列
p0 = [0.1,-0.01,100] # 擬合的初始參數(shù)設(shè)置
para =leastsq(error, p0, args=(x,y)) # 進(jìn)行擬合
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()
最終擬合的參數(shù)結(jié)果:
[-1.99437662 5.03789895 10.00150115]
二, 使用curve_fit() 進(jìn)行擬合
Note:使用 curve_fit(),主要的區(qū)別在于擬合函數(shù)的定義不同
def Fun(x, a1,a2,a3): # 定義擬合函數(shù)形式
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): # 定義擬合函數(shù)形式
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) # 創(chuàng)建時(shí)間序列
a1,a2,a3 = [-2,5,10] # 原始數(shù)據(jù)的參數(shù)
noise = np.random.randn(len(x)) # 創(chuàng)建隨機(jī)噪聲
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()
擬合結(jié)果
最終的擬合結(jié)果參數(shù)為:
[-2.00309373 5.00945061 10.30565526]
三, 多項(xiàng)式擬合
代碼實(shí)現(xiàn):
def main():
x = np.linspace(-10,10,100) # 創(chuàng)建時(shí)間序列
a1,a2,a3 = [-2,5,10] # 原始數(shù)據(jù)的參數(shù)
noise = np.random.randn(len(x)) # 創(chuàng)建隨機(jī)噪聲
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()
擬合結(jié)果為:
[-2.00532192 5.01626878 10.07612899]
總結(jié):
本文主要講了最小二乘法擬合曲線的實(shí)現(xiàn)方法,使用 leastsq() 和 curve_fit(),最后講解了多項(xiàng)式的擬合poly.fit(). 最小二乘法的兩個(gè)擬合大體的步驟是一樣的,定義擬合范式,傳入擬合參數(shù),開始擬合得出擬合結(jié)果。對(duì)于簡(jiǎn)單的擬合函數(shù)兩者的差別很小,但是復(fù)雜的,需要具體的分析。文章還會(huì)繼續(xù)的分析擬合結(jié)果的含義,讓我們對(duì)擬合的結(jié)果有更加透徹的理解,隨心擬合。
參考文獻(xiàn):
總結(jié)
以上是生活随笔為你收集整理的python拟合函数_Python-最小二乘法曲线拟合的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: ecs硬盘数据迁移_阿里云ECS新增数据
- 下一篇: 东风风神奕炫的1挡一直闪烁是什么情况?