【问题标题】:Python LMFIT restriction fit parametersPython LMFIT 限制拟合参数
【发布时间】:2018-10-20 22:04:18
【问题描述】:

我正在尝试使用用于非线性函数的 LMFIT 库将函数拟合到 Python 中的某些数据。这很容易,但我想知道是否有办法限制拟合值的某些属性。

例如,在下面的代码中,我拟合我的数据以优化值 A、B 和 C。但我还希望 A 与 B 的比率为 pi/4 乘以某个整数。有没有办法施加这种限制?

from lmfit import  Model
import numpy
from numpy import cos, sin, pi, linspace

上传数据:

data = numpy.genfromtxt('data')
axis = numpy.genfromtxt('axis')

定义函数:

def func(x, A, B, C):
return (A*cos(x)*cos(x) + B*sin(x)*sin(x) + 2*C*sin(x)*cos(x))**2

我必须对我的参数进行初步猜测:

a = 0.009 
b = 0.3 
c = 0.3 

然后创建一个模型来适应我的功能:

func_model = Model(func)

用初始猜测(A = a,B = b,C = c)将函数拟合到输入数据:

result = func_model.fit(data, x=axis, A = a, B = b, C = c) 
fitted_vals = result.best_values #dictionary structure
Afit = fitted_vals['A']
Bfit = fitted_vals['B']
Cfit = fitted_vals['C']

如何确定 Afit 与 Bfit 的比值是 pi/4 乘以某个整数?

如果不可能,是否有人知道具有此功能的软件?

【问题讨论】:

    标签: python data-fitting model-fitting lmfit


    【解决方案1】:

    标准拟合的问题在于雅可比的估计。如果参数是离散的,则导数几乎处处为零。一种解决方法可能是使用带有自定义残差函数的leastsq 并另外提供导数。可以将残差函数中的参数设置为离散的,但在导数中使其连续。我不是说这是解决这类问题的通用方法,但如果是 OP 的功能,它就可以正常工作。

    编辑 - 代码为:

    # -*- coding: utf-8 -*-
    import matplotlib.pyplot as plt
    import numpy as np
    from scipy.optimize import leastsq
    
    def f0( x, A, B, C ):
        return ( A * np.cos( x )**2 + B * np.sin( x )**2 + 2 * C * np.sin( x ) * np.cos( x ) )
    
    def func(x, A, B, C):
        return f0( x, A, B, C )**2
    
    a = 0.009
    b = 0.3
    c = 0.4
    
    xList = np.linspace( -1, 6, 500 )
    yList = np.fromiter( ( func( x, a, b, c ) for x in xList ), np.float )
    
    
    def residuals( p, x, y ):
        return func(x, p[0], int(p[1]) * np.pi / 2. * p[0], p[2] ) - y
    
    def dfunc( p, x, y ):     #Derivative
        return [ 
            f0( x, p[0], int( p[1] ) * np.pi / 2. * p[0] , p[2] ) * ( np.cos( x )**2 + p[1] * np.pi / 2. * np.sin( x )**2 ),
            f0( x, p[0], int( p[1] ) * np.pi / 2. * p[0] , p[2] ) * ( p[0] * np.pi / 2.* np.sin( x )**2 ),
            f0( x, p[0], int( p[1] ) * np.pi / 2. * p[0] , p[2] ) * ( 2 * np.sin( x ) * np.cos( x ) ),
         ]
    
    plsq, cov, infodict, mesg, ier = leastsq( residuals, [ 0.009, .3/.01, .4 ], args=( xList, yList ), Dfun=dfunc, col_deriv=1, full_output=True )
    
    fit = func(xList, plsq[0], int( plsq[1] ) * np.pi / 2. * plsq[0],  plsq[2] )
    print plsq
    print int( plsq[1] ) 
    fig1 = plt.figure( 1, figsize=( 6, 4 ), dpi=80 )
    ax = fig1.add_subplot( 1, 1, 1 )
    ax.plot( xList, yList )
    ax.plot( xList, fit, ls='--')
    plt.show()
    

    提供:

    >>[8.68421935e-03 2.22248626e+01 4.00032135e-01]
    >>22
    

    【讨论】:

    • 这是一个有趣的建议。你能发布代码来说明你将如何做到这一点吗?
    • @MNewville 给你
    • 谢谢——这是欺骗雅可比信息处理离散变量的一个很好的例子。就像你说的,它不适用于很多问题,但它可能会激发类似的案例。
    【解决方案2】:

    我认为答案是否定的。 scipy.optimize 中的求解器 lmfit 包装不支持离散变量,仅支持连续变量。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2022-10-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-05-24
      • 2014-12-17
      • 1970-01-01
      相关资源
      最近更新 更多