R里的伪随机数怎么取的不得而知,但逆变换法应该是在分布函数已知的情况下最方便的做法吧。
我们从最简单的指数分布来测试吧。方法1用逆变换,方法2用伪随机也就是R里的built-in.
最后比较每种方法和各自,还有和对方的最大绝对值差值的分布。
方法1:
invF <- function(x){ log(1/(1-x))}D <- vector()
for (i in 1:100){
a <- runif(1e4) # 两组1万个0-1均匀分布随机数
b <- runif(1e4)
ran1 <- sapply(a, invF)
ran2 <- sapply(b, invF)
D <- c(D, max(abs(ran1 - ran2)))
}
summary(D)
Min. 1st Qu. Median Mean 3rd Qu. Max.
7.651 9.100 9.762 9.875 10.540 13.940
方法2:
D <- vector()for (i in 1:100){
a <- rexp(1e4, rate = 1) # 两组1万个参数为1的指数分布随机数
b <- rexp(1e4, rate = 1)
D <- c(D, max(abs(a - b)))
}
summary(D)
Min. 1st Qu. Median Mean 3rd Qu. Max.
7.765 8.977 9.574 9.727 10.590 12.540
两种方法混合:a是逆变换,b是伪随机
invF <- function(x){ log(1/(1-x))}D <- vector()
for (i in 1:100){
a <- runif(1e4) # 1万个0-1均匀分布随机数
b <- rexp(1e4, rate = 1) # 1万个参数为1的指数分布随机数
ran1 <- sapply(a, invF)
D <- c(D, max(abs(ran1 - b)))
}
summary(D)
Min. 1st Qu. Median Mean 3rd Qu. Max.
7.679 8.701 9.385 9.536 10.150 13.610
有没有发现。。根本没什么不同。
R语言中set.seed()作用是设定生成随机数的种子,目的是为了让结果具有重复性,重现结果。 注:set.seed(1000),不是运行1000次,而是把种子设置为1000。 那么问题来了:设成100呢,1呢?有什么区别?(见下面的问答部分) 伪随机产生的。计算机的程序,都是通过确定的算法,根据确定的输入,算出确定的输出。想要得到真正的随机,需要通过外接物理随机数发生器,通过把随机的物理过程转变为随机值,才能实现。因此我们平常使用的计算机的随机数,其实都只是通过算法模拟得到,也就是伪随机。一般采用的办法是 线性同余 (进一步了解线性同余可参考下面的连接2,也可自行百度)。 参考文献: (1): https://www.jianshu.com/p/38d0a44630f8(2)经管之家1: https://bbs.pinggu.org/thread-2121186-1-1.html(3)经管之家2: https://bbs.pinggu.org/thread-336973-2-1.htmlR语言中set.seed()作用是设定生成随机数的种子,种子是为了让结果具有重复性,重现结果。如果不设定种子,生成的随机数无法重现。
后两次在设定了相同的种子前提下,生成的随机数是相同的。
说明,来源于网络
计算机并不能产生真正的随机数,如果你不设种子,计算机会用系统时钟来作为种子,如果你要模拟什么的话,每次的随机数都是不一样的,这样就不方便你研究,如果你事先设置了种子,这样每次的随机数都是一样的,便于重现你的研究,也便于其他人检验你的分析结果。
set.seed(3000),不是运行3000次,而是把种子设置为3000。
计算机的程序,都是通过确定的算法,根据确定的输入,算出确定的输出。想要得到真正的随机,需要通过外接物理随机数发生器,通过把随机的物理过程转变为随机值,才能实现。因此我们平常使用的计算机的随机数,其实都只是通过算法模拟得到,也就是伪随机。一般采用的办法是线性同余:
为简单起见,我取简单的参数(a = 1, c = 3, m = 5),得到一个简单的算式:
这时,把X[0]视为种子,于是:
对于每个种子,所得到的数列看起来都是随机的(每个数值出现的频率都是相同的)。而一旦种子给定,每次调用随机数函数,函数都会根据上次得到的数列的某个值,计算出数列的下一个值并返回回来。而对于随机浮点数,一般是用随机产生的整数除以最大整数得到。
所以,随机数的种子一般只需要在调用随机函数之前设置一次,不建议设置多次。