Einführung
Wahrscheinlichkeit und Statistik sind die Grundpfeiler der Data Science. Tatsächlich beruhen Machine Learning und Künstliche Intelligenz im Kern auf Statistik und Linearer Algebra. Gerade in der Data Science stößt du oft auf Fachartikel mit viel Mathematik. Wenn du in Data Science besser werden willst, brauchst du daher ein solides mathematisches Verständnis. In diesem Tutorial geht es um häufig verwendete Wahrscheinlichkeitsverteilungen in der Machine-Learning-Literatur. Wenn du Einsteiger bist, bist du hier genau richtig. In diesem Tutorial wirst du:
- Wichtige Begriffe der Wahrscheinlichkeit wie Zufallsvariable, Dichtekurve, Wahrscheinlichkeitsfunktion usw. kennenlernen.
- Verschiedene Wahrscheinlichkeitsverteilungen samt ihrer Verteilungsfunktionen und einigen Eigenschaften verstehen.
- Lernen, diese Verteilungen in Python zu erzeugen und zu visualisieren.
Bevor es losgeht, solltest du mit einigen mathematischen Begriffen vertraut sein – genau das deckt der nächste Abschnitt ab.
Zufallsvariable
Eine Zufallsvariable ist eine Variable, deren mögliche Werte die numerischen Ergebnisse eines zufälligen Vorgangs sind. Es gibt zwei Typen von Zufallsvariablen: diskret und stetig.
Eine diskrete Zufallsvariable kann nur eine abzählbare Anzahl verschiedener Werte annehmen und ist damit quantifizierbar. Beispiel: Definiere eine Zufallsvariable $X$ als die Augenzahl beim Wurf eines fairen Würfels. $X$ kann die Werte $[1,2,3,4,5,6]$ annehmen und ist damit diskret.
Die Wahrscheinlichkeitsverteilung einer diskreten Zufallsvariablen ist eine Liste der Wahrscheinlichkeiten für jeden möglichen Wert. Sie wird auch Wahrscheinlichkeitsfunktion oder Wahrscheinlichkeitssummenfunktion (PMF) genannt. Formal: Angenommen, eine Zufallsvariable $X$ kann $k$ verschiedene Werte annehmen und $P(X = x_{i}) = p_{i}$. Dann müssen die Wahrscheinlichkeiten $p_{i}$ Folgendes erfüllen:
1: 0 < $p_{i}$ < 1 für jedes $i$
2: $p_{1} + p_{2} + ... + p_{k} = 1$.
Beispiele für diskrete Verteilungen sind u. a. die Bernoulli-, Binomial- und Poisson-Verteilung.
Eine stetige Zufallsvariable nimmt unendlich viele mögliche Werte an. Beispiel: Definiere $X$ als Körpergröße der Schüler in einer Klasse. Da die stetige Zufallsvariable über einem Intervall definiert ist, wird sie durch die Fläche unter einer Kurve (bzw. das Integral) dargestellt.
Die Wahrscheinlichkeitsverteilung einer stetigen Zufallsvariablen, die sogenannten Wahrscheinlichkeitsdichtefunktionen (PDFs), sind Funktionen, die stetige Werte annehmen. Die Wahrscheinlichkeit, genau einen einzelnen Wert zu beobachten, ist $0$, da unendlich viele Werte möglich sind. Sei $X$ über einem Intervall der reellen Zahlen definiert. Dann ist die Wahrscheinlichkeit, dass $X$ in der Ergebnismenge $A$ liegt, $P(A)$, als Fläche über $A$ und unter einer Kurve definiert. Diese Kurve, die eine Funktion $p(x)$ darstellt, muss Folgendes erfüllen:
1: Die Kurve nimmt keine negativen Werte an $(p(x) > 0$ für alle $x$)
2: Die gesamte Fläche unter der Kurve ist gleich $1$.
Eine Kurve, die diese Anforderungen erfüllt, nennt man Dichtekurve. Beispiele für stetige Verteilungen sind die Normal-, Exponential- und Beta-Verteilung.
Außerdem taucht in der Literatur oft die Kumulative Verteilungsfunktion (CDF) auf, die du kennen solltest. Alle Zufallsvariablen (diskret und stetig) haben eine kumulative Verteilungsfunktion. Sie gibt für jeden Wert $x$ die Wahrscheinlichkeit an, dass die Zufallsvariable $X$ kleiner oder gleich $x$ ist. Für diskrete Zufallsvariablen erhält man die CDF durch Aufsummieren der Wahrscheinlichkeiten.
Im nächsten Abschnitt lernst du einige wichtige Verteilungen kennen und setzt sie in Python um. Zuvor importierst du aber die nötigen Bibliotheken.
# for inline plots in jupyter
%matplotlib inline
# import matplotlib
import matplotlib.pyplot as plt
# for latex equations
from IPython.display import Math, Latex
# for displaying images
from IPython.core.display import Image
# import seaborn
import seaborn as sns
# settings for seaborn plotting style
sns.set(color_codes=True)
# settings for seaborn plot sizes
sns.set(rc={'figure.figsize':(5,5)})
Code aus diesem Tutorial online ausführen und bearbeiten
Code ausführenLerne Python kostenlos
Einführung in die Statistik
Gleichverteilung
Eine der einfachsten und zugleich nützlichen Verteilungen ist die Gleichverteilung. Die Wahrscheinlichkeitsdichtefunktion der stetigen Gleichverteilung lautet:

