Der Posterior

Zeit: 10 min

Theorie: Die Synthese von Vorwissen und Fakten

In der bayesianischen Statistik ist die Berechnung des Posteriors \(P(\theta|D)\) das entscheidende Ziel. Der Posterior repräsentiert deine aktualisierte Überzeugung, basierend auf den neuen Daten aktualisierten Vorurteile. Er ist das logische Resultat, wenn du dein theoretisches Vorwissen (den Prior \(P(\theta)\)) mit den empirischen Fakten (der Likelihood \(P(D|\theta)\)) kombinierst.

Das Bayes-Theorem fungiert hierbei als mathematischer Aktualisierungsmechanismus. Es zeigt, wie vorhandenes Vorwissen mit neuen Daten kombiniert wird, um zu einer rational aktualisierten Einschätzung zu gelangen. Je nach Fragestellung kann dieses Ergebnis unterschiedliche Formen annehmen: Bei der Parameterschätzung erhalten wir eine Posterior-Verteilung über einen unbekannten Parameter, etwa die wahre Pünktlichkeitsquote von SmartRail. Bei einem Hypothesen- oder Modellvergleich erhalten wir dagegen aktualisierte Wahrscheinlichkeiten für konkurrierende Theorien, Modelle oder Annahmen.

Bayesianische Inferenz liefert damit nicht einfach eine isolierte Punktschätzung oder eine starre Ja-Nein-Entscheidung. Sie macht explizit, wie plausibel verschiedene Parameterwerte, Hypothesen oder Modelle nach Berücksichtigung der beobachteten Daten sind.

Ein massiver Vorteil von Posterior-Verteilungen ist die direkte Berechnung von Glaubwürdigkeitsintervallen (Credible Intervals). Klassische Konfidenzintervalle sind konzeptionell schwer zu verstehen und werden in der Praxis häufig falsch interpretiert. Das bayesianische Glaubwürdigkeitsintervall liefert dagegen exakt die Aussage, die Menschen intuitiv suchen: “Mit 95 % Wahrscheinlichkeit liegt der wahre Wert \(\theta\) in genau diesem Bereich”.

Beispiel SmartRail: Die aktualisierte Überzeugung

Du möchtest die wahre durchschnittliche Verspätungsreduktion \(\theta\) durch SmartRail auf der Pilotstrecke bestimmen.

Dein Prior \(P(\theta)\) basiert auf Simulationen und Herstellerangaben. Du gehst von 8 Minuten durchschnittlicher Reduktion aus (wir sind hier ja Optimisten). Die Daten \(D\) sind die echten Messungen aus den Testfahrten. Du hast fünf Fahrten ausgewertet. SmartRail hat im Schnitt nur 6 Minuten Verspätung eingespart. Die Likelihood \(P(D|\theta)\) quantifiziert, wie diese harten Beobachtungen zu verschiedenen Werten für \(\theta\) passen.

Der Posterior \(P(\theta|D)\) ist nun deine neue, datenbasierte Realität. Er liegt als Kompromiss irgendwo zwischen deinem Prior (8 Minuten) und den gesammelten Daten (6 Minuten). Wie stark sich der Posterior den Daten anpasst, hängt davon ab, wie sicher dein Prior formuliert war und wie umfangreich die Menge der neuen Daten ist.

Deine Aufgabe

