将分布拟合到直方图上

8
我想知道我的数据点分布情况,所以首先绘制了数据的直方图。我的直方图如下所示: my histogram 其次,为了将它们拟合到一个分布上,我编写了以下代码:
size = 20000
x = scipy.arange(size)
# fit
param = scipy.stats.gamma.fit(y)
pdf_fitted = scipy.stats.gamma.pdf(x, *param[:-2], loc = param[-2], scale = param[-1]) * size
plt.plot(pdf_fitted, color = 'r')

# plot the histogram
plt.hist(y)

plt.xlim(0, 0.3)
plt.show()

结果如下:

结果为:

输入图片描述

我做错了什么?

1个回答

13

您的数据似乎不符合伽玛分布,但是如果假设它符合,可以按照以下方式进行拟合:

import numpy as np
import scipy.stats as stats
import matplotlib.pyplot as plt

gamma = stats.gamma
a, loc, scale = 3, 0, 2
size = 20000
y = gamma.rvs(a, loc, scale, size=size)

x = np.linspace(0, y.max(), 100)
# fit
param = gamma.fit(y, floc=0)
pdf_fitted = gamma.pdf(x, *param)
plt.plot(x, pdf_fitted, color='r')

# plot the histogram
plt.hist(y, normed=True, bins=30)

plt.show()

在此输入图片描述

  • 概率密度函数下的面积(在整个定义域上)等于1。如果使用normed=True,则直方图下的面积也等于1。

  • x的长度为size(即20000),pdf_fittedx具有相同的形状。如果我们调用plot并仅指定y值,例如plt.plot(pdf_fitted),则值将在x范围[0,size]上绘制。这个x范围太大了。由于直方图将使用x范围[min(y),max(y)],因此我们必须选择跨越类似范围的xx = np.linspace(0,y.max()),然后指定x和y值调用plot,例如plt.plot(x,pdf_fitted)

  • 正如Warren Weckesser在评论中指出的那样,对于大多数应用程序,伽马分布的定义域从0开始。如果是这种情况,请使用floc=0loc参数设置为0。如果没有floc=0,则gamma.fit也会尝试找到最佳的loc参数值,但是由于数据的不确定性,一般不会恰好为零。


4
请注意,通常情况下伽马分布的 loc 参数不会被使用(即 PDF 不应该被移动),并且该值被固定为 0。默认情况下,fit 方法将 loc 视为拟合参数,因此您可能会得到一个小的非零偏移量--请检查 fit 返回的参数。您可以通过使用参数 floc=0 告诉 fit 不要将 loc 包括在拟合参数中。 - Warren Weckesser
1
@po6: 抱歉,我不知道你的数据可能来自哪个分布。如果你正在测量的系统有一个理论模型,那么该模型将为分布提供猜测。或者,如果没有这样的模型,那么也许你需要更多的样本来“充实”那个薄尾部。如果没有模型并且无法获得更多样本,则可能必须使用数据本身作为离散概率质量函数的定义。 - unutbu
@unutbu 关于使用伽马分布进行拟合的问题:对于直方图,由于您使用了“normed = True”,所有条的面积加起来为1,但是如果我们改为重新规范化,使得每个条形的y值已经是正确的概率,因为所有的bin都是同样大小,使用“weights = np.ones_like(y) /float(len(y))”即可。到目前为止,这很好,但是我如何使我的伽玛拟合符合这种新的规范化呢? - user6039682
我之所以问这个问题,是因为考虑到拟合的参数结果,其中 a=param[0] 是形状参数,而 theta=param[2] 是尺度参数,我们如何对它们进行重新归一化,使得得到的概率密度函数是标准化的呢?(我们是否可以在 gamma.fit() 中包含某些参数,以便得到的概率密度函数是标准化的?)(为了测试当前是否未标准化,sum(pdf_fitted) 不等于1)我通过乘以 np.diff(bins)[0] 来修复它。 - user6039682
你好!你有没有想过如何使用自定义分布(例如 f(x)=C*exp(a*x+b*x^2+c*x^4+d*x^8))来完成相同的拟合,而不是使用伽马分布? - CyberMathIdiot
显示剩余3条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接