如何从np.random.power函数获得完美契合

时间:2016-06-02 14:58:05

标签: python optimization

我使用以下方法生成随机数据:

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>

1 个答案:

答案 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')

reversed probability density function of the power function distribution

如果现在给你这些箱子的中心和计数,

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/2xdata[-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

fit to reversed probability density function of the power function distribution

如果您想使用splines将曲线拟合到直方图,则应从生成的样条线中检索结和系数,并将其传递到bspleval的函数中,如图所示here。然而,写出这些方程式的主题很长,互联网上有许多资源可供你检查以了解它是如何完成的。毋庸置疑,如果您想要走这条路线,那么bspleval函数就是您所需要的。如果是我,我会走上面所示的曲线拟合路线。