Unstandardisierte Effekte
Zeit: 15 min | Schwierigkeit: Einsteiger
Theorie: Die Rückkehr in die reale Welt
Wissenschaftliche Forschungsfragen zielen in den meisten Fällen auf Effekte ab. Ein Effekt ist, je nach Forschungsfrage, der Unterschied in der Ausprägung der interessierenden Variable zwischen Gruppen oder Bedingungen oder die Stärke des Zusammenhangs zwischen zwei oder mehr Variablen. Er ist oft die einzig relevante Größe für die Theorieentwicklung und für praktische Interventionen.
Unstandardisierte Effekte sind in den Einheiten des verwendeten Messinstruments ausgedrückt. Sie beantworten die Frage nach der Existenz und der exakten Größe eines Effektes direkt und intuitiv und bilden die Basis für praktische Entscheidungen (Baguley, 2009). Ein p Wert enthält diese Information nur indirekt, sodass er keine direkte Aussage über Richtung oder Größe eines gefundenen Effekts liefert.
Beispiel SmartRail: Was bringt das System wirklich?
Die Bahn hat SmartRail ausgerollt und seine Wirksamkeit untersucht. Jetzt stellt sich die entscheidende Frage: Wie viele Minuten Verspätung spart das System tatsächlich ein?
Dieser rohe Differenzwert in Minuten ist der unstandardisierte Effekt. Er ist sofort greifbar. Spart SmartRail durchschnittlich 0.5 Minuten, ist das für den Pendler kaum spürbar. Spart es 12 Minuten, verändert das den Arbeitsweg täglich deutlich. Der unstandardisierte Effekt in Minuten liefert die entscheidende Information, um die praktische Relevanz des Projekts zu beurteilen. Er ist die Brücke von der Statistik in die Realität.
Deine Aufgabe
Die Applikation zeigt zwei überlappende Verteilungen: die Verspätungen ohne SmartRail (grau) und mit SmartRail (blau). Der Alltagsrechner unten übersetzt den gemessenen Effekt direkt in deinen Pendleralltag.
- Beobachten: Bei den Startwerten überschneiden sich die Verteilungen stark. Der unstandardisierte Effekt beträgt 5 Minuten. Der Alltagsrechner zeigt, was das für einen Jahrespendler bedeutet.
- Effekt vergrößern: Verschiebe den Durchschnitt von SmartRail auf 2 Minuten. Die blaue Verteilung wandert nach links. Der unstandardisierte Effekt wächst auf 13 Minuten. Beobachte, wie sich der Alltagsrechner verändert.
- Streuung begreifen: Erhöhe die Schwankung der Verspätung. Die Verteilung wird breiter und flacher. Der Unterschied bleibt gleich, aber das System wird für den einzelnen Fahrgast unzuverlässig. Der undstandardisierte Mittelwertsunterschied allein ist also schon das entscheidende Maß,erzählt aber noch nicht die ganze Geschichte.
⏳ Die Anwendung wird geladen, dies kann bis zu 30 Sekunden dauern.
#| '!! shinylive warning !!': |
#| shinylive does not work in self-contained HTML documents.
#| Please set `embed-resources: false` in your metadata.
#| standalone: true
#| viewerHeight: 750
from shiny import App, render, ui
import numpy as np
import matplotlib.pyplot as plt
from scipy.stats import norm
MEAN_OLD = 15.0
SD_OLD = 5.0
app_ui = ui.page_fluid(
ui.card(
ui.card_header("SmartRail: Unstandardisierter Effekt in Minuten"),
ui.layout_columns(
ui.div(
ui.h5("SmartRail einstellen"),
ui.input_slider("new_mean", "Durchschnittliche Verspätung mit SmartRail (Min)", 0, 30, 10),
ui.input_slider("new_sd", "Schwankung der Verspätung mit SmartRail (Min)", 1, 15, 4),
ui.hr(),
ui.output_ui("alltagsrechner"),
ui.output_ui("einzelfahrt_panel"),
),
ui.output_plot("hist_plot"),
col_widths=(4, 8)
)
)
)
def server(input, output, session):
@render.plot
def hist_plot():
mean_new = input.new_mean()
sd_new = input.new_sd()
effect = MEAN_OLD - mean_new
np.random.seed(42)
data_old = np.random.normal(MEAN_OLD, SD_OLD, 2000)
data_new = np.random.normal(mean_new, sd_new, 2000)
fig, ax = plt.subplots(figsize=(10, 6))
bins = np.linspace(-10, 40, 60)
ax.hist(data_old, bins=bins, alpha=0.5, color='#95a5a6',
label=f'Ohne SmartRail (Ø {MEAN_OLD:.0f} Min)', density=True)
ax.hist(data_new, bins=bins, alpha=0.6, color='#3498db',
label=f'Mit SmartRail (Ø {mean_new:.0f} Min)', density=True)
ax.axvline(MEAN_OLD, color='#7f8c8d', linestyle='dotted', linewidth=2)
ax.axvline(mean_new, color='#2980b9', linestyle='dotted', linewidth=2)
# Doppelpfeil für den Effekt
y_arrow = ax.get_ylim()[1] * 0.85
if abs(effect) > 0.5:
ax.annotate(
"", xy=(mean_new, y_arrow), xytext=(MEAN_OLD, y_arrow),
arrowprops=dict(arrowstyle="<->", color='#2c3e50', lw=2)
)
ax.text((MEAN_OLD + mean_new) / 2, y_arrow * 1.02,
f'{abs(effect):.1f} Min', ha='center', va='bottom',
fontweight='bold', fontsize=12, color='#2c3e50')
title_color = '#27ae60' if effect > 0 else '#c0392b'
label = "Verbesserung" if effect > 0 else "Verschlechterung"
ax.set_title(f"Unstandardisierter Effekt: {abs(effect):.1f} Minuten {label}",
color=title_color, fontweight='bold', fontsize=13)
ax.set_xlabel("Verspätung in Minuten (Rohwerte)")
ax.set_ylabel("Relative Häufigkeit")
ax.set_xlim(-10, 40)
ax.legend(loc='upper right')
ax.spines['top'].set_visible(False)
ax.spines['right'].set_visible(False)
return fig
@render.ui
def alltagsrechner():
mean_new = input.new_mean()
effect = MEAN_OLD - mean_new # Minuten gespart pro Fahrt
fahrten = 230 # Arbeitstage pro Jahr
jahreswert = effect * fahrten # Minuten pro Jahr
if effect > 0:
stunden = abs(jahreswert) / 60
farbe = "#27ae60"
pfeil = "▼"
label = "gespart"
else:
stunden = abs(jahreswert) / 60
farbe = "#c0392b"
pfeil = "▲"
label = "verloren"
return ui.div(
ui.tags.p("Alltagsrechner (230 Arbeitstage/Jahr)",
style="font-weight:bold; font-size:13px; margin-bottom:6px;"),
ui.tags.p(
ui.tags.span(f"{pfeil} {abs(effect):.1f} Min ",
style=f"color:{farbe}; font-weight:bold; font-size:16px;"),
"pro Fahrt",
),
ui.tags.p(
ui.tags.span(f"{pfeil} {abs(jahreswert):.0f} Min ",
style=f"color:{farbe}; font-weight:bold; font-size:16px;"),
f"{label} pro Jahr",
),
ui.tags.p(
ui.tags.span(f"= {stunden:.1f} Stunden",
style=f"color:{farbe}; font-weight:bold; font-size:16px;"),
" pro Jahr",
),
style="background:#f8f9fa; padding:12px; border-radius:8px; margin-top:8px;"
)
@render.ui
def einzelfahrt_panel():
mean_new = input.new_mean()
sd_new = input.new_sd()
effect = MEAN_OLD - mean_new
# P(SmartRail-Fahrt < Alt-Fahrt) = Phi(effect / sqrt(SD_OLD² + sd_new²))
sigma_diff = np.sqrt(SD_OLD**2 + sd_new**2)
prob = norm.cdf(effect / sigma_diff) if sigma_diff > 0 else 0.5
pct = prob * 100
if effect <= 0:
color = "#c0392b"
fazit = "SmartRail verschlechtert die Einzelfahrt."
elif pct >= 80:
color = "#27ae60"
fazit = "Effekt ist für die Einzelfahrt klar spürbar."
elif pct >= 65:
color = "#e67e22"
fazit = "Effekt ist für die Einzelfahrt mäßig spürbar."
else:
color = "#c0392b"
fazit = "Effekt geht in der Streuung unter."
return ui.div(
ui.tags.p("Einzelfahrt-Perspektive",
style="font-weight:bold; font-size:13px; margin-bottom:6px; margin-top:10px;"),
ui.tags.p(
ui.tags.span(f"{pct:.0f}% ",
style=f"color:{color}; font-weight:bold; font-size:16px;"),
"der Fahrten pünktlicher",
),
ui.tags.p(fazit, style=f"color:{color}; font-size:12px; font-style:italic;"),
ui.tags.hr(style="margin:6px 0;"),
ui.tags.p(
"Der Mittelwertsunterschied allein sagt nicht, wie verlässlich "
"der Effekt für die einzelne Fahrt ist — das hängt auch von "
"der Streuung ab.",
style="font-size:11px; color:#7f8c8d;"
),
style="background:#f8f9fa; padding:12px; border-radius:8px; margin-top:8px;"
)
app = App(app_ui, server)