Inhaltsverzeichnis Lektion 1: Erste Schritte 1 1.1 Starten und Beenden von R . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1 1.2 Aufruf der Online-Hilfstexte in R . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3 1.3 Arithmetische Operationen und numerische Funktionen . . . . . . . . . . . . . . . . . 4 1.4 Vektoren . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4 1.5 Einige spezielle Funktionen für Vektoren . . . . . . . . . . . . . . . . . . . . . . . . . . 6 1.6 Plotten von Funktionen . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6 1.7 Anwenderfunktionen . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10 1.8 Erzeugte R-Objekte . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 12 1.9 Übungen . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13 Lektion 2: Grundlagen 14 2.1 Nicht definierte und fehlende Werte . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 14 2.2 Logische Größen und Vergleichsoperatoren in R . . . . . . . . . . . . . . . . . . . . . . 14 2.3 Bedingte Anweisungen . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 17 2.4 Datentypen in R . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 17 2.5 Indizierung von Vektoren . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 19 2.5.1 Numerische Indizes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 19 2.5.2 Indizierung mit logischen Vektoren . . . . . . . . . . . . . . . . . . . . . . . . . 20 2.5.3 Indizierung mit Namen . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 21 2.6 Listen . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 22 2.7 Übungen . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 23 Lektion 3: Matrizenrechnung 24 3.1 Matrizen . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 24 3.2 Matrizen und arithmetische Operationen . . . . . . . . . . . . . . . . . . . . . . . . . . 26 3.3 Das Matrizenprodukt . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 28 3.4 Block- und Diagonalmatrizen . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 29 3.5 Die Funktion apply() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 29 3.6 Lineare Gleichungssysteme . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 30 3.7 Eigenwerte und -Vektoren . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 31 i 3.8 Übungen . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Lektion 4: Mehrdimensionale Plots 33 34 4.1 Arrays . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 34 4.2 Die Funktion outer() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 35 4.3 3-D-Plots . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 36 4.4 Contour-Plots . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 38 4.5 Image-Plots . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 38 4.6 Die zweidimensionale Normalverteilung . . . . . . . . . . . . . . . . . . . . . . . . . . 38 4.7 Übungen . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 41 Lektion 5: Stetige und diskrete Verteilungen 42 5.1 Stetige Verteilungen in R . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 42 5.2 Diskrete Verteilungen in R . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 44 5.3 Übungen . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 48 Lektion 6: Externe Quellen und visuelle Datenanalyse 49 6.1 Der Datensatz lottery . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 49 6.2 Interaktives Identifizieren und Festlegen von Punkten . . . . . . . . . . . . . . . . . . 50 6.3 Balkendiagramme - Teil I . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 52 6.4 Mehrere Plots in einem Graphikfenster . . . . . . . . . . . . . . . . . . . . . . . . . . . 52 6.5 Balkendiagramme - Teil II . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 54 6.5.1 Die Funktion cut() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 54 6.5.2 Die Funktion tabulate() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 55 6.5.3 Die Funktion barplot() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 56 Ordnungstatistiken, empirische Verteilungsfunktion und Quantile . . . . . . . . . . . . 57 6.6.1 Sortieren von Daten . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 57 6.6.2 Empirische Verteilungsfunktion und Quantile . . . . . . . . . . . . . . . . . . . 57 6.7 Q-Q-Plots . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 59 6.8 Anhang: Ein- und Ausgabe von Daten . . . . . . . . . . . . . . . . . . . . . . . . . . . 61 6.9 Übungen . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 63 6.6 Lektion 7: Simulation von Zufallszahlen 7.1 64 Simulation von Standardzufallszahlen . . . . . . . . . . . . . . . . . . . . . . . . . . . 64 7.1.1 For- und while- Schleifen . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 65 7.1.2 Optimierungskriterien . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 66 7.2 Q-Q-Plots . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 67 7.3 Simulation allgemeiner Zufallsgrößen . . . . . . . . . . . . . . . . . . . . . . . . . . . . 69 7.3.1 Simulation exponentialverteilter Zufallsgrößen . . . . . . . . . . . . . . . . . . . 69 7.3.2 Simulation von Bernoulli-Variablen . . . . . . . . . . . . . . . . . . . . . . . . . 70 7.3.3 Simulation eines fairen Würfels . . . . . . . . . . . . . . . . . . . . . . . . . . . 70 ii c Math. Stochastik, Uni Freiburg ° 7.4 7.3.4 Simulation binomialverteilter Zufallsgrößen . . . . . . . . . . . . . . . . . . . . 71 7.3.5 Simulation poissonverteilter Zufallsgrößen . . . . . . . . . . . . . . . . . . . . . 72 7.3.6 Simulation normalverteilter Zufallsgrößen . . . . . . . . . . . . . . . . . . . . . 72 Übungen . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 74 Lektion 8: Lineare Modelle 8.1 76 Theoretische Grundlagen . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 76 Lineare Regressionsanalyse . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 76 8.2 Lineare Modelle . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 78 8.3 Lineare Modelle in R . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 80 8.3.1 Die Funktion lm() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 80 8.3.2 Der Parameter formula . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 81 8.3.3 Interna eines lm()-Aufrufs . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 82 Übungen . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 85 8.1.1 8.4 Lektion 9: Lineare Modelle 2 9.1 9.2 9.3 9.4 86 Experimente an Datensätzen . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 86 9.1.1 Der Datensatz trees . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 86 9.1.2 Transformationen der Zielgröße . . . . . . . . . . . . . . . . . . . . . . . . . . . 87 9.1.3 Der Datensatz trees - Eine mögliche Transformation . . . . . . . . . . . . . . 88 Modellwahl am Datensatz trees . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 89 9.2.1 Der Datensatz trees - linearer Ansatz . . . . . . . . . . . . . . . . . . . . . . . 89 9.2.2 Fehleranalyse bei statistischen Modellen . . . . . . . . . . . . . . . . . . . . . . 89 9.2.3 Der Datensatz trees - quadratischer Ansatz . . . . . . . . . . . . . . . . . . . 91 Modellvalidierung am Datensatz trees . . . . . . . . . . . . . . . . . . . . . . . . . . . 91 9.3.1 Einflussreiche Beobachtungen . . . . . . . . . . . . . . . . . . . . . . . . . . . . 91 9.3.2 Diagnostik für das Standardmodell . . . . . . . . . . . . . . . . . . . . . . . . . 92 Übungen . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 93 Lektion 10: Testen 95 10.1 Der exakte Binomial-Test . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10.2 Der χ2 -Anpassungstest 95 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 99 10.2.1 Grundlagen . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 99 10.2.2 Ein Beispiel aus der Zuverlässigkeitstheorie . . . . . . . . . . . . . . . . . . . . 101 10.3 Übungen . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 103 Lektion 11: t-Tests 105 11.1 Der einfache t-Test . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 105 11.2 Der doppelte t-Test – Vergleich der Mittelwerte . . . . . . . . . . . . . . . . . . . . . . 110 11.3 Übungen . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 114 iii c Math. Stochastik, Uni Freiburg ° Lektion 12: Konfidenzintervalle 116 12.1 Intervallschätzer bei normalverteilten Zufallsgrößen . . . . . . . . . . . . . . . . . . . . 116 12.1.1 Konfidenzintervall für µ unter Normalverteilungsannahme . . . . . . . . . . . . 116 12.1.2 Konfidenzintervall für σ 2 unter Normalverteilungsannahme . . . . . . . . . . . 117 12.1.3 Ein Backtest mit simulierten Daten . . . . . . . . . . . . . . . . . . . . . . . . 118 12.2 Konfidenzintervalle bei binomialverteilten Daten . . . . . . . . . . . . . . . . . . . . . 119 12.3 Konfidenzintervalle bei poissonverteilten Daten . . . . . . . . . . . . . . . . . . . . . . 120 12.4 Übungen . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 122 iv c Math. Stochastik, Uni Freiburg ° Lektion 1: Erste Schritte 1.1 Starten und Beenden von R Wie genau R gestartet werden kann, hängt maßgeblich von dem zugrundeliegenden Betriebssystem ab. In der nachfolgenden Liste sind ein paar einfache Möglichkeiten für alle von R unterstützten Plattformen zusammengefasst: Linux: Wer mit R innerhalb des XEmacs arbeiten möchte und dazu bereits das Zusatzpaket ESS gemäß der Anleitung auf der Praktikums-Webseite installiert hat, muss zunächst den XEmacs aufrufen (entweder über eine praktischerweise ebenfalls zuvor eingerichtete Verknüpfung auf dem Desktop oder durch Eingabe von xemacs in einem Befehlsfenster). Nach Erscheinen des XEmacsFensters ist die Tastenkombination Esc x R zu verwenden, d.h. erst die [Esc]-Taste und dann die [x]-Taste zu drücken und anschließend R einzugeben (großes R, also gleichzeitig [Shift]- und [r]-Taste drücken!). Anschließend sind die Meldungen in der untersten Zeile des XEmacs-Fensters durch zweimaliges (!) Drücken der [Enter]-Taste zu bestätigen. Wer R lieber ohne viel Schnickschnack innerhalb eines Befehlsfensters verwenden möchte, öffne ein solches, wechsle mit cd /Pfad/zum/R-Arbeitsverzeichnis in sein R-Arbeitsverzeichnis (sofern zuvor eingerichtet und vorhanden) und starte dann R mit R Mac OS X: Wenn man R nach der Installation praktischerweise gleich im Dock verankert hat wie auf der Praktikums-Webseite beschrieben, genügt zum Start der grafischen Benutzeroberfläche von R ein einfacher Klick auf das zugehörige Programmsymbol im Dock. Falls dies dort noch fehlt, kann man alternativ auch mit dem Finder in den Ordner Programme wechseln und dann dort R mit einem Doppelklick auf das R-Programmsymbol starten. Windows: Bei der Installation von R werden in der Regel per Default zwei Verknüpfungen (32- und 64-Bit) auf dem Desktop angelegt. Die 64-Bit Verknüpfung kann bedenkenlos gelöscht werden. Durch Doppelklick auf das R-Icon wird die grafische Benutzeroberfläche von R (RGui) gestartet. 1 Nach erfolgreichem Start von R sollte sich das Programm auf allen Systemen mit den folgenden Zeilen vorstellen (sofern Deutsch als Standardsprache voreingestellt ist): R version 2.13.0 (2011-04-13) Copyright (C) 2011 The R Foundation for Statistical Computing ISBN 3-900051-07-0 Platform: i386-pc-mingw32/i386 (32-bit) R ist freie Software und kommt OHNE JEGLICHE GARANTIE. Sie sind eingeladen, es unter bestimmten Bedingungen weiter zu verbreiten. Tippen Sie ’license()’ or ’licence()’ für Details dazu. R ist ein Gemeinschaftsprojekt mit vielen Beitragenden. Tippen Sie ’contributors()’ für mehr Information und ’citation()’, um zu erfahren, wie R oder R packages in Publikationen zitiert werden können. Tippen Sie ’demo()’ für einige Demos, ’help()’ für on-line Hilfe, oder ’help.start()’ für eine HTML Browserschnittstelle zur Hilfe. Tippen Sie ’q()’, um R zu verlassen. Bemerkung 1.1. Im aktuellen R-Praktikum werden wir ausschließlich die R Version 2.13.0 (Stand: 2011-04-13) verwenden. Falls Sie vorher bereits mit R gearbeitet und die dabei erhaltenen Daten abgespeichert haben, stehen diese bei nachfolgenden Starts von R direkt zur Verfügung, was angezeigt wird durch [Vorher gesicherter Workspace wiederhergestellt] > Damit hat die interaktive R-Arbeitssitzung begonnen. Das Programm wartet nun mit der Eingabeaufforderung > (R-Prompt) auf weitere Befehle. Bemerkung 1.2. R unterscheidet zwischen Groß- und Kleinbuchstaben! Mit dem Befehl q() (quit) können Sie das Programm verlassen. Beachten Sie dabei, dass q() eine R-Funktion ist und deshalb dem Aufruf die Klammern ( und ) beigefügt werden müssen. Unter Linux und Mac OS X führt die Eingabe zu folgendem Ergebnis: > q() Save workspace image? [y/n/c]: Hierbei werden Sie gefragt, ob die während der Sitzung erzeugten Objekte, Funktionen o.ä. gespeichert werden sollen. Dies geschieht bei Eingabe von y (yes). Mit n (no) wird R ohne Datensicherung beendet, 2 c Math. Stochastik, Uni Freiburg ° d.h. alles während der letzten Sitzung Erzeugte oder Geänderte geht verloren! Mit c (cancel) kann man den q()-Befehl aufheben und mit der Arbeit in R fortfahren. Bei der grafischen Benutzeroberfläche von Windows erscheint nach Eingabe des Befehls ein kleines Auswahlfenster mit der Frage Workspace speichern? und den analogen Optionen Ja, Nein und Abbrechen. Da wir bisher noch nichts zu sichern haben und die Arbeit mit R fortsetzen wollen, beantworten wir die obige Frage mit c bzw. klicken auf den Button Abbrechen. Technische Anmerkung: Während der Arbeit mit R werden alle von Ihnen erzeugten Objekte im Hauptspeicher des Rechners abgelegt, eine Sicherung auf der Festplatte erfolgt erst bei Beendigung des Programms, wenn die obige Anfrage mit y bzw. Ja beantwortet wird. In diesem Fall werden die Daten in komprimierter Form in einem File namens .RData in Ihrem R-Arbeitsverzeichnis gespeichert, das bei jedem Start von R eingelesen wird. Falls Sie vorsichtshalber bereits während einer Sitzung das bisher Erreichte derart sichern wollen, verwenden Sie dazu den Befehl > save.image() 1.2 Aufruf der Online-Hilfstexte in R Wie aufmerksame Leser vielleicht schon dem R-Begrüßungstext entnommen haben, kann man durch > help.start() zur html-basierten Online-Hilfe von R gelangen. Der Befehl generiert die Startseite der Hilfe mit einigen Links und reicht diese an den in den jeweiligen Standardwebbrowser des Systems weiter (wurde dieser bereits zuvor geöffnet, erscheint die Hilfsseite als weiteres Tab im Browserfenster). Die sicher oftmals hilfreiche Suchfunktion erreicht man über den Link Search Engine & Keywords. Bemerkung 1.3. Für die html-Hilfe selbst wird keine Internet-Verbindung benötigt, da sämtliche Hilfsseiten bereits in R enthalten sind und nach der Installation lokal auf dem Rechner vorliegen. Anstatt über diesen Umweg zu den html-Hilfsseiten einzelner R-Funktionen zu gelangen, erhält man unter Windows die genaue Beschreibung einer R-Funktion auch direkt durch Voranstellen eines ?. So bewirkt die Eingabe des Befehls > ?save.image die Weiterleitung der Anfrage an den Webbrowser, der daraufhin die entsprechende Hilfsseite in einem eigenen Tab anzeigt. Alternativ kann hierfür auch die help()-Funktion benutzt werden: > help(save.image) Bemerkung 1.4. Per Default wird unter Linux durch den Befehl help() die Texthilfe aufgerufen. Da die Begriffe in der Texthilfe untereinander nicht verlinkt sind, kann man durch Angabe des 3 c Math. Stochastik, Uni Freiburg ° zusätzlichen Arguments help type="html" im help()-Befehl zur html-Hilfe gelangen. Außerdem verhindert man damit die Zweiteilung des XEmacs, was durch die Eingabe des help()-Befehls ohne das zusätzliche Argument geschehen würde. Man vergleiche beispielsweise die beiden Varianten: > help(save.image) > help(save.image,help_type="html") Damit die Linux-Nutzer das zusätzliche Argument in help() für die html-Hilfe nicht immer angeben müssen, werden wir uns gegen Ende dieser Lektion eine eigene Funktion myhelp() definieren, die uns diese Arbeit abnimmt. 1.3 Arithmetische Operationen und numerische Funktionen In R sind die üblichen arithmetischen Operationen möglich, dabei gilt Punkt vor Strich“. ” > 1+2*2 [1] 5 Ebenfalls vorhanden sind auch die gängigen mathematischen Funktionen wie Logarithmus oder Wurzel. Die Funktionen log(), exp(), sin(), cos(), tan(), acos(), asin(), atan(), sqrt(), gamma() haben ihre übliche Bedeutung. Den Absolutbetrag einer Zahl erhalten Sie mit abs() und beliebige Potenzen mit ^. Es gelten die üblichen Regeln bezüglich der Reihenfolge bei der Auswertung (Potenz vor Punkt vor Strich), ferner können Sie Klammern setzen. > 4*atan(1) [1] 3.141593 > exp(1) [1] 2.718282 > 8^(1/3) [1] 2 1.4 Vektoren Mehrere Zahlen können Sie durch den Befehl c() zu einem Vektor zusammenfassen. Mit dem Operator <- können Sie das Ergebnis einer Operation einem R-Objekt zuweisen. Im folgenden Beispiel erzeugen Sie einen Vektor der Länge 5 mit dem Namen x. > x <- c(1,2,4,9,16) Bemerkung 1.5. Der Zuweisungsoperator kann analog auch von links nach rechts“ verwendet wer” den: 4 c Math. Stochastik, Uni Freiburg ° > c(1,2,4,9,16) -> x Auch eine Zuweisung mittels = wie in C ist möglich; äquivalent zu obigem ist > x=c(1,2,4,9,16) Da jedoch <- und -> die Standard-Zuweisungsoperatoren in R sind und überall verwendet werden können, während für = gewisse Einschränkungen gelten, werden wir letzteren nicht weiter verwenden. Geben Sie nur den Namen eines Objektes an, so wird sein Inhalt auf dem Bildschirm ausgegeben. > x [1] 1 2 4 9 16 Bei Funktionsnamen (ohne die Klammern ( und )) erhalten Sie so das zugehörige Listing: > exp function (x) .Primitive("exp") Dies ist bei generischen R-Funktionen wie exp() nicht unbedingt informativ, aber nützlich bei selbstgeschriebenen Funktionen, wie wir sie weiter unten kennenlernen werden. Wenden Sie eine der Funktionen aus Abschnitt 1.3 auf einen Vektor an, so geschieht die Auswertung komponentenweise. Dies gilt auch für arithmetische Operationen. > sqrt(x) [1] 1.000000 1.414214 2.000000 3.000000 4.000000 > 2*x [1] 2 4 8 18 32 > x*x [1] 1 4 16 81 256 Zahlenfolgen mit gleichmäßigem Abstand erzeugt der Befehl seq(x,y,h) (sequence). Dabei bestimmen x und y Anfangs- und Endwert, h gibt die Schrittlänge an. > seq(0,10,.5) [1] [16] 0.0 7.5 0.5 8.0 1.0 1.5 8.5 9.0 2.0 2.5 3.0 3.5 4.0 4.5 5.0 5.5 6.0 6.5 7.0 9.5 10.0 Gibt man stattdessen die gewünschte Folgenlänge an, wird die Schrittlänge automatisch angepasst: > seq(0,10,length=10) [1] 0.000000 1.111111 2.222222 [8] 7.777778 8.888889 10.000000 3.333333 4.444444 5.555556 6.666667 Eine andere Möglichkeit, Zahlenfolgen mit Schrittweite 1 zu erzeugen, bietet der : -Operator. > 1.5:4.5 [1] 1.5 2.5 3.5 4.5 5 c Math. Stochastik, Uni Freiburg ° 1.5 Einige spezielle Funktionen für Vektoren Bisher haben Sie nur R-Funktionen kennengelernt, die eigentlich für Skalare definiert sind und bei Anwendung auf einen Vektor komponentenweise wirken. Wir stellen nun einige nützliche Funktionen vor, die auf einen Vektor angewendet werden können, aber nicht komponentenweise wirken. Mit den Funktionen cumsum(), cumprod() und cummax() erhalten Sie die kumulativen Summen, Produkte und Maxima. > x <- c(3,1,2,5,6,4) > cumsum(x) [1] 3 4 6 11 17 21 > cumprod(x) [1] 3 3 6 30 180 720 > cummax(x) [1] 3 3 3 5 6 6 Mit der Funktion diff() kann man die sukzessiven Differenzen berechnen. > diff(x) [1] -2 1 3 1 -2 R verfügt auch über Funktionen, die auf einen Vektor angewendet eine Zahl als Ergebnis liefern und diesen gleichsam zusammenfassen“. Mit den R-Funktionen sum(), prod(), max() und min() erhalten ” Sie Summe, Produkt, Maximum und Minimum aller Komponenten eines Vektors. Mit mean() erhalten Sie den Mittelwert aller Komponenten. > x <- 1:6 > c(sum(x),prod(x)) [1] 21 720 > c(min(x),max(x)) [1] 1 6 > mean(x) [1] 3.5 Mit der Funktion length() erhalten Sie die Anzahl der Komponenten eines Vektors. > length(x) [1] 6 1.6 Plotten von Funktionen Wir beschäftigen uns nun mit einfachen grafischen Befehlen in R. Mit x11() (Linux), quartz() (Mac OS X) bzw. windows() (Windows) kann man ein grafisches Fenster öffnen, was aber in der Regel 6 c Math. Stochastik, Uni Freiburg ° gar nicht notwendig ist, da der plot()-Befehl dies bei Bedarf selbst nachholt. Über diesen vielleicht wichtigsten Grafik-Befehl können Sie sich ausführlich mit > ?plot informieren. Wie Sie sehen, lassen sich mit plot(x,y) Punkte mit den in x angegebenen x-Koordinaten und den in y angegebenen y-Koordinaten plotten. Dabei müssen x und y Vektoren gleicher Länge sein. Mit der Option type können Sie zwischen verschiedenen Modi wählen; so werden etwa bei type="l" (lines) die Punkte durch Geradenstücke verbunden, mit type="s" (stair steps) erhalten Sie eine Treppenfunktion, und mit type="p" (points) werden einzelne Punkte eingezeichnet. Letzteres ist die Defaulteinstellung. Die Punktmarkierung können Sie durch den grafischen Parameter pch (plotting character) auswählen. Über die verschiedenen grafischen Parameter informiert Sie der nächste Befehl. > ?par Nun einige einfache Beispiele: > plot(1,1) > plot(c(1,2,3),c(3,1,2),type="l") > plot(c(1,2,3,4),c(1,4,9,16),pch=1) > plot(c(1,2,3,4),c(1,4,9,16),pch=c(2,5)) Wenn Sie das Grafik-Fenster durch Ziehen mit der Maus vergrößern oder verkleinern, passt sich der Plot dem Fensterformat an. R verfügt über eine Vielzahl eingebauter Funktionen, darunter befinden sich auch die Dichtefunktionen gängiger Wahrscheinlichkeitsverteilungen. Definition 1.6. Eine Wahrscheinlichkeitsdichte ist eine nicht-negative Funktion f : R → R+ mit der R Eigenschaft R f (x) dx = 1. So erhalten Sie z.B. mit dlnorm() die Dichtefunktion der Log-Normal-Verteilung. > x <- seq(0,5,0.1) > plot(x,dlnorm(x,meanlog=0,sdlog=0.5),type="l") Wir möchten nun zu verschiedenen Parametern gehörige Dichte-Funktionen vergleichen und dazu gemeinsam in einem Fenster plotten. Um eine weitere Kurve in einen bestehenden Plot zu zeichnen, können Sie die Funktion plot() nicht benutzen. Sie löscht stets den vorhergehenden Plot und zeichnet einen neuen. Zum Hinzufügen von Kurven in einen bestehenden Plot stellt R die Funktionen lines() und points() zur Verfügung. Mit title() kann ein Titel ergänzt werden. > points(x,dlnorm(x,0,1),pch=5) > points(x,dlnorm(x,2,0.5),pch=1) > title("Log-Normal-Dichten") 7 c Math. Stochastik, Uni Freiburg ° R bestimmt die Skalen auf den beiden Achsen bei plot() automatisch und passt diese leider bei hinzukommenden Punkten nicht mehr neu an. > lines(x,dlnorm(x,0,0.25)) Mit ylim können Sie die Skala auf der y-Achse selbst festlegen; entsprechendes gilt für xlim. Dabei müssen ylim und xlim Vektoren der Länge 2 sein, die die jeweiligen Achsengrenzen enthalten. Mit col können Sie die Farbe des Graphen bestimmen. Acht verschiedene Farben können durch Zuweisung der Zahlen 1, 2, . . . , 8 für col festgelegt werden; welche dies sind, verrät der Befehl > palette() [1] "black" "red" "green3" "blue" "cyan" "magenta" "yellow" [8] "gray" Man kann col die gewünschte Farbe alternativ auch als Textstring übergeben; das ist zwar etwas aufwändiger, dafür hat man allerdings auch eine bedeutend größere Auswahl. Sämtliche zur Verfügung stehenden Farben kann mit sich auflisten lassen mit > colors() Wird der Parameter col nicht explizit angegeben, wird per Default "black" bzw. 1 gewählt. > plot(x,dlnorm(x,0,0.5),type="l",xlim=c(0,20),ylim=c(0,1.9)) > lines(x,dlnorm(x,0,0.25),col=2) > lines(x,dlnorm(x,0,0.2),col="gold") Die Achsenbeschriftung kann mit xlab (x-axis label) bzw. ylab (y-axis label) eigenen Wünschen angepasst werden. Mit xlab="" bzw. ylab="" kann dabei die Beschriftung unterdrückt werden. > plot(x,dlnorm(x,0,0.25),type="l",xlab="x",ylab="dlnorm(x)",col="blue") Das grafische Fenster können Sie mit dem Befehl dev.off() wieder schließen. > dev.off() Bemerkung 1.7. Das Grafik-Fenster ist allein zur Ansicht gedacht; will man den erstellten Plot speichern oder ausdrucken, muss man ihn in eine Postscript- oder PDF-Datei umwandeln. Dies kann in Abhängigkeit vom jeweils zugrundeliegenden Betriebssystem wie folgt geschehen: Mit dem Befehl > dev.print(file="/Pfad/zum/file/name.ps") wird unter Linux und Mac OS X ein Postscript-File name.ps unter dem angegebenen Pfad abgelegt. Per Defaulteinstellung wird als Papiergröße DIN A4 angenommen, der eigentliche Plot hat aber dessenungeachtet die gleichen Dimensionen wie das Grafik-Fenster! Um einen vermutlich gewünschten 8 c Math. Stochastik, Uni Freiburg ° rechteckigen Ausdruck zu bekommen, muss man entweder vor Verwendung des dev.print()-Befehls mit der Maus das Grafik-Fenster in Größe und Format entsprechend anpassen oder die zusätzlichen Parameter width und height verwenden, mit denen man Breite und Höhe des Plots explizit angeben kann. Achtung: Dabei wird die Maßeinheit Inch statt cm zugrundegelegt (1 Inch = 2.54 cm)! Folgende Werte liefern akzeptable Ergebnisse für Ausdrucke im DIN A4-Format: > dev.print(file="/Pfad/zum/file/name.ps", width=11.25, height=8) Zur Erzeugung von PDF-Files ist obiger Befehl geringfügig zu modifizieren: > dev.print(device=pdf,file="/Pfad/zum/file/name.pdf",width=11.25,height=8) Da Windows das Postscript-Dateiformat nicht nennenswert unterstützt und von Haus aus auch keine Programme zur Ansicht und Bearbeitung solcher Dateien mitbringt, sollte man sich bei Verwendung dieses Betriebssystems auf die Erzeugung von PDF-Dateien beschränken, die man z.B. mit dem Acrobat Reader öffnen und ausdrucken kann. Mit > dev.print(device=pdf, file="name.pdf") wird ein PDF-File name.pdf erzeugt und im momentan verwendeten R-Arbeitsverzeichnis abgelegt. Wie unter Linux und Mac OS X hat auch hier der Plot die gleichen Dimensionen wie das GrafikFenster, so dass man das jeweils gewünschte Format mit Hilfe der Parameter width und height festlegen muss. Für DIN A4 sind wie oben die folgenden Werte zu wählen: > dev.print(device=pdf, file="name.pdf", width=11.25, height=8) Soll die Grafik nicht direkt im R-Arbeitsverzeichnis, sondern woanders abgespeichert werden, muss ähnlich wie unter Linux und Mac OS X der komplette Pfad angegeben werden. Achtung: Die Verwendung des unter Windows üblichen Backslashs \ in der Pfadangabe führt in R zu Problemen und einer Fehlermeldung! Dieser muss entweder durch einen doppelten Backslash \\ oder einen einfachen Slash / ersetzt werden: Die Befehle > dev.print(device=pdf, file="C:\\Eigene Dateien\\R-Grafiken\\name.pdf") und > dev.print(device=pdf, file="C:/Eigene Dateien/R-Grafiken/name.pdf") sind äquivalent und erzeugen beide eine PDF-Datei name.pdf im angegebenen Verzeichnis, die nachfolgende Version dagegen funktioniert nicht: > dev.print(device=pdf, file="C:\Eigene Dateien\R-Grafiken\name.pdf") 9 c Math. Stochastik, Uni Freiburg ° 1.7 Anwenderfunktionen R bietet die Möglichkeit, mit Hilfe bereits vorhandener Funktionen neue Funktionen zu definieren. Der größte Teil der in R bereitgestellten Funktionen ist von diesem Typ. Die allgemeine Syntax einer Funktionsdefinition lautet: Funktionsname <- function(arg1, arg2, ...){R-Befehl(e) } Die Funktion wird dabei als R-Objekt unter dem Namen Funktionsname abgelegt. Sie sollten es möglichst vermeiden, einen Namen doppelt zu vergeben (z.B. für eine Funktion und einen Vektor), ansonsten wird das ältere der gleichnamigen Objekte durch das neuere überschrieben. Ebensowenig sollten Sie einen bereits in R intern vergebenen Namen wählen. Um zu überprüfen, ob es etwa bereits ein R-Objekt mit Namen test gibt, geben Sie einfach diesen Namen ein. > test Fehler: Objekt ’test’ nicht gefunden Besteht eine Funktionsdefinition aus mehreren Anweisungen, so werden diese bei der Eingabe durch Semikolons oder durch Beginnen einer neuen Zeile mit [Enter] getrennt. Zuweisungen innerhalb von Funktionen gelten nur lokal“ und werden bei Beendigung der Funktion aufgehoben. Die Rückgabe ” von Werten kann mittels des Befehls return() erfolgen; fehlt dieser, gibt die Funktion den Wert des zuletzt ausgewerteten Ausdrucks zurück. Beispiel 1.8. > func.1 <- function(x){y <- x*x-3*x; return(y)} > func.1(3) [1] 0 > y Fehler: Objekt ’y’ nicht gefunden > func.1(1:5) [1] -2 -2 0 4 10 > func.1 function(x){y <- x*x-3*x; return(y)} Beispiel 1.9. > func.2 <- function(x){c(exp(x),x*x+1)} > func.2(1) [1] 2.718282 2.000000 Bemerkung 1.10. Jede Funktion wird unmittelbar nach Ausführung eines return()-Befehls beendet, auch wenn diesem innerhalb der Funktionsdefinition noch weitere Befehle folgen! Bei aufwändigeren Funktionsdefinitionen empfiehlt sich die Verwendung eines Editors. Detailliertere Informationen dazu findet man für alle unterstützten Betriebssysteme auf der Praktikums-Webseite. 10 c Math. Stochastik, Uni Freiburg ° Bei einer Funktion mit mehreren Argumenten gibt es zwei Möglichkeiten, die Werte für die einzelnen Argumente korrekt zu übergeben: Zuordnung durch Reihenfolge oder Zuordnung durch Benennung. Beispiel 1.11. > func.3 <- function(x,y){x*sqrt(y)} > func.3(4,9) [1] 12 > func.3(9,4) [1] 18 > func.3(y=9,x=4) [1] 12 > func.3(9) Fehler in sqrt(y) : ’y’ fehlt Es ist möglich, bei der Definition einer Funktion Defaultwerte für einzelne Argumente festzulegen. Diesen Argumenten muss dann beim Aufruf der Funktion nicht zwingend ein Wert zugewiesen werden. Beispiel 1.12. > func.4 <- function(x,y=1){sqrt(x)*sqrt(y)} > func.4(9) [1] 3 > func.4(9,4) [1] 6 Falls Anzahl und Art der Argumente nicht von vornherein festgelegt werden können oder sollen, kann man innerhalb der Funktionsdefinition das spezielle Argument ... verwenden. Dies fungiert als Platzhalter, für den beim späteren Funktionsaufruf beliebige Argumente eingesetzt werden können. Damit kann man sehr einfach viele Argumente gleichzeitig an eine innere Funktion übergeben, ohne sie alle einzeln in der äußeren deklarieren zu müssen. Als einfaches Beispiel betrachten wir eine Funktion, die x · sin(x) mit Achsenbeschriftung zeichnet: Beispiel 1.13. > myplot <- function(x,...){plot(x,x*sin(x),xlab="x",ylab="x*sin(x)",...)} > x <- seq(0,5,0.01) > myplot(x) > myplot(x,type="l",col="red") Linux-Nutzer können dies bei der Definition der oben angekündigten Funktion myhelp() verwenden, mit der man die Zweiteilung des XEmacs bei Aufruf der html-Hilfe auch ohne explizite Angabe der Option help type="html" verhindern kann: > myhelp <- function(...){help(..., help_type="html")} 11 c Math. Stochastik, Uni Freiburg ° 1.8 Erzeugte R-Objekte Wie zuvor bereits angesprochen, bleiben die während einer R-Sitzung erzeugten Objekte nur dann für künftige Sitzungen erhalten, wenn die beim Beenden von R erscheinende Frage mit y bzw. Ja beantwortet wird oder bereits zuvor eine Datensicherung mit dem Befehl save.image() erfolgt ist. Da dabei alle derzeit im Arbeitsspeicher vorgehaltenen Objekte gesichert werden, muss Überflüssiges, auf dessen weitere Verwendung man keinen Wert legt, zuvor gelöscht werden. Zur Ansicht aller verfügbaren, selbst erzeugten Objekte können die äquivalenten Befehle ls() (list) oder objects() verwendet werden, zum Löschen einzelner oder mehrerer davon die Befehle rm() oder remove(). > ls() > rm(x) > ls() Damit wollen wir die erste Lektion wie auch R beenden mit > q() 12 c Math. Stochastik, Uni Freiburg ° 1.9 Übungen Aufgabe 1.1. Schreiben Sie eine Funktion, die die Differenz zwischen dem Maximum und dem Minimum der Komponenten eines Vektors ausgibt. Aufgabe 1.2. Schreiben Sie eine Funktion, die den euklidischen Abstand zwischen zwei Vektoren x, y ∈ Rn berechnet. 13 c Math. Stochastik, Uni Freiburg ° Lektion 2: Grundlagen 2.1 Nicht definierte und fehlende Werte In R existiert ein spezieller Wert zur Kennzeichnung undefinierter numerischer Größen: die Konstante NaN (not a number). Diese wird als Ergebnis unzulässiger numerischer Operationen zurückgegeben und ist wohl zu unterscheiden von den Werten Inf und -Inf (±∞): > c(1/0,0/0,-1/0) [1] Inf NaN -Inf > log(c(-2,-1,0,1,2)) [1] NaN NaN -Inf 0.0000000 0.6931472 Warnmeldung: In log(c(-2, -1, 0, 1, 2)) : NaNs wurden erzeugt Fast alle numerischen Funktionen können diese drei Werte verarbeiten. Bei NaN als Argument wird derselbe Wert zurückgegeben, die Verarbeitung von -Inf und Inf ist jedoch funktionsabhängig: > exp(c(-Inf,NaN,Inf)) [1] 0 NaN Inf > sin(c(-Inf,NaN,Inf)) [1] NaN NaN NaN Warnmeldung: In sin(c(-Inf, NaN, Inf)) : NaNs wurden erzeugt Neben der numerischen Konstante NaN gibt es ferner die logische Größe NA (not available), die fehlende Werte kennzeichnet (siehe Abschnitt 2.2). Diese kann ebenfalls als Argument eingesetzt werden; üblicherweise geben numerische R-Funktionen in diesem Fall wieder NA als Ergebnis zurück. > sqrt(c(1,2,NA,4)) [1] 1.000000 1.414214 NA 2.000000 2.2 Logische Größen und Vergleichsoperatoren in R R kennt logische Größen mit drei (!) möglichen Werten: TRUE, FALSE und NA. Fehlende Werte können z.B. als Ergebnis eines unentscheidbaren Ausdrucks zurückgegeben werden: 14 > 1 < 0/0 [1] NA Logische Größen können, wie im letzten Beispiel bereits angedeutet, durch Vergleichsoperationen erzeugt werden. In R stehen hierzu die folgenden Operatoren zur Verfügung: R-Operator Wirkung < echt kleiner > echt größer <= kleiner gleich >= größer gleich == gleich != ungleich Einige einfache Beispiele: > 1>2 [1] FALSE > 1!=2 [1] TRUE > x <- c(NA,5,2,7,3,NA,-Inf,Inf) > x>3 [1] NA TRUE FALSE TRUE FALSE NA FALSE TRUE Beachten Sie, dass auch die logischen Operatoren komponentenweise wirken und daher das Ergebnis im letzten Beispiel ein Vektor ist mit Einträgen TRUE und FALSE, entsprechend den Elementen von x, die die Bedingung x>3 erfüllen bzw. nicht erfüllen, und Einträgen NA an den Positionen, denen kein Ergebnis zugeordnet werden kann. R verfügt also über eine dreiwertige Logik“. ” Logische Größen können in arithmetische Ausdrücke eingesetzt werden – in diesem Fall wird der Wert TRUE zu 1 und der Wert FALSE zu 0 umgewandelt. Dies gibt Ihnen beispielsweise die Möglichkeit, rasch zu ermitteln, wieviele Komponenten eines Vektors eine Vergleichsbedingung erfüllen. > (1:4)>2 [1] FALSE FALSE TRUE TRUE > sum((1:4)>2) [1] 2 Sie können logische Ausdrücke durch und“ oder oder“ verknüpfen oder auch negieren. Hierzu stehen ” ” R-Operator Wirkung & oder && und | oder || oder ! Negation 15 c Math. Stochastik, Uni Freiburg ° zur Verfügung. Um alle Komponenten eines logischen Vektors durch und“ oder oder“ zu verknüpfen, ” ” stellt R die Funktionen all() und any() bereit. Bei der direkten Eingabe logischer Werte als Argumente kann man statt TRUE und FALSE auch kürzer T und F schreiben. > !(1+1>3) [1] TRUE > (2>3) | (3<4) [1] TRUE > NA | T [1] TRUE > (2>3) & (3<4) [1] FALSE > T & NA [1] NA > all(c(T,F,F)) [1] FALSE > any(c(T,F,F)) [1] TRUE Bemerkung 2.1. T und F sind globale Variablen in R, denen der Wert TRUE bzw. FALSE zugeordnet ist. Man sollte sie nicht als Namen für selbst erzeugte Objekte verwenden und damit überschreiben! Zwischen den einfachen (&,|) und doppelten (&&,||) Operatoren besteht ein kleiner, aber feiner Unterschied: Die doppelten Operatoren wirken nicht wie die anderen komponentenweise, sondern werten sukzessiv von links nach rechts nur das jeweils erste Element eines Vektors aus. Die Bearbeitung wird vorzeitig abgebrochen, sofern das Ergebnis eindeutig ist, d.h. bei &&, sobald erstmalig FALSE auftritt, und bei ||, sobald erstmalig TRUE auftritt. Daher geben sie stets nur einen einzelnen Wert zurück. > x [1] NA 5 2 7 3 NA -Inf Inf > x<7 & x>=3 [1] NA TRUE FALSE FALSE TRUE NA FALSE FALSE > x <7 && x>=3 [1] NA Das vorzeitige Abbrechen der Bearbeitung verhindert die Auswertung fehlerhafte Ausdrücke, wie das folgende Beispiel zeigt: > y <- -1 > y > 0 & log(y)>1 [1] FALSE Warnmeldung: 16 c Math. Stochastik, Uni Freiburg ° In log(y) : NaNs wurden erzeugt > y > 0 && log(y)>1 [1] FALSE Statt, wie zuvor gesehen, logische Werte in numerische (Zahlen) umzuwandeln, ist auch die Umkehrung möglich. Dabei wird 0 in FALSE, NaN in NA und alles übrige zu TRUE konvertiert: > c(-Inf,Inf,NaN,-2,-1,0,5) & T [1] TRUE TRUE NA TRUE TRUE FALSE TRUE 2.3 Bedingte Anweisungen Logische Größen erlauben die Einführung bedingter Anweisungen in Programmen, bei denen ein oder mehrere nachfolgende Befehle nur dann ausgeführt werden, wenn eine bestimmte Bedingung erfüllt ist. In R steht hierzu der Befehl if(Bedingung ){R-Befehl(e) } zur Verfügung. Hat der logische Ausdruck Bedingung den Wert TRUE, so werden die sich anschließenden Befehle abgearbeitet, bei FALSE dagegen nicht (falls Bedingung den Wert NA hat, bricht R die weitere Bearbeitung mit einer Fehlermeldung ab). Dabei ist darauf zu achten, dass Bedingung nur einen einzelnen logischen Wert liefert; ist das Ergebnis stattdessen ein mehrkomponentiger logischer Vektor, wird nur dessen erste Komponente ausgewertet und eine entsprechende Warnung ausgegeben! Sollen, falls Bedingung den Wert FALSE annimmt, alternative Befehle ausgeführt werden, so kann man direkt nach der if-Anweisung den Befehl else{R-Befehl(e) } folgen lassen. Wenn if oder else nur ein einziger Befehl folgt, kann man auf die geschweiften Klammern verzichten. Aufgrund der besseren Lesbarkeit werden wir die Klammern allerdings stets setzen. Beispiel 2.2. Wir verdeutlichen die Anwendung dieser Anweisungen anhand der untenstehenden Funktion is.pos(), die der Indikatorfunktion 1R+ (x) entspricht. > is.pos <- function(x){ if(is.na(x)|is.nan(x)){return(x)} else{return(1-(x<0))} } Die Funktionen is.na() und is.nan() überprüfen dabei, ob x den Wert NA bzw. NaN hat und geben je nachdem den Wert TRUE oder FALSE zurück. Damit wird die hinter else stehende Indikatorfunktion nur dann ausgewertet, wenn die Bedingung x<0 nicht den Wert NA ergibt. In obiger Form kann die Funktion is.pos() vektorwertige Argumente nicht korrekt verarbeiten. Mit den in Abschnitt 2.5.2 vorgestellten Methoden werden wir diesen Mangel beheben können. 2.4 Datentypen in R R kennt neben logischen und numerischen Größen eine Reihe weiterer Datentypen. In Tabelle 2.1 geben wir eine Übersicht von grundlegenden Datentypen. 17 c Math. Stochastik, Uni Freiburg ° Datentyp Beispiele character "name", "2+3i" complex 1-5i, 42+0i numeric -0.5, pi, 1 logical FALSE, TRUE, NA Tabelle 2.1: Übersicht wichtiger Datentypen in R. Den Datentyp eines Objekts erhalten Sie mit der Funktion mode(). > a <- NULL > b <- TRUE > d <- 1 > e <- 3+4i > f <- "abcdef" > mode(a) [1] "NULL" > mode(b) [1] "logical" > mode(c) [1] "function" > mode(d) [1] "numeric" > mode(e) [1] "complex" > mode(f) [1] "character" Mit den Funktionen is.character(), is.numeric(), is.complex() usw. können Sie prüfen, ob ein Objekt zu einem bestimmten Datentyp gehört. Mit den Funktionen as.character(), as.numeric(), as.complex() usw. können Sie Daten von einem Typ in einen anderen umwandeln; dabei geht allerdings bisweilen Information verloren. > is.numeric(d) [1] TRUE > is.complex(f) [1] FALSE > as.numeric(b) [1] 1 > e <- as.numeric(e) 18 c Math. Stochastik, Uni Freiburg ° Warnmeldung: imaginäre Teile verworfen in Umwandlung > e [1] 3 > e <- as.complex(e) > e [1] 3+0i Bemerkung 2.3. Die Größen NA und NULL sind wohl voneinander zu unterscheiden: Während NA ein logischer Wert vom Datentyp "logical" ist, entspricht NULL der leeren Menge und hat gar keinen Datentyp (bzw. ebenfalls den Typ "NULL"). 2.5 Indizierung von Vektoren Wir wollen uns nun näher mit den verschiedenen Möglichkeiten beschäftigen, die R bietet, um einzelne Komponenten von Vektoren auszuwählen. 2.5.1 Numerische Indizes Mit x[i] können Sie das i-te Element eines Vektors x auswählen. Gemäß den allgemeinen Prinzipien von R können Sie für Indizes auch Vektoren einsetzen. Negative Indizes unterdrücken die Ausgabe der entsprechenden Komponente(n). > x <- c(2,4,6) > x[2:3] [1] 4 6 > x[-2] [1] 2 6 > x[4] <- 8 > length(x) [1] 4 > x[5] [1] NA > x[6] <- 12 > mode(x) [1] "numeric" > x[1:10] [1] 2 4 6 8 NA 12 NA NA NA NA Wie Sie sehen, wird ein Vektor x mit n = length(x) Komponenten in gewissem Sinn wie eine unendliche Folge (x1 , . . . , xn , NA, NA, . . . ) behandelt. 19 c Math. Stochastik, Uni Freiburg ° 2.5.2 Indizierung mit logischen Vektoren Neben dem Gebrauch von numerischen Indizes besteht in R auch die Möglichkeit, logische Indizes zu verwenden. Darunter versteht man die Verwendung von logischen Vektoren als Index – in diesem Fall werden diejenigen Elemente ausgewählt, denen der Wert TRUE entspricht. Bei dieser Form der Indizierung sollten der logische Indexvektor und der zu indizierende Vektor die gleiche Länge aufweisen. Andernfalls wird der Indexvektor zyklisch wiederholt, wenn er kürzer ist; sollte er länger sein, wird er abgeschnitten. Enthält der logische Vektor NAs, wird dieser Wert in der Regel auch den entsprechenden Komponenten des Ergebnisvektors zugeordnet, wie die ersten zwei Beispiele zeigen. > x [1] 2 4 6 8 NA 12 > x[x<6] [1] 2 4 NA > x[c(NA,T)] [1] NA 4 NA 8 NA 12 > y <- c(3,2,4,7,1,6) > y[y>=3] [1] 3 4 7 6 Mit Hilfe der bereits erwähnten Funktion is.na() erhalten Sie schnell einen Vektor ohne die lästigen NA-Komponenten. > x.ok <- !is.na(x) > x.ok [1] TRUE TRUE TRUE TRUE FALSE TRUE > x[x.ok] [1] 2 4 6 8 12 > length(x) [1] 6 > length(x[x.ok]) [1] 5 Beispiel 2.4 (Fortsetzung von Beispiel 2.2). Mit den o.g. Hilfsmitteln können wir nun auch die oben definierte Funktion is.pos() auf vektorwertige Argumente erweitern. Allen Komponenten des eingegebenen Vektors, die < 0 sind, wird der Wert 0 zugewiesen, denen ≥ 0 der Wert 1, NAs und NaNs bleiben unverändert: > is.pos <- function(x){x.ok <- !(is.na(x)|is.nan(x)); x[x.ok] <- 1-(x[x.ok]<0); x} > is.pos(c(-1,2,3,Inf,-Inf,NA,6,NaN)) [1] 0 1 1 1 0 NA 1 NaN 20 c Math. Stochastik, Uni Freiburg ° 2.5.3 Indizierung mit Namen Sie können die einzelnen Komponenten eines Vektors auch mit der Funktion names() benennen und dann einzelne Komponenten mit ihrem Namen auswählen. > vektor.namen <- c("a","b","c","d","e","f") > names(x) <- vektor.namen > names(x) [1] "a" "b" "c" "d" "e" "f" > x a b c d e f 2 4 6 8 NA 12 > x["d"] d 8 Man beachte die in der letzten Eingabezeile notwendigen Anführungszeichen ", die das von ihnen eingeschlossene d als Variable vom Typ "character" kennzeichnen, so wie es auch innerhalb des Vektors vektor.namen definiert wurde. > 3*x a b c d e f 6 12 18 24 NA 36 > as.vector(3*x) [1] 6 12 18 24 NA 36 Vektoren sind dadurch gekennzeichnet, dass alle ihre Elemente vom gleichen Datentyp sind. Fügt man einem Vektor ein Element hinzu, das einen anderen Datentyp hat als die bisherigen Komponenten, findet eine Typumwandlung in den Datentyp mit dem höheren Rang statt. Hat das neu hinzugefügte Element einen Datentyp niedrigeren Ranges als der bisherige Vektor, wird es selbst umgewandelt, ansonsten werden alle anderen Komponenten entsprechend konvertiert (lediglich NAs bleiben jeweils unverändert). Die Hierarchie der Datentypen (siehe Tabelle 2.1) ist "logical" < "numeric" < "complex" < "character". > y [1] 3 2 4 7 1 6 > y[7] <- TRUE > y [1] 3 2 4 7 1 6 1 > y[8] <- "a" > y [1] "3" "2" "4" "7" "1" "6" "1" "a" 21 c Math. Stochastik, Uni Freiburg ° > y^2 Fehler in y^2 : nicht-numerisches Argument für binären Operator 2.6 Listen In sogenannten Listen können Sie R-Objekte verschiedenen Datentyps zu einem neuen R-Objekt zusammenbinden. Eine Liste ist vereinfacht gesagt ein Vektor mit Komponenten verschiedenen Typs. > namen <- c("Erika","Johann","Sieglinde","Heinrich","Anna","Uta","Dieter","Josef") > list.example <- list(100:107,namen,c(T,F,T,T,F,F,F,T)) > list.example [[1]] [1] 100 101 102 103 104 105 106 107 [[2]] [1] "Erika" [7] "Dieter" "Johann" "Sieglinde" "Heinrich" "Anna" "Uta" "Josef" [[3]] [1] TRUE FALSE TRUE TRUE FALSE FALSE FALSE TRUE Die einzelnen Komponenten lassen sich wie bei Vektoren auswählen: Mit list.example[i] oder auch list.example[[i]] erhält man den i-ten Eintrag (bei Verwendung der Doppelklammern [[ und ]] kann allerdings nur ein einzelnes Listenelement ausgewählt werden, da in diese keine Vektoren eingesetzt werden dürfen). Zur Bearbeitung ist es aber meist vorteilhafter, die Komponenten zu benennen, so dass diese unter ihrem jeweiligen Namen aufgerufen werden können: > mitglieder <- list(nummer=100:107,namen=namen,bezahlt=c(T,F,T,T,F,F,F,T)) > mitglieder$nummer [1] 100 101 102 103 104 105 106 107 > mitglieder$bezahlt [1] TRUE FALSE TRUE TRUE FALSE FALSE FALSE TRUE Auf diese Weise lassen sich elegant Fragen an die Daten beantworten, wie etwa die Namen der Mitglieder mit einer Mitgliedsnummer größer als 103 oder die Namen der Mitglieder, die ihren Jahresbeitrag schon bezahlt haben. > mitglieder$namen[mitglieder$nummer>103] [1] "Anna" "Uta" "Dieter" "Josef" > mitglieder$namen[mitglieder$bezahlt] [1] "Erika" "Sieglinde" "Heinrich" "Josef" Beachten Sie dabei, dass im Index ein anderer Vektor steht als derjenige, der indiziert wird. Die beiden Vektoren (Vektor und Vektorindex) müssen lediglich von der Länge zueinander passen. 22 c Math. Stochastik, Uni Freiburg ° 2.7 Übungen Aufgabe 2.1. Passen Sie die Funktion aus Aufgabe 1.1 so an, dass Komponenten NA und/oder NaN aussortiert werden. Aufgabe 2.2. Schreiben Sie eine Funktion, die die Elemente eines Vektors in umgekehrter Reihenfolge ausgibt. Aufgabe 2.3. Geben Sie alle ungeraden Zahlen zwischen 1 und 100 (mit einem möglichst kompakten Befehl!) aus. Aufgabe 2.4. Schreiben Sie eine Funktion, die die Anzahl der Komponenten > 1 eines numerischen Vektors ausgibt. Zusatz : Berücksichtigen Sie auch hier eventuelle Probleme mit Komponenten NA und/oder NaN. Aufgabe 2.5. Numerische Integration: a) Schreiben Sie eine Funktion, die für eine Folge (xk )1≤k≤n die Riemannsumme der Sinusfunktion berechnet: n X sin(xk )(xk − xk−1 ). k=2 b) Erweitern Sie die Funktion, so dass sie die Riemannsumme einer beliebigen Funktion f für eine Folge (xk )1≤k≤n berechnen kann. Benutzen Sie dabei f = sin als Defaulteinstellung. n X f (xk )(xk − xk−1 ). k=2 c) Die Genauigkeit der Approximation lässt sich durch Anwendung der Trapezregel erhöhen. Erweitern Sie daher die Funktion derart, dass bei der Berechnung des Integrals zwischen der Riemannsumme und der Trapezregel gewählt werden kann. Setzen Sie dabei die Anwendung der Riemannsumme als Defaulteinstellung. Aufgabe 2.6. Definition neuer Verteilungen: Implementieren Sie eine neue Klasse von Verteilungen V (α) in R, deren Dichten gegeben sind durch dV (α) (x) = α (|x| + 1)−α−1 , 2 x ∈ R, α ∈ (0, ∞). a) Schreiben Sie eine Funktion dv(x,alpha), die den Wert der Dichte dV (α) an der Stelle x berechnet und ausgibt. Geben Sie dabei für alpha den Defaultwert 1 vor. Falls die Voraussetzung α ∈ (0, ∞) nicht erfüllt wird, sollte die Funktion mit einer Fehlermeldung abbrechen. Hinweis: In return() lassen sich auch Textstrings einsetzen. b) Schreiben Sie analog zu a) eine Funktion pv(x,alpha), die die zugehörigen VerteiRx lungsfunktion FV (α) (x) = −∞ dV (α) (y) dy für (vektorwertige) x berechnet. Hinweis: Beachten und benutzen Sie dafür die Achsensymmetrie der Dichte. 23 c Math. Stochastik, Uni Freiburg ° Lektion 3: Matrizenrechnung 3.1 Matrizen R kennt auch Matrizen; diese können Sie mit der Funktion matrix() erzeugen, deren allgemeine Syntax lautet matrix(data,nrow=1,ncol=1,byrow=FALSE,dimnames=NULL) Dabei ist data ein (numerischer) Vektor, der die einzelnen Matrixelemente enthält, die spaltenweise eingetragen werden, falls byrow=FALSE (Default), und zeilenweise, falls byrow=TRUE. Mit nrow (number of rows) wird die Zeilenzahl festgelegt, mit ncol (number of columns) die Spaltenzahl. Meist genügt die Angabe eines der beiden Parameter, den anderen bestimmt R anhand der Länge von data automatisch, sofern möglich. Enthält der Datenvektor weniger als nrow · ncol Elemente, so wird er zur Erzeugung der Matrix entsprechend oft zyklisch wiederholt. Mit dimnames kann man ähnlich wie bei Vektoren einzelnen Zeilen und Spalten Namen geben, worauf wir untenstehend näher eingehen werden. > m <- matrix(1:12,nrow=3) > m [,1] [,2] [,3] [,4] [1,] 1 4 7 10 [2,] 2 5 8 11 [3,] 3 6 9 12 Machen Sie sich mit Funktion und Wirkung der einzelnen Parameter vertraut durch Eingabe von > matrix(1:-10,ncol=4,byrow=T) > matrix(1:3,nrow=3,ncol=4) > matrix(1:13,ncol=4,byrow=T) Die Dimensionen einer Matrix erhalten Sie mit dim(). > dim(m) [1] 3 4 Mit length() erhalten Sie im Gegensatz dazu die Anzahl der Elemente: 24 > length(m) [1] 12 Die Indizierung von Matrizen mit numerischen Indizes verläuft analog zur Indizierung von Vektoren. Werden dabei entweder Zeilen- oder Spaltenindizes nicht explizit angegeben, so werden jeweils alle Zeilen oder Spalten ausgewählt. > m[1,2] [1] 4 > m[,1:2] [,1] [,2] [1,] 1 4 [2,] 2 5 [3,] 3 6 > m[c(1,3),c(2,4)] [,1] [,2] [1,] 4 10 [2,] 6 12 Gibt man anstatt eines durch Komma getrennten Indexpaares aus Zeilen- und Spaltennummern nur einen einzelnen Index oder Indexvektor an, so wird die Matrix (wie auch bei dem length()-Befehl) R-intern wie ein Vektor behandelt, der durch Zusammenfassung der einzelnen Spalten entsteht, und die entsprechenden Komponenten dieses Vektors ausgegeben. > m[9] [1] 9 > m[m>5] [1] 6 7 8 9 10 11 12 Mit den Befehlen row() und col() erhalten Sie ganzzahlige Matrizen, die die Zeilen- bzw. Spaltennummern aller Elemente enthalten. > row(m) [,1] [,2] [,3] [,4] [1,] 1 1 1 1 [2,] 2 2 2 2 [3,] 3 3 3 3 Diese sind besonders nützlich, wenn man (Neben-)Diagonalen oder nicht-quadratische Teile einer Matrix auswählen will, wie das folgende Beispiel zeigt: 25 c Math. Stochastik, Uni Freiburg ° > m[row(m)>=col(m)] <- 0 > m [,1] [,2] [,3] [,4] [1,] 0 4 7 10 [2,] 0 0 8 11 [3,] 0 0 0 12 Sie können die Zeilen oder Spalten einer Matrix auch mit Namen versehen, entweder durch Angabe des Parameters dimnames im matrix()-Befehl oder nachträglich mit dimnames(). Die Namen sind dabei in einer zweikomponentigen Liste (siehe Abschnitt 2.6) zu übergeben, deren Elemente Vektoren mit den Zeilen- und Spaltennamen sind. Die Längen der beiden Vektoren müssen mit den Dimensionen der Matrix übereinstimmen. > dimnames(m) <- list(c("I" ,"II","III"),c("a","b","c","d")) > m a b c d I 0 4 7 10 II 0 0 8 11 III 0 0 0 12 > m[,"d"] I II III 10 11 12 > dimnames(m) [[1]] [1] "I" "II" "III" [[2]] [1] "a" "b" "c" "d" Bemerkung 3.1. Auch bei Matrizen müssen alle Elemente vom gleichen Datentyp sein! Werden einzelnen Matrixelementen Werte verschiedenen Typs zugewiesen, findet wie bei Vektoren eine Typumwandlung nach den in Lektion 2, Abschnitt 2.5.3 beschriebenen Regeln statt. 3.2 Matrizen und arithmetische Operationen Wie im Fall von Vektoren werden arithmetische Operationen bei Matrizen komponentenweise ausgeführt (sofern die Matrizen in ihren Dimensionen übereinstimmen). > M <- matrix(1:9,3,3) > M1 <- matrix(-9:-1,3,3) > M1+M > M1*M 26 c Math. Stochastik, Uni Freiburg ° Sie können zu einer Matrix auch ein Skalar oder einen Vektor addieren bzw. multiplizieren. Ein Skalar wird einfach zu jedem Element der Matrix dazu addiert bzw. multipliziert, die Vektoraddition erfolgt wie die Multiplikation spaltenweise. > (-1)*M1 > v <- c(9,8,7) > v*M1 > M1+9 > M1+v Hierbei sollte darauf geachtet werden, dass die Länge des Vektors mit der Zeilenzahl der Matrix übereinstimmt, ansonsten kann es zu unerwarteten Ergebnissen kommen, wie das folgende Beispiel zeigt: > M2 <- matrix(1:12,3,4) > M2 [,1] [,2] [,3] [,4] [1,] 1 4 7 10 [2,] 2 5 8 11 [3,] 3 6 9 12 > M2 + 1:4 [,1] [,2] [,3] [,4] [1,] 2 8 10 12 [2,] 4 6 12 14 [3,] 6 8 10 16 Da im letzten Fall der Vektor länger ist als die Spalten der Matrix, wird dessen letztes Element zur ersten Komponente der zweiten Spalte der Matrix addiert, dann wieder das erste Element des Vektors zur zweiten Komponente der zweiten Spalte usw. Mit dem Befehl t() können Sie Matrizen transponieren. > M > t(M) Beachten Sie, dass mit c() erzeugte Vektoren keine Spalten- oder Zeilenvektoren sind, wie im folgenden deutlich wird: > v [1] 9 8 7 > dim(v) NULL > t(v) 27 c Math. Stochastik, Uni Freiburg ° [,1] [,2] [,3] [1,] 9 8 7 > as.matrix(v) [,1] [1,] 9 [2,] 8 [3,] 7 Bei Anwendung der Funktion t() wird also der Vektor v intern erst in eine 3 × 1-Matrix umgewandelt und diese dann anschließend transponiert; t(v) entspricht somit dem Befehl t(as.matrix(v)). Auch bei der Addition/Multiplikation von Vektoren und Matrizen finden R-intern entsprechende Umwandlungen statt. 3.3 Das Matrizenprodukt Mit der Verknüpfung %*% erhalten Sie das übliche Matrizenprodukt. Passen die Dimensionen der Matrizen nicht zusammen, gibt R eine Fehlermeldung aus. > M1 <- matrix(1:9,3,3) > M2 <- matrix(c(1,1,1,0,1,1,0,0,1),3,3,byrow=T) > M2 %*% M1 > M2 %*% v > M2 %*% t(v) Fehler in M2 %*% t(v) : nicht passende Argumente > v %*% M2 > t(v) %*% M2 > M3 <- matrix(1:8,2,4) > M4 <- matrix(c(1,1,1,0,0,0),3,2) > M4 %*% M3 > M3 %*% M1 Fehler in M3 %*% M1 : nicht passende Argumente Die Funktion crossprod(x,y) berechnet t(x) %*% y; sind x und y Vektoren gleicher Länge, so entspricht dies dem Skalarprodukt. Beachten Sie, dass crossprod() stets eine Matrix zurückgibt. > crossprod(M4,M) > crossprod(1:3,2:4) [,1] [1,] 20 > as.vector(crossprod(1:3,2:4)) [1] 20 28 c Math. Stochastik, Uni Freiburg ° 3.4 Block- und Diagonalmatrizen Mit der Funktion cbind() (c steht für column“) können Sie Vektoren gleicher Länge beziehungsweise ” Matrizen mit der gleichen Anzahl von Zeilen der Reihe nach zu einer neuen Matrix zusammenfügen. Das zeilenorientierte Gegenstück zu cbind() heißt rbind() (r steht für row“). ” > cbind(c(1,2,3),c(6,5,4),matrix(1,3,2)) > rbind(matrix(1,2,3),matrix(2,2,3)) > cbind(rbind(matrix(1,2,3),matrix(2,2,3)),rbind(matrix(3,2,3),matrix(4,2,3))) Mit diag() können Sie Diagonalmatrizen erzeugen, die Diagonale quadratischer Matrizen verändern und auch die Elemente der Diagonale auswählen. Wird als Argument ein Vektor der Länge n übergeben, so erzeugt der Befehl eine n × n-Diagonalmatrix, deren Diagonalelemente durch die Komponenten des Vektors gegeben sind. Ist das Argument eine Matrix, gibt die Funktion einen Vektor mit den Diagonalenelementen zurück. > diag(1:5) > M <- matrix(1:16,4,4) > diag(M) > diag(diag(M)) > M-diag(diag(M)) > diag(M) <- c(0,0,0,0) > M 3.5 Die Funktion apply() Mit der Funktion apply() können Sie Funktionen auf Zeilen und Spalten von Matrizen anwenden, deren Syntax gegeben ist durch apply(X,MARGIN,FUN,...) Hierbei ist X die Matrix, auf die die Funktion FUN angewendet werden soll. Für FUN kann jede beliebige R-Funktion durch Angabe des Funktionsnamens (ohne nachfolgende Klammern) gewählt werden; zusätzliche oder optionale Argumente für diese können anstelle von ... angegeben werden. Mit MARGIN wird festgelegt, ob die Funktion zeilenweise (MARGIN=1) oder spaltenweise (MARGIN=2) wirken soll. Nachfolgend einige Beispiele: > M <- matrix(1:9,3,3) > apply(M,1,sum) > apply(M,2,sum) > apply(M,2,crossprod,y=c(2,4,6)) > A <- matrix(c(1,8,2,6,5,4,7,3,9,0,-1,11),3,4) 29 c Math. Stochastik, Uni Freiburg ° > apply(A,1,diff) > t(apply(A,1,diff)) > apply(A,2,diff) 3.6 Lineare Gleichungssysteme Mit der Funktion solve(A,b) können Sie lineare Gleichungssysteme (sofern lösbar) der Form Ax = b lösen. > A <- matrix(c(1,1,0,0,1,1,1,0,1),3,3) > A [,1] [,2] [,3] [1,] 1 0 1 [2,] 1 1 0 [3,] 0 1 1 > solve(A,c(1,0,0)) [1] 0.5 -0.5 0.5 > solve(A,c(0,0,1)) [1] -0.5 0.5 0.5 Mit solve(A) können Sie die Matrix A invertieren, sofern möglich. > A <- matrix(c(2,1,7,5,6,8,9,3,4),3) > A [,1] [,2] [,3] [1,] 2 5 9 [2,] 1 6 3 [3,] 7 8 4 > solve(A) [,1] [1,] [,2] [,3] 0.00000000 -0.23529412 0.17647059 [2,] -0.07692308 [3,] 0.24886878 -0.01357466 0.15384615 -0.08597285 -0.03167421 > A %*% solve(A) [,1] [,2] [,3] [1,] 1 1.110223e-16 5.551115e-17 [2,] 0 1.000000e+00 2.775558e-17 [3,] 0 -1.110223e-16 1.000000e+00 > B <- matrix(c(1,1,0,1,0,1,0,1,-1),3,3) > solve(B) Fehler in solve.default(B) : 30 c Math. Stochastik, Uni Freiburg ° Lapackroutine dgesv: System ist genau singulär > solve(B,c(2,1,1)) Fehler in drop(.Call("La_dgesv", a, as.matrix(b), tol, PACKAGE = "base")) : Lapackroutine dgesv: System ist genau singulär Die Determinante einer quadratischen Matrix erhalten Sie mit dem Befehl det(). > det(A) [1] -221 > det(B) [1] 0 > det(matrix(1:8,2)) Fehler in determinant.matrix(x, logarithm = TRUE, ...) : ’x’ muss eine quadratische Matrix sein 3.7 Eigenwerte und -Vektoren Die Eigenwerte und -Vektoren einer (quadratischen!) Matrix M erhalten Sie durch den Befehl eigen(M,only.values=FALSE) Die Funktion gibt eine Liste mit den Eigenwerten und zugehörigen Vektoren aus; die Eigenvektoren sind dabei auf Länge 1 normiert und werden in einer Matrix zusammengefasst. Die j-te Spalte der Matrix entspricht dabei dem Eigenvektor zur j-ten Komponente des Vektors mit den Eigenwerten. Sind ausschließlich die Eigenwerte von Interesse, so kann man die Berechnung der Eigenvektoren unterdrücken, indem man statt der Defaulteinstellung only.values=T setzt. > M <- matrix(c(1,2,2,1),2,byrow=T) > eigen(M) $values: [1] 3 -1 $vectors: [,1] [,2] [1,] 0.7071068 -0.7071068 [2,] 0.7071068 0.7071068 Die Matrix M muss nicht notwendigerweise symmetrisch sein. Fehlt diese Eigenschaft, können allerdings komplexe Werte auftreten. > M <- matrix(c(1,-3,1,1),2,byrow=T) > eigen(M) 31 c Math. Stochastik, Uni Freiburg ° $values: [1] 1+1.732051i 1-1.732051i $vectors: [,1] [,2] [1,] -0.8660254+0.0i -0.8660254+0.0i [2,] 0.0000000+0.5i 0.0000000-0.5i > eigen(M,only.values=T) $values: [1] 1+1.732051i 1-1.732051i $vectors: NULL 32 c Math. Stochastik, Uni Freiburg ° 3.8 Übungen Aufgabe 3.1. Schreiben Sie eine Funktion, die die i-te Zeile und die j-te Spalte einer m × n-Matrix löscht und die so erhaltene (m − 1) × (n − 1)-Matrix ausgibt. Die Funktion soll eine Fehlermeldung ausgeben, falls i ∈ / {1, . . . , m} oder j ∈ / {1, . . . , n}. Aufgabe 3.2. Schreiben Sie zwei Funktionen myrow() und mycol(), die die in R enthaltenen Funktionen row() und col() nachbilden. Falls keine Matrix als Argument vorgegeben wird, soll eine Fehlermeldung ausgegeben werden. Aufgabe 3.3. Schreiben Sie eine Funktion, die überprüft, ob die als Argument eingegebene Matrix quadratisch und symmetrisch ist und in diesem Fall den logischen Wert TRUE zurückgibt, ansonsten den Wert FALSE. Aufgabe 3.4. Schreiben Sie eine Funktion, die den Elementen beider Nebendiagonalen einer quadratischen Matrix den Wert 0 zuweist (überprüfen Sie zuvor, ob die eingegebene Matrix quadratisch ist). Aufgabe 3.5. Schreiben Sie eine Funktion, die überprüft, ob drei einzugebende Vektoren x, y, z ∈ R3 linear unabhängig sind, und entsprechend den Wert TRUE oder FALSE zurückgibt. Aufgabe 3.6. Schreiben Sie eine Funktion, die für quadratische Matrizen die Differenzen der Maxima der i-ten Zeile und der Minima der i-ten Spalte berechnet und in einem Vektor ausgibt. Aufgabe 3.7. Schreiben Sie eine Funktion, die die Wurzel einer quadratischen, symmetrischen und positiv semidefiniten Matrix A berechnet, d.h. diejenige Matrix B, für die gilt B · B = A. Hinweis: Verwenden Sie den aus LA bekannten Satz über die Hauptachsentransformation: Satz: Zu jeder symmetrischen, reellen n × n-Matrix A existiert eine orthogonale n × n-Matrix O (d.h. O> · O = I mit der n × n-Einheitsmatrix I), so dass gilt λ1 0 0 λ2 O> · A · O = . .. .. . 0 ... ... 0 ... .. . 0 .. . 0 λn , wobei λ1 , . . . , λn die Eigenwerte (mit Vielfachheit) von A sind. Testen Sie Ihre geschriebene R-Funktion anhand der Matrix 2 −1 0 −1 2 −1 0 −1 2 33 c Math. Stochastik, Uni Freiburg ° Lektion 4: Mehrdimensionale Plots 4.1 Arrays R-Objekte dieser Klasse kann man sich als verallgemeinerte Matrizen mit beliebig vielen Dimensionen vorstellen. Vektoren kann man auch als arrays der Dimension 1, Matrizen als arrays der Dimension 2 auffassen. Erzeugen kann man sie durch den Befehl array(), dessen allgemeine Syntax lautet array(data,dim=length(data),dimnames=NULL) Dabei ist data wie beim matrix()-Befehl ein Vektor mit den in das array einzuordnenden Elementen und dim ein Vektor natürlicher Zahlen, der die maximalen Indizes (Anzahl der Komponenten) für jede Dimension angibt. Mit dimnames kann man Namen an die Einträge vergeben; dazu muss dieses Argument eine Liste der Länge length(dim) sein, deren i-te Komponente ein Vektor der Länge dim[i] mit den entsprechenden Namen für die Dimension i ist. Das folgende Beispiel zeigt die Wirkung dieses Befehls bei der Erzeugung eines 3-dimensionalen arrays: > M <- array(1:24,dim=c(2,3,4)) > M ,,1 [,1] [,2] [,3] [1,] 1 3 5 [2,] 2 4 6 ,, 2 [,1] [,2] [,3] [1,] 7 9 11 [2,] 8 10 12 ,,3 [,1] [,2] [,3] [1,] 13 15 17 [2,] 14 16 18 ,,4 [,1] [,2] [,3] [1,] 19 21 23 [2,] 20 22 24 34 Alle Elemente eines arrays müssen denselben Datentyp haben, was gegebenenfalls durch Typumwandlungen nach den von Vektoren und Matrizen bekannten Regeln erzwungen wird. Die Indizierung von arrays verläuft analog zu der von Matrizen, wie die folgenden Beispiele verdeutlichen: > M[1:2,c(1,3),4] [,1] [,2] [1,] 19 23 [2,] 20 24 > M[,2,] [,1] [,2] [,3] [,4] [1,] 3 9 15 21 [2,] 4 10 16 22 > M[1,,3] [1] 13 15 17 4.2 Die Funktion outer() Mit dieser Funktion erhalten Sie verallgemeinerte äußere Produkte, die sehr wichtig und flexibel zur Auswertung von Funktionen auf Zahlenmengen (Gittern) sind. Die allgemeine Syntax lautet outer(X,Y,FUN="*",...) Dabei sind X und Y arrays (oder speziell auch Vektoren) und FUN eine beliebige, auch selbstdefinierte R-Funktion, die zumindest zwei numerische Argumente benötigt (weitere können wie bei apply() anstelle der Punkte ... übergeben werden) und einen einzelnen Wert zurückgibt. Als Default ist die Multiplikation voreingestellt. Die Funktion outer() gibt als Wert ein array der Dimension c(dim(X),dim(Y)) zurück, dessen [i,j,...,a,b,...]-tes Element dem Funktionswert FUN(X[i,j,...],Y[a,b,...]) entspricht. Im weiteren Verlauf dieser Lektion werden wir ausschließlich Vektoren für X und Y einsetzen und als Ergebnis eine Matrix erhalten. > outer(1:3,1:3) [,1] [,2] [,3] [1,] 1 2 3 [2,] 2 4 6 [3,] 3 6 9 Beachten Sie den Unterschied zur üblichen Multiplikation in R: > (1:3)*(1:3) [1] 1 4 9 35 c Math. Stochastik, Uni Freiburg ° Beim Einsetzen anderer Funktionen für FUN ist darauf zu achten, dass diese zwei Argumente erwarten und auf diesen elementweise operieren, d.h. FUN(x,y) = c(FUN(x[1],y[1]),...,FUN(x[n],y[n])), ansonsten erhält man (durch die interne Verarbeitung von outer() bedingt) mitunter unerwartete Ergebnisse oder Fehlermeldungen wie im folgenden Beispiel: > outer(1:5,1:5,max) Fehler in dim(robj) <- c(dX, dY) : Dimensionen [Produkt 25] passen nicht zur Länge des Objektes [1] Dies liegt daran, dass die Funktion max() nicht elementweise operiert wie oben gefordert, sondern das Maximum aller x[i] und y[j] zurückgibt. Um an der Stelle [i,j] den Wert max(x[i],y[j]) zu erhalten, muss man eine komponentenweise arbeitende Maximumsfunktion einsetzen: > max.neu <- function(x,y){(x+y+abs(x-y))/2} > outer(1:5,1:5,max.neu) [,1] [,2] [,3] [,4] [,5] [1,] 1 2 3 4 5 [2,] 2 2 3 4 5 [3,] 3 3 3 4 5 [4,] 4 4 4 4 5 [5,] 5 5 5 5 5 Die Funktion outer() eignet sich somit insbesondere zur Auswertung von (elementweise operierenden) Funktionen zweier Veränderlicher auf einem rechteckigen Gitter, was wir uns im Folgenden bei der Erstellung von 3-D-Plots zunutze machen werden. 4.3 3-D-Plots Die Funktion persp() ermöglicht das Zeichnen perspektivischer Plots. Die allgemeine Syntax und wichtigsten Optionen dieses Befehls lauten persp(x,y,z,xlab=NULL,ylab=NULL,zlab=NULL,main=NULL,theta=0,phi=15,r=sqrt(3)) x und y sind dabei die Koordinatenvektoren für das Gitter in der x-y-Ebene, über dem die Höhen abgetragen werden; die Elemente beider Vektoren müssen jeweils aufsteigend geordnet sein. z ist eine length(x)×length(y)-Matrix, deren Komponente z[i,j] die dem Gitterpunkt (x[i],y[j]) zugeordnete Höhe (Funktionswert) angibt. xlab, ylab und zlab legen die Achsenbeschriftungen fest, mit main kann eine Bildüberschrift hinzugefügt werden. Mit den Parametern theta, phi und r legt man fest, aus welcher Richtung die Fläche der Funktionswerte betrachtet wird; theta und phi geben die Blickwinkel an, aus denen ein fiktiver Beobachter im Abstand r vom Zentrum des Plots auf diesen blickt. theta ist dabei der Winkel in der x-y-Ebene, bezogen auf die y-Achse (mit theta=0 (Default) blickt man genau in positive y-Richtung, mit theta=90 in negative x -Richtung), phi der Winkel bezüglich der z -Achse (mit phi=0 schaut man parallel zur 36 c Math. Stochastik, Uni Freiburg ° x-y-Ebene, also senkrecht zur z -Achse, mit phi=90 parallel zur z -Achse in negative z -Richtung). Wir zeichnen nun ein hyperbolisches Paraboloid, das durch die Gleichung z = y 2 − x2 gegeben ist. > x <- seq(-4,4,0.1) > persp(x,x,outer(x,x,function(x,y){y^2-x^2})) Wie Sie sehen, sind die Defaulteinstellungen für die Achsenbeschriftungen nicht sehr informativ und sollten der besseren Übersicht halber angepasst werden. Durch Setzung des optionalen Parameters ticktype="detailed" erhalten Sie Achsenmarkierungen (ticks) und zugehörige Größenangaben wie von 2-D-Plots gewohnt: > persp(x,x,outer(x,x,function(x,y){y^2-x^2}),xlab="x",ylab="y",zlab="z", ticktype="detailed") Das Zeichnen des umgebenden Kastens kann durch Setzung von box=F im persp()-Befehl unterdrückt werden – allerdings werden dann auch keine Achsen und Achsenbeschriftungen mehr eingezeichnet. Ändern Sie nun einmal die Blickrichtung. Mit der folgenden Einstellung schauen Sie von halb rechts oben auf die Fläche: > persp(x,x,outer(x,x,function(x,y){y^2-x^2}),xlab="x",ylab="y",zlab="z",theta=45, phi=45,ticktype="detailed") Experimentieren Sie auch mit anderen Werten für theta, phi und r! Um die Fläche etwas bunter zu gestalten, können Sie die Parameter col und border benutzen. Mit border legt man die Farbe der Gitterlinien fest, mit col die Farbe(n) der von ihnen eingeschlossenen Flächenstücke. Im nachfolgenden Beispiel sollen diese blau und das Gitter rot erscheinen: > persp(x,x,outer(x,x,function(x,y){y^2-x^2}),xlab="x",ylab="y",zlab="z",theta=45, phi=45,ticktype="detailed",col="blue",border="red") Als abschließendes Beispiel plotten wir zweidimensionale Sinuswellen. > x <- pi*(0:100)/25 > persp(x,x,outer(x,x,function(u,v){sin(u)*sin(v)}),xlab="x",ylab="y",zlab="z", theta=45,phi=30,r=5) Durch Verlängerung der z -Achse ergibt sich ein weniger verzerrtes Bild: > persp(x,x,outer(x,x,function(u,v){sin(u)*sin(v)}),zlim=c(-2,2),xlab="x",ylab="y", zlab="z",theta=45,phi=30,r=5) Alternativ kann man die z -Achse auch mit dem Streckungsfaktor expand entsprechend stauchen: > persp(x,x,outer(x,x,function(u,v){sin(u)*sin(v)}),expand=0.5,xlab="x",ylab="y", zlab="z",theta=45,phi=30,r=5) Weitere Einstellungen und Parameter des persp()-Befehls finden Sie auf der zugehörigen Hilfsseite. 37 c Math. Stochastik, Uni Freiburg ° 4.4 Contour-Plots Mit dem Befehl contour() können Sie einen sogenannten Contour-Plot erstellen, d.h. Höhenlinien einer Fläche zeichnen. Die allgemeine Syntax mit den wichtigsten Optionen ist contour(x,y,z,nlevels=10,levels) Dabei sind x, y und z Vektoren bzw. Matrizen wie im persp()-Befehl. Mit nlevels kann man die (ungefähre) Anzahl von äquidistanten Intervallen festlegen, für die jeweils eine Höhenlinie in der Intervallmitte gezeichnet wird (das ungefähr“ ist durch die R-interne Verarbeitung bedingt), mit levels ” alternativ direkt die gewünschten Niveaus. Wir veranschaulichen dies anhand des Sinuswellenbildes. > contour(x,x,outer(x,x,function(u,v){sin(u)*sin(v)}),nlevels=10) > contour(x,x,outer(x,x,function(u,v){sin(u)*sin(v)}),levels=seq(-0.75,0.75,0.25)) Die Größe der Beschriftung der Höhenlinien kann mit dem optionalen Parameter labcex (label character extension) eingestellt werden, Farbe, Form und Strichdicke der Höhenlinien können mit col, lty (line type) und lwd (line width) eigenen Wünschen angepasst werden. Über weitere Möglichkeiten informiert Sie die entsprechende Hilfsseite. 4.5 Image-Plots Mit der Funktion image() können Sie die Größe der z -Werte durch unterschiedliche Färbung bzw. Grautöne kennzeichnen. Solche Plots werden in R als Image-Plots bezeichnet. Im Wesentlichen benötigt die Funktion als Argumente nur x, y und z wie zuvor. > image(x,x,outer(x,x,function(u,v){sin(u)*sin(v)})) Eine Färbung in Grautönen können Sie mit Hilfe der Funktion gray() erhalten, die als einziges Argument einen Vektor mit Elementen aus dem Intervall [0, 1] benötigt, mit dem Anzahl und Intensität der verschiedenen Grautöne festgelegt werden (0 entspricht schwarz, 1 weiß). > image(x,x,outer(x,x,function(u,v){sin(u)*sin(v)}),col=gray((0:32)/32)) 4.6 Die zweidimensionale Normalverteilung Wir wollen die bisher kennengelernten Befehle nutzen, um uns die zweidimensionale Normalverteilung grafisch zu veranschaulichen. Dazu benötigen wir zunächst ein paar Begriffe und Definitionen. Definition 4.1. 1. Sei X = (X1 , . . . , Xn )> ein n-dimensionaler Zufallsvektor (d.h. seine Komponenten sind 1-dim. Zufallsvariablen), so definieren wir dessen Erwartungswert ¡ ¢> E[X] := E[X1 ], . . . , E[Xn ] als Vektor der komponentenweisen Erwartungswerte. 38 c Math. Stochastik, Uni Freiburg ° 2. Die üblicherweise mit Σ bezeichnete Kovarianzmatrix eines n-dimensionalen Zufallsvektors X ist definiert als h i Σ := Σ(X) := E (X − E[X]) · (X − E[X])> Var(X1 ) Cov(X1 , X2 ) . . . Cov(X2 , X1 ) Var(X2 ) ... = . . .. .. .. . Cov(Xn , X1 ) Cov(Xn , X2 ) . . . Cov(X1 , Xn ) Cov(X2 , Xn ) .. . . Var(Xn ) Diese ist offensichtlich symmetrisch und positiv-semidefinit. Ist A eine k × n-Matrix, so folgt h i E[A · X] = A · E[X], E X > · A> = E[X]> · A> , Cov(A · X) = Σ(AX) = A · Σ(X) · A> . Definition 4.2. Ein Zufallsvektor X = (X1 , . . . , Xn )> ist n-dimensional normalverteilt, falls für alle a ∈ Rn gilt, dass die Linearkombination a> X = a1 X1 + · · · + an Xn ( 1-dim.) normalverteilt ist. Ist die Kovarianzmatrix Σ eines n-dim. normalverteilten Zufallsvektors X positiv definit, dann ergibt sich die Dichte der Verteilung von X zu dN (µ,Σ) (x) = · ¸ 1 > −1 exp − (x − µ) · Σ · (x − µ) , 2 det(Σ) 1 np (2π) 2 dabei ist x ∈ Rn und µ = E[X]. Im nun näher betrachteten Fall n = 2 ist à ! à ! σ12 σ12 σ12 ρσ1 σ2 Σ= = σ21 σ22 ρσ1 σ2 σ22 mit σi2 = Var(Xi ), i = 1, 2, σ12 = σ21 = Cov(X1 , X2 ) und ρ = Corr(X1 , X2 ). Für ρ = 0 erhält man ¸ ¸ · · 1 1 (x1 − µ1 )2 (x2 − µ2 )2 √ , dN (µ,Σ) (x) = √ exp − exp − 2σ12 2σ22 2πσ1 2πσ2 d.h. gemeinsam normalverteilte Zufallsvariablen, die paarweise unkorreliert sind, sind sogar unabhängig (dies gilt analog auch für n > 2). Da der Erwartungswertvektor µ lediglich eine Verschiebung des Maximums der Dichte bewirkt, setzen wir nachfolgend stets o.B.d.A. µ = (0, 0)> . Wir schreiben zunächst ein Programm zur Berechnung der zweidimensionalen Dichte. Verwenden Sie dazu den Funktionseditor! d2norm <- function(x,y,s1,s2,rho,mu=c(0,0)){ if(s1<=0 || s2<=0 || abs(rho)>=1) {return("Parameter s1, s2 <= 0 oder abs(rho) >= 1")} M <- cbind(x-mu[1],y-mu[2]) Sinv <- solve(matrix(c(s1^2,rho*s1*s2,rho*s1*s2,s2^2),ncol=2)) detS <- s1^2*s2^2*(1-rho^2) mult <- function(x,S){as.vector(x %*% S %*% x)} exponent <- -0.5*apply(M,1,mult,Sinv) return(1/(2*pi*sqrt(detS))*exp(exponent))} 39 c Math. Stochastik, Uni Freiburg ° Einzugeben sind die Vektoren mit den x - und y-Koordinaten sowie die Werte für σ1 , σ2 und ρ; dabei ist σ1 , σ2 > 0 und −1 < ρ < 1 zu beachten. Wir plotten nun die Dichte für σ1 = σ2 = 1 und ρ = 0. > x <- seq(-3,3,0.1) > persp(x,x,outer(x,x,d2norm,s1=1,s2=1,rho=0),xlab="x",ylab="y",zlab="d2norm(x,y)", theta=40,phi=10,ticktype="detailed") Wie sehen die Höhenlinien aus? > contour(x,x,outer(x,x,d2norm,s1=1,s2=1,rho=0),levels=seq(0.02,0.1,0.01)) Beachten Sie dabei, dass diese aufgrund des gewählten quadratischen Definitionsbereichs evtl. durch einen rechteckigen Plot verzerrt sind, falls Sie das Grafikfenster in der Größe verändert haben. Einen unverzerrten Plot erhalten Sie durch Setzung des grafischen Parameters pty (plot type) auf "s" (square). Dazu ist der in der nächsten Lektion genauer vorgestellte par()-Befehl zu verwenden. > par(pty="s") > contour(x,x,outer(x,x,d2norm,s1=1,s2=1,rho=0),levels=seq(0.02,0.1,0.01)) Die Veränderung des Parameters pty hat auch Auswirkungen auf die 3-D-Plots. Mit > par(pty="m") (maximale Plotgröße) setzten Sie diesen wieder auf seinen Defaultwert zurück. Als nächstes wählen wir σ1 = 2 und plotten erneut Dichte und Höhenlinien. Wie verändern sich letztere? > x <- seq(-4,4,0.1) > persp(x,x,outer(x,x,d2norm,s1=2,s2=1,rho=0),xlab="x",ylab="y", zlab="d2norm(x,y)",theta=40,phi=10,ticktype="detailed") > par(pty="s") > contour(x,x,outer(x,x,d2norm,s1=2,s2=1,rho=0),levels=seq(0.02,0.1,0.01)) > par(pty="m") Zusätzlich setzen wir nun noch ρ = 0.8. Welche Auswirkungen hat dies auf die Dichte und die Höhenlinien? > persp(x,x,outer(x,x,d2norm,s1=2,s2=1,rho=0.8),xlab="x",ylab="y", zlab="d2norm(x,y)",theta=40,phi=10,ticktype="detailed") > par(pty="s") > contour(x,x,outer(x,x,d2norm,s1=2,s2=1,rho=0.8),levels=seq(0.02,0.1,0.01)) Probieren Sie es auch einmal mit anderen Werten für σ2 und negativem ρ! Schauen Sie sich dabei die Dichten auch aus anderen Blickwinkeln an. Viel Spaß beim Experimentieren! 40 c Math. Stochastik, Uni Freiburg ° 4.7 Übungen Aufgabe 4.1. Zeichnen Sie die obere Hälfte des durch die Gleichung 1 + z 2 = x2 + y 2 gegebenen Rotationshyperboloids und betrachten Sie sie aus verschiedenen Blickrichtungen. Zusatz: Vermeiden Sie die Ausgabe der Warnmeldung, die sich bei Erzeugung von NaNs ergibt. Aufgabe 4.2. Die Funktion f : R2 → R sei definiert durch ( 4xy, 0 ≤ x, y ≤ 1 f (x, y) = . 0, sonst Zeigen Sie, dass f eine 2-dimensionale Dichte ist. Plotten Sie die obige Funktion mit einem geeigneten Definitionsbereich. Aufgabe 4.3. Die Dichte der zweidimensionalen Cauchy-Verteilung ist gegeben durch dC(δ,µ) (x) = i− 3 δ h 2 , (x − µ)> · (x − µ) + δ 2 2π x, µ ∈ R2 , δ > 0. Schreiben Sie eine zur Verwendung mit outer() geeignete Funktion d2cauchy(), die die obige Dichte berechnet, und plotten Sie diese. Setzen Sie dabei für δ und µ geeignete Defaultwerte. Betrachten Sie auch den Einfluss von δ durch Vergleich der Höhenlinien für verschiedene Werte dieses Parameters. 41 c Math. Stochastik, Uni Freiburg ° Lektion 5: Stetige und diskrete Verteilungen 5.1 Stetige Verteilungen in R In Lektion 1 (Abschnitt 1.6) haben Sie bereits die Log-Normalverteilung als ein Beispiel der in R implementierten Verteilungen kennengelernt. Die neben dieser ebenfalls verfügbaren stetigen Verteilungen sind in der untenstehenden Tabelle aufgeführt. Unter stetigen Verteilungen“ sollen dabei solche ver” standen werden, die eine stetige Verteilungsfunktion besitzen. Name Verteilung auf Parameter Defaults beta Beta [0, 1] shape1, shape2, ncp -, - , 0 cauchy Cauchy R location, scale 0, 1 chisq Chi-quadrat R+ df, ncp -, 0 exp Exponential R+ rate 1 f F R+ df1, df2, ncp -, -, 0 gamma Gamma R+ shape, rate -, 1 lnorm Log-normal R+ meanlog, sdlog 0, 1 logis Logistische R location, scale 0, 1 norm Normal R mean, sd 0, 1 t Studentsche t R df, ncp -, 0 unif Gleichverteilung [a, b] min, max 0, 1 weibull Weibull R+ shape, scale -, 1 Tabelle 5.2: Stetige Verteilungen in R Den Verteilungs-Kurznamen ist jeweils einer der Buchstaben d, p, q oder r voranzustellen. Mit d (density) erhalten Sie, wie schon in der ersten Lektion gesehen, den Wert der Dichte an der (den) Stelle(n) x, mit p (probability) den Wert (die Werte) der zugehörigen Verteilungsfunktion. Mit q (quantile) am Anfang erhalten Sie die entsprechende Quantilfunktion, und mit r (random) können Sie eine Stichprobe unabhängiger, identisch nach der jeweils gewählten Verteilung verteilter Zufallsvariablen erzeugen. 42 Dabei gilt Definition 5.1. Bei einer stetigen Verteilung V mit streng monoton wachsender Verteilungsfunktion FV ist die zugehörige Quantilfunktion qV die Inverse von FV , d.h. qV : (0, 1) → R, qV (p) := FV−1 (p). ¡ ¢ Für ein p-Quantil qV (p) von V gilt somit stets p = FV qV (p) . Bei vielen Verteilungen besitzen die zugehörigen Parameter Defaultwerte (vgl. dazu auch Lektion 1, Abschnitt 1.7). Beispielsweise ist bei Normalverteilungen stets der Mittelwert (mean) 0 und die Varianz 1 voreingestellt. So erhält man z.B. für Dichte und Verteilungsfunktion der Standard-Normalverteilung an den Stellen ±1.6448536 die Werte > dnorm(c(-1.6448536,1.6448536)) [1] 0.1031356 0.1031356 > pnorm(c(-1.6448536,1.6448536)) [1] 0.05 0.95 Da die Quantilfunktion gerade die Umkehrfunktion der Verteilungsfunktion ist, sind die 5%- und 95%-Quantile gegeben durch > qnorm(c(0.05,0.95)) [1] -1.644854 1.644854 Bei Änderung der Varianz von Normalverteilungen muss man in R etwas Vorsicht walten lassen: Der zweite Verteilungsparameter sd (standard deviation) beschreibt nicht die Varianz, sondern deren Wurzel! Die Wahrscheinlichkeit, dass eine normalverteilte Zufallsvariable mit Mittelwert 1 und Varianz 4 innerhalb des Intervalls [0, 3] liegt, berechnet sich daher in R wie folgt: > pnorm(3,mean=1,sd=2)-pnorm(0,mean=1,sd=2) [1] 0.5328072 Zum Vergleich von Verteilungs- und Quantilfunktion der Standard-Normalverteilung zeichnen wir beide in einem gemeinsamen Plot. Dabei definieren wir, um Verzerrungen zu vermeiden, mithilfe des bereits bekannten par-Befehls einen quadratischen Plotbereich. > par(pty="s") > x <- seq(-2,2,0.01) > plot(x,pnorm(x),type="l",col="blue",ylim=c(-2,2),xlab="x",ylab="", main="Verteilungs- und Quantilfuntion von N(0,1)") > lines(seq(0.02,0.98,0.01),qnorm(seq(0.02,0.98,0.01)),col="red") Zur Verdeutlichung fügen wir noch die Asymptoten beider Kurven hinzu. Zum Zeichnen solcher Geraden kann man den Befehl abline() einsetzen. Mit abline(a,b) wird eine Gerade der Form y = a + bx gezeichnet, mit abline(h=y) eine zur x-Achse parallele (horizontale) Gerade durch y und 43 c Math. Stochastik, Uni Freiburg ° mit abline(v=x) analog eine Parallele zur y-Achse (Vertikale) durch x. Der unten verwendete optionale Parameter lty (line type) im abline()-Befehl bewirkt, dass die Linie gestrichelt wird. Dazu sind in R fünf Strichmuster vordefiniert, die durch die Zahlen 2, . . . , 6 ausgewählt werden können (mit der Defaulteinstellung lty=1 erhält man eine normale durchgezogene Linie, mit lty=0 wird die Zeichnung der Linie unterdrückt; lty kann auch innerhalb von lines() verwendet werden). > abline(h=c(0,1),lty=3) > abline(v=c(0,1),lty=3) Im Gegensatz zu den Normal- sind die Exponentialverteilungen nur auf R+ definiert. Der Verteilungsparameter λ hat in R den Namen rate und den Defaultwert 1. Einen Plot mit Dichte und Verteilungsfunktion der Exp(2)-Verteilung kann man wie folgt erhalten: > x <- seq(0,2.5,0.01) > plot(x,dexp(x,rate=2),type="l",ylim=c(0,2.5),xlab="x",ylab="",col="orange", main="Dichte und Verteilungsfunktion von Exp(2)") > lines(x,pexp(x,rate=2),col="blue") Auch hier kann man wiederum Verteilungs- und Quantilfunktion grafisch miteinander vergleichen. Da die Verteilungsfunktion für x > 2 nur noch sehr langsam wächst, sollte der Argumentvektor für die Quantilfunktion etwas feiner unterteilt werden, damit beide Graphen in etwa die gleiche Länge haben. > plot(x,pexp(x,rate=2),type="l",ylim=c(0,2.5),xlab="x",ylab="",col="blue", main="Verteilungs- und Quantilfunktion von Exp(2)") > lines(seq(0,0.993,0.001),qexp(seq(0,0.993,0.001),rate=2),col="red") > abline(h=1,v=1,lty=3) > par(pty="m") 5.2 Diskrete Verteilungen in R Neben den im vorherigen Abschnitt vorgestellten stetigen Verteilungen sind in R auch fünf diskrete Verteilungen implementiert, nämlich die Binomialverteilung, die geometrische Verteilung, die Hypergeometrische Verteilung, die Poissonverteilung und die negative Binomial- oder Pascalverteilung. Die jeweiligen Kurznamen und benötigten Parameter können Sie der untenstehenden Tabelle entnehmen. Die Parameter size und prob entsprechen bei der Binomialverteilung n und p, bei der Hypergeometrischen Verteilung ist m die Anzahl der z.B. weißen Kugeln in der Urne, n die Anzahl der schwarzen und k die Anzahl der insgesamt gezogenen Kugeln. Alle oben genannten Parameter haben keine Defaultwerte und müssen beim Aufruf der Verteilungen (durch Voranstellen von d, p, q oder r wie zuvor beschrieben) explizit angegeben werden. Für die Wahrscheinlichkeit, aus einer Urne mit 4 weißen und 6 schwarzen Kugeln bei drei Ziehungen ohne Zurücklegen insgesamt höchstens eine weiße zu ziehen, erhält man beispielsweise 44 c Math. Stochastik, Uni Freiburg ° Name Verteilung Parameter Defaults binom Binomial size, prob -, - geom Geometrische prob - hyper Hypergeometrische m, n, k -, -, - pois Poisson lambda - nbinom negative Binomial size, prob -, - Tabelle 5.3: Diskrete Verteilungen in R > phyper(1,m=4,n=6,k=3) [1] 0.6666667 Bei den Dichte- und Verteilungsfunktionen der geometrischen Verteilung ist als erstes Argument anstelle der Wartezeit n bis zum ersten Erfolg eines Bernoulli-Experiments die Anzahl n − 1 der vorausgehenden Misserfolge anzugeben. Die Wahrscheinlichkeit, dass bei wiederholtem Werfen einer fairen Münze spätestens im sechsten Wurf das erste Mal Kopf“ fällt, erhält man somit durch ” > pgeom(5,prop=0.5) [1] 0.984375 Man beachte, dass alle o.g. Verteilungen nur Masse auf die natürlichen Zahlen (inklusive der Null) legen; bei einer B(10, 0.4)-Verteilung erhält man z.B. > dbinom(seq(0,2,0.5),size=10,prob=0.4) [1] 0.006046618 0.000000000 0.040310784 0.000000000 0.120932352 Warnmeldungen: 1: In dbinom(seq(0, 2, 0.5), 10, 0.4) : non-integer x = 0.500000 2: In dbinom(seq(0, 2, 0.5), 10, 0.4) : non-integer x = 1.500000 Anders ausgedrückt: Bei diskreten Verteilungen berechnen die zugehörigen Dichte“-Funktionen in R ” die Elementarwahrscheinlichkeiten P (X = k), sofern die entsprechende Komponente des Argumentvektors eine natürliche Zahl k ist, und geben ansonsten Null zurück. Diese Besonderheiten sollten auch bei der grafischen Darstellung berücksichtigt werden. Dichten diskreter Verteilungen stellt man üblicherweise als Stabdiagramme dar, bei denen die einzelnen Punkte bzw. Zahlen, denen die betreffende Verteilung echt positive Gewichte zuordnet, durch Stäbe oder Linien markiert werden, deren Längen jeweils den genauen Wert der dort liegenden Wahrscheinlichkeiten angeben. Grafiken dieser Art kann man in R durch Setzen der Plot-Option type="h" (histogram oder high density) erzeugen. Damit lassen sich die Gewichte der B(10, 0.4)-Verteilung wie folgt visualisieren: > plot(0:10,dbinom(0:10,10,0.4),type="h",col="red",xlab="k",ylab="", main="Gewichte der B(10,0.4)-Verteilung") 45 c Math. Stochastik, Uni Freiburg ° Die Verteilungsfunktionen diskreter Verteilungen lassen sich als einfache Summe darstellen und berechnen. Definition 5.2. Sei G eine Verteilung, deren Gewichte g(xk ) = P (X = xk ) auf den Zahlen (xk )k≥0 liegen, für die x0 < x1 < x2 , . . . gelte. Dann ist die zugehörige Verteilungsfunktion FG gegeben durch P P ∗ FG (x) := xk ≤x g(xk ) = kk=0 g(xk ), wobei k ∗ = max{k ≥ 0 | xk ≤ x}. Aus dieser Definition folgt unmittelbar, dass die Verteilungsfunktionen diskreter Verteilungen stückweise konstant sind und ihren Wert nur durch Sprünge ändern. Die Sprunghöhe entspricht dabei jeweils dem an der betreffenden Stelle liegenden Gewicht. Um solche Funktionen in R grafisch darzustellen, greifen wir auf den Befehl segments(x0,y0,x1,y1) zurück, der innerhalb eines bestehenden Plots jeweils die Punkte (x0[i], y0[i]) und (x1[i], y1[i]) durch Geradenstücke miteinander verbindet. Zur Erzeugung eines zunächst leeren Plots, in den man anschließend mit Hilfe von segments() die gewünschte Verteilungsfunktion einzeichnen kann, muss die Option type="n" (nothing) gesetzt werden. Sie bewirkt, dass der plot()-Befehl lediglich anhand der Koordinatenvektoren die Achsen samt Beschriftung generiert, eine (sichtbare) Ausgabe bzw. Markierung der angegebenen Punkte jedoch unterbleibt. Um zu verdeutlichen, dass diese gemäß obiger Definition rechtsseitig stetig ist, fügen wir an den Sprungstellen zusätzlich einzelne Punkte hinzu. > plot(0:12,pbinom(0:12,10,0.4),xlab="x",ylab="",type="n", main="Verteilungsfunktion der B(10,0.4)-Verteilung") > segments(0:11,pbinom(0:11,10,0.4),1:12,pbinom(0:11,10,0.4),col="blue") > points(0:10,pbinom(0:10,10,0.4),pch=20,col="blue") Die Quantilfunktion ist für diskrete Verteilungen wie folgt definiert: Definition 5.3. Sei G eine Verteilung, deren Gewichte g(xk ) = P (X = xk ) auf den Zahlen (xk )k≥0 liegen, für die x0 < x1 < x2 , . . . gelte. Dann ist die zugehörige Quantilfunktion qG : (0, 1) → {xk , k ≥ P 0} gegeben durch qG (p) := inf{x | FG (x) ≥ p} = xl∗ , wobei l∗ = min{l ≥ 0 | lk=0 g(xk ) ≥ p}. Auch die Quantilfunktion diskreter Verteilungen ist somit eine stückweise konstante Sprungfunktion, deren Sprungstellen innerhalb des Einheitsintervalls gerade den (endlich oder abzählbar vielen) verschiedenen Werten der zugehörigen Verteilungsfunktion entsprechen. Beim Plot der Quantilfunktion kann man sich zunutze machen, dass diese auch bei diskreten Verteilungen in gewissem Sinn die Inverse der Verteilungsfunktion ist und man daher das allgemeine Prinzip der Umkehrfunktion – vertausche x und y – anwenden kann. Daher kann man die Quantilfunktion der B(10, 0.4)-Verteilung in R mit den folgenden Befehlen zeichnen (man vergleiche dabei den untenstehenden segments()-Befehl mit dem zum Plotten der Verteilungsfunktion verwendeten!): > plot(c(0,1),c(0,10),type="n",xlab="p",ylab="", main="Quantilfunktion der B(10,0.4)-Verteilung") > segments(c(0,pbinom(0:9,10,0.4)),0:10,pbinom(0:10,10,0.4),0:10,col="red") > points(pbinom(0:9,10,0.4),0:9,pch=20,col="red") 46 c Math. Stochastik, Uni Freiburg ° Während die Binomialverteilungen B(n, p) ihre Gewichte lediglich auf die Zahlen 0, 1, . . . , n verteilen und somit auch deren Quantilfunktionen nur diese Werte annehmen können, belegen geometrische und Poisson-Verteilung ganz N ∪ {0} mit echt positiven Wahrscheinlichkeiten, so dass ihre Quantilfunktionen beliebig große Werte annehmen können. Wie man allerdings am Plot der Verteilungsfunktion der Geom(0.5)-Verteilung erkennen kann, ist diese bei x = 9 schon sehr nahe an der 1 und steigt für größere x nur noch sehr langsam an. > plot(0:13,pgeom(0:13,0.5),type="n",xlab="x",ylab="",ylim=c(0,1), main="Verteilungsfunktion der Geom(0.5)-Verteilung") > segments(0:12,pgeom(0:12,0.5),1:13,pgeom(0:12,0.5),col="blue") > points(0:12,pgeom(0:12,0.5),pch=20,col="blue") Dies impliziert, dass sich die Sprünge der Quantilfunktion bei 1 häufen. Wegen > qgeom(0.999,0.5) [1] 9 genügt es aber, sich auf den Wertebereich von 0 bis 9 zu beschränken, um die Quantilfunktion zumindest über (0, 0.999) (statt (0, 1)) plotten zu können. > plot(c(0,1),c(0,9),type="n",xlab="p",ylab="", main="Quantilfunktion der Geom(0.5)-Verteilung") > segments(c(0,pgeom(0:8,0.5)),0:9,pgeom(0:9,0.5),0:9,col="red") > points(pgeom(0:8,0.5),0:8,pch=20,col="red") 47 c Math. Stochastik, Uni Freiburg ° 5.3 Übungen Aufgabe 5.1. An einer (ausgeschalteten) Lichterkette hängen 50 Glühbirnen von denen fünf defekt sind. Nun werden nacheinander drei Glühbirnen herausgeschraubt und anschließend auf ihre Funktionalität getestet. Wie hoch ist die Wahrscheinlichkeit, dass unter den getesteten Glühbirnen (a) alle defekt sind. (b) genau zwei defekt sind. (c) mindestens eine defekt ist. Aufgabe 5.2. Ergänzen Sie die in Aufgabe 2.6 eingeführte Verteilungsfamilie um eine Funktion qv(p,alpha), die die p-Quantile qV (α); p von V (α) berechnet und ausgibt. Dabei sollte qv() für p 6∈ [0, 1] mit einer Fehlermeldung abbrechen und alpha=1 als Defaultwert vorgegeben werden. Zusatz : Erweitern Sie qv(p,alpha) so, dass auch vektorwertige Argumente p korrekt verarbeitet werden. Aufgabe 5.3. Falls log(X) eine nach N (µ, σ 2 )-verteilte Zufallsvariable ist, so nennt man die Verteilung von X eine Log-Normalverteilung. In R ist deren Quantilfunktion durch den Befehl qlnorm implementiert (siehe Tabelle 5.2). Bestimmen Sie eine Funktion h, die h(qnorm(x,mean=mu,sd=sigma))==qlnorm(x,meanlog=mu,sdlog=sigma) für alle x ∈ (0, 1) erfüllt. Schreiben Sie anschließend mithilfe der Funktion qnorm eine eigene Funktion, die die Quantile der Lognormalverteilung mit Parametern µ und σ 2 berechnet. Dabei soll bei unzulässigen Argumenten eine Fehlermeldung ausgegeben werden. Aufgabe 5.4. Gegeben seien stochastisch unabhängige, auf dem Intervall [0, 1] gleichverteilte Zufallsvariablen U1 , . . . , Un . Es ist bekannt, dass max1≤i≤n Ui Beta-verteilt ist mit Parametern shape1=n, shape2=1. Welche Gestalt müsste die Verteilungsfunktion der Beta-Verteilung mit den Parametern shape1=n, shape2=1 und folglich von max1≤i≤n Ui haben, wenn Sie für x <- seq(0,1,0.01) und beliebige n das Ergebnis des R-Befehls punif(x)^n - pbeta(x,n,1) betrachten? Beweisen Sie Ihre Vermutung. 48 c Math. Stochastik, Uni Freiburg ° Lektion 6: Externe Quellen und visuelle Datenanalyse 6.1 Der Datensatz lottery Wir haben Ihnen die folgenden Datensätze bereitgestellt: lottery.number lottery2.number lottery3.number lottery.payoff lottery2.payoff lottery3.payoff Um diese im Folgenden verwenden zu können, speichern Sie sie bitte in Ihrem R-Arbeitsverzeichnis ab. Der Datensatz lottery besteht aus den beiden Teilen lottery.number und lottery.payoff, die Sie wie folgt in R einlesen können: > lottery.number <- scan("lottery.number") Read 254 items > lottery.payoff <- scan("lottery.payoff") Read 254 items Der Vektor lottery.number enthält die maximal dreistellige Gewinnzahl der New Jersey Pick-It ” Lottery“ vom 22.05.1975 bis 16.03.1976, der Vektor lottery.payoff die zugehörigen Gewinnsummen in Dollar. Eine Beschreibung der New Jersey Pick-It Lottery“ können Sie folgender Passage aus dem ” Buch The New S Language von Becker, Chambers und Wilks (S. 2) entnehmen: The specific data we will look at concerns the New Jersey Pick-It Lottery, a daily numbers game run by the state of New Jersey to aid education and institutions. Our data is for 254 drawings just after the lottery was started, from May, 1975 to March, 1976. Pick-It is a parimutual game, meaning that the winners share a fraction of the money taken in for the particular drawing. Each ticket costs fifty cents and at the time of purchase the player picks a three-digit number ranging from 000 to 999. Half of the money bet during the day is placed in a prize pool (the state takes the other half ) and anyone who picked the winning number shares equally in the pool. Die Datensätze lottery2 und lottery3 sind genauso aufgebaut wie der Datensatz lottery und können analog in R eingelesen werden. Die Verteilung der Daten können Sie sich ansehen mit 49 > plot(lottery.number,lottery.payoff,pch=20) Wir wollen uns im Folgenden mit verschiedenen Möglichkeiten beschäftigen, die Daten grafisch darzustellen. 6.2 Interaktives Identifizieren und Festlegen von Punkten Hierfür stellt R die Befehle identify() und locator() zur Verfügung. Mit identify() können Sie interaktiv Punkte identifizieren. Die allgemeine Syntax und wichtigsten optionalen Argumente lauten identify(x,y=NULL,labels=seq(along=x),n=length(x),plot=TRUE) • x und y sind Vektoren mit Koordinaten von bereits gezeichneten Punkten im aktuellen Plot die in jedem Fall angegeben werden müssen. • labels: Deklariert die Ausgabe des identifizierten Punktes. Wenn Sie einen Punkt (sagen wir, (xi , yi ) im Sample) mit der linken Maustaste anklicken, wird neben dem Punkt standardmäßig sein Index (also i) eingeblendet. Alternativ können Sie als labels auch Vektoren mit Zeichenketten (Buchstaben, Worte) als Einträge übergeben, sofern diese die gleiche Länge wie x und y haben. • plot: Die Ausgabe des Punktes im Graphen kann durch plot=FALSE unterdrückt werden. • n: Gibt die Maximalanzahl der zu identifizierenden Punkte an (per Default werden alle geplottet). Machen Sie sich den obigen Befehl anhand der zuvor erzeugten Grafik mit den lottery-Daten klar: > identify(lottery.number,lottery.payoff) Klicken Sie nun einige Punkte im Plot mit der linken Maustaste an. Beachten Sie dabei, dass während dieses Befehls der Eingabeprompt > verschwindet – Sie können bis zum Beenden von identify() durch Druck auf die mittlere oder rechte Maustaste keine weiteren Befehle eingeben. Anschließend werden die Indizes der identifizierten Punkte (bezüglich der Koordinatenvektoren x und y) in R als Vektor ausgegeben. Um zum Beispiel die Gewinnsumme neben jeden angeklickten Punkt zu schreiben, verwendet man den folgenden Befehl: > identify(lottery.number,lottery.payoff,lottery.payoff) Text an einer beliebigen Stelle in einen Plot können Sie mit dem Befehl text(x,y=NULL,labels=seq(along=x),adj=NULL,cex=1,col=NULL) 50 c Math. Stochastik, Uni Freiburg ° einfügen. Mit dem optionalen Parameter cex (character extension) können Sie die Schriftgröße skalieren, mit adj (adjust) die Position des Textes. Letzterer muss eine Zahl zwischen 0 und 1 oder ein Vektor der Länge zwei sein, dessen Komponenten jeweils zwischen 0 und 1 liegen. Mit einer Zahl lässt sich lediglich die Ausrichtung in horizontaler Richtung beeinflussen, bei Eingabe eines Vektors mit der zweiten Komponente zusätzlich in vertikaler Richtung. Mit 0 wird der Text linksbündig (horizontal) bzw. oberhalb (vertikal) gesetzt, bei 0.5 (Defaultwert für beide Richtungen) zentriert und bei 1 rechtsbündig bzw. unterhalb, bei dazwischenliegenden Werten wird die Ausrichtung entsprechend zwischen den genannten Extremen interpoliert. > plot(c(0,5),c(0,5),type="n") > text(1,1,"A",col=3) > text(c(1,2),c(2,2),c("B","C"),col=c(2,4)) > text(c(1,2),c(3,3),c("B","C"),cex=2,adj=0) > text(c(1,2),c(4,4),c("B","C"),cex=2,adj=c(1,0) Interaktives Festlegen von Positionen innerhalb eines Plots gestattet der Befehl locator(n=512,type="n") dabei gibt n die Maximalzahl der durch Anklicken mit der linken Maustaste festzulegenden Punkte innerhalb des Grafik-Fensters an, Sie können jedoch den Befehl vorzeitig durch Drücken der mittleren oder rechten Maustaste beenden. Dabei wird eine Liste mit den Koordinaten der ausgewählten Punkte ausgegeben. Wie bei identify() ist währenddessen keine weitere Befehlseingabe möglich. Mit > locator(1,type="p",pch=20) können Sie beispielsweise einen Punkt an der betreffenden Stelle zeichnen, bei > locator(type="l") werden die angeklickten Punkte durch Linien verbunden. Mit Hilfe dieses Befehls können Sie auch Text an einer frei gewählten Stelle einfügen: > text(locator(1),"Text") Hinweis: Das etwas nervige Beep“ bei jedem Mausklick während des locator()- oder identify()” Befehls können Sie ausschalten mit > options(locatorBell=F) 51 c Math. Stochastik, Uni Freiburg ° 6.3 Balkendiagramme - Teil I Mit der Funktion hist() können Sie Histogramme erstellen. Die allgemeine Befehlssyntax und die wichtigsten Optionen lauten hist(x,breaks,freq,density,col) Die einzelnen Parameter haben die folgende Bedeutung: • x: Der Datenvektor. • breaks (optional): Anzahl der Balken im Diagramm festlegen. Bei Angabe einer natürlichen Zahl wird der Wertebereich von x in entsprechend viele äquidistante Teilintervalle zerlegt. Bei Angabe eines Vektors dienen die Vektorkomponenten als Klassengrenzen. • freq (optional): Der Wert TRUE (Default) bewirkt, dass Balkenhöhen die absoluten Häufigkeiten (frequencies) anzeigen. Mit freq=FALSE zeigen die Balkenhöhen die relativen Häufigkeiten ( pro” babilities“) an. • density (optional): Bei Angabe einer Zahl werden die Balken schraffiert; die Zahl gibt die Liniendichte (lines per inch) an. • col (optional): Die Farbe der Balken. Weitere Argumente und Optionen können Sie den Hilfstexten entnehmen. Hier sind einige einfache Beispiele. > hist(lottery.number,breaks=20) > hist(lottery.number,freq=F,density=10) > hist(lottery.payoff,breaks=seq(0,870,30),col=3) 6.4 Mehrere Plots in einem Graphikfenster Grafische Parameter in R können mit dem par()-Befehl gesetzt werden; die Syntax dazu lautet par(Parameter1=Wert1,Parameter2=Wert2,...) Ohne Argumente gibt par() eine Liste mit allen Parametern und den momentanen Werten aus. Um mehrere Plots in einem Fenster zeichnen zu können, müssen die Parameter mfrow (multiple figures per row) oder mfcol (multiple figures per column) verändert werden. Sie setzen diese mit par(mfrow=c(m,n)) oder par(mfcol=c(m,n)). Wie bei einer m × n-Matrix definieren Sie damit m Zeilen mit jeweils n Plots nebeneinander. Bei Verwendung von mfrow werden die verschiedenen Plots zeilenweise hinzugefügt, bei mfcol spaltenweise. Mit den graphischen Parametern mar (margin) und oma (outer margin) können Sie die Blattaufteilung beeinflussen. Dies geschieht mit par(mar=c(bottom,left,top,right)) bzw. 52 par(oma=c(bottom,left,top,right)) c Math. Stochastik, Uni Freiburg ° Outer Margin margin 3 • Margin for figure 1 • Margin for figure 2 • margin 2 Plot area Plot area for figure 1 for figure 2 margin 4 • • • Plot Figure margin 1 Abbildung 6.1: Zur Definiton und Wirkung der grafischen Parameter mar und oma Für bottom, left, top und right ist jeweils eine Zahl einzusetzen, die die Breite des zugehörigen Randes (Maßstab: eine Textzeile) angibt. Die Defaultwerte sind mar=c(5.1,4.1,4.1,2.1) und oma=c(0,0,0,0) (kein äußerer Rand). Zum besseren Verständnis siehe auch die Abbildung 6.1. Randbeschriftungen können Sie mit dem Befehl mtext(text,side=3,line=0,outer=FALSE,adj=0.5) einfügen; dabei ist text eine Zeichenkette mit dem gewünschten Text, side legt den Rand fest (1 unten, 2 links, 3 oben, 4 rechts), line die Position der Textzeile (von innen nach außen, beginnend bei 0). Mit outer=T wird der Text in den äußeren Rand geschrieben. Um die Histogramme aller drei Lotterie-Auszahlungen untereinander zu plotten und einen oberen Rand für einen gemeinsamen Titel zu haben, setzen wir zunächst > par(mfrow=c(3,1),oma=c(0,0,2,0)) Anschließend plotten wir die drei Histogramme mit einer zusätzlichen Bildbeschriftung. Beachten Sie dabei, dass der mtext()-Befehl nur im jeweils aktiven Plot-Bereich wirkt und erst mit outer=T eine Gesamtüberschrift erzeugt wird. Zum Schluß sollten die Graphik-Parameter wieder auf die Defaultwerte zurückgesetzt werden. > hist(lottery.payoff) > mtext("Plot 1",side=4) > hist(lottery2.payoff) > mtext("Plot 2",side=4) > hist(lottery3.payoff) > mtext("Plot 3",side=4) > mtext("Lotterie-Histogramme",outer=T) > par(mfrow=c(1,1),oma=c(0,0,0,0)) 53 c Math. Stochastik, Uni Freiburg ° 6.5 Balkendiagramme - Teil II Zur Erzeugung von Histogrammen sind im Wesentlichen drei Schritte notwendig: Einteilung der Daten in verschiedene Klassen, Ermitteln der Häufigkeiten für jede Klasse und als letztes die graphische Darstellung der ermittelten Häufigkeiten. Für alle drei Zwecke stellt R auch eigene Befehle bereit, die nachfolgend kurz vorgestellt werden sollen. 6.5.1 Die Funktion cut() Die Funktion cut() dient dazu, kontinuierliche Daten in Klassen aufzuteilen. Sie wird folgendermaßen aufgerufen: cut(x,breaks,labels=NULL) Die Parameter sind: • x: Der Datenvektor. • breaks: Klassen für die Aufteilung der Daten. Jeder Komponente von x wird die entsprechende Klasse (Level) zugewiesen. Werte, die in keiner Klasse liegen, wird als Ergebnis NA zugeordnet. Die Levels werden ebenfalls ausgegeben. Analog zum hist()-Befehl können die Klassen sowohl durch die Angabe einer natürlichen Zahl (äquidistante Zerlegung des Wertebereichs), als auch durch die explizite Angabe eines Grenzenvektors definiert werden. • labels (optional): Eigene Namen der Levels. Die Länge des Vektors muss mit der Anzahl der Klassen übereinstimmen. Mit labels=FALSE wird jedem Element von x seine Klassenzahl zugeordnet. > x <- c(44,48,49,52,49,46,52,38,53,45,49,39,37,33,47) > cut(x,3) [1] (39.7,46.3] (46.3,53] (46.3,53] (46.3,53] (46.3,53] (39.7,46.3] [7] (46.3,53] (33,39.7] (46.3,53] (39.7,46.3] (46.3,53] (33,39.7] [13] (33,39.7] (33,39.7] (46.3,53] Levels: (33,39.7] (39.7,46.3] (46.3,53] > cut(x,c(40,50,60)) [1] (40,50] (40,50] (40,50] (50,60] (40,50] (40,50] (50,60] <NA> (50,60] [10] (40,50] (40,50] <NA> <NA> <NA> (40,50] Levels: (40,50] (50,60] > cut(x,c(30,40,50,60),labels=c("dreissiger","vierziger","fuenfziger")) [1] vierziger vierziger vierziger fuenfziger vierziger vierziger [7] fuenfziger dreissiger fuenfziger vierziger vierziger dreissiger 54 c Math. Stochastik, Uni Freiburg ° [13] dreissiger dreissiger vierziger Levels: dreissiger vierziger fuenfziger > cut(x,c(30,40,50,60),labels=F) [1] 2 2 2 3 2 2 3 1 3 2 2 1 1 1 2 6.5.2 Die Funktion tabulate() Die Funktion tabulate() zählt Häufigkeiten in einem Vektor von natürlichen Zahlen (Vorsicht! Wegen N = 1, 2, . . . werden dabei Einträge mit Wert 0 ignoriert). Die Syntax lautet: tabulate(bin,nbins=max(bin)) Die Argumente sind: • bin: Ein Vektor aus natürlichen Zahlen. • nbins (optional): Der maximale Wert, für den noch Häufigkeiten bestimmt werden sollen. Sinnvollerweise sollte nbins nicht kleiner als max(bin) gewählt werden – dies ist auch der Defaultwert. > tabulate(c(1,2,1,3,4,5,4,1)) [1] 3 1 1 2 1 > tabulate(c(1,2,1,3,4,5,4,1),3) [1] 3 1 1 > tabulate(c(1,2,1,3,4,5,4,1),6) [1] 3 1 1 2 1 0 > tabulate(c(1,2,1,3,4,5,4,0)) [1] 2 1 1 2 1 > tabulate(cut(x,c(30,40,50,60))) [1] 4 8 3 Es ist zu beachten, dass die Funktion tabulate die Häufigkeit aller natürlichen Zahlen von 1 bis nbins ausgibt. > tabulate(c(5,9,3)) [1] 0 0 1 0 1 0 0 0 1 Nicht natürliche Einträge von bin, die positiv und reell sind, werden auf die nächstkleinere natürliche Zahl abgerundet. > tabulate(c(1.3,7.5,6,7)) [1] 1 0 0 0 0 1 2 55 c Math. Stochastik, Uni Freiburg ° 6.5.3 Die Funktion barplot() Mit der Funktion barplot(height) können Sie Balkendiagramme zeichnen. Ihre wichtigsten optionalen Argumente sind width, space und names, mit denen Sie die Balkenbreite, den Abstand zwischen zwei Balken sowie den unter jeden zu schreibenden Text festlegen können. Wenn für height ein Vektor reeller Zahlen eingesetzt wird, besteht der Plot aus einer Reihe rechteckiger Balken, deren Höhe durch die Einträge von height bestimmt wird. Positive Werte werden entsprechend ihrer Höhe nach oben, negative nach unten aufgetragen. Wir verdeutlichen uns die Funktionsweise am folgenden Beispiel. Der Befehl > barplot(rnorm(100)) −2 −1 0 1 2 erzeugt folgendes Balkendiagramm. Abbildung 6.2: Die Funktion barplot(). Nachfolgend ein paar einfache Beispiele, über weitere Möglichkeiten können Sie sich auf der entsprechenden Hilfsseite informieren. > h <- c(1,4,2,10) > w <- c(4,1,1,3) > barplot(h,width=w) > namen <- c("Pos1","Pos2","Pos3","Pos4") 56 c Math. Stochastik, Uni Freiburg ° > barplot(h,width=1,names=namen) > barplot(h,width=1,names=namen,space=0) > barplot(h,width=w,names=namen,density=3) 6.6 Ordnungstatistiken, empirische Verteilungsfunktion und Quantile 6.6.1 Sortieren von Daten Mit dem Befehl sort() können Sie einen beliebigen Vektor in einen geordneten Vektor überführen. Per Default werden dabei fehlende und undefinierte Werte (NA, NaN) entfernt. Mit rev() können Sie die Anordnung eines Vektors umkehren (vgl. Übungsaufgabe 2.2); damit kann das Sortieren in absteigender Reihenfolge erreicht werden. > x <- c(1.2,NA,3.5,1.4,7.9,1.1) > sort(x) [1] 1.1 1.2 1.4 3.5 7.9 > rev(sort(x)) [1] 7.9 3.5 1.4 1.2 1.1 Mit sort.list() erhalten Sie eine Permutation der Indizes, die aus dem unsortierten Vektor den sortierten Vektor erzeugt. Enthält der Datenvektor identische Elemente, so werden diese passend von links nach rechts nummeriert. Der Wert NA wird dabei als +∞ behandelt. > sort.list(x) [1] 6 1 4 3 5 2 > sort.list(c(2,1,3,2,NA,4)) [1] 2 1 4 3 6 5 Mit dem Befehl rank() erhalten Sie die Ränge der Elemente eines Vektors. Sind alle Elemente des Vektors verschieden, so stellen die Ränge eine Permutation der Indizes dar, die aus dem sortierten Vektor den ursprünglichen unsortierten Vektor erzeugt. Enthält der Datenvektor identische Elemente, so werden mittlere Ränge berechnet. Auch hier werden NA und NaN per Default wie +∞ behandelt. > rank(x) [1] 2 6 4 3 5 1 > rank(c(2,1,3,2)) [1] 2.5 1.0 4.0 2.5 6.6.2 Empirische Verteilungsfunktion und Quantile Ist P ein Wahrscheinlichkeitsmaß auf R und F die zugehörige Verteilungsfunktion sowie p ∈ (0, 1), so heißt jede Zahl q mit ¡ ¢ ¡ ¢ P (−∞, q) ≤ p ≤ P (−∞, q] 57 c Math. Stochastik, Uni Freiburg ° p-Quantil von P bzw. F . Im allgemeinen sind Quantile nicht eindeutig bestimmt. Ist F aber stetig und streng monoton wachsend, so ist das p-Quantil von P bzw. F für alle 0 < p < 1 eindeutig bestimmt. Definition 6.1. Seien Beobachtungen x1 , . . . , xn ∈ R gegeben, so ist die zugehörige empirische Verteilungsfunktion Fbn durch n 1 X b Fn (z) = 1(−∞,z] (xi ) n i=1 gegeben. Für p ∈ (0, 1) ist q genau dann p-Quantil von Fbn , falls gilt © ª © ª # i | xi < q ≤ np ≤ # i | xi ≤ q . Der Median entspricht dem 0.5-Quantil. Diesen (bzw. genauer einen) erhalten Sie mit der Funktion median(). Diese übergeht allerdings Komponenten mit dem Wert NA nur bei der Option na.rm=T. > median(x) [1] NA > median(x,na.rm=T) [1] 1.4 > median(1:6) [1] 3.5 Weitere empirische Quantile erhalten Sie mit der Funktion quantile(x,probs=seq(0,1,0.25),na.rm=FALSE) Dabei ist x ein numerischer Vektor, dessen p-Quantile berechnet werden sollen. Die gewünschten pWerte sind durch probs festzulegen; dies muss ein Vektor sein, dessen Elemente alle in [0, 1] liegen. Einträge NA und NaN von x werden wieder nur dann ignoriert, falls die Option na.rm=T gesetzt wird. Hat x die Länge n, so setzt die Funktion bei der Berechnung das i-te Element des geordneten Vektors gleich dem i−1 n−1 -Quantil. Für davon verschiedene Werte p wird zwischen den benachbarten Quantilen linear interpoliert — daher erfüllen die erhaltenen Werte nicht in allen Fällen die o.g. Definition. > quantile(1:10) 0% 25% 50% 75% 100% 1.00 3.25 5.50 7.75 10.00 > 1+9*seq(0,1,0.25) [1] 1.00 3.25 5.50 7.75 10.00 > quantile(c(1,2),0.5) 50% 1.5 > quantile(c(1,2),1/3) 33.33333% 58 c Math. Stochastik, Uni Freiburg ° 1.333333 > quantile(c(1,2,3),1/3) 33.33333% 1.666667 > quantile(x) Error in quantile.default(x) : Missing values and NaN’s not allowed if ‘na.rm’ is FALSE > quantile(x,na.rm=T) 0% 25% 50% 75% 100% 1.1 1.2 1.4 3.5 7.9 Um Quantile zu Fuß“ mit Hilfe der sort()-Funktion bestimmen zu können, benötigen Sie einzelne ” Komponenten des Vektors der sortierten Daten. > length(lottery.payoff) [1] 254 > lots <- sort(lottery.payoff) > quantile(lottery.payoff,c(0.25,0.5, 0.75)) 25% 50% 75% 194.25 270.25 364.00 > 1+ (254-1)*seq(0.25,0.75,0.25) [1] 64.25 127.50 190.75 > c(lots[64],lots[65],lots[127],lots[128],lots[190],lots[191]) [1] 194.0 195.0 268.5 272.0 361.0 365.0 > c(0.75*lots[64]+0.25*lots[65],0.5*(lots[127]+lots[128]),0.25*lots[190]+0.75*lots[191]) [1] 194.25 270.25 364.00 > quantile(1:254) 6.7 0% 25% 50% 75% 100% 1.00 64.25 127.50 190.75 254.00 Q-Q-Plots Eine gute Methode, zwei (empirische) Verteilungen grafisch zu vergleichen sind Q-Q-Plots (QuantileQuantile-Plots). Dabei werden im einfachsten Fall die zwei geordneten Stichproben gegeneinander aufgetragen. Schreiben Sie dazu (unter Verwendung des Funktionseditors) die folgende Funktion: my.qqplot <- function(x,y){ x <- sort(x) y <- sort(y) plot(x,y,pch=20) } Geben Sie danach die folgenden Befehle ein: 59 c Math. Stochastik, Uni Freiburg ° > my.qqplot(lottery.number,lottery2.number) > lines(c(0,1000),c(0,1000)) Mit der R-Funktion qqplot() erhalten Sie ebenfalls einen Q-Q-Plot. > qqplot(lottery.number,lottery2.number) Mit dem Befehl qqplot(x,y) erhalten Sie auch dann einen Q-Q-Plot, falls die Längen von x und y verschieden sind. In diesem Fall wird der längere Vektor durch lineare Interpolation geeignet verändert und auf die gleiche Länge wie der kürzere gebracht. Ist x der längere der beiden Vektoren, so wird die Funktion, die den Zahlen 1, . . . , length(x) die Komponenten des sotierten Vektors sort(x) zuordnet, linear an den Stellen 1+i length(x) − 1 , length(y) − 1 i = 0, 1, . . . , length(y) − 1, interpoliert. Die resultierenden Werte werden dann gegen die Komponenten des sortierten Vektors sort(y) aufgetragen. Die k-te Komponente von sort(x) ist für k = 1, 2, . . . , length(x) ein empirisches k length(x) -Quantil. i length(y) Durch lineare Interpolation werden aus diesen Quantilen Werte an den Stellen für i = 1, 2, . . . , length(y) berechnet und den Komponenten von sort(y) zugeordnet. Ent- sprechendes gilt für den Fall, dass y der längere der beiden Vektoren ist. > qqplot(1:4,1:3) > qqplot(runif(10),runif(5)) > qqplot(runif(100),runif(50)) Die Funktion qqnorm() dient zum Prüfen auf Normalität. Beim Aufruf qqnorm(x) trägt diese Funktion den durch Sortieren aus x hervorgehenden Vektor gegen entsprechende Quantile der StandardNormalverteilung auf. Dabei wird der i-ten Komponente von sort(x) das i−0.5 length(x) -Quantil der Stan- dard-Normalverteilung gegenübergestellt. > r <- rnorm(20) > qqnorm(r) > qp <- qnorm(((1:20)-0.5)/20) > points(qp,sort(r),pch=3) Wir wenden nun diese Funktion auf die Lotterieauszahlungen an. > par(mfrow=c(3,1)) > qqnorm(lottery.payoff) > qqnorm(lottery2.payoff) > qqnorm(lottery3.payoff) > par(mfrow=c(1,1)) Ein Vergleich mit anderen Verteilungen ist auf ähnliche Weise möglich — allerdings stehen hierfür keine vorgefertigten (d.h. qqnorm() entsprechende) R-Funktionen zur Verfügung. 60 c Math. Stochastik, Uni Freiburg ° 6.8 Anhang: Ein- und Ausgabe von Daten Mit dem Befehl scan() können Sie Daten in R einlesen und dort weiter bearbeiten. Erzeugen Sie zunächst mit einem Texteditor (z.B. mit dem R-Gui) eine Datei mit dem Namen daten und dem folgenden Inhalt. Anschließend speichern Sie diese in Ihrem R-Arbeitsverzeichnis ab. 24 45 32 8 36 9 53 29 15 Geben Sie danach in R folgendes ein: > v <- scan("daten") Read 9 Items > v [1] 24 45 32 8 36 9 53 29 15 Um eine Datei aus einem anderen Verzeichnis einzulesen, ist eine komplette Pfadangabe nötig. Unter Windows 7 hat der Befehl z.B. die folgende Gestalt. > scan("C:\\Users\\Stochastik\\Desktop\\beispiel.txt") Geben Sie beim Aufruf von scan() keinen Dateinamen an, so können Sie von der Tastatur aus der Reihe nach die Werte eingeben. Mit [Return] am Anfang einer Zeile beenden Sie die Eingabe. > v <- scan() 1: 50 2: 22 3: 33 4: Read 3 Items > v [1] 50 22 33 Das Gegenstück zu scan() ist der Befehl cat(). Mit diesem können Sie den Inhalt von R-Objekten in eine Textdatei schreiben. Um sie in einem Verzeichnis zu speichern, gibt man wiederum den kompletten Pfad an. > x <- cumprod(1:5) > cat(x,file="fakt.txt") Um einer bereits bestehenden Datei weitere Daten hinzuzufügen, muss die Option append=TRUE angegeben werden. Damit die neuen Daten nicht nahtlos an die alten gereiht werden, sollte man zunächst mit "\n" (newline) einen Zeilenumbruch erzwingen. > x <- prod(1:5)*cumprod(6:10) > cat("\n",x,file="fakt.txt",append=TRUE) 61 c Math. Stochastik, Uni Freiburg ° Mit dem Argument fill kann man die Zeilenbreite innerhalb der Datei begrenzen; bei dessen Angabe werden jeweils nur so viele Daten in eine Zeile geschrieben, dass deren Breite (Zeichenzahl) nicht den Wert von fill übersteigt. > x <- prod(1:10)*cumprod(11:15) > cat("\n",x,file="fakt.txt",append=T,fill=30) Mit dem Befehl source() können Sie Textdateien, die R-Befehle enthalten, in R einlesen und dort ausführen. Erzeugen Sie zunächst mit einem Texteditor ein File mit dem Namen daten.cmd und folgendem Inhalt: w <- c(45,18,67,74) Geben Sie anschließend in R folgendes ein: > source("daten.cmd") > w [1] 45 18 67 74 Erzeugen Sie ebenso eine Datei namens square.func mit dem Inhalt square.func <- function(x){return(x*x)} und führen dann in R die folgenden Befehle aus: > source("square.func") > square.func function(x){return(x*x)} Weitere Details und Parameter zu den o.g. Funktionen können Sie den Online-Hilfsseiten entnehmen. 62 c Math. Stochastik, Uni Freiburg ° 6.9 Übungen Aufgabe 6.1. Was passiert bei 1. > x[sort.list(x)] 2. > x[sort.list(x)][rank(x)]? Aufgabe 6.2. 1. Welches sind im lottery-Datensatz die Gewinnzahlen, die eine Auszahlung von mehr als $500 erbracht haben? 2. Finden Sie die 10 niedrigsten Auszahlungen, einschließlich der Unglücks“-Gewinnziffern. ” Aufgabe 6.3. Wenden Sie die Befehle cut(), tabulate() und barplot() auf die verschiedenen lottery-Datensätze an und erstellen Sie damit zu Fuß ein Histogramm. Aufgabe 6.4. Sei x <- seq(0,1,0.001). Offenbar liefert > mu <- 10 > sigma <- 144 > plot(qnorm(x,mean=0,sd=1), (qnorm(x,mean=mu,sd=sigma) - mu)/sigma, xlab="Quantile von N(0,1)", ylab="Quantile von standardisierter N(mu,sigma)", pch=20, main="") eine Gerade. Warum liefert auch > plot(qnorm(x,mean=0,sd=1), qnorm(x,mean=mu,sd=sigma), xlab="Quantile von N(0,1)", ylab="Quantile von N(mu,sigma)", pch=20, main="") eine Gerade? 63 c Math. Stochastik, Uni Freiburg ° Lektion 7: Simulation von Zufallszahlen 7.1 Simulation von Standardzufallszahlen Die Simulation von Zufallszahlen ist mitnichten nur eine mathematisch-theoretische Spielerei, sondern eine in der Praxis häufig eingesetzte Methode zur Überprüfung von Test- und Prognoseverfahren, durch die auf zeit- und kostenintensive Experimente ganz oder weitgehend verzichtet werden kann. Die dahinterstehende Aufgabe lässt sich allgemein wie folgt formulieren: Erzeuge eine Realisierung von n unabhängigen, identisch nach V verteilten Zufallsgrößen X1 , . . . , Xn . Obwohl die Verteilung V prinzipiell beliebig sein kann, lässt sich die Aufgabe, wie wir in den nachfolgenden Abschnitten sehen werden, in den meisten Fällen auf das Problem der Generierung von Standardzufallszahlen zurückführen, die anschließend geeignet transformiert werden. Als Standardzufallszahlen bezeichnet man dabei eine im Einheitsintervall [0, 1] liegende endliche Folge (ui )1≤i≤n , die (näherungsweise) als Realisierung von n unabhängigen, identisch gleichverteilten Zufallsvariablen Ui ∼ U ([0, 1]), 1 ≤ i ≤ n, angesehen werden kann. Die zur Generierung von Standardzufallszahlen verwendeten Algorithmen sind Kongruenzengeneratoren. Im einfachsten Fall handelt es sich dabei um einen linearen Kongruenzgenerator. Dieser erzeugt eine Folge von Zahlen (yi )i≥1 nach der folgenden Rekursionsformel: yi = (ayi−1 + b) mod m, (7.1) wobei mod m den ganzzahligen Divisionsrest nach Teilen durch m bezeichne (modulo), den man in R mit Hilfe des Operators %% berechnen kann: > c(2,5,7,12) %% 4 [1] 2 1 3 0 > 21 %% c(2,3,4,5,6) [1] 1 0 1 1 3 Der lineare Kongruenzgenerator benötigt neben den fest vorzugebenden Parametern m ∈ {2, 3, 4, . . . } (oft Modul genannt), a ∈ {1, . . . , m − 1} und b ∈ {0, . . . , m − 1} auch einen Startwert (random seed) y0 ∈ {0, . . . , m − 1}, der im Gegensatz zu den anderen Größen beliebig (aus der vorgenannten Menge) 64 gewählt werden kann. Die daraus nach der Rekursion (7.1) berechneten (yi )i≥1 werden als Zufallszahlen verwendet; zum Erhalt einer Folge von Standardzufallszahlen (ui )i≥1 setzt man ui := yi m. Um einen linearen Kongruenzgenerator in R zu programmieren, benötigen wir eine for-Schleife für die Rekursion, die wir im folgenden Unterabschnitt vorstellen. 7.1.1 For- und while- Schleifen In Anwendungen müssen häufiger Werte rekursiv berechnet werden. In solchen Fällen benötigt man Schleifen. Die einfachste Form, in Abhängigkeit von einer Bedingung Anweisungen mehrmals ausführen zu lassen, ist die for-Schleife. Die Syntax der for-Schleife lautet: for (Name in Vektor ) {Ausdruck } Dabei kann Vektor ein Vektor oder eine Liste sein. Für jedes Element des Vektors wird die Variable Name auf den Wert dieses Elements gesetzt und Ausdruck ausgewertet. Dabei ist zu beachten, dass die Variable Name nach Beendigung der Schleife weiterhin existiert und den Wert des letzten Elements von Vektor besitzt, für den die Schleife ausgewertet wurde. Die while-Schleife hat dagegen folgende Syntax. while (Bedingung) {Ausdruck } Zunächst wird Bedingung ausgewertet. Nimmt Bedingung den Wert FALSE an, so wird die Schleife ohne jegliche Aktion abgebrochen. Trifft sie zu, d.h. nimmt Bedingung den Wert TRUE an, so wird der Ausdruck ausgewertet. Anschließend wird die Bedingung wiederum überprüft und je nach Ausgang erfolgt ein Abbruch oder ein weiterer Durchlauf der Schleife. Bemerkung 7.1. Da Schleifen in R langsam sind, sollte auf die Implementierung von Schleifen so weit wie möglich verzichtet werden. Dies gelingt bei for-Schleifen häufig durch vektorwertige Operationen. Damit können wir nun den linearen Kongruenzgenerator in R programmieren. Dafür benutzen wir den Funktionseditor. Zu Testzwecken bauen wir eine Option norm ein, die wahlweise die Ausgabe der standardisierten Zahlen ui (norm=TRUE) oder der yi (norm=FALSE) gestattet. Durch die anfängliche Initialisierung des Vektors y arbeitet die Funktion insbesondere bei großen Argumenten n deutlich schneller. Dabei erzeugt der Befehl numeric(n) einen Vektor der Länge n, der die Werte 0 (Null) enthält. lin.kon <- function(n,m,a,b,y0,norm=TRUE){ if(any(c(a,b,y0)<0) || any(c(a,b,y0)>=m)) {return("Es muss m > a,b,y0 >= 0 sein!")} y <- c(y0,numeric(n)) for(i in 2:(n+1)) {y[i] <- (a*y[i-1]+b) %% m} if(norm) {return(y[-1]/m)} 65 c Math. Stochastik, Uni Freiburg ° else {return(y[-1])} } Da die insgesamt möglichen verschiedenen Divisionsreste von m durch {0, 1, 2, . . . , m − 1} gegeben sind, wird sich die von dem linearen Kongruenzgenerator erzeugte Folge der yi nach spätestens m Schritten wiederholen, d.h. das Programm generiert eine periodische Zahlenfolge mit maximaler Periodenlänge m. Bei ungeschickter Wahl der Parameter kann die tatsächlich erhaltene Periodenlänge allerdings auch deutlich kürzer ausfallen, wie die nachfolgenden Beispiele mit m = 10, a = 3 und b = 2 zeigen: > lin.kon(n=15,m=10,a=3,b=2,y0=8,norm=FALSE) [1] 6 0 2 8 6 0 2 8 6 0 2 8 6 0 2 > lin.kon(n=15,m=10,a=3,b=2,y0=4,norm=FALSE) [1] 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 7.1.2 Optimierungskriterien Der folgende Satz von Donald E. Knuth gibt Bedingungen an die Parameter an, unter denen man stets die größtmögliche Periodenlänge erhält: Satz 7.2 (D. Knuth). Ein linearer Kongruenzgenerator erreicht genau dann für jeden Startwert y0 ∈ {0, 1, . . . , m − 1} die maximal mögliche Periodenlänge m, wenn gilt: a) m und b sind teilerfremd, b) jeder Primfaktor von m teilt a − 1, c) falls m durch 4 teilbar ist, dann auch a − 1. Die Voraussetzungen des Satzes lassen sich leicht erfüllen, wenn man für m eine Zweierpotenz wählt, d.h. m = 2k , für b eine ungerade Zahl kleiner als m und a := 2l + 1 mit l < k setzt. Beispielsweise erhält man durch die Wahl von m = 8, a = 5 und b = 3 für jeden Startwert y0 ∈ {0, 1, . . . , 7} eine Folge (yi )i≥1 mit Periodenlänge 8 (nachfolgend werden y0 = 6 bzw. y0 = 3 verwendet, Skeptiker können aber natürlich auch alle übrigen möglichen Werte ausprobieren): > lin.kon(n=26,m=8,a=5,b=3,y0=6,norm=FALSE) [1] 1 0 3 2 5 4 7 6 1 0 3 2 5 4 7 6 1 0 3 2 5 4 7 6 1 0 > lin.kon(n=26,m=8,a=5,b=3,y0=3,norm=FALSE) [1] 2 5 4 7 6 1 0 3 2 5 4 7 6 1 0 3 2 5 4 7 6 1 0 3 2 5 In der Praxis wählt man m natürlich möglichst groß, um eine ausreichende Periodenlänge und somit eine hinreichend zufällige“ Zahlenfolge zu generieren, aber schon mit verhältnismäßig kleinen Zahlen ” kann man – zumindest auf den ersten Blick – halbwegs brauchbare Resultate erzielen, wie das folgende Beispiel mit m = 210 = 1024, a = 27 + 1 = 129 und b = 17 zeigt: 66 c Math. Stochastik, Uni Freiburg ° > lin.kon(n=12,m=1024,a=129,b=17,y0=241) [1] 0.376953125 0.643554688 0.035156250 0.551757812 0.193359375 0.959960938 [7] 0.851562500 0.868164062 0.009765625 0.276367188 0.667968750 0.184570312 Da unter den in Satz 7.2 genannten Bedingungen die Periodenlänge unabhängig vom Startwert y0 ist, wird dieser üblicherweise selbst zufällig aus der Menge {0, 1, . . . , m − 1} ausgewählt, damit die erhaltenen Zahlenfolgen etwas weniger deterministisch“ sind. Eine genauere Untersuchung kann mit ” dem im nächsten Abschnitt vorgestellten Hilfsmittel durchgeführt werden. 7.2 Q-Q-Plots Q-Q-Plots sind uns schon in Lektion 6, Abschnitt 6.7, beim Vergleich zweier Verteilungen begegnet. Man kann sie aber ebenso nutzen, um grafisch zu überprüfen, ob die Elemente einer Folge von Werten als (unabhängige und identisch verteilte) Realisierungen einer Zufallsgröße mit vorgegebener, stetiger Verteilung V angesehen werden können. In diesem Fall plottet man die sortierte Folge gegen die Quantile von V . Hat man n Werte, so wird jeweils das i-te Element der aufsteigend sortierten Folge ¡ i−0.5 ¢ von V aufgetragen. Wie früher ist dabei die Idee, dass die Verteilung gegen das i−0.5 n -Quantil qV n der Folgenglieder umso besser mit V übereinstimmt, je näher die erhaltenen Punkte an der Winkelhalbierenden y = x liegen, während merkliche Abweichungen von dieser auf Verteilungsunterschiede hindeuten. In R gibt es dazu bereits eine Funktion qqnorm() zur Prüfung auf Vorliegen einer Normalverteilung. Diese Funktion, die wir bereits in Lektion 6 kennengelernt haben, erstellt einen Q-Q-Plot, bei dem die sortierten Folgenglieder den Quantilen der N (0, 1)-Verteilung gegenübergestellt werden. Für andere stetige Verteilungen (bei diskreten macht das Verfahren nur wenig Sinn) stellt R dagegen keine vorgefertigten, d.h. qqnorm() entsprechenden Befehle zur Verfügung. Um die Güte unseres linearen Kongruenzgenerators grafisch zu untersuchen, schreiben wir daher zunächst eine Funktion qqvert(), die einen Vergleich mit beliebigen stetigen Verteilungen ermöglicht. Dabei ist neben x als zweites Argument der Name der zur gewünschten Verteilung gehörigen Quantilfunktion (ohne Klammern () !) anzugeben. Als Default werden dabei die Quantile der Standardnormalverteilung verwendet. Da nicht alle in R implementierten Verteilungen Defaultwerte für sämtliche ihrer Parameter besitzen, muss man diese unter Umständen noch als zusätzliche Argumente übergeben. Wie viele genau benötigt werden, hängt dabei von der gewählten Verteilung bzw. Quantilfunktion ab und kann vorab nicht eindeutig festgelegt werden. Um dieses Problem elegant zu lösen, wird in der untenstehenden Funktion auf das bereits in Lektion 1 (in der Funktion myplot(), siehe Beispiel 1.13) verwendete spezielle Argument ... zurückgegriffen. Zur Erinnerung: Es fungiert als Platzhalter, für den beim späteren Funktionsaufruf beliebige und beliebig viele Argumente eingesetzt werden können, die man auf diese Weise sehr einfach an eine innere Funktion übergeben kann, ohne sie alle einzeln in der äußeren deklarieren zu müssen. Vorsichtshalber sortiert die Funktion auch unschöne Komponenten des Arguments x (NA, NaN, Inf,-Inf) aus, sofern vorhanden. 67 c Math. Stochastik, Uni Freiburg ° qqvert <- function(x,qvert=qnorm,...){ x <- x[!(is.na(x)|is.nan(x)|abs(x)==Inf)] plot(qvert(((1:length(x))-0.5)/length(x),...),sort(x),pch=20, xlab="theoretische Quantile",ylab="empirische Quantile")} Wir erzeugen nun jeweils 50 Werte mit unserem linearen Kongruenzgenerator und vergleichen die erhaltenen Resultate mit der gewünschten Gleichverteilung auf dem Intervall [0, 1]. Mit den Parametern m = 10, a = 3, b = 2 und dem Startwert y0 = 8 erhalten wir, wie bereits zuvor erwähnt, eine sehr schlechte Anpassung: > qqvert(lin.kon(n=50,m=10,a=3,b=2,y0=8),qunif) Mit m = 8, a = 5 und b = 3 wird dagegen, wie gesehen, für jeden Startwert y0 die maximale Periodenlänge 8 ausgeschöpft und damit das Ergebnis etwas besser. > qqvert(lin.kon(n=50,m=8,a=5,b=3,y0=0),qunif) Wählt man die Parameter gemäß den Bedingungen von Satz 7.2 und erhöht dabei den Modul m sukzessive, erhält man zunehmend realistischere Ergebnisse. Für m = 64, a = 17 und b = 3 ergibt sich mit y0 = 5 folgendes Bild: > qqvert(lin.kon(n=50,m=64,a=17,b=3,y0=5),qunif) Da in diesem Fall die Periodenlänge größer als die Anzahl der generierten Werte ist, fallen die qualitativen Defizite der erzeugten Zufalls“zahlen noch nicht besonders auf, sondern treten erst bei längeren ” Folgen zutage. > qqvert(lin.kon(n=250,m=64,a=17,b=3,y0=5),qunif) Hier zeigt sich die Periodizität der Zahlen in der stückweisen Konstanz des Q-Q-Plots, wobei die Anzahl der Konstanzbereiche gerade der Periodenlänge (hier 64) entspricht. Mit den Parametern m = 1024, a = 129 und b = 17 (sowie y0 = 241) erhält man optisch bereits recht überzeugende Resultate. > qqvert(lin.kon(n=250,m=1024,a=129,b=17,y0=241),qunif) Bemerkung 7.3. Einen grundlegenden Mangel linearer Kongruenzgeneratoren kann jedoch auch die fortlaufende Vergrößerung des Moduls m nicht beheben: Zwischen den erzeugten Zahlen bestehen Abhängigkeiten, die man auch anhand der erhaltenen Folgen selbst (ohne genaue Kenntnis des sie erzeugenden Algorithmus) nachweisen kann. Gute und praxistaugliche Zufallszahlengeneratoren setzen daher zusätzlich noch eine Reihe weiterer raffinierter Verfahren und Tricks ein, um diese Abhängigkeiten aufzulösen und die ausgegebenen Folgen so zufällig und gleichverteilt wie möglich“ ” aussehen zu lassen. Im Kern beruhen aber auch sie auf den hier vorgestellten Grundprinzipien: Kongruenzenrechnung, Wahl guter Parameter sowie Abhängigkeit von einem oder mehreren Startwerten. 68 c Math. Stochastik, Uni Freiburg ° Bemerkung 7.4. In R wird per Default einer der zurzeit besten bekannten Zufallszahlengeneratoren eingesetzt, der sog. Mersenne-Twister. Dieser beruht auf 624 Startwerten und hat eine extrem lange Periodenlänge von 219937 −1 ≈ 4.3·106001 . Aufgrund seiner Qualitäten werden wir im Folgenden wieder ihn bzw. die R-Funktion runif() anstelle des eher zur Demonstrationszwecken gedachten lin.kon() verwenden. 7.3 Simulation allgemeiner Zufallsgrößen Hat man das Problem der Simulation auf [0, 1] gleichverteilter Zufallsvariablen gelöst und einen hinreichend guten Zufallszahlengenerator hierfür zur Verfügung, kann man auf dessen Grundlage in der Regel recht einfach Realisierungen von Zufallsgrößen mit beliebigen Verteilungen erhalten, indem man die erzeugten Standardzufallszahlen geeignet transformiert. Ein sehr allgemeiner und vielseitig verwendbarer Ansatz hierzu ist die sogenannte Inversionsmethode, die auf dem folgenden Satz beruht: Satz 7.5. Seien V eine Verteilung auf R mit zugehöriger Verteilungsfunktion FV und Quantilfunktion qV mit qV (p) := inf{x ∈ R | FV (x) ≥ p} sowie (Ui )1≤i≤n unabhängige, identisch nach U ([0, 1]) verteilte Zufallsgrößen. Dann sind Y1 , . . . , Yn mit Yi := qV (Ui ) unabhängig und identisch nach V verteilt. Für jede beliebige Verteilung existiert somit prinzipiell immer zumindest eine passende Transformation der Standardzufallszahlen, nämlich die zugehörige Quantilfunktion. Bemerkung 7.6. Man beachte, dass die o.g. Definition der Quantilfunktion qV mit Definition 5.1 aus Lektion 5 übereinstimmt, sofern die Verteilungsfunktion FV stetig und streng monoton wachsend ist. 7.3.1 Simulation exponentialverteilter Zufallsgrößen Für die Quantilfunktion der Exponetialverteilung gilt, wie man leicht nachrechnen kann, qExp(λ) (p) = . Sind also U1 , . . . , Un unabhängig und identisch gleichverteilt auf [0, 1], sind nach Satz 7.5 − log(1−p) λ i) unabhängige Exp(λ)-verteilte Zufallsgrößen. Damit können wir einen Y1 , . . . , Yn mit Yi := − log(1−U λ Zufallszahlengenerator für die Exponentialverteilung wie folgt programmieren (wobei wir analog R den Defaultwert λ = 1 setzen): my.rexp <- function(n,rate=1){y <- -log(1-runif(n))/rate; return(y)} Bemerkung 7.7. Bei dieser und allen folgenden Funktionsdefinitionen sollte der Funktionsname sicherheitshalber mit my. beginnen, um ein versehentliches Überschreiben der Standard-R-Funktionen zu vermeiden. Die Güte unseres selbstgeschriebenen Zufallszahlengenerators können wir anhand eines Q-Q-Plots überprüfen wie in Abschnitt 7.2 beschrieben. Bei einer geringeren Anzahl simulierter Größen zeigen sich insbesondere am oberen Rand des Plots, der dem rechten Tail der Verteilung entspricht, noch Abweichungen von der idealen Geraden. Bei größeren Samples werden diese jedoch zunehmend geringer. 69 c Math. Stochastik, Uni Freiburg ° > qqvert(my.rexp(50),qexp) > qqvert(my.rexp(500),qexp) > qqvert(my.rexp(50,rate=4),qexp,rate=4) > qqvert(my.rexp(500,rate=4),qexp,rate=4) 7.3.2 Simulation von Bernoulli-Variablen Eine Bernoulli-Variable Xi kann genau zwei verschiedene Werte annehmen, typischerweise 0 und 1. Unter der Annahme p0 = P (Xi = 1) = 1 − P (Xi = 0), p0 ∈ (0, 1), ist gemäß Definition 5.3 aus Lektion 5 die 0 das p-Quantil für alle p ∈ (0, 1 − p0 ] und 1 das pQuantil für alle p ∈ (1 − p0 , 1). Nach Satz 7.5 kann man somit aus unabhängigen, gleichverteilten Zufallsgrößen U1 , . . . , Un ein Sample unabhängiger, identisch verteilter Bernoulli-Variablen X1 , . . . , Xn erhalten, indem man Xi := 1(1−p0 ,1) (Ui ) setzt. Dies lässt sich in R einfach durch eine entsprechende logische Abfrage und anschließende Umwandlung der logischen Werte realisieren. my.rbernoulli <- function(n,p){y <- as.numeric(runif(n) > 1-p); return(y)} Da in diesem Fall die Verteilung diskret ist, können wir die Qualität unseres Bernoulli-Generators nicht anhand eines Q-Q-Plots überprüfen. Ersatzweise können wir untersuchen, ob (bei hinreichend großen Samples) die relative Häufigkeit der 1 in etwa p0 entspricht (Sie werden auf Ihren Rechnern natürlich leicht abweichende Ergebnisse erhalten, da die intern aufgerufene Funktion runif() bei Ihnen jeweils andere Zufallszahlen erzeugt): > sum(my.rbernoulli(50,0.5))/50 [1] 0.46 > sum(my.rbernoulli(500,0.5))/500 [1] 0.504 > sum(my.rbernoulli(50,0.1))/50 [1] 0.06 > sum(my.rbernoulli(500,0.1))/500 [1] 0.098 7.3.3 Simulation eines fairen Würfels Nach dem gleichen Prinzip wie bei den Bernoulli-Variablen lassen sich auch die Ergebnisse eines fairen Würfels simulieren. Da j−1 6 < Ui ≤ j 6 für j = 1, . . . , 6 genau dann, wenn j − 1 < 6Ui ≤ j, kann man die gleichverteilten Größen U1 , . . . , Un wie folgt transformieren, um die gewünschte Verteilung zu bekommen: Xi = d6Ui e, wobei dxe := min{n ∈ Z | n ≥ x} die kleinste ganze Zahl größer oder gleich x bezeichnet, die man in R durch den Befehl ceiling() erhält. my.dice <- function(n){y <- ceiling(6*runif(n)); return(y)} 70 c Math. Stochastik, Uni Freiburg ° Auch hier kann man überprüfen, ob jede der Zahlen im Mittel mit Häufigkeit 1 6 erscheint: > sum(my.dice(100)==2)/100 [1] 0.13 > sum(my.dice(100)==5)/100 [1] 0.18 Einen schnellen Überblick über die absoluten bzw. relativen Häufigkeiten der einzelnen Zahlen kann man sich auch mit der Funktion tabulate() verschaffen: > tabulate(my.dice(100)) [1] 23 9 13 25 17 13 > tabulate(my.dice(100))/100 [1] 0.19 0.18 0.20 0.13 0.14 0.16 7.3.4 Simulation binomialverteilter Zufallsgrößen B(n, p)-verteilte Zufallsvariablen kann man analog dem fairen Würfel dadurch simulieren, dass man das Einheitsintervall entsprechend unterteilt und dann den Ui abhängig davon, in welchem Teilintervall sie jeweils liegen, einen der Werte 0, 1, . . . , n zuordnet. Da die Verteilungsgewichte der B(n, p)-Verteilung jedoch unterschiedliche Größen haben und die zugehörigen n+1 Teilintervalle von [0, 1] somit verschiedene Längen haben müssten, lässt sich dies nicht ganz so einfach wie beim fairen Würfel realisieren und würde mit wachsendem n auch zunehmend komplizierter. Viel einfacher geht es, wenn man sich die Tatsache zunutze macht, dass die Summen unabhängiger Bernoulli-Variablen binomialverteilt sind: Pn i=1 Xi ∼ B(n, p), falls Xi u.i.v. nach B(1, p). Um m unabhängige Realisierungen einer B(n, p)-verteilten Zufallsvariablen zu simulieren, benötigt man somit m · n u.i.v. Bernoulli-Variablen. Diese erzeugen wir wie oben, tragen sie in eine m × nMatrix ein und bilden anschließend die Zeilensummen dadurch, dass wir die Matrix mit einem Vektor (1, 1, . . . , 1)> der Länge n multiplizieren (das geht durch die vektorwertige Arbeitsweise von R bei großen m und n viel schneller, als die Zeilensummen mit apply(M,1,sum) zu berechnen). Die Parameter n und p der Binomialverteilung nennen wir wie in R size und prob. Zur Erzeugung des Vektors (1, 1, . . . , 1)> benutzen wir den Befehl rep(1,size); allgemein bewirkt rep(x,times) die Erzeugung eines Vektors, der durch times-fache Aneinanderreihung des Vektors x entsteht. my.rbinom <- function(n,size,prob){ M <- matrix(runif(n*size),nrow=n,ncol=size) x <- as.vector((M > 1-prob) %*% rep(1,size)) return(x)} Man beachte, dass (M > 1-prob) zunächst eine logische Matrix ist, deren Komponenten durch Anwendung einer arithmetischen Operation (hier das Matrizenprodukt %*%) in die Zahlen 0 und 1 umgewandelt werden (vgl. Lektion 2, Abschnitt 2.2). 71 c Math. Stochastik, Uni Freiburg ° 7.3.5 Simulation poissonverteilter Zufallsgrößen Zwischen poisson- und exponentialverteilten Zufallsvariablen besteht der im Folgenden hilfreiche Zusammenhang. Satz 7.8. Sei (Xi )i≥1 eine Folge unabhängiger, identisch Exp(λ)-verteilter Zufallsgrößen und Sn := Pn i=1 Xi , n ≥ 0, wobei S0 := 0. Dann ist N := max{n ≥ 0 | Sn ≤ 1} poissonerteilt zum Parameter λ, d.h. N ∼ Pois(λ). Aus diesem Grund lassen sich poissonverteilte Zufallsgrößen leicht aus exponentialverteilten Zufallsgrößen bestimmen. Das Erstellen einer Funktion my.rpois(n,lambda), die n unabhängige Realisierungen einer mit Parameter lambda poissonverteilten Zufallsvariablen erzeugt, ist Bestandteil von Übungsaufgabe 7.3. 7.3.6 Simulation normalverteilter Zufallsgrößen Zur Erzeugung normalverteilter Zufallsvariablen ist Satz 7.5 nur bedingt geeignet, da sich die Quantilfunktion von Normalverteilungen nicht exakt, sondern nur näherungsweise berechnen lässt (die Stammfunktion von e− x2 2 lässt sich nicht in geschlossener Form angeben und daher auch nicht die Verteilungs- und Quantilfunktionen von N (µ, σ 2 )). Es gibt jedoch eine recht einfache alternative Transformation, mit der man gleichverteilte in normalverteilte Zufallszahlen umwandeln kann, die als Box-Muller-Methode bekannt ist (siehe auch Aufgabe 2, Übungsblatt 9 zur Vorlesung Stochastik): Satz 7.9 (Box-Muller-Methode). Seien U1 , U2 zwei unabhängige, U ([0, 1])-verteilte Zufallsgrößen und X1 , X2 definiert durch X1 = p −2 log(U1 ) cos(2πU2 ), X2 = p −2 log(U1 ) sin(2πU2 ), dann sind X1 , X2 unabhängig und identisch N (0, 1)-verteilt. Anschaulich gesprochen wird durch die Box-Muller-Methode ein Punkt (U1 , U2 ) des Einheitsquadrates [0, 1]2 in einen Punkt der Ebene R2 mit den Polarkoordinaten (r, ϕ) transformiert, wobei p r = −2 log(U1 ) und ϕ = 2πU2 . Da mit diesem Verfahren nur gerade Anzahlen normalverteilter Zufallszahlen generiert werden können, erzeugt die untenstehende R-Funktion bei ungeraden Werten für n intern zunächst n+1 Zufallsgrößen, ignoriert am Ende jedoch die letzte und gibt nur die ersten n zurück. N (µ, σ 2 )-verteilte Zufallsgrößen Yi lassen sich aus obigem leicht durch die bekannte Transformation Yi = σXi + µ erzeugen. Wie in R üblich geben wir dabei die Defaultwerte µ = 0 und σ = 1 vor. my.rnorm <- function(n,mean=0,sd=1){ m <- n if(m %% 2 != 0) {m <- m+1} x <- rep(0,m) 72 c Math. Stochastik, Uni Freiburg ° u1 <- runif(m/2) u2 <- runif(m/2) x[seq(1,m-1,2)] <- sqrt(-2*log(u1))*cos(2*pi*u2) x[seq(2,m,2)] <- sqrt(-2*log(u1))*sin(2*pi*u2) return(sd*x[-(n+1)]+mean)} Wegen der Stetigkeit der Normalverteilung können wir zur Überprüfung der Güte unseres Zufallszahlengenerators wieder auf Q-Q-Plots zurückgreifen und dabei wahlweise die selbstgeschriebene Funktion qqvert() oder die R-eigene qqnorm() verwenden. Um diese miteinander vergleichen zu können, speichern wir die Ausgabe von my.rnorm() in einem Vektor x und setzen diesen dann nacheinander in beide Funktionen ein. x <- my.rnorm(500) > qqvert(x,qnorm) > qqnorm(x,pch=20) Da die Funktion qqnorm() die übergebenen Werte stets mit einer Standard-Normalverteilung vergleicht, liegen die Punkte des von ihr erstellten Q-Q-Plots nur dann auf bzw. nahe bei der Winkelhalbierenden y = x, wenn das Argument x Realisierungen einer N (0, 1)-verteilten Zufallsgröße beinhaltet. Wird dagegen eine N (µ, σ 2 )-Verteilung simuliert, liegen die geplotteten Punkte näherungsweise auf der Geraden y = σx + µ. x <- my.rnorm(500,mean=1,sd=2) > qqvert(x,qnorm,mean=1,sd=2) > abline(0,1) > qqnorm(x,pch=20) > abline(0,1) > qqnorm(x,pch=20) > abline(1,2) 73 c Math. Stochastik, Uni Freiburg ° 7.4 Übungen Aufgabe 7.1. Schreiben Sie eine Funktion unfair.dice(n,p), die n Ergebnisse eines unfairen Würfels simuliert, bei dem die 6“ mit Wahrscheinlichkeit p und alle übrigen Zahlen jeweils mit Wahrscheinlichkeit 1−p 5 fallen. ” Testen Sie anschließend, ob die simulierten Zahlen mit den gewünschten Häufigkeiten übereinstimmen. Hinweis: Sie können hierzu entweder wie in der Lektion die Quantilfunktion der Verteilung der Augenzahl des unfairen Würfels verwenden oder sich mit der R-Funktion sample() vertraut machen, zu der Sie mit help(sample) genauere Erläuterungen erhalten können. Aufgabe 7.2. Die Dichte der symmetrischen Dreiecks-Verteilung T (a) ist Dichte von T(a) dT (a) (x) = x+a , a2 −a ≤ x ≤ 0, − x−a , a2 0 ≤ x ≤ a, 0, |x| > a, 1/a a > 0. 0 −a 0 a Schreiben Sie eine Funktion rtriangle(n,a), die n unabhängige Realisierungen einer T (a)-verteilten Zufallsgröße erzeugt. Hinweise: Berechnen Sie zunächst die Verteilungs- und Quantilfunktion und benutzen Sie dann Satz 7.5. Falls Sie die Quantilfunktion nicht vektorwertig implementieren können oder wollen, können Sie alternativ auch eine for-Schleife in rtriangle() verwenden. Aufgabe 7.3. Schreiben Sie eine Funktion my.rpois(n,lambda), die n unabhängige Realisierungen einer Pois(λ)verteilten Zufallsgröße mit dem Defaultwert λ = 1 erzeugt. Verwenden Sie dafür den Satz 7.8. Hinweise: Im Prinzip kann eine Poisson-Variable zwar beliebig große Werte annehmen, hier genügt es aber, wenn Sie jeweils nur qpois(0.99,lambda) exponentialverteilte Zufallszahlen zur Erzeugung einer Poisson-Variablen generieren. Tragen Sie diese wie bei der Simulation binomialverteilter Zufallszahlen in eine Matrix ein und ermitteln deren kumulative Zeilensummen mit Hilfe von apply() und cumsum(). Prüfen Sie dann für jede der kumulierten Summen, ab welchem Index der Wert 1 überschritten wird. Aufgabe 7.4. Die Erzeugung von Zufallszahlen ist oftmals so langsam, dass es sich lohnen kann, eine einzige Zufallszahl öfter“ zu verwenden. ” Begründen Sie, warum der Funktionsaufruf von my.cointoss(n,p) einen n-fachen Münzwurf mit Erfolgswahrscheinlichkeit p simuliert (beachten Sie, dass innerhalb der Funktion nur eine einzige Zufallszahl gezogen wird!): 74 c Math. Stochastik, Uni Freiburg ° my.cointoss <- function(n,p){ x <- runif(1) res <- numeric(n) for(i in 1:n){ if(x < p){ res[i] <- 1 x <- x/p } else{ res[i] <- 0 x <- (x-p)/(1-p) } } return(res)} Können Sie erklären, warum beim Aufruf von my.cointoss(n,0.5) für n > 32 die Ergebnisse der letzten n − 32 Münzwürfe immer 1 ergeben? 75 c Math. Stochastik, Uni Freiburg ° Lektion 8: Lineare Modelle 8.1 Theoretische Grundlagen In der Theorie linearer Modelle wird eine Variable durch eine gewichtete Summe von für den jeweiligen Fall bekannten Einflussgrößen modelliert, sogenannter Regressoren oder auch Faktoren (s.u.). Die Bedeutung einer statistischen Theorie für solche Modelle liegt auf der Hand, da hiermit die Relevanz verschiedener Faktoren gefunden und geprüft werden kann. Dies ist etwa für medizinische Anwendungen von erheblicher Bedeutung. In der Tat sind lineare Modelle und ihre Verallgemeinerungen auch aktuell ein sehr wichtiges Thema in der Medizin und in angrenzenden Bereichen. 8.1.1 Lineare Regressionsanalyse Bei der linearen Regression wird versucht, eine abhängige Variable durch eine oder mehrere unabhängige Variablen zu erklären. Im einfachsten Fall – der linearen Einfachregression – wird das Modell y = β0 + β1 x (8.1) gewählt. Dabei ist y die abhängige“ Variable und x die erklärende“ Variable. ” ” Das Ziel der Regressionsanalyse ist nun, bei gegebenen Beobachtungen (xi , yi )i=1,...,n die Parameter β0 und β1 zu bestimmen. Bei der Methode der kleinsten Quadrate wird der Term S(β0 , β1 ) := n X (yi − β0 − β1 xi )2 i=1 minimiert. Die Werte β0 und β1 für die S(β0 , β1 ) ihr Minimum annimmt, nennt man Kleinste-QuadrateSchätzer (KQ-Schätzer). Die Kleinste-Quadrate Schätzer βˆ0 und βˆ1 erhält man durch Nullsetzen der partiellen Ableitungen: n X ∂S (yi − β0 − β1 xi ) = 0 (β0 , β1 ) = −2 ∂β0 ∂S (β0 , β1 ) = −2 ∂β1 i=1 n X xi (yi − β0 − β1 xi ) = 0 i=1 76 Auflösen der Gleichungen liefert: µn P βˆ0 = i=1 ¶µ x2i n P ¶ yi i=1 n P n i=1 n βˆ1 = n P i=1 µ x i yi − n n P i=1 − x2i − i=1 xi i=1 − n P i=1 ¶µ n P i=1 µn P ¶µ n P µ x2i µ xi ¶2 n P i=1 ¶ xi yi = ȳ − βˆ1 x̄ xi n P i=1 ¶2 ¶ n P yi = (xi − x̄)(yi − ȳ) i=1 xi n P . (xi − x̄)2 i=1 Bei der multiplen linearen Regression werden p − 1 erklärende Variablen verwendet. Sie ist gegeben durch y = β0 + β1 x1 + . . . + βp−1 xp−1 . (8.2) Bei gegebenen Daten yi , xi1 , . . . , xi,p−1 , (i = 1, . . . , n) seien X = (xij )1≤i≤n, 0≤j≤p−1 mit xi0 = 1 für 1 ≤ i ≤ n, y = (y1 , . . . , yn )> und β = (β0 , β1 , . . . , βp−1 )> . Die Matrix X wird als Design-Matrix bezeichnet. Dann lässt sich das Modell (8.2) in Matrixschreibweise angeben y = Xβ . (8.3) Mit der Methode der kleinsten Quadrate wird dann der Vektor β bestimmt, der S(β) = n X (yi − β0 − β1 xi1 − . . . − βp−1 xi,p−1 )2 (8.4) i=1 = ky − Xβk2 (8.5) minimiert. Nullsetzen der partiellen Ableitungen nβ̂0 + β̂1 n X ∂S ∂βk für k = 0, . . . , p − 1 ergibt p Gleichungen: xi1 + . . . + β̂p−1 n X i=1 β̂0 n X i=1 xik + β̂1 n X i=1 xi1 xik + . . . + β̂p−1 i=1 xi,p−1 = n X n X yi (für k = 0) yi xik (für k = 1, . . . , p − 1) i=1 xi,p−1 xik = i=1 n X i=1 In Matrixschreibweise lässt sich dies schreiben als X> Xβ̂ = X> y . (8.6) Bemerkung 8.1. Im weiteren gehen wir von p−1 < n aus (ansonsten ist das Modell unterbestimmt). Beachten Sie hierbei, dass die Matrix X nicht quadratisch ist, X> X allerdings schon. Sind die Spalten der Design-Matrix linear unabhängig (besitzt also X maximalen Rang), dann ergibt sich der Kleinste-Quadrate-Schätzer zu β̂ = (X> X)−1 X> y . 77 (8.7) c Math. Stochastik, Uni Freiburg ° 8.2 Lineare Modelle Im Folgenden wollen wir die Situation aus dem vorherigen Abschnitt durch ein stochastisches Modell nachbilden. Definition 8.2. Ein lineares Modell ist durch die Gleichungen yi = β0 + p−1 X βj xij + ei , 1 ≤ i ≤ n. (8.8) j=1 gegeben. Dabei seien e1 , . . . , en identisch verteilte Zufallsvariablen mit E[ei ] = 0, Var(ei ) = σ 2 und Cov(ei , ej ) = 0 für i 6= j. In diesem Modell wird yi durch die erklärenden Variablen“ xi1 , . . . , xi,p−1 und einen Fehler ei be” stimmt. Die Zufallsvariable ei ist eine (etwa durch Messfehler bedingte) zufällige Abweichung von der deterministischen Gesetzmäßigkeit yi = β0 + p−1 X βj xij . j=1 Ziel ist es, durch multiple lineare Regression die unbekannten Koeffizienten β0 , . . . , βp−1 bei bekannten xij und yi zu bestimmen. Wir setzen e = (e1 , . . . , en )> , um das obige Modell in die Matrixschreibweise y = Xβ + e (8.9) zu überführen. Es gilt: E[e] = 0 und Σ(e) = σ 2 I. Der KQ-Schätzer β̂ hat aufgrund der im letzten Abschnitt erhaltenen Gestalt und in Verbindung mit der Gleichung (8.9) die Darstellung β̂ = (X> X)−1 X> y = (X> X)−1 X> (Xβ + e) = β + (X> X)−1 X> e. (8.10) Daraus ergibt sich E[β̂] = β + (X> X)−1 X> E[e] = β, d.h. β̂ ist erwartungstreu für β. Bemerkung 8.3. Unter der zusätzlichen Annahme, dass die Fehler normalverteilt sind, ist β̂ der Maximum Likelihood-Schätzer (ML-Schätzer) für β. 78 c Math. Stochastik, Uni Freiburg ° Weitere statistische Kennzahlen Mit Hilfe von β̂ ergeben sich als vorhergesagte (gefittete) Werte für y: ŷ = Xβ̂. (8.11) Ein geeigneter Schätzer der Varianz σ 2 von ei ist n s2 := 1 X (yi − ŷi )2 . n−p (8.12) i=1 Man kann nämlich zeigen, dass für einen solchen Schätzer E[s2 ] = σ 2 ist, also s2 ein erwartungstreuer Schätzer für σ 2 ist. Als Residuen bezeichnet man die Differenz zwischen theoretischen und gemessenen Werten: ê = y − ŷ. (8.13) Definiert man nun ȳ := n 1 X yj , n j=1 so gilt n 1 X ŷ¯ := ŷj n j=1 n 1 X und ê¯ := êj , n (8.14) j=1 n n n X ¡ ¢2 X ¡ ¢2 X ¡ ¢2 yj − ȳ = ŷj − ŷ¯ + êj − ê¯ . j=1 j=1 j=1 Die Größe R mit n ¡ n ¡ ¢2 P ¢2 P yj − ȳ − êj − ê¯ R2 := j=1 j=1 n ¡ ¢2 P yj − ȳ = s2ŷ s2y (8.15) j=1 heisst Bestimmtheitsmaß und gibt den Anteil der durch das Modell erklärten Streuung an der gesamten Streuung an. Bisweilen wird R auch als empirischer multipler Korrelationskoeffizient“ bezeichnet, da ” R die empirische Korrelation zwischen beobachteten Werten yj und gefitteten Werten ŷj angibt. Sind die Fehler e1 , . . . , en unabhängig und normalverteilt, so ist der Vektor β̂, der nach (8.10) eine ¡ ¢−1 Linearkombination aus den ei darstellt, ebenfalls normalverteilt mit Kovarianzmatrix σ 2 X> X , es gilt also h¡ ¢¡ ¢> i ¡ ¢−1 E β̂ − β β̂ − β = σ 2 X> X . 79 (8.16) c Math. Stochastik, Uni Freiburg ° 8.3 Lineare Modelle in R 8.3.1 Die Funktion lm() Unser erstes Beispiel für ein lineares Modell kommt aus der Physik: Wir wissen, dass in einem Stromkreis die Spannung U , der Widerstand R und die Stromstärke I im folgenden Zusammenhang stehen: U =I ·R (Ohmsches Gesetz) Um den Widerstand R zu bestimmen, misst man typischerweise U und I. Die Messvorgänge sind mit Fehlern behaftet, daher werden mehrere Messungen in verschiedenen Spannungsbereichen durchgeführt. Unser lineares Modell lautet also: yi = β0 + xi · β1 + ei , i = 1, . . . , n (8.17) wobei yi bzw. xi für die Werte der Spannung bzw. der Stromstärke stehen und der Parameter β1 für den Widerstand R steht. Der Parameter β0 fasst die systematische Abweichung (Trend ) der Messfehler zusammen, während die Abweichungen ei den chaotischen Anteil der Messfehler beschreiben. Man spricht in diesem Zusammenhang von weißem Rauschen. Das Schätzen der Parameter in linearen Modellen ist in R bereits implementiert. Die Funktion dazu lautet lm(). Angenommen, wir haben folgende Messwerte: Spannung (in Volt) Strom (in Ampère) 2 0.015 4 0.030 6 0.048 8 0.069 10 0.081 12 0.100 Dann lassen sich β0 und β1 wie folgt schätzen: > y <- 2*(1:6) > x <- c(15,30,48,69,81,100)/1000 > fit <- lm(y~x) > fit Call: lm(formula = y ~ x) Coefficients: (Intercept) x 0.3416 116.4728 Die Funktion lm() gibt das Ergebnis in Form einer Liste aus. In der Ausgabe steht unter “(Intercept)“ der KQ-Schätzer β̂0 und unter “x“ der KQ-Schätzer β̂1 . 80 c Math. Stochastik, Uni Freiburg ° 8.3.2 Der Parameter formula Die Funktion lm() hat nur einen obligatorischen Parameter, der in der online-Hilfe als formula bezeichnet wird. Dieser Parameter spezifiziert das lineare Modell, dessen Parameter durch lm() geschätzt werden sollen. Der Aufruf lm(y ~ x) ist eine abkürzende Schreibweise für lm(formula = y ~ x) und bedeutet exakt den Zusammenhang (8.17). Eine ausführliche Beschreibung der formula-Definitionen findet man in der online-Hilfe. Folgende Beispiele machen dies verständlicher: • Der allgemeine Fall eines linearen Modells (8.8) wird mit folgender Zuweisung definiert: formula = y ~ x1 + x2 + ... + xp Dabei müssen die Vektoren y,x1,...,xp definiert sein und gleiche Dimension haben. • Liegen die Vektoren x1,...,xp in der Form einer Matrix X vor, dann definiert man das Modell (8.8) bzw. (8.9) mit der Zuweisung formula = y ~ X • Ein lineares Modell ohne den Parameter β0 (d.h. mit β0 = 0) definiert man mit der Zuweisung formula = y ~ x1 +...+ xp - 1, bzw. mit formula = y ~ X - 1. In unserem Physik-Beispiel würde dies folgenden Aufruf bedeuten: > lm(y~x-1) Call: lm(formula = y ~ x - 1) Coefficients: x 121.2 Die formula-Funktion kann aber noch mehr als das klassische lineare Modell: • Die sogenannte Interaktion yi = β0 + β1 xi1 xi2 + ei wird mit der Zuweisung formula = y ~ x1 : x2 dargestellt. • Ein linearer Zusammenhang mit zusätzlicher Interaktion yi = β0 + β1 xi1 + β2 xi2 + β3 xi1 xi2 + ei kann mit der Zuweisung 81 c Math. Stochastik, Uni Freiburg ° formula = y ~ x1 + x2 + x1 : x2 oder mit der kürzeren Schreibweise formula = y ~ x1 * x2 dargestellt werden. • Mit der Funktion I() kann man Teile der formula-Zuweisung schützen“. So erhält im Aufruf ” formula = y ~ I(x1 * x2) das “*“ -Zeichen seine ursprüngliche Bedeutung zurück, so dass diese Zuweisung den Zusammenhang yi = β0 + β1 x1i x2i + ei definiert und zu der Zuweisung formula = y ~ x1 : x2 äquivalent ist. 8.3.3 Interna eines lm()-Aufrufs Im folgenden Ausschnitt sehen Sie, wie man mit der Funktion summary() ausführliche Informationen zum Modell erhält, das die Funktion lm() angepasst hat: > summary(fit) Call: lm(formula = y ~ x) Residuals: 1 2 -0.08873 0.16418 3 4 5 6 0.06767 -0.37826 0.22407 0.01108 Coefficients: Estimate Std. Error t value Pr(>|t|) (Intercept) x 0.3416 0.2161 116.4728 3.3641 1.581 0.189 34.622 4.15e-06 *** --Signif. codes: 0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1 Residual standard error: 0.2413 on 4 degrees of freedom 82 c Math. Stochastik, Uni Freiburg ° Multiple R-squared: 0.9967, Adjusted R-squared: 0.9958 F-statistic: p-value: 4.153e-06 1199 on 1 and 4 DF, Nun wollen wir der Funktion lm() auf die Finger schauen und rechnen das Ergebnis selbst nach. Dazu erzeugen wir zunächst die passende Design-Matrix X: > X <- matrix(c(rep(1,6),x),ncol=2) > X [,1] [,2] [1,] 1 0.015 [2,] 1 0.030 [3,] 1 0.048 [4,] 1 0.069 [5,] 1 0.081 [6,] 1 0.100 Die erste Spalte, die nur aus Einsen besteht, wird hier mit Funktion rep() erzeugt. Nun berechnen wir gemäß (8.7) den KQ-Schätzer b (:= (β̂0 , β̂1 )> ): > b <- solve(t(X) %*% X) %*% t(X) %*% y > b [,1] [1,] 0.3416405 [2,] 116.4727614 Rundet man die Komponenten des Vektors b auf 4 Nachkommastellen, erhält man Schätzwerte, wie die Funktion lm() sie ausgegeben hat. Die Residuen ê und deren empirische Standardabweichung gemäß den Gleichungen (8.11), (8.13) und (8.12) erhält man durch: > y.dach <- X %*% b > e.dach <- y-y.dach > se <- sqrt(sum((e.dach^2)/4)) > se [1] 0.241255 Nun zum Anteil der erklärten“ Variabilität. Hierzu verwenden wir die Funktion var(), die bei An” wendung auf einen Vektor x dessen empirische Varianz berechnet. Dabei wird der erwartungstreue Ausdruck (Normierung der Summe mit 1 length(x)−1 ) berechnet und NA zurückgegeben, falls x die Länge 1 hat. > var(y.dach)/var(y) [,1] [1,] 0.9966741 83 c Math. Stochastik, Uni Freiburg ° Diese muss natürlich mit der relativen empirischen Varianz R2 aus Gleichung (8.15) übereinstimmen: > (var(y)-var(e.dach))/var(y) [,1] [1,] 0.9966741 Gleichung (8.16) zufolge erhalten wir für die (geschätzte) Standardabweichung der Schätzer β̂0 und β̂1 : > se.b <- se*sqrt(diag(solve(t(X) %*% X))) > se.b [1] 0.2160707 3.3641480 84 c Math. Stochastik, Uni Freiburg ° 8.4 Übungen Aufgabe 8.1. Schreiben Sie eine Funktion lin.einfach(x,y,pred=FALSE), die für zwei Datenvektoren gleicher Länge x und y einen Plot erstellt, der die Datenpunkte und wahlweise die Regressionsgerade (pred=FALSE) oder die gefitteten Werte (xi , ŷi ) (pred=TRUE) der einfachen Regression enthält. Überprüfen Sie darin zunächst, ob die Längen der beiden übergebenen Vektoren übereinstimmen. Verwenden Sie zur Bestimmung der Parameter β0 und β1 (für die Geradengleichung), die in der Lektion vorgestellte R-Funktion. Aufgabe 8.2. (a) Schreiben Sie eine Funktion f1(n,a,b,sigma), welche Zufallsvariablen X1 , . . . , Xn und Y1 , . . . , Yn simuliert mit X1 . . . , Xn i.i.d.∼ Unif(0, 10) und Yi = a + bXi + ei , i = 1, . . . , n, wobei e1 , . . . , en i.i.d.∼ N (0, σ 2 ) und unabhängig von X1 , . . . , Xn sind. (b) Schreiben Sie eine Funktion f2(x,y), welche aus den simulierten Werten x1 , . . . , xn und y1 , . . . , yn die Parameter a und b schätzt. Welchen Einfluss haben die Parameter n und σ auf die Genauigkeit der Schätzung? 85 c Math. Stochastik, Uni Freiburg ° Lektion 9: Lineare Modelle 2 9.1 Experimente an Datensätzen 9.1.1 Der Datensatz trees R enthält einige Beispieldatensätze, auf die Sie mit dem Befehl data() zugreifen können. Um den trees-Datensatz einzulesen, geben Sie > data(trees) ein. Dieser enthält für 31 Bäume (black cherry trees) Umfang (Girth) und Höhe (Height) der Stämme in Zoll bzw. Fuss sowie deren Holzvolumen (Volume)in Kubikfuss (12 Zoll entsprechen einem Fuss) in jeweils einer Spalte, wie Sie durch Eingabe von > trees sehen können. Anhand dieser Daten soll ein lineares Modell entwickelt werden, das es erlaubt, das Holzvolumen aus Stammumfang und Höhe annähernd zu bestimmen. Mathematische“ Intuition und Erfahrung legen folgendes Modell für die Abhängigkeit des Holzvolu” mens V eines Baumes von Stammumfang u und Stammhöhe h nahe: V = βu2 h. (9.1) Bemerkung 9.1. Bei einem Kreiszylinder wäre β = 0.00055 und bei einem Kreiskegel β = 0.00018, falls alle Einheiten in Fuss umgerechnet werden. > trees.fit <- lm(Volume ~ -1+I(Girth^2*Height),data=trees) > trees.fit Call: lm(formula = Volume ~ -1 + I(Girth^2 * Height), data = trees) Coefficients: I(Girth^2 * Height) 0.002108 86 Die Residuen ê erhalten Sie durch den Befehl residuals(). > sum(residuals(trees.fit)^2) [1] 180.8291 Wieviel bringt ein konstanter Term? > trees.fit2 <- lm(Volume ~ I(Girth^2*Height),trees) > trees.fit2 Call: lm(formula = Volume ~ I(Girth^2 * Height), data = trees) Coefficients: (Intercept) I(Girth^2 * Height) -0.297679 0.002124 > sum(residuals(trees.fit2)^2) [1] 180.2359 Wir werden weiter unten zu diesem Datensatz zurückkehren. 9.1.2 Transformationen der Zielgröße Oftmals erhält man eine bessere Anpassung, wenn man vor Anwendung der Methode der kleinsten Quadrate die Zielgröße“ einer Transformation unterwirft. ” Bei einer Messung zur Bestimmung des Bremsweges eines PKW in Abhängigkeit von seiner Geschwindigkeit ergaben sich folgende Werte: Geschwindigkeit (mph) Bremsweg (ft) 20.5 15.4 20.5 13.3 30.5 33.9 40.5 73.1 48.8 113.0 57.8 142.6 > x <- c(20.5,20.5,30.5,40.5,48.8,57.8) > y <-c(15.4,13.3,33.9,73.1,113.0,142.6) > plot(x,y,pch=20) > mod1 <- lm(y ~ x) > mod2 <- lm(sqrt(y) ~ x) 87 c Math. Stochastik, Uni Freiburg ° Die gefitteten Werte ŷ erhalten Sie durch den Befehl fitted.values(). Wir vergleichen diese grafisch mit den tatsächlich gemessenen Werten bei beiden Modellen: > points(x,fitted.values(mod1),pch=20,col=2) > plot(x,sqrt(y),ylim=c(3,13),pch=20) > points(x,fitted.values(mod2),pch=20,col=3) Ebenso gibt die Summe der Residuenquadrate Aufschluss über die Güte der Anpassung – je kleiner sie ist, desto besser ist der Fit. > sum((y-fitted.values(mod1))^2) [1] 228.8029 > sum((y-fitted.values(mod2)^2)^2) [1] 159.7338 Eine Zusammenfassung der meisten statistisch relevanten Ergebnisse erhalten Sie wie zuvor mit > summary(mod1) > summary(mod2) 9.1.3 Der Datensatz trees - Eine mögliche Transformation Das Modell V = βu2 h lässt sich umschreiben zu log(V ) = β̃0 + 2 log(u) + log(h). Dies legt es nahe, einmal den Ansatz log(V ) = β̃0 + β̃1 log(u) + β̃2 log(h) zu wählen. Wir erhalten > trees.fit.log <- lm(log(Volume) ~ log(Girth)+log(Height),trees) > trees.fit.log Call: lm(formula = log(Volume) ~ log(Girth) + log(Height), data = trees) Coefficients: (Intercept) log(Girth) log(Height) -6.632 1.983 1.117 Für die Summe der Residuenquadrate erhält man dann > sum((trees$Volume-exp(fitted.values(trees.fit.log)))^2) [1] 180.8260 also ein im Vergleich zu Modell (9.1) fast identisches Ergebnis. 88 c Math. Stochastik, Uni Freiburg ° 9.2 Modellwahl am Datensatz trees 9.2.1 Der Datensatz trees - linearer Ansatz In vielen Anwendungsbeispielen fehlt jegliches Vorwissen über die explizite Gestalt des Zusammenhangs zwischen den erklärenden Variablen und der abhängigen Größe. Deshalb vergessen“ wir nun ” unser Vorwissen über Bäume. Wie gut können wir das Volumen der black cherry trees mit einem rein linearen Modell erklären? > trees.fit.lin <- lm(Volume ~ Girth+Height,trees) > summary(trees.fit.lin) > sum(residuals(trees.fit.lin)^2) [1] 421.9214 Wie man sieht, ist der Fit des Modells deutlich schlechter (die Summe der Residuenquadrate ist höher) als in Modellen, die das Wissen über die Form von Baumstämmen berücksichtigen. 9.2.2 Fehleranalyse bei statistischen Modellen Können wir das obige Modell auch ohne Vorinformation sinnvoll erweitern? Hierzu untersuchen wir nun die Residuen êi = yi − ŷi genauer. Diese geben die Abweichungen zwischen Beobachtungen und Modell an. Die Verteilung der Residuen êi hängt ab von der Fehlervarianz σ 2 und den Diagonalelementen der sogenannten hat-Matrix (Prädiktions-Matrix ) V = X(X> X)−1 X> = (vij )1≤i≤n, 1≤j≤n . (9.2) Die Matrix V ist symmetrisch und idempotent, das heißt V> = V und VV = V. (9.3) Nach den Gleichungen (8.7) und (8.11) aus Lektion 8 gilt ŷ = Vy. (9.4) Diese Identität erklärt den Namen hat-Matrix bzw. Prädiktions-Matrix, da sie die beobachteten Werte der Zielgröße auf die vorhergesagte Werte abbildet. Nach (9.4) und (9.2) erhält man die Residuen durch ê = (I − V)y = (I − V)(Xβ + e) = (I − X(X> X)−1 X> )(Xβ + e) = (I − V)e. (9.5) Dabei gilt E[e] = 0 und Σ(e) = σ 2 I. Somit folgt unmittelbar, dass E[ê] = (I − V)E[e] = 0 ist. Außerdem ist die Kovarianzmatrix von ê wegen (9.3) gegeben durch Σ(ê) = σ 2 (I − V)(I − V)> = σ 2 (I − V). 89 (9.6) c Math. Stochastik, Uni Freiburg ° Speziell für die Varianz von êi gilt also: Var(êi ) = (1 − vii )σ 2 , i = 1, . . . , n. Deshalb ist es angebracht, die Residuen folgendermaßen zu standardisieren: êi yi − ŷi ri = √ = √ , s 1 − vii s 1 − vii wobei s2 = n ¢2 1 X¡ yj − ŷj . n−p (9.7) j=1 Die Größe s aus obiger Gleichung erhalten Sie mit dem Befehl summary()$sigma, die Diagonalelemente (vii )1≤i≤n der hat-Matrix durch lm.influence()$hat. > sigma.lin <- summary(trees.fit.lin)$sigma > res.lin <- residuals(trees.fit.lin) > hat.lin <- lm.influence(trees.fit.lin)$hat > sres.lin <- res.lin/(sigma.lin*sqrt(1-hat.lin)) Bemerkung 9.2. Die Residuen êi sind wie die Fehlerterme ei im Mittel Null. Im Gegensatz zu den Fehlertermen ei sind die Residuen êi im Allgemeinen aber nicht unkorreliert (da V keine Diagonalmatrix ist). Unter der Annahme unabhängiger, identisch normalverteilter Fehlerterme gilt wegen (9.5) dann ¡ ¢ ê ∼ N 0, σ 2 (I − V) . Wir plotten nun die standardisierten Residuen gegen die erklärenden Variablen. Bei einem guten Fit sollten die Residuen annähernd unabhängig und identisch verteilt sein und somit die geplotteten Punkte gleichmäßig verstreut liegen, während erkennbare Zusammenhänge und Häufungen darauf hindeuten, dass der deterministische Teil des Modells durch Xβ̂ nur unzureichend erfasst wird. Mit Hilfe des Befehls abline() zeichnen wir eine gestrichelte Horizontale (dies wird durch den optionalen Parameter lty gesetzt) durch den Nullpunkt > par(mfrow=c(2,1),pty="s") > plot(trees$Girth,sres.lin) > abline(h=0,lty=2) > plot(trees$Height,sres.lin) > abline(h=0,lty=2) > par(mfrow=c(1,1)) Der Plot der standardisierten Residuen gegen die erklärende Variable Girth deutet auf einen quadratischen Einfluss dieser Größe hin, während beim zweiten Plot kein augenscheinlicher Zusammenhang erkennbar ist. Auch der Plot der standardisierten Residuen gegen die gefitteten Werte zeigt eine gewisse Systematik, wie unten zu sehen ist. > y.dach.lin <- fitted.values(trees.fit.lin) > plot(y.dach.lin,sres.lin) > abline(h=0,lty=2) 90 c Math. Stochastik, Uni Freiburg ° 9.2.3 Der Datensatz trees - quadratischer Ansatz Aufgrund der obigen Ergebnisse wählen wir nun einen quadratischen Ansatz und untersuchen anschließend wieder die Residuen. > trees.fit.quad <- lm(Volume ~ Girth+I(Girth*Girth)+Height,trees) > summary(trees.fit.quad) > sum(residuals(trees.fit.quad)^2) [1] 186.0118 > sigma.quad <- summary(trees.fit.quad)$sigma > res.quad <- residuals(trees.fit.quad) > hat.quad <- lm.influence(trees.fit.quad)$hat > sres.quad <- res.quad/(sigma.quad*sqrt(1-hat.quad)) > par(mfrow=c(2,1),pty="s") > plot(trees$Girth,sres.quad) > abline(h=0,lty=2) > plot(trees$Height,sres.quad) > abline(h=0,lty=2) > par(mfrow=c(1,1)) > y.dach.quad <- fitted.values(trees.fit.quad) > plot(y.dach.quad,sres.quad) > abline(h=0,lty=2) Unter der Annahme unabhängiger, identisch normalverteilter Fehler e sind die Residuen mehrdimensional normalverteilt mit Erwartungswert Null und Kovarianzmatrix σ 2 (I − V) nach Gleichung (9.6). Die standardisierten Residuen sollten deshalb annähernd standardnormalverteilt sein. Wir überprüfen dies anhand eines QQ-Plots. > qqnorm(sres.quad) > abline(0,1) 9.3 9.3.1 Modellvalidierung am Datensatz trees Einflussreiche Beobachtungen R bietet Ihnen auch eine direkte Möglichkeit, den Einfluss einer einzelnen Beobachtung zu evaluieren. Der Befehl lm.influence() erzeugt eine Liste mit den Komponenten hat, coefficients und sigma (sowie gewichteten Residuen wt.res, die wir aber hier vernachlässigen). Die Komponente sigma gibt die geschätzte Standardabweichung der Fehlerterme an, wenn die i-te Beobachtung gestrichen wird, während coefficients die Änderung der geschätzen Koeffizienten β̂ bei Auslassung der i-ten Beobachtung in Form einer n × p-Matrix ausgibt, wobei n die Anzahl der Beobachtungen ist und p − 1 91 c Math. Stochastik, Uni Freiburg ° die Anzahl der erklärenden Variablen. Die i-ten Zeile der Matrix ist dann β̂ − β̂ −i , wobei β̂ −i der Schätzer für β bei Auslassen der i-ten Beobachtung ist. Dies ermöglicht es Ihnen, die Stabilität“ der ” Schätzungen zu beurteilen. > coeff.quad <- lm.influence(trees.fit.quad)$coefficients > coeff.quad[,1] > coeff.quad[31,] > sigma.quad <- lm.influence(trees.fit.quad)$sigma > sigma.quad 9.3.2 Diagnostik für das Standardmodell Zum Schluss werden die vorgestellten Methoden auf das Modell aus (9.1) angewandt. Die übrigen Modelle für den Datensatz trees können analog untersucht werden. Zuerst berechnen wir die standardisierten Residuen. > sigma <- summary(trees.fit)$sigma > res <- residuals(trees.fit) > hat <- lm.influence(trees.fit)$hat > sres <- res/(sigma *sqrt(1-hat)) Anschließend plotten wir diese wieder gegen die erklärenden Variablen. > par(mfrow=c(2,1)) > plot(trees$Girth,sres) > abline(h=0,lty=2) > plot(trees$Height,sres) > abline(h=0,lty=2) > par(mfrow=c(1,1)) Abschließend erstellen wir einen Plot der standardisierten Residuen gegen die gefitteten Werte > y.dach <- fitted.values(trees.fit) > plot(y.dach,sres) > abline(h=0,lty=2) 92 c Math. Stochastik, Uni Freiburg ° 9.4 Übungen Zum Einlesen formatierter Datensätze nach R sollte der Befehl read.table() anstelle von scan() verwendet werden, da er die (Tabellen-)Struktur der Daten erhält (scan() liest die Daten stets als Vektor ein). Die allgemeine Syntax und die wichtigsten Optionen lauten read.table(file,header=FALSE,sep="",dec = ".",row.names,col.names,skip=0) Unter file ist der komplette Pfad zur Datei (R-Arbeitsverzeichnis), die eingelesen werden soll, anzugeben (z.B.: file="C:/Users/Stochastik/Desktop/york.data"), mit header kann man angeben, ob die erste Zeile der Datei eine Kopfzeile“ ist, also Zeilen- oder Spaltennamen statt Daten enthält. ” Mit sep (separator) teilt man read.table() mit, durch welches Symbol (z.B. ;) die Daten innerhalb der Datei getrennt sind; sep= (Default) zeigt einen (beliebig großen) Leerraum als Trennzeichen an. dec gibt an, wie Dezimalstellen abgetrennt sind. Mit row.names bzw. col.names kann man Zeilenund Spaltennamen für das eingelesene R-Objekt zuweisen, und skip legt fest, wie viele Zeilen der Originaldatei beim Einlesen übersprungen werden sollen (Default: keine). Aufgabe 9.1. Der Datensatz york.data Dieser Datensatz enthält den jährlichen Weizenertrag in einem Gebiet auf der Halbinsel York in Südaustralien. Neben dem Ertrag sind das Jahr und die Niederschlagsmenge für jeden der drei entscheidenden Sommermonate angegeben. Untersuchen Sie diese Daten mit Hilfe der Methode der multiplen Regression, indem Sie den Weizenertrag als Funktion der erklärenden Variablen Regen1, Regen2, Regen3 und Jahr beschreiben. Vergleichen Sie dabei die verwendeten Modelle anhand der Summe der Residuenquadrate und des Bestimmtheitsmaßes R. Untersuchen Sie, ob die erklärende Variable Jahr eine Rolle spielt, was auf eine Verbesserungen im Saatgut und der Anbauweise hindeuten würde. Sie können den Datensatz folgendermaßen einlesen: > york <- read.table("C:/Users/Stochastik/Desktop/york.data", col.names=c("Ertrag","Regen1","Regen2","Regen3","Jahr")) Aufgabe 9.2. Der Datensatz janka.data Die sogenannte Janka“-Härte y ist ein wichtiges Maß für die Qualität australischer Harthölzer. Leider ” ist es sehr umständlich, diese Größe direkt zu bestimmen. Die spezifische Dichte x des Holzes lässt sich allerdings rasch ermitteln. Eine polynomiale Regression der Art y = β0 + β1 x + β2 x2 + · · · + e zwischen diesen beiden Größen scheint aus theoretischen Gründen angemessen zu sein. Der Datensatz janka.data enthält Beobachtungen von 36 Bäumen einer bestimmten Eukalyptusart. Bearbeiten Sie diese Daten mit Methoden der multiplen Regression. Gehen Sie dabei möglichst sparsam mit dem Grad des gefitteten Polynoms um. Sie können den Datensatz wie folgt einlesen: 93 c Math. Stochastik, Uni Freiburg ° > janka <- read.table("C:/Users/Stochastik/Desktop/janka.data", col.names=c("Janka","Dichte")) 94 c Math. Stochastik, Uni Freiburg ° Lektion 10: Testen 10.1 Der exakte Binomial-Test Seien Xi , i = 1, . . . , n unabhängige, identisch verteilte Zufallsvariablen mit P (Xi = 1) = p = 1 − P (Xi = 0). Der exakte Binomial-Test verwendet als Testgröße T (X1 , . . . , Xn ) = Pn i=1 Xi . Diese Statistik ist B(n, p)-verteilt, somit kann man die kritischen Werte des Binomial-Tests numerisch bestimmen. Mit dem exakten Binomial-Test können wir folgende Nullhypothesen testen H0 : p = p 0 gegen H1 : p 6= p0 (Zweiseitiger Test) H0 : p ≤ p 0 gegen H1 : p > p0 (Einseitiger Test) H0 : p ≥ p 0 gegen H1 : p < p0 (Einseitiger Test) Für den Binomialtest stellt R die Funktion binom.test() bereit. Die allgemeine Syntax lautet binom.test(x,n,p=0.5,alternative="two.sided",conf.level=0.95) • Dabei ist für x die Teststatistik (d.h. die Anzahl der Erfolge“) und für n die Länge des Daten” satzes einzusetzen. • Die Default-Einstellung ist p = 0.5, alternative = "two.sided" und conf.level=0.95. In diesem Fall wird die Hypothese (a) H0 : p = 0.5 gegen H1 : p 6= 0.5 zum Konfidenzniveau 0.95 getestet. Als Konfidenzniveau ist hier 1 − α zu wählen, wobei α = 0.05 das Signifikanzniveau ist. • Wird alternative = "greater" eingestellt, so wird der einseitige Test (b) H0 : p ≤ p0 gegen H1 : p > p0 und entsprechend bei alternative = "less" der einseitige Test (c) durchgeführt. Wir wenden diese Funktion im Folgenden auf den lottery-Datensatz an und prüfen, ob die Losnummern < 500 mit Wahrscheinlichkeit 0.5 und die Losnummern < 250 mit Wahrscheinlichkeit 0.25 vorkommen. Den Datensatz können Sie wie in Lektion 6 beschrieben mit dem scan()-Befehl in R einlesen. > lottery.number <- scan("lottery.number") Read 254 items 95 Der Binomialtest: überprüft, ob bestimmte Erfolgswahrscheinlichkeiten einer Binomialverteilung angenommen werden. Statistisches Modell Hypothesen X = (X1 , ..., Xn ) und X1 , ..., Xn unter Pp unabhängig und nach B(1, p) verteilt (a) H0 : p ∈ {p0 } gegen H1 : p ∈ / {p0 } (b) H0 : p ∈ [0, p0 ] gegen H1 : p ∈ (p0 , 1] (c) H0 : p ∈ [p0 , 1] gegen H1 : p ∈ [0, p0 ) n X T (X) = Xi unter Pp verteilt nach B(n, p) Teststatistik i=1 Ablehnungsbereich (a) {0, . . . , k} ∪ {l, . . . , n} mit l = min Pp0 (T (X) ≥ m) ≤ 0≤m≤n α 2 k = max Pp0 (T (X) ≤ m]) ≤ 0≤m≤n α 2 (b) {l, . . . , n} mit l = min Pp0 (T (X) ≥ m) ≤ α 0≤m≤n (c) {0, . . . , k} mit k = max Pp0 (T (X) ≤ m) ≤ α, 0≤m≤n p-Wert, falls für die Teststatistik x beobachtet wird (a) n P j=0 Pp0 (T (X) = j)1{Pp0 (T (X)=j)≤Pp0 (T (X)=x)} (b) Pp0 (T (X) ≥ x) (c) Pp0 (T (X) ≤ x) Abbildung 10.3: Schematische Darstellung des Binomialtests. Bemerkung 10.1. Der Wert der Teststatistik sei T (X) = x, d.h. dass die Teststatistik T , angewendet auf die beobachteten Daten, x ergibt. Der Wert px := sup Pp (T (X) extremer als x) p∈Θ0 heißt p-Wert des Tests für T (X) = x. Die Bedeutung von extrem“ hängt davon ab, was dabei die ” Alternative des Tests ist. In Worten ist der p-Wert die Wahrscheinlichkeit unter H0 , den beobachteten Wert der Teststatistik oder einen in Richtung der Alternative extremeren Wert zu erhalten. Es gibt einen engen Zusammenhang zwischen dem Signifikanzniveau α des Tests und dem p-Wert. Betrachten wir einen Test zum Niveau α, so wird H0 genau dann abgelehnt, wenn für ein T (X) = x0 px0 ≤ α. Die Nullhypothese H0 wird also verworfen, wenn der p-Wert kleiner oder gleich dem vorgegebenem Signifikanzniveau α ist. Ansonsten behält man die Nullhypothese H0 bei. 96 c Math. Stochastik, Uni Freiburg ° Beispiel 10.2. (Losnummern < 500) Wir testen H0 : p = 0.5 gegen H1 : p 6= 0.5 zum Signifikanzniveau α = 0.05. > lot.lt500 <- lottery.number < 500 > n <- length(lot.lt500) > x <- sum(lot.lt500) > binom.test(x,n) Exact binomial test data: x and n number of successes = 142, number of trials = 254, p-value = 0.06861 alternative hypothesis: true probability of success is not equal to 0.5 95 percent confidence interval: 0.4956405 0.6210754 sample estimates: probability of success 0.5590551 Die Nullhypothese wird also zum vorgegebenen Signifikanzniveau α nicht verworfen, da der p-Wert mit 0.06861 größer als α = 0.05 ist. Wir rechnen die erhaltenen Ergebnisse abschließend noch nach: > x/n [1] 0.5590551 > 2*(1-pbinom(141,254,0.5)) [1] 0.06860601 Beispiel 10.3. (Losnummern < 250) Wir testen H0 : p = 0.25 gegen H1 : p 6= 0.25 zum Signifikanzniveau α = 0.05. > lot.lt250 <- lottery.number < 250 > n <- length(lot.lt250) > x <- sum(lot.lt250) 97 c Math. Stochastik, Uni Freiburg ° > binom.test(x,n,p=0.25) Exact binomial test data: x and n number of successes = 73, number of trials = 254, p-value = 0.169 alternative hypothesis: true probability of success is not equal to 0.25 95 percent confidence interval: 0.2325538 0.3472880 sample estimates: probability of success 0.2874016 Da der p-Wert deutlich größer als α = 0.05 ist, wird die Nullhypothese nicht verworfen. Für die empirische Erfolgswahrscheinlichkeit ergibt sich > x/n [1] 0.2874016 Nachrechnen des p-Wertes ergibt: > extrem <- dbinom(0:254,size=254,prob=0.25)<=dbinom(73,size=254,prob=0.25) > sum(dbinom(0:254,size=254,prob=0.25)[extrem]) [1] 0.1690098 Beispiel 10.4. (Anteil der Mädchengeburten) In der Stadt A waren in einem Jahr 15.632 Geburten zu verzeichnen. Dabei waren 7.809 der Säuglinge weiblich. Jemand behauptet, dass im Schnitt mehr Frauen als Männer geboren werden. Stützen die Daten diese These? Wir testen also H0 : p ≤ 0.5 gegen H1 : p > 0.5 zum Signifikanzniveau α = 0.05. > n <- 15632 > x <- 7809 > x/n [1] 0.4995522 > binom.test(x,n,alternative="greater") Exact binomial test 98 c Math. Stochastik, Uni Freiburg ° data: x and n number of successes = 7809, number of trials = 15632, p-value = 0.5477 alternative hypothesis: true probability of success is greater than 0.5 95 percent confidence interval: 0.4929427 1.0000000 sample estimates: probability of success 0.4995522 Auch hier wird die Nullhypothese nicht verworfen, da der p-Wert größer als das vorgebene Signifikanzniveau ist. Nachrechnen ergibt > 1-pbinom(7808,15632,0.5) [1] 0.5477475 10.2 Der χ2 -Anpassungstest 10.2.1 Grundlagen Seien X1 , . . . , Xn unabhängige, identisch verteilte Zufallsvariablen (mit Werten in R oder Rd ). Wir vermuten, dass diesen Zufallsvariablen eine vorgegebene Verteilung F zugrunde liegt. Um dies zu überprüfen, unterteilen wir den Wertebereich dieser Zufallsvariablen in k disjunkte Klassen I1 , . . . , Ik . Seien Ni = n X 1{Xj ∈Ii } j=1 die Klassenhäufigkeiten und pi = F (Ii ) die Klassenwahrscheinlichkeiten für 1 ≤ i ≤ k. Ist die Verteilung der Xi durch F gegeben, so ist der Vektor (N1 , . . . , Nk ) multinomialverteilt zu den Parametern n und p1 , . . . , pk , d.h. es gilt P (N1 = n1 , . . . , Nk = nk ) = Qk n! k Y i=1 (ni !) i=1 pni i , falls n1 + · · · + nk = n mit ni ∈ N0 , und Null sonst. Wir betrachten die Statistik, die durch X2 = k X (Ni − npi )2 npi i=1 gegeben ist. Dabei kennzeichnet npi die Anzahl der erwarteten Beobachtungen in der i-ten Klasse. Die Abweichung zwischen beobachteten und theoretischen Werten wird daher durch Ni − npi ausgedrückt. 99 c Math. Stochastik, Uni Freiburg ° Die Verteilung von X2 ist für genügend große Werte von n (Daumenregel n min pi ≥ 5) approximativ 1≤i≤n eine χ2 -Verteilung mit k − 1 Freiheitsgraden. Will man die Hypothese H0 : F = F0 gegen H1 : F 6= F0 zum Niveau α testen, so wählt man als Ablehnbereich das Intervall (χ2k−1;1−α , +∞), wobei χ2k−1;1−α das (1 − α)-Quantil der χ2 -Verteilung mit k − 1 Freiheitsgraden bezeichnet. Zur Durchführung des χ2 -Anpassungstests stellt R die Funktion chisq.test() zur Verfügung. Die Syntax dieses Befehls lautet chisq.test(x,p=rep(1/length(x),length(x))) Dabei sind für x die beobachteten Klassenhäufigkeiten und für p die zugehörigen Klassenwahrscheinlichkeiten einzugeben. Per Default wird für jede Klasse die selbe Wahrscheinlichkeit gewählt. Beispiel 10.5. (Mendel Experiment) In einem seiner berühmten Experimente kreuzte Mendel 556 männliche Erbsenpflanzen mit glatten und gelben Früchten mit ebensovielen weiblichen Erbsenpflanzen mit gerunzelten und grünen Früchten. Das Ergebnis seines Experiments ist in der folgenden Tabelle angegeben. Die zweite Zeile gibt die nach der Vererbungslehre erwarteten relativen Häufigkeiten an, in der dritte Zeile finden Sie die von Mendel beobachteten absoluten Häufigkeiten. glatt gelb glatt grün gerunzelt gelb gerunzelt grün 9/16 3/16 3/16 1/16 315 108 102 31 Wir testen nun, ob sich die durch die Vererbungslehre gegebene Verteilung anhand der gegebenen Daten zum Signifikanzniveau α = 0.05 bestätigen lässt. > n <- c(315,108,102,31) > prob <- c(9,3,3,1)/16 > chisq.test(n,p=prob) Chi-squared test for given probabilities data: n X-squared = 0.6043, df = 3, p-value = 0.8954 Da der p-Wert mit 0.8954 deutlich größer als das vorgegeben Signifikanzniveau ist, nehmen wir die Hypothese, dass die Vererbungslehre zutrifft, an. Nachrechnen ergibt > nerw <- sum(n)*prob > sum((nerw-n)^2/nerw) [1] 0.6043165 100 c Math. Stochastik, Uni Freiburg ° > 1-pchisq(0.6043165,3) [1] 0.8954435 Für beliebige Verteilungen F funktioniert der χ2 -Test im Prinzip genauso; hat man jedoch zuvor einen oder mehrere Verteilungsparameter von F aus den vorliegenden Daten geschätzt, sind die Freiheitsgrade der χ2 -Verteilung um die Anzahl der geschätzten Parameter zu reduzieren. Da die vorgefertigte R-Funktion hierfür keine entsprechende Option besitzt, schreiben wir ein kurzes eigenes Programm, bei dem man mit dem zusätzlichen Argument n.params.est angeben kann, wie viele Parameter von F bereits aus den Daten geschätzt worden und in die Berechnung der Klassenwahrscheinlichkeiten eingeflossen sind: chisquare.test <- function(n,p,n.params.est=0){ df <- length(n)-1-n.params.est nerw <- sum(n)*p chi.stat <- sum((nerw-n)^2/nerw) pw <- 1-pchisq(chi.stat,df) return(list(Teststatistik=chi.stat,Freiheitsgrade=df,p.wert=pw))} 10.2.2 Ein Beispiel aus der Zuverlässigkeitstheorie Der Werkstoff Kevlar 49/epoxy wird unter anderem im Spaceshuttle verwendet. Um seine Bruchfestigkeit zu testen, wurden 76 Proben mit einer bestimmten Kraft belastet (90% der zulässigen Maximalbelastung). Angegeben sind für jede Probe die Zeit in Stunden bis zum Bruch. Diese Daten finden sie in der Datei kevlar90.data, die Sie wieder mit dem scan() Befehl einlesen können. Wir überprüfen nun, ob die Daten annähernd exponentialverteilt sind. Den Parameter λ schätzen wir durch den Maximum-Likelihood-Schätzer. Dieser ist durch λ̂ = Pnn i=1 xi gegeben. Wir testen H0 : F = Exp(λ̂) gegen H1 : F 6= Exp(λ̂). Durch die Schätzung eines eindimensionalen Parameters verlieren wir einen weiteren Freiheitsgrad in der χ2 -Statistik. Zuerst verschaffen wir uns einen grafischen Überblick. > k90 <- scan("kevlar90.data") > hist(k90,breaks=seq(0,8,0.5)) Ein häufig angewandtes Verfahren zur Bestimmung geeigneter Klassengrenzen ist die Regel von Moore: Nach ihr sind die Grenzen so zu wählen, dass man k = max(3, [2n2/5 ]) Klassen gleicher Wahrscheinlichkeit (bzgl. F ) erhält; dabei ist n die Länge des Datensatzes, [x] bezeichnet die größte ganze Zahl ≤ x, die Sie in R mit der Funktion floor() erhalten. Für den Kevlardatensatz ergibt sich damit k zu: > max(3,floor(2*length(k90)^(2/5))) [1] 11 101 c Math. Stochastik, Uni Freiburg ° Der Schätzer von λ ergibt sich hier zu > lambda <- 1/mean(k90) > lambda Die zugehörigen Klassengrenzen erhält man leicht durch die Quantilfunktion. > b.points <- qexp(seq(0,1,length=12),lambda) > x <- cut(k90,breaks=b.points,labels=F) > n.k90 <- tabulate(x) > n.k90 [1] 19 > 6 0 0 0 6 12 12 10 5 6 chisquare.test(n.k90,p=rep(1/11,11),1) $Teststatistik [1] 51.65789 $Freiheitsgrade [1] 9 $p.wert [1] 5.246029e-08 Demzufolge wäre die Hypothese auf quasi jedem Niveau α zu verwerfen! Als weiteres Hilfsmittel zur Entscheidung über die Güte der Exponentialapproximation können wir wieder einen QQ-Plot erstellen. Dazu verwenden wir die Funktion qqvert(), die wir in Lektion 7 erstellt haben. > qqvert(k90,qvert=qexp, rate=lambda) > abline(0,1) Wie man sieht, erhalten wir hier eine sehr schlechte Anpassung. 102 c Math. Stochastik, Uni Freiburg ° 10.3 Übungen Aufgabe 10.1. (Fairer Münzwurf) Im Jahr 1965 berichteten amerikanische Zeitungen von einem High School-Studenten, der 17 850 mal eine Münze geworfen hatte. Dabei kamen 9 127 mal Kopf und 8 723 mal Zahl. Ist die verwendete Münze fair gewesen? Ein Statistiker des National Bureau of Standards setzte sich auf die Meldungen hin mit dem Studenten in Verbindung und fragte ihn nach Details dieses Experiments“. Der Student ” hatte, um Zeit zu sparen, jeweils fünf Münzen gleichzeitig geworfen, und ein jüngerer Bruder hatte die Ergebnisse aufgezeichnet. Die untenstehende Tabelle gibt die Daten für die Fünfergruppen an. Anzahl der Ausgänge Kopf Häufigkeit 0 100 1 524 2 1 080 3 1 126 4 635 5 105 (a) Kann das Experiment als Realisierung von B(5, 0.5)-verteilten Zufallsvariablen angesehen werden? (b) Wir fassen das Experiment als 17 850-fachen Münzwurf auf. Testen Sie, ob die Münze fair ist. (c) Kann das Experiment überhaupt als Realisierung einer binomalverteilten Zufallsvariable angesehen werden? Schätzen Sie dazu den Erfolgsparameter p der Binomialverteilung aus den Daten. Hinweis: Verwenden Sie bei allen Tests das Signifikanzniveau α = 0.05. Aufgabe 10.2. (Das Geschlechtsverhältnis bei Geborenen) Im Jahr 1889 untersuchte der Wissenschaftler Geissler in einer Studie zum Verhältnis der Geschlechter bei Geburten die Aufzeichnungen sächsischer Krankenhäuser. Die folgende Tabelle fasst die Anzahl der weiblichen Geburten aus 6115 Familien mit je 12 Kindern zusammen. Angegeben ist jeweils die Anzahl der Familien mit keiner, einer, usw. weiblichen Geborenen. Weibliche Geburten 0 1 2 3 4 5 6 7 8 9 10 11 12 Familien 7 45 181 478 829 1112 1343 1033 670 286 104 24 3 (a) Testen Sie mithilfe eines geeigneten Tests zum Signifikanzniveau α = 0.05, ob die vorliegenden Daten durch eine Binomialverteilung adäquat beschrieben werden. Dies sollen Sie unter der Vorausetzung tun, dass im Mittel gleich viele Jungen und Mädchen geboren sind. (b) Betrachten Sie obigen Test für den ML-Schätzer des Parameters prob. (c) Testen Sie mithilfe eines geeigneten Tests zum Niveau α = 0.05, ob weniger Mädchen als Jungen geboren werden. 103 c Math. Stochastik, Uni Freiburg ° (Quelle: Geissler, A. (1889). Beiträge zur Frage des Geschlechtsverhältnisses der Geborenen. Z. K. Sachs. Stat. Bur. 35, 1–24.) 104 c Math. Stochastik, Uni Freiburg ° Lektion 11: t-Tests 11.1 Der einfache t-Test Sei X = (X1 , . . . , Xn ), wobei X1 , . . . , Xn unabhängig und identisch N (µ, σ 2 )-verteilt seien. Der MaximumLikelihood-Schätzer von µ ist dann gegeben durch n X̄n = 1X Xi . n i=1 Die Varianz σ 2 lässt sich durch n ¢2 1 X¡ Xi − X̄n s (X) = n−1 2 i=1 erwartungstreu schätzen. Da X̄n und s2 (X) stochastisch unabhängig sind, folgt die Größe √ X̄n − µ n s(X) einer t-Verteilung mit n − 1 Freiheitsgraden. Als Teststatistik für die Hypothese µ = µ0 wird deshalb T (X) = √ X̄n − µ0 n s(X) gewählt. Unter obiger Hypothese ist diese t-verteilt mit n − 1 Freiheitsgraden. Mit dieser Teststatistik können die folgenden Hypothesen getestet werden: (a) H0 : µ = µ0 gegen H1 : µ 6= µ0 (Zweiseitiger Test) (b) H0 : µ ≤ µ0 gegen H1 : µ > µ0 (Einseitiger Test) (c) H0 : µ ≥ µ0 gegen H1 : µ < µ0 (Einseitiger Test) Die Ablehnbereiche werden jeweils so bestimmt, dass die Tests das Signifikanzniveau α besitzen. Bezeichne tn−1;p das p-Quantil der t-Verteilung mit n − 1 Freiheitsgraden, dann folgt für die Ablehnbereiche: (a) (b) (c) ¢ ¢ ¡ − ∞, tn−1; α2 ∪ tn−1;1− α2 , ∞ ¡ ¢ tn−1;1−α , ∞ ¡ ¢ − ∞, tn−1;α ¡ 105 Für den t-Test stellt R die Funktion t.test() bereit: t.test(x, y = NULL, alternative = c("two.sided", "less", "greater"), mu = 0, paired = FALSE, var.equal = FALSE, conf.level = 0.95, ...) Für den einfachen t-Test sind die Parameter x, alternative, mu und conf.level anzugeben. • Für x ist der Vektor der normalverteilten Daten einzugeben. • Die Default-Einstellung ist mu = 0, alternative = "two.sided" und conf.level=0.95. In diesem Fall wird die Hypothese (a) H0 : µ = 0 gegen H1 : µ 6= 0 zum Konfidenzniveau 0.95 getestet. Als Konfidenzniveau ist hier 1 − α zu wählen, wobei α = 0.05 das Signifikanzniveau ist. • Wird alternative = "greater" eingestellt, so wird der einseitige Test (b) H0 : µ ≤ µ0 gegen H1 : µ > µ0 und entsprechend bei alternative = "less" der einseitige Test (c) durchgeführt. In vielen Anwendungsbeispielen sind zwei zu vergleichende Stichproben auf eine natürliche Weise gepaart. So besteht unter Umständen ein Datenpaar aus einer Messung vor und einer Messung nach einer Behandlung. In einem solchen Fall geht man von den Paaren (Xi , Yi ), 1 ≤ i ≤ n, zu den Differenzen Zi = Xi − Yi über. Wir nehmen nicht an, dass X1 , . . . , Xn , Y1 , . . . , Yn stochastisch unabhängig sind, sondern nur, dass die Paare (Xi , Yi ), 1 ≤ i ≤ n, stochastisch unabhängig und identisch bivariat normalverteilt sind. Unter dieser Annahme sind die Differenzen Z1 , . . . , Zn unabhängig identisch N (µ, σ 2 )-verteilt. Beispiel 11.1. (Einfluss des Rauchens auf Blutgerinnung) Um den Einfluss des Rauchens auf die Blutgerinnung (genauer: Aggregation der Blutplättchen) zu untersuchen, wurde das Blut von 11 Testpersonen untersucht, bevor und nachdem sie eine Zigarette geraucht hatten. Es wurden folgende Werte bestimmt (die Zahlen geben jeweils die Prozentzahl der aggregierten Blutplättchen an): Vorher Nachher Unterschied 25 27 2 25 29 4 27 37 10 44 56 12 30 46 16 67 82 15 53 57 4 53 80 27 52 61 9 60 59 -1 28 43 15 106 c Math. Stochastik, Uni Freiburg ° Wir überprüfen nun mit dem t-Test, ob das Rauchen Einfluss auf die Blutgerinnung hat. Wir testen also H0 : µ = 0 gegen H1 : µ 6= 0 zum Signifikanzniveau α = 0.01. > Vorher <- c(25,25,27,44,30,67,53,53,52,60,28) > Nachher <- c(27,29,37,56,46,82,57,80,61,59,43) > Z <- Nachher-Vorher > t.test(Z,conf.level=0.99) One Sample t-test data: Z t = 4.2716, df = 10, p-value = 0.001633 alternative hypothesis: true mean is not equal to 0 99 percent confidence interval: 2.650991 17.894463 sample estimates: mean of x 10.27273 In der obigen Ausgabe bezeichnet t den Wert der anfangs definierten Statistik T (Z), df die Anzahl der Freiheitsgrade (degrees of freedom) der zugrundeliegenden t-Verteilung und p-value den p-Wert. Desweiteren wird noch der empirische Mittelwert Z̄n (mean of x) berechnet und ausgegeben. Da der p-Wert kleiner als das vorgegebene Signifikanzniveau 0.01 ist, lehnen wir die Hypothese ab. Zu diesem Niveau des Tests zeigen uns die Daten, dass das Rauchen tatsächlich Auswirkungen auf die Blutgerinnung hat. Wir überprüfen nun diese Ergebnisse zu Fuss“ und beginnen mit der Teststatistik T (Z): ” > TZ <- sqrt(11)*mean(Z)/sqrt(var(Z)) > TZ [1] 4.271609 Für α = 0.01 ergibt sich als untere Grenze des rechtsseitigen Ablehnbereichs > df <- length(Z)-1 > qt(0.995,df) [1] 3.169273 Da T (Z) größer als diese Schranke ist, ist bei einer Irrtumswahrscheinlichkeit von 1% die Nullhypothese zu verwerfen, was auch durch den sehr kleinen p-Wert impliziert wurde. Unter Beachtung der Symmetrie der t-Verteilungen erhält man für letzteren 107 c Math. Stochastik, Uni Freiburg ° > 2*(1-pt(TZ,df)) [1] 0.00163285 Nun wollen wir testen, ob die Blutgerinnung durch Rauchen größer wird. Dafür betrachten wir den einseitigen t-Test (b) zu dem oben gegebenen Signifikanzniveau. Dazu muss das optionale Argument alternative="greater" zugewiesen werden. > t.test(Z,alternative="greater", conf.level=0.99) One Sample t-test data: Z t = 4.2716, df = 10, p-value = 0.0008164 alternative hypothesis: true mean is greater than 0 99 percent confidence interval: 3.62618 Inf sample estimates: mean of x 10.27273 Die linke Grenze des Ablehnbereichs berechnet sich wie folgt > qt(1-0.01,df) [1] 2.763769 Damit ist der Wert der Teststatistik 4.271609 größer als der kritische Wert 2.763769 und liegt somit im Ablehnbereich der Nullhypothese. Daher wird diese verworfen. Der p-Wert berechnet sich in diesem Fall zu > 1-pt(TZ,10) [1] 0.000816425 Bemerkung 11.2. Bei gepaarten Beobachtungen kann man auch beide Datensätze (Xi )1≤i≤n , (Yi )1≤i≤n der Funktion t.test() direkt als Argumente übergeben. Dabei muss die Option paired=T gewählt werden. Auch hier kann man durch entsprechende Setzung von alternative die einseitigen Tests durchführen. Für den obigen zweiseitigen Test ergibt sich dann > t.test(Nachher,Vorher,paired=T,conf.level=0.99) Paired t-test data: Nachher and Vorher 108 c Math. Stochastik, Uni Freiburg ° t = 4.2716, df = 10, p-value = 0.001633 alternative hypothesis: true difference in means is not equal to 0 99 percent confidence interval: 2.650991 17.894463 sample estimates: mean of the differences 10.27273 Der einfache t-Test überprüft, ob der Erwartungswert einer Normalverteilung gleich einer vorgegebenen Größe µ0 ist, wenn die Varianz unbekannt ist. Statistisches Modell X = (X1 , ..., Xn ) und X1 , ..., Xn unter Pµ,σ2 unabhängig und nach N (µ, σ 2 ) verteilt Hypothesen (a) H0 : µ = µ0 gegen H1 : µ 6= µ0 (b) H0 : µ ≤ µ0 gegen H1 : µ > µ0 (c) H0 : µ ≥ µ0 gegen H1 : µ < µ0 X − µ0 T (X) = p unter Pµ0 ,σ2 verteilt nach tn−1 s2 (X)/n Teststatistik Ablehnungsbereich (a) (−∞, tn−1α/2 ) ∪ (tn−1;1−α/2 , ∞) (b) (tn−1,1−α , ∞) (c) (−∞, tn−1,α ) p-Wert, falls die Test- (a) ¡ ¢ 2 · 1 − Pµ0 ,σ2 (T ≤ |t|) statistik den Wert t an- (b) Pµ0 ,σ2 (T ≥ t) (c) Pµ0 ,σ2 (T ≤ t) nimmt R-Befehl t.test(x, alternative=c("two.sided","less","greater"), mu=0, conf.level=0.95) Abbildung 11.4: Schematische Darstellung des einfachen t-Tests. 109 c Math. Stochastik, Uni Freiburg ° 11.2 Der doppelte t-Test – Vergleich der Mittelwerte Seien X = (X1 , . . . , Xm ) und Y = (Y1 , . . . , Yn ), wobei ¡ ¡ ¢ ¢ X1 , . . . , Xm ∼ N µX , σ 2 und Y1 , . . . , Yn ∼ N µY , σ 2 alle stochastisch unabhängig und X̄m , Ȳn , s2 (X), s2 (Y ) wie zu Beginn der Lektion definiert. Unter unseren generellen Annahmen ist ¢ ¡ ¢ ¡ X̄m − Ȳn − µX − µY q 1 s(X, Y ) m + n1 t-verteilt mit m + n − 2 Freiheitsgraden, wobei s2 (X, Y ) die gepoolte“ empirische Varianz ” s2 (X, Y ) = (m − 1)s2 (X) + (n − 1)s2 (Y ) m+n−2 ist. Untersucht werden soll nun, ob die Erwartungswerte der unverbundenen Stichproben X und Y gleich sind. Als Teststatistik für die Hypothese µX = µY (d.h. µX − µY = 0) wird T (X, Y ) = X̄m − Ȳn q 1 s(X, Y ) m + 1 n , verwendet. Für diese Hypothese ist der Ablehnbereich zum Niveau α durch ¢ ¡ ¡ ¢ −∞, tm+n−2; α2 ∪ tm+n−2;1− α2 , +∞ gegeben. Für den doppelten t-Test wird ebenfalls die Funktion t.test() verwendet. Per Defaulteinstellung werden dabei die Varianzen der Verteilung von Xi und Yi als ungleich angenommen. Da sie in unserem Fall als gleich vorausgesetzt werden, muss die zusätzliche Option var.equal=T (variance equality) angegeben werden. Beispiel 11.3. (Bestimmung der Schmelzwärme von Eis) Der Datensatz, mit dem wir im weiteren arbeiten werden, stammt aus dem Buch Mathematical Statistics and Data Analysis von J. A. Rice. Die Daten stammen aus zwei Messreihen zur Bestimmung der (latenten) Schmelzwärme von Eis. Dabei wurden zwei verschiedene Methoden verwendet, und es soll festgestellt werden, ob zwischen den beiden Verfahren ein systematischer Unterschied besteht (d.h. ob eines der Verfahren oder beide einen systematischen Fehler besitzen). Wie in der Physik üblich nehmen wir an, dass die Messwerte mit einem normalverteilten Fehler um den wahren“ Wert schwanken. ” Mit der ersten Methode (A) wurden folgende Werte bestimmt: 79.98 80.04 80.02 80.04 80.03 80.03 80.04 79.97 80.05 80.03 80.02 80.00 80.02 110 c Math. Stochastik, Uni Freiburg ° Mit der zweiten Methode (B) erhielt man: 80.02 79.94 79.98 79.97 79.97 80.03 79.95 79.97 Die Werte geben jeweils die benötigte Wärmemenge an, um ein Gramm Eis von −0.72 0 C auf 0 0 C zu erhitzen. Sie können folgendermaßen nach R eingelesen werden: > icea <- scan("C:/Users/Stochastik/Desktop/icea.data") > iceb <- scan("C:/Users/Stochastik/Desktop/iceb.data"") > boxplot(icea,iceb,varwidth=T) Wir testen also H0 : µA = µB gegen H1 : µA 6= µB zum Niveau α = 0.05. > t.test(icea,iceb,var.equal=T) Two-Sample t-Test data: icea and iceb t=3.4722, df=19, p-value=0.002551 alternative hypothesis: true difference in means is not equal to 0 95 percent confidence interval: 0.01669058 0.06734788 sample estimates: mean of x mean of y 80.02077 79.97875 Die Nullhypothese gleicher Erwartungswerte wird also zum Signifikanzniveau 0.05 verworfen. Wir überprüfen nun dieses Ergebnis: > mean(icea) [1] 80.02077 > mean(iceb) [1] 79.97875 Für die Grenzen des Ablehnbereiches erhalten wir > qt(1-0.05/2,19) [1] 2.093024 > qt(0.05/2,19) [1] -2.093024 111 c Math. Stochastik, Uni Freiburg ° Die Teststatistik dieses Tests ergibt: > pooled.variance <- (12*var(icea)+7*var(iceb))/19 > TXY <- (mean(icea)-mean(iceb))/sqrt(pooled.variance*(1/13+1/8)) > TXY [1] 3.472245 Abschließend rechnen wir den p-Wert, der sich aufgrund der symmetrischen Verteilung, wie folgt ergibt: > 2*(1-pt(3.472245,19)) [1] 0.002551003 Bemerkung 11.4. Sie können mit dem t-Test auch das einseitige Problem der Nullhypothese µX ≤ µY gegen die Alternative µX > µY behandeln. In diesem Fall ist der Ablehnungsbereich des t-Tests zum ¡ ¢ Niveau α durch das Intervall tm+n−2;1−α , ∞ gegeben. Analoge Aussagen gelten für die Alternative µX < µY . > t.test(icea,iceb,var.equal=T,conf.level=0.99,alternative="greater") Two Sample t-test data: icea and iceb t = 3.4722, df = 19, p-value = 0.001276 alternative hypothesis: true difference in means is greater than 0 99 percent confidence interval: 0.01128778 Inf sample estimates: mean of x mean of y 80.02077 79.97875 112 c Math. Stochastik, Uni Freiburg ° Der doppelte t-Test überprüft, ob die Erwartungswerte einer Normalverteilung zweier unverbundener Stichproben gleich ist, wenn deren Varianz gleich, aber unbekannt ist. Statistisches Modell X1 , ..., Xm unter unter PµX ,µY ,σ2 unabhängig und nach N (µX , σ 2 ) verteilt, Y1 , ..., Yn unter unter PµX ,µY ,σ2 unabhängig und nach N (µY , σ 2 ) verteilt Hypothesen (a) H0 : µX = µY gegen H1 : µX 6= µY (b) H0 : µY ≤ µX gegen H1 : µY > µX (c) H0 : µY ≥ µX gegen H1 : µY < µX Ȳn − X̄m 2 s (X, Y )(m + n)/(mn) T (X, Y ) = p Teststatistik mit s2 (X, Y ) := 1 m+n−2 µm P (Xi − X̄m )2 + i=1 n P ¶ (Yi − Ȳn )2 i=1 unter Pµ,µ,σ2 verteilt nach t(m + n − 2) Ablehnungsbereich (a) (−∞, tm+n−2;α/2 ) ∪ (tm+n−2;1−α/2 , ∞) (b) (tm+n−2;1−α , ∞) (c) p-Wert, falls die Test- (−∞, tm+n−2;α ) ¡ ¢ (a) 2 · 1 − Pµ,µ,σ2 (T ≤ |t|) statistik den Wert t an- (b) Pµ,µ,σ2 (T ≥ t) (c) Pµ,µ,σ2 (T ≤ t) nimmt R-Befehl t.test(x, y, alternative=c("two.sided","less","greater"), mu=0, var.equal=TRUE, conf.level=0.95) Abbildung 11.5: Schematische Darstellung des doppelten t-Tests. 113 c Math. Stochastik, Uni Freiburg ° 11.3 Übungen Aufgabe 11.1. (Anteil der erwerbstätigen Frauen) In 19 Städten der USA wurde der Prozentsatz der berufstätigen Frauen unter allen Frauen für die beiden Jahre 1968 und 1972 bestimmt. Es stellt sich die Frage, ob der Anteil berufstätiger Frauen im Zuge der allgemeinen gesellschaftlichen Entwicklungen gestiegen ist. Es liegt nahe, diese Daten als gepaarte Beobachtungen aufzufassen. Sie können diesen Datensatz folgendermaßen einlesen: > labor.dat <- read.table("C:/Users/Stochastik/Desktop/lfpr.data",header=T,sep="\t") > labor.dat City X1972 X1968 1 N.Y. 0.45 0.42 2 L.A. 0.50 0.50 3 Chicago 0.52 0.52 4 Philadelphia 0.45 0.45 5 Detroit 0.46 0.43 6 San Francisco 0.55 0.55 7 Boston 0.60 0.45 8 Pitt. 0.49 0.34 9 St. Louis 0.35 0.45 10 Connecticut 0.55 0.54 11 Wash.,D.C. 0.52 0.42 12 Cinn. 0.53 0.51 13 Baltimore 0.57 0.49 14 Newark 0.53 0.54 15 Minn/St. Paul 0.59 0.50 16 Buffalo 0.64 0.58 17 Houston 0.50 0.49 18 Patterson 0.57 0.56 19 Dallas 0.64 0.63 Aufgabe 11.2. (Welche Unterrichtsmethode ist besser?) Um zu sehen, ob eine neue Unterrichtsmethode für den Leseunterricht in der Grundschule besser“ ist, ” wurden zwei Klassen der dritten Jahrgangsstufe verglichen. Die erste Klasse mit 21 Schülern wurde acht Wochen lang mit der neuen“ Methode unterrichtet. Eine zweite Klasse mit 23 Schülern wurde im ” selben Stoff mit der alten“ Methode unterrichtet. Am Ende der acht Wochen nahmen alle 44 Schüler ” an einem Lesetest teil. Der Datensatz in enthält für jeden Schüler die erreichte Punktzahl. Eine hohe Punktzahl deutet dabei auf hohe Lesefähigkeit hin. Schüler der ersten Klasse sind mit Treated“ ” gekennzeichnet, Schüler der zweiten Klasse mit Control“. Sie können den Datensatz folgendermaßen ” nach R einlesen: 114 c Math. Stochastik, Uni Freiburg ° > scores.dat <- read.table("C:/Users/Stochastik/Desktop/scores.data",header=T) Zu welchem Ergebnis kommen Sie an Hand dieser Daten? 115 c Math. Stochastik, Uni Freiburg ° Lektion 12: Konfidenzintervalle 12.1 Intervallschätzer bei normalverteilten Zufallsgrößen Sei X = (X1 , . . . , Xn ), wobei X1 , . . . , Xn unter Pµ,σ2 unabhängige, identisch N (µ, σ 2 )-verteilte Zufallsvariablen seien, dann ist der Maximum-Likelihood-Schätzer für µ gegeben durch n X̄n = 1X Xi . n i=1 Die Varianz σ2 lässt sich durch n s2 (X) = 1 X (Xi − X̄n )2 n−1 i=1 erwartungstreu schätzen. Das Ziel ist nun, Konfidenzintervalle für die Parameter µ und σ 2 zu bestimmen. 12.1.1 Konfidenzintervall für µ unter Normalverteilungsannahme In diesem Abschnitt bestimmen wir ein Konfidenzintervall für den Erwartungwert µ von normalverteilten Zufallsgrößen, wobei die Varianz σ 2 unbekannt ist. Wir wollen also in Abhängigkeit der Daten ein Intervall I(X) bestimmen, so dass Pµ,σ2 (µ ∈ I(X)) ≥ 1 − α ist. Bemerkung 12.1. Im Falle stetiger Verteilungen – wie die hier betrachtete Normalverteilung – lässt sich stets ein Intervall I(X) mit einem Gleichheitszeichen in der letzten Ungleichung finden. Die Größe √ X̄n − µ n· s(X) ist unter diesen Voraussetzungen gemäß einer Studentschen t-Verteilung mit n − 1 Freiheitsgraden verteilt (Satz 99 aus der Vorlesung). Bezeichne tn−1;α das α-Quantil der t-Verteilung mit n − 1 Freiheitsgraden, dann gilt für alle µ ∈ R, σ 2 ∈ R+ µ ¶ √ X̄n − µ Pµ,σ2 tn−1;α/2 ≤ n · ≤ tn−1;1−α/2 = 1 − α. s(X) Auflösen der Ungleichungen nach µ liefert dann µ ¶ s(X) s(X) Pµ,σ2 X̄n − √ tn−1;1−α/2 ≤ µ ≤ X̄n − √ tn−1;α/2 = 1 − α. n n 116 Aufgrund der Symmetrie der t-Verteilung gilt −tn−1;α/2 = tn−1;1−α/2 . Dies ergibt als Konfidenzintervall zum Niveau 1 − α für µ · ¸ s(X) s(X) X̄n − √ tn−1;1−α/2 , X̄n + √ tn−1;1−α/2 . n n Wir erstellen uns nun eine Funktion, die zu einem vorgegebenen Vektor von normalverteilten Zufallsgrößen ein Konfidenzintervall zu einem vorgegebenen Konfidenzniveau 1 − α bestimmt. Die Quantile der t-Verteilung lassen sich in R mit dem Befehl qt() berechnen. conf.mean <- function(x,alpha=0.05){ n <- length(x) qtX <- qt(1-alpha/2,df=n-1) dX <- sqrt(var(x))*qtX/sqrt(n) return(c(mean(x)-dX,mean(x)+dX))} Beispiel 12.2. Als Anwendung berechnen wir die Konfidenzintervalle zum Niveau 1 − α = 0.95 bzw. 1 − α = 0.99 für den Erwartungswert der Auszahlung bei der Pick-It Lotterie anhand des Datensatzes lottery3.payoff unter der Annahme, dass die Auszahlungen unabhängig normalverteilt sind. > conf.mean(lottery3.payoff) [1] 265.2898 283.5158 > conf.mean(lottery3.payoff,0.01) [1] 262.3927 286.4129 Bemerkung 12.3. R stellt keine eigene Funktion zur Berechnung des obigen Konfidenzintervalls bereit. Sie erhalten dieses allerdings mit dem Befehl t.test()$conf.int, da R bei der Durchführung des t-Test das zugehörigen Konfidenzintervall (confidence interval) standardmäßig bestimmt. > t.test(lottery3.payoff)$conf.int [1] 265.2898 283.5158 attr(,"conf.level") [1] 0.95 > t.test(lottery3.payoff,conf.level=0.99)$conf.int [1] 262.3927 286.4129 attr(,"conf.level") [1] 0.99 12.1.2 Konfidenzintervall für σ 2 unter Normalverteilungsannahme Jetzt wollen wir ein Konfidenzintervall für die Varianz σ 2 von normalverteilten Zufallsgrößen bestimmen, wobei der Erwarungswert µ als unbekannt vorausgesetzt wird. Hier wollen wir also in Abhängigkeit der Daten ein Intervall I(X) bestimmen, so dass Pµ,σ2 (σ 2 ∈ I(X)) ≥ 1 − α ist. Die Größe n−1 2 s (X) σ2 117 c Math. Stochastik, Uni Freiburg ° ist gemäß einer χ2 -Verteilung mit n − 1 Freiheitsgraden verteilt (Satz von Fisher). Bezeichne χ2n−1;α das α-Quantil der χ2 -Verteilung mit n − 1 Freiheitsgraden, dann ergibt sich µ ¶ n−1 2 2 2 Pµ,σ2 χn−1;α/2 ≤ s (X) ≤ χn−1;1−α/2 = 1 − α σ2 . Auflösen nach σ 2 liefert als Konfidenzintervall für σ 2 zum Niveau 1 − α analog zu oben # " n−1 n−1 2 2 s (X), 2 s (X) . χ2n−1;1−α/2 χn−1;α/2 Auch hierfür definieren wir uns eine eigene Funktion zur Berechnung des Konfidenzintervalls. conf.var <- function(x,alpha=0.05){ dfX <- length(x)-1 qchia <- qchisq(1-alpha/2,dfX) qchib <- qchisq(alpha/2,dfX) return(dfX*var(x)*c(1/qchia,1/qchib))} Beispiel 12.4. Als Anwendung berechnen wir wiederum das Konfidenzintervall zum Niveau 1 − α = 0.95 bzw. 1 − α = 0.99 für die Varianz der Auszahlung bei der Pick-It Lotterie anhand des Datensatzes lottery3.payoff unter der Annahme, dass die Auszahlungen unabhängig und normalverteilt sind. > conf.var(lottery3.payoff) [1] 4563.266 6479.440 > conf.var(lottery3.payoff,0.01) [1] 4334.198 6872.873 12.1.3 Ein Backtest mit simulierten Daten Nun wollen wir die Güte der oben angegebenen Konfidenzintervalle bestimmen. Dazu verwenden wir einen Backtest mit simulierten Daten. Wir erzeugen zunächst eine 100 × 50-Matrix N, deren Einträge simulierte unabhängige, standardnormalverteilte Zufallsgrößen sind. Dann berechnen wir zeilenweise die Konfidenzintervalle für Mittelwert und Varianz und überprüfen (mit den Funktionen indik0() bzw. indik1()), ob diese jeweils die wahren Werte 0 bzw. 1 enthalten. Der relative Anteil der Intervalle, für die dies zutrifft, sollte nahe bei dem theoretischen Wert 1 − α liegen (in diesem Fall bei 0.95). > indik0 <- function(x){(x[1]<0)*(x[2]>0)} > indik1 <- function(x){(x[1]<1)*(x[2]>1)} > N <- matrix(rnorm(5000),100,50) > Nm <- apply(N,1,conf.mean) > sum(apply(Nm,2,indik0))/100 > Nv <- apply(N,1,conf.var) > sum(apply(Nv,2,indik1))/100 118 c Math. Stochastik, Uni Freiburg ° 12.2 Konfidenzintervalle bei binomialverteilten Daten Seien X1 , X2 , . . . , Xn unter Pp unabhängige und identisch verteilte Bernoulli-Variablen mit Pp (Xi = 1) = p = 1 − Pp (Xi = 0). Der Maximum-Likelihood-Schätzer für p ist dann gegeben durch n pbn = 1X Xi . n i=1 Es gilt p(1 − p) . n Im Folgenden wollen wir ein approximatives Konfidenzintervall I(X) bestimmen, so dass Varp (b pn ) = Pp (p ∈ I(X)) ≥ 1 − α ist. Für große n ist die Größe nach dem Satz von de Moivre-Laplace √ pbn − p np p(1 − p) näherungsweise normalverteilt mit Erwartungswert 0 und Varianz 1. Ein approximatives Konfidenzintervall zum Niveau 1 − α erhalten wir somit aus ! à √ p̂n − p ≤ z1− α2 ≈ Φ(z1− α2 ) − Φ(−z1− α2 ) = 1 − α. Pp −z1− α2 ≤ n p p(1 − p) Dabei ist zq das q-Quantil der Standardnormalverteilung. Beachten Sie hierbei, dass −z1− α2 = z α2 ist. Geeignetes Umformen der Ungleichungskette −z1− α2 ≤ √ p̂n − p ≤ z1− α2 np p(1 − p) (12.1) führt auf eine quadratische Gleichung r aus deren Lösungen wir das Konfidenzintervall bestimmen können. Dieses ergibt sich mit c = z " 1− α 2 np̂n (1 − p̂n ) + 2 z1− α 4 2 zu # 2 2 z1− z1− α α ¡ ¡ ¢ ¢ 1 1 2 2 np̂n + np̂n + −c , +c . 2 2 2 2 n + z1− n + z1− α α 2 (12.2) 2 Bemerkung 12.5. Ersetzt man in Gleichung (12.1) den Term p p p(1 − p) durch pbn (1 − pbn ), so erhält man unmittelbar das (1 − α)-Konfidenzintervall " # p p pbn (1 − pbn ) pbn (1 − pbn ) √ √ pbn − z1− α2 , pbn + z1− α2 . n n Dieses ist zwar wesentlich einfacher zu bestimmen, allerdings auch viel ungenauer, wie man bei kleinen und großen Werten für den wahren Parameter p beobachten kann. 119 c Math. Stochastik, Uni Freiburg ° Beispiel 12.6. (Lottery Datensatz) Wir bestimmen mit dem Datensatz lottery.number ein (näherungsweise) 0.99-Konfidenzintervall gemäß (12.2), für den Erfolgsparameter, dass bei der Pick-it Lotterie eine Zahl kleiner als 500 gezogen wird. Dabei nehmen wir an, dass die Ziehungen unabhängig und Bernoulli verteilt sind. > n <- length(lottery.number) > phat <- sum(lottery.number<500)/n > alpha <- 0.01 > z <- qnorm(1-alpha/2) > abw <- z*sqrt(n*phat*(1-phat)+0.25*z^2 ) > (1/(n+z^2))* (n*phat+ 0.5*z^2 + c(-abw,abw)) [1] 0.4783202 0.6367834 12.3 Konfidenzintervalle bei poissonverteilten Daten Sind X1 , X2 , . . . , Xn unter Pλ unabhängig und identisch poissonverteilt zum Parameter λ, so ist der (erwartungstreue) Maximum-Likelihood-Schätzer für λ durch n X bn = 1 Xi λ n i=1 gegeben. Es gilt Varλ (λ̂n ) = nλ . Nun wollen wir ein approximatives Konfidenzintervall I(X) bestimmen, so dass Pλ (λ ∈ I(X)) ≥ 1 − α ist. Die Größe bn − λ √ λ n √ λ ist nach dem zentralen Grenzwertsatz näherungsweise gemäß einer Standardnormalverteilung verteilt. Zur Bestimmung approximativer Konfidenzintervalle zum Niveau 1 − α erhalten wir analog zum vorherigen Abschnitt λ̂n + 2 z1− α 2 2n s − z1− α2 n nλ̂n + 2 z1− α 2 4 , λ̂n + 2 z1− α 2 2n s + z1− α2 n nλ̂n + 2 z1− α 2 4 (12.3) p √ Bemerkung 12.7. Alternativ erhalten wir durch Ersetzen von λ durch λ̂n das 1−α-Konfidenzintervall s s b b bn − z1− α λn , λ bn + z1− α λn . λ 2 2 n n 120 c Math. Stochastik, Uni Freiburg ° Beispiel 12.8. (Hufschlagtote in der Preußischen Armee) Ein klassisches Beispiel für die Anwendung der Poissonverteilung ist die Anzahl der Hufschlagtoten pro Jahr in den Regimentern der Preußischen Armee. Die untenstehenden Daten sind das Ergebnis der Auswertung der Aufzeichnungen für 14 Regimenter über 20 Jahre. Angeben ist, wie oft 0, 1, 2, 3 oder 4 Todesfälle pro Jahr in einem Regiment zu verzeichnen waren. Anzahl der Todesfälle Beobachtete Häufigkeit 0 144 1 91 2 32 3 11 4 2 Wir berechnen hier ein approximatives 0.95-Konfidenzintervall für λ gemäß Bemerkung (12.7) unter der Annahme von unabhängigen und poissonverteilten Daten. > counts <- c(144,91,32,11,2) > n <- sum(counts) > lhat <- sum((0:4)*counts)/n > lhat [1] 0.7 > delta <- sqrt(lhat/n)*qnorm(0.975) > lhat+c(-delta,delta) [1] 0.6020018 0.7979982 Zum Schluss wollen wir dazu noch eine entsprechende Funktion definieren. conf.lambda <- function(lhat,n,alpha=0.05){ zalpha <- qnorm(1-alpha/2) return(lhat+sqrt(lhat/n)*c(-zalpha,zalpha))} > conf.lambda(lhat,280) [1] 0.6020018 0.7979982 121 c Math. Stochastik, Uni Freiburg ° 12.4 Übungen Aufgabe 12.1. (Gepaarte Beobachtungen) Bestimmen Sie ein näherungsweises Konfidenzintervall zum Niveau 1 − α = 0.95 für den Mittelwert und die Varianz der Anzahl der veränderten Blutplättchen aus Beispiel 11.1 unter der Annahme, diese seien normalverteilt. Ist die Anzahl der veränderten Blutplättchen normalverteilt? Aufgabe 12.2. (Meinungsumfrage) Bei einer Meinungsumfrage mit der Auswahl zwischen zwei Bewerbern für das Amt des amerikanischen Präsidenten zogen von 1600 Befragten 53% Kandidat A Kandidat B vor. Bestimmen Sie ein Konfidenzintervall zum Niveau 1 − α = 0.95 für die Beliebtheit“ von Kandidat A. Schreiben Sie hierzu eine ” Funktion konf.binom(x,n,alpha=0.05, direct=FALSE), die wahlweise das approximative Konfidenzintervall aus der Gleichung (12.2) (direct=FALSE) bzw. aus der Bemerkung (12.5) (direct=TRUE) bestimmt. Dabei soll x der Mittelwert resultierend aus den Beobachtungen sein. Aufgabe 12.3. (Backtest mit simulierten Daten) Überprüfen Sie die Güte der in Aufgabe 12.2 bestimmten Konfidenzintervalle. Erzeugen Sie dazu eine 1000 × 50-Matrix N, deren Einträge simulierte unabhängige, zu p = 0.53 und n = 1 binomialverteilte Zufallsgrößen sind. Berechnen Sie anschließend zeilenweise mit der Funktion konf.binom() aus Aufgabe 12.2 (a) die Konfidenzintervalle aus (12.2) für p zum Niveau 1 − α = 0.95 (b) die Konfidenzintervalle aus der Bemerkung (12.5) für p zum Niveau 1 − α = 0.95 und überprüfen Sie, ob diese jeweils den wahren Wert enthalten. Der relative Anteil der Intervalle, für die dies zutrifft, sollte nahe bei dem theoretischen Wert 1 − α liegen (in diesem Fall bei 0.95). Welche Methode ist besser? Wiederholen Sie den Test auch mit anderen Werten für p. Aufgabe 12.4. Schreiben Sie eine Funktion konf.lambda2(), die die Grenzen des KonfidenzinterbM L bei poissonverteilten Daten ausgibt. Als Parameter der Funktion sollen die valls aus (12.3) für λ Anzahl der Zufallsgrößen n und das Konfidenzniveau 1 − α gewählt werden können. Berechnen Sie ein Konfidenzintervall zum Niveau 1 − α = 0.95 für den Parameter λ der Poissonverteilung anhand der Daten aus Beispiel 12.8. Vergleichen Sie schließlich Ihr Ergebnis mit dem aus der Lektion. 122 c Math. Stochastik, Uni Freiburg °