为了扩展@Ilmari Karonen 的解决方案,您要做的是计算每个直方图的权重,然后根据这些权重进行采样。在我看来,根据您的目标,最有效的方法是使用linear program。
令 D_ij 为第 i 个项目的直方图中第 j 个 bin 的权重。然后,如果每个项目的权重为 w_i,则“总和直方图”的权重 sum(i in items) w_i D_ij。获得“近似均匀”分布的一种方法是最小化箱之间的最大差异,因此我们将解决以下 LP:
minimize z
subject to (for all j, k)
z >= (sum i in items) w_i D_ij - (sum i in items) w_i D_ik
z >= (sum i in items) w_i D_ik - (sum i in items) w_i D_ij
上面基本上是说z >= 所有加权 bin 对的差异绝对值。要解决此 LP,您将需要一个单独的包,因为 numpy 不包含 LP 求解器。有关使用cplex 的解决方案,请参阅this gist 或使用cvxpy 的解决方案this gist。请注意,您需要像这些解决方案一样对权重设置一些约束(例如,每个权重大于或等于 0)。 GLPK(GNU 线性编程工具包)的其他 python 绑定可以在这里找到:http://en.wikibooks.org/wiki/GLPK/Python。
最后,您只需从直方图 i 和权重 w_i 中采样。这可以通过使用@Ilmari Karonen 建议的cumsum 和searchsorted 调整轮盘选择来完成,请参阅this gist。
如果您希望得到的加权分布“尽可能均匀”,我会用权重解决类似的问题,但要最大化 bin 加权总和的加权熵。尽管您可以使用任意数量的非线性求解器,例如 BFGS 或基于梯度的方法,但这个问题似乎是非线性的。这可能会比 LP 方法慢一点,但这取决于您在应用程序中需要什么。如果您有大量直方图,LP 方法将非常接近非线性方法,因为它很容易达到均匀分布。
当使用 LP 解决方案时,由于约束的数量很少,一堆直方图的权重可能会绑定到 0,但这对于非平凡的 bin 数量不会有问题,因为约束的数量是 O (n^2)。
具有 50 个直方图和 10 个 bin 的权重示例:
[0.006123642775837011, 0.08591660144140816, 0.0, 0.0, 0.0, 0.0, 0.03407525280610657, 0.0, 0.0, 0.0, 0.07092537493489116, 0.0, 0.0, 0.023926802333318554, 0.0, 0.03941537854267549, 0.0, 0.0, 0.0, 0.0, 0.10937063438351756, 0.08715770469631079, 0.0, 0.05841899435928017, 0.016328676622408153, 0.002218517959171183, 0.0, 0.0, 0.0, 0.08186919626269101, 0.03173286609277701, 0.08737065271898292, 0.0, 0.0, 0.041505225727435785, 0.05033635148761689, 0.0, 0.09172214842175723, 0.027548495513552738, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0259929997624099, 0.0, 0.0, 0.028044483157851748, 0.0, 0.0, 0.0]
有 50 个直方图,每个直方图有 50 个 bin,现在零值很少:
[0.0219136051655165, 0.0, 0.028325808078797768, 0.0, 0.040889043180965624, 0.04372501089775975, 0.0, 0.031032870504105477, 0.020745831040881676, 0.04794861828714149, 0.0, 0.03763592540998652, 0.0029093177405377577, 0.0034239051136138398, 0.0, 0.03079554151573207, 0.0, 0.04676278554085836, 0.0461258666541918, 9.639105313353352e-05, 0.0, 0.013649362063473166, 0.059168272186891635, 0.06703936360466661, 0.0, 0.0, 0.03175895249795131, 0.0, 0.0, 0.04376133487616099, 0.02406633433758186, 0.009724226721798858, 0.05058252335384487, 0.0, 0.0393763638188805, 0.05287112817101315, 0.0, 0.0, 0.06365320629437914, 0.0, 0.024978299494456246, 0.023531082497830605, 0.033406648550332804, 0.012693750980220679, 0.00274892002684083, 0.0, 0.0, 0.0, 0.0, 0.04465971034045478, 4.888224154453002]