Vorhersagen

Zeit: 10 min

Theorie: Die Zukunft berechnen

Bisher haben wir nach innen geschaut. Wir haben aus den Daten gelernt, was der wahre Effekt von SmartRail vermutlich ist, und dieses Wissen in der Posterior Verteilung gebündelt. Doch ein Modell beweist seinen Wert erst, wenn es nach vorne schaut. Niemanden interessiert allein der geschätzte Durchschnittswert. Das Projektteam will wissen, was bei der nächsten konkreten Fahrt tatsächlich passiert. Genau diesen Schritt von der Analyse des Bekannten zur Vorhersage des Unbekannten gehen wir in diesem Kapitel.

Unser Ziel ist die Vorhersage der Zukunft. Wir bedienen wir uns unseres Priors (Die Vergangenheit) und unserer erhobenen Daten (Die Gegenwart), um unsere Posteriori (Zukunft) vorherzusagen. Die Posterior Prädiktive Verteilung \(P(\tilde{y}|D)\) ist das bayesianische Werkzeug, um neue, noch ungesehene Datenpunkte \(\tilde{y}\) vorherzusagen, basierend auf den bereits gesammelten Daten \(D\).

Klassische Regressionsmodelle schätzen oft nur einen einzelnen , festen Vorhersagewert. Das ignoriert fundamentale Unsicherheiten. Die bayesianische Methode ist mathematisch strikter. Sie nutzt deine gesamte Posterior Verteilung \(P(\theta|D)\) und simuliert daraus die Zukunft.

Dabei kombiniert sie zwei völlig unterschiedliche Arten von Unsicherheit: Die epistemische Unsicherheit (Wie sicher bist du dir über den wahren Parameter \(\theta\)?) und die aleatorische Unsicherheit (Das natürliche Rauschen der realen Welt). Das Resultat ist eine Vorhersage, die echte Unsicherheiten nicht künstlich glattbügelt, sondern ehrlich ausweist.

Beispiel SmartRail: Die Prognose für morgen

Du hast die Testfahrten \(D\) ausgewertet. Deine Posterior Verteilung \(P(\theta|D)\) sagt dir nun, dass SmartRails durchschnittliche Verspätungsreduktion \(\theta\) bei etwa 6 Minuten liegt.

Aber der Durchschnitt reicht dem Projektteam nicht. Es will wissen, wie verlässlich diese Reduktion von 6 Minuten bei einer konkreten Fahrt morgen auf der Pilotstrecke eintreten wird. Diese eine zukünftige Fahrt ist dein neuer Datenpunkt \(\tilde{y}\).

Selbst wenn du die wahre durchschnittliche Reduktion \(\theta\) exakt kennen würdest, kann die morgige Fahrt davon abweichen. Einzelfahrten unterliegen einer natürlichen Schwankung durch Wetter, Auslastung oder technische Störungen. Die Posterior Prädiktive Verteilung \(P(\tilde{y}|D)\) nimmt deine bestehende Unsicherheit über den Durchschnitt \(\theta\) und addiert das unvorhersehbare tägliche Chaos des Bahnbetriebs. Das Ergebnis ist eine Kurve, die dir genau sagt, mit welcher Wahrscheinlichkeit SmartRail morgen exakt \(\tilde{y}\) Minuten Verspätung einspart.

Deine Aufgabe

Die Applikation zeigt dir die violette Posterior Verteilung \(P(\theta|D)\) für den Durchschnittseffekt \(\theta\) und die orange Posterior Prädiktive Verteilung \(P(\tilde{y}|D)\) für die konkrete Fahrt morgen \(\tilde{y}\).

  1. Beobachten: Die orange Vorhersagekurve für morgen \(\tilde{y}\) ist immer breiter als die violette Kurve für den Durchschnitt \(\theta\). Einzelfahrten schwanken immer stärker als der langfristige Durchschnitt.
  2. Das Betriebsrauschen erhöhen: Erhöhe die natürliche Schwankung im Bahnbetrieb (das aleatorische Rauschen). Die orange Kurve wird extrem breit. Präzise Vorhersagen für Einzelfahrten werden unmöglich, selbst wenn der Durchschnittseffekt \(\theta\) perfekt geschätzt ist.
  3. Parameter Unsicherheit erhöhen: Mache deine Schätzung für \(\theta\) unsicherer. Beide Kurven werden breiter. Dein fehlendes Wissen über SmartRails wahren Effekt überträgt sich direkt auf die Verlässlichkeit der Vorhersage der morgigen Fahrt.

⏳ 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
from scipy.stats import norm

app_ui = ui.page_fluid(
    ui.card(
        ui.card_header("SmartRail: Vorhersage für die nächste Fahrt"),
        ui.layout_columns(
            ui.div(
                ui.h5("Wissen über SmartRails Durchschnittseffekt"),
                ui.input_slider("post_mean", "Geschätzte Reduktion Theta", 0, 20, 6),
                ui.input_slider("post_sd", "Unsicherheit über Theta", 0.1, 10, 2),
                ui.hr(),
                ui.h5("Schwankungen im Bahnbetrieb"),
                ui.input_slider("noise_sd", "Natürliche Schwankung pro Fahrt", 1, 15, 4),
            ),
            ui.output_plot("pred_plot"),
            col_widths=(4, 8)
        )
    )
)

def server(input, output, session):
    @render.plot
    def pred_plot():
        mu = input.post_mean()
        sd_theta = input.post_sd()
        sd_noise = input.noise_sd()
        
        # Varianz der Vorhersage ist die Summe aus Parameter Varianz und System Varianz
        sd_pred = np.sqrt(sd_theta**2 + sd_noise**2)
        
        x_vals = np.linspace(-20, 50, 400)
        post_y = norm.pdf(x_vals, mu, sd_theta)
        pred_y = norm.pdf(x_vals, mu, sd_pred)
        
        fig, ax = plt.subplots(figsize=(10, 6), layout="constrained")
        
        ax.plot(x_vals, post_y, color='#8e44ad', linewidth=2, label='Posterior P(Theta|D)')
        ax.fill_between(x_vals, 0, post_y, color='#8e44ad', alpha=0.3)
        
        ax.plot(x_vals, pred_y, color='#e67e22', linewidth=3, label='Vorhersage P(y neu|D)')
        
        ax.set_title("Vorhersage für die nächste SmartRail-Fahrt")
        ax.set_xlabel("Verspätungsreduktion in Minuten")
        ax.set_ylabel("Wahrscheinlichkeitsdichte")
        ax.set_xlim(-20, 50)
        ax.set_ylim(0, max(np.max(post_y), np.max(pred_y)) * 1.2)
        ax.set_yticks([])

        ax.legend(loc="upper right")
        ax.spines['top'].set_visible(False)
        ax.spines['right'].set_visible(False)
        
        return fig

app = App(app_ui, server)