【问题标题】:Why does numpy.random.choice not use arithmetic coding?为什么 numpy.random.choice 不使用算术编码?
【发布时间】:2020-11-20 14:42:36
【问题描述】:

如果我评估类似:

numpy.random.choice(2, size=100000, p=[0.01, 0.99])

使用一个均匀分布的随机float,比如r,并确定r < 0.01 是否会浪费许多生成的随机位(熵)。我听说(二手)生成伪随机数的计算成本很高,所以我认为numpy 不会这样做,而是在这种情况下使用像arithmetic coding 这样的方案。

然而,起初glance 似乎choice 确实为它所要求的每个样本生成了一个float。此外,一个快速的timeit 实验表明,生成n 统一浮点数实际上比来自p=[0.01, 0.99]n 样本更快。

>>> timeit.timeit(lambda : numpy.random.choice(2, size=100000, p=[0.01, 0.99]), number=1000)
1.74494537999999
>>> timeit.timeit(lambda : numpy.random.random(size=100000), number=1000)
0.8165735180009506

choice 真的会为每个样本生成一个float,就像它看起来的那样吗?在某些情况下(尤其是size 很大且p 分布不均匀时)使用某些压缩算法不会显着提高性能吗?如果没有,为什么不呢?

【问题讨论】:

  • python 的一大优点是大多数软件包都可以很容易地作为开源找到,因此您可以轻松地调查这些问题,似乎您已经回答了自己的问题,但是你可以确切地看到 numpy.random.choice 是如何实现的@@github.com/numpy/numpy/blob/master/numpy/random/mtrand.pyx#L805
  • 也许我应该编辑标题。问题实际上是为什么生成比您需要的更多的随机位有意义。
  • 这似乎是一个很好的问题,您应该在上面列出的 gitlab 上提交并将 MR 提交给 numpy for :)... 然后您甚至可以说您为数百万(可能是数百万)使用的软件包做出了贡献...也许只有 100 的数千)
  • @JoranBeasley :) 好的。我只是希望一些更聪明的人会指出我上面推理中的错误
  • 老实说,我不知道……就我而言,随机数接近于一个神奇的黑匣子……而且对我来说似乎“足够快”

标签: python python-3.x performance numpy random


【解决方案1】:

从 NumPy 1.17 开始,很大程度上是向后兼容。另见this questionthis question

根据NumPy's new RNG policy 的说法,从 NumPy 1.17 开始,numpy.random.* 函数(包括 numpy.random.choice)是遗留函数,并且“应保持与当前相同”,该函数还引入了 new random generation system for NumPy。使它们成为遗留函数的原因包括建议避免全局状态。尽管如此,NumPy 并没有在 1.17 版本中弃用任何 numpy.random.* 函数,尽管 NumPy 的未来版本可能会。

回想一下,在您的示例中,numpy.random.choicefloats 数组作为权重。整数权重数组将导致更精确的随机数生成。尽管任何float 都可以转换为有理数(导致有理值权重,从而导致整数权重),但旧版 NumPy 似乎没有这样做。在不破坏向后兼容性的情况下,无法更改 numpy.random.choice 中的这些和其他实施决策。

顺便说一句,算术编码并不是唯一避免浪费比特的算法。也许对离散分布进行采样的规范算法是 Knuth 和 Yao 算法 (1976),它根据所涉及的概率的二元展开精确地选择一个随机整数,并将问题视为二叉树上的随机游走。 (该算法平均使用距离理论下限最多 2 位。)任何其他整数生成算法最终都可以以相同的方式描述,即作为二叉树上的随机游走。例如,Fast Loaded Dice Roller 是一种最近的算法,它对其使用的平均位数有保证的界限(在这种情况下,距离理论下限不超过 6 位)。 Han 和 Hoshi 算法(从 1997 年开始)是另一种此类算法,但使用累积概率。另请参阅我的部分“Weighted Choice With Replacement”。

【讨论】:

  • 很好的答案。赞成。只是好奇,是否不可能同时包含新版本和旧版本以实现依赖于 Numpy 版本的向后兼容性?
  • 这很有趣。我想知道是否会对 numpy 的加权选择实现感兴趣? (或者如果一个已经隐藏在某个地方?)
  • 嗯,但为什么他们在做出旧决定之前不使用(类似的)它呢?有反对使用它的理由吗?就像,它是否不值得,因为开销工作比生成额外的随机位需要更多的时间?
  • @superbrain:你得问问 NumPy 的创建者。我不知道答案,我能给出的答案都是猜测。
猜你喜欢
  • 1970-01-01
  • 2013-09-08
  • 2016-05-24
  • 2012-01-15
  • 2012-03-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-03-18
相关资源
最近更新 更多