data > opinion

Tom Alby

03 Verteilungen

2021-05-02


Die Altersverteilung im Book Crossing Datensatz

Wie im vorherigen Abschnitt besprochen, haben anscheinend einige der Nutzer ein falsches Alter angegeben:

summary(as.numeric(users$Age))
## Warning in summary(as.numeric(users$Age)): NAs introduced by coercion
##    Min. 1st Qu.  Median    Mean 3rd Qu.    Max.    NA's 
##    0.00   24.00   32.00   34.75   44.00  244.00  110762

In einem Histogramm wird eine Häufigkeitstabelle visualisiert, für jedes Vorkommen einer Merkmalsausprägung einer Variabble (!) wird sozusagen eine Strichliste geführt und dann die Anzahl der jeweiligen Ausprägungen in Säulen geplottet:

hist(as.numeric(users$Age), main = "Histogramm der Altersverteilung", xlab = "Alter")
## Warning in hist(as.numeric(users$Age), main = "Histogramm der
## Altersverteilung", : NAs introduced by coercion

R bestimmt dabei selbst, wie Säulen zusammengefasst werden, was nicht immer sinnvoll sein muss. Mit dem Parameter breaks kann dieses Verhalten gesteuert werden:

hist(as.numeric(users$Age), breaks=60,  main = "Histogramm der Altersverteilung", xlab = "Alter")
## Warning in hist(as.numeric(users$Age), breaks = 60, main = "Histogramm der
## Altersverteilung", : NAs introduced by coercion

Das Visualisieren von Daten ist ein wichtiger Schritt in der Datenanalyse, um Muster, insbesondere die Verteilung einer Variable zu verstehen. In dem Beispiel des Book Crossing-Datensatzes wird deutlich, dass das Alter nicht normalverteilt ist, diese Verteilung wird auch auch als rechtsschief beziehungsweise linkssteil bezeichnet. Auf die Schiefe wird noch genauer eingegangen.

Die Standardnormalverteilung

Eine der bekanntesten Verteilungen ist die Normalverteilungen. Die Normalverteilung heißt nicht deswegen so, weil alle anderen Verteilungen oder alles Nichtnormalverteilte nicht normal wären. Vielmehr heißt sie so, weil der belgische Wissenschaftler Adolphe Quetelet bei der Vermessung von Tausenden von Soldaten Normalverteilungen entdeckte und daher wahrscheinlich den Begriff prägte. Eine Normalverteilung ist dadurch geprägt, dass die Häufigkeitsverteilung der Werte einer symmetrischen Glockenkurve entspricht:

x <- rnorm(1000000, 3, .25)
hist(x, breaks=100)

Sie ist nicht nur deswegen interessant, weil die Messung mancher Phänomene zu einer Normalverteilung führen kann, sondern weil sie uns auch einen Hinweis auf einen Erwartungswert gibt.

Lageparameter

Informationen über einen Datensatz bietet auch der Befehl summary wie in der ersten Session besprochen.

summary(x)
##    Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
##   1.770   2.831   3.000   3.000   3.169   4.174

Median und Mean sind in diesem Beispiel gleich oder zumindest sehr nah beieinander, was eine Charakteristik einer Normalverteilung ist. Mit dem Mean ist das arithmetische Mittel gemeint, häufig einfach als Durchschnitt bezeichnet. Der Median ist der mittlere Wert, wenn alle Werte sortiert aufgereiht werden und dann bei einer nicht-geraden Zahl genau der Wert in der Mitte oder bei einer geraden Zahl das arithmetische Mittel der beiden Zahlen in der Mitte gebildet wird:

x <- c(2,2,2,2,2,2,2,2,2,2,100)
mean(x)
## [1] 10.90909
median(x)
## [1] 2

Der Median ist weniger anfällig für Ausreißer als der Durchschnitt. Tatsächlich ist der Durchschnitt nur dann spannend, wenn eine Normalverteilung vorliegt, ansonsten kann er in die Irre führen.

