拟合模型中数据集的参数

时间:2020-05-07 23:47:50

标签: python lmfit scipy-optimize-minimize

我正在尝试拟合交通灯曲线的参数。

我观察到了过渡光曲线数据,我在python中使用了.py,它通过4个参数(周期,a(半长轴),倾斜度,行星半径)返回了模型过渡光曲线。我想最小化这两条光曲线之间的残差。这就是我要做的事情:首先-使用method =“ L-BFGS-B”估计最大似然,然后使用emcee应用mcmc来估计不确定性。

代码:

p = lmfit.Parameters()
p.add_many(('per', 2.), ('inc', 90.), ('a', 5.), ('rp', 0.1))

per_b = [1., 3.]
a_b = [4., 6.]
inc_b = [88., 90.]
rp_b = [0.1, 0.3]

bounds = [(per_b[0], per_b[1]), (inc_b[0], inc_b[1]), (a_b[0], a_b[1]), (rp_b[0], rp_b[1])]

def residual(p):
    v = p.valuesdict()

    eclipse.criarEclipse(v['per'], v['a'], v['inc'], v['rp'])
    lc0 = numpy.array(eclipse.getCurvaLuz())   (observed flux data)
    ts0 = numpy.array(eclipse.getTempoHoras())   (observed time data)

    c = numpy.linspace(min(time_phased[bb]),max(time_phased[bb]),len(time_phased[bb]),endpoint=True)
    nn = interpolate.interp1d(ts0,lc0)

    return nn(c) - smoothed_LC[bb] (residual between the model and the data)

在def残差(p)内,我确保所观察到的数据(time_phased [bb]和smoothed_LC [bb])具有与模型过渡光曲线相同的大小。我希望它为我提供最适合参数的值(v ['per'],v ['a'],v ['inc'],v ['rp'])。

我需要您的帮助,感谢您的宝贵时间和关注。亲切的问候,尤里。

1 个答案:

答案 0 :(得分:0)

您的示例不完整,包含许多局部概念和一些无效的Python。这使您很难理解您的意图。如果下面的答案还不够,请使用完整的示例更新您的问题。

很显然,您希望使用某种模型来对数据smoothed_LC[bb](不确定bb是什么)进行建模,以产生某种日蚀效果。基于这种假设,我建议使用lmfit.Model方法。首先编写一个对数据进行建模的函数,以便检查并绘制模型。我不能完全确定我了解您所做的一切,但是此模型函数可能看起来像这样:

import numpy
from scipy import interpolate
from lmfit import Model
# import eclipse from somewhere....

def eclipse_lc(c, per, a, inc, p): 
    eclipse.criarEclipse(per, a, inc, rp)
    lc0 = numpy.array(eclipse.getCurvaLuz())   # observed flux data
    ts0 = numpy.array(eclipse.getTempoHoras()) # observed time data
    return interpolate.interp1d(ts0,lc0)(c)

使用此模型功能,您可以构建模型:

lc_model = Model(eclipse_lc)

,然后为您的模型构建参数。这将自动以模型函数的参数名称命名它们。在这里,您还可以为其指定初始值:

params = lc_model.make_params(per=2, inc=90, a=5, rp=0.1)

您想在这些参数上设置上限和下限。这是通过设置minmax参数来完成的,而不是对边界进行有序排列:

params['per'].min = 1.0
params['per'].max = 3.0

,依此类推。而且:设置如此严格的界限通常不是一个好主意。设置边界以避免非自然的参数值,或者当您明显需要放置它们时。

现在,您可以使用此模型拟合数据。好吧,首先,您需要获取要建模的数据。从您的示例来看,这似乎不太清楚,但是也许:

   c_data = numpy.linspace(min(time_phased[bb]), max(time_phased[bb]),
                           len(time_phased[bb]), endpoint=True)
   lc_data = smoothed_LC[bb]

嗯:为什么需要制作这个c_data?为什么不只使用time_phased作为自变量?无论如何,现在您可以使用参数使数据适合模型:

   result = lc_model(lc_data, params, c=c_data)

这时,您可以打印出结果报告和/或查看或获取最适合的数组:

   print(result.fit_report())

   for p in result.params.items(): print(p)

   import matplotlib.pyplot as plt
   plt.plot(c_data, lc_data, label='data')
   plt.plot(c_data. result.best_fit, label='fit')
   plt.legend()
   plt.show()

希望有帮助...