[英]Difference drawing random numbers from distributions R
我正在比较这两个 forms 从 beta 和高斯分布中抽取随机数。 他们有什么区别? 他们为什么不同?
第一种方法 ( _1
) 从 Uniform(0,1) 进行模拟,然后将 Beta(正态)分布的逆 CDF 应用于这些均匀绘制,以从 Beta(正态)分布中获取绘制。
而第二种方式 ( _2
) 使用默认的 function 从分布中生成随机数。
set.seed(1)
beta_1 <- qbeta(runif(1000,0,1), 2, 5)
set.seed(1)
beta_2 <- rbeta(1000, 2,5)
> summary(beta_1); summary(beta_2)
Min. 1st Qu. Median Mean 3rd Qu. Max.
0.009481 0.164551 0.257283 0.286655 0.387597 0.895144
Min. 1st Qu. Median Mean 3rd Qu. Max.
0.006497 0.158083 0.261649 0.284843 0.396099 0.841760
这里每个数字都不一样。
set.seed(1)
norm_1 <- qnorm(runif(1000, 0,1), 0, 0.1)
set.seed(1)
norm_2 <- rnorm(1000, 0, 0.1)
> summary(norm_1); summary(norm_2)
Min. 1st Qu. Median Mean 3rd Qu. Max.
-0.3008048 -0.0649125 -0.0041975 0.0009382 0.0664868 0.3810274
Min. 1st Qu. Median Mean 3rd Qu. Max.
-0.300805 -0.069737 -0.003532 -0.001165 0.068843 0.381028
这里的数字几乎相同,除了均值和中位数
不应该都是平等的吗? 因为我从具有相同参数的分布中生成随机数
我尝试使用两种不同的方式在家里对伯努利参数进行采样。
我只做了二十次而不是一千次,但原理是一样的。 我得到以下结果:
结果 0 | 结果 1 | |
---|---|---|
方法一 | 11 | 9 |
方法二 | 8个 | 12 |
问:为什么两种方法都没有得到相同的结果?
A:嗯,这当然是因为它们是样本,应该每次都是可变的。
如果我能够重置一些随机种子以消除可变性,那么这仍然无关紧要,因为它们是不同的方法。
正态分布实际上确实使用了逆变换采样。 以下命令返回相同的值0.3735462
set.seed(1)
rnorm(1,1,1)
set.seed(1)
qnorm(runif(1),1,1)
此外, rbeta
使用逆变换采样,以下返回相同的0.7344913
和0.2655087
,它们仅因关系 Y = 1-X 而不同(因此内部存在一些反转)
alpha = 1
beta = 1
set.seed(1)
rbeta(1,alpha,beta)
set.seed(1)
qbeta(runif(1),alpha,beta)
当$\alpha$和$\beta$不等于 1 时,beta function 会变得不同。 这是因为逆采样效率不高, rbeta
function 会执行一些以不同方式创建样本的算法。 以下是$min(\alpha,\beta) \leq 1$情况下的算法代码。
有关该算法的更多信息,请参阅:Hung、Ying-Chao、Narayanaswamy Balakrishnan 和 Yi-Te Lin。 “评估 beta 生成算法。” 统计模拟与计算通信 38.4 (2009):750-770。
您可以看到一些计算方式不同的点。 该算法有几个步骤,它开始重新绘制随机数,这样做是因为重新绘制数字比计算困难情况下的逆变换更容易。
alpha = 0.9
beta = 0.9
#### Cheng's BC algorithm
### used if min(alpha,beta)<=1
### initialize
set.seed(1)
p = min(alpha,beta)
q = max(alpha,beta)
a = p+q
b = p^-1
delta = 1+q-p
k1 = delta*(0.0138889+0.0416667*p)/(q*b-0.777778)
k2 = 0.25 + (0.5+0.25/delta)*p
sample = function() {
### Perform steps of algorithm in a loop
step = 1
while(step<6) {
if (step == 1) {
U1 = runif(1)
U2 = runif(1)
if (U1 < 0.5)
{step = 2}
else
{step = 3}
}
if (step == 2) {
Y = U1*U2
Z = U1*Y
if (0.25*U2 + Z-Y >= k1) {
step = 1
} else {
step = 5
}
}
if (step == 3) {
Z = U1^2*U2
if (Z > 0.25) {
step = 4
} else {
V = b*log(U1/(1-U1))
W = q*exp(V)
step = 6
}
}
if (step == 4) {
if (Z < k2) {
step = 5
} else {
step = 1
}
}
if (step == 5) {
V = b*log(U1/(1-U1))
W = q*exp(V)
if (a*(log(a/(p+W))+V) - 1.3862944 < log(Z)) {
step = 1
} else {
step = 6
}
}
}
if (q == alpha) {
X = W/(p+W)
} else {
X = p/(p+W)
}
return(X)
}
sample()
n = 20
beta_orig = sapply(1:n,function(x) {
set.seed(x)
rbeta(1,alpha,beta)
})
beta_quantile = sapply(1:n,function(x) {
set.seed(x)
qbeta(runif(1),alpha,beta)
})
beta_BC = sapply(1:n,function(x) {
set.seed(x)
sample()
})
plot(beta_orig,beta_BC, pch = 1, xlim = c(0,1), ylim = c(0,1))
points(beta_orig,beta_quantile, col = 2, pch = 3)
legend(0.3,1, c("rbeta compared to inverse transform sampling", "rbeta compared to manual"), pch=c(3,1), col = c(2,1), cex = 0.85)
在上面的代码中,我为每次计算重置了随机种子。 逆变换仅对第一个数字相同。 当您计算多个数字时,只有第一个数字是相同的。
以下代码
set.seed(1)
rnorm(6,1,1)
set.seed(1)
qnorm(runif(6),1,1)
set.seed(2)
rnorm(6,1,1)
set.seed(2)
qnorm(runif(6),1,1)
回报
[1] 0.3735462 1.1836433 0.1643714 2.5952808 1.3295078 0.1795316
[1] 0.3735462 0.6737666 1.1836433 2.3297993 0.1643714 2.2724293
[1] 0.1030855 1.1848492 2.5878453 -0.1303757 0.9197482 1.1324203
[1] 0.10308546 1.53124079 1.18484918 0.03810797 2.58784531 2.58463150
您在这里看到的是rnorm
function 跳过了一个数字。 原因是因为它对两个随机数进行采样以创建更高的精度。
请参阅 R 使用的 norm_rand() function 的源代码中的这些行https://svn.r-project.org/R/trunk/src/nmath/snorm.c
define BIG 134217728 /* 2^27 */
/* unif_rand() alone is not of high enough precision */
u1 = unif_rand();
u1 = (int)(BIG*u1) + unif_rand();
return qnorm5(u1/BIG, 0.0, 1.0, 1, 0);
我认为您的问题归结为关于随机数生成器的假设。 如果rnorm
在后台使用与runif
相同的 RNG,那么您的期望就会成立。 它不使用相同的 RNG。 正态分布 RNG 和均匀分布 RNG 是分开的。 见?RNGkind
。 如果没有完全匹配,您将得到以下统计测试:
norm_1 的均值是否与 norm_2 的均值不同?
t.test(x = norm_1, y = norm_2)
p 值 > 0.05 表示没有足够的证据拒绝 null 假设均值在 0.05 I 类错误水平下相等
分布不同吗?
ks.test(x = norm_1, y = norm_2)
p 值 > 0.05 表示没有足够的证据拒绝 null 假设,即分布在 0.05 I 类错误水平下相等
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.