Python 如何拟合指数衰减曲线来解释不确定性?

Python 如何拟合指数衰减曲线来解释不确定性?,python,matplotlib,exponential,errorbar,lmfit,Python,Matplotlib,Exponential,Errorbar,Lmfit,我有一些放射性衰变数据,在x和y上都有不确定性。图本身很好,但我需要绘制指数衰减曲线,并从拟合返回报告,以找到半衰期,并减少chi^2 图表的代码为: fig, ax = plt.subplots(figsize=(14, 8)) ax.errorbar(ts, amps, xerr=2, yerr=sqrt(amps), fmt="ko-", capsize = 5, capthick= 2, elinewidth=3, markersize=5) plt

我有一些放射性衰变数据,在x和y上都有不确定性。图本身很好,但我需要绘制指数衰减曲线,并从拟合返回报告,以找到半衰期,并减少chi^2

图表的代码为:

 fig, ax = plt.subplots(figsize=(14, 8))
    ax.errorbar(ts, amps, xerr=2, yerr=sqrt(amps), fmt="ko-", capsize = 5, capthick= 2, elinewidth=3, markersize=5)
    plt.xlabel('Time  /s', fontsize=14)
    plt.ylabel('Counts Recorded in the Previous 15 seconds', fontsize=16)
    plt.title("Decay curve of P-31 by $β^+$ emission", fontsize=16)
我正在使用的模型(承认我对我的编程没有信心)是:

但我认为这并没有考虑到不确定性,只是将它们绘制在图表上。考虑到不确定性,我希望它能够拟合指数衰减曲线,并返回半衰期(在本例中为t)和具有各自不确定性的简化chi^2

目标类似下图,但考虑到配件的不确定性:

使用
weight=1/sqrt(amps)
建议和完整的数据集,我得到:


我想,这是这个数据可能的最佳拟合(chi减少为3.89)。我希望它能给我t=150秒,但是,嘿,那个在实验中。谢谢大家的帮助。

您可以使用参数指定权重。要对不确定性较小的值赋予更多权重,请使用例如
1/不确定性

然而,示例中的不确定性问题是,它们直接取决于振幅值(
不确定性=np.sqrt(安培)
)。如果你使用这种不确定性,它们只会使拟合曲线向下移动。因此,只有当你的不确定性是从某种测量中获得的真实不确定性时,这种方法才有意义

例如:

import matplotlib.pyplot as plt
import numpy as np
import lmfit

ts = np.array([ 15,  32,  51, 106, 123, 142, 160, 177, 196, 213, 232, 249, 269, 286, 323, 340, 359, 375, 394, 466, 484, 520, 539, 645, 681])
amps = np.array([78, 64, 64, 42, 42, 15, 34, 29, 34, 31, 31, 22,  5,  6,  8,  4, 11, 14, 14,  1,  2, 10,  4,  3,  1])
emodel = lmfit.Model(lambda x,t,A: A*np.exp(-x/t))

plt.errorbar(ts, amps, xerr=2, yerr=np.sqrt(amps), fmt="ko-", capsize = 5)
plt.plot(ts, emodel.fit(amps, x=ts, t=150, A=140).best_fit, 'r-', label='best fit')
plt.plot(ts, emodel.fit(amps, x=ts, weights=1/np.sqrt(amps), t=150, A=140).best_fit, 'r--', label='weighted best fit (1/err)')
plt.plot(ts, emodel.fit(amps, x=ts, weights=1/amps, t=150, A=140).best_fit, 'r:', label='weighted best fit (1/err²)')
plt.legend()

Scipy曲线拟合具有加权拟合的功能。您还应该包括您用于当前拟合的库的信息-可能有一个选项您不知道。您可以指定
weights=1/yerr
,其中
yerr
是具有不确定性的numpy数组,但如果您使用
yerr=sqrt(amps)
就像你的例子一样,我想你不会有太大的改进
lmfit
的使用是不言自明的。我不太了解这个图书馆,但也许@m-newville会帮助你。然而,正如Stef所说,看着你发布的图片,你不能对加权拟合期望过高。原始数据非常嘈杂,拟合看起来相当不错。我不知道在拟合过程中考虑不确定性的方法(这并不意味着没有)。不,太模糊了,我不喜欢。也许其他人有更重要的贡献。这里的数据点是从实验中获得的测量值。我使用的是YER=sqrt(amps),因为这是一个放射性衰变实验,衰变测量的不确定度被定义为测量的平方根,因为这是一个随机过程。因此,正如你所建议的那样,我们应该采用加权法。是什么决定了我们应该使用1/err、1/err^2,还是任何其他随着误差变小而变大的函数?我不是统计学家,但我认为这不能先验地决定什么是最佳权重。因此,一种常见的方法是首先不使用权重进行拟合,然后根据偏差δ=abs(y-y(fitted))确定权重,例如使用w=1/max(δ,eps),其中eps是一个下限。例如,参见第3.3章或。我想你最好继续问这个问题。我用我最喜欢的在线数字化仪获取数据。没有区别,只是为了简洁起见,让示例更紧凑。像您这样使用常规函数是绝对好的。@Stef做得好!我可能建议打印出
t
amp
参数的值(和不确定性!)。
import matplotlib.pyplot as plt
import numpy as np
import lmfit

ts = np.array([ 15,  32,  51, 106, 123, 142, 160, 177, 196, 213, 232, 249, 269, 286, 323, 340, 359, 375, 394, 466, 484, 520, 539, 645, 681])
amps = np.array([78, 64, 64, 42, 42, 15, 34, 29, 34, 31, 31, 22,  5,  6,  8,  4, 11, 14, 14,  1,  2, 10,  4,  3,  1])
emodel = lmfit.Model(lambda x,t,A: A*np.exp(-x/t))

plt.errorbar(ts, amps, xerr=2, yerr=np.sqrt(amps), fmt="ko-", capsize = 5)
plt.plot(ts, emodel.fit(amps, x=ts, t=150, A=140).best_fit, 'r-', label='best fit')
plt.plot(ts, emodel.fit(amps, x=ts, weights=1/np.sqrt(amps), t=150, A=140).best_fit, 'r--', label='weighted best fit (1/err)')
plt.plot(ts, emodel.fit(amps, x=ts, weights=1/amps, t=150, A=140).best_fit, 'r:', label='weighted best fit (1/err²)')
plt.legend()