我想生成一个mean = 0,sd = 1和size 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))
我很满意确定性解决方案,以更有效的方式将结果返回到接近平均值的方法。
根据答案,以下似乎可行,相对于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)
}
答案 0 :(得分:5)
如果你想要一个确定性的解决方案,这应该有效
qnorm(seq(0.01, 0.99, length.out = 100))
请注意qnorm(0)
给$ - \ infty $而qnorm(1)
是$ \ infty $,所以你需要找到一些合理的界限。
对于n=100
,界限0.01和0.99似乎效果最好。如果您希望确定性解决方案的界限更远,则需要增加n
。
答案 1 :(得分: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
答案 2 :(得分:1)
答案 3 :(得分:0)
低差异序列? 希尔顿,福尔,索博尔,哈姆斯利:例如:
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)),请看数字。 / p>
(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)