7 Aufgaben

Programmieren mit Statistischer Software
Eugster
7. Block
SS2012
7 Aufgaben
Aufgabe 1:
Beim Zahlenraten erzeugt der Computer eine Zufallszahl in einem bestimmten Bereich (z.B. [0, 20])
und Sie müssen diese Zahl erraten. Bei jedem Versuch bekommen Sie die Meldung, ob die gesuchte Zahl
größer oder kleiner als die eingegebene Zahl ist; oder ob Sie die Zahl gefunden haben. Ziel bei diesem
Spiel ist es, möglichst wenige Versuche zu brauchen.
Programmieren Sie die Funktion
> zahlenraten <- function(min = 0, max = 20) {
+
...
+ }
welches dieses Spiel umsetzt. Die beiden Argumente min und max definieren den Bereich in dem die
Zufallszahl vom Computer gezogen wird.
Das Einlesen einer Zahl funktioniert mit:
> versuch <- as.numeric(readline("Neuer Versuch: "))
Lösung:
Bei diesem Spiel ist die Anzahl der Schleifendurchläufe nicht bekannt, d.h. eine while-Schleife wird
verwendet. In jedem Schleifendurchlauf wird der Spieler nach einer Zahl gefragt, welche dann entsprechend
ausgewertet wird. Hat der Spieler die Zahl erraten, wird eine logische Variable zahlErraten auf TRUE
gesetzt, was den Abbruch der Schleife bedeutet.
> zahlenraten <- function(min = 0, max = 20) {
+
stopifnot(min < max)
+
+
zahl <- sample(seq(min, max), size=1)
+
zahlErraten <- FALSE
+
i <- 0
+
+
cat("Erraten Sie eine Zahl zwischen", min, "und", max, "...\n")
+
while (!zahlErraten) {
+
i <- i + 1
+
+
versuch <- as.numeric(readline(paste(i, ". Versuch: ", sep="")))
+
+
if (versuch == zahl ) {
+
zahlErraten <- TRUE
1
+
}
+
else {
+
if ( versuch < zahl )
+
cat("Zahl ist größer!\n")
+
else
+
cat("Zahl ist kleiner!\n")
+
}
+
}
+
+
cat("Zahl erraten! Sie haben", i, "Versuche benötigt!\n")
+ }
Eine mögliche Spielfolge ist:
> zahlenraten()
Erraten Sie eine Zahl zwischen 0 und 20 ...
1. Versuch: 10
Zahl ist größer!
2. Versuch: 15
Zahl ist größer!
3. Versuch: 17
Zahl ist größer!
4. Versuch: 18
Zahl ist größer!
5. Versuch: 19
Zahl erraten! Sie haben 5 Versuche benötigt!
Anmerkung: Die optimale Strategie für dieses Spiel ist die binäre Suche.
Aufgabe 2:
Die Kreiszahl π kann mit Hilfe eines Monte-Carlo-Algorithmus näherungsweise bestimmt werden: für
die Berechnung lässt man zufällige Punkte auf ein Quadrat regnen und berechnet, ob sie innerhalb oder
außerhalb eines eingeschriebenen Kreises liegen. Der Anteil der innen liegenden Punkte ist gleich π4 . Mit
steigender Anzahl der Punkten steigt auch die Genauigkeit.
2
Schreiben Sie eine Funktion, welche für eine gegebene Punkteanzahl n π berechnet.
(Hinweis: Für xy-Paare, die innerhalb des Viertelkreises liegen, gilt x2 + y 2 ≤ 1.)
Lösung:
Funktion zur Bestimmung mit Hilfe des Monte-Carlo-Algorithmus:
> mcpi <- function(n) {
+
x <- runif(n)
+
y <- runif(n)
+
+
## xy-Paare die innerhalb des Viertelkreises liegen:
+
inside <- ((x^2 + y^2) <= 1)
+
+
## Pi berechnen:
+
pi <- 4 * sum(inside) / n
+
+
return(pi)
+ }
Aufruf für n = 100:
> set.seed(1234)
> mcpi(100)
[1] 3.32
Simulation um zu sehen, wie sich die Schätzung dem echten π annähert:
> set.seed(1234)
> s <- seq(0, 5000000, by = 10000)[-1]
> mypi <- sapply(s, mcpi)
Visualisierung:
3
>
>
>
>
op <- par(mar = c(4, 4, 0, 0), ps = 8, las = 2)
plot(s, mypi, type = "l", lwd = 2)
abline(h = pi, col = 2, lwd = 2)
par(op)
3.15
mypi
3.14
3.13
3.12
5e+06
4e+06
3e+06
2e+06
1e+06
0e+00
3.11
s
Aufgabe 3:
Bei einer gegebenen Menge von Datenpunkten x1 , x2 , . . . , xn ist der gleitende Mittelwert (moving
average) x̄i der Mittelwert von w (w eine ungerade Zahl größer 0) Datenpunkten, genauer w−1
2 vor xi
w−1
und w−1
nach
x
liegend.
Daraus
folgt,
dass
für
die
ersten
und
letzen
Datenpunkte
kein
gleitender
i
2
2
Mittelwert definiert ist.
Schreiben Sie eine Funktion
> movave <- function(x, w) { ... }
welche einen Vektor x von Datenpunkten und eine Fenstergröße w (ganze ungerade Zahl größer 0) als
Argumente übernimmt. Rückgabewert soll der Vektor der gleitenden Mittelwerte sein, der die selbe Länge
wie x besitzt mit NA bei den ersten und letzten w−1
2 Elementen.
Laden Sie dann den Datensatz LakeHuron,
> data("LakeHuron", package = "datasets")
> x <- as.vector(LakeHuron)
berechnen Sie den gleitenden Mittelwert für w = 3, 5, 21 und zeichnen Sie diese in eine Grafik zusammen
mit den Originaldaten ein.
Lösung:
4
> movave <- function(x, w) {
+
n <- length(x)
+
w2 <- (w - 1) / 2
+
ma <- rep(NA, n)
+
+
for ( i in seq(w2+1, n-w2) )
+
ma[i] <- mean(x[(i-w2):(i+w2)])
+
+
ma
+ }
Lake Huron:
>
>
>
>
>
data("LakeHuron", package = "datasets")
x <- as.vector(LakeHuron)
ma3 <- movave(x, 3)
ma5 <- movave(x, 5)
ma21 <- movave(x, 21)
>
>
>
>
>
>
op <- par(mar = c(4, 4, 0, 0), ps = 8, las = 2)
plot(x, type = "l")
lines(ma3, col = 2)
lines(ma5, col = 3)
lines(ma21, col = 4)
par(op)
582
581
x
580
579
578
577
100
80
60
40
20
0
576
Index
Aufgabe 4:
In der Einheit “Funktionen” haben Sie ein Funktion which maxdev() entwickelt, welche den Index der
Beobachtung mit der maximalen Abweichung vom Median aller Beobachtungen zurückliefert.
Schreiben Sie eine Funktion
5
> which_maxdevs <- function(...) {
+
...
+ }
welche diese Funktion für alle Spalten einer Matrix oder eines data.frames ausführt.
Installieren Sie das Paket benchmark und laden Sie den Datensatz uci621raw. Schauen Sie sich die
Struktur des Objektes an und extahieren Sie die Daten für die das erste Element der dritten und das
erste Element der vierten Dimension. Wenden Sie die programmierte Funktion auf diese Teilmatrix an.
Lösung:
> which_maxdev <- function(x, na.rm = TRUE) {
+
stopifnot(is.numeric(x) & is.vector(x))
+
stopifnot(is.logical(na.rm))
+
+
mdn <- median(x, na.rm = na.rm)
+
devs <- abs(x - mdn)
+
which.max(devs)
+ }
> which_maxdevs <- function(m, na.rm = TRUE) {
+
stopifnot(is.matrix(m) | is.data.frame(m))
+
apply(m, 2, which_maxdev)
+ }
> data("uci621raw", package = "benchmark")
> str(uci621raw)
num [1:250, 1:6, 1:2, 1:21] NA 0.0618 0.0445 0.0413 0.0685 ...
- attr(*, "dimnames")=List of 4
..$ samp: NULL
..$ alg : chr [1:6] "lda" "rf" "knn" "rpart" ...
..$ perf: chr [1:2] "Misclassification" "Time"
..$ ds : chr [1:21] "BreastCancer" "Cards" "chess" "Circle" ...
>
+ dat <- uci621raw[, , 1, 1]
>
> which_maxdevs(dat)
lda
40
rf
151
knn rpart
185
181
svm
216
nnet
106
6