Da jedes Intervall gleicher Breite mit der gleichen Wahrscheinlichkeit beobachtet wird, ist die Kurve ein Rechteck: konstante Höhe über dem Intervall und außerhalb 0. Weil die Fläche unter der Kurve 1 sein muss, bestimmt die Intervalllänge die Höhe der Kurve. Die folgende Abbildung zeigt eine Gleichverteilung im Intervall (a,b). Da die Fläche $1$ sein muss, ist die Höhe $1/(b-a)$.

Gleichverteilung in Python
Du kannst die Gleichverteilung in Python mithilfe eines Zufallszahlengenerators über einem Intervall (a,b) visualisieren. Importiere dazu die Funktion uniform aus dem Modul scipy.stats.
# import uniform distribution
from scipy.stats import uniform
Die Funktion uniform erzeugt eine stetige Gleichverteilung im angegebenen Intervall über die Argumente loc und scale. Die Verteilung ist zwischen loc und loc + scale konstant. Mit size legst du die Anzahl der Zufallswerte fest. Für reproduzierbare Ergebnisse kannst du ein random_state setzen.
# random numbers from uniform distribution
n = 10000
start = 10
width = 20
data_uniform = uniform.rvs(size=n, loc = start, scale=width)
Mit Seaborns distplot zeichnest du ein Histogramm der erzeugten Verteilung. distplot bietet zahlreiche Argumente zur Anpassung: Du erzeugst zuerst ein Plot-Objekt ax, gibst die Anzahl der bins vor, wählst die color und aktivierst mit kde die Dichteschätzung. Über hist_kws passt du z. B. die Linienbreite an. Achsenbeschriftungen setzt du mit xlabel und ylabel.
ax = sns.distplot(data_uniform,
bins=100,
kde=True,
color='skyblue',
hist_kws={"linewidth": 15,'alpha':1})
ax.set(xlabel='Uniform Distribution ', ylabel='Frequency')
[Text(0,0.5,u'Frequency'), Text(0.5,0,u'Uniform Distribution ')]

Normalverteilung
Die Normalverteilung, auch Gauß-Verteilung, ist in der Data Science allgegenwärtig – besonders bei statistischer Inferenz. Viele Algorithmen setzen sie voraus.
Eine Normalverteilung hat eine glockenförmige Dichtekurve, beschrieben durch ihren Mittelwert $μ$ und ihre Standardabweichung $σ$. Die Kurve ist symmetrisch um den Mittelwert, die Streuung wird durch $σ$ bestimmt: Werte nahe dem Mittel sind häufiger als weit entfernte. Die Wahrscheinlichkeitsdichte einer Normalverteilung mit $μ$ und $σ$ an der Stelle $x$ ist gegeben durch:

Die folgende Abbildung zeigt die Form der Verteilung:

Etwa 68% der Daten liegen innerhalb einer Standardabweichung um den Mittelwert, etwa 95% innerhalb von zwei. Eine Verteilung mit Mittelwert $0$ und Standardabweichung $1$ heißt Standardnormalverteilung.
Normalverteilung in Python
Eine normalverteilte Zufallsvariable erzeugst du mit norm.rvs() aus scipy.stats. loc entspricht dem Mittelwert, scale der Standardabweichung und size der Anzahl der Zufallswerte. Für Reproduzierbarkeit setze random_state.
from scipy.stats import norm
# generate random numbers from N(0,1)
data_normal = norm.rvs(size=10000,loc=0,scale=1)
Die Visualisierung funktioniert analog zur Gleichverteilung mit Seaborns distplot. Die Argumente haben die gleiche Bedeutung.
ax = sns.distplot(data_normal,
bins=100,
kde=True,
color='skyblue',
hist_kws={"linewidth": 15,'alpha':1})
ax.set(xlabel='Normal Distribution', ylabel='Frequency')
[Text(0,0.5,u'Frequency'), Text(0.5,0,u'Normal Distribution')]

