Python中的非线性最小二乘回归
我必须按照公式计算30个数据点的非线性最小二乘回归 我尝试了scipy的Python中的非线性最小二乘回归,python,Python,我必须按照公式计算30个数据点的非线性最小二乘回归 我尝试了scipy的曲线拟合函数。使用以下代码进行优化 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是我的数据数组。函数运行时没有错误消息,但结果不符合预期。我已经绘制了函数的结果和原始数据点。我并不是想得到这条
曲线拟合
函数。使用以下代码进行优化
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中的二阶多项式拟合。绿色虚线显示的只是一个快速手动尝试,以接近多项式拟合
拟合函数的计算错误,以及原始数据点:
有人知道如何使计算按我的要求运行吗?您的代码很好。然而,这些数据并不容易拟合。图表右侧的点太少,左侧的噪音太大。这就是曲线拟合失败的原因。 改进解决方案的一些方法可以是:
- 提高曲线拟合的maxfev参数()请参见
- 为曲线拟合()提供起始值-请参见
- 添加更多数据点
- 在函数或不同函数中使用更多参数
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+021.08755430e-05]
我想我已经找到了使用lmfit软件包()解决此问题的最佳方法。当我尝试将非线性最小二乘回归拟合到Excel提供的拟合函数(虽然不是很优雅)而不是原始数据时,效果最好 结果看起来很好,包也很容易使用(我省略了最后的情节)
[[Fit统计信息]]
#拟合方法=最小二乘法
#函数evals=25
#数据点=24
#变量=2
卡方检验=862.285318
缩减卡方检验=39.1947872
Akaike信息临界值=89.9567771
贝叶斯信息标准=92.3128848
[[变量]]
o1:310.243771+/-12.7126811(4.10%)(初始值=210)
氧气:0.13403974+/-0.00120453(0.90%)(初始值=0.118)
[[相关性]](未报告的相关性<0.100)
C(o1,o2)=0.930
您的代码很好。公式与数据集之间可能存在次优选择。请共享数据以运行测试。希望有效。我已将数据保存为.csv文件(在我的操作中最容易使用)好的,谢谢。这对我帮助很大。然而,我对结果并不完全满意,但添加第三个参数提供了很好的相关性。需要补充的一点是:这些问题不是由数据的噪音引起的。我用多项式拟合的数据点尝试了代码,结果是相似的。我想我找到了一个更好的方法(见上面的答案)。
from lmfit import Model
import matplotlib.pyplot as plt
import numpy as np
def func(x, o1 ,o2):
return o1*x/(1-x/o2)
xt = np.arange(0, 0.12, 0.005)
yt = 2.2268*np.exp(40.755*xt)
model = Model(func)
result = model.fit(yt, x=xt, o1=210, o2=0.118)
print(result.fit_report())
plt.plot(xt, yt, 'bo')
plt.plot(xt, result.init_fit, 'k--', label='initial fit')
plt.plot(xt, result.best_fit, 'r-', label='best fit')
plt.legend(loc='best')
plt.show
[[Fit Statistics]]
# fitting method = leastsq
# function evals = 25
# data points = 24
# variables = 2
chi-square = 862.285318
reduced chi-square = 39.1947872
Akaike info crit = 89.9567771
Bayesian info crit = 92.3128848
[[Variables]]
o1: 310.243771 +/- 12.7126811 (4.10%) (init = 210)
o2: 0.13403974 +/- 0.00120453 (0.90%) (init = 0.118)
[[Correlations]] (unreported correlations are < 0.100)
C(o1, o2) = 0.930