最小二乘法原理:
已知:一組實驗數據(x[i], y[i]),我們知道它們之間的存在函數關係:y = f(x),關係可以爲線性或非線性,最簡單線性範例:f(x) = k*x+b,另外可能爲:f(x) = sin(kx +b),對數、指數等函數。
現期望通過這些已知數據,確定假設函數中的參數項,建立完整的函數關係式,使得應用函數計算的因變量結果值與實現數據值之間差值的平方和最小,稱之爲最小二乘法。
經典Python實現函數:
經典的最小二乘法函數,出自scipy.optimize,查看官方文檔,存在太多疑慮,且未提供直接應用範例,如何應用,難以理解。
scipy.optimize.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)
應用範例:
使用最小二乘法擬合直線
'''
import numpy as np
from scipy.optimize import leastsq
import matplotlib.pyplot as plt
#訓練數據
Xi = np.array([8.19,2.72,6.39,8.71,4.7,2.66,3.78])
Yi = np.array([7.01,2.78,6.47,6.71,4.1,4.23,4.05])
#定義擬合函數形式
def func(p,x):
k,b = p
return k*x+b
#定義誤差函數
def error(p,x,y,s):
print(s)
return func(p,x)-y
#隨機給出參數的初始值
p = [10,2]
#使用leastsq()函數進行參數估計
s = '參數估計次數'
Para = leastsq(error,p,args=(Xi,Yi,s))
k,b = Para[0]
print('k=',k,'\n','b=',b)
#圖形可視化
plt.figure(figsize = (8,6))
#繪製訓練數據的散點圖
plt.scatter(Xi,Yi,color='r',label='Sample Point',linewidths = 3)
plt.xlabel('x')
plt.ylabel('y')
x = np.linspace(0,10,1000)
y = k*x+b
plt.plot(x,y,color= 'orange',label = 'Fitting Line',linewidth = 2)
plt.legend()
plt.show()
分析代碼,SciPy的最小二乘法,具有較強的通用性,可以對多種設想的擬合曲線,利用試驗數據求得其擬合參數。
根據誤差函數設置,其嚴格遵照擬合結果確保二乘誤差最小的原則,應該是採取逼近法求得。
利用偏導數,代數求解法,可求得參數公式:
網址:https://blog.csdn.net/sinat_23338865/article/details/80608834
自編Python代碼實現
#最小二乘法計算線性係數值
def leastsq(Xi, Yi):
m = len(Xi)
multiply_Xi_Yi = Xi*Yi
sum_mp = np.sum(multiply_Xi_Yi)
sum_Xi = np.sum(Xi)
sum_Yi = np.sum(Yi)
pow_Xi = Xi * Xi
sum_pow_Xi = np.sum(pow_Xi)
k = (m * sum_mp - sum_Xi*sum_Yi)/(m*sum_pow_Xi - sum_Xi * sum_Xi)
return k
同樣參數驗證,自建算法與SciPy算法結果高度一致