Nicht durch den Befehl summary generiert, aber dennoch wichtig ist der Modalwert beziehungsweise Modus. Dies ist der häufigste Wert in einer Verteilung. Auch dieser ist in einer Normalverteilung gleich dem Median und dem Durchschnitt.

Diese Lageparameter beschreiben Zentren der Verteilung, allein durch die Lageparameter kann eine Verteilung bereits eingeschätzt werden.

Varianz und Standardabweichung

Oft interessiert uns aber auch, wie breit die Streuung um den Mittelwert ist. Dazu bedienen wir uns der sogenannten Standardabweichung. Die Standardabweichung ist so etwas wie der Durchschnitt der Abweichungen, allerdings werden bei einem Durchschnitt die einzelnen Werte summiert und dann durch die Anzahl der Werte geteilt. Da wir sowohl positive als auch negative Werte haben, würde das hier nicht funktionieren. Der Trick ist nun, dass wir erst einmal alle Werte quadrieren und dann summieren und durch die Anzahl der Elemente teilen. Das ist die sogenannte Varianz:

var(x)
## [1] 873.0909

Das Problem mit der Varianz ist allerdings, dass sie eine andere Metrik hat. Wenn vorher die Länge von Bohnen in Zentimetern gemessen und deren Varianz berechnet wird, dann ist die quadrierte Summe was? Wird aus diesem Wert widerum die Wurzel gezogen, ergibt dies die Standardabweichung, die in derselben Metrik ist wie die Ursprungswerte.

In einer Formel ausgedrückt:

\[\sigma_x = \sqrt{\frac{1}{n} \sum_{i=1}^{n} (x_i - \bar{x})^2}\]

In R müssen wir natürlich nicht erst die Varianz berechnen und davon dann die Standardabweichung, hier geht das alles mit einem Befehl:

sd(x)
## [1] 29.54811

95% aller Werte einer Normalverteilung liegen zwischen +/- 1.96 Standardabweichungen (manchmal sagt man auch einfach zwei Standardabweichungen, weil man sich das besser merken kann, aber es sind wirklich nur 1,96). Mit anderen Worten, wenn wir einen Wert aus einer Population haben, dann liegt die Wahrscheinlichkeit bei 95%, dass dieser Wert aus den Werten innerhalb von +/- 1.96 Standardabweichungen kommt. Dieses Prinzip spielt eine wichtige Rolle für weitere Verfahren in der Datenanalyse, siehe vor allem die Stichprobenverteilung des Mittelwerts.

Die Wahrscheinlichkeitsdichtefunktion

Im April 2021 veröffentlichte die Hamburger Morgenpost einen Artikel über die Häufigkeit von Corona-Fällen in verschiedenen Hamburger Stadtteilen:

Die Daten stammen von den Behörden Hamburgs, der Datensatz kann hier heruntergeladen werden. Hier wird eine bereits bereinigte Version des Datensatzes verwendet:

corona_hamburg <- read_csv("data/corona-hamburg.csv", 
    col_types = cols(`Inzidenz jemals` = col_integer(), 
        `Summe jemals` = col_integer(), Einwohner = col_integer()))
