
Einleitung
Wer in Münster wohnt, arbeitet oder studiert, kommt am Busverkehr kaum vorbei. Dabei fällt nicht selten auf: Die Busse kommen häufig zu spät, aber woran liegt das eigentlich?
Aus dieser alltäglichen Beobachtung entstand unsere Projektidee. Wir wollten herausfinden, welche Faktoren mit Busverspätungen zusammenhängen und ob es möglich ist, die Verspätungen einer Busfahrt vorherzusagen.
Dabei begann unser Projekt ursprünglich sogar mit einer anderen Idee: Wir wollten Daten der Deutschen Bahn analysieren und Zugverspätungen untersuchen. Im Laufe der Planung wurde uns jedoch schnell bewusst, wie wichtig eine solide und für uns zugängliche Datengrundlage ist. Deshalb änderten wir unseren Fokus und beschäftigten uns schließlich mit dem Busverkehr in Münster.
Unser Ziel war es, aus realen Busdaten ein Machine-Learning-Modell zu entwickeln, das die erwartete Verspätung eines Busses in Minuten vorhersagt. Dafür haben wir eigene Daten gesammelt, einen bereits vorhandenen historischen Datensatz aufbereitet und verschiedene Einflussfaktoren, wie unter anderem die Uhrzeit, Bushaltestelle, das Wetter und verschiedene Events miteinander kombiniert.
Am Ende ist daraus nicht nur ein Machine-Learning-Modell, sondern auch eine eigene Anwendung entstanden, mit der sich eine konkrete Busverspätung vorhersagen lässt.

