Mathematik für Biologiestudierende II¶

Sommersemester 2024

02.07.2024

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

In [1]:
import numpy as np
import pandas as pd
from scipy import stats
import statsmodels.formula.api as smf
import seaborn as sns
sns.set_theme()
import warnings
warnings.filterwarnings('ignore', message='The figure layout has changed')

Klausur¶

  • Sie können sich jetzt zur Klausur am 06.08.2024 anmelden.
  • Die Klausur dauert 120 Minuten.

Es gibt zwei verschiedene Aufgabensaätze

  • Klausur mit den Themen vor dem WS 2023/24
  • Klausur mit den Themen ab dem WS 2024/24
  • neue Klausuraufgaben bekommt
    • wer im WS 2023/24 oder im SS 2024 Übungspunkte gesammelt hat
    • wer keine Übungspunkte hat und sich im Oktober 2023 oder später erstmals im LSF zur Vorlesung angemeldet hat
  • alte Klausuraufgaben bekommt
    • wer vor dem WS 2023/24 Übungspunkte gesammelt hat
    • wer keine Übungspunkte hat und sich vor Oktober 2023 im LSF zur Vorlesung angemeldet hat
  • wer sowohl vor als auch nach Oktober 2023 Übungspunkte bekommen hat und sich anmeldet, wird von mir angeschrieben
  • Mit der Aufteilung auf die Hörsäle teile ich mit, welche Aufgaben jemand bekommen wird
  • Dann kann man widersprechen, aber bitte zügig

Themen heute¶

  • Lineare Modelle mit kategoriellen Daten
  • ANOVA als lineares Modell
  • Regression im exponentiellen Modell
  • Halblogarithmische Darstellung
  • Halbwerts- und Verdoppelungszeit

Lineare Modelle mit kategoriellen Daten¶

Wir kommen zu dem Rattenbeispiel aus Lektion 21 zurück:

  • 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 [2]:
df = pd.read_csv('ratten.csv')
In [3]:
sns.lmplot(df, x='Alter', y='Belastung', hue='Gelände');
No description has been provided for this image
  • Der t-Test zeigte keinen Unterschied zwischen den Ratten auf kontaminierten und nicht kontaminiertem Gelände.
  • Die Ratten auf dem kontaminierten Gelände sind aber im Schnitt jünger.
  • Wir wollen gleichaltrige Ratten vergleichen
In [4]:
formel = 'Belastung ~ Alter + Gelände'
modell = smf.ols(formel, df)
res = modell.fit()
In [5]:
res.summary()
Out[5]:
OLS Regression Results
Dep. Variable: Belastung R-squared: 0.673
Model: OLS Adj. R-squared: 0.635
Method: Least Squares F-statistic: 17.52
Date: Tue, 21 Jan 2025 Prob (F-statistic): 7.42e-05
Time: 10:57:26 Log-Likelihood: -63.935
No. Observations: 20 AIC: 133.9
Df Residuals: 17 BIC: 136.9
Df Model: 2
Covariance Type: nonrobust
coef std err t P>|t| [0.025 0.975]
Intercept 39.1728 5.166 7.583 0.000 28.273 50.072
Gelände[T.unkontaminiert] -11.0980 3.124 -3.552 0.002 -17.689 -4.507
Alter 3.5490 0.617 5.752 0.000 2.247 4.851
Omnibus: 1.119 Durbin-Watson: 2.547
Prob(Omnibus): 0.572 Jarque-Bera (JB): 0.408
Skew: -0.346 Prob(JB): 0.815
Kurtosis: 3.102 Cond. No. 33.2


Notes:
[1] Standard Errors assume that the covariance matrix of the errors is correctly specified.
  • Gelände[T.unkontaminiert] ist signifikant
  • Allerdings ist das der Unterschied bei Alter = 0
  • Das ist Unsinn
  • Wir vergleichen im Alter von 8 und 9 Monaten
