Pakete und Daten einlesen¶
import pandas as pd # Datenanalyse & Einlesen (z. B. Excel, CSV)
import numpy as np # Mathematische Funktionen & Arrays
import matplotlib.pyplot as plt # Diagramme erstellen (z. B. Linien, Balken, Histogramme)
import seaborn as sns # Statistische & ästhetische Visualisierungen
from scipy.stats import ttest_ind, t, levene # t-Test, kritischer t-Wert, Levene-Test
# Daten einlesen
df = pd.read_excel("t-testUN.xlsx")
df.columns = df.columns.str.strip()
df.head()
Berechnung der Teststatistik¶
Um zu prüfen, ob die Mittelwertsunterschiede statistisch signifikant sind, muss die zugehörige Teststatistik berechnet werden. Die Verteilung der Teststatistik t folgt einer theoretischen t-Verteilung, deren Form sich in Abhängigkeit der Freiheitsgrade unterscheidet. Die dem Test zu Grunde liegende t-Verteilung gibt dem Test den Namen t-Test.
Die Teststatistik berechnet sich mit:
$$ t = \frac{\bar {X_1} - \bar {X_2}}{Standardfehler der Mittelwertsdifferenz}$$ mit:
- $\bar X_1, \bar X_2$: Mittelwerte der Variablen $X_1$ und $X_2$
- $n_1, n_2$: Stichprobengröße der beiden Stichproben.
Die Freiheitsgrade werden folgend berechnet:
$$ df = n1 + n2 -2$$
mit:
- $n_1, n_2$: Stichprobengröße der beiden Stichproben.
Es gibt zwei Arten für dieses Verfahren den Standardfehler der Mittelwertdifferenz
- $\sigma_{\bar X_1 - \bar X_2}$: Standardfehler der Mittelwertsdifferenz
- $\hat \sigma_{\bar X_1 - \bar X_2}$: Schätzer für den Standardfehler der Verteilung der Mittelwertsdifferenzen
Sind die Populationsvarianzen bekannt, so wird der Standardfehler der Mittelwertsdifferenz wie folgt berechnet:
$$\sigma_{\bar X_1 - \bar X_2} = \sqrt{\frac{\sigma^2_1}{n_1}+\frac{\sigma^2_2}{n_2}} $$ mit:
- $\sigma_{\bar X_1 - \bar X_2}$: Standardfehler der Verteilung der Mittelwertsdifferenzen
- $\sigma^2_1, \sigma^2_2$: Populationsvarianzen der Variablen $X_1$ und $X_2$
- $n_1, n_2$: Stichprobengröße der beiden Stichproben.
Sind die Populationsvarianzen unbekannt, so wird der Standardfehler der Mittelwertsdifferenz wie folgt geschätzt:
$$ \hat \sigma_{\bar X_1 - \bar X_2} = \sqrt{\frac{\hat\sigma^2_{inn}}{n_1}+\frac{\hat\sigma^2_{inn}}{n_2}} $$ mit:
- $\hat \sigma_{\bar X_1 - \bar X_2}$: Schätzer für den Standardfehler der Verteilung der Mittelwertsdifferenzen
- $n_1, n_2$: Stichprobengröße der beiden Stichproben.
- $\hat\sigma^2_{inn}$: Schätzer für die gepoolte Varianz der beiden Grundgesamtheiten.
wobei sich der Schätzer für die gepoolte Varianz der beiden Grundgesamtheiten berechnet mit:
$$ \hat\sigma^2_{inn} = \frac{(n_1 - 1)\cdot s_1^2 + (n_2-1)\cdot s_2^2}{n_1+n_2-2} $$ mit:
- $n_1, n_2$: Stichprobengröße der beiden Stichproben.
- $s_1^2, s_2^2$: Stichprobenvarianzen der Variablen $X_1$ und $X_2$
Für das vorliegende Beispiel sind die Populationsvarianzen nicht bekannt, so dass sich nach Einfügen der Werte aus Abbildung in die entsprechenden Formeln folgendes ergibt:
$$ \hat\sigma^2_{inn} = \frac{(25 - 1)\cdot 3.70^2 + (26-1)\cdot 3.74^2}{25+26-2} =\frac{(25 - 1)\cdot 3.70^2 + (26-1)\cdot 3.74^2}{49} = \frac { 678.25}{49} = 13.841 $$
$$ t = \frac{\bar {X_1} - \bar {X_2}}{ \sqrt{\frac{\hat\sigma^2_{inn}}{n_1}+\frac{\hat\sigma^2_{inn}}{n_2}} }= \frac{21.00 - 16.15}{ \sqrt{\frac{13.841}{25}+\frac{13.841}{26}}}= 4.6$$ Der Freiheitsgrad ist:
$$ df = 25 + 26 -2 = 49$$ t-kritsch
# Kritischer Wert für zweiseitigen Test (2.5% in jeder Seite)
kritischer_t = t.ppf(0.975, df=49)
print(f"Kritischer t-Wert (df=49, α=0.05): {kritischer_t:.4f}")
Kritischer t-Wert (df=49, α=0.05): 2.0096
Signifikanz der Teststatistik¶
Um zu beurteilen, ob der berechnete Wert statistisch signifikant ist, wird er mit einem kritischen Wert aus der t-Verteilung verglichen, der anhand der Freiheitsgrade bestimmt wird. Diese kritischen Werte sind in sogenannten t-Tabellen zu finden.
Die untenstehende Abbildung zeigt einen Auszug aus einer solchen Tabelle mit den kritischen Werten für die Signifikanzniveaus α = .05 und α = .01.
Im vorliegenden Fall liegt der kritische Wert bei 2.009 für df = 49 und α = .05. Da der Betrag der berechneten Teststatistik mit |4.6| deutlich über dem kritischen Wert liegt (|4.6| > 2.009), ist das Ergebnis statistisch signifikant.
Es kann somit angenommen werden, dass ein Unterschied zwischen den Mittelwerten besteht (t(49) = 4.6, p < .05, n = 51).
Hypothese¶
H1: Es gibt einen Unterschied zwischen dem Sicherheitsgefühl von Selbstständigen und Nicht-Selbstständigen. $M_{S} \ne M_{NS}$
H0: Es gibt keinen Unterschied zwischen dem Sicherheitsgefühl von Selbstständigen und Nicht-Selbstständigen.$M_{S} = M_{NS}$
Voraussetzungen des t-Tests für unabhängige Stichproben¶
Die abhängige Variable ist min. intervallskaliert -> Sicherheitsgefuehl(AV)
Es liegt eine unabhängige Variable vor, mittels der die beiden zu vergleichenden Gruppen gebildet werden. -> Ja, Selbstständigen und Nicht-Selbstständigen
Das untersuchte Merkmal ist in den Grundgesamtheiten der beiden Gruppen normalverteilt -> siehe Histogramm
Homogenität der Varianzen: Die Gruppen kommen aus Grundgesamtheiten mit annähernd identischer Varianz -> siehe Levene-Test
Die einzelnen Messwerte sind voneinander unabhängig (das Verhalten einer Versuchsperson hat keinen Einfluss auf das Verhalten einer anderen) -> ist gegeben.
Prüfung der Normalverteilung mithilfe des Histogramms¶
# Histogramm gruppiert nach 'Selbststaendig' mit Facetten (Subplots)
g = sns.displot(
data=df,
x="Sicherheitsgefuehl",
col="Selbststaendig",
hue="Selbststaendig",
binwidth=4,
kde=False,
palette="pastel",
edgecolor="#e9ecef",
alpha=0.7
)
# Beschriftung
g.set_axis_labels("Gruppierungen", "Anzahl")
g.set_titles("Gruppe: {col_name}")
g.fig.suptitle("Histogramm nach Selbstständigkeit", y=1.05)
plt.show()
Es liegt eine Normalverteilung von.
Deskriptive Statistiken¶
# Gruppierte deskriptive Statistik berechnen und runden
stats_by_group = (
df.groupby("Selbststaendig")["Sicherheitsgefuehl"]
.agg(Anzahl="count", Mittelwert="mean", Median="median", Standardabweichung="std")
.round(2)
)
display(stats_by_group)
Anzahl | Mittelwert | Median | Standardabweichung | |
---|---|---|---|---|
Selbststaendig | ||||
nicht-selbststaendig | 25 | 21.00 | 22.0 | 3.70 |
selbststaendig | 26 | 16.15 | 16.0 | 3.74 |
Es zeigt sich für diese Fragestellung einen Mittelwertsunterschied. Das Sicherheitsgefühl bei Nicht-Selbstständigen ist höher (M = 21.00 SD = 3.7, n = 25) als bei Selbstständigen (M = 16.15 SD = 3.74, n = 26).
Test auf Varianzhomogenität (Levene-Test)¶
Für die Durchführung eines t-Tests für unabhängige Gruppen ist die Annahme der Varianzhomogenität erforderlich. Wenn jedoch Varianzheterogenität – also ungleiche Varianzen – vorliegt, müssen unter anderem die Freiheitsgrade des t-Wertes angepasst werden.
Ob die Varianzen tatsächlich gleich sind, lässt sich mit dem Levene-Test überprüfen.
Der Levene-Test geht von der Nullhypothese aus, dass sich die Varianzen nicht unterscheiden. Ein nicht signifikantes Ergebnis spricht daher dafür, dass die Varianzen als gleich angenommen werden können – es liegt also Varianzhomogenität vor.
Ist das Testergebnis hingegen signifikant, deutet dies auf Varianzheterogenität hin – die Annahme gleicher Varianzen muss dann verworfen werden.
# Levene-Test: Varianzgleichheit von 'Sicherheitsgefuehl' über die Gruppen 'Selbststaendig'
stat, p = levene(
*[group['Sicherheitsgefuehl'].values # Sternchen (*) splittet die Liste in einzelne Arrays
for _, group in df.groupby('Selbststaendig')],
center='mean' # entspricht center = mean in R
)
print(f"Levene-Statistik: {stat:.4f}, p-Wert: {p:.4g}")
Levene-Statistik: 0.1566, p-Wert: 0.694
Also es ist zuerkennen, das Homogenität vorliegt, da der Levene-Test nicht signifikant ist. Daher können wir von gleichen Varianzen ausgehen (F(1, 49) = .1566, p = .694). Es ist daher nicht notwendig eine Welch-Korrektur durchzuführen.
Mit Welch-Korrektur: p < 0.05 => Ergebnis Signifikant --> Varianzen heterogen
Ohne Welch-Korrektur: p > 0.05 => Ergebnis nicht Signifikant --> Varianzen homogen --> H0 mit Annahme Var1=Var2
Ergebnisse des t-Tests für unabhängige Stichproben¶
An dieser Stelle findet die eigentliche Auswertung des t-Testes statt. Beim t-test wird die t-Verteilung verwendet.
Auch hier ist auf die Reihenfolge zu achten erst AV und dann UV. Da in diesem Beispiel eine ungerichtete Hypothese verwendet wird mit einem Sig.-Niveau von 0.05,ist “con= 0.95, alt =”two.sided"" zu verwenden. Sollten Sie sich jedoch entscheiden eine gerichtete Hypothese zu verwenden, dann empfiehlt es sich folgende Zeilen zu ersetzen “con= 0.95, alt =”greater"" Je nach Richtung “less” or “greater”. Sollte eine 1 bei p-value stehen ist es genau die andere Richtung.
“Var.eq =True” bedeutet, dass die Varianzen homogen (gleich) sind, bzw. “Var.eq =False” das die Varianzen hetrogen sind.
Gruppen bilden¶
print(df.columns) # zeigt alle Spaltennamen
print(df['Selbststaendig'].unique()) # zeigt, welche Werte vorhanden sind
gruppe_ns = df[df['Selbststaendig'] == 'nicht-selbststaendig']['Sicherheitsgefuehl']
gruppe_s = df[df['Selbststaendig'] == 'selbststaendig']['Sicherheitsgefuehl']
print(f"Größen: NS={len(gruppe_ns)}, S={len(gruppe_s)}")
Index(['ID', 'Selbststaendig', 'Sicherheitsgefuehl'], dtype='object') ['selbststaendig' 'nicht-selbststaendig'] Größen: NS=25, S=26
Variante 1: ohne Welch - Korrektur¶
# Ungerichteter t-Test mit gleichen Varianzen (var.eq = TRUE)
t_stat, p_value = ttest_ind(gruppe_ns, gruppe_s, equal_var=True, alternative='two-sided')
print(f"t(49) = {t_stat:.4f}, p = {p_value:.4g}")
t(49) = 4.6532, p = 2.513e-05
Die Teststatistik betraegt t = 4.65 und der zugehörige Signifikanzwert p = 2.513e-05. Damit ist der Unterschied signifikant:
Mittelwerte der beiden Arten der Selbstständigkeit unterscheiden sich (t(49) = 4.65, p = 2.513e-05, n= 51)
Variante 2: MIT Welch-Korrektur¶
# Welch-t-Test (Varianzen ungleich)
t_stat_welch, p_value_welch = ttest_ind(gruppe_ns, gruppe_s, equal_var=False, alternative='two-sided')
# df wird bei Welch automatisch berechnet und ist nicht integer
print(f"Welch-Korrektur: t = {t_stat_welch:.4f}, p = {p_value_welch:.4g}")
Welch-Korrektur: t = 4.6542, p = 2.507e-05
mit Welch-Korrektur(t(48.959) = 4.65, p = 2.507e-05)
Berechnung der Effektstärke¶
Bei gleichgroßen Gruppen¶
$$r=\sqrt{\frac{t^2}{t^2+df}}$$
# Effektstärke r nach t-Wert und df
r = (t_stat**2 / (t_stat**2 + 49))**0.5
print(f"Effektstärke r = {r:.2f}")
Effektstärke r = 0.55
Zur Beurteilung der Groesse des Effektes dient die Einteilung von Cohen (1992):
$$ \begin{align} \text{Schwacher Effekt: } 0.10 &< ||r|| < 0.30 \\ \text{Schwacher bis mittlerer Effekt: } 0.30 &= ||r|| \\ \text{Mittlerer Effekt: } 0.30 &< ||r|| < 0.50 \\ \text{Mittlerer bis starker Effekt: }0.50 &= ||r|| \\ \text{Starker Effekt: } 0.50 &< ||r|| \end{align} $$ Im Rahmen des t-Tests fuer unabhängige Stichprobe berechnen wir nach Pearson und interpretieren nach Cohen(1992).
Damit entspricht eine Effektstaerke von .55 einem starken Effekt.
ALTERNATIVE¶
Bei ungleichgroßen Gruppen¶
$$ d = (\frac {n1+n2}{n1*n2}+ 0.5*d^2/df) * (\frac{(n1+n2}{df})$$
Diese Formel verwendet das EffSize-Package - Cooper et al. (2009):
# Gruppengrößen, Mittelwerte und SDs
n1, n2 = len(gruppe_ns), len(gruppe_s)
mean1, mean2 = gruppe_ns.mean(), gruppe_s.mean()
std1, std2 = gruppe_ns.std(ddof=1), gruppe_s.std(ddof=1)
# Pooled SD
s_pooled = np.sqrt(((n1 - 1)*std1**2 + (n2 - 1)*std2**2) / (n1 + n2 - 2))
d = (gruppe_ns.mean() - gruppe_s.mean()) / s_pooled
print(f"Cohen's d = {d:.2f}")
Cohen's d = 1.30
Interpretation von d nach Cohen (1988):
$$ \begin{align} \text{Schwacher Effekt: } 0.20 &< ||d|| < 0.50 \\ \text{Schwacher bis mittlerer Effekt: } 0.50 &= ||d|| \\ \text{Mittlerer Effekt: } 0.50 &< ||d|| < 0.80 \\ \text{Mittlerer bis starker Effekt: }0.80 &= ||d|| \\ \text{Starker Effekt: } 0.80 &< ||d|| \end{align} $$
Damit entspricht eine Effektstaerke von 1.3 einem starken Effekt.
Eine Aussage¶
Nicht-Selbststaendige fühlen sich signifikant beruflich sicherer (M = 21, SD = 3.69, n = 25) als Selbständige (M = 16.15, SD = 3.73, n = 26) (t(49) = 4.6532, p = 2.513e-05, n = 51). Die Effektstärke liegt bei r = .55 und entspricht damit einem starken Effekt nach Cohen (1992). H0 kann verworfen werden.