【问题标题】:python nonlinear least squares fittingpython非线性最小二乘拟合
【发布时间】:2016-10-06 23:39:01
【问题描述】:

就我的问题所涉及的数学而言,我有点超出我的深度,所以对于任何不正确的命名法,我深表歉意。

我正在考虑使用 scipy 函数 leastsq,但不确定它是否是正确的函数。 我有以下等式:

eq = lambda PLP,p0,l0,kd : 0.5*(-1-((p0+l0)/kd) + np.sqrt(4*(l0/kd)+(((l0-p0)/kd)-1)**2))

我有除 kd (PLP,p0,l0) 之外的所有术语的数据(8 组)。我需要通过上述方程的非线性回归来找到 kd 的值。 从我读过的例子来看,leastsq 似乎不允许输入数据,以获得我需要的输出。

感谢您的帮助

【问题讨论】:

    标签: python scipy nonlinear-optimization


    【解决方案1】:

    这是一个关于如何使用scipy.optimize.leastsq 的简单示例:

    import numpy as np
    import scipy.optimize as optimize
    import matplotlib.pylab as plt
    
    def func(kd,p0,l0):
        return 0.5*(-1-((p0+l0)/kd) + np.sqrt(4*(l0/kd)+(((l0-p0)/kd)-1)**2))
    

    residuals 的平方和是我们试图最小化的kd 的函数:

    def residuals(kd,p0,l0,PLP):
        return PLP - func(kd,p0,l0)
    

    在这里我生成一些随机数据。你会想在这里加载你的真实数据。

    N=1000
    kd_guess=3.5  # <-- You have to supply a guess for kd
    p0 = np.linspace(0,10,N)
    l0 = np.linspace(0,10,N)
    PLP = func(kd_guess,p0,l0)+(np.random.random(N)-0.5)*0.1
    
    kd,cov,infodict,mesg,ier = optimize.leastsq(
        residuals,kd_guess,args=(p0,l0,PLP),full_output=True,warning=True)
    
    print(kd)
    

    产生类似的东西

    3.49914274899
    

    这是optimize.leastsq 找到的kd 的最佳拟合值。

    这里我们使用刚刚找到的kd 的值生成PLP 的值:

    PLP_fit=func(kd,p0,l0)
    

    下面是PLPp0 的对比图。蓝线来自数据,红线是最佳拟合曲线。

    plt.plot(p0,PLP,'-b',p0,PLP_fit,'-r')
    plt.show()
    

    【讨论】:

    • 非常感谢,我添加了我的数据,但它不起作用。我一直在调整 kd_guess 值,但出现错误:ValueError:操作数无法与形状一起广播 (15) (8)
    • @Anake:听起来你的数据可能有不同的形状。尝试打印 len(PLP)len(p0)len(l0) 以确保它们都具有相同数量的项目。
    【解决方案2】:

    另一种选择是使用lmfit

    他们提供了一个很棒的example 来帮助您入门:。

    #!/usr/bin/env python
    #<examples/doc_basic.py>
    from lmfit import minimize, Minimizer, Parameters, Parameter, report_fit
    import numpy as np
    
    # create data to be fitted
    x = np.linspace(0, 15, 301)
    data = (5. * np.sin(2 * x - 0.1) * np.exp(-x*x*0.025) +
            np.random.normal(size=len(x), scale=0.2) )
    
    # define objective function: returns the array to be minimized
    def fcn2min(params, x, data):
        """ model decaying sine wave, subtract data"""
        amp = params['amp']
        shift = params['shift']
        omega = params['omega']
        decay = params['decay']
        model = amp * np.sin(x * omega + shift) * np.exp(-x*x*decay)
        return model - data
    
    # create a set of Parameters
    params = Parameters()
    params.add('amp',   value= 10,  min=0)
    params.add('decay', value= 0.1)
    params.add('shift', value= 0.0, min=-np.pi/2., max=np.pi/2)
    params.add('omega', value= 3.0)
    
    
    # do fit, here with leastsq model
    minner = Minimizer(fcn2min, params, fcn_args=(x, data))
    kws  = {'options': {'maxiter':10}}
    result = minner.minimize()
    
    
    # calculate final result
    final = data + result.residual
    
    # write error report
    report_fit(result)
    
    # try to plot results
    try:
        import pylab
        pylab.plot(x, data, 'k+')
        pylab.plot(x, final, 'r')
        pylab.show()
    except:
        pass
    
    #<end of examples/doc_basic.py>
    

    【讨论】:

    • 此链接已损坏。你还有这个例子,可以在这里发布吗?
    猜你喜欢
    • 2017-02-24
    • 1970-01-01
    • 2012-08-29
    • 1970-01-01
    • 2012-06-29
    • 2012-04-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多