Mathematik für Biologiestudierende II¶
Sommersemester 2024
11.06.2024
© 2024 Prof. Dr. Rüdiger W. Braun
In [1]:
import numpy as np
import pandas as pd
from scipy import stats
import seaborn as sns
sns.set_theme()
Lineare Modelle¶
- eine lineare Funktion einer Variablen ist eine Funktion der Form $$ y = m \cdot x + b $$
- bei der linearen Regression besteht die Aufgabe darin, $m$ und $b$ zu bestimmen
- beim linearen Modell werden $m$ und $b$ auch bestimmt, man erhält aber zusätzlich noch ein Konfidenzintervall für sie
- Literatur: "Linear Models with Python" von Faraway
- Statsmodels: https://www.statsmodels.org/stable/user-guide.html
Wir beginnen mit den Blutdruckdaten
In [2]:
df = pd.read_csv("blutdruckdaten.csv")
df.head()
Out[2]:
| Alter | Blutdruck | Größe | |
|---|---|---|---|
| 0 | 17 | 110.0 | 165.3 |
| 1 | 19 | 125.0 | 180.0 |
| 2 | 21 | 118.0 | 177.8 |
| 3 | 23 | 119.0 | 173.3 |
| 4 | 25 | 125.0 | 173.5 |
In [3]:
sns.regplot(df, x='Alter', y='Blutdruck');
In [4]:
import statsmodels.formula.api as smf
In [5]:
formel = 'Blutdruck ~ Alter'
Das bedeutet:
- wir wollen den Blutdruck modellieren
- als einzigen unabhängigen Parameter wählen wir das Alter
In [6]:
modell = smf.ols(formel, df)
ols: ordinary least squares- Lektion 20: die Regression ist "bestmöglich" in dem Sinn, dass $$ \sum_{j=1}^n (m \cdot x_j + b - y_j)^2 $$ minimal wird
- daher der Name "Methode der kleinsten Quadrate"
In [7]:
res = modell.fit()
In [8]:
res.summary()
Out[8]:
| Dep. Variable: | Blutdruck | R-squared: | 0.701 |
|---|---|---|---|
| Model: | OLS | Adj. R-squared: | 0.690 |
| Method: | Least Squares | F-statistic: | 65.54 |
| Date: | Tue, 21 Jan 2025 | Prob (F-statistic): | 8.17e-09 |
| Time: | 10:57:17 | Log-Likelihood: | -123.27 |
| No. Observations: | 30 | AIC: | 250.5 |
| Df Residuals: | 28 | BIC: | 253.3 |
| Df Model: | 1 | ||
| Covariance Type: | nonrobust |
| coef | std err | t | P>|t| | [0.025 | 0.975] | |
|---|---|---|---|---|---|---|
| Intercept | 80.3697 | 8.798 | 9.135 | 0.000 | 62.348 | 98.391 |
| Alter | 1.5081 | 0.186 | 8.096 | 0.000 | 1.127 | 1.890 |
| Omnibus: | 2.886 | Durbin-Watson: | 2.401 |
|---|---|---|---|
| Prob(Omnibus): | 0.236 | Jarque-Bera (JB): | 1.526 |
| Skew: | 0.390 | Prob(JB): | 0.466 |
| Kurtosis: | 3.782 | Cond. No. | 149. |
Notes:
[1] Standard Errors assume that the covariance matrix of the errors is correctly specified.
- Ich werde die wichtigsten Daten aus dieser Ausgabe erkären
- aber nicht alle
zum Vergleich: wir hatten in Lektion 20 die lineare Regression zu Fuß gerechnet und für die Steigung den folgenden Wert erhalten:
In [9]:
cov = 348.57
var_x = 231.13
m = cov / var_x
np.round(m, 4)
Out[9]:
1.5081
- Das ist genau die Zahl, die in der Spalte
coefund der ZeileAltersteht
- Der Wert für den Ordinatenabschnitt (engl: "intercept") war damals
In [10]:
xq = 44.800 # Mittelwert für x
yq = 147.93 # Mittelwert für y
b = yq - m*xq
np.round(b, 4)
Out[10]:
80.3666
- Das ist die Zahl, die in der Spalte
coefund der ZeileInterceptsteht - es gibt eine kleine Abweichung durch Rundungsfehler
Wir schauen uns die Zeile Alter weiter an:
In [11]:
res.summary()
Out[11]:
| Dep. Variable: | Blutdruck | R-squared: | 0.701 |
|---|---|---|---|
| Model: | OLS | Adj. R-squared: | 0.690 |
| Method: | Least Squares | F-statistic: | 65.54 |
| Date: | Tue, 21 Jan 2025 | Prob (F-statistic): | 8.17e-09 |
| Time: | 10:57:17 | Log-Likelihood: | -123.27 |
| No. Observations: | 30 | AIC: | 250.5 |
| Df Residuals: | 28 | BIC: | 253.3 |
| Df Model: | 1 | ||
| Covariance Type: | nonrobust |
| coef | std err | t | P>|t| | [0.025 | 0.975] | |
|---|---|---|---|---|---|---|
| Intercept | 80.3697 | 8.798 | 9.135 | 0.000 | 62.348 | 98.391 |
| Alter | 1.5081 | 0.186 | 8.096 | 0.000 | 1.127 | 1.890 |
| Omnibus: | 2.886 | Durbin-Watson: | 2.401 |
|---|---|---|---|
| Prob(Omnibus): | 0.236 | Jarque-Bera (JB): | 1.526 |
| Skew: | 0.390 | Prob(JB): | 0.466 |
| Kurtosis: | 3.782 | Cond. No. | 149. |
Notes:
[1] Standard Errors assume that the covariance matrix of the errors is correctly specified.
- Der Eintrag
P>|t|bezeichnet den p-Wert für den zweiseitigen Test, dasscoefungleich 0 ist. coefist das m aus der Formel der linearen Regression
- wenn die Nullhypothese $H_0=\{m\ne0\}$ nicht abgelehnt werden kann, dann bedeutet das, dass zum Signifikanzniveau $\alpha=0.05$ nicht nachgewiesen wurde, dass das Alter überhaupt einen Einfluss auf den Blutdruck hat
- zum Vergleich fügen wir eine zufällige Zeile an
In [12]:
P = stats.norm()
df['Zufallsdaten'] = P.rvs(size=30)
In [13]:
formel2 = 'Blutdruck ~ Zufallsdaten'
modell2 = smf.ols(formel2, df)
In [14]:
res2 = modell2.fit()
res2.summary()
Out[14]:
| Dep. Variable: | Blutdruck | R-squared: | 0.004 |
|---|---|---|---|
| Model: | OLS | Adj. R-squared: | -0.031 |
| Method: | Least Squares | F-statistic: | 0.1249 |
| Date: | Tue, 21 Jan 2025 | Prob (F-statistic): | 0.726 |
| Time: | 10:57:17 | Log-Likelihood: | -141.30 |
| No. Observations: | 30 | AIC: | 286.6 |
| Df Residuals: | 28 | BIC: | 289.4 |
| Df Model: | 1 | ||
| Covariance Type: | nonrobust |
| coef | std err | t | P>|t| | [0.025 | 0.975] | |
|---|---|---|---|---|---|---|
| Intercept | 148.1211 | 5.106 | 29.010 | 0.000 | 137.662 | 158.580 |
| Zufallsdaten | -1.6736 | 4.735 | -0.353 | 0.726 | -11.374 | 8.026 |
| Omnibus: | 5.538 | Durbin-Watson: | 0.689 |
|---|---|---|---|
| Prob(Omnibus): | 0.063 | Jarque-Bera (JB): | 2.453 |
| Skew: | 0.398 | Prob(JB): | 0.293 |
| Kurtosis: | 1.847 | Cond. No. | 1.14 |
Notes:
[1] Standard Errors assume that the covariance matrix of the errors is correctly specified.
- Der Wert für
P>|t|ist größer als 0.05 - Daher kann die Nulhypothese, dass
Zufallsdatenkeinen Einfluss aufBlutdruckhat, nicht abglehent werden
In [15]:
sns.regplot(df, x='Zufallsdaten', y='Blutdruck');
Weiter mit der Zeile Alter
In [16]:
res.summary()
Out[16]:
| Dep. Variable: | Blutdruck | R-squared: | 0.701 |
|---|---|---|---|
| Model: | OLS | Adj. R-squared: | 0.690 |
| Method: | Least Squares | F-statistic: | 65.54 |
| Date: | Tue, 21 Jan 2025 | Prob (F-statistic): | 8.17e-09 |
| Time: | 10:57:17 | Log-Likelihood: | -123.27 |
| No. Observations: | 30 | AIC: | 250.5 |
| Df Residuals: | 28 | BIC: | 253.3 |
| Df Model: | 1 | ||
| Covariance Type: | nonrobust |
| coef | std err | t | P>|t| | [0.025 | 0.975] | |
|---|---|---|---|---|---|---|
| Intercept | 80.3697 | 8.798 | 9.135 | 0.000 | 62.348 | 98.391 |
| Alter | 1.5081 | 0.186 | 8.096 | 0.000 | 1.127 | 1.890 |
| Omnibus: | 2.886 | Durbin-Watson: | 2.401 |
|---|---|---|---|
| Prob(Omnibus): | 0.236 | Jarque-Bera (JB): | 1.526 |
| Skew: | 0.390 | Prob(JB): | 0.466 |
| Kurtosis: | 3.782 | Cond. No. | 149. |
Notes:
[1] Standard Errors assume that the covariance matrix of the errors is correctly specified.
- Die Einträge
[0.025und0.975]geben die untere und die obere Vertrauensgrenze des Konfidenzintervalls zum Konfidenzniveau 0.95 an
- Variante: 99%-Konfidenzintervall
- Achtung: Für Konfidenzintervall zum Konfidenzniveau $1-\alpha$ muss $\alpha$ eingegeben werden
In [17]:
res.conf_int(alpha=.01)
Out[17]:
| 0 | 1 | |
|---|---|---|
| Intercept | 56.058844 | 104.680629 |
| Alter | 0.993358 | 2.022874 |
Der Wert für $m$ in der Formel für die lineare Regression liegt mit 99% Sicherheit zwischen 0.993 und 2.034.
- Der Eintrag
tist der Wert der Teststatistik, aus dem der p-Wert bestimmt worden ist
In Lektion 21 hattenn wir den Korrelationskoeffizienten bestimmt
In [18]:
r = 0.83705
In [19]:
r**2
Out[19]:
0.7006527024999999
In [20]:
res.summary()
Out[20]:
| Dep. Variable: | Blutdruck | R-squared: | 0.701 |
|---|---|---|---|
| Model: | OLS | Adj. R-squared: | 0.690 |
| Method: | Least Squares | F-statistic: | 65.54 |
| Date: | Tue, 21 Jan 2025 | Prob (F-statistic): | 8.17e-09 |
| Time: | 10:57:17 | Log-Likelihood: | -123.27 |
| No. Observations: | 30 | AIC: | 250.5 |
| Df Residuals: | 28 | BIC: | 253.3 |
| Df Model: | 1 | ||
| Covariance Type: | nonrobust |
| coef | std err | t | P>|t| | [0.025 | 0.975] | |
|---|---|---|---|---|---|---|
| Intercept | 80.3697 | 8.798 | 9.135 | 0.000 | 62.348 | 98.391 |
| Alter | 1.5081 | 0.186 | 8.096 | 0.000 | 1.127 | 1.890 |
| Omnibus: | 2.886 | Durbin-Watson: | 2.401 |
|---|---|---|---|
| Prob(Omnibus): | 0.236 | Jarque-Bera (JB): | 1.526 |
| Skew: | 0.390 | Prob(JB): | 0.466 |
| Kurtosis: | 3.782 | Cond. No. | 149. |
Notes:
[1] Standard Errors assume that the covariance matrix of the errors is correctly specified.
- $r^2$ ist die Größe, die in
res.summary()alsR-squaredauftaucht
Anderes Beispiel: Größen von Vätern und Söhnen¶
In [21]:
df = pd.read_csv('galton.csv')
df.head()
Out[21]:
| family | father | mother | midparentHeight | children | childNum | gender | childHeight | |
|---|---|---|---|---|---|---|---|---|
| 0 | 001 | 78.5 | 67.0 | 75.43 | 4 | 1 | male | 73.2 |
| 1 | 002 | 75.5 | 66.5 | 73.66 | 4 | 1 | male | 73.5 |
| 2 | 002 | 75.5 | 66.5 | 73.66 | 4 | 2 | male | 72.5 |
| 3 | 003 | 75.0 | 64.0 | 72.06 | 2 | 1 | male | 71.0 |
| 4 | 004 | 75.0 | 64.0 | 72.06 | 5 | 1 | male | 70.5 |
Ein Datensatz zum Buch "Linear Models with Python" von Faraway
In [22]:
formel = 'childHeight ~ mother'
In [23]:
modell = smf.ols(formel, df)
In [24]:
res = modell.fit()
res.summary()
Out[24]:
| Dep. Variable: | childHeight | R-squared: | 0.104 |
|---|---|---|---|
| Model: | OLS | Adj. R-squared: | 0.102 |
| Method: | Least Squares | F-statistic: | 55.80 |
| Date: | Tue, 21 Jan 2025 | Prob (F-statistic): | 3.84e-13 |
| Time: | 10:57:17 | Log-Likelihood: | -1119.5 |
| No. Observations: | 481 | AIC: | 2243. |
| Df Residuals: | 479 | BIC: | 2251. |
| Df Model: | 1 | ||
| Covariance Type: | nonrobust |
| coef | std err | t | P>|t| | [0.025 | 0.975] | |
|---|---|---|---|---|---|---|
| Intercept | 45.8580 | 3.132 | 14.644 | 0.000 | 39.705 | 52.011 |
| mother | 0.3651 | 0.049 | 7.470 | 0.000 | 0.269 | 0.461 |
| Omnibus: | 3.813 | Durbin-Watson: | 1.353 |
|---|---|---|---|
| Prob(Omnibus): | 0.149 | Jarque-Bera (JB): | 3.794 |
| Skew: | -0.144 | Prob(JB): | 0.150 |
| Kurtosis: | 3.326 | Cond. No. | 1.77e+03 |
Notes:
[1] Standard Errors assume that the covariance matrix of the errors is correctly specified.
[2] The condition number is large, 1.77e+03. This might indicate that there are
strong multicollinearity or other numerical problems.
childHeight = 0.4465*father + 38.3626
Vorfaktor ist kleiner als 1: Regression to the mean
In [25]:
sns.regplot(df, x='father', y='childHeight')
Out[25]:
<Axes: xlabel='father', ylabel='childHeight'>
In [ ]: