【问题标题】:Make a number more probable to result from random使数字更有可能由随机产生
【发布时间】:2015-10-06 08:59:19
【问题描述】:

我正在使用x = numpy.random.rand(1) 来生成一个介于 0 和 1 之间的随机数。如何使 x > .5 的概率是 x < .5 的 2 倍?

【问题讨论】:

  • @Jodrell 它随机的。只是不均匀分布随机。
  • 您需要指定您要查找的概率分布类型 - 有无限多种可能的分布,其中 p(x > 0.5) = 2*p(x .

标签: python numpy random


【解决方案1】:
tmp = random()
if tmp < 0.5: tmp = random()

这个方法很简单

嗯,我想这可能是 3 倍……这就是我想通过那节课睡觉得到的结果

from random import random,uniform

def rand1():
    tmp = random()
    if tmp < 0.5:tmp = random()
    return tmp
def rand2():
    tmp = uniform(0,1.5)
    return tmp if tmp <= 1.0 else tmp-0.5

sample1 = []
sample2 = []
for i in range(10000):
    sample1.append(rand1()>=0.5)
    sample2.append(rand2()>=0.5)

print sample1.count(True) #~ 75% 
print sample2.count(True) #~ 66% <- desired i believe :)

【讨论】:

  • 对于大于 0.5 的数字,这不是 3 倍吗?不过我确实喜欢这种方式
  • 我相信它可能是 0.5 或更大的 2 倍,我的测试表明大约 75% 的时间是,我猜这个可能性是 3 倍......很好的数学:P跨度>
  • hmmm 重复测试(只是填充一个大列表)显示另一种解决方案(rand(1.5) 仅在大约 50% 的时间导致 0.5 或更大......这看起来很奇怪......
  • @JoranBeasley 这实际上是Monty Hall Problem 背后逻辑的变体。你正在做的事情有 25% 的机会出现 0.5,这是真的。 other 的一半时间, 时间的一半> 0.5 并且为真。 另一半那一半会是假的。
  • 好吧,我哑了 random.rand 只给出了一个 int ...它需要是一个统一的随机数才能获得预期的 66%
【解决方案2】:

这个名字很合适!

只需对输入进行一点操作即可。首先将x 设置在01.5 的范围内。

x = numpy.random.uniform(1.5)

x 的概率大于0.51/3 的概率小于2/3。那么如果x大于1.0,则减去.5

if x >= 1.0:
    x = x - 0.5

【讨论】:

  • 。如果范围在末尾是独占的,则可能需要为&gt;=
  • 会有所作为吗?
【解决方案3】:

首先,numpy.random.rand(1) 不返回 [0,1) 范围内的 (半开,包括零但不包括一),它返回一个大小为 1 的 数组, 包含该范围内的值,范围的上端与传入的参数无关。

您可能需要的函数是均匀分布函数numpy.random.uniform(),因为这将允许任意上限。

而且,使上半部分的可能性增加一倍是一件相对简单的事情。

以随机数生成器r(n) 为例,它返回[0,n) 范围内的均匀分布整数。您需要做的就是调整值以更改分布:

x = r(3)     # 0, 1 or 2, @ 1/3 probability each
if x == 2:
    x = 1    # Now either 0 (@ 1/3) or 1 (@ 2/3)

现在得到 0 的机会是 1/3,而得到 1 的机会是 2/3,这基本上是您尝试使用浮点值实现的目标。

所以我会简单地得到一个[0,1.5) 范围内的随机数,如果大于或等于 1,则减去 0.5。

x = numpy.random.uniform(high=1.5)
if x >= 1: x -= 0.5

由于原始分布应该在[0,1.5) 范围内均匀,因此减法应该使[0.5,1.0) 的可能性增加一倍(并且[1.0,1.5) 不可能),同时保持每个部分内的分布均匀([0,0.5) 和@987654333 @):

 [0.0,0.5)  [0.5,1.0)  [1.0,1.5)  before
<---------><---------><--------->
 [0.0,0.5)  [0.5,1.0)  [0.5,1.0)  after

【讨论】:

  • @Blackhole,它几乎是同时发布的,所以当我开始时,AZ 的答案实际上并不存在(这种情况经常发生)。一旦我看到它,它的分布就有一个错误(如果不是文本,它已经在代码中修复了),这就是为什么我没有删除我的。无论如何,我相信我的额外解释使它有用。
【解决方案4】:

这对你来说有点过头了,但最好知道用任何概率密度函数 (pdf) 生成随机数的实际方法。

只要你做的正确,你可以通过继承scipy.stat.rv_continuous 来做到这一点。您将必须有一个标准化的 pdf(使其积分为 1)。如果你不这样做,numpy 会自动为你调整范围。在这种情况下,您的 pdf 对于 x0.5 的值为 4/3,支持为 [0, 1)(支持是非零的区间):

import scipy.stats as spst
import numpy as np
import matplotlib.pyplot as plt
import ipdb


def pdf_shape(x, k):
    if x < 0.5:
        return 2/3.
    elif 0.5 <= x and x < 1:
        return 4/3.
    else:
        return 0.


class custom_pdf(spst.rv_continuous):
    def _pdf(self, x, k):
        return pdf_shape(x, k)

instance = custom_pdf(a=0, b=1)

samps = instance.rvs(k=1, size=10000)

plt.hist(samps, bins=20)
plt.show()

【讨论】:

  • 我想表明它为你打开了一个窗口,它不只是自动保存在某个地方。
【解决方案5】:

如果您想要更流畅的随机性,您可以将随机函数的输出平方

(并从 1 中减去它以使x &gt; 0.5 更有可能而不是x &lt; 0.5)。

x = 1 - sqr(numpy.random.rand(1))

【讨论】:

  • 通过流体,我假设您的意思是“与指定的不同”:-) 我看不出这会使上半部分的可能性增加一倍,实际上我怀疑它引入了一个连续变量概率向高端加权。
【解决方案6】:

您可以采用“混合模型”方法,将过程分为两个步骤:首先,决定是选择选项 A 还是 B,其中 B 的可能性是 A 的两倍;那么,如果您选择 A,则返回一个介于 0.0 和 0.5 之间的随机数,否则如果您选择 B,则返回一个介于 0.5 和 1.0 之间的随机数。

在示例中,randint 随机返回 0、1 或 2,因此 else 的可能性是 if 的两倍。

  m = numpy.random.randint(3)
  if m==0:
    x = numpy.random.uniform(0.0, 0.5)
  else:
    x = numpy.random.uniform(0.5, 1.0)

这有点贵(两次随机抽取而不是一次),但它可以以相当直接的方式推广到更复杂的分布。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-08-09
    • 2019-12-15
    相关资源
    最近更新 更多