Angewandte Datenanalyse mit R und R-Stan Dieser Artikel zeigt die nötigen R-Befehle, um die Abbildungen und Simulationen zu den Beispielen im Buch D. Bättig: Angewandte Datenanalyse Der Bayes sche Weg erzeugen zu können. Version: 8. Februar 2016 Kapitel 1 Beispiel 1.7 (Nicht keimende Blumenzwiebeln) Die Daten sind im EXCEL-File mit Namen blumenzwiebeln.xlsx gespeichert. Sie liegen in der A-Spalte (A2 bis A51) und der Name der Variablen (in A1) ist anzahl. Zuerst wird das File in ein tab-getrenntes Formt umgewandelt: blumenzwiebeln.txt. Für das Einlesen der Daten muss man zuerst das Verzeichnis wählen, in dem das File abgespeichert ist. Besonders einfach ist dies bei RStudio. Dann File einlesen: > daten <- read.table("blumenzwiebeln.txt", header = T) Darstellen der Abb. 1.5 geht wie folgt: > plot(anzahl) > lines(anzahl) > grid() Kapitel 2 Beispiel 2.13 (Kanalwärmetauscher) Die Daten sind im tab-getrennten-file mit Namen kanalwaermetauscher.txt gespeichert. Die Messwerte von S, D, R und der Zielvariablen Verformung liegen in den Spalten. Einlesen der Daten zuerst richtiges Verzeichnis wählen mit: > daten <- read.table("kanalwaermetauscher.txt", header = T) Berechung der Effekte von S, D und R und ihrer Interaktion bis zu dritter Ordung mit: > lm(verformung ~.^3, data = daten) Call: lm(formula = Verformung ~.^3, data = daten) Coefficients: (Intercept) S D R S:D 4.632083-2.438750-1.269583 0.005417 0.669583 S:R D:R S:D:R -0.152083 0.038750-0.008750 R berechnet die halben Werte der Effekte und Interaktionen. 1
Kapitel 3 Beispiel 3.6 (Nicht keimende Blumenzwiebeln) Ziehen mit Zurücklegen einer Stichprobe mit Stichprobenumfang n aus einer Grundgesamtheit mit N Elementen: > sample(1:n, n, replace = T) Ziehen ohne Zurücklegen einer Stichprobe mit Stichprobenumfang n aus einer Grundgesamtheit mit N Elementen: > sample(1:n, n, replace = F) Besteht die Grundgesamtheit aus 10 Elementen und zieht man vier Elemente mit Zrücklegen, so hat man etwa > sample(1:10,4,replace=t) [1] 8 1 8 3 Gezogen wurde zuerst 8, dann 1, dann 8 und schliesslich 3. Beispiel 3.13 (Druck in einer Vakuumkammer) Die Daten sind im tab-getrennten File mit Namen vakuum.txt gespeichert. Sie liegen in einer Spalte und der Name der Variablen ist druck. Einlesen der Daten: > daten <- read.table("vakuum.txt", header = T); Zeichnen der Kontrollkarte: > plot(druck); lines(druck) Die Kontrollgrenzen LCL und UCL können wie folgt berechnet werden: > mean(druck)+3*sd(druck) [1] 0.5938749 > mean(druck)-3*sd(druck) [1] 0.5884701 Kapitel 4 Beispiel 4.6 (Tagesschlusskurs einer Aktie) Darstellung der Massenfunktion des diskreten Wahrscheinlichkeitsmodells, wie in Abb. 4.1: > wschluss <- c( 2,6,10 ) > P <- c( 0.15,0.4,0.45 ) > plot(wschluss,p,"h",lwd=20) Die Zahl lwd=20 gibt die Stabdicke an. 2
Beispiel 4.9 (Zerfallszeit von Radon) Um die Abb. 4.4 für den Graph der Dichtefunktion für die Exponentialverteilung mit Rate λ = 1/5.515 zu zeichnen, geht man wie folgt vor: > lambda <- 1/ 5.515 > x <- seq(-1,15,length.out=1000) > y <- dexp(x,lambda) > plot(x,y, type="l", lwd=3, col="blue") Der zweite Befehl entpricht dem MATLAB Befehl linspace(-1,15,1000). Beispiel 4.21 (Zeit zwischen starken Erdbeben) Die MCMC-Simulation für die gegebene Dichtefunktion erfolgt mit R-Stan und mit dem Logarithmus der Dichtefunktion. Zuerst wird in einem R-File das Modell eingegeben und einlesen: verteilungcode <- " // Logarithmus der Dichtefunkton: Name_log(...): functions { real meinefunktion_log(real x ) { return -29*log(x)-13910.55/x; // Groessen, die mit dem Modell beschrieben werden: parameters { real<lower=0> mu; // Wahrscheinlichkeitsmodell: model { mu ~ meinefunktion(); " Das File nun mit R einlesen. Nun erfolgt die MCMC-Simulation (hier Kette mit einer Gesamtlänge von 100 000): > library(rstan) > mcmckette <- stan(model_code = verteilungcode, iter = 50000) > print(mcmckette) Inference for Stan model: verteilungcode. 4 chains, each with iter=50000; warmup=25000; thin=1; post-warmup draws per chain=25000, total post-warmup draws=1e+05. mean... 2.5% 25% 50% 75% 97.5% n_eff Rhat 3
mu 514.99... 353.40 443.50 502.48 572.99 748.41 34431 1 lp -202.33... -204.36-202.49-202.06-201.88-201.83 36349 1 Samples were drawn using NUTS(diag_e) at Thu Jun 4 07:46:22 2015. For each parameter, n_eff is a crude measure of effective sample size, and Rhat is the potential scale reduction factor on split chains (at convergence, Rhat=1). Man sieht, dass die Verteilung von µ wahrscheinlich vollständig abgetast ist (R_hat= 1). Mit einer Wahrscheinlichkeit von 0.95 ist 353.4 µ 748.4. Darstellung der Abtastung und der Dichtefunktion wie in Abb. 4.15: > mu <- extract(mcmckette)$mu > split.screen(c(1,2)) > screen(1) > plot(mu, type="l") > screen(2) > hist(mu, prob=t, col="grey", border="white") > lines(density(mu), lwd=3) Buntere und designte Bilder erhält man mit den folgenden Befehlen: > stan_trace( mcmckette, pars="mu" ) > bild <- stan_hist( mcmckette, pars="mu", fill="green", color="white" ) > bild + geom_density( size=2 ) Berechnung des plausibelsten Wertes (Modus) von µ: > op <- optimizing(mcmckette@stanmodel) > op mu 479.6455 $value [1] -208.0201 Der Modus µ 0 der Verteilung ist 479,65. Die Berechnung von Quantilen und Wahrscheinlichkeiten erfolgt mit: > quantile(mu, c(0.025,0.25,0.5,0.75,0.975) ) 2.5% 25% 50% 75% 97.5% 353.3970 443.4956 502.4819 572.9883 748.4092 > sum(mu>600)/length(mu) [1] 0.18279 Mit einer Wahrscheinlichkeit von 0,50 liegt µ zwischen 443,5 und 573,0. Die Wahrscheinlichkeit ist 0,18, dass µ grösser als 600 ist. 4
Kapitel 5 Beispiel 5.3 (HNV-Indikator) in Abb. 5.3: Prior und Plausibilität zum Anteil A dargestellt wie > A <- seq(0,1,length.out=10000) > plot(a,504*a^3*(1-a)^5, type="l", lwd=3) # Posterior > abline(h=1, lty="dashed") # Prior Bestimmung des Posteriors von A aus den Daten und dem Bernoulli-Model mit R-Stan. Zuerst wird in einem R-File das Modell eingegeben und eingelesen: codebernoulli <- " data { int n; int<lower=0, upper=1> x[n]; parameters { real<lower=0, upper=1> A; model { A ~ uniform(0,1); // Prior for ( i in 1:n) { x[i] ~ bernoulli(a); // Datenmodell " Die Daten müssen eingelesen und strukturiert werden, damit Stan die MCMC-Simulation ausführen kann: > daten <- list(x = c(1,1,0,0,0,1,0,0), n = 8) Nun erfolgt die MCMC-Simulation (hier Kette mit einer Gesamtlänge von 10 000): > library(rstan) > mcmckette <- stan(model_code = codebernoulli, data = daten, iter = 5000) > print(mcmckette) Inference for Stan model: codebernoulli. 4 chains, each with iter=5000; warmup=2500; thin=1; post-warmup draws per chain=2500, total post-warmup draws=10000. mean se_mean sd 2.5% 25% 50% 75% 97.5% n_eff Rhat A 0.40 0.00 0.15 0.14 0.29 0.39 0.50 0.70 3442 1 5
lp -7.24 0.01 0.73-9.31-7.39-6.96-6.78-6.73 3661 1 Samples were drawn using NUTS(diag_e) at Thu Jun 4 09:08:11 2015. For each parameter, n_eff is a crude measure of effective sample size, and Rhat is the potential scale reduction factor on split chains (at convergence, Rhat=1). Man sieht, dass der Posterior von A wahrscheinlich vollständig abgetast ist (R_hat= 1). Mit einer Wahrscheinlichkeit von 0,95 ist 0,14 A 0,70. Darstellung der Abtastung und der Dichtefunktion wie in Abb. 5.4: > A <- extract(mcmckette)$a > split.screen(c(1,2)) > screen(1) > plot( A, type="l" ) > screen(2) > hist( A, prob = T, col="grey", border="white" ) > lines( density(a), lwd = 3 ) Berechnung des plausibelsten Wertes (Modus) von A: > op <- optimizing(mcmckette@stanmodel, data = daten) > op $par A 0.375 $value [1] -5.292506 Der Modus A 0 des Posteriors von A ist 0,375. Die Berechnung von Quantilen und Wahrscheinlichkeiten erfolgt mit: > quantile(a, c(0.025,0.25,0.5,0.75,0.975) ) 2.5% 25% 50% 75% 97.5% 0.1399492 0.2948650 0.3919208 0.4992926 0.6988811 > sum(a>0.5)/length(a) [1] 0.2486 Mit einer Wahrscheinlichkeit von 0,50 liegt A zwischen 0,295 und 0,499. Die Wahrscheinlichkeit ist 0,249, dass A grösser als 0,5 ist. Beta-Verteilung mit R Die Beta-Verteilung mit Kennzahlen α und β hat die Dichtefunktion pdf(a = x α, β) x α 1 (1 x) β 1 für 0 x 1 Beachten Sie die Exponenten: α 1 und β 1! Mit R: 6
Dichtefunktion: dbeta(x,alpha,beta) Quantil q: qbeta(q,alpha,beta) Wahrscheinlichkeit P(A x): pbeta(x,alpha,beta) Wahrscheinlichkeit P(a A b): pbeta(b,alpha,beta) - pbeta(a,alpha,beta) Kapitel 6 Beispiel 6.3 und 6.4 (Arbeitslosigkeit und Flexibilität) Die Daten sind im tabgetrennten-file mit Namen wirtschaft.txt gespeichert. Die Messwerte von Flexi und Arbeit liegen in den Spalten. Einlesen der Daten: > daten <- read.table("wirtschaft.txt", header = T) Das Streudiagramm in Abb. 6.5 erzeugt man wie folgt: > plot(flexi, Arbeit) Der empirische Korrelationskoeffizient ρ emp nach Pearson berechnet sich mit > cor(flexi, Arbeit) [1] -0.3295118 Beispiel 6.7 (Zeit zwischen starken Erdbeben) Die Daten sind im tab-getrennten File mit Namen warteohnenach.txt gespeichert. Die Messwerte liegen in einer Spalte mit mit Variablenname Zeit. Einlesen der Daten: > daten <- read.table("warteohnenach.txt", header=t) Streudiagramm (Abb. 6.9) der Daten: > plot(zeit); lines(zeit) Der Graph der Autokorrelationsfunktion (Abb. 6.10) berechnet sich mit: > acf(zeit) Kapitel 7 Beispiel 7.3 (Qualität eines Expertensystems) P(Messwert = 1 Daten) Um das Prognosemodell für den nächsten Messwert zu bestimmen, muss man eine MCMC-Kette des Posteriors von A haben. Dies geschieht wie in Kapitel 5 mit dem Bernoulli-Model und R-Stan. Zuerst wird das R-File mit dem codebernoulli eingelesen. Die Daten müssen dann eingelesen und strukturiert werden, damit Stan die MCMC-Simulation ausführen kann: 7
> daten <- list(x = c( rep(0,18),1,1 ), n = 20) Nun erfolgt die MCMC-Simulation (hier Kette mit einer Gesamtlägne von 10 000): > library(rstan) > mcmckette <- stan(model_code=codebernoulli, data = daten, iter = 5000) Die MCMC-Kette zu A extrahieren und mit dem Bernoulli-Modell 10 000 nächste Messewerte simulieren: > A <- extract(mcmckette)$a > N <- length(a) > naechstermesswert <- rbinom(n,1,a) Die Wahrscheinlichkeit eine Eins als nächsten Messwert zu haben, ist : > sum(naechstermesswert>0)/length(naechstermesswert) [1] 0.1355 Kapitel 9 Exponentialverteilung mit R Die Exponential-Verteilung mit Rate λ = 1/µ hat die Dichtefunktion pdf(x = x µ) = 1 exp( x/µ) µ für x 0 Mit R: Dichtefunktion: dexp(x,lambda) Quantil q: qexp(q,lambda) Wahrscheinlichkeit P(X x): pexp(x,lambda) Wahrscheinlichkeit P(a X b): pexp(b,lambda) - pexp(a,lambda) n Zufallszahlen nach Exp-Modell: rexp(n,lambda) Beispiel 9.1 (Zeit zwischen starken Erdbeben) Die Daten sind im tab-getrennten File mit Namen warteohnenach.txt gespeichert. Die Messwerte liegen in einer Spalte mit Variablennamen Zeit. Einlesen der Daten: > daten <- read.table( warteohnenach.txt, header = T) Streudiagramm (Abb. 9.1) der Daten: > plot(zeit); lines(zeit) 8
Der Graph der Autokorrelationsfunktion (Abb. 9.2) berechnet sich mit: > acf(zeit) Bestimmung des Posteriors von µ (der durchschnittliche zukünfitgen Wartezeit zwischen starken Erdbeben) aus den Daten und dem Exponential-Model mit R-Stan. Zuerst wird in einem R-File das Modell eingegeben und eingelesen: codeexponential <- " data { int n; real<lower=0> x[n]; parameters { real<lower=0> mu; model { // Prior mu ~ gamma(1e-10,1e-10); " // Datenmodell for ( i in 1:n ) { x[i] ~ exponential(1/mu); Die Daten müssen nun eingelesen und strukturiert werden, damit Stan die MCMC- Simulation ausführen kann: > daten <- list( x = Zeit, n = length(zeit) ) Nun erfolgt die MCMC-Simulation (hier Kette mit einer Gesamtlägne von 50 000): > mcmckette <- stan(model_code=codeexponential, data=daten, iter=25000) > print(mcmckette) Inference for Stan model: codeexponential. 4 chains, each with iter=25000; warmup=12500; thin=1; post-warmup draws per chain=12500, total post-warmup draws=50000. mean... 2.5% 25% 50% 75% 97.5% n_eff Rhat mu 515.40... 355.98 444.63 502.88 571.92 743.56 16536 1 lp -202.32... -204.28-202.48-202.05-201.88-201.83 20560 1 9
Samples were drawn using NUTS(diag_e) at Thu Jun 4 14:08:31 2015. For each parameter, n_eff is a crude measure of effective sample size, and Rhat is the potential scale reduction factor on split chains (at convergence, Rhat=1). Man sieht, dass die Verteilung von µ wahrscheinlich vollständig abgetast ist (R_hat= 1). Mit einer Wahrscheinlichkeit von 0.95 ist 356 µ 744. Darstellung der Abtastung und der Dichtefunktion wie in Abb. 9.4: > mu <- extract(mcmckette)$mu > split.screen(c(1,2)) > screen(1) > plot(mu, type="l") > screen(2) > hist(mu, prob=t, col="grey", border="white" ) > lines(density(mu), lwd=3) Berechnung des plausibelsten Wertes (Modus) von µ: > op <- optimizing(mcmckette@stanmodel, data=daten) > op $par mu 479.6741 $value [1] -208.0201 Der Modus µ 0 der Verteilung ist 479,67 Tage. Die Berechnung von Quantilen und Wahrscheinlichkeiten erfolgt mit: > quantile(mu, c( 0.025,0.25,0.5,0.75,0.975 ) ) 2.5% 25% 50% 75% 97.5% 355.9845 444.6343 502.8754 571.9219 743.5578 > sum(mu>600)/length(mu) [1] 0.18262 Mit einer Wahrscheinlichkeit von 0,50 liegt µ zwischen 444,6 und 571,9 Tagen. Die Wahrscheinlichkeit ist 0,18, dass µ grösser als 600 ist. Nun zum Prognosemodell für den nächsten Messwert: Die Monte-Carlo-Simulation für weitere Messwerte erfolgt mit dem Exponential-Modell: > N <- length(mu) > neumess <- rexp(n,1/mu) Darstellung des Prognosemodells wie in Abb. 9.6 durch: > hist( neumess, prob = T, col="grey", border="white" ) > lines( density(neumess), lwd = 3, col = "red" ) 10
Beispiel 9.3 (Zeit zwischen starken Erdbeben) Mit dem Prognosemodell für den nächsten Messwert kann man überprüfen, ob das Datenmodell (die Exponentialverteilung) sinnvoll ist. Dazu macht man den QQ-Plot (Abb. 9.8): > n <- length(zeit); > quantilemodell <- quantile( neumess, ppoints(n) ) > qqplot(quantilemodell, Zeit) > abline(a = 0, b = 1) > grid() Kapitel 10 Normalverteilung mit R Die Normalverteilung mit Modus µ und Standardabweichung σ hat die Dichtefunktion ( ) 2 1 x µ pdf(x = x µ, σ) = { 0.5 exp 2πσ 2 σ Mit R: Dichtefunktion: dnorm(x,mu, sigma) Quantil q: qnorm(q,mu, sigma) Wahrscheinlichkeit P(X x): pnorm(x, mu, sigma) Wahrscheinlichkeit P(a X b): pnorm(b, mu, sigma) - pnorm(a, mu, sigma) n Zufallszahlen: rnorm(n,mu, sigma) Beispiel 10.4 (Chloridgehalt) Die Daten sind im tabstoppgetrennten File mit Namen chlorid.txt gespeichert. Die Messwerte liegen in einer Spalte mit Variablennamen konz. Einlesen der Daten: > daten <- read.table("chlorid.txt", header = T) Streudiagramm (Abb. 10.7) der Daten: > plot(konz); lines(konz) Bestimmung des Posteriors für den Chloridgehalt Cl (um den die Messwerte streuen) aus den Daten und dem Normal-Model mit R-Stan. Zuerst wird in einem R-File das Modell eingegeben und eingelesen: 11
codenormal <- " data { int n; real x[n]; parameters { real Cl; real<lower=0> sigma; model { // Prior sigma ~ gamma(1e-10,1e-10); " // Datenmodell for ( i in 1:n ) { x[i] ~ normal( Cl, sigma ); Die Daten müssen nun eingelesen und strukturiert werden, damit Stan die MCMC- Simulation ausführen kann: > daten <- list( konz = konz, n = length(konz) ) Nun erfolgt die MCMC-Simulation (hier Kette mit einer Gesamtlägne von 50 000): > library(rstan) > mcmckette <- stan(model_code=codenormal, data=daten, iter=25000) > print(mcmckette) Inference for Stan model: codenormal. 4 chains, each with iter=25000; warmup=12500; thin=1; post-warmup draws per chain=12500, total post-warmup draws=50000. mean se_mean sd 2.5% 25% 50% 75% 97.5% n_eff Rhat Cl 102.84 0.00 0.45 101.96 102.59 102.84 103.10 103.75 13875 1 sigma 1.11 0.00 0.41 0.62 0.84 1.01 1.26 2.15 12361 1 lp -3.85 0.01 1.18-7.11-4.29-3.48-3.02-2.72 8969 1 Samples were drawn using NUTS(diag_e) at Fri Jun 5 15:19:59 2015. For each parameter, n_eff is a crude measure of effective sample size, and Rhat is the potential scale reduction factor on split chains (at convergence, Rhat=1). 12
Man sieht, dass der Posterior von Cl wahrscheinlich vollständig abgetast ist (R_hat= 1). Mit einer Wahrscheinlichkeit von 0,95 ist 102,0 Cl 103,8. Darstellung der Abtastung und der Dichtefunktion wie in Abb. 10.11: > Cl <- extract(mcmckette)$cl > split.screen(c(1,2)) > screen(1) > plot(cl, type="l") > screen(2) > hist( Cl, prob = T, col="grey", border="white" ) > lines(density(cl), lwd=3) Die Berechnung von Quantilen für Cl erfolgt mit: > quantile(cl, c( 0.025,0.25,0.5,0.75,0.975 ) ) 2.5% 25% 50% 75% 97.5% 101.9555 102.5871 102.8421 103.1023 103.7456 Darstellung der Abtastung und der Dichtefunktion der Streuung σ des Datenmodells wie in Abb. 10.12: > sigma <- extract(mcmckette)$sigma > split.screen(c(1,2)) > screen(1) > plot(sigma, type="l") > screen(2) > hist( sigma, prob = T, col="grey", border="white" ) > lines(density(sigma), lwd=3) Berechnung der plausibelsten Werte von Cl und der Streuung σ: > op <- optimizing(mcmckette@stanmodel, data=daten) > op $par Cl sigma 102.8428605 0.8334537 $value [1] -2.54257 Der plausibelste Wert für den Chloridgehalt Cl ist Modus Cl 0 = 102,8. Der wahrscheinlichste Wert für die Streuung ist σ 0 = 0,83. Nun zum Prognosemodell für den nächsten Messwert: Die Monte-Carlo-Simulation für weitere Messwerte erfolgt mit dem Normalverteilungs-Modell: > N <- length(cl) > neumess <- rnorm(n, Cl, sigma) 13
Darstellung des Prognosemodells wie in Abb. 10.14 durch: > hist( neumess, prob = T, ylim = c(0,0.4), col="grey", border="white" ) > lines( density(neumess), lwd=3, col="red" ) Mit dem Prognosemodell für den nächsten Messwert kann man überprüfen, ob das Datenmodell (die Normalverteilung) sinnvoll ist. Dazu macht man den QQ-Plot (Abb. 10.15): > n <- length(konz); > quantilemodell <- quantile( neumess, ppoints(n) ) > qqplot(quantilemodell, konz) > abline(a = 0, b = 1) > grid() (Student) t-verteilung mit R Die t-verteilung mit Modus µ, Skalierung a > 0 und Freiheitsgrad n > 0 hat die Dichtefunkton ( ) (n+1)/2 1 pdf(x = x µ, a, n) 1 + (1/n) (x µ) 2 /a 2 Mit R: Dichtefunktion: dt( (x-mu)/a, df = n ) * 1/a Quantil q: qt( q, df = n ) * a + mu Wahrscheinlichkeit P(X x): pt( (x-mu)/a, df = n ) Wahrsch. P(x 1 X x 2 ): pt((x2-mu)/a,df = n) - pt((x1-mu)/a,df = n) n Zufallszahlen: rt(1, df = n) * a + mu Ist µ = 0 und a = 1, so hat man die Standard - t-verteilung mit Modus null und Skalierung eins. Kapitel 11 Beispiel 11.6 (Unwetterschäden) Die Daten sind im tab-getrennten File mit Namen unwetter.txt gespeichert. Die Messwerte liegen in einer Spalte mit mit Variablenname schaden. Einlesen der Daten: > daten <- read.table("unwetter.txt", header=t) Streudiagramm (Abb.11.5) der Daten: > plot(schaden); lines(schaden) Der Grösse nach darstellen (Abb. 11.6): > stripchart(schaden, method="stack") 14
Beispiel 11.6 (Unwetterschäden) Die Daten sind im tab-getrennten File mit Namen unwetter.txt gespeichert. Die Messwerte liegen in einer Spalte mit mit Variablenname schaden. Einlesen der Daten: > daten <- read.table("unwetter.txt", header=t) Stamm-Blatt-Diagramm (Abb.11.9) der Daten: > stem(schaden, scale=2) Mit dem Attribut scale kann indirekt die Stammbreite gewählt werden. Beispiel 11.10 (Nicht keimende Blumenzwiebeln) Die Daten sin im tab-getrennten File mit Namen blumenzwiebeln.txt gespeichert. Die Messwerte liegen in einer Spalte mit mit Variablenname schaden. File einlesen: > daten <- read.table("blumenzwiebeln.txt", header = T) Darstellen der Häufigkeitsverteilung mit einem Stabdiagramm (Abb. 11.15) geht wie folgt: > plot(table(anzahl),lwd=20) Die Zahl lwd=20 gibt die Stabdicke an. Beispiel 11.15 (Bleigehalte in Weinen) Die Daten sind im tab-getrennten File mit Namen wein.txt gespeichert. Die Messwerte liegen in einer Spalte mit mit Variablenname Bleigehalt. File einlesen: > daten <- read.table("wein.txt", header = T) Darstellen der Häufigkeitsverteilung mit einem Histogramm (Abb. 11.23) geht wie folgt: > hist(bleigehalt,col="gray", border="white", nclass=20) Die Zahl nclass=20 ist optional ung gibt die Anzahl Klassen an. In der Regel sollte man diesen Parameter nicht selber bestimmen. Beispiel 11.24 (Chloridgehalt) Die Daten zur Methode A (bzw. Methode B)sind im tab-getrennten File mit Namen chlorida.txt (bzw. chloridb.txt) gespeichert. Die Messwerte liegen in einer Spalte mit mit Variablenname gehalta (bzw. gehaltb). Die Daten einlesen und Boxplot (Abb. 11.36) darstellen: 15
> datena <- read.table("chlorida.txt", header=t) > attach(datena) > datenb <- read.table("chloridb.txt", header=t) > attach(datenb) > boxplot( gehalta, gehaltb, names=c("methodea","methodeb") ) Zeichnen der Wahrscheinlichkeitsintervalle zum Niveau 0,95 für den Chloridgehalt (mit Modellannahme Normalverteilung der Messwerte): > a <- t.test(gehalta,conf.level=0.95)$conf > segments(1,a[1],1,a[2],lwd=15,col="gray") > b <- t.test(gehaltb,conf.level=0.95)$conf > segments(2,b[1],2,b[2],lwd=15,col="gray") Kapitel 12 Beispiel 12.1 (Unwetterschäden) Die Daten sind im tab-getrennten File mit Namen unwetter.txt gespeichert. Die Messwerte liegen in einer Spalte mit mit Variablenname schaden. Einlesen der Daten: > daten <- read.table("unwetter.txt", header=t) Balken-Diagramm (Abb.12.1) der Daten: > plot(1977:1997,schaden,type="h",lwd=10) Beispiel 12.5 (Akkommodationsbreite) Die Daten sind im tab-getrennten File mit Namen MonoSehen.txt gespeichert. Die Messwerte liegen in zwei Spalten mit mit Variablenname Alter und AkkoMono. Einlesen der Daten: > daten <- read.table("monosehen.txt", header=t) Das Streudiagramm gemäss Abb.12.8 ist: > plot(alter, AkkoMono) > grid() Falls Punkte aufeinanderliegenden, können sie wie folgt leicht versetzt werden: > plot(jitter(alter), jitter(akkomono)) 16
Beispiel 12.9 (Akkommodationsbreite) Die Daten sind im tab-getrennten File mit Namen MonoSehen.txt gespeichert. Die Messwerte liegen in zwei Spalten mit mit Variablenname Alter und AkkoMono. Einlesen der Daten: > daten <- read.table("monosehen.txt", header=t) Ein Kernel-Regresionsmodel gemäss Abb.12.15 kann wie folgt berechnet und visualisiert werden: > model <- ksmooth(alter, AkkoMono, kernel="box", bandwidth=10) > plot(alter, AkkoMono) > lines(model, lwd=3) > grid() Dabei ist bandwidth zweimal die Bandbreite (hier als h = 5). Wählt man den Parameter kernel="normal", so werden Messpunkte am Rand stark weniger gewichtet als diejenigen in der Mitte. Es ensteht ein glattes Regressionmodell. Kapitel 13 Beispiel 13.1 (Akkommodationsbreite) Die Daten sind im tab-getrennten File mit Namen MonoSehen.txt gespeichert. Die Messwerte liegen in zwei Spalten mit mit Variablenname Alter und AkkoMono. Einlesen der Daten: > daten <- read.table("monosehen.txt", header=t) Bestimmung der Parameter des Regressionsmodells mit R-Stan. Zuerst wird in einem R-File das Modell eingegeben und eingelesen: codeakko <- " data{ int n; real Alter[n]; real AkkoMono[n]; parameters { real a; real<upper=0> b; real<lower=0> sigma; // Achsenabschnitt Reg.Gerade // Steigung Reg.Gerade // Streuung model { 17
// Prior a ~ uniform(-100,100); b ~ uniform(-100,0); sigma ~ gamma(1e-10,1e-10); // Skalenparameter " // Datenmodell for (i in 1:n) { AkkoMono[i] ~ normal( a + b*alter[i], sigma); Die Daten müssen nun eingelesen und strukturiert werden, damit Stan die MCMC- Simulation ausführen kann: > daten <- list( Alter = Alter, AkkoMono = AkkoMono, n = length(alter) ) Nun erfolgt die MCMC-Simulation (hier Kette mit einer Gesamtlänge von 50 000): > library(rstan) > mcmckette <- stan(model_code=codeakko, data=daten, iter=25000) > print(mcmckette) Inference for Stan model: 7a0153903a2b0649ffd7111dc592b121. 4 chains, each with iter=25000; warmup=12500; thin=1; post-warmup draws per chain=12500, total post-warmup draws=50000. mean se_mean sd 2.5% 25% 50% 75% 97.5% n_eff Rhat a 14.16 0.01 1.13 11.94 13.41 14.16 14.88 16.43 11890 1 b -0.28 0.00 0.03-0.34-0.30-0.28-0.26-0.21 11987 1 sigma 1.32 0.00 0.24 0.95 1.15 1.29 1.46 1.89 12782 1 lp -15.78 0.01 1.34-19.28-16.39-15.42-14.80-14.25 10408 1 Samples were drawn using NUTS(diag_e) at Sun Feb 7 16:12:03 2016. For each parameter, n_eff is a crude measure of effective sample size, and Rhat is the potential scale reduction factor on split chains (at convergence, Rhat=1). Man sieht, dass die Posterior für die Parameter a, b und σ wahrscheinlich vollständig abgetast sind (R_hat= 1). Mit einer Wahrscheinlichkeit von 0,95 ist 11,9 a 16,4. Darstellung der Abtastung und der Dichtefunktion wie in Abb. 13.2 für die Plausibilität zum Parameter a: > a <- extract(mcmckette)$a > split.screen(c(1,2)) > screen(1) > plot(a, type="l") > screen(2) 18
> hist(a, prob = T, col="grey", border="white") > lines(density(a), lwd=3) Darstellung der Abtastung und der Dichtefunktion des Parameters b wie in Abb. 13.3: > b <- extract(mcmckette)$b > split.screen(c(1,2)) > screen(1) > plot(b, type="l") > screen(2) > hist(b, prob = T, col="grey", border="white") > lines(density(b), lwd=3) Der plausibelste Wert a 0 für den Parameter a ist a 0 = 14,16, für b ist der plausibelste Wert b 0 = 0,28. Plotten der Daten und des Regressionsmodells wie in Abb. 13.7: > plot(alter, AkkoMono) > abline(a=14.16, b=-0.28, lwd=3) > grid() Nun zum Prognosemodell für den nächsten Messwert, z.b. für das Alter von 35 Jahren: > a <- extract(mcmckette)$a > b <- extract(mcmckette)$b > sigma <- extract(mcmckette)$sigma > N <- length(a) > AkkoNeu35 <- rnorm(n,mean=a+b*35,sd=sigma) Darstellung des Prognosemodells wie in Abb. 13.6 durch: > hist( AkkoNeu35, prob = T, col="grey", border="white") > lines( density(akkoneu35), lwd=3, col ="red" ) Um die finale Darstellung des Prognosemodells und des Regressionsmodells wie in Abb. 13.7 zu erhalten, geht man wie folgt vor. Zuerst müssen wir uns entscheiden, für welche Alter wir die Bänder zeichnen wollen und anschliessend das Prognosemodell berechnen: > AlterNeu <- seq(20,50,by=2.5) > NBand <- length(alterneu) > AkkoNeu <- matrix(nrow=nband, ncol =N) > for (i in 1:NBand) AkkoNeu[i,] <- rnorm(n,mean=a+b*alterneu[i],sd=sigma) Zeichnen der Daten und des Regressionsmodells mit den plausibelsten Werten für die Parameter und der Prognosebänder: > plot(alter, AkkoMono) > abline(a=14.16, b=-0.28, lwd=3) 19
> grid() > q975 <- apply(akkoneu, 1, quantile, 0.975) > q025 <- apply(akkoneu, 1, quantile, 0.025) > segments(alterneu, q025, AlterNeu, q975, lwd=5, col="green") > q75 <- apply(akkoneu, 1, quantile, 0.75) > q25 <- apply(akkoneu, 1, quantile, 0.25) > segments(alterneu, q25, AlterNeu, q75, lwd=5, col="blue") > points(alter, AkkoMono) Beispiel 13.2 (Ausspülen von Milch) Die Daten sind im tab-getrennten File mit Namen milchdaten.txt gespeichert. Die Messwerte liegen in zwei Spalten mit mit Variablenname v und M. Einlesen der Daten: > daten <- read.table("milchdaten.txt", header=t) Bestimmung der Parameter des Regressionsmodells mit R-Stan. Zuerst wird in einem R-File das Modell eingegeben und eingelesen: codemilch <- " data { int n; real v[n]; real M[n]; parameters { real<lower=0,upper=10> A; real<lower=0,upper=10> c; real<lower=0> sigma; model { // Prior A ~ uniform(0,10); c ~ uniform(0,10); sigma ~ gamma(1e-10,1e-10); " // Datenmodell for (i in 1:n) { M[i] ~ normal( A*( 1 - exp(- c*v[i]) ), sigma); 20
Die Daten müssen nun eingelesen und strukturiert werden, damit Stan die MCMC- Simulation ausführen kann: > daten <- list( v = v, M = M, n = length(v) ) Nun erfolgt die MCMC-Simulation wie beim obigen Beispiel. Analog berechnen sich Prognosebänder für das Modell. Beispiel 13.3 (Akkommodationsbreite) Die Daten sind im tab-getrennten File mit Namen MonoSehen.txt gespeichert. Die Messwerte liegen in zwei Spalten mit mit Variablenname Alter und AkkoMono. Einlesen der Daten: > daten <- read.table("monosehen.txt", header=t) Bestimmung der Parameter des linearen Regressionsmodells (also linear in den Parametern) mit der Methode der kleinsten Quadrate: > model <- lm( AkkoMono ~ Alter, data = daten) > model Call: lm(formula = AkkoMono ~ Alter, data = daten) Coefficients: (Intercept) Alter 14.1492-0.2762 Berechnung von Wahrscheinlichkeitsintervallen für die Parameter des Regressionsmodells zum Niveau 0,95: > confint(model,level=0.95) 2.5 % 97.5 % (Intercept) 11.9311582 16.3672936 Alter -0.3389932-0.2133642 Berechnung eines Prognoseintervalls zum Niveau 0,95 für die beiden Alter 30 Jahre und 40 Jahre: > AlterNeu = data.frame(alter=c(30,40)) > predict(model,alterneu,interval="prediction",level=0.95) fit lwr upr 1 5.863863 3.1222427 8.605484 2 3.102076 0.3453476 5.858804 Mehr dazu findet man unter dem Befehl?lm. Insbesondere sieht man aus dieser Hilfe, wie man kompliziertere lineare Regressionsmodell (Stichwort formula ) eingeben kann. 21
Beispiel 13.5 (Akkommodationsbreite) Die Daten sind im tab-getrennten File mit Namen MonoSehen.txt gespeichert. Die Messwerte liegen in zwei Spalten mit mit Variablenname Alter und AkkoMono. Einlesen der Daten: > daten <- read.table("monosehen.txt", header=t) Nachdem die plausibelsten Werte a 0 und b 0 des Regressionsmodells berechnet sind, lassen sich die Residuen und die Abb. 13.17 wie folgt bestimmen: > residuen <- AkkoMono - (14.15-0.28*Alter) > plot(residuen); lines(residuen) > acf(residuen) 22