Praktische Bedeutsamkeit

Zeit: 15 min | Schwierigkeit: Einsteiger

Theorie: Messbar ist nicht gleich wichtig

Statistische Signifikanz wird oft fälschlicherweise mit praktischer Bedeutsamkeit gleichgesetzt. Die Relevanz einer Maßnahme für die Praxis kann ausschließlich anhand der Effekte oder Effektgrößen beurteilt werden.

Über den echten Nutzen in der realen Welt sagt der p-wert fast gar nichts aus. Cohen kritisierte diese Verwechslung scharf und betonte, dass eine quantitative Wissenschaft ihr primäres Ziel verfehlt, wenn sie Entscheidungen auf p Werte stützt anstatt auf die Größe von Effekten.

Wichtig ist außerdem: Für die Beurteilung der praktischen Bedeutsamkeit zählt oft gerade der unstandardisierte Effekt in seiner natürlichen Einheit. Manche Fragestellungen lassen sich überhaupt nur mit unstandardisierten Effekten sinnvoll prüfen, weil erst die Rohgröße die für die Entscheidung relevante Information trägt: gesparte Sekunden pro Fahrt, eingesparte Euro, gewonnene Lebensjahre. Eine standardisierte Effektgröße wie Cohens d macht Studien zwar vergleichbar, sagt aber für sich genommen nichts darüber aus, ob ein Effekt die Kosten rechtfertigt — die hier entscheidende Schwelle ist immer in der konkreten Einheit definiert, nicht in Standardabweichungen.

Beispiel SmartRail: Das hochsignifikante Nichts

Die Bahn investiert 180 Millionen Euro in den bundesweiten SmartRail Rollout. Eine gigantische Studie mit 200.000 ICE Fahrten zeigt: SmartRail verbessert die Pünktlichkeit statistisch hochsignifikant, p < 0.001. Das Projektteam präsentiert den winzigen p Wert als Beleg für einen enormen Erfolg.

Du schaust als Pendler auf den unstandardisierten Effekt: SmartRail spart dir im Schnitt 4 Sekunden pro Fahrt. Der Anschlusszug fährt weiter pünktlich ohne dich ab. Die Investition war statistisch gesehen ein Triumph, praktisch gesehen ein teures Nichts. Die Frage ist nicht “Ist der Effekt von null verschieden?” sondern “Ist der Effekt groß genug, um die Kosten zu rechtfertigen?”

Deine Aufgabe

Die Applikation visualisiert die Lücke zwischen Signifikanz und Bedeutsamkeit. Du legst selbst fest, ab wann ein Zeitgewinn für dich als Pendler praktisch relevant ist. Der Investitionsrechner zeigt, wie viel die Bahn pro eingesparter Stunde ausgibt.

  1. Beobachten: Bei den Startwerten spart SmartRail 4 Sekunden pro Fahrt. Das Projekt verfehlt deine Relevanzschwelle massiv und kostet die Bahn unverhältnismäßig viel pro eingesparter Stunde.
  2. Schwellenwert setzen: Definiere deine persönliche Grenze: Ab wie vielen Sekunden Zeitgewinn ist ein Projekt für dich im Alltag relevant? Setze die Schwelle auf 120 Sekunden (2 Minuten).
  3. Effekt verändern: Erhöhe den gemessenen Effekt mit dem oberen Regler. Beobachte, wann der Balken grün wird und wie sich der Investitionsrechner verändert. Um wie viele Sekunden muss SmartRail nach deinen Angaben schneller sein, um sein Geld zu rechtfertigen?

⏳ 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: 720

from shiny import App, render, ui
import matplotlib.pyplot as plt

INVESTITION_MIO = 180     # Millionen Euro
FAHRTEN_JAHR    = 500_000 # Fahrten pro Jahr
JAHRE           = 10      # Nutzungsdauer

