用泊松函数拟合直方图
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)
然后用 lamb
和 scale
的合适起始值调用 curve_fit()
:
parameters, cov_matrix = curve_fit(poisson, x, y, p0=[10., 10.])
对我来说,这仍然不是很合适,但至少它给出了一些合理的东西。希望对您有所帮助。
我正在尝试用泊松函数拟合直方图。我正在关注网站上的一些答案,但我无法解决问题。 我只是想使用 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)
然后用 lamb
和 scale
的合适起始值调用 curve_fit()
:
parameters, cov_matrix = curve_fit(poisson, x, y, p0=[10., 10.])
对我来说,这仍然不是很合适,但至少它给出了一些合理的东西。希望对您有所帮助。