Mathematik für Biologiestudierende II¶
Sommersemester 2025
06.05.2025
© 2025 Prof. Dr. Rüdiger W. Braun
In [1]:
import numpy as np
np.set_printoptions(legacy='1.21')
import pandas as pd
from scipy import stats
import seaborn as sns
sns.set_theme()
Themen¶
- Alexander-Govern-Test
Alexander-Govern-Test¶
Beispiel: Barsche¶
Es werden Barsche gleichen Alters verglichen
In [2]:
df = pd.read_csv('barsche.csv')
df.head()
Out[2]:
Art | Länge | |
---|---|---|
0 | gestreift | 9.890006 |
1 | gestreift | 9.343944 |
2 | gestreift | 9.867069 |
3 | gestreift | 10.302781 |
4 | gestreift | 10.066964 |
In [3]:
sns.boxplot(df, x="Art", y="Länge");
Alexander-Govern-Test¶
Wenn die Daten heteroskedastisch, aber normalverteilt sind, dann rechnet man einen Alexander-Govern-Test
In [4]:
ds = df[df.Art=='gestreift'].Länge
dl = df[df.Art=='gefleckt'].Länge
db = df[df.Art=='blau'].Länge
dr = df[df.Art=='braun'].Länge
In [5]:
stats.alexandergovern(ds, dl, dr, db)
Out[5]:
AlexanderGovernResult(statistic=113.40810114676775, pvalue=2.02668339537414e-24)
Welch-Test¶
- Der t-Test kann nur gerechnet werden, wenn die Varianzen der zu vergleichenden Datensätze übereinstimmen
- Im heteroskedastischen Fall ist das nicht der Fall
- Man rechnet dann einen Welch-Test
- In scipy ist der Welch-Test wie folgt implementiert
In [6]:
stats.ttest_ind(db, dr, equal_var=False)
Out[6]:
TtestResult(statistic=9.647287139857793, pvalue=1.2289650206522807e-13, df=57.645418945809595)
equal_var=True
: dann wird ein unverbundener t-Test gerechnetequal_var=False
: dann wird ein Welch-Test gerechnet
- Standardeinstellung ist
equal_var=True
In [7]:
from statsmodels.sandbox.stats.multicomp import MultiComparison
In [8]:
muc = MultiComparison(df.Länge, df.Art)
muc.allpairtest(stats.ttest_ind)
würde einen t-Test rechnen- wir können den Schalter
equal_var=False
nicht ohne weiteres übergeben
- wir werden uns ein winziges Programm schreiben
Python-Funktionen¶
In [9]:
def quadrat(x):
return x*x
In [10]:
quadrat(5)
Out[10]:
25
def
definiert eine Funktion- die Rechnungen, welche aus die Funktion besteht, werden eingerückt
- der auf
return
folgende Wert ist das Funktionsergebnis
Post-hoc Analyse¶
In [11]:
def welch_test(a, b):
return stats.ttest_ind(a, b, equal_var=False)
In [12]:
res = muc.allpairtest(welch_test)[0]
res
Out[12]:
group1 | group2 | stat | pval | pval_corr | reject |
---|---|---|---|---|---|
blau | braun | 9.6473 | 0.0 | 0.0 | True |
blau | gefleckt | 5.8735 | 0.0 | 0.0 | True |
blau | gestreift | 18.752 | 0.0 | 0.0 | True |
braun | gefleckt | 0.7068 | 0.484 | 1.0 | False |
braun | gestreift | 8.4956 | 0.0 | 0.0 | True |
gefleckt | gestreift | 3.3453 | 0.002 | 0.012 | True |
In [13]:
res = muc.allpairtest(welch_test, method='holm')[0]
res
Out[13]:
group1 | group2 | stat | pval | pval_corr | reject |
---|---|---|---|---|---|
blau | braun | 9.6473 | 0.0 | 0.0 | True |
blau | gefleckt | 5.8735 | 0.0 | 0.0 | True |
blau | gestreift | 18.752 | 0.0 | 0.0 | True |
braun | gefleckt | 0.7068 | 0.484 | 0.484 | False |
braun | gestreift | 8.4956 | 0.0 | 0.0 | True |
gefleckt | gestreift | 3.3453 | 0.002 | 0.004 | True |
Normalverteilungsannahmen¶
- Sowohl
f_oneway
als auchalexandergovern
liefern nur für normalverteilte Daten richtige Ergebnisse - Normalverteilungsannahmen prüfen wir mit dem Q-Q-Plot
In [14]:
import statsmodels.api as sm
pp = sm.ProbPlot(db)
pp.qqplot();
ausreichende Übereinstimmung
Flügellängen von Libellen in mm (erfundene Daten)
In [15]:
df = pd.read_csv('libellen.csv')
df.head()
Out[15]:
Art | Länge | |
---|---|---|
0 | graue | 4.908840 |
1 | graue | 5.016692 |
2 | graue | 4.382700 |
3 | graue | 4.847548 |
4 | graue | 5.523503 |
In [16]:
sns.boxplot(df, x="Art", y="Länge");
In [17]:
dg = df[df.Art=='graue'].Länge
du = df[df.Art=='grüne'].Länge
da = df[df.Art=='ägyptische'].Länge
dB = df[df.Art=='Bilker'].Länge
In [18]:
pp = sm.ProbPlot(dB)
pp.qqplot();
nicht normalverteilt
Kruskal-Wallis-Test¶
- im Fall nicht normalverteilter Daten rechnet man den Kruskal-Wallis-Test
- dann ist es auch gleichgültig, ob die Daten heteroskedastisch sind
In [19]:
stats.kruskal(dg, du, da, dB)
Out[19]:
KruskalResult(statistic=16.028153526970982, pvalue=0.0011190121329907562)
Post-hoc Analyse¶
Das nicht-parametrische Analogon zum unverbundenen t-Test ist der Mann-Whitney-Test
In [20]:
muc = MultiComparison(df.Länge, df.Art)
In [21]:
muc.allpairtest(stats.mannwhitneyu, method='holm')[0]
Out[21]:
group1 | group2 | stat | pval | pval_corr | reject |
---|---|---|---|---|---|
Bilker | graue | 2360.0 | 0.0033 | 0.0199 | True |
Bilker | grüne | 2167.0 | 0.0544 | 0.1088 | False |
Bilker | ägyptische | 2217.0 | 0.0288 | 0.0864 | False |
graue | grüne | 1260.0 | 0.0046 | 0.0228 | True |
graue | ägyptische | 1259.0 | 0.0046 | 0.0228 | True |
grüne | ägyptische | 1561.0 | 0.2106 | 0.2106 | False |
ANOVA¶
Übersicht
Verteilungsannahmen | Test in scipy.stats |
Post-hoc-Test | in scipy.stats |
---|---|---|---|
normalverteilt, homoskedastisch | f_oneway |
unverbundener t-Test | ttest_ind |
normalverteilt, heteroskedastisch | alexandergovern |
Welch-Test | ttest_ind mitequal_var=False |
nicht normalverteilt | kruskal |
Mann-Whitney-Test | mannwhitneyu |
Test | Art |
---|---|
t-Test | parametrisch |
Welch-Test | parametrisch |
Mann-Whitney-Test | nichtparametrisch |
ANOVA | parametrisch |
Alexander-Govern-Test | parametrisch |
Kruskal-Wallis-Test | nichtparametrisch |
- die parametrischen Tests vergleichen Mittelwerte
- die nichtparametrischen Tests vergleichen Mediane