如何使用数据拟合我的函数以获得拟合参数?

时间:2017-06-19 14:14:34

标签: python numpy matplotlib

我有一组数据,其中x和y是我函数中的已知参数,它们在函数中写为x = x和y = x1,我需要拟合数据,这样我才能获得值未知参数(E,B0,S0)。 到目前为止,我有这个,但是当我尝试运行时,我得到了错误:

ValueError: x and y must have same first dimension, but have shapes (4L,) and (1L,)

当我尝试绘制拟合曲线时会发生此错误。关于我设置的界限,我也得到了这个错误:

 lb, ub = [np.asarray(b, dtype=float) for b in bounds]
ValueError: too many values to unpack

import numpy as np
import matplotlib.pyplot as plt
from scipy.optimize import curve_fit

def func (x, x1, E, B0, S0):
    # function to optimize where x and x1 are known
    # E, B0, S0 need to be fitted
    return sum((x-np.power((E*B0*(1+((x1-S0)/(B0)))),(1/2)))**2)

#define the data to be fit
xdata = [0.00, 3.42, 4.56, 5.31] #distance
ydata = [335.4, 149.1, 167.1, 292.2] # beam size
plt.plot(xdata, ydata, 'b-', label='data')
pl.show()

# fit for parameters E, B0, and S0
popt, pcov = curve_fit(func, xdata, ydata)
plt.plot(xdata, func(xdata, *popt), 'r-', label='fit')

#put bounds on the optimization: 0.5<E<5, 1<S0<10, 0.1<B0,10
bnds= [(0.5,5.0),(0.1,10.0),(1,10)]
popt, pcov = curve_fit(func, xdata, ydata, bounds = [(0.5,5.0),(0.1,10.0),
(1.0,10.0)])
plt.plot(xdata,func(xdata, *popt),'g--', label='fit-with-bounds')
plt.xlabel('distance')
plt.ylabel('beam size')
plt.legend()
plt.show()

2 个答案:

答案 0 :(得分:1)

目前尚不清楚func函数中的总和应该做什么。您可以将其删除以消除第一个错误。

其次,curve_fit方法中的边界是独立变量的边界,而不是参数的边界。保留界限,你将摆脱第二个错误。

import numpy as np
import matplotlib.pyplot as plt
from scipy.optimize import curve_fit

def func (x, x1, E, B0, S0):
    # function to optimize where x and x1 are known
    # E, B0, S0 need to be fitted
    return (x-np.power((E*B0*(1.+((x1-S0)/(B0)))),(1/2.)))**2

#define the data to be fit
xdata = [0.00, 3.42, 4.56, 5.31] #distance
ydata = [335.4, 149.1, 167.1, 292.2] # beam size
plt.plot(xdata, ydata, 'b-', label='data')


# fit for parameters E, B0, and S0
popt, pcov = curve_fit(func, xdata, ydata)
plt.plot(xdata, func(xdata, *popt), 'r-', label='fit')

popt, pcov = curve_fit(func, xdata, ydata) 
plt.plot(xdata,func(xdata, *popt),'g--', label='fit-with-bounds')
plt.xlabel('distance')
plt.ylabel('beam size')
plt.legend()
plt.show()

enter image description here

现在显然“适合”和“适应边界”是相同的。

<小时/> 编辑:为了仅适合E, B0, S0,fit函数应该只将这些值作为参数。

funcwithx1 = lambda x,x1, E, B0, S0: (x-np.power((E*B0*(1.+((x1-S0)/(B0)))),(1/2.)))**2
x1 = 4.6
func = lambda x, E, B0, S0: funcwithx1(x, x1, E, B0, S0)

答案 1 :(得分:0)

错误定义了该功能。您知道独立变量和因变量,但您只为拟合函数提供独立变量。

y = func(x; params)

现在,您的目标函数有4个参数需要确定。

稍后,在调用curve_fit时,您可以正确地提供独立变量和因变量 popt, pcov = curve_fit(func, xdata, ydata)

因此,popt是一个长度为4的数组,可能会引起您的部分问题。

我不确切地知道你的目标功能,所以我不会试图解决这个问题。希望这能指导您解决问题。