我正在尝试使用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
但这些远不及原始值。
对这里发生的事情有什么帮助以及如何解决这个问题,以便给出合理的结果?
答案 0 :(得分:1)
您几乎肯定需要sigma
和mu
参数的更好的起始值。
lognorm().ppf()
函数在x=1
处发散,给出了巨大的值,这些值将完全支配任何误差测量,例如卡方。
此外,参数值的微小变化对总失配基本没有影响,所有拟合算法都会很快放弃。 x=1
的巨大价值也会使其他数据不敏感。也许你实际上是指lognorm
pdf
或cdf
的其他方法?
如果没有,您可能希望“适应日志空间” - 将数据日志与模型日志相匹配。这将降低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方法)。