Die interaktive Abbildung zeigt dir drei Kurven. Den Prior \(P(\theta)\) in Grau, die aus den Testdaten abgeleitete Likelihood \(P(D|\theta)\) in Rot und den resultierenden Posterior \(P(\theta|D)\) in Violett. Der schattierte Bereich unter der violetten Kurve markiert das 95 % Glaubwürdigkeitsintervall.

  1. Beobachten: Bei einem unsicheren Prior (großer SD Wert) dominieren die roten Testdaten \(D\). Der violette Posterior \(P(\theta|D)\) verschmilzt fast mit der roten Kurve.
  2. Vorwissen einbauen: Mache deinen Prior extrem sicher. Reduziere die Unsicherheit (SD) auf einen minimalen Wert. Beobachte, wie der graue Prior den violetten Posterior förmlich an sich reißt, wenig beeindruckt von den roten Testdaten.
  3. Interpretation: Lies das Glaubwürdigkeitsintervall auf der horizontalen Achse ab. Du kannst nun empirisch fundiert behaupten, in welchem exakten Bereich sich SmartRails wahre durchschnittliche Verspätungsreduktion \(\theta\) höchstwahrscheinlich bewegt.

⏳ 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

# Fixierte Daten D: 5 SmartRail-Testfahrten, Durchschnitt 6 Min Reduktion, SD 2.5
data_n = 5
data_mean = 6.0
data_sd = 2.5
data_se = data_sd / np.sqrt(data_n)

app_ui = ui.page_fluid(
    ui.card(
        ui.card_header("SmartRail: Prior und Testdaten fusionieren"),
        ui.layout_columns(
            ui.div(
                ui.h5("Prior P(Theta) konfigurieren"),
                ui.input_slider("prior_mean", "Erwartete Reduktion", 0, 20, 8, step=1),
                ui.input_slider("prior_sd", "Unsicherheit (SD)", 0.5, 10, 5, step=0.5),
                ui.hr(),
                ui.p("Die Testdaten D sind fixiert (Rote Kurve: 5 Fahrten, Schnitt 6 Min Reduktion). Ändere den Prior und beobachte den violetten Posterior."),
            ),
            ui.output_plot("posterior_plot"),
            col_widths=(4, 8)
        )
    )
)

def server(input, output, session):
    @render.plot
    def posterior_plot():
        p_mean = input.prior_mean()
        p_sd = input.prior_sd()
        
        # Bayesian Updating fuer Normalverteilungen (Conjugate Math)
        prior_var = p_sd**2
        data_var = data_se**2
        
        post_var = 1.0 / ((1.0 / prior_var) + (1.0 / data_var))
        post_mean = post_var * ((p_mean / prior_var) + (data_mean / data_var))
        post_sd = np.sqrt(post_var)
        
        x_vals = np.linspace(-5, 25, 400)
        
        prior_y = norm.pdf(x_vals, p_mean, p_sd)
        like_y = norm.pdf(x_vals, data_mean, data_se)
        post_y = norm.pdf(x_vals, post_mean, post_sd)
        
        fig, ax = plt.subplots(figsize=(10, 6), layout="constrained")
        
        ax.plot(x_vals, prior_y, color='#7f8c8d', linewidth=2, linestyle='dotted', label='Prior P(Theta)')
        ax.plot(x_vals, like_y, color='#e74c3c', linewidth=2, linestyle='dashed', label='Likelihood P(D|Theta)')
        ax.plot(x_vals, post_y, color='#8e44ad', linewidth=3, label='Posterior P(Theta|D)')
        
        # 95 Prozent Glaubwuerdigkeitsintervall berechnen
        ci_lower, ci_upper = norm.interval(0.95, loc=post_mean, scale=post_sd)
        
        # Intervall schattieren
        x_fill = np.linspace(ci_lower, ci_upper, 100)
        y_fill = norm.pdf(x_fill, post_mean, post_sd)
        ax.fill_between(x_fill, 0, y_fill, color='#8e44ad', alpha=0.3, label='95 % Glaubwürdigkeitsintervall')
        
        ax.set_title("Aktualisierung deiner Überzeugung")
        ax.set_xlabel("Wahre durchschnittliche Verspätungsreduktion Theta (Minuten)")
        ax.set_ylabel("Wahrscheinlichkeitsdichte")
        ax.set_xlim(-5, 25)
        ax.set_ylim(0, max(np.max(like_y), np.max(post_y), np.max(prior_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)