## Warning: 6 parsing failures.
## row             col   expected actual                      file
##  15 Inzidenz jemals an integer   null 'data/corona-hamburg.csv'
##  15 Einwohner       an integer   #NV  'data/corona-hamburg.csv'
##  84 Summe jemals    an integer   null 'data/corona-hamburg.csv'
##  89 Inzidenz jemals an integer   null 'data/corona-hamburg.csv'
##  89 Summe jemals    an integer   null 'data/corona-hamburg.csv'
## ... ............... .......... ...... .........................
## See problems(...) for more details.
corona_hamburg
## # A tibble: 101 x 4
##    Namen             `Inzidenz jemals` `Summe jemals` Einwohner
##    <chr>                         <int>          <int>     <int>
##  1 Billbrook                      4425             77      1740
##  2 Billstedt                      4910           3457     70410
##  3 Borgfelde                      3416            285      8343
##  4 Finkenwerder                   3097            364     11754
##  5 HafenCity                      2904            143      4925
##  6 Hamburg-Altstadt               2979             70      2350
##  7 Hamm                           2820           1081     38331
##  8 Hammerbrook                    4785            221      4619
##  9 Horn                           4250           1631     38373
## 10 Kleiner Grasbrook              5259             60      1141
## # … with 91 more rows
summary(corona_hamburg)
##     Namen           Inzidenz jemals  Summe jemals      Einwohner    
##  Length:101         Min.   :   0    Min.   :   9.0   Min.   :  506  
##  Class :character   1st Qu.:2168    1st Qu.: 147.0   1st Qu.: 5544  
##  Mode  :character   Median :2817    Median : 403.0   Median :15204  
##                     Mean   :2891    Mean   : 559.1   Mean   :19121  
##                     3rd Qu.:3324    3rd Qu.: 818.5   3rd Qu.:26904  
##                     Max.   :7978    Max.   :3457.0   Max.   :92087  
##                     NA's   :2       NA's   :2        NA's   :2
sd(corona_hamburg$`Inzidenz jemals`,na.rm = TRUE)
## [1] 1097.231
hist(corona_hamburg$`Inzidenz jemals`, breaks = 25)

Im Vergleich dazu die Normalverteilung mit demselben Mean und Standardabweichung. Hier wird dem Histogramm der Parameter freq = FALSE hinzugefügt, so dass nicht mehr die Häufigkeit, sondern eine Dichtefunktion verwendet wird:

x <- rnorm(1000, mean = 2891, sd = 1097)
hist(x, freq = FALSE)
lines(density(x), col="red")

Dasselbe wird mit dem Corona-Datensatz vorgenommen:

hist(corona_hamburg$`Inzidenz jemals`, freq=FALSE, breaks = 30)
lines(density(corona_hamburg$`Inzidenz jemals`, na.rm = TRUE), col="red")

Offensichtlich verlaufen die Wahrscheinlichkeitsdichtefunktionen anders.

Kumulative Verteilungsfunktion (Cumulative Density Function, CDF)

Die obigen Histogramme lassen sich nur schwer miteinander vergleichen, es ist auch wenig hilfreich sie in einen Plot zu packen. Abhilfe schafft hier die kumulative Verteilungsfunktion, häufiger CDF genannt. Sie kumuliert jeden Wert, so dass in dem folgenden Beispiel gesagt werden kann, dass in einer Normalverteilung ca. 60% der Bezirke eine Inzidenz von 3.000 oder darunter haben:

plot(ecdf(x), col="green")

Legt man nun die CDF der tatsächlichen Daten darüber, so wird klarer deutlich, dass die Verteilung anders ist.

plot(ecdf(x), col="green")
lines(ecdf(corona_hamburg$`Inzidenz jemals`), col="red")

Stichprobenverteilung des Mittelwerts

Eine ganz besondere Verteilung ist die Stichprobenverteilung des Mittelwerts. Sie ist ein elementares Konzept für viele weitere Ansätze in der Statistik, so dass ein Verständnis davon notwendig ist. Gegeben sei eine Verteilung, in diesem Beispiel nicht-normalverteilt:

y <- rf(100000, df1 = 10, df2 = 20)
hist(y, breaks=30)

Daraus wird das arithmetische Mittel gezogen:

mean(y)
## [1] 1.11302

Wird nun eine Stichprobe aus der Verteilung gezogen und daraus das arithmetische Mittel berechnet, so wird dieses mit hoher Wahrscheinlichkeit nicht genau dem tatsächlichen Mittelwert entsprechen:

mean(sample(y, 30))
## [1] 1.142136

