首页 > 解决方案 > 有没有一种矢量化的方法可以用 np.random.choice() 对不同的 p 进行多次采样?

问题描述

我正在尝试实现变化比率,并且我需要T来自 array 的样本C,但每个样本都有不同的 weights p_t

我正在使用这个:

import numpy as np
from scipy import stats

batch_size = 1
T = 3
C = np.array(['A', 'B', 'C'])
# p_batch_T dimensions: (batch, sample, class)
p_batch_T = np.array([[[0.01, 0.98, 0.01],
                       [0.3,  0.15, 0.55],
                       [0.85, 0.1,  0.05]]])

def variation_ratio(C, p_T):
  # This function works only with one sample from the batch.
  Y_T = np.array([np.random.choice(C, size=1, p=p_t) for p_t in p_T]) # vectorize this
  C_mode, frecuency =  stats.mode(Y_T)
  T = len(Y_T)
  return 1.0 - (f/T)

def variation_ratio_batch(C, p_batch_T):
  return np.array([variation_ratio(C, p_T) for p_T in p_batch_T]) # and vectorize this

有没有办法用任何 for 来实现这些功能?

标签: pythonarraysnumpy

解决方案


我们可以在给定分布p_T之间进行均匀采样[0,1],并将其与累积分布进行比较,而不是使用给定的分布进行采样:

让我们从 开始Y_T,说p_T = p_batch_T[0]

cum_dist = p_batch_T.cumsum(axis=-1)

idx_T = (np.random.rand(len(C),1) < cum_dist[0]).argmax(-1)
Y_T = C[idx_T[...,None]]
_, f = stats.mode(Y_T) # here axis=0 is default

现在让我们把它带到variation_ratio_batch

idx_T = (np.random.rand(len(p_batch_T), len(C),1) < cum_dist).argmax(-1)

Y = C[idx_T[...,None]]

f = stats.mode(Y, axis=1)   # notice axis 0 is batch

out = 1 - (f/T)

推荐阅读