【问题标题】:Generate uniform random variable when lower boundary is close to zero当下边界接近零时生成均匀随机变量
【发布时间】:2017-02-04 16:43:15
【问题描述】:

当我在 R 中运行时

runif(100,max=0.1, min=1e-10)

我得到 100 个均匀分布的随机变量介于 0.1 和 0.0001 之间。因此,在 0.0001 和最小值 (min=1e-10) 之间没有随机值。

如何在整个区间(最小值和最大值之间)生成均匀随机变量?

【问题讨论】:

  • “随机变量”是什么意思?
  • 随机变量的实现
  • 你最后一轮的编辑对我来说似乎很奇怪......“值”是复数,而不是单数......你的最后一句话是一个问题......但无论如何......
  • 我本来打算接受你的更正,但我不熟悉这个网站,所以我以某种方式驳回了他们。

标签: r random boundary uniform-distribution


【解决方案1】:

也许你生成的不够多,以至于你已经看到了一个:

> range(runif(100,max=0.1,min=exp(-10)))
[1] 0.00199544 0.09938462
> range(runif(1000,max=0.1,min=exp(-10)))
[1] 0.0002407759 0.0999674631
> range(runif(10000,max=0.1,min=exp(-10)))
[1] 5.428209e-05 9.998912e-02

它们多久出现一次?

> sum(runif(10000,max=0.1,min=exp(-10)) < .0001)
[1] 5

在 10000 个样本中有 5 个。因此,在 100 个样本中得到一个的机会是……(实际上,您可以从均匀分布的数量和属性中准确计算出)。

【讨论】:

  • 运行 runif(200,max=0.1, min=exp(-10)) 我得到了 0.000451 和 0.09921 之间非常好的分布值。我在这两个值之间制作了 15 个块,每个块包含 10 到 15 个这些生成的值。并且有 0 个值小于 0.000451。所以,我的 min-max 区间的一半没有被这些数据覆盖,而另一半则很好地填充。如果我生成 $1e^{6}$ 随机变量,我会得到一些更少的值,但是......整个区间没有均匀分布。
  • 我的最小-最大间隔的一半没有被覆盖”这个完全错误。您的比例从exp(-10) = 4.5e-50.1,总间隔宽度为0.0999546。您的观察值从0.000451 变为0.09921,观察范围为0.098759。取观察到的宽度与总宽度的比率,您的区间覆盖率为 98.8%!您是否想要在对数尺度上均匀分布的随机值?
  • 我打字不好。最小值是 0.0000000001 或类似的值(而不是我写的 exp(-10) )。对此感到抱歉。我没有复制->粘贴 R 代码(我应该这样做)。
  • 这并没有改变重点,只是细节 - 您正在查看间隔的 小条 - 使用 1e-10 作为总间隔宽度的最小值0.1 - 1e-10 = 0.099999999,我们可以近似为0.1。您关注的是宽度为1e-4 - 1e-10 的切片,大约是1e-4,大约是间隔的0.1%。这就像你在随机拨打电话号码,你会惊讶地发现接听的人不是你认识的人!电话号码不是均匀分布的吗?到了第 10 次尝试时,您肯定会找到亲戚或至少是朋友……对吧?没有。
  • 我夸大了电话号码示例中的几率,但如果您希望在 0.1% 的区间内随机抽取的几率很高,则需要抽取超过 100 个值。跨度>
【解决方案2】:

已编辑以将 exp(-10) 替换为 1e-10

给定0.1 的最大值和1e-10 的最小值,任何给定值小于1e-4 的概率由下式给出

(1e-4 - 1e-10) / (0.1 - 1e-10) = 9.99999e-04

这个分布中的 100 个随机值都大于1e-4 的概率是

(1 - 9.99999e-04) ^ 100 = 0.90479

大约 90.5%。因此,在从该分布中抽取 100 个数字时,您一点也不应该感到惊讶,您看到的数字不小于 1e-4。理论上,这预计超过 90.5% 的时间。我们甚至可以在模拟中验证这一点:

set.seed(47) # for replicability
# 100,000 times, draw 100 numbers from your uniform distribution
d = replicate(n = 1e5, runif(100, max = 0.1, min = 1e-10))
# what proportion of the 100k draws have no values less than 1e-4?
mean(colSums(d < 1e-4) == 0)
# [1] 0.90557
# 90.56% - very close to our calculated 90.48%

为了更精确,我们可以重复更多次

# same thing, 1 million replications
d2 = replicate(n = 1e6, runif(100, max = 0.1, min = 1e-10))
mean(colSums(d2 < 1e-4) == 0)
# [1] 0.90481

因此,对于 1MM 复制,runif() 几乎完全符合预期。与0.90481 - 0.90479 = 0.00002 的预期不同。我会说绝对没有证据表明runif 已损坏。

我们甚至可以绘制一些复制的直方图。以下是前 20 个:

par(mfrow = c(4, 5), mar = rep(0.4, 4))
for (i in 1:20) {
    hist(d[, i], main = "", xlab  = "", axes = F, 
         col = "gray70", border = "gray40")
}

直方图每个显示 10 个条形图,因此每个条形图的宽度约为 .01(因为总范围约为 0.1)。您感兴趣的范围约为0.0001 宽。要在直方图中看到这一点,我们需要在每个图中绘制 1,000 个条形图,是条形图的 100 倍。当只有 100 个值时,使用 1,000 个 bin 没有多大意义。当然,几乎所有的垃圾箱都是空的,尤其是最低的垃圾箱,大约 90% 的时间都是空的,正如我们上面计算的那样。

要获得更多非常低的随机值,您的两个选择是 (a) 从均匀分布中提取更多数字或 (b) 将分布更改为权重更接近 0 的分布。您可以尝试指数分布吗?或者,如果你也想要一个硬上限,你可以扩展一个 beta 分布?您的另一个选择是根本不使用随机值,也许您想要均匀间隔的值,seq 就是您要找的?

【讨论】:

  • 最小值是 0.0000000001 或类似的值(而不是我写的 exp(-10))。对此感到抱歉。但我需要覆盖整个区间的均匀分布。在我看来,R 有一些我无法克服的限制。
  • 除非您编辑您的问题以显示它,否则我们不相信 R 中存在限制。由于可能数字的分布变得不均匀,小数字的浮点运算可能存在限制,但这不应该在 1e-10 发生。
  • 美丽的小多重情节。我可以在您的hist() 通话中推荐col="gray" 吗...?
  • @BenBolker 感谢您的推荐 :)
猜你喜欢
  • 2013-12-09
  • 2012-10-12
  • 2018-10-24
  • 2020-09-07
  • 2019-07-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多