Mathematik für Biologiestudierende II¶

Sommersemester 2024

04.06.2024

© 2024 Prof. Dr. Rüdiger W. Braun

Vorlesungsevaluation¶

  • Bitte füllen Sie den Evaluationsbogen aus
  • Der Bogen hat drei Seiten, die als zwei getrennte Blätter durchgereicht werden
  • Bitte stecken Sie den ausgefüllten Bogen in den Briefumschlag, der durch die Reihen geht
Nr Tag Zeit Leitung Nr Tag Zeit Leitung
1 Di 14:30 Adams 6 Do 12:30 Dreher (online)
2 Do 10:30 Dubovci 7 Do 17:30 Dreher (online)
3 Do 11:30 Dubovci 8 Fr 11:30 Mones
4 Di 13:30 Adams 9 Fr 12:30 Mones
5 Mi 12:30 Pukhova
In [1]:
import numpy as np
import pandas as pd
from scipy import stats
import seaborn as sns
sns.set_theme()

Korrelation¶

  • Eine Korrelation zwischen zwei Datensätzen ist eine gemeinsame oder gegenläufige Tendenz.
  • Beispielsweise steigt der Blutdruck tendenziell mit dem Alter.
  • Gemessen wird die Korrelation durch den empirischen Korrelationskoeffizienten.
  • Der empirischen Korrelationskoeffizient beantwortet die Frage
 Gibt es eine Korrelation?
  • Die Antwort ist "ja", wenn der empirische Korrelationskoeffizient nahe bei $1$ oder bei $-1$ liegt.

Empirischer Korrelationskoeffizient¶

  • Kennzahl zur Überprüfung gemeinsamer Tendenz
  • $s_x$ sei die Stichprobenstreuung der $x_j$ und $s_y$ die Stichprobenstreuung der $y_j$
  • dann ist der empirische Korrelationskoeffizient gleich $$ r = \frac{\text{covar}_{\text{emp}}(x,y)}{s_x \cdot s_y} $$
  • Der Korrelationskoeffizient ist dimensionslos

Beispiel: Blutdruckdaten¶

Wir hatten in der letzten Woche die Kovarianz für die Blutdruckdaten bestimmt

In [2]:
df = pd.read_csv('blutdruckdaten.csv')
df.cov()
Out[2]:
Alter Blutdruck Größe
Alter 231.131034 348.572414 36.128966
Blutdruck 348.572414 750.271264 69.805057
Größe 36.128966 69.805057 28.617195
In [3]:
df.describe()
Out[3]:
Alter Blutdruck Größe
count 30.000000 30.000000 30.000000
mean 44.800000 147.933333 176.373333
std 15.202994 27.391080 5.349504
min 17.000000 108.000000 165.300000
25% 37.250000 125.250000 173.350000
50% 45.000000 144.500000 176.650000
75% 56.000000 173.250000 179.075000
max 69.000000 199.000000 189.000000
In [4]:
cor = 348.57 / (15.203*27.391)
cor
Out[4]:
0.837052741260317

Berechnung mit pandas¶

In [5]:
df.corr()
Out[5]:
Alter Blutdruck Größe
Alter 1.000000 0.837056 0.444235
Blutdruck 0.837056 1.000000 0.476392
Größe 0.444235 0.476392 1.000000

Interpretation¶

Der Korrelationskoeffizient zeigt an, ob zwei Datensätze eine gemeinsame Tendenz aufweisen

  • wenn er nahe bei $1$ liegt, dann wachsen $x$ und $y$ gemeinsam (gemeinsame Tendenz)
  • wenn er nahe bei $-1$ liegt, dann fällt $y$, wenn $x$ wächst (gegenläufige Tendenz)
  • wenn er nahe bei $0$ liegt, dann gibt es kein gemeinsames Verhalten
  • auch ein negativer Korrelationskoeffizient hat eine Bedeutung
  • Beispiel: Je weniger Pestizide ich im Garten ausbringe, desto mehr Bienen habe ich

Beispiele¶

Sehr gute Korrelation¶

In [6]:
df1 = pd.DataFrame()
P = stats.norm()
df1['x'] = np.arange(30)
df1['y'] = -2*df1['x'] + P.rvs(size=30)
df1
Out[6]:
x y
0 0 0.817915
1 1 -0.984298
2 2 -3.775090
3 3 -6.125030
4 4 -8.319028
5 5 -11.003132
6 6 -11.809764
7 7 -13.118088
8 8 -14.341614
9 9 -18.172484
10 10 -19.242826
11 11 -22.360211
12 12 -26.361336
13 13 -25.407310
14 14 -27.765344
15 15 -28.871056
16 16 -32.861575
17 17 -33.346099
18 18 -35.740095
19 19 -38.113468
20 20 -41.292656
21 21 -41.391056
22 22 -44.840173
23 23 -44.915220
24 24 -48.043995
25 25 -50.034775
26 26 -52.250311
27 27 -54.097706
28 28 -56.108222
29 29 -57.821771
In [7]:
sns.regplot(df1, x='x', y='y');
No description has been provided for this image
In [8]:
df1.corr()
Out[8]:
x y
x 1.000000 -0.998955
y -0.998955 1.000000

schlechte Korrelation¶

