最小二乘法原理:
已知:一组实验数据(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算法结果高度一致