In [6]:
anfrage = pd.DataFrame()
anfrage['Alter'] = [8,8,9,9]
anfrage['Gelände'] = ['kontaminiert', 'unkontaminiert', 'kontaminiert', 'unkontaminiert']
anfrage
Out[6]:
Alter Gelände
0 8 kontaminiert
1 8 unkontaminiert
2 9 kontaminiert
3 9 unkontaminiert
In [7]:
res.get_prediction(anfrage).summary_frame()
Out[7]:
mean mean_se mean_ci_lower mean_ci_upper obs_ci_lower obs_ci_upper
0 67.564695 2.037898 63.265107 71.864283 53.358146 81.771244
1 56.466728 2.284487 51.646882 61.286575 42.094168 70.839289
2 71.113678 2.182221 66.509596 75.717761 56.812030 85.415327
3 60.015712 2.074920 55.638014 64.393409 45.785328 74.246095
  • Relevant sind hier die Konfidenzintervalle für die Mittelwerte
  • Für beide Werte von Alter ist die untere Vertrauensgrenze für die Belastung im Gewebe der Ratten vom kontaminierten Gelände höher als die obere Vertrauensgrenze für die Ratten vom unkontaminierten Gelände
  • Zum Signifikanzniveau $\alpha = 0.95$ ist der Unterschied in der Bleibelastung signifikant

Bestimmung des p-Werts¶

  • Der p-Wert wird nur für den Unterschies beim Alter 0 ausgegeben.
  • Trick: Verlegung des Nullpunkts.
  • Im Beispiel verlegen wird den Nullpunkt auf 8 Monate.
  • Wir führen in der Tabelle also eine Spalte mit der Altersdifferenz zu 8 Monaten ein
In [8]:
df['Altersdifferenz'] = df.Alter - 8
df.head()
Out[8]:
Alter Belastung Gelände Altersdifferenz
0 10 63 unkontaminiert 2
1 12 67 unkontaminiert 4
2 6 55 unkontaminiert -2
3 6 42 unkontaminiert -2
4 11 73 unkontaminiert 3
In [9]:
formel2 = 'Belastung ~ Altersdifferenz + Gelände'
modell2 = smf.ols(formel2, df)
res2 = modell2.fit()
In [10]:
res2.summary()
Out[10]:
OLS Regression Results
Dep. Variable: Belastung R-squared: 0.673
Model: OLS Adj. R-squared: 0.635
Method: Least Squares F-statistic: 17.52
Date: Tue, 21 Jan 2025 Prob (F-statistic): 7.42e-05
Time: 10:57:26 Log-Likelihood: -63.935
No. Observations: 20 AIC: 133.9
Df Residuals: 17 BIC: 136.9
Df Model: 2
Covariance Type: nonrobust
coef std err t P>|t| [0.025 0.975]
Intercept 67.5647 2.038 33.154 0.000 63.265 71.864
Gelände[T.unkontaminiert] -11.0980 3.124 -3.552 0.002 -17.689 -4.507
Altersdifferenz 3.5490 0.617 5.752 0.000 2.247 4.851
Omnibus: 1.119 Durbin-Watson: 2.547
Prob(Omnibus): 0.572 Jarque-Bera (JB): 0.408
Skew: -0.346 Prob(JB): 0.815
Kurtosis: 3.102 Cond. No. 6.48


Notes:
[1] Standard Errors assume that the covariance matrix of the errors is correctly specified.
  • Der p-Wert ist 0.002

Regression im exponentiellen Modell¶

Beispiel Covid-Erkrankungen¶

In [11]:
df = pd.read_csv('corona.csv')
df.head()
Out[11]:
Tag (im März) Anzahl
0 3 38
1 4 52
2 5 109
3 6 185
4 7 150
In [12]:
ax = sns.scatterplot(data=df, x="Tag (im März)", y="Anzahl");
No description has been provided for this image
  • Das Wachstum war exponentiell
  • Es gab aber Schankungen durch unterschiedliche Verzögerungen der Berichte der Gesundheitsämter

Halblogarithmische Darstellung¶

Bei halblogarithmischer Darstellung

  • ist die $x$-Achse linear skaliert: Gleiche absolute Zuwächse pro Längeneinheit
  • ist die $y$-Achse logarithmisch skaliert: Gleiche relative Zuwächse pro Längeneinheit
  • Das bedeutet: Der Logarithmus der Daten wird angezeigt, und die $y$-Achse wird entsprechend unterteilt
  • Exponentiell wachsende Daten liegen bei halblogarithmischer Darstellung annäherend auf einer wachsenden Geraden, exponentiell fallende auf einer fallenden Geraden
