1

我想生成一个平均值 = 0、sd = 1 和大小 n = 100 的样本,其分布尽可能正常。单独使用 rnorm 会返回很多可变性。

我发现的唯一方法是平均多个 rnorms。

rowMeans(replicate(10000, sort(rnorm(100, 0, 1))))

这会返回一个相当令人满意的结果,但我不确定这是最有效的方法。


编辑:

我不希望均值和 sd 严格等于 0 和 1,而是让分布“看起来”像正态分布(在绘制密度曲线时)。

似乎 qnorm 方法比“平均”方法效果更差:

# qnorm method
x <- qnorm(seq(.00001, .99999, length.out = 100), mean=0, sd=1)
plot(density(x))

# average method
x <- rowMeans(replicate(10000, sort(rnorm(100, mean=0, sd=1))))
plot(density(x))

在此处输入图像描述 在此处输入图像描述

我会对确定性解决方案以更有效的方式返回接近平均方法的结果感到满意。


编辑 2:可能的解决方案

根据答案,以下似乎可行,相对于 n 调整边界:

x <- qnorm(seq(1/n, 1-1/n, length.out = n), mean=0, sd=1)

下面是不同 n 值的 qnorm 和 average 方法的比较:

par(mfrow=c(6,2))
for(n in c(10, 20, 100, 500, 1000, 9876)){
  x <- qnorm(seq(1/n, 1-1/n, length.out = n), mean=0, sd=1)
  plot(density(x), col="blue", lwd=2)

  x <- rowMeans(replicate(10000, sort(rnorm(n, mean=0, sd=1))))
  plot(density(x), col="red", lwd=2)
}

在此处输入图像描述

4

4 回答 4

5

如果您想要一个确定性的解决方案,这应该可以

qnorm(seq(0.01, 0.99, length.out = 100))

注意qnorm(0)给出 $-\infty$ 并且qnorm(1)是 $\infty$,所以你需要找到一些合理的界限。

对于n=100,边界 0.01 和 0.99 似乎效果最好。如果您希望确定性解决方案的界限更远,则需要增加n.

于 2018-05-09T16:59:20.660 回答
5

您是否尝试创建 100 个具有近似正态分布的数字,其均值恰好为零,sd 恰好为 1?做这个:

大致开始:

> X = rnorm(100)

转移它们:

> X = X-mean(X)

缩放它们:

> X = X/sd(X)

核实:

> mean(X)
[1] -7.223497e-18

足够近

> sd(X)
[1] 1

砰的一声。

这与scale函数的作用相同:

> X = rnorm(100)
> mean(X)
[1] -0.007667039
> sd(X)
[1] 0.9336842
> sx = scale(X)
> mean(sx)
[1] 1.437056e-17
> sd(sx)
[1] 1
于 2018-05-09T16:59:47.203 回答
1

您可以使用 bayestestR 包:

library(bayestestR)
x <-  rnorm_perfect(n = 100, mean = 0, sd = 1)
plot(density(x))

在此处输入图像描述

于 2019-05-21T13:22:50.310 回答
0

低差异序列?Halton、faure、sobol、hammsley:例如:

library(randtoolbox)

sequence <-sobol(n=100, dim = 1, init = TRUE, scrambling = 0, seed = 4711, normal = FALSE)
mean(sequence)
[1] 0.4982031
sd(sequence)
[1] 0.2860574

#trial with prng
set.seed(1) 
sequence2 <- runif(100)
mean(sequence2)
[1] 0.5178471
sd(sequence2)
[1] 0.2675848

具有相同点数的低差异序列优于伪随机生成器,请记住,对于均匀随机样本,真实均值是 0.5,sd 是 0.2886751 (sqrt(1/12)),请查看数字。

(mean(sequence) - 0.5)/0.5   #  -0.0008984375
(mean(sequence2) - 0.5)/0.5  #  -0.008923532
(sd(sequence) - sqrt(1/12))*sqrt(12)
[1] -0.009067992
(sd(sequence2) - sqrt(1/12))*sqrt(12)
[1] -0.07305918

~ 10 倍好,如果你不相信,试试其他种子

ks.test(sequence,"runif")

    One-sample Kolmogorov-Smirnov test

data:  sequence
D = 0.96268, p-value < 2.2e-16
alternative hypothesis: two-sided

> ks.test(sequence2,"runif")

    One-sample Kolmogorov-Smirnov test

data:  sequence2
D = 0.93956, p-value < 2.2e-16
alternative hypothesis: two-sided

现在进行一些平衡:

    sequence <- c(sequence, 1.0 - sequence)  #balancing the mean = use antithetics
    #or if you want (sequence <- sequence - mean(sequence))
    normal_sample <- qnorm(sequence)
    normal_sample <- normal_sample/sd(normal_sample)
    plot(normal_sample)
于 2018-06-29T14:58:25.907 回答