使用pyminuit将函数拟合到数据

时间:2014-07-31 12:27:50

标签: python curve-fitting pyminuit

我写了一个Python(2.7)程序来评估一些科学数据。它的主要任务是将这些数据拟合到某个函数(1)。由于这是相当多的数据,程序使用多处理将作业(="适合一组数据")分配到多个核心。在第一次尝试中,我使用scipy.optimize中的curve_fit实现了拟合过程,该过程非常有效。

到目前为止,这么好。然后我们看到数据通过函数(1)和高斯分布的卷积更精确地描述。我们的想法是先将数据拟合到函数(1),得到猜测值,然后再将数据拟合到卷积中。由于数据非常嘈杂,我试图将其与七个参数的卷积相匹配,结果这次非常糟糕。特别是高斯参数在某种程度上是不可能的。

所以我尝试在PyMinuit中实现拟合过程,因为它允许限制某些边界内的参数(如正幅度)。由于我之前从未和Minuit合作过,所以我尝试从小开始,我重写了第一个(#34; easy")部分的拟合过程。执行该作业的代码片段如下所示(简化):

import minuit
import numpy as np
# temps are the x-values
# pol are the y-values
def gettc(temps, pol, guess_values):
    try:
        efunc_chi2 = lambda a,b,c,d: np.sum( (efunc(temps, a,b,c,d) - pol)**2 )
        fit = minuit.Minuit(efunc_chi2)
        fit.values['a'] = guess_values[0]
        fit.values['b'] = guess_values[1]
        fit.values['c'] = guess_values[2]
        fit.values['d'] = guess_values[3]
        fit.fixed['d'] = True
        fit.maxcalls = 1000
        #fit.tol = 1000.0
        fit.migrad()
        param = fit.args
        popc = fit.covariance
    except minuit.MinuitError:
        return np.zeros(len(guess_values))
    return param,popc

其中efunc()是函数(1)。参数d是固定的,因为我暂时不使用它 PyMinuit function reference
最后,出现了实际问题:在运行脚本时,Minuit几乎可以打印所有适合的

VariableMetricBuilder: Tolerance is not sufficient - edm is 0.000370555 requested 1e-05 continue the minimization

使用不同的edm值的stdout。适合仍然可以正常工作,但打印速度大大降低了程序。我试图增加fit.tol但是有很多数据集可以返回更高的edm。然后我尝试使用实际有效的this solution隐藏fit.migrad()的输出。现在发生了一些奇怪的事情:在程序中间的某个地方,所有核心上的进程同时失败。不是第一次适合,而是在我整个数据集的中间。我唯一改变的是

with suppress_stdout_stderr():
    fit.migrad()

我知道这是一个很长的介绍,但我认为当你了解整个框架时它会对你有所帮助。如果有人知道如何处理这个问题,我将非常感激。


注意:函数(1)定义为

def efunc(x,a,b,c,d):
    if x < c:
        return a*np.exp(b*x**d)
    else:
        return a*np.exp(b*c**d)   # therefore constant
efunc = np.vectorize(efunc)

0 个答案:

没有答案