在使用lmfit进行最小化时,如何解决“函数返回的数组在调用之间改变大小”的问题?

时间:2019-07-10 08:49:27

标签: python anaconda minimization lmfit

使用null进行最小化时,如何解决错误为“函数返回的数组在调用之间改变大小”的错误代码?

请在下面找到我的代码:

lmfit

这是错误消息:

import numpy as np
import pandas as pd
import lmfit as lf

#model needs to be fitted
x0 = 75
def func(params, x, Tsky):
    A = params['amp']
    w = params['width']
    t = params['thickness']
    v0 = params['mid_freq']
    b0 = params['b0']
    b1 = params['b1']
    b2 = params['b2']
    b3 = params['b3']
    b4 = params['b4']
    B = (4 * (x - v0)**2. / w**2.) * np.log(-1./t * np.log((1 + np.exp(-t))/2))
    T21 = -A * (1 - np.exp(-t * np.exp(B)))/(1 - np.exp(-t))
    model = T21 + b0 * ((x/x0)**(-2.5 + b1 + b2 * np.log(x/x0))) * np.exp(-b3*(x/x0)**-2.) + b4 *  (x/x0)**-2.
    return (Tsky-model)

#read the data
df = pd.read_csv('figure1_plotdata.csv')
data_list = df.T.values.tolist()
xdata = np.array(data_list[0])
Tsky = np.array(data_list[2])

#initial value of the parameters
params = lf.Parameters()
params.add('amp', value=0.2)
params.add('width', value=10)
params.add('thickness', value=5)
params.add('mid_freq', value=70)
params.add('b0', value=500)
params.add('b1', value=-0.5)
params.add('b2', value=-0.5)
params.add('b3', value=-0.5)
params.add('b4', value=500)

#minimize the function
out = lf.minimize(func, params, args=(xdata, Tsky), method='leastsq', kws=None, iter_cb=None, scale_covar=True, nan_policy='omit', calc_covar=True)

print(lf.fit_report(out))

1 个答案:

答案 0 :(得分:0)

如果您曾经使用过

import seaborn as sns 

g = sns.catplot(data=df, x='xvar', y='yvar', hue='hue_bar')
g.fig.set_figheight(8.27)
g.fig.set_figheight(11.7)

您会看到一个异常提示您存在NaN。当您使用out = lf.minimize(func, params,...,nan_policy='raise') 时,将从残留数组中删除由模型生成的任何此类NaN,因此,两次调用之间的数组大小会发生变化。该配件无法处理NaN或更改数组大小-您必须消除它们。

特别是,nan_policy='omit'np.log(x)时为NaN。您有一个复杂的参数x<0,该参数取决于参数np.log()的值。如果对于某个t值,该参数低于0,则该模型具有NaN,并且没有意义。 您将必须确保该参数不能小于0。这可能是因为 使用

t

就足够了。但是您应该更详细地检查模型,并确定是否有意义。

您的模型对我来说看起来很复杂。我无法猜出这种模型的来源。取多个params.add('thickness', value=5, min=0) np.exp()有点要求数值不稳定性。因此,我不知道简单地将np.log()强制为正数会很合适,但它可能会为您指明正确的方向。