Python 正确使用fmin_l_bfgs_b拟合模型参数

Python 正确使用fmin_l_bfgs_b拟合模型参数,python,numpy,scipy,model-fitting,Python,Numpy,Scipy,Model Fitting,我有一些实验数据(对于y,x,t_exp,m_exp),并希望使用。参数E必须大于0,其他参数不受约束 def func(x, A, B, C, D, E, *args): return A * (x ** E) * numpy.cos(t_exp) * (1 - numpy.exp((-2 * B * x) / numpy.cos(t_exp))) + numpy.exp((-2 * B * x) / numpy.cos(t_exp)) * C + (D * m_exp) init

我有一些实验数据(对于y,x,t_exp,m_exp),并希望使用。参数E必须大于0,其他参数不受约束

def func(x, A, B, C, D, E, *args):
    return A * (x ** E) * numpy.cos(t_exp) * (1 - numpy.exp((-2 * B * x) / numpy.cos(t_exp))) +  numpy.exp((-2 * B * x) / numpy.cos(t_exp)) * C + (D * m_exp)

initial_values = numpy.array([-10, 2, -20, 0.3, 0.25])
mybounds = [(None,None), (None,None), (None,None), (None,None), (0, None)]
x,f,d = scipy.optimize.fmin_l_bfgs_b(func, x0=initial_values, args=(m_exp, t_exp), bounds=mybounds)
有几个问题:

  • 我的模型公式
    func
    应该包括我的自变量
    x
    ,还是应该从实验数据
    x_exp
    中作为
    *args
    的一部分提供
  • 当我运行上面的代码时,我得到一个错误
    func()接受至少6个参数(给定3个)
    ,我假设它们是x,我的两个*参数。。。如何定义
    func
  • 编辑:感谢@zephyr的回答,我现在明白了目标是最小化残差平方和,而不是实际函数。我得到了以下工作代码:

    def func(params, *args):
        l_exp = args[0]
        s_exp = args[1]
        m_exp = args[2]
        t_exp = args[3]
        A, B, C, D, E = params
        s_model = A * (l_exp ** E) * numpy.cos(t_exp) * (1 - numpy.exp((-2 * B * l_exp) / numpy.cos(t_exp))) +  numpy.exp((-2 * B * l_exp) / numpy.cos(theta_exp)) * C + (D * m_exp)
        residual = s_exp - s_model
        return numpy.sum(residual ** 2)
    
    initial_values = numpy.array([-10, 2, -20, 0.3, 0.25])
    mybounds = [(None,None), (None,None), (None,None), (None,None), (0,None)]
    
    x, f, d = scipy.optimize.fmin_l_bfgs_b(func, x0=initial_values, args=(l_exp, s_exp, m_exp, t_exp), bounds=mybounds, approx_grad=True)
    

    我不确定边界是否正常工作。当我为E指定(0,无)时,我得到一个运行标志2,异常终止。如果我将其设置为(1e-6,无),它运行正常,但选择1e-6作为E。我是否正确指定了边界?

    我不想尝试找出您使用的模型代表了什么,因此下面是一个简单的拟合直线示例:

    x_true = arange(0,10,0.1) m_true = 2.5 b_true = 1.0 y_true = m_true*x_true + b_true def func(params, *args): x = args[0] y = args[1] m, b = params y_model = m*x+b error = y-y_model return sum(error**2) initial_values = numpy.array([1.0, 0.0]) mybounds = [(None,2), (None,None)] scipy.optimize.fmin_l_bfgs_b(func, x0=initial_values, args=(x_true,y_true), approx_grad=True) scipy.optimize.fmin_l_bfgs_b(func, x0=initial_values, args=(x_true, y_true), bounds=mybounds, approx_grad=True) x_真=arange(0,10,0.1) m_真=2.5 b_真=1.0 y_真=m_真*x_真+b_真 def func(参数,*args): x=args[0] y=args[1] m、 b=参数 y_模型=m*x+b 误差=y-y_模型 返回和(错误**2) 初始值=numpy.array([1.0,0.0]) mybounds=[(无,2),(无,无)] scipy.optimize.fmin\u l\u bfgs\u b(func,x0=初始值,args=(x\u真,y\u真),近似梯度=真) scipy.optimize.fmin\u l\u bfgs\u b(func,x0=初始值,args=(x\u真,y\u真),界限=我的界限,近似梯度=真) 第一个优化是无界的,并且给出了正确的答案,第二个优化考虑了阻止其达到正确参数的边界


    最重要的一点是,对于几乎所有的优化函数,“x”和“x0”都是指您正在优化的参数,其他所有参数都作为参数传递。fit函数返回正确的数据类型也很重要-这里我们需要一个值,一些例程需要一个错误向量。此外,您还需要“近似梯度=真实”标志,除非您希望通过分析计算梯度并提供它。

    谢谢,这帮助了我的理解。我更新了这个问题,仍然有一个关于E的边界的问题。@Benjamin-我看到的一个问题是,在你的模型中,A和E是不确定的。由于它们只出现在术语Al_exp*E中,它们可以同时变化而不影响模型值,因此不会有唯一的解决方案。似乎使用(0,无)将参数固定为0,而使用(0,10)则允许该范围内的值。