Dieses Kapitel umfasst die grafische Darstellung und Analyse von empirischen Daten.
Obwohl streng gesprochen keine Statistik, sind Zufallszahlen in Computerprogrammen immer wieder notwendig und ein praktisches Hilfsmittel um diverse Statistiken zu illustrieren.
Python's internes random
modul hat einige praktische Funktionen:
import random
Fließkommazahl in [0, 1)
random.random()
0.36461328514232505
zufällige Ganzzahl
random.randint(-10, 10)
7
mischen einer Liste (hier, die Zahlen von 0 bis 9)
x = list(range(10))
random.shuffle(x)
print(x)
[0, 5, 1, 4, 9, 3, 8, 2, 6, 7]
Gauß'sche Normalverteilung, wobei mu
der Mittelwert und sigma
die Standardabweichung ist.
random.normalvariate(mu = 1, sigma = 2)
1.790115275319303
Da Zufallszahlen in Programmen unvorhersebar sind,
jedoch mit einer deterministischen Methode berechnet werden,
gibt es die Möglichkeit den internen Status des Zufallszahlengenerators zu setzen.
Dies passiert mit der seed
Funktion und ist für Tests oder das reproduzieren bestimmter Ergebnisse nützlich.
# zweimal genau dieselbe Zufallszahl!
random.seed(42)
print(random.random(), random.normalvariate(mu = 1, sigma = 2))
random.seed(42)
print(random.random(), random.normalvariate(mu = 1, sigma = 2))
0.6394267984578837 -1.2479729469788396 0.6394267984578837 -1.2479729469788396
Mittels der Klasse Counter
in den collections
(Counter in Python 3) können Listen abgezählt werden.
from collections import Counter
from random import randint
Multipliziere 10000 mal zwei zufällig von 1 bis 4 gewählte Ganze Zahlen. Welche Häufigkeiten gibt es und was sind die drei häufigsten Zahlen?
numbers = [randint(1, 4) * randint(1, 4) for i in range(10000)]
c = Counter(numbers)
c
Counter({1: 638, 2: 1264, 3: 1227, 4: 1901, 6: 1224, 8: 1261, 9: 599, 12: 1240, 16: 646})
c.most_common(3)
[(4, 1901), (2, 1264), (8, 1261)]
Einfaches Balkendiagramm, mit Skalierung. Beachte, dass einige Zahlen überhaupt nicht vorkommen.
Frage: warum kommt die 4 am häufigsten vor?
for i in range(1, 17):
print("%2d: " % i + "-" * (c[i]/30))
TypeErrorTraceback (most recent call last) <ipython-input-16-604a169dfc9a> in <module>() 1 for i in range(1, 17): ----> 2 print("%2d: " % i + "-" * (c[i]/30)) TypeError: can't multiply sequence by non-int of type 'float'
N = 1000 # Anzahl der Punkte
xx = [ random.expovariate(.5) for _ in range(N)]
yy = [ random.normalvariate(10, 2) for _ in range(N)]
%matplotlib inline
import matplotlib.pyplot as plt
plt.scatter(xx, yy, marker=".", color="black", alpha=.5)
<matplotlib.collections.PathCollection at 0x7f00f5b47588>
Es lassen sich leicht einfache Statistiken über Arrays or Matrizen berechnen:
import numpy as np
data = np.array([
[ 3.1, 3.3, 3.2, 3.0 ],
[ 0.1, 11, 9999, 0],
[ 31, -33, 11, 51],
[-5.1, -.6, 1, 9.1]
])
data.mean()
630.44375000000002
# Spaltenweise
data.mean(axis=0)
array([ 7.275, -4.825, 2503.55 , 15.775])
# Zeilenweise
data.mean(axis=1)
array([ 3.15000000e+00, 2.50252500e+03, 1.50000000e+01, 1.10000000e+00])
data.max()
9999.0
# Zeilenweiser Median
np.median(data, axis=1)
array([ 3.15, 5.55, 21. , 0.2 ])
# Spaltenweise die range von Minimum bis Maximum
np.ptp(data, axis=0)
array([ 36.1, 44. , 9998. , 51. ])
# Standardabweichung
np.std(data, axis=1)
array([ 1.11803399e-01, 4.32809417e+03, 3.11126984e+01, 5.13176383e+00])
NumPy liefert in numpy.random eine Fülle von Funktionen für das effiziente Sampeln verschiedener Verteilungen in Arrays.
Die vorhergehenden xx
und yy
listen lassen sich viel effizienter als NumPy Vektoren erzeugen:
xx = np.random.exponential(scale = 5, size = N)
yy = 10 + 2 * np.random.randn(N)
plt.scatter(xx, yy, color="black", marker=".", alpha=.5)
<matplotlib.collections.PathCollection at 0x7f00f3277c18>
SciPy beinhaltet in scipy.stats eine Sammlung von statistischen Verteilungen, Methoden und Tests. Viele alltägliche Anwendungen sind damit abgedeckt.
Das allgemeine Schema ist hierbei so, dass für jede der diskreten oder kontinuierlichen Verteilungen jeweils eine Liste bestimmter Funktionen implementiert sind.
pdf
und cdf
sind beispielsweise die Dichte- und kumulierten Dichteverteilungen,rvs
zum Sampeln zufälliger Werte,fit
zum Anpassen an gegebene Daten undstats
für generelle Daten über die Verteilung.import scipy.stats as sps
10 Bernulli-verteilte Zahlen, mit Wahrscheinlichkeitsparameter p = 0.2
:
sps.bernoulli.rvs(.2, size = 10)
array([0, 1, 0, 0, 0, 0, 0, 1, 0, 1])
Rekonstruktion unserer Parameter der Normalverteilung (siehe yy
oben)
sps.norm.fit(yy)
(10.04454503926571, 2.0309183722908273)
Es gibt in scipy.stats
auch eine Reihe von statistischen Funktionen und Tests.
Beispielsweise gibt es den berühmten T-Test,
um herauszufinden ob zwei unterschiedliche Samples den gleichen Mittelwert haben.
Als visuelles Ergebnis eines Zufallsprozesses.
import numpy as np
%matplotlib inline
import matplotlib.pyplot as plt
N = 2000
edges = np.array([[0, 0], [2, 0], [1, 2]], dtype=np.float)
sierp = np.empty((N, 2))
point = edges[0]
for i in range(3, N):
edge = edges[random.randint(0, 2)]
point = (point + edge) / 2
sierp[i] = point
plt.scatter(*sierp.T, s=1, marker=".", c="b")
<matplotlib.collections.PathCollection at 0x7f00e629db70>
male
und female
sind (halbwegs normalverteilte) Prüfungsergebnisse.
Gibt es einen signifikanten Unterschied?
Die $H_0$ Nullhypothese wäre, dass die Mittelwerte gleich sind.
Die Ergebnisse des Tests liegen aber über der 1% bzw. 5% Schranke ($\sim 55.2\%$)
und daher kann die Nullhypothese nicht verworfen werden.
In der Tat sind die Mittelwerte jedoch nicht gleich,
jedoch kann der Test dies aufgrund der kleinen Datenmenge bzw. großen Streuung dies nicht erkennen.
male = [3, 4, 1, 2, 2, 1, 3, 4, 2, 3, 2, 3, 3, 4, 4, 3, 3, 5, 1, 4,
2, 3, 3, 2, 1, 5, 3, 3, 1, 2]
female = [3, 3, 2, 3, 4, 3, 1, 4, 1, 2, 1, 3, 2, 3, 4, 1, 3, 3, 3, 2]
np.mean(male), np.std(male), np.median(male)
(2.7333333333333334, 1.1234866364235143, 3.0)
np.mean(female), np.std(female), np.median(female)
(2.5499999999999998, 0.97339611669658921, 3.0)
sps.ttest_ind(male, female, equal_var = False)
Ttest_indResult(statistic=0.59990642797746641, pvalue=0.55161451342571177)
Eine mächtigere Bibliothek für statistische Modellierung und Rechnung ist Statsmodels.