使用pyminui将函数拟合到数据

2024-06-26 07:39:16 发布

您现在位置:Python中文网/ 问答频道 /正文

我编写了一个Python(2.7)程序来评估一些科学数据。它的主要任务是使这些数据适合某个函数(1)。由于这是相当多的数据,程序使用多处理将作业(=“适合一组数据”)分配给多个核心。在第一次尝试中,我使用scipy.optimize公司效果很好。在

到目前为止,还不错。然后我们看到数据被更精确地描述为函数(1)和高斯分布的卷积。我们的想法是首先将数据拟合到函数(1)中,得到由此得到的猜测值,然后再将数据拟合到卷积上。由于数据非常嘈杂,我正试图将其拟合成七个参数的卷积,所以这次的结果相当糟糕。尤其是高斯参数在某种程度上是物理上不可能的。在

所以我尝试在PyMinuit中实现拟合过程,因为它允许将参数限制在特定的边界内(比如正振幅)。因为我以前从未使用过Minuit,所以我尝试从小处着手,所以我重写了拟合过程的第一部分(“简单”)。执行此操作的代码段如下所示(简化):

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几乎每次都会打印

^{pr2}$

为edm使用不同的值进行标准输出。fit仍然可以正常工作,但是打印会大大减慢程序的速度。我试着增加配合公差但是有很多数据集会返回更高的edm值偏头痛发作()使用实际有效的this solution。现在奇怪的事情发生了:在程序中间的某个地方,所有核心上的进程同时失败。一开始不是这样,而是在整个数据集中。我唯一改变的是

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)

Tags: 数据函数程序参数returnnp卷积fit