Python - 使用lmfit来适应函数

时间:2018-01-01 19:00:53

标签: python scipy scikit-learn

我正在尝试使用lmfit,但获得参数的零星结果:

import numpy as np
import scipy.stats as sp
from scipy.optimize import curve_fit
from lmfit import minimize, Parameters, Parameter, report_fit

x = [0.01,
0.02,
0.03,
0.04,
0.05,
0.06,
0.07,
0.08,
0.09,
0.1,
0.2,
0.3,
0.4,
0.5,
0.6,
0.7,
0.8,
0.9,
0.99999999,]

#some paramters to try to estimate
sigma1 = 6
scale1 = np.exp(5)

#generate values to use to fit
y = sp.lognorm(sigma1,scale=scale1).ppf(x)

#function set-up to use in lmfit
def invlognorm(params,x,data):
    sigma = params['sigma']
    mu = params['mu']

    model = sp.lognorm(sigma,scale=mu).ppf(x)
    return model - data

params = Parameters()
params.add('sigma', value= 1,)
params.add('mu', value= 1, )
# do fit, here with leastsq model
result = minimize(invlognorm,params, method = 'least-squares',args=(x, y))

最后检查结果

result.params.pretty_print()
Name      Value      Min      Max   Stderr     Vary     Expr Brute_Step
mu        2.161     -inf      inf     None     True     None     None
sigma     6.754     -inf      inf     None     True     None     None

但这些远不及原始值。

对这里发生的事情有什么帮助以及如何解决这个问题,以便给出合理的结果?

1 个答案:

答案 0 :(得分:1)

您几乎肯定需要sigmamu参数的更好的起始值。

lognorm().ppf()函数在x=1处发散,给出了巨大的值,这些值将完全支配任何误差测量,例如卡方。 此外,参数值的微小变化对总失配基本没有影响,所有拟合算法都会很快放弃。 x=1的巨大价值也会使其他数据不敏感。也许你实际上是指lognorm pdfcdf的其他方法?

如果没有,您可能希望“适应日志空间” - 将数据日志与模型日志相匹配。这将降低x=1基准的重要性。

此外,虽然是导致问题的原因,但您的评价实际上并没有使用leastsq方法。要使用leastsq(Levenberg-Marquardt方法),请使用:

# do fit, here with leastsq model
result = minimize(invlognorm, params, args=(x, y))

使用scipy.optimize.least_squares(实际上使用信任区域反思使用

# do fit, here with least_squares model
result = minimize(invlognorm,params, method='least_squares', args=(x, y))

(请注意拼写。您的示例使用least-squares无法识别,因此会导致使用Nelder-Mead方法)。