从直方图中创建概率分布函数(PDF)

Ame*_*ina 9 python scipy scikit-learn statsmodels pymc

假设我有几个直方图,每个直方图都在不同的 bin位置(在实轴上)进行计数.例如

def generate_random_histogram():

    # Random bin locations between 0 and 100
    bin_locations = np.random.rand(10,) * 100
    bin_locations.sort()

    # Random counts between 0 and 50 on those locations 
    bin_counts = np.random.randint(50, size=len(bin_locations))
    return {'loc': bin_locations, 'count':bin_counts}

# We can assume that the bin size is either pre-defined or that 
# the bin edges are on the middle-point between consecutive counts.
hists = [generate_random_histogram() for x in xrange(3)]
Run Code Online (Sandbox Code Playgroud)

如何对这些直方图进行标准化,以便获得 PDF,其中每个PDF的积分在给定范围内(例如0和100)加起来为1?

我们可以假设直方图根据预定义的bin大小计算事件(例如10)

我见过的大多数实现都是基于高斯内核(参见scipyscikit-learn)从数据开始.就我而言,我需要从直方图中做到这一点,因为我无法访问原始数据.

更新:

请注意,所有当前答案都假设我们正在查看(-Inf,+ Inf)中的随机变量.这可以作为粗略的近似,但根据应用可能不是这种情况,其中变量可以在某个其他范围内定义[a,b](例如,在上述情况下为0和100)

ask*_*han 6

精致的要点是定义,bin_edges因为从技术上讲它们可以在任何地方.我选择了每对bin中心之间的中点.可能还有其他方法可以做到这一点,但这里有一个:

hists = [generate_random_histogram() for x in xrange(3)]
for h in hists:
    bin_locations = h['loc']
    bin_counts = h['count']
    bin_edges = np.concatenate([[0], (bin_locations[1:] + bin_locations[:-1])/2, [100]])
    bin_widths = np.diff(bin_edges)
    bin_density = bin_counts.astype(float) / np.dot(bin_widths, bin_counts)
    h['density'] = bin_density

    data = np.repeat(bin_locations, bin_counts)
    h['kde'] = gaussian_kde(data)

    plt.step(bin_locations, bin_density, where='mid', label='normalized')
    plt.plot(np.linspace(0,100), h['kde'](np.linspace(0,100)), label='kde')
Run Code Online (Sandbox Code Playgroud)

这将产生如下图(每个直方图一个): hists

  • 抱歉.编辑---现在按顺序运行所有格式化的代码,你应该得到情节.(当然,在你创建了'hists`随机直方图列表之后).这只是绘制了`hists`中的最后一个条目.如果要绘制每个函数,请将`plt`函数放在循环中. (2认同)