Gamma-Verteilung
Die Gamma-Verteilung ist eine zweiparametrige Familie stetiger Verteilungen. Zwar nutzt man sie seltener direkt, doch viele verbreitete Verteilungen wie Exponential-, Chi-Quadrat- oder Erlang-Verteilung sind Spezialfälle der Gamma-Verteilung. Sie kann mit einem Formparameter $α = k$ und einem inversen Skalenparameter $β = 1/θ$ (auch Rate-Parameter) beschrieben werden. Dabei bezeichnet $Γ(n)$ die Gamma-Funktion und ist definiert als $(n-1)!$:

Eine typische Gamma-Verteilung sieht so aus:

Gamma-Verteilung in Python
Eine gamma-verteilte Zufallsvariable erzeugst du mit gamma.rvs() aus scipy.stats; dabei ist $a$ der Formparameter. Für ganzzahliges $a$ reduziert sich die Verteilung auf Erlang; für $a=1$ auf die Exponentialverteilung. Mit loc verschiebst du die Verteilung, mit scale skalierst du sie; size legt die Anzahl der Zufallswerte fest. Für Reproduzierbarkeit setze random_state.
from scipy.stats import gamma
data_gamma = gamma.rvs(a=5, size=10000)
Die Visualisierung erfolgt wie bei der Gleichverteilung über Seaborns distplot. Die Argumente sind entsprechend identisch.
ax = sns.distplot(data_gamma,
kde=True,
bins=100,
color='skyblue',
hist_kws={"linewidth": 15,'alpha':1})
ax.set(xlabel='Gamma Distribution', ylabel='Frequency')
[Text(0,0.5,u'Frequency'), Text(0.5,0,u'Gamma Distribution')]

Exponentialverteilung
Die Exponentialverteilung beschreibt die Zeit zwischen Ereignissen in einem Poisson-Prozess, also wenn Ereignisse kontinuierlich und unabhängig mit konstanter durchschnittlicher Rate auftreten. Ihr Parameter ist $λ$ (Rate-Parameter), und die Gleichung lautet:

Eine abnehmende Exponentialverteilung sieht so aus:

Exponentialverteilung in Python
Eine exponentialverteilte Zufallsvariable erzeugst du mit expon.rvs() aus scipy.stats. Das Argument scale entspricht in der Formel 1/lambda. Mit loc verschiebst du die Verteilung, size legt die Anzahl der Zufallswerte fest. Für Reproduzierbarkeit setze random_state.
from scipy.stats import expon
data_expon = expon.rvs(scale=1,loc=0,size=1000)
Die Visualisierung mit Seaborn liefert folgende Kurve:
ax = sns.distplot(data_expon,
kde=True,
bins=100,
color='skyblue',
hist_kws={"linewidth": 15,'alpha':1})
ax.set(xlabel='Exponential Distribution', ylabel='Frequency')
[Text(0,0.5,u'Frequency'), Text(0.5,0,u'Exponential Distribution')]

Poisson-Verteilung
Die Poisson-Zufallsvariable wird typischerweise genutzt, um die Anzahl von Ereignissen in einem Zeitintervall zu modellieren. Beispiel: die Zahl der Website-Besuche in einem Intervall. Die Poisson-Verteilung wird durch die Rate ($μ$) der Ereignisse beschrieben. Ein Ereignis kann 0, 1, 2, … Mal im Intervall auftreten. Der erwartete Wert pro Intervall ist $λ$ (Lambda), die Ereignisrate bzw. der Rate-Parameter. Die Wahrscheinlichkeit, $k$ Ereignisse in einem Intervall zu beobachten, ist gegeben durch:

Hinweis: Die Normalverteilung ist ein Grenzfall der Poisson-Verteilung für $λ →∞$. Folgen die Zwischenzeiten zwischen zufälligen Ereignissen einer Exponentialverteilung mit Rate $λ$, dann folgt die Gesamtzahl der Ereignisse in einer Zeitspanne der Länge $t$ einer Poisson-Verteilung mit Parameter $λt$.
Die folgende Abbildung zeigt eine typische Poisson-Verteilung:

Poisson-Verteilung in Python
Eine Poisson-verteilte diskrete Zufallsvariable erzeugst du mit poisson.rvs() aus scipy.stats. Das Formargument ist $μ$ und entspricht dem $λ$ in der Formel. Mit loc verschiebst du die Verteilung, size legt die Anzahl der Zufallswerte fest. Für Reproduzierbarkeit setze random_state.
from scipy.stats import poisson
data_poisson = poisson.rvs(mu=3, size=10000)
Die Visualisierung erfolgt wie bei der Gleichverteilung mit Seaborns distplot. Die Argumente bleiben gleich.
ax = sns.distplot(data_poisson,
bins=30,
kde=False,
color='skyblue',
hist_kws={"linewidth": 15,'alpha':1})
ax.set(xlabel='Poisson Distribution', ylabel='Frequency')
[Text(0,0.5,u'Frequency'), Text(0.5,0,u'Poisson Distribution')]