Wird nicht nur eine Stichprobe gezogen und das Mean berechnet, sondern ganz viele, so sind die arithmethischen Mittel dieser Stichproben annähernd normalverteilt (je größer die Anzahl der Stichproben ist), unabhängig von der Verteilung des Original-Datensatzes.

set.seed(234)
n = 5000

sample_means = rep(NA, n)

for(i in 1:n){
  sample_means[i] = mean(sample(y, 30))
}

hist(sample_means, breaks=20)

Genau dies besagt der Zentrale Grenzwertsatz (auch Central Limit Theorem): Ist eine Stichprobengröße groß genug (wobei das nicht genauer definiert ist, die Zahl 30 hat sich aber als robust bewiesen), so ist die Stichprobenverteilung des Mittelwerts (fast) normalverteilt.

Der Zentrale Grenzwertsatz spielt eine große Rolle in statistischen Verfahren, die einen p-Wert nutzen und wird in den nächsten Abschnitten noch mehrmals vorkommen. Dass selbst Wissenschaftler nicht immer einen p-Wert erklären können, wird in dem Video auf dieser Seite ersichtlich.

Z-Werte / Standardisierung

Standardabweichungen sind auch hilfreich, um Daten vergleichbar zu machen. In dem Beispiel des Datensatzes women sind Größe und Gewicht in zwei verschiedenen Einheiten gemessen und nicht direkt miteinander vergleichbar:

women
##    height weight
## 1      58    115
## 2      59    117
## 3      60    120
## 4      61    123
## 5      62    126
## 6      63    129
## 7      64    132
## 8      65    135
## 9      66    139
## 10     67    142
## 11     68    146
## 12     69    150
## 13     70    154
## 14     71    159
## 15     72    164

Die Standardisierung ermöglicht den Vergleich durch die Umwandlung in die Anzahl von Standardabweichungen vom Mittelwert:

\[z = \frac{(x - \bar{x})}{\sigma}\] Im Beispiel des Datensatzes women:

scale(women)
##           height     weight
##  [1,] -1.5652476 -1.4022687
##  [2,] -1.3416408 -1.2732255
##  [3,] -1.1180340 -1.0796608
##  [4,] -0.8944272 -0.8860962
##  [5,] -0.6708204 -0.6925315
##  [6,] -0.4472136 -0.4989668
##  [7,] -0.2236068 -0.3054021
##  [8,]  0.0000000 -0.1118374
##  [9,]  0.2236068  0.1462489
## [10,]  0.4472136  0.3398136
## [11,]  0.6708204  0.5978998
## [12,]  0.8944272  0.8559861
## [13,]  1.1180340  1.1140723
## [14,]  1.3416408  1.4366802
## [15,]  1.5652476  1.7592880
## attr(,"scaled:center")
##   height   weight 
##  65.0000 136.7333 
## attr(,"scaled:scale")
##    height    weight 
##  4.472136 15.498694

Standardisierte Werte werden für manche Machine Learning-Algorithmen benötigt.

Standardfehler

Zum Abschluss soll noch der Standardfehler besprochen werden, eine weitere Anwendung der Standardabweichung. Wird eine Stichprobe aus einer Grundgesamtheit genommen, so ist der Mittelwert der Stichprobe der Stichprobe nicht unbedingt der der Grundgesamtheit. Der Standardfehler gibt die Streuung des Mittelwerts einer Stichprobe vom Mittelwert der Grundgesamtheit an. Er ist zudem wichtig für die Berechnung von Konfidenzintervallen.

Ist der Mittelwert und die Standardabweichung der Grundgesamtheit bekannt, so kann der Standardfehler wie folgt berechnet werden:

\[\sigma_\bar{x} = \frac{\sigma}{\sqrt{n}}\] Ist beides nicht bekannt, so lautet die Formel:

\[\sigma_\bar{x} = \frac{s_x}{\sqrt{n}}\]