首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >lmfit未探索参数空间

lmfit未探索参数空间
EN

Stack Overflow用户
提问于 2020-01-03 01:19:00
回答 1查看 849关注 0票数 2

我尝试使用lmfit通过ModelParameters类为一些随机数据找到函数的最佳拟合参数。然而,它似乎并没有过多地探索参数空间。它执行大约10次函数求值,然后返回一个糟糕的拟合结果。

代码如下:

代码语言:javascript
复制
import numpy as np
from lmfit.model import Model
from lmfit.parameter import Parameters
import matplotlib.pyplot as plt

def dip(x, loc, wid, dep):
    """Make a line with a dip in it"""
    # Array of ones
    y = np.ones_like(x)

    # Define start and end points of dip
    start = np.abs(x - (loc - (wid/2.))).argmin()
    end = np.abs(x - (loc + (wid/2.))).argmin()

    # Set depth of the dip
    y[start:end] *= dep

    return y

def fitter(x, loc, wid, dep, scatter=0.001, sigma=3):
    """Find the parameters of the dip function in random data"""
    # Make the lmfit model
    model = Model(dip)

    # Make random data and print input values
    rand_loc = abs(np.random.normal(loc, scale=0.02))
    rand_wid = abs(np.random.normal(wid, scale=0.03))
    rand_dep = abs(np.random.normal(dep, scale=0.005))
    print('rand_loc: {}\nrand_wid: {}\nrand_dep: {}\n'.format(rand_loc, rand_wid, rand_dep))
    data = dip(x, rand_loc, rand_wid, rand_dep) + np.random.normal(0, scatter, x.size)

    # Make parameter ranges
    params = Parameters()
    params.add('loc', value=loc, min=x.min(), max=x.max())
    params.add('wid', value=wid, min=0, max=x.max()-x.min())
    params.add('dep', value=dep, min=scatter*10, max=0.8)

    # Fit the data
    result = model.fit(data, x=x, params)
    print(result.fit_report())

    # Plot it
    plt.plot(x, data, 'bo')
    plt.plot(x, result.init_fit, 'k--', label='initial fit')
    plt.plot(x, result.best_fit, 'r-', label='best fit')
    plt.legend(loc='best')
    plt.show()

然后我运行:

代码语言:javascript
复制
fitter(np.linspace(55707.97, 55708.1, 100), loc=55708.02, wid=0.04, dep=0.98)

它返回(例如,因为它是随机数据):

代码语言:javascript
复制
rand_loc: 55707.99659784677
rand_wid: 0.02015076619874132
rand_dep: 0.9849809461153651

[[Model]]
    Model(dip)
[[Fit Statistics]]
    # fitting method   = leastsq
    # function evals   = 9
    # data points      = 100
    # variables        = 3
    chi-square         = 0.00336780
    reduced chi-square = 3.4720e-05
    Akaike info crit   = -1023.86668
    Bayesian info crit = -1016.05117
##  Warning: uncertainties could not be estimated:
    loc:  at initial value
    wid:  at initial value
[[Variables]]
    loc:  55708.0200 (init = 55708.02)
    wid:  0.04000000 (init = 0.04)
    dep:  0.99754082 (init = 0.98)

你知道为什么它只执行这么少的函数求值返回一个不合适的函数吗?任何与此相关的帮助都将不胜感激!

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2020-01-03 23:24:17

这是一个与fitting step function with variation in the step location with scipy optimize curve_fit类似的问题。参见https://stackoverflow.com/a/59504874/5179748

基本上,scipy.optimize/lmfit中的求解器假定参数是连续的,而不是离散的变量。他们对参数做了一些小的修改,看看这对结果有什么影响。locwid参数的微小更改不会对结果产生任何影响,因为argmin()将始终返回整数值。

您可能会发现,使用有限宽度的矩形模型(请参阅https://lmfit.github.io/lmfit-py/builtin_models.html#rectanglemodel)会很有帮助。我对您的示例做了一些修改,但这应该足以让您入门:

代码语言:javascript
复制
import numpy as np
import matplotlib.pyplot as plt
from lmfit.models import RectangleModel, ConstantModel

def dip(x, loc, wid, dep):
    """Make a line with a dip in it"""
    # Array of ones
    y = np.ones_like(x)

    # Define start and end points of dip
    start = np.abs(x - (loc - (wid/2.))).argmin()
    end = np.abs(x - (loc + (wid/2.))).argmin()

    # Set depth of the dip
    y[start:end] *= dep
    return y

x = np.linspace(0, 1, 201)
data = dip(x, 0.3, 0.09, 0.98) + np.random.normal(0, 0.001, x.size)

model = RectangleModel() + ConstantModel()
params = model.make_params(c=1.0, amplitude=-0.01, center1=.100, center2=0.7, sigma1=0.15)

params['sigma2'].expr = 'sigma1' # force left and right widths to be the same size
params['c'].vary = False         # force offset = 1.0 : value away from "dip"


result = model.fit(data, params, x=x)
print(result.fit_report())

plt.plot(x, data, 'bo')
plt.plot(x, result.init_fit, 'k--', label='initial fit')
plt.plot(x, result.best_fit, 'r-', label='best fit')
plt.legend(loc='best')
plt.show()
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/59567399

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档