首页 > 解决方案 > 如何确定使用 lmfit 进行曲线拟合的初始参数值

问题描述

我目前正在对来自 DMA 测试(流变学)的几个数据进行非线性拟合。对于我目前正在使用的数据,该程序可以工作,但我希望程序能够灵活地使曲线拟合的起始参数取决于我的数据输入。有没有办法确定这一点?

也许是蒙特卡洛方法,但我不知道从哪里开始。

这是我的代码,提前谢谢!:

def calc_gmm(dframe):
    array_omega = np.array(dframe['Angular Frequency']).flatten()
    array_G_storage = np.array(dframe['Storage Modulus']).flatten()
    array_G_loss = np.array(dframe['Loss Modulus']).flatten()

    chisqr = 99999999999;
    j=1


    fig, (ax1,ax2) = plt.subplots(nrows=2, ncols=1)


    while j <= 10:
        params = lmfit.Parameters()

        # Adding amount n of parameters and G0, start values were determined by trial and error
        params.add('n', value=j, vary=False, min=1, max=10)
        params.add('G0', value=0.4, min=0)
        for i in range(params['n'].value):
            params.add(f't_{i}', value=0.5, min=0)
            params.add(f'g_{i}', value=17, min=0)

        # Minimization function
        res = lmfit.minimize(min_function, params, args=(array_omega, array_G_storage, array_G_loss))

        # Determining the smallest chi-squared in order to develop a criterium to stop iterating over different orders
        if res.chisqr < chisqr*0.5:
            chisqr = res.chisqr
            ax1.plot(array_omega, array_G_storage + res.residual, label='n: '+ (str)(j))
            ax2.plot(array_omega, array_G_loss + res.residual, label='n: '+ (str)(j))
            j += 1
        else:
            params = lmfit.Parameters()
            j -= 1
            # Adding amount n of parameters and G0, start values were determined by trial and error
            params.add('n', value=j, vary=False, min=1, max=10)
            params.add('G0', value=0.4, min=0)
            for i in range(params['n'].value):
                params.add(f't_{i}', value=0.5, min=0)
                params.add(f'g_{i}', value=17, min=0)

            # Minimization function
            res = lmfit.minimize(min_function, params, args=(array_omega, array_G_storage, array_G_loss))

            j = 11

标签: pythoncurve-fittingmodel-fitting

解决方案


一般来说,答案是“否”——参数值的适当范围将取决于目标函数对参数的作用。就像,为了清楚起见,它可以首先将所有 't_N' 参数乘以 1e-6。用户需要知道函数将如何处理参数。由于您确实在拟合实验数据,因此您可以(例如)断言参数的单位是什么。

但是,如果你有一个稳定的函数定义和一些单位或参数的明确定义,你也许可以想出一套不错的起始参数。

对于 lmfit 中的许多模型函数(请参阅https://github.com/lmfit/lmfit-py/blob/master/lmfit/models.py),我们可以对一组数据做出不错的猜测。就像,对于一个类似峰的函数,你可以说质心应该在数据的最大强度点附近,等等。对于一个数据集,可以在没有太多工作的情况下找到半高全宽,然后“ sigma" 可能在其中的一半左右。

为其他功能这样做需要一些启发式和常识,但它应该是可行的。


推荐阅读