In [13]:
ax.set_yscale('log')
ax.figure
Out[13]:
No description has been provided for this image

Exponentielles Modell vs. Lineare Regression¶

  • Lineares Modell: in gleichen Zeitabständen gleiche absolute Zuwächse
  • Exponentielles Modell: in gleichen Zeitabständen gleiche relative Zuwächse
  • Biologische Wachstums- oder Abklingprozesse verlaufen meistens exponentiell
  • Aufgabe der Regression im exponentiellen Modell ist es, bei Wachstumsprozessen die Verdoppelungszeit und bei Abklingprozessen die Halbwertszeit zu bestimmen
  • Dies geschieht, indem man die Werte logarithmiert und dann deren lineare Regression berechnet

Regression im exponentiellen Modell¶

  • $x$ die Zeit, $z$ Daten, die exponentiell wachsen (bzw. abklingen)
  • Modellgleichung für Wachstumsprozess: $$ z = c \cdot e^{m\cdot x} $$
  • logarithmierte Modellgleichung $$ y = \ln(z) = \ln(c) + m \cdot x $$
  • bestimme diese Gerade durch lineare Regression
  • wenn $m < 0$, dann Abklingprozess
In [14]:
df['logAnzahl'] = np.log(df.Anzahl)
df['Tag'] = df['Tag (im März)']
In [15]:
formel = 'logAnzahl ~ Tag'
modell = smf.ols(formel, df)
res = modell.fit()
In [16]:
res.summary()
Out[16]:
OLS Regression Results
Dep. Variable: logAnzahl R-squared: 0.960
Model: OLS Adj. R-squared: 0.958
Method: Least Squares F-statistic: 458.1
Date: Tue, 21 Jan 2025 Prob (F-statistic): 9.25e-15
Time: 10:57:26 Log-Likelihood: -2.9636
No. Observations: 21 AIC: 9.927
Df Residuals: 19 BIC: 12.02
Df Model: 1
Covariance Type: nonrobust
coef std err t P>|t| [0.025 0.975]
Intercept 3.4410 0.151 22.728 0.000 3.124 3.758
Tag 0.2260 0.011 21.403 0.000 0.204 0.248
Omnibus: 0.968 Durbin-Watson: 1.597
Prob(Omnibus): 0.616 Jarque-Bera (JB): 0.816
Skew: -0.438 Prob(JB): 0.665
Kurtosis: 2.594 Cond. No. 34.1


Notes:
[1] Standard Errors assume that the covariance matrix of the errors is correctly specified.
  • m = 0.226
  • b = 3.441

Die Regressionsgerade für die logarithmierten Daten ist $$ y = 0.226 \cdot x + 3.441 $$

In [17]:
tage = np.arange(3, 24)
gerade = 0.226*tage + 3.441
In [18]:
titel = "Die logarithmierten Daten zusammen mit ihrer Regressionsgerade"
ax2 = sns.scatterplot(x=df.Tag, y=df.logAnzahl)
sns.lineplot(x=tage, y=gerade)
ax2.set_title(titel);
No description has been provided for this image
In [19]:
titel = "Die exponentierte Regressionskurve zusammen mit den Ausgangsdaten in halblogarithmischer Darstellung"
sns.lineplot(x=tage, y=np.exp(gerade), ax=ax)
ax.set_title(titel)
ax.figure
Out[19]:
No description has been provided for this image
In [20]:
titel = "Die exponentierte Regressionskurve zusammen mit den Ausgangsdaten in linearer Darstellung"
ax.set_title(titel)
ax.set_yscale('linear')
ax.figure
Out[20]:
No description has been provided for this image

Halbwerts- bzw. Verdoppelungszeit¶

  • Modell eines Wachstumsprozesses $$ z = c \cdot e^{m\cdot x} $$
  • Verdoppelungszeit $t$ bestimmt durch $$ e^{m\cdot t} = 2 $$
  • Also $$ t = \frac{\ln 2}m $$
  • Bei Abklingprozessen ist $m < 0$, dann ist $$ t = -\frac{\ln 2}m $$ die Halbwertszeit

Im Beispiel Covid

In [21]:
m = 0.226
In [22]:
t = np.log(2) / m
t
Out[22]:
3.067022922831616

Die Verdoppelungszeit beträgt 3.07 Tage