用泊松函数拟合直方图

Fitting an histogram with a poisson function

我正在尝试用泊松函数拟合直方图。我正在关注网站上的一些答案,但我无法解决问题。 我只是想使用 python 3.6.

来拟合下面直方图条的上行线,使用泊松函数

我正在尝试这个:

import numpy as np
import matplotlib.pyplot as plt
from scipy.optimize import curve_fit
from scipy.special import factorial

def poisson(k, lamb):
   return (lamb**k/factorial(k))*np.exp(-lamb)
 
fig, ax = plt.subplots()
ax.hist(magz,bins=10,alpha=0.3)
y,x=np.histogram(magz,bins=10)

x = x + (x[1]-x[0])/2
x = np.delete(x,-1)
parameters, cov_matrix = curve_fit(poisson, x, y)
x_new = np.linspace(x[1], x[-1], 50)
ax.plot(x_new, poisson(x_new, *parameters), color='b')

结果是:

蓝色拟合线在图的底部,似乎不起作用。

magz值为:

magz = [ 24.638505,  20.446914,  22.10271,   21.227533,  21.761152,  18.923867,
  24.054868,  23.92457,   21.515022,  21.835458,  21.204597,  21.848573,
  24.036382,  21.126777,  21.599414,  20.044833,  24.390594,  23.772577,
  19.608918,  22.676774,  23.6312,    24.12077,   21.22321,   20.350204,
  20.548614,  22.650914,  20.561528,  24.892959,  22.49959,   22.94469,
  24.346355,  23.934491,  22.448417,  20.535562,  20.785362,  25.131568,
  24.462043,  24.173652,  19.105512,  20.641586,  19.5268,    25.0747,    23.254556,
  24.460447,  24.37759,   22.708406,  20.765025,  17.27031,   22.723192,  22.4452,
  23.366233,  23.238118,  20.72437,   22.278445,  22.231206,  20.98687,
  20.341756,  22.968032,  22.504077,  21.277349,  19.163532,  22.44034,
  22.406581,  21.999019,  23.313155,  17.945062,  23.027715,  23.640596,
  20.60174,   20.124156,  22.39343,   23.786641,  25.201003,  25.227441,
  22.537135,  23.779794,  19.416995,  23.550315,  23.225908,  22.579364,
  21.69014,   20.50741,   22.543212,  21.640962,  20.425422,  23.793624,
  20.554366,  23.522594,  21.03864,   18.282573,  17.33285,   21.015233,
  21.611837,  24.00014,   22.741971,  24.416913,  24.053067,  24.314742,
  22.400808,  19.622712,  24.911735,  20.04981,   19.128503,  23.83536,
  21.864501,  25.037927,  24.449472,  24.200244,  24.492582,  22.378057,
  25.411336,  21.727248,  20.16391,   22.045026,  20.017703,  18.534318,
  21.995092,  21.434434,  21.825042,  22.78943,   19.006103,  22.398988,
  24.198657,  25.018417,  18.829948,  23.94818,   20.813966]

我想要这样的东西:

我认为这里有两个不同的问题。

首先,在使用curve_fit()时,确实需要考虑并给参数赋初值。由于您没有为 lamb 提供初始值,因此 scipy 的 curve_fit 做出绝对不合理的假设,即该值为 1.0。明确一点:让你不给起始值,默默给你一个值,是curve_fit()的一个严重缺陷。这个漏洞让很多用户感到困惑。

这里的问题是 lambda=1 的起始值在 k > 10 时没有给出强度,而你所有的样本都是。因此,当对 lambda 的值进行小的更改时,拟合并没有看到拟合的改善,因此无法探索值并找到更好的解决方案。您可以通过打印 curve_fit() 发送到 poisson() 函数的值来测试它。您肯定希望起始值在 10 左右。它不需要是完美的,但不能太差以至于模型函数根本没有强度。

其次,您的值实际上并不遵循泊松分布。看起来它们可能 与泊松分布成正比 ,但您需要包含比例因子

简而言之,我想你会想要像

这样的东西
def poisson(k, lamb, scale):
    return scale*(lamb**k/factorial(k))*np.exp(-lamb)

然后用 lambscale 的合适起始值调用 curve_fit():

parameters, cov_matrix = curve_fit(poisson, x, y, p0=[10., 10.])

对我来说,这仍然不是很合适,但至少它给出了一些合理的东西。希望对您有所帮助。