从有界域 zipf 分布中抽样

Sampling from a bounded domain zipf distribution

我想从有界域的 "zipf" 分布中采样。

也就是说,假设域是 {1,...,N},我希望域 i 中的每个元素的选择概率与 i ** -a 成正比,其中 a 是分布的一个参数。

numpy提供了一个zipf采样器(numpy.random.zipf),但它不允许我限制域。

How can I easily sample from such distribution?


如果分布参数 a 大于 1,我可以通过拒绝(并重新采样)所有大于 N 的样本来使用 numpy 采样器。但是,由于它不限制样本范围,因此尝试使用任何较小的 a 值都不起作用。

当域有限时,使用这样的 a 应该没有问题,这就是我的应用程序所需要的。

使用 scipy.stats,您可以创建自定义离散分布:

bounded_zipf = stats.rv_discrete(name='bounded_zipf', values=(x, weights))

例如,

import numpy as np
import scipy.stats as stats
import matplotlib.pyplot as plt

N = 7
x = np.arange(1, N+1)
a = 1.1
weights = x ** (-a)
weights /= weights.sum()
bounded_zipf = stats.rv_discrete(name='bounded_zipf', values=(x, weights))

sample = bounded_zipf.rvs(size=10000)
plt.hist(sample, bins=np.arange(1, N+2))
plt.show()

产量

如果采样性能有问题,您可以根据拒绝反转采样实施您自己的采样方法。您会找到相应的 Java 实现 here.