Wie wir rechnen · ohne Beschönigung

Methodik

Der Frust-Score ist eine Zahl von 0 bis 100. 0 heißt: steig ein, das wird schön. 100 heißt: bleib lieber daheim. Hier steht, wie diese Zahl zustande kommt, und wie wir prüfen, ob sie stimmt.

0–19 · Fahr los 20–44 · Machbar 45–69 · Wackelig 70–100 · Bleib daheim

Was in den Score einfließt

Für jede Verbindung schauen wir uns die konkreten Züge, Umstiege und Halte an und bewerten mehrere Dinge, die eine Fahrt anstrengend machen können. Jeder Punkt trägt einen Teil zum Gesamtwert bei:

Verspätungsrisiko

Wie stark diese Züge auf dieser Strecke erfahrungsgemäß und laut aktueller Lage zu spät kommen. Basis ist unsere Prognose (siehe unten), nicht nur die aktuelle Live-Verspätung.

Ausfallrisiko

Wie wahrscheinlich einer der Züge ganz ausfällt, inklusive Teilausfällen einzelner Abschnitte.

Umstiege und Anschlüsse

Jeder Umstieg ist ein Risiko. Besonders zählt, wie knapp der Anschluss ist und wie wahrscheinlich der Zubringer ihn reißt.

Auslastung

Ob der Zug voraussichtlich voll wird. Stehen für vier Stunden ist kein Vergnügen.

Fahrzeit und Umweg

Wie lang die Reise im Verhältnis zur Luftlinie ist. Eine zähe Verbindung mit vielen Zwischenhalten kostet Nerven.

Warnmeldungen

Bauarbeiten, Störungen, Schienenersatzverkehr und andere Hinweise der Bahn zu genau diesen Zügen.

Preis

Was die Fahrt kostet, fließt mit ein, weil ein hoher Preis für eine wacklige Verbindung besonders ärgert.

Wie stark die einzelnen Punkte zählen, kannst du oben in der Suche über „Was nervt dich?" selbst gewichten. Wer Verspätung hasst, aber mit vollen Zügen leben kann, bekommt einen anderen Score als jemand, dem der Preis am wichtigsten ist.

Die Verspätungs-Prognose

Das Herzstück ist ein Modell, das aus vielen tausend beobachteten Fahrten gelernt hat, wie zuverlässig eine bestimmte Zugart auf einer bestimmten Strecke zu einer bestimmten Zeit unterwegs ist. Für jeden Zug einer Verbindung schätzt es zwei Dinge: die Ausfallwahrscheinlichkeit und die zu erwartende Verspätung.

Wichtig ist uns, dass wir keine falsche Genauigkeit vorgaukeln. Statt einer einzelnen Minutenzahl geben wir eine Spanne an (etwa: meist pünktlich, im ungünstigen Fall aber bis zu 30 Minuten). Diese Spannen sind kalibriert, das heißt: wenn wir sagen „in 9 von 10 Fällen unter X Minuten", dann soll das über viele Fahrten hinweg auch tatsächlich so eintreffen.

Warum wackelige Anschlüsse extra zählen

Ein knapper Umstieg ist gefährlicher, als es der Durchschnitt vermuten lässt. Deshalb rechnen wir aus der Verspätungs-Verteilung des Zubringers aus, wie wahrscheinlich er den Anschluss reißt, und nicht nur, ob er im Mittel pünktlich ist. Ein Zug, der meistens auf die Minute kommt, aber ab und zu eine halbe Stunde hängt, macht einen 8-Minuten-Umstieg trotzdem riskant. Genau das fängt der Score ein.

So prüfen wir uns selbst

Zu jeder Suche speichern wir unsere Prognose und vergleichen sie später mit den echten Ist-Zeiten der Deutschen Bahn. So sehen wir Woche für Woche, wie oft wir richtig lagen, und wo nicht.

Dabei trennen wir sauber: Fahrten, die wir live erfasst haben, sind tendenziell zu verspätungslastig (gestörte Züge fallen eher auf). Diese Verzerrung weisen wir getrennt aus, statt sie als Modellqualität schönzurechnen. Den ehrlichen Wochen-Rückblick findest du im Wochenbericht.

Grenzen, ehrlich gesagt

Der Score ist eine Wahrscheinlichkeit, kein Versprechen. Auch die beste Verbindung kann erwischt werden, und ein roter Score fährt manchmal pünktlich. Wir arbeiten mit den Daten, die uns die Bahn öffentlich zur Verfügung stellt, plus dem, was wir selbst über die Zeit beobachten. Was wir beobachten, legen wir unter Offene Daten offen. bleibZuhause ist ein unabhängiges Projekt und steht in keiner Verbindung zur Deutschen Bahn.

Für die Nerds: die exakte Rechnung Formeln direkt aus dem Code

Der Score ist ein additives Malus-Modell: Start bei 0, jeder zutreffende Faktor addiert Strafpunkte, am Ende wird auf 0 bis 100 gekappt.

score = clamp( round( Σ Faktor-Punkte ), 0, 100 )

