一元二次曲线拟合的最小二乘python实现

时间:2024-05-18 13:30:39

1、首先定义一个误差函数,t为需要拟合的参数

def residual(t, x, y):
    return y - (t[0] * x ** 2 + t[1] * x + t[2])
2、接着设定真实值

x = np.linspace(-2, 2, 50)
A, B, C = 2, 3, -1           #为真实值
y = (A * x ** 2 + B * x + C) + np.random.rand(len(x))*0.75  
#np.random.rand(len(x))*0.75 加入噪声,len(x)为50,
3、使用python里scipy.optimize.leastsq()函数

p = leastsq(residual, [0, 0, 0], args=(x, y))

#leastsq(func, x0, args=())  func 是我们自己定义的一个计算误差的函数即residual,args 是指定func的其他参数,调用leastsq进行数据拟合, residual为计算误差的函数,
x0为拟合参数的初始值,# args为需要拟合的实验数据这里将 (x,y)传递给args参数。Leastsq()会将这两个额外的参数传递给residual()因此residual()有三个参数,t是拟合函数的参数,yx是表示实验数据的数组
theta = p[0] #将拟合出来的参数赋值给theta
print('真实值:', A, B, C)
print('预测值:', theta)
y_hat = theta[0] * x ** 2 + theta[1] * x + theta[2]
plt.plot(x, y, 'r-', linewidth=2, label=u'Actual')
plt.plot(x, y_hat, 'g-', linewidth=2, label=u'Predict')
plt.legend(loc='upper left')
plt.grid()
plt.show()

最后生成结果

真实值: 2 3 -1
预测值: [ 1.99181411  2.97673496 -0.60163036]


关于theta = p[0] #将拟合出来的参数赋值给theta
本人开始有一个小疑问,就是p[0]不应该输出的是第一个参数吗,为什么是同时输出了三个参数,因此

输出了具体形式

print(p)
结果为(array([ 1.98688109,  2.99088257, -0.64934811]), 3),3代表有三个参数

print(theta),调用了第一个数组,即三个参数的列表
结果为[ 1.98688109  2.99088257 -0.64934811]

图像为

一元二次曲线拟合的最小二乘python实现