heute gibt es Schlangenhappen zum Abendbrot. Ich habe für euch ein kleines Python-Skript geschrieben, um anhand einer Würfelsimulation ein paar Konzepte zu demonstrieren.
Ok, wir fangen langsam an. Eine zufällige Zahl erzeugen geht ganz einfach mit der Library random über die Funktion randint, welche auch alle möglichen weiteren Wahrscheinlichkeitsverteilungen, z.B Normal-, Beta- oder Binomialverteilung.
# ganz einfach den Zufallsgenerator von Python benutzt import random for i in range(15): print(random.randint(1,6)) def wuerfeln(): return(random.randint(1,6)) wuerfeln()
Klassen in Python
Klassen kennt ihr vielleicht aus anderen objektorientierten Programmiersprachen (OOP). Eine Klasse ist im Prinzip der Datentyp eines Objekts und besteht aus Attributen und Methoden. Unsere Klasse heißt Wuerfel und soll – Überraschung – einen Würfel widerspiegeln. Ich erzeuge einen Würfel, indem ich ein neues Objekt der Klasse erzeuge. Das ruft nun den Konstruktor auf. Dabei gebe ich entweder nur die Anzahl Seiten an – die Wahrscheinlichkeit ist dann eine Gleichverteilung, d.h. jede Seite ist gleich wahrscheinlich – oder ich gebe explizit die Wahrscheinlichkeiten der einzelnen Seiten an.
Mit den get- und set-Funktionen können die Attribute, sprich Variablen, der Klasse abgerufen oder gesetzt werden.
Und natürlich soll der Würfel auch etwas machen, nämlich gewürfelt werden. Die Funktion wuerfeln erzeugt eine Zufallsstichprobe der Größe n.
Ist der Würfel fair?
Man spricht von einem fairen Würfel, wenn alle Seiten auf lange Sicht gleich häufig auftreten. Es muss also eine Gleichverteilung vorliegen. Um das statistisch zu testen, benötigen wir zuerst eine Stichprobe, die wir ja schnell mit unserer Funktion wuerfeln erzeugen können. Nun werden die absoluten Häufigkeiten der einzelnen Zahlen mit der Funktion unique aus der library numpy ermittelt. Numpy ist übrigens eine super wichtige Bibliothek, die effeziente Berechnungen ermöglicht und die man als Data Scientist unbedingt gut kennen sollte.
Auf die Häufigkeiten lassen wir nun einen Chi²-Test los. Die Nullhypothese geht von einer Gleichverteilung aus. Ist es sehr unwahrscheinlich, dass die Stichprobe – gegeben die Nullhypthese – gezogen wird, bekommen wir einen kleinen p-Wert. Liegt der p-Wert nun unter einer vorher festgelegten Grenze alpha, z.B. alpha =0,01, wird die Nullhypothese abgelehnt. In unserem Fall heißt das, dass der Würfel also nicht fair ist.
Der Python-Code für die Würfelsimulation
Und nun endlich der Code
# so, ab jetzt wird es interessant import numpy as np from scipy.stats import chisquare # Definition der Klasse Wuerfel class Wuerfel(object): #Konstruktor #entweder nur die Anzahl Seiten angeben oder #die Anzahl Seiten und die zugehörigen Wahrscheinlichkeiten def __init__(self,seiten=6,wahrscheinlichkeiten=None): self.seiten = seiten if wahrscheinlichkeiten is None: self.wahrscheinlichkeiten = np.repeat(1/seiten,seiten) else: self.wahrscheinlichkeiten = wahrscheinlichkeiten def getSeiten(self): return self.seiten def setSeiten(self,seiten): self.seiten=seiten def getWahrscheinlichkeiten(self): return self.wahrscheinlichkeiten def setWahrscheinlichkeiten(self,wahrscheinlichkeiten): self.seiten = wahrscheinlichkeiten.size self.wahrscheinlichkeiten=wahrscheinlichkeiten #die Funktion wuerfeln erzeugt ein Array der Länge n def wuerfeln(self,n=1): return(np.random.choice(np.arange(1, self.seiten+1), size=n,p=self.wahrscheinlichkeiten)) # Wir erzeugen einen regulären 6-seitigen Würfel W6 = Wuerfel(seiten=6) # nun würfeln wir 100 Mal sample1 = W6.wuerfeln(100) # und zählen, wie häufig jede Zahl vorkommt haeufigkeiten = np.unique(sample1, return_counts=True)[1] # Der Chi²-Test prüft auf Gleichverteilung chisquare(haeufigkeiten) # Jetzt erzeugen wir einen gezinkten 6-seitigen Würfel, # der viel zu häufig eine 6 würfelt W6gezinkt = Wuerfel(seiten=6,wahrscheinlichkeiten=[0.1,0.1,0.1,0.1,0.1,0.5]) # und werfen diesen wieder 100 Mal sample2 = W6gezinkt.wuerfeln(100) haeufigkeiten = np.unique(sample2, return_counts=True)[1] # hier sollte der Chi²-Test die Nullhypothese verwerfen chisquare(haeufigkeiten) # und noch schnell ein Histogramm gezeichnet import matplotlib.pyplot as plt plt.hist(sample1, density=True, bins=6) plt.hist(sample2, density=True, bins=6)
Happy coding,
Euer Holger