In [9]:
df2 = pd.DataFrame()
df2['x'] = np.arange(30)
df2['y'] = P.rvs(size=30)
df2
Out[9]:
x y
0 0 -0.596320
1 1 1.955290
2 2 -1.423429
3 3 0.916467
4 4 0.249895
5 5 -0.196226
6 6 -0.958411
7 7 -0.217308
8 8 1.946565
9 9 -0.041887
10 10 0.904979
11 11 -0.926685
12 12 0.272166
13 13 1.185755
14 14 -0.819968
15 15 -0.401578
16 16 -0.480274
17 17 -0.057313
18 18 -0.322542
19 19 0.184700
20 20 1.114620
21 21 -1.145277
22 22 -0.038550
23 23 0.601807
24 24 0.152455
25 25 0.182674
26 26 -0.723546
27 27 0.999886
28 28 -1.152555
29 29 -0.738527
In [10]:
sns.regplot(df2, x='x', y='y');
No description has been provided for this image
In [11]:
df2.corr()
Out[11]:
x y
x 1.000000 -0.147891
y -0.147891 1.000000
  • Man kann immer eine lineare Regression berechnen. Bei schlechter Korrelation ist sie allerdings bedeutungslos.

Regression zum Mittelwert¶

  • Der Begriff Regression kommt von Francis Galton, einem Neffen von Charles Darwin
  • Er hatte den auf der nächsten Folie gezeigten Datensatz analysiert
  • Auf der $x$-Achse stehen die Größen der Väter in Zoll
  • Auf der $y$-Achse stehen die Größen der Söhne in Zoll

Daten von F. Galton

Regression zum Mittelwert: Interpretation¶

  • Die Söhne ungewöhnlich großer oder kleiner Väter sind im Mittel selbst zwar auch größer bzw. kleiner als der Mittelwert, aber diese Differenz ist kleiner als bei den Vätern
  • Galton bezeichnet dies (ziemlich unfreundlich) als "Regression to mediocrity"
  • Das gilt aber nur für die Individuen, nicht für die Population als Ganzes
  • auch in der nächsten Generation gibt es wieder ungewöhnlich große Individuen, aber in anderen Familien

Korrelation $\ne$ Kausalität¶

  • Wenn der Korrelationskoeffizient von $x$ und $y$ nahe $0$ liegt, dann gibt es keinen kausalen Zusammenhang zwischen ihnen (seltene nichtlineare Pänomene mal ausgenommen)
  • Man kann aber im umgekehrten Fall von einem Korrelationskoeffizienten nahe bei $1$ nicht auf einen kausalen Zusammenhang schließen
  • Zum Beispiel nimmt seit Jahrzehnten in Deutschland sowohl die Zahl der Geburten als auch die Zahl der Störche ab
  • Der kausale Zusammenhang ist aber umstritten
  • Beispiel aus der Schlafforschung: Mittagsschlafdauern über 90 Minuten sind ungesund
  • Bei Menschen korreliert die Rechtschreibfähigkeit mit der Schuhgröße
  • zumindest bei Menschen unter zehn Jahren

xkcd Cartoon 552

Quelle: http://xkcd.com/552

Beispiel: Bleibelastung im Gewebe von Ratten¶

  • kontaminiertes Gelände: fange 10 Ratten
  • unbelastetes Vergleichsgelände: fange 10 Ratten
  • für jede Ratte wird ihr Alter in Monaten und der Bleigehalt im Gewebe bestimmt
In [12]:
df = pd.read_csv('ratten.csv')
df
Out[12]:
Alter Belastung Gelände
0 10 63 unkontaminiert
1 12 67 unkontaminiert
2 6 55 unkontaminiert
3 6 42 unkontaminiert
4 11 73 unkontaminiert
5 13 69 unkontaminiert
6 12 73 unkontaminiert
7 10 75 unkontaminiert
8 9 58 unkontaminiert
9 8 50 unkontaminiert
10 8 70 kontaminiert
11 10 60 kontaminiert
12 4 53 kontaminiert
13 4 50 kontaminiert
14 9 77 kontaminiert
15 11 78 kontaminiert
16 10 81 kontaminiert
17 8 65 kontaminiert
18 7 64 kontaminiert
19 6 67 kontaminiert
In [13]:
df_b = df[df.Gelände=='belastet']
df_u = df[df.Gelände=='unbelastet']
In [14]:
df_b.describe()
Out[14]:
Alter Belastung
count 0.0 0.0
mean NaN NaN
std NaN NaN
min NaN NaN
25% NaN NaN
50% NaN NaN
75% NaN NaN
max NaN NaN
In [15]:
df_u.describe()
Out[15]:
Alter Belastung
count 0.0 0.0
mean NaN NaN
std NaN NaN
min NaN NaN
25% NaN NaN
50% NaN NaN
75% NaN NaN
max NaN NaN
  • Es gibt einen Unterschied in der Bleibelastung; aber auch eine große Stichprobenstreuung.
In [16]:
stats.ttest_ind(df_u.Belastung, df_b.Belastung, alternative='less')
/tmp/ipykernel_22669/579058202.py:1: SmallSampleWarning: One or more sample arguments is too small; all returned values will be NaN. See documentation for sample size requirements.
  stats.ttest_ind(df_u.Belastung, df_b.Belastung, alternative='less')
Out[16]:
TtestResult(statistic=nan, pvalue=nan, df=nan)
  • Der Unterschied ist nicht signifikant.
  • Es fällt aber auf, dass die Ratten von dem belasteten Gebiet im Mittel jünger als die anderen sind.
  • Wir wollen das Alter herausrechnen
  • Steigt die Bleibelastung mit dem Alter
In [17]:
df_b.corr(numeric_only=True)
Out[17]:
Alter Belastung
Alter NaN NaN
Belastung NaN NaN
In [18]:
df_u.corr(numeric_only=True)
Out[18]:
Alter Belastung
Alter NaN NaN
Belastung NaN NaN

Wir plotten beide Regressionen in ein Bild, ähnlich wie bei distplot

In [19]:
sns.lmplot(df, x='Alter', y='Belastung', hue='Gelände');
No description has been provided for this image