我使用以下方法生成随机数据:
var newHashQuery = "#k=" + encodeURIComponent("something 2");
window.location.hash = newHashQuery;
我使用
将点绘制成直方图bkg= 240-140*np.random.power(3.5,50000)
我的问题是,如果我知道pdf(在这种情况下称为“bkg”),我可以使用h_all = plt.hist(all,bins=binedges,histtype='step')
生成一条适合完美生成的点的曲线,以及曲线的等式是什么? / p>
答案 0 :(得分:0)
首先,请注意您的bkg
不是概率密度函数(pdf)。相反,它是来自pdf的观察的列表。通过在此观察列表上调用matplotlib.pyplot.hist
,您可以看到近似(概率密度函数的偏移和缩放版本)的曲线。如果给出了这条曲线,只要您已经先验地给出了参数化模型,就可以很好地估算出对此进行建模所需的参数。
例如:
import matplotlib.pyplot as plt
import numpy as np
from scipy.optimize import curve_fit
offset, scale, a, nsamples = 240, -140, 3.5, 500000
bkg = offset + scale*np.random.power(a, nsamples) # values range between (offset, offset+scale), which map to 0 and 1
nbins = 100
count, bins, ignored = plt.hist(bkg, bins=nbins, histtype='stepfilled', edgecolor='none')
如果现在给你这些箱子的中心和计数,
xdata = .5*(bins[1:]+bins[:-1])
ydata = count
并且要求您找到适合此数据的配电功能参数( - >有人告诉您,您信任该来源),然后您可以通过以下方式进行操作。
首先,观察功率分布函数P(x,a)
是单调递增函数(即P(x1, a ) < P(x2, a)
时的0 <= x1 < x2 <= 1
。这意味着上面给出的数据集已从左向右翻转,或者表示factor*P(x, a )
与factor < 0
。
接下来,请注意,在[0,1]
的间隔内未给出给定数据,这是概率密度函数的典型值。这意味着您应该在尝试使用幂函数分布之前将给定xdata
重新调整为[0,1]
间隔。只需观察图形,就可以看出0和1映射到的值是100和240.但是,这只是运气,因为matplotlib选择了一个合理的绘图范围。如果你面对的是实际上并不知道0和1映射到的限制,你可以选择xdata[0] - binwidth/2
和xdata[-1] + binwidth/2
或者(稍差一点选择)的不太理想(但仍然非常好)的选择)xdata[0]
和xdata[-1]
。从上一段开始,您知道1映射到xdata[0] - binwidth/2 :=: a
,0映射到xdata[-1] + binwidth/2 :=: b
。执行此操作的线性映射是lambda x: (a - b)*x + b
(简单代数)。
如果你将这个xdata的[0,1]映射版本传递给curve_fit
,它会给你一个很好的猜测。
def get_model(nobservations, binwidth, scale, offset):
def model(bin_centers, exponent):
x = (bin_centers - offset)/scale
y = exponent*x**(exponent - 1)
normed_y = nobservations * binwidth * y / np.abs(scale)
return normed_y
return model
binwidth = np.diff(xdata)[0]
p0, _ = curve_fit(get_model(nsamples, binwidth, scale=-xdata.ptp() - binwidth, offset=xdata[-1] + binwidth/2), xdata, ydata)
print(p0) # prints e.g.: 3.37117679
plt.plot(xdata, get_model(nsamples, binwidth, scale=-xdata.ptp() - binwidth, offset=xdata[-1] + binwidth/2)(xdata, *p0))
此时,您已经找到了相当准确的分布描述
用于生成bkg
的观察结果:
f(x) = offset + scale*(exponent * x**(exponent - 1))
= (xdata[-1] + binwidth/2) + (-xdata.ptp() - binwidth)*(p0[0] * x**(p0[0] - 1))
~ 234.85 - 1.34.85*(3.37 * x**(3.37 - 1))
顺便说一句,我想指出复制bkg
(来自发行版的观察)
如果您知道分布的确切参数(240,-140和3.5)并且将随机数生成的种子设置为等于在初始调用之前生效的种子,那么您只能做一个完美的副本。 np.random.power
。
如果您想使用splines将曲线拟合到直方图,则应从生成的样条线中检索结和系数,并将其传递到bspleval
的函数中,如图所示here。然而,写出这些方程式的主题很长,互联网上有许多资源可供你检查以了解它是如何完成的。毋庸置疑,如果您想要走这条路线,那么bspleval
函数就是您所需要的。如果是我,我会走上面所示的曲线拟合路线。