我正致力于将muon寿命数据拟合到曲线中,以使用lmfit函数提取平均寿命。我使用的一般过程是使用直方图函数将13,000个数据点分成10个区间,用每个区间中的计数的平方根计算不确定性(它是一个指数模型),然后使用lmfit模块确定最佳拟合以及均值和不确定性。但是,绘制model.fit()方法的输出图形会返回此图形,其中红线是合适的(显然不是正确的拟合)。 Fit result output graph
我已经在线查看过,无法找到解决方案,我真的很感激帮助找出正在发生的事情。这是代码。
import os
import numpy as np
import matplotlib.pyplot as plt
from numpy import sqrt, pi, exp, linspace
from lmfit import Model
class data():
def __init__(self,file_name):
times_dirty = sorted(np.genfromtxt(file_name, delimiter=' ',unpack=False)[:,0])
self.times = []
for i in range(len(times_dirty)):
if times_dirty[i]<40000:
self.times.append(times_dirty[i])
self.counts = []
self.binBounds = []
self.uncertainties = []
self.means = []
def binData(self,k):
self.counts, self.binBounds = np.histogram(self.times, bins=k)
self.binBounds = self.binBounds[:-1]
def calcStats(self):
if len(self.counts)==0:
print('Run binData function first')
else:
self.uncertainties = sqrt(self.counts)
def plotData(self,fit):
plt.errorbar(self.binBounds, self.counts, yerr=self.uncertainties, fmt='bo')
plt.plot(self.binBounds, fit.init_fit, 'k--')
plt.plot(self.binBounds, fit.best_fit, 'r')
plt.show()
def decay(t, N, lamb, B):
return N * lamb * exp(-lamb * t) +B
def main():
muonEvents = data('C:\Users\Colt\Downloads\muon.data')
muonEvents.binData(10)
muonEvents.calcStats()
mod = Model(decay)
result = mod.fit(muonEvents.counts, t=muonEvents.binBounds, N=1, lamb=1, B = 1)
muonEvents.plotData(result)
print(result.fit_report())
print (len(muonEvents.times))
if __name__ == "__main__":
main()
答案 0 :(得分:0)
这可能是一个简单的缩放问题。作为快速测试,尝试将所有原始数据除以因子1000(X和Y),以查看更改数据的大小是否有任何影响。
答案 1 :(得分:0)
为了建立James Phillips的答案,我认为你在图表中显示的数据意味着N,lamb和B的值与1,1,1非常不同。请记住exp(-lamb * t对于lamb = 1,t基本上为0,并且t> 100.因此,如果算法从lamb = 1开始并稍微改变以找到更好的值,那么它实际上无法看到模型与数据的匹配程度有任何差异。
我建议尝试从对你的数据更合理的值开始,也许N = 1.e6,lamb = 1.e-4,B = 100。
正如James建议的那样,让变量的值大约为1,并根据需要加入比例因子通常有助于获得数值稳定的解决方案。