library(ggplot2)
options(repr.plot.width=4, repr.plot.height=4)
Seine eine Folge von unabhängigen und identisch verteilten Zufallsvariablen, so dass Mittelwert und Standardabweichung definiert und endlich sind. Sei
Dann gilt:
Vulgo: Die Summe von i.i.d. Zufallsvariablen kann durch eine Normalverteilung approximiert werden.
Für eine Standard-Gleichverteilung in gilt:
Wenn standard-gleichverteilt ist, hat Mittelwert 0 und Standardabweichung 1.
x <- replicate(10000, sum(replicate(1000,
sqrt(3)*(2*runif(1)-1)))/sqrt(1000))
ggplot(data.frame(x), aes(x=x)) +
geom_histogram(aes(y = ..density..), color='black', fill='white') +
geom_density(col='red')
(mean(x))
(sd(x))
qqnorm(x)
abline(0, 1, col='red')
ks.test(x, "pnorm")
shapiro.test(x[1:5000])
ks.test(runif(100), "pnorm")
xx <- seq(-5, 5, length.out=1000)
g <- function(x) exp(x)/(1+exp(x))^2
plot(xx, g(xx), type='l', xlab='x', ylab='g(x)',
ylim=c(0, dnorm(0)))
points(xx, dnorm(xx), type='l', col='red')
Die Verteilungsfunktion ist die logistische Funktion
Deren Umkehrung ist die Logit-Funktion
Daher lässt sich durch die inverse Methode leicht eine -verteilte Zufallsvariable generieren.
logit <- function(p) log(p/(1-p))
x <- replicate(100000, logit(runif(1)))
ggplot(data.frame(x), aes(x=x)) +
geom_histogram(aes(y = ..density..), color='black', fill='white') +
geom_density(col='red')
(mean(x))
(sd(x))
C = 4/sqrt(2*pi)
f <- function(x) {
return(1/sqrt(2*pi) * exp(-x^2/2))
}
rnormal <- function() {
x <- logit(runif(1))
u <- runif(1)
weiter = TRUE
while (weiter) {
if (u > f(x)/(C*g(x))) {
x <- logit(runif(1))
u <- runif(1)
} else {
weiter = FALSE
}
}
return(x)
}
x <- replicate(10000, rnormal())
ggplot(data.frame(x), aes(x=x)) +
geom_histogram(aes(y = ..density..), color='black', fill='white') +
geom_density(col='red')
(mean(x))
(sd(x))
qqnorm(x)
abline(0, 1, col='red')
ks.test(x, "pnorm")
shapiro.test(x[1:500])
Seien und zwei unabhängige standard-normalverteilte Zufallsvariablen. und sind die entsprechenden polaren Koordinaten, also
Sei .
Die gemeinsame Dichte von und ist
Sei eine differenzierbare bijektive Funktion zwischen Vektorräumen. Dann gilt
Angewandt auf ergibt das
Das ist das Produkt einer Gleichverteilung über im Intervall und einer Exponentialverteilung über mit Mittelwert 2.
Wenn man also eine exponential verteilte Zufallsvariable mit Mittelwert 2 und eine im Interval gleichverteilte Zufallsvariable , generiert, sind die folgenden Variablen unabhängig und standard-normalverteilt:
Dieses Verfahren heißt Box-Muller-Methode.
Die kostspielige Berechnung der trigonometrischen Funktionen lässt sich vermeiden, indem man state gleichverteilte Koordinaten innerhalb des Einheitskreises simuliert.
plot(NULL, xlim=c(-1, 1), ylim=c(-1,1), asp=1)
for (i in 1:1000) {
weiter <- TRUE
while (weiter) {
x <- 2*runif(1)-1
y <- 2*runif(1)-1
if ((x^2 + y^2) <= 1) {
weiter <- FALSE
}
}
points(x, y)
points(x/sqrt(x^2+y^2), y/sqrt(x^2+y^2), col='red', cex=.1)
}
Aus den Regeln für das Wechseln von Variablen folgt, dass bei diesem Verfahren und unabhängige, gleichverteilte Zufallsvariablen sind (über die Intervalle und . Daher kann man zur Simulierung der exponentiell verteilten Variable recyclen.
polarNormal <- function() {
weiter <- TRUE
while (weiter) {
x <- 2*runif(1)-1
y <- 2*runif(1)-1
if ((x^2 + y^2) <= 1) {
weiter <- FALSE
}
}
R2 <- x^2+y^2
output <- sqrt(-2*log(R2))*c(x, y)/sqrt(R2)
return(output)
}
x <- as.vector(replicate(5000, polarNormal()))
ggplot(data.frame(x), aes(x=x)) +
geom_histogram(aes(y = ..density..), color='black', fill='white') +
geom_density(col='red')
(mean(x))
(sd(x))
qqnorm(x)
abline(0, 1, col='red')
ks.test(x, "pnorm")
shapiro.test(x[1:500])
Eine normal verteilte Zufallsvariable hat die Dichtefunktion
Dabei sind der Mittelwert und die Standardabweichung.
Wenn normalverteilt ist mit Parametern , dann ist standard-normalverteilt.
Mit Hilfe dieses Zusammenhangs lassen sich standard-normalverteilte Zufallszahlen in beliebig parametrisierte normalverteilte Zufallszahlen transformieren.
mu <- -10
sigma <- 0.1
z <- as.vector(replicate(5000, polarNormal()))
x <- sigma*z + mu
ggplot(data.frame(x), aes(x=x)) +
geom_histogram(aes(y = ..density..), color='black', fill='white') +
geom_density(col='red')
(mean(x))
(sd(x))
d <- data.frame(matrix(replicate(20000, polarNormal()), ncol=2))
colnames(d) <- c('x', 'y')
ggplot(d, aes(x=x, y=y)) + geom_point(alpha=.3) + geom_density_2d() + coord_fixed()
Sei
und sei eine standard-normalverteilte bivariate Zufallsvariable. Dann ist
Im Beispiel:
heißt die Varianz-Kovarianz-Matrix der Verteilung. Es ist das multivariate Analog der univariaten Varianz . Das Verhalten einer multivariaten Normalverteilung ist durch und eindeutig bestimmt. Weiterhin ist für gegeben Varianz-Kovarianz-Matrix die multivariate Normalverteilung die Wahrscheinlichkeitsverteilung mit maximaler Entropie.
(A <- matrix(c(4, 8, 2, 3), nrow=2, byrow=T))
mu <- c(1, 2)
(Sigma <- A %*% t(A))
(detSigma <- det(Sigma))
(invSigma <- solve(Sigma))
Multivariat standard-normalverteilte Zufallszahlen können durch Multiplikation mit und Addition von leicht in beliebige Normalverteilungen transformiert werden.
z <- replicate(10000, polarNormal())
x <- data.frame(t((A %*% z) + mu ))
colnames(x) <- c('x1', 'x2')
apply(x, 2, mean)
var(x)
ggplot(x, aes(x=x1, y=x2)) + geom_point(alpha=.3) + geom_density_2d()
Angenommen, wir kennen für eine multivariate Normalverteilung die Parameter und . Wir möchten Zufallszahlen für diese Verteilung generieren.
Wenn wir eine Matrix kennen mit der Eigenschaft , können wir obige Methode verwenden, um aus standard-multivariat-normalverteilten Zufallszahlen die gewünschten Zufallszahlen zu gewinnen.
Wenn positiv (semi-)definit ist, ist es immer möglich, eine solche Matrix zu berechnen, dank des Theorems:
Wenn eine symmetrische, positiv (semi-)definite Matrix ist, dann gibt es genau eine untere Dreiecksmatrix , so dass .
Diese Zerlegung heißt Cholesky-Zerlegung.
Für unser Beispiel gilt:
t(chol(Sigma))
(B = matrix(c(20, 0, 8, 1), nrow=2, byrow=T)/sqrt(5))
B %*% t(B)
Sigma <- matrix(c(4, 12, -16,
12, 37, -43,
-16, -43, 98), nrow=3)
mu <- c(1, 2, 3)
(A <- t(chol(Sigma)))
(A %*% t(A))
z <- matrix(replicate(3*1e5, polarNormal()), ncol=3)
x <- t(A %*% t(z) + mu)
apply(x, 2, mean)
cov(x)