为什么runif不会每次都产生相同的结果?


11

为什么像runif()R 中的随机数生成器每次都不会生成相同的结果?

例如:

X <- runif(100)
X

每次都会产生不同的输出。

每次产生不同输出的原因是什么?

它在后台执行什么功能?


3
考虑这一点的一种方法是问自己:“您希望您的随机数生成器每次生成相同的数字吗?”
shadowtalker 2014年

2
@ssdecontrol:请参见Dilbert
Henry

2
xkcd
亨利

Answers:


18

从本质上讲,这实际上不仅仅是一个R问题;它实际上是一个R问题。它更一般地涉及随机数生成。

“随机”数字在统计的许多部分中非常重要。我们需要生成的随机值具有某些属性,并且(通常)需要大量精力来构建随机数生成器并检查其属性。

我们的想法是,我们要获得一个值序列,这些值序列可以很好地代理实际的随机数。随机数生成的通常主力是均匀分布(据此我们构造了其他分布,例如高斯随机数)。

因此(最典型地),使用一种数值算法来构造一个整数序列,每个整数都基于先前整数的某些函数。然后将这些整数缩放为介于0和1之间(通常为)。[01个

例如,许多仅适用于上一个:

X1个=FX0ž1个=X1个/X2=FX1个ž2=X2/X3=FX2ž3=X3/

...其中是整数,然后将缩放到单位间隔,而是一些通常很复杂但通常是快速的函数,它对参数中的位进行运算以产生一组新的位(希望)似乎与任何先前的值都不相关(如果我们以各种方式仔细地研究它们,即使它们非常相关,即使它们确实是相关的,因为它们是这样产生的)。必须仔细构造这些序列,以确保序列具有很长的周期,并且其值确实是统一的,并且不以我们可能真正关心的任何方式依序依赖(以及通常被视为重要)。ž ˚FXžF

它们需要您提供的起始(“种子”)整数()(某些算法可能需要多个种子)。如果再次使用相同的种子,则会得到相同的序列(这对于能够重现结果非常方便)。但是有时候,您只想要一些随机数,并且只要起始点与以前使用的批次不同,就不必在乎种子是什么。X0

因此,如果您不提供种子,许多包装可以为您制作一个。有些程序包会查看内部数字时钟的后几位(通常以某种方式进行操作)。一些(包括R)存储由随机数生成器生成的用作最后一个种子的最后一个值(上面的整数,更一般地,术语“状态”用于涵盖涉及多个数字的情况)如果您不提供一个。X3

?runif在R中看到,您会注意到它解释了随机种子的存在,并带有帮助链接,该帮助?.Random.seed解释了R中可用的大量随机数生成器(甚至可以提供您自己的)。相同的帮助页面说明,如果您之前未使用随机数生成或未设置种子,则从时钟开始获取种子,然后再存储前一个值(这样您将获得下一个随机数如果您上次创造了另一个价值,您会获得与之相同的价值-它会记住“您的目标”。

runifR中的函数(像其他程序包中的许多其他随机数生成例程一样,通常可以做类似的事情)知道保留随机数种子的位置。它会不断更新该值。因此它可以运行而不必显式地传递种子,但是它仍然使用一个。如果您不给它一个,它只会使用最后保存的一个。

至于为什么每次都会给出不同的输出(如果您不告诉它给出相同的序列):这样做是因为每次相同的值通常会产生相反的效果-它不会具有重复的属性随机抽样将具有随机抽样,这对于我们使用随机数生成器的假定来说不是很有用。


14

您必须设置随机种子才能每次获得相同的结果。使用?set.seed这样做。考虑:

> runif(1)
[1] 0.6467259
> runif(1)
[1] 0.2101857
> set.seed(1)
> runif(1)
[1] 0.2655087
> set.seed(1)
> runif(1)
[1] 0.2655087

您可能有兴趣阅读以下内容: 使用set.seed函数的原因


3
尽管这解释了重现一组结果的机制,但似乎并没有解决问题本身,这使为什么这种行为不是自动的很奇怪。
ub

@whuber,我认为问题不在这里。我投票决定立即关闭,如果有这个特权,我会彻底关闭它。我张贴了这个,这样操作员就不会空手而归。
gung-恢复莫妮卡

每次都运行“ set.seed(1)”。
–'Nip
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.