Numpy 如何从分类分布中抽取样本

Numpy 如何从分类分布中抽取样本,numpy,vectorization,probability,Numpy,Vectorization,Probability,我有一个3D numpy数组,其中包含最后一个维度中每个类别的概率。比如: 将numpy导入为np 来自scipy.special import softmax 数组=np.random.normal(大小=(10100,5)) 概率=softmax(阵列,轴=2) 我如何从具有这些概率的分类分布中取样 编辑: 现在我是这样做的: def分类(x): 返回np.随机多项式(1,pvals=x) 样本=np。沿_轴应用_(分类,轴=2,arr=概率) 但是它非常慢,所以我想知道是否有一种方法可

我有一个3D numpy数组,其中包含最后一个维度中每个类别的概率。比如:

将numpy导入为np
来自scipy.special import softmax
数组=np.random.normal(大小=(10100,5))
概率=softmax(阵列,轴=2)
我如何从具有这些概率的分类分布中取样

编辑: 现在我是这样做的:

def分类(x):
返回np.随机多项式(1,pvals=x)
样本=np。沿_轴应用_(分类,轴=2,arr=概率)

但是它非常慢,所以我想知道是否有一种方法可以对这个操作进行矢量化。

从给定的概率分布中抽取样本是通过为0到1范围内的随机数建立反向累积分布来完成的。对于一小部分离散类别(如问题中所述),您可以使用线性搜索找到相反的结果:

## Alternative test dataset
probabilities[:, :, :] = np.array([0.1, 0.5, 0.15, 0.15, 0.1])

n1, n2, m = probabilities.shape

cum_prob = np.cumsum(probabilities, axis=-1) # shape (n1, n2, m)
r = np.random.uniform(size=(n1, n2, 1))

# argmax finds the index of the first True value in the last axis.
samples = np.argmax(cum_prob > r, axis=-1)

print('Statistics:')
print(np.histogram(samples, bins=np.arange(m+1)-0.5)[0]/(n1*n2))
对于测试数据集,典型的测试输出为:

Statistics:
[0.0998 0.4967 0.1513 0.1498 0.1024]
看起来不错


如果你有很多很多类别(数千个),可能最好使用numba编译函数进行二分搜索。

你能澄清一下“最后维度中每个类别的概率”吗?是否有5个类别,1000个点中的每一个都有不同的概率分布?@Han KwangNienhuys这是一个推荐系统
概率[i,j,k]
是用户i用k评级项目j的概率