Methodik
1. Von der Idee zum Datensatz Unser Projekt hat wie bereits erwähnt nicht mit dem Busverkehr begonnen. Im Laufe der Projektplanung zur Verspätung der deutschen Bahn wurde uns schnell deutlich, dass wir zunächst eine belastbare Datengrundlage brauchen. Die Datensätze für die deutsche Bahn gab das leider nicht her. Eine unserer ersten und gleichzeitig größten Herausforderungen war deshalb die Datenerhebung selbst. Die API der Stadtwerke Münster bot lediglich die Information der Livedaten, sodass wir anstatt einen fertigen Datensatz zu übernehmen, eigene Daten sammeln mussten.
Später konnten wir dann glücklicherweise auf einen umfangreichen historischen Datensatz von Thomas Viehmann (Mentor für Deep Learning bei TechLabs) zurückgreifen, der Daten aus dem Zeitraum von Dezember 2023 bis Mai 2026 enthält. Unsere eigenen Erhebungen ergänzten diesen Datensatz ab Juni 2026.
Wir betrachten dabei mehrere Buslinien in Münster, darunter die Linien 1, 2, 5, 8, 10, 14, 15 und 17. Erfasst werden unter anderem Zeitpunkt, Buslinie, Fahrzeug, Fahrt, Fahrtrichtung, aktuelle und nächste Haltestelle sowie die jeweilige Verspätung und der konkrete Standort des jeweiligen Busses.
Damit war die Arbeit noch lange nicht erledigt. Die verschiedenen Datenquellen mussten zunächst zusammengeführt und bereinigt werden. Doppelte Datensätze wurden entfernt und fehlende oder nicht verwertbare Werte bereinigt.
2. Welche Faktoren beeinflussen die Verspätung? Nachdem unsere Datengrundlage stand, wollten wir herausfinden, welche Informationen für eine Vorhersage relevant sein könnten.
Neben der Buslinie und der aktuellen Haltestelle haben wir deshalb zeitliche Faktoren wie Wochentag und Uhrzeit berücksichtigt. Auch Stoßzeiten spielen eine Rolle: Unser Datensatz unterscheidet zwischen Zeiten von morgens bis zum frühen Abend; bis die Nachtbusse zu fahren beginnen. Zusätzlich haben wir Wetterdaten für Münster integriert. Dazu gehören beispielsweise Temperatur, gefühlte Temperatur, Luftfeuchtigkeit, Regen, Luftdruck und Windgeschwindigkeit. Besonders interessant war für uns dabei auch die Frage, ob Regen und Hitze während der Stoßzeiten einen zusätzlichen Einfluss auf die Verspätung haben kann.
Auch Schulferien und Fahrplanabweichungen durch beispielsweise Baustellen wurden in unser Modell aufgenommen. So wollten wir möglichst viele Faktoren abbilden, die erklären könnten, warum sich die Verspätung einer Busfahrt verändert. Unsere Zielgröße war dabei immer dieselbe: Wie viele Minuten Verspätung hat der Bus?
3. Vom Datensatz zum Machine Learning Nachdem unsere Daten aufbereitet waren, stand die nächste große Frage im Raum: Wie können wir aus unseren Daten tatsächlich eine Vorhersage machen? Dafür mussten wir zunächst verstehen, was Machine Learning überhaupt bedeutet. Beim Machine Learning geht es darum, dass ein Computer nicht für jede Situation eine feste Regel vorgegeben bekommt. Stattdessen bekommt er viele Beispiele und versucht, daraus selbst Muster und Zusammenhänge zu lernen. In unserem Fall bedeutet das: Wir geben dem Modell viele vergangene Busfahrten zusammen mit den dazugehörigen Informationen und der tatsächlich gemessenen Verspätung. Daraus soll es lernen, welche Kombinationen von Faktoren typischerweise mit einer bestimmten Verspätung zusammenhängen.
4. Unsere Features Diese sogenannten Features sind die Merkmale, anhand derer unser Modell die erwartete Busverspätung berechnet.
In unserem Code verwenden wir folgende Features:
Line (Buslinie)
Current_Stop (aktuelle Haltestelle)
Direction_ID (Fahrtrichtung)
day_of_week (Wochentag)
hour_sin (zyklisch codierte Uhrzeit – Sinus-Anteil)
hour_cos (zyklisch codierte Uhrzeit – Cosinus-Anteil)
is_rush_hour (Kennzeichnung, ob die Fahrt während einer Stoßzeit stattfindet)
rain_during_rush (Kennzeichnung, ob während einer Stoßzeit Regen vorliegt)
temperature_2m (Temperatur)
apparent_temperature (gefühlte Temperatur)
relative_humidity_2m (relative Luftfeuchtigkeit)
precipitation (Niederschlag)
rain (Regen)
surface_pressure (Luftdruck)
wind_speed_10m (Windgeschwindigkeit)
schulferien (Kennzeichnung, ob Schulferien sind)
abweichung_aktiv (Kennzeichnung, ob eine Fahrplanabweichung aktiv ist)
Unsere Zielvariable ist Delay_Min (Verspätung des Busses in Minuten).
Damit das Modell mit diesen unterschiedlichen Informationen arbeiten kann, mussten wir einige Features zunächst in numerische Werte umwandeln. Für Line und day_of_week haben wir One-Hot-Encoding verwendet: Dabei wird eine kategoriale Variable in mehrere einzelne Merkmale aufgeteilt, die jeweils angeben, ob eine bestimmte Kategorie vorliegt.
Für Current_Stop haben wir dagegen Target Encoding verwendet: Dabei wird für jede Haltestelle anhand der Trainingsdaten ein Wert berechnet, der hier der durchschnittlichen Verspätung an dieser Haltestelle entspricht. Dieser Wert wird anschließend als numerisches Feature Current_Stop_Encoded verwendet. Falls für eine Haltestelle kein entsprechender Wert vorhanden war, wurde der Durchschnitt der Trainingsdaten eingesetzt. Die ursprüngliche Haltestellen-Spalte wurde danach entfernt.
5. Entscheidungsbäume und Random Forest Für unsere Vorhersage haben wir einen Random Forest Regressor verwendet.
Ein Entscheidungsbaum trifft Entscheidungen schrittweise anhand verschiedener Merkmale. Die Daten werden dabei immer weiter aufgeteilt, bis am Ende eine Vorhersage entsteht. Ein Random Forest kombiniert viele solcher Entscheidungsbäume. Dadurch basiert die finale Vorhersage nicht auf einem einzelnen Baum, sondern auf einer Vielzahl von Entscheidungsbäumen.
Für unser Modell haben wir 200 Entscheidungsbäume verwendet. Die maximale Tiefe eines Baumes wurde auf 16 festgelegt. Außerdem haben wir mit min_samples_leaf=4 festgelegt, dass mindestens vier Beobachtungen in einem Blatt enthalten sein müssen.
6. Training und Test Damit wir später überprüfen konnten, wie gut unser Modell auf unbekannten Daten funktioniert, haben wir unsere Daten in Trainings- und Testdaten aufgeteilt. 80 % der Daten wurden zum Trainieren des Modells verwendet, 20 % wurden für den Test zurückgehalten. Die Aufteilung erfolgte zufällig mit einem festgelegten random_state von 42. Anschließend wurde unser Random Forest mit den Trainingsdaten trainiert. Im Code geschieht dies über: modell.fit(Y_train_numeric, x_train). Das Modell erhält dabei die aufbereiteten Features und die dazugehörigen tatsächlichen Verspätungen. Anschließend kann es auf Basis der Testdaten neue Verspätungen vorhersagen.
Damit war der zentrale Teil unseres Modells fertig: Aus unseren Busdaten war eine trainierte Vorhersagekomponente geworden.
Die Arbeit am R2 Wert Nachdem wir unser erstes Modell trainiert hatten, war unser Projekt noch lange nicht abgeschlossen. Es galt den R²-Wert unseres Modells zu verbessern.
Der R²-Wert (Bestimmtheitsmaß) zeigt bei einem Random-Forest-Regressionsmodell, wie gut das Modell die tatsächlichen Werte vorhersagt.
R² = 1,0: perfekte Vorhersage R² = 0,8: Das Modell erklärt etwa 80 % der Schwankungen in den Daten R² = 0: Das Modell ist nicht besser als eine einfache Vorhersage des Durchschnittswerts R² < 0: Das Modell ist sogar schlechter als diese Durchschnittsvorhersage
Wir haben Zur Verbesserung des Wertes immer wieder unsere Features betrachtet und durch Veränderung und Ergänzung aufbereitet und angepasst sowie anschließend überprüft, wie sich dies auf die Modellleistung auswirkt. Auf diese Weise konnten wir den Wert erhöhen und eine akkuratere Vorhersage schaffen.