Binomialverteilung
Eine Verteilung, bei der es nur zwei mögliche Ausgänge gibt – etwa Erfolg oder Misserfolg, Gewinn oder Verlust – und bei der die Erfolgswahrscheinlichkeit in allen Versuchen gleich ist, nennt man Binomialverteilung. Die Ausgänge müssen nicht gleich wahrscheinlich sein; zudem sind die Versuche unabhängig. Die Parameter der Binomialverteilung sind $n$ und $p$, wobei $n$ die Anzahl der Versuche und $p$ die Erfolgswahrscheinlichkeit pro Versuch ist. Die Wahrscheinlichkeitsfunktion lautet:

wobei gilt:

Binomialverteilung in Python
Eine binomialverteilte diskrete Zufallsvariable erzeugst du mit binom.rvs() aus scipy.stats. Die Formparameter sind $n$ (Anzahl der Versuche) und $p$ (Erfolgswahrscheinlichkeit). Mit loc verschiebst du die Verteilung; size gibt an, wie oft die Versuche wiederholt werden. Für Reproduzierbarkeit setze random_state.
from scipy.stats import binom
data_binom = binom.rvs(n=10,p=0.8,size=10000)
Die Visualisierung der erzeugten Verteilung mit Seaborns distplot liefert folgendes Histogramm:
ax = sns.distplot(data_binom,
kde=False,
color='skyblue',
hist_kws={"linewidth": 15,'alpha':1})
ax.set(xlabel='Binomial Distribution', ylabel='Frequency')
[Text(0,0.5,u'Frequency'), Text(0.5,0,u'Binomial Distribution')]

Hinweis: Da die Erfolgswahrscheinlichkeit größer als $0.5$ ist, ist die Verteilung nach rechts schief. Die Poisson-Verteilung ist ein Grenzfall der Binomialverteilung unter folgenden Bedingungen:
- Die Anzahl der Versuche ist sehr groß, $n → ∞$.
- Die Erfolgswahrscheinlichkeit pro Versuch ist gleich und sehr klein, $p → 0$.
- $np = λ$ ist endlich.
Die Normalverteilung ist ein weiterer Grenzfall der Binomialverteilung unter folgenden Bedingungen:
- Die Anzahl der Versuche ist sehr groß, $n → ∞$.
- Sowohl $p$ als auch $q$ sind nicht sehr klein.
Bernoulli-Verteilung
Die Bernoulli-Verteilung hat nur zwei mögliche Ausgänge, nämlich $1$ (Erfolg) und $0$ (Misserfolg), und genau einen Versuch, z. B. einen Münzwurf. Die Zufallsvariable $X$ mit Bernoulli-Verteilung nimmt den Wert $1$ mit der Erfolgswahrscheinlichkeit $p$ und den Wert $0$ mit der Misserfolgswahrscheinlichkeit $q$ bzw. $1-p$ an. Die Wahrscheinlichkeiten müssen nicht gleich groß sein. Die Bernoulli-Verteilung ist ein Spezialfall der Binomialverteilung mit einem einzelnen Versuch ($n=1$). Die Wahrscheinlichkeitsfunktion lautet:

Bernoulli-Verteilung in Python
Eine Bernoulli-verteilte diskrete Zufallsvariable erzeugst du mit bernoulli.rvs() aus scipy.stats. Der Formparameter ist $p$ (Erfolgswahrscheinlichkeit). Mit loc verschiebst du die Verteilung; size legt fest, wie oft der Versuch wiederholt wird. Für Reproduzierbarkeit setze random_state.
from scipy.stats import bernoulli
data_bern = bernoulli.rvs(size=10000,p=0.6)
Die Visualisierung zeigt, dass es genau zwei mögliche Ausgänge gibt:
ax= sns.distplot(data_bern,
kde=False,
color="skyblue",
hist_kws={"linewidth": 15,'alpha':1})
ax.set(xlabel='Bernoulli Distribution', ylabel='Frequency')
[Text(0,0.5,u'Frequency'), Text(0.5,0,u'Bernoulli Distribution')]

Fazit
Glückwunsch, du hast das Ende dieses Tutorials erreicht! Du hast einige gängige Wahrscheinlichkeitsverteilungen kennengelernt und gelernt, sie in Python zu erzeugen und zu plotten. Es gibt noch viele weitere Verteilungen zu entdecken, aber für den Einstieg reicht das aus. Schau dir unbedingt die Python-Bibliothek scipy an – sie bietet noch viele weitere nützliche Statistikfunktionen. Viel Spaß beim Entdecken!
Wenn du mehr über Wahrscheinlichkeit in Python lernen möchtest, besuche den DataCamp-Kurs Statistical Simulation in Python.
Sieh dir auch unser Tutorial Poker Probability and Statistics with Python an.