来自 scipy.optimize.curve_fit 的 TypeError

计算科学 Python 统计数据
2021-11-30 19:11:43

我正在尝试使用 scipy 将数据集拟合到指数模型。但是,返回的协方差矩阵是“inf”,我收到以下错误:

回溯(最近一次通话最后一次):文件“C:\Users\Christopher\Desktop\advancedLab\03_ML_Mogni\analyzeTHIS.py”,第 21 行,在 print 'A = ', ans[0], '+/-', cov [0][0] TypeError: 'float' 对象没有属性 '__getitem__'

现在,我不明白为什么我的协方差矩阵返回为无限......我知道这是此错误消息的来源。我的数据集有时间,在 400 到 20000 单位之间,概率在 0.005 到 0.3 单位之间,以及它们各自的标准差。这是我的代码:

import numpy
import scipy.optimize, scipy.stats.stats
import pylab

use = raw_input('File: ')

time = numpy.loadtxt(use + 'time.txt', unpack = 'True')
prob = numpy.loadtxt(use + 'prob.txt', unpack = 'True')
std = numpy.loadtxt(use + 'std.txt', unpack = 'True')
stdProb = numpy.loadtxt(use + 'stdProb.txt', unpack = 'True')

guess = prob
guess.tolist()

def muon_model(x,A):
    return A*numpy.exp(-A*x)

ans, cov = scipy.optimize.curve_fit(muon_model, time, prob, p0 = 2200, sigma = stdProb, maxfev = 10000)

print cov
print 'A = ', ans[0], '+/-', cov[0][0]

numpy.savetxt(use + '_counts_best_fit.txt', ans)
numpy.savetxt(use + '_counts_cov.txt', cov)

x = numpy.linspace(0,22000,500)
y = ans[0]*numpy.exp(-ans[0]*x)

model = muon_model(time,ans[0])
pylab.plot(x,y,label='Model')
pylab.errorbar(time, prob, xerr = std, yerr = stdProb, label = 'Data', fmt = 'o')
pylab.legend()
pylab.xlabel('Time (nanoseconds)')
pylab.ylabel('Probability')
pylab.savefig(use + '_counts_with_fit.png')
pylab.clf()

mod = []
ind = 0
while ind < len(time):
    mod.append(math.exp(-1000*ans[0]*ind) - math.exp(-1000*ans[0]*(ind + 1)))
residual = prob - mod

chisq = (residual**2/std**2).sum()
dof = len(counts)-len(ans)
print 'Chi-Sq = ', chisq
print 'dof = ', dof
print 'Reduced Chi-Sq = ', chisq/dof
print 'PTE = ', scipy.stats.stats.chisqprob(chisq,dof)

任何帮助将不胜感激。

编辑: 我将猜测参数更改为 0.5,因为我输入了错误的猜测。我仍然得到了相同的答案。不幸的是,我的数据点不是等间距的。我所做的是以 1000 个单位间隔对我的时间进行分类,并将我在那个 bin 中的数据点作为那个 bin 中所有值的平均值。无论我使用哪种猜测,我仍然会遇到相同的错误。

1个回答

欢迎来到 SciComp。首先,如果您需要纯指数拟合并且拥有等距数据,Prony 的方法(参见expfit以了解 Octave 中的实现,可以轻松移植到 Python)更合适(并且数值稳定)。

也就是说,如果我查看您对参数 (2200) 的初始猜测并且您说您的时间跨度从 0 到 22000,那么您的指数模型将在很多时间(以双精度)给出零。这将导致数值问题。你确定这个参数(没有缩放错误)?如果这不是问题,您能否在某个地方提供(较小版本的)您的数据集?

免责声明:我是 Octave 的 expfit 函数的原作者(但后来被其他人改进)。