从有界域 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.
我想从有界域的 "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.