• R语言
  • 关于set.seed函数的意义还是不太明白

      如果说函数中出现set.seed(3000),那就是说程序运行3000次,都是从同一个种子产生的随机数,还是从不同的种子产生的?



      另外,这个3000,指的是3000“个”随机数,还是3000“批”(一批里面可能有若干个)随机数呢?



     如果我每循环一次,让set.seed(N)中的N增加一个常数,那会有什么作用?

set.seed()里面的数字与循环无关,它只是一个ID。
set.seed(3000),不是运行3000次,而是把种子设置为3000。



计算机的程序,都是通过确定的算法,根据确定的输入,算出确定的输出。想要得到真正的随机,需要通过外接物理随机数发生器,通过把随机的物理过程转变为随机值,才能实现。因此我们平常使用的计算机的随机数,其实都只是通过算法模拟得到,也就是伪随机。一般采用的办法是线性同余(参见http://en.wikipedia.org/wiki/Linear_congruential_generator)。



X[n+1] = (a * X[n] + c) mod m

为简单起见,我取简单的参数(a = 1, c = 3, m = 5),得到一个简单的算式:

X[n+1] = (X[n] + 3) mod 5

这时,把X[0]视为种子,于是:

若种子为0,得到数列:0, 3, 1, 4, 2, 0, ...

若种子为1,得到数列:1, 4, 2, 0, 3, 1, ...

若种子为2,得到数列:2, 0, 3, 1, 4, 2, ...

若种子为3,得到数列:3, 1, 4, 2, 0, 3, ...

若种子为4,得到数列:4, 2, 0, 3, 1, 4, ...



对于每个种子,所得到的数列看起来都是随机的(每个数值出现的频率都是相同的)。而一旦种子给定,每次调用随机数函数,函数都会根据上次得到的数列的某个值,计算出数列的下一个值并返回回来。而对于随机浮点数,一般是用随机产生的整数除以最大整数得到。



所以,随机数的种子一般只需要在调用随机函数之前设置一次,不建议设置多次。



另外,我一直没有搞明白一件事:设置多次种子,在算法上会不会对最终生成的随机数的分布造成影响?不知道有人了解么?
哦,终于搞明白这括号里面是啥东东了!是一个产生随机数的出发点。



     如果在每次循环时都先设定不同的随机数,也就意味着在这次循环过程中产生的肯定是与上一次不同的随机数,就如我上面提到的那个每次循环让这个种子加上一个常数的方法。不过,即便不设定这个随机数种子,计算机在每次运算产生的随机数应该也是不同的吧,那样就应该没有必要用这个种子循环的办法了。



    另外,根据这个原理,如果每次设置的种子都相同,那多次设置种子得到的随机数肯定都是相同的一批数据了。

    

     我感觉这个set.seed还是没有多大意义!
这恰恰就是种子最重要的作用。比如说你写了一段程序发给别人看,程序中要生成一系列随机数,如果你不设置随机数种子,那么别人运行你的程序时,生成的随机数就会与你的不同,得到的结果也就可能与你不同,这样就没有办法重复及验证你的结果。在这种情况下就必须设置随机数种子,从而可以重复你的程序结果。
7 个月 后
请问 ,原则是什么?到底设置为多大呢 ?
原则是在其允许范围内(一般是4字节有符号整数,范围-2147483648~2147483647)任选一个,至于取哪一个,那就看个人喜好了。要还是迷惑,那就取自己的生辰八字好了 :P
我正有用某些日期做随机数种子的习惯,哈哈
23 天 后

# x: the random vector;<br />
# FUN: the function that generates random numbers with the first argument<br />
#      being the length of random numbers<br />
# seed: candidate seeds to be tried one by one<br />
# ...: other arguments to be passed to FUN<br />
find.seed = function(x, FUN = rnorm, seed = 0:10000, ...) {<br />
    res = NULL<br />
    for (i in seed) {<br />
        set.seed(i)<br />
        rx = FUN(length(x), ...)<br />
        # all() can be changed to all.equal() to obtain a rough solution<br />
        #     allowing a little bit numeric errors<br />
        if (all(x == rx)) {<br />
            res = i<br />
            break<br />
        }<br />
    }<br />
    res<br />
}<br />


在网上找到这个find.seed()。
> set.seed(1)<br />
> test = rnorm(30)<br />
> find.seed(test)<br />
[1] 1<br />
> set.seed(1234)<br />
> test = rnorm(30)<br />
> find.seed(test)<br />
[1] 1234<br />
> set.seed(987)<br />
> test = runif(30, min = -1, max = 2)<br />
> find.seed(test, runif, min = -1, max = 2)<br />
[1] 987<br />


attributes也找不到,只知道可以通过别人写的find.seed()找出。请问还有什么方法可以更容易找出seed吗?
</p>

回复 第10楼 的 ryusukekenji:这个是老大博客里的吧,其实set.seed()在理论上是不能反向获取seed的,这个find.seed()的使用也是有条件的,即你必须给出一个搜索的范围,然后遍历所有可能。另外就是如果我在随机数序列中略过若干个数,比如生成100个但只取最后几十个,这样搜索的难度就更大了。

哦,通过rseek.org找到R Blogger中的文章上刚刚留意到有注名:Published on Keep on Fighting! » R Language: Guess the Random Seed · Retrieved on March 12, 2010

原来是谢老师写的。还正想问倘若想要找出runif中的其中几个元素的seed该如何,谢谢站长也回答了。[s:13]

"比如生成100个但只取最后几十个,这样搜索的难度就更大了。 "

2 年 后

也就是说set.seed()的参数只要在-2147483648~2147483647范围内都是可以的,对后面的计算结果不会有影响是吧?比如接下来要做permutation test,不同的种子得到的结果是一样的或者是影响不大(比如set.seed(1000000)和set.seed(1)结果近似),设置随机数的目的只是保证结果的重演性是不是??

1 个月 后