繁体   English   中英

从分布中提取随机数的差异 R

[英]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

这里的数字几乎相同,除了均值和中位数

不应该都是平等的吗? 因为我从具有相同参数的分布中生成随机数

我尝试使用两种不同的方式在家里对伯努利参数进行采样。

  1. 我掷一枚硬币,正面为 1,反面为 0
  2. 我掷一个六面骰子,并将结果 1 分配给 3 个最高数字的掷骰,结果 0 分配给 3 个最低数字的掷骰。

我只做了二十次而不是一千次,但原理是一样的。 我得到以下结果:

结果 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.73449130.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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM