首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >在NumPy中按非标准化对数概率从集合中采样

在NumPy中按非标准化对数概率从集合中采样
EN

Stack Overflow用户
提问于 2021-01-24 05:38:05
回答 1查看 181关注 0票数 2

我有一个一维np.ndarray,里面充满了定义分类分布的非标准化对数概率。我想从这个分布中抽取一个整数索引。由于许多概率都很小,对对数概率进行归一化和指数化会带来很大的数值误差,因此我不能使用np.random.choice。实际上,我正在寻找一个与TensorFlow的tf.random.categorical等效的NumPy,它处理非标准化的对数概率。

如果NumPy中没有直接实现此目的的函数,那么实现这种采样的有效方式是什么?

EN

回答 1

Stack Overflow用户

发布于 2021-01-24 06:16:28

通常,存在具有自定义分布的many ways to choose an integer,但它们中的大多数采用与给定概率成比例的权重。如果权重是对数概率,则需要一种略有不同的方法。也许最简单的算法是拒绝采样,下面将对其进行描述并用Python实现。在下面的算法中,最大对数概率是max,并且有k个整数可供选择。

对数权重在[0 ]中取一个均匀的随机整数,将-

  1. 对应的对数权重生成一个指数(1)随机数,称其为ex.
  2. If i - maxex小于对数权重,返回i。否则,请转至步骤1.

拒绝采样的时间复杂度平均而言是恒定的,特别是当max设置为等于真正的最大权重时。另一方面,每个样本的预期迭代次数在很大程度上取决于分布的形状。另请参阅“公平芯片/偏置硬币加载芯片”算法中的Keith Schwarz's discussion

现在,此算法的Python代码如下所示。

代码语言:javascript
运行
AI代码解释
复制
import random
import math

def categ(c):
 # Do a weighted choice of an item with the
 # given log-probabilities.
 cm=max(c) # Find max log probability
 while True:
      # Choose an item at random
      x=random.randint(0,len(c)-1)
      # Choose it with probability proportional
      # to exp(c[x])
      y=cm-random.expovariate(1)
      # Alternatively: y=math.log(random.random())+cm
      if y<c[x]:
          return x

上面的代码一次生成一个变量,并且只使用Python的基本模块,而不是NumPy。Another answer展示了如何在NumPy中通过随机变量块一次实现拒绝采样(尽管在不同的随机采样任务中演示)。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/65867476

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档