Ergebnisse
1. Wie gut funktioniert unsere Vorhersage? Nachdem unser Random Forest trainiert war, wollten wir natürlich wissen, wie gut er tatsächlich vorhersagen kann. Dafür haben wir zwei Kennzahlen verwendet: MAE und R².
Der Mean Absolute Error (MAE) beschreibt den durchschnittlichen absoluten Unterschied zwischen der tatsächlichen und der vorhergesagten Verspätung. Der Wert lässt sich direkt in Minuten interpretieren. Unser Modell erreicht einen MAE von 1,07 Minuten. Die vorhergesagte Verspätung weicht damit durchschnittlich um etwa 1,07 Minuten von der tatsächlichen Verspätung ab.
Zusätzlich haben wir den R²-Wert berechnet. Er dient uns als weitere Kennzahl zur Bewertung unseres Modells. Unser finales Modell erreicht einen R²-Wert von 0,354 und erklärt damit 35,4% der Schwankungen in unseren Daten.
Gerade der R²-Wert war während unserer Entwicklung eine besondere Herausforderung. Mit zunehmender Datenmenge sank der Wert zunächst sogar. Aus diesem Grund haben wir immer wieder an unseren Features gearbeitet und untersucht, wie wir die Eingabedaten für unser Modell verbessern können. Für uns war das eine wichtige Erkenntnis: Mehr Daten allein bedeuten nicht automatisch ein besseres Modell. Auch die Auswahl und Aufbereitung der Features spielt eine entscheidende Rolle.
2. Was beeinflusst die Verspätung am stärksten? Neben dem allgemeinen Modellaufbau wollten wir wissen, welche unserer Features für den Random Forest besonders wichtig sind.
Dafür haben wir die im trainierten Modell enthaltene Feature Importance ausgelesen und die Merkmale nach ihrer Bedeutung sortiert. Das Ergebnis war besonders interessant: Das mit Abstand wichtigste Feature ist Current_Stop_Encoded, also die Information über die aktuelle Haltestelle. Es erreicht eine Feature Importance von 54 %.
Danach folgen:
hour_cos: 8,85 %
Windgeschwindigkeit: 5,77 %
Luftdruck: 5,30 %
Fahrtrichtung: 4,69 %
hour_sin: 4,46 %
Luftfeuchtigkeit: 4,45 %
gefühlte Temperatur: 4,17 %
Temperatur: 3,66 %
Schulferien: 3,01 %
Damit liefert uns das Modell nicht nur eine Vorhersage, sondern auch eine interessante Perspektive auf unsere Daten: Die aktuelle Haltestelle ist für die Vorhersage unseres Modells mit großem Abstand das wichtigste Feature.
Dabei ist wichtig: Die 54 % bedeuten nicht, dass 54 % einer Verspätung durch die Haltestelle verursacht werden. Die Zahl beschreibt die Bedeutung dieses Features innerhalb der Vorhersagen unseres Random Forest.
3. Von der Modellierung zur Anwendung Unser Ziel war es nicht, am Ende lediglich ein trainiertes Modell in Google Colab zu haben. Deshalb haben wir zusätzlich ein Frontend entwickelt. Über unsere Bus Verspätungsvorhersage können Nutzer*innen unter anderem eine Buslinie, einen Wochentag, eine Uhrzeit, eine Haltestelle angeben. Diese Informationen werden im Hintergrund in genau die Form gebracht, die unser Modell benötigt. Anschließend wird die erwartete Verspätung ausgegeben.
Damit haben wir aus unserem Machine-Learning-Modell eine Anwendung gemacht, die tatsächlich ausprobiert werden kann.
4. Was wir gelernt haben Unser größtes Learning war, dass ein Data-Science-Projekt nicht einfach aus der Idee, dem Programmieren und einem fertigen Ergebnis besteht. Der Weg dazwischen verändert das Projekt immer wieder.
Im Laufe der Projektplanung mussten wir unseren Fokus ändern und eine eigene Datengrundlage schaffen. Das Durchforsten, Analysieren und Verstehen der selbst gesammelten Daten war deshalb eine unserer ersten großen Herausforderungen. Dabei haben wir gelernt, wie wichtig ein starkes Fundament für ein Projekt ist. Bevor wir überhaupt über ein Machine-Learning-Modell nachdenken konnten, mussten wir klären, welche Daten wir benötigen, wie wir sie bekommen und wie wir sie sinnvoll miteinander verbinden.
Auch technisch sind wir im Laufe des Projekts stark gewachsen. Wir haben gelernt, wie Datensätze aufgebaut sind, wie einzelne Komponenten programmiert werden und wie unterschiedliche Datenquellen miteinander verbunden werden können. Mit der Vorhersagekomponente mussten wir schließlich in ein für uns neues Gebiet eintauchen: Machine Learning und Random Forest. Dabei war auch der Austausch mit unserem Mentor Hendrik Linn unheimlich hilfreich. Durch zusätzliche Hilfsvideos und Literatur konnten wir uns Schritt für Schritt in das Thema einarbeiten. Besonders viel gelernt haben wir aber darüber, dynamisch mit Veränderungen umzugehen**.** Unser Projekt hat sich mehrfach verändert und nicht jede unserer ersten Ideen hat sich am Ende als sinnvoll erwiesen. Auch unser Modell funktionierte nicht einfach beim ersten Versuch so, wie wir es uns vorgestellt hatten. Wir mussten Features anpassen, Ergebnisse analysieren und immer wieder neue Ansätze ausprobieren. Genau das hat uns gezeigt, dass ein gutes Projekt nicht unbedingt dadurch entsteht, dass von Anfang an alles perfekt geplant ist. Vielmehr geht es darum, Probleme zu erkennen, darauf zu reagieren und gemeinsam Lösungen zu entwickeln. Genau das hat uns an unserem Projekt besonders viel Spaß gemacht**:** Wir mussten immer wieder dazulernen – und konnten dadurch an unseren Aufgaben wachsen.
Und vielleicht hilft unsere Vorhersage beim nächsten Mal zumindest dabei, eine Frage etwas besser zu beantworten: Lohnt es sich noch zu warten – oder nehme ich lieber das Fahrrad?
Letztlich geht ein riesengroßes Dankeschön an unseren Mentor Hendrik, der uns bei Fragen, Problemen und Unverständlichkeiten immer schnell zur Seite stand und uns unterstütze, wo er nur konnte. Wir danken dir sehr für dein Engagement und deine Geduld <3
Team
Anonym
Mentor:in
Hendrik Linn






