Python 将分布拟合到直方图
我想知道我的数据点的分布,所以首先我绘制了数据的直方图。我的直方图如下所示: 其次,为了使它们适合发行版,我编写了以下代码:Python 将分布拟合到直方图,python,scipy,data-fitting,Python,Scipy,Data Fitting,我想知道我的数据点的分布,所以首先我绘制了数据的直方图。我的直方图如下所示: 其次,为了使它们适合发行版,我编写了以下代码: 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_fitt
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()
结果是:
我做错了什么?您的数据似乎不是伽马分布的,但假设是伽马分布的,您可以这样进行拟合:
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()
- pdf下的面积(整个域)等于1。
如果使用
,则直方图下的区域等于1normed=True
具有长度x
(即20000),并且size
具有与pdf\u-fitted
相同的形状。如果我们调用x
并仅指定y值,例如plot
,则在x范围plt.plot(pdf_fitted)
上绘制值。 这在x范围内太大了。由于直方图将使用x范围[0,大小]
,我们通常选择[min(y),max(y)]
来跨越一个类似的范围:x
,并使用指定的x和y值调用x=np.linspace(0,y.max())
plt.plot(x,pdf\u拟合)
- 正如Warren Weckesser在评论中指出的,对于大多数应用程序,您知道gamma分布的域从0开始。如果是这种情况,请使用
将floc=0
参数保持为0。如果没有loc
,floc=0
也会尝试为gamma.fit
参数找到最佳拟合值,考虑到数据的不确定性,该值通常不会完全为零loc
loc
参数(即不应移动PDF),并且该值固定为0。默认情况下,fit
方法将loc
视为拟合参数,因此您可能会得到一个小的非零移位——检查fit
返回的参数。通过使用参数floc=0
@WarrenWeckesser,您可以告诉fit
不要将loc
作为拟合参数;我不知道floc
@unutbu,非常感谢您的详细回答!现在我明白我做错了什么。事实上,我的数据不是伽马分布的。有什么线索可以告诉我我的分布吗?@po6:对不起,我不知道你的数据可能来自哪个分布。如果您正在测量的系统有一个理论模型,那么该模型将提供分布的猜测。或者,如果没有这样的模型,那么您可能需要更多的样本来“充实”这条细尾巴。如果没有模型,您无法获得更多样本,那么您可能必须使用数据本身作为离散曲线的定义。@unutbu关于使用伽马分布进行拟合的一个问题:对于直方图,因为您使用了normed=True
所有条带的面积相加为一,但是,如果我们改为重新规范化,使每个条的y值已经是正确的概率,因为所有箱子都是相同大小的,使用weights=np。像(y)/float(len(y))
,到目前为止还可以,但是我如何使我的gamma拟合匹配这个新的规范化呢?