如何确定将给定数据合并为平滑直方图的网格?

问题描述

说明

我有一些模拟数据应该合并到直方图中(使用 sum 合并)。

原始数据如下图所示。蓝点是要分箱的数据,红线是定义分箱边界的 logscale 网格。

correct grid

当使用正确数量的 bin (50) 时,结果 bin 化直方图是一条平滑曲线。

correct histogram

但是,如果我使用了不正确的网格大小,例如 58,结果会变得振荡

incorrect histogram

要理解原因,请看下面不正确的网格:似乎网格可能会在错误的周期内拆分某些周期性数据,从而导致数据点的摆动分配和振荡数据。

incorrect grid

问题

目前,我通过反复试验找到了最佳网格。我想知道是否有一种简单的方法可以找到将数据合并为平滑曲线的网格(假设始终存在)?

示例数据

示例数据 N 在此 gist上传。第一列是Size,第二列是Count

我创建了一个示例 colab notebook 来重现情节。

谢谢!

解决方法

这仍然是“反复试验”,但至少以编程方式。我假设我们只想找出 bin 的数量。

让我们检查一定数量的垃圾箱以获得最佳垃圾箱。我们将最好的定义为最小化“计数”对数绝对差异的平均值,对正差异施加巨大惩罚(代表图中的跳跃)。

def judge_grid(N,grid,pos_penalty=1e5):
    stat,bin_edges,_ = binned_statistic(N[:,0],N[:,1],statistic="sum",bins=grid)
    logcounts = np.log(stat) - np.log(bin_edges[1:] - bin_edges[:-1])
    d = np.diff(logcounts)
    # Huge penalty for positive difference.
    ad = np.where(d > 0,d * pos_penalty,-d)
    return np.mean(ad)

lo = np.log10(1e-5)
hi = np.log10(1.0)
min_bins = 10
max_bins = 80
best_num_bins = min(range(min_bins,1+max_bins),key=lambda b: judge_grid(N,np.logspace(lo,hi,b)))
print(best_num_bins) 

对于您的示例,返回 50。