|
Prof.
Urban
|
![]() |
![]() |
||
Wir werden lernen, die üblichen Mathe-Aufgaben zur Statistik mithilfe von Python zu lösen. Dazu benötigen wir die Bibliothek SciPy, die auf dem Computer installiert sein muss.
Um statistische Funktionen nutzen zu können, müssen wir die Bezeichnungen kennen, die Mathematiker verwenden. Das 'Schulvokabular' ist da etwas ungenau
Die Wahrscheinlichkeit, dass ein Studienanfänger seinen Abschluss macht, beträgt 40%. Berechne die Wahrscheinlichkeit, dass von 5 Studenten a) einer b) mindestens einer seinen Abschluss macht. c) Wie viele von 500 Studenten werden wohl den Abschluss machen und wie groß ist die Varianz?
>>> import scipy
>>> from scipy import stats
>>> stats.binom.pmf(1,5,0.4)
0.25919999999999999
>>> stats.binom.cdf(5,5,0.4)-stats.binom.cdf(0,5,0.4)
0.92224000000000006
>>> stats.binom.stats(500,0.4)
(array(200.0), array(120.0))
Damit ergeben sich die Antworten a) 25.9%, b) 92.2%, c) μ = 200 (=Np) und σ2 =120 (=Npq)
Wenn N sehr groß ist, kann das Berechnen dieser Wahrscheinlichkeiten schwierig sein. Die Binomialkoeffizienten werden sehr groß (500 über 200 hat 145 Stellen, das kann kein Taschenrechner mehr anzeigen) und das Produkt pkqN-k wird sehr sehr klein. Das gesuchte Produkt dieser beiden Zahlen ist ebenfalls sehr klein (500 Summanden, die sich zu 1 addieren).
Dann ist es praktisch, (hoffentlich) kleine Fehler in Kauf zu nehmen und leichter berechenbare Funktionen anzuwenden, bzw. solche, die sich als Tabellenwerk zum Nachschlagen einsetzen lassen.
Poisson-Verteilung
Wenn N groß ist und p sehr klein ist (seltene Ereignisse), dann kann man alle Potenzen von q=1-p durch 1 abschätzen und erhält eine Näherungsformel für die Binomialverteilung. Sie liefert dann brauchbare Ergebnisse, wenn N mindestens 50 und Np kleiner als 5 ist.
Normalverteilung
Wenn N groß ist und weder p noch q nahe bei 0 liegen, kann die Binomialverteilung durch die Gauss-Verteilung angenähert werden. In der Praxis müssen Np und Nq größer als 5 sein.
(Da es keine geschlossene Formel zur Berechnung der Binomialverteilungs-cdf gibt, muss auch der Computer numerische Näherungsmethoden einsetzen. Diese Ungenauigkeiten sind aber viel kleiner als die Fehler aus einer unangebracht eingesetzten Normalverteilung. Genaugenommen weckt die Normalverteilung heute eher historisches Interesse, für Berechnungen ist sie nicht mehr notwendig.)
Eine faire Münze wird 500 mal geworfen. Bestimme die Wahrscheinlichkeit, dass die Anzahl von Kopf sich nicht um mehr als 10 von 250 unterscheidet.
Beachte: wir müssen zuerst die Angabe in standardisierte Werte (Standardscores) umrechnen!
>>> stats.binom.stats(500,0.5)
(array(250.0), array(125.0))
>>> z1 = (239.5-250)/125**0.5 >>> z2 = (260.5-250)/125**0.5
>>> stats.norm.cdf(z2)-stats.norm.cdf(z1)
0.65234551986668121
Es ergeben sich 65.2%
Zur Kontrolle die exakte Berechnung mithilfe der Binomialverteilung
>>> stats.binom.cdf(260,500,0.5)-stats.binom.cdf(239,500,0.5)
0.6523358206868517
Erst die fünfte Nachkommastelle ist im Ergebnis der Normalverteilung falsch - wir können zufrieden sein.
Die Wahrscheinlichkeit, dass ein Studienanfänger seinen Abschluss macht, beträgt 40%. Berechne die Wahrscheinlichkeit, dass von 5 Studenten a) einer b) mindestens einer seinen Abschluss macht. c) Was ergäbe sich ohne Stetigkeitskorrektur?
>>> stats.binom.stats(5,0.4)
(array(2.0), array(1.2))
>>> z1 = (0.5-2)/1.2**0.5
>>> z2 = (1.5-2)/1.2**0.5
>>> stats.norm.cdf(z2)-stats.norm.cdf(z1)
0.23858667395417432 >>> z1 = (0.5-2)/1.2**0.5
>>> z2 = (5.5-2)/1.2**0.5
>>> stats.norm.cdf(z2)-stats.norm.cdf(z1)
0.91384920256399549
>>> z1 = (1-2)/1.2**0.5
>>> z2 = (5-2)/1.2**0.5
>>> stats.norm.cdf(z2)-stats.norm.cdf(z1)
0.81625983607663866
Damit ergeben sich die Antworten a) 23.9% anstatt 25.9%, b) 91.4% anstatt92.2%
Das Ergebnis von c) ist - klarerweise - noch viel schlechter.
Was lernen wir daraus? Die Näherungen darf man nur dann einsetzen, wenn sie wirklich angebracht sind!
Um Schreibarbeit zu sparen, kannst Du in Python die Funktionsnamen ändern. Nennen wir die Normalverteilungsfunktion einfach nur 'norm'.
>>> norm = stats.normal.cdf
>>> z1 = (0.5-2)/1.2**0.5
>>> z2 = (1.5-2)/1.2**0.5
>>> norm(z2)-norm(z1)
0.23858667395417432
Analog könnst Du 'bino' für die Massenfunktion stats.binomial.pmf setzen. Gewissenhafte Schüler stellen ein 'd' oder 'v' für Dichte- und Verteilungsfunktion hinten dran.
Die Wahrscheinlichkeit, dass jemand allergisch auf ein Serum reagiert, ist 0.1%. Berechne die Wahrscheinlichkeit, dass von 2000 Personen a) genau 3 b) mehr als 2 eine allergische Reaktion zeigen werden.
Np ist hier gleich 2, also können wir die Poisson-Verteilung einsetzen.
>>> poissd = stats.poisson.pmf
>>> poissv = stats.poisson.cdf
>>> poissd(3,2000*0.001)
0.18044704431548356
>>> poissv(2000,2000*0.001)-poissv(2,2000*0.001)
0.32332358381693638
a) 18%, b) 32,3%
Kontrollieren wir, indem wir die exakten Binomial-Ergebnisse berechnen:
>>> stats.binom.pmf(3,2000,0.001)
0.18053732803215539 >>> stats.binom.cdf(2000,2000,0.001)-stats.binom.cdf(2,2000,0.001)
0.32332356123927086
Die Approximation ist erwartungsgemäß gut.
Eins der beliebten Schularbeitsbeispiele:
Die Wahrscheinlichkeit, dass ein Los gewinnt, sei 15%. Wie viele Lose muss man kaufen, um (mindestens) mit a) 99% b) 99,99% Gewissheit (mindestens) einen Treffer zu haben?
Hier müssen wir uns selbst um den Algorithmus bemühen. Einfaches Umformen genügt zum Glück.
1 - (1-p)N ≥ total
>>> from math import *
>>> def w(p,total): return log(1.0-total)/log(1.0-p) >>> w(0.15,0.99)
28.336207974167962
>>> w(0.15,0.9999)
56.672415948336614
Das wären dann 29 bzw. 57 Stück.
P.S. Zur Erhöhung des Komforts: Eine Funktion schreiben, die das Umrechnen auf die Standardvariable der Normalverteilung besorgt und auch die Intervallgrenzen entgegennimmt,...
Tips für Interessenten - freie Mathematik-Software:
- SciPy und SymPy (numerische und symbolische Mathematik in Python)
- Maxima (statt Mathematica), an Unis zugelassen
- Octave (statt Matlab), an Unis zugelassen
- R Project (Visualisierung statistischer Daten)
(Wolfgang.Urban@schule.at)