app_ui = ui.page_fluid(
    ui.card(
        ui.card_header("SmartRail: Signifikanz vs. Praktische Bedeutsamkeit"),
        ui.layout_columns(
            ui.div(
                ui.h5("Studienergebnis"),
                ui.input_slider("eff_sek", "Gemessener Zeitgewinn (Sekunden/Fahrt)", 1, 600, 4),
                ui.tags.p("Studie: p < 0.001, statistisch hochsignifikant.",
                          style="font-size:12px; color:#7f8c8d;"),
                ui.hr(),
                ui.h5("Deine Relevanzschwelle"),
                ui.input_slider("schwelle", "Ab wann ist es dir relevant? (Sekunden)", 10, 600, 120),
                ui.hr(),
                ui.output_ui("invest_panel"),
            ),
            ui.output_plot("relevanz_plot"),
            col_widths=(4, 8)
        )
    )
)

def server(input, output, session):

    @render.plot
    def relevanz_plot():
        eff      = input.eff_sek()
        schwelle = input.schwelle()

        is_relevant = eff >= schwelle
        bar_color   = '#27ae60' if is_relevant else '#c0392b'

        fig, ax = plt.subplots(figsize=(10, 6))

        ax.barh(["Gemessener\nZeitgewinn"], [eff], color=bar_color, height=0.35, alpha=0.85)
        ax.axvline(schwelle, color='#2c3e50', linestyle='dotted', linewidth=2.5)

        ax.text(schwelle + 8, 0, f'Deine Schwelle:\n{schwelle} Sek',
                va='center', fontweight='bold', fontsize=10, color='#2c3e50')

        ax.set_xlim(0, 720)
        ax.set_xlabel("Zeitgewinn in Sekunden pro Fahrt")

        status = "Praktisch relevant" if is_relevant else "Praktisch irrelevant"
        status_color = '#27ae60' if is_relevant else '#c0392b'
        konj = "und" if is_relevant else "aber"
        ax.set_title(f"Hochsignifikant, {konj}: {status}",
                     fontweight='bold', color=status_color, fontsize=13)

        # Annotation: was bedeutet der Effekt in Minuten?
        eff_min = eff / 60
        ax.text(eff / 2 if eff > 30 else eff + 5,
                -0.28, f'{eff_min:.2f} Min = {eff} Sek',
                ha='center', va='top', fontsize=10, color='#7f8c8d')

        ax.spines['top'].set_visible(False)
        ax.spines['right'].set_visible(False)
        ax.spines['left'].set_visible(False)
        ax.set_yticks([])

        return fig

    @render.ui
    def invest_panel():
        eff_sek = input.eff_sek()

        # Gesamteingesparte Zeit über Nutzungsdauer
        sek_gesamt   = eff_sek * FAHRTEN_JAHR * JAHRE
        stunden_ges  = sek_gesamt / 3600
        invest_eur   = INVESTITION_MIO * 1_000_000

        kosten_pro_h = invest_eur / stunden_ges if stunden_ges > 0 else float('inf')
        kosten_str   = (f"{kosten_pro_h:,.0f} €" if kosten_pro_h < 1_000_000
                        else f"{kosten_pro_h/1_000_000:.1f} Mio €")

        return ui.div(
            ui.tags.p("Investitionsrechner",
                      style="font-weight:bold; font-size:13px; margin-bottom:6px;"),
            ui.tags.p(
                ui.tags.span(f"{eff_sek} Sek/Fahrt × {FAHRTEN_JAHR:,} Fahrten/Jahr × {JAHRE} Jahre",
                             style="font-size:11px; color:#7f8c8d;"),
            ),
            ui.tags.p(
                ui.tags.span(f"= {stunden_ges:,.0f} Stunden ",
                             style="font-weight:bold; font-size:14px;"),
                "eingesparte Zeit gesamt",
            ),
            ui.tags.p(
                ui.tags.span(f"{INVESTITION_MIO} Mio € ÷ {stunden_ges:,.0f} h",
                             style="font-size:11px; color:#7f8c8d;"),
            ),
            ui.tags.p(
                ui.tags.span(f"= {kosten_str} ",
                             style="font-weight:bold; font-size:15px; color:#c0392b;"),
                "pro eingesparter Stunde",
            ),
            style="background:#f8f9fa; padding:12px; border-radius:8px; margin-top:8px;"
        )

app = App(app_ui, server)