Генерация идеально нормально распределенной выборки размером n в R - PullRequest
0 голосов
/ 09 мая 2018

Я хотел бы создать выборку со средним значением = 0, sd = 1 и размером n = 100, распределение которого является нормальным, насколько это возможно. Использование одного только rnorm возвращает большую изменчивость.

Единственный способ, который я нашел, - усреднить несколько норм.

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

Это дает довольно удовлетворительный результат, но я не уверен, что это самый эффективный способ сделать это.


EDIT:

Я не хочу, чтобы среднее значение и 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))

enter image description here enter image description here

Я был бы рад, если бы детерминированное решение более эффективно возвращало результаты, близкие к среднему методу.


РЕДАКТИРОВАТЬ 2: Возможное решение

Судя по ответам, работает следующее, корректируя границы относительно n:

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

Ниже приведено сравнение методов qnorm и среднего для разных значений n:

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)
}

enter image description here

Ответы [ 4 ]

0 голосов
/ 21 мая 2019

Вы можете использовать пакет bayestestR:

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

enter image description here

0 голосов
/ 09 мая 2018

Вы пытаетесь создать 100 чисел с приблизительным нормальным распределением со средним значением ровно ноль и sd ровно одним? Сделайте это:

Начните примерно:

> 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
0 голосов
/ 29 июня 2018

Последовательность с низким расхождением? халтон, форе, соболь, хаммерсли: пример:

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 (квадрат (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)
0 голосов
/ 09 мая 2018

Если вы хотите детерминистическое решение, это должно работать

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

Обратите внимание, что qnorm(0) дает $ - \ infty $, а qnorm(1) - это $ \ infty $, поэтому вам нужно найти разумные границы.

Для n=100 границы 0,01 и 0,99 работают лучше всего. Если вы хотите, чтобы границы определяли детерминированное решение дальше, вам нужно увеличить n.

...