Unsicherheit quantifizieren

Zeit: 15 min

Theorie: Das Ende der absoluten Gewissheit

Wissenschaft liefert keine absoluten Wahrheiten. Jede Messung in der realen Welt enthält einen unvermeidbaren Zufallsfehler. Ein einzelner berechneter Mittelwert, der sogenannte Punktschätzer, ist mit an Sicherheit grenzender Wahrscheinlichkeit niemals exakt richtig. Die wahre Kunst der Statistik liegt darin, diese unvermeidbare Unsicherheit ehrlich zu quantifizieren.

Konfidenzintervalle oder Glaubwürdigkeitsintervalle liefern beide diese Information. Sie rahmen den gemessenen Effekt ein und zeigen den Bereich der Werte, die mit den gesammelten Daten mathematisch kompatibel sind. Die Betrachtung diese Intervalle zwingt uns, die fehlerhafte und reduktive binäre Logik von signifikant und nicht signifikant zu überwinden. Anstatt eine künstliche Schwelle anzubeten, bewerten wir die gesamte Spanne der plausiblen Wahrheiten.

Beispiel SmartRail: Die gefährliche Illusion der Präzision

Die Deutsche Bahn evaluiert die Verspätungsreduktion durch SmartRail auf dem gesamten ICE-Netz.

Das binäre statistische Urteil lautet schlicht: SmartRail wirkt, das Ergebnis ist signifikant. Diese Aussage ist für eine Investitionsentscheidung in Milliardenhöhe gefährlich unpräzise. Der isolierte Punktschätzer sagt: SmartRail reduziert die Verspätung um durchschnittlich 2.5 Minuten pro Fahrt. Das suggeriert eine falsche absolute Gewissheit und ignoriert die Unsicherheit der realen Welt komplett.

Die Angabe des Konfidenzintervalls liefert ein vollständigeres Bild der Wahrheit: SmartRail reduziert die Verspätung im Schnitt um 2.5 Minuten, aber die Unsicherheit ist massiv. Das berechnete Konfidenzintervall reicht von einer enormen Reduktion um 5 Minuten bis zu einer praktisch irrelevanten Verbesserung um lediglich 0.1 Minuten. Beide Extreme sind mit den Daten vereinbar. Erst diese ehrliche Quantifizierung der Unsicherheit ermöglicht eine fundierte Investitionsentscheidung.

Deine Aufgabe

Die Applikation visualisiert die gemessene Verspätungsreduktion durch SmartRail inklusive der berechneten Unsicherheit (dem 95 Prozent Konfidenzintervall). Die vertikale Nulllinie markiert die absolute Wirkungslosigkeit.

  1. Beobachten: Bei wenigen ausgewerteten Fahrten ist das Konfidenzintervall (der dicke Balken) sehr breit. Es kreuzt die Nulllinie. SmartRail könnte die Pünktlichkeit in Wahrheit massiv verbessern oder sogar leicht verschlechtern; wir wissen es nicht. Die Unsicherheit ist zu groß für eine belastbare Schlussfolgerung.
  2. Präzision erzwingen: Erhöhe die Anzahl der ausgewerteten ICE-Fahrten massiv. Der berechnete Effekt bleibt exakt bei 2.5 Minuten, aber das Konfidenzintervall schrumpft dramatisch zusammen.
  3. Erkenntnis bewerten: Das Intervall löst sich von der Nulllinie. Du bekommst einen Eindruck davon, wie viele Fahren nötig sind, um den gesuchten Effekt mit einer bestimmten Präzision schätzen zu können.

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

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

app_ui = ui.page_fluid(
    ui.card(
        ui.card_header("SmartRail: Konfidenzintervall der Verspätungsreduktion"),
        ui.layout_columns(
            ui.div(
                ui.h5("Parameter der Auswertung"),
                ui.input_slider("n_trips", "Anzahl ausgewerteter ICE-Fahrten", 10, 500, 20, step=10),
                ui.input_slider("sd_effect", "Natürliche Schwankung der Verspätung", 3, 15, 8, step=1),
                ui.hr(),
                ui.p("Die gemessene durchschnittliche Verspätungsreduktion liegt fest bei 2.5 Minuten. Wir quantifizieren lediglich die Unsicherheit beim Schätzen dieses Wertes."),
            ),
            ui.output_plot("ci_plot"),
            col_widths=(4, 8)
        )
    )
)

def server(input, output, session):
    @render.plot
    def ci_plot():
        n = input.n_trips()
        sd = input.sd_effect()

        effect = 2.5

        se = sd / np.sqrt(n)

        margin_of_error = 1.96 * se
        ci_lower = effect - margin_of_error
        ci_upper = effect + margin_of_error

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

        ax.axvline(0, color='#34495e', linestyle='dotted', linewidth=2, label='Kein Effekt (SmartRail wirkungslos)')

        is_significant = ci_lower > 0
        color = '#27ae60' if is_significant else '#7f8c8d'

        ax.plot([ci_lower, ci_upper], [1, 1], color=color, linewidth=8, solid_capstyle='round')

        ax.scatter([effect], [1], color='#2c3e50', s=200, zorder=5, label=f'Gemessener Effekt ({effect} Min)')

        ax.text(ci_lower, 1.1, f'{ci_lower:.1f}', ha='center', color=color, fontweight='bold', fontsize=12)
        ax.text(ci_upper, 1.1, f'{ci_upper:.1f}', ha='center', color=color, fontweight='bold', fontsize=12)

        status = "SmartRail wirkt nachweislich" if is_significant else "Zu unsicher (Wirkung nicht gesichert)"
        ax.set_title(f"Quantifizierte Unsicherheit: {status}", fontweight='bold', color=color)

        ax.set_xlabel("Verspätungsreduktion in Minuten")
        ax.set_yticks([])
        ax.set_xlim(-8, 14)
        ax.set_ylim(0, 2)

        ax.legend(loc="lower right")
        ax.spines['top'].set_visible(False)
        ax.spines['right'].set_visible(False)
        ax.spines['left'].set_visible(False)

        return fig

app = App(app_ui, server)