首页 > 解决方案 > Python中的非线性最小二乘回归

问题描述

我必须按照公式为我的约 30 个数据点计算非线性最小二乘回归

非线性最小二乘公式

curve_fit使用以下代码尝试了 scipy.optimize 中的功能

def func(x, p1 ,p2):
  return p1*x/(1-x/p2)

popt, pcov = curve_fit(func, CSV[:,1], CSV[:,0])

p1 = popt[0]
p2 = popt[1]

p1 和 p2 分别相当于 A 和 C,CSV 是我的数据数组。函数运行时没有错误消息,但结果与预期不符。我已经将函数的结果与原始数据点一起绘制。我不想得到这条几乎直线(图中的红线),而是更接近绿线的东西,这只是 Excel 的二阶多项式拟合。绿色虚线只是快速​​手动尝试接近多项式拟合。

拟合函数的错误计算,连同原始数据点:1

有谁知道如何让计算按我的意愿运行?

标签: python

解决方案


你的代码很好。数据虽然不容易拟合。图表右侧的点太少,左侧的噪音太多。这就是curve_fit失败的原因。改进解决方案的一些方法可能是:

  • 提高 curve_fit() 的 maxfev 参数,请参见此处
  • 给 curve_fit() 起始值 - 见同一个地方
  • 添加更多数据点
  • 在函数或不同函数中使用更多参数。

curve_fit() 可能不是最强的工具。看看您是否可以使用其他回归类型的工具获得更好的结果。

以下是我能用你的初始数据和公式得到的最好的结果:

df = pd.read_csv("c:\\temp\\data.csv", header=None, dtype = 'float' )
df.columns = ('x','y')

def func(x,  p1 ,p2):
    return p1*x/(1-x/p2)

popt, pcov = curve_fit(func, df.x, df.y,  maxfev=3000)
print('p1,p2:',popt)
p1, p2 = popt

y_pred = [ p1*x/(1-x/p2)+p3*x for x in range (0, 140, 5)]
plt.scatter(df.x, df.y)
plt.scatter(range (0, 140, 5), y_pred)

plt.show()

p1,p2:[-8.60771432e+02 1.08755430e-05]

在此处输入图像描述


推荐阅读