Stand: Juli 2026. Die Gewichte sind Heuristiken, wir justieren sie gelegentlich nach, wenn die Realität es verlangt.

Alle Faktoren, exakt

v = Ist-Ankunftsverspätung in Minuten, u = Umstiege, n = Anzahl, s = slowKeep (siehe unten). Sortiert nach maximalem Gewicht.

FaktorStrafpunkte
(Teil-)Ausfall45 je ausgefallenem Zug
Verspätung (Ist)min(v · 0,8 , 42)
Anschluss-Risikoje Umstieg min(Erwartungsverlust · 0,55 , 22) , gesamt min(Σ , 30)
Ausfallrisiko (Prognose)min((p − 0,09) · 140 , 20) , ab p > 9 %
Verspätung wahrscheinlich (Prognose)min((p − 0,06) · 90 , 20) , ab 6 %, nur ohne bereits gemessene Verspätung
Warnmeldungenmin(n · 5 , 20)
Voller Zughoch 6 · sehr hoch 12 · überfüllt 18
Zäh für die Distanzmin((Dauer − Erwartung − 20) · 0,1 · s , 18) , Erwartung = 25 + km/80 · 60 [min]
Umweg vs. schnellste+14 (> 50 %) · +9 (> 30 %) · +4 (> 15 % länger)
Wartezeit beim Umstieg+9 (> 90 min Leerlauf) · +4 (> 60 min) , gesamt min(Σ , 14)
Teuermin((€/h − 19) · 0,45 , 12) , ab 30 min Fahrzeit
Umstiegemin(u · 3 , 9)
Nachtumstieg8 je Umstieg zwischen 23 und 5 Uhr
Langsame Zugartmin(Rohwert · s , 8) , je nach Nahverkehrsanteil
Keine Klimaanlageab 24 °C 2 · ab 28 °C 4 · ab 31 °C 6 · ab 34 °C 8
Gleiswechsel4 je kurzfristigem Wechsel
Fußwegemin(n · 2 , 6)
Verspätet aus Vorfahrt6
Sehr früher Start6 , bei Abfahrt vor 6 Uhr
Späte Ankunft6 , bei Ankunft ab 23 oder vor 5 Uhr
Zwischenhaltemin((n − 9) · 0,8 , 5) , ab 10 Halten
Hitze / WetterStörungsrisiko laut Wettervorhersage

slowKeep: keine Strafe für langsam, wenn es eh nicht schneller geht

Die Zeit-Strafen (langsame Zugart, zäh für die Distanz, Umweg) werden gedämpft, wenn diese Verbindung ohnehin zu den schnellsten gehört. Es wäre unfair, die schnellste Option als „zu langsam" zu bestrafen.

s = 1 − 0,6 · clamp((1,3 − Dauer / schnellste) / 0,3 , 0 , 1)

Anschluss reißt: die Wahrscheinlichkeit

Für jeden Umstieg schätzen wir P(Zubringer-Verspätung > Puffer) aus den Quantilen p10, p50 und p90 der prognostizierten Ankunftsverspätung, modelliert als stückweise lineare Verteilungsfunktion.

pMiss = clamp( 1 − F(Puffer) , 0 , 1 ) · F = stückweise linear durch (p10, 0,1), (p50, 0,5), (p90, 0,9)

Diese Modell-Wahrscheinlichkeit mischen wir mit der empirischen Verspätungs-Verteilung genau dieser Linie an genau diesem Bahnhof. Je mehr echte Fälle wir gesehen haben, desto stärker zählt die Empirie:

Mischgewicht der Empirie = n / (n + 600) (n = beobachtete Fälle)

Warum eine Spanne statt einer Zahl

Die p10/p50/p90 sind konform kalibriert. Über viele Fahrten hinweg soll die tatsächliche Verspätung also wirklich in etwa 8 von 10 Fällen zwischen p10 und p90 liegen. So vermeiden wir falsche Punktgenauigkeit und sagen ehrlich „meist X, im ungünstigen Fall Y".

Personalisierung: „Was nervt dich?"

Drei Faktor-Gruppen sind persönlich gewichtbar: Zeit (Reisezeit, Umweg, langsame Zugart), Komfort (voller Zug, Klimaanlage) und Kosten (Preis). Jede Gruppe wird mit einem Faktor multipliziert, danach wird neu summiert und wieder gekappt. Alles andere bleibt unverändert.

Punkte' = round(Punkte · w) , w ∈ { egal: 0 , normal: 1 , nervt: 1,8 }

Das Modell hinter den Prognosen

Ausfallwahrscheinlichkeit und Verspätungs-Quantile kommen aus einem Gradient-Boosting-Modell, das auf vielen tausend historischen Fahrten gelernt hat, mit Merkmalen rund um Linie, Bahnhof, Uhrzeit und Wochentag. Das trainierte Modell und die genaue Merkmalsliste behalten wir bewusst für uns, aus zwei Gründen: sie sind unser eigentlicher Vorsprung, und eine offene Merkmalsliste würde einladen, den Score auszutricksen statt die Bahn.

Verbindung prüfen Offene Daten ansehen