Bundesliga-Prognose
Ein selbst trainiertes Modell, das aus historischen Spielstärken eine komplette Saison simuliert und daraus Tabellen-Wahrscheinlichkeiten ableitet.
| Stack | Python, Monte-Carlo-Simulation, TypeScript |
|---|---|
| Demo | Demo folgt |
| Quellcode | noch nicht veröffentlicht |
Wie man den Bundesliga-Meister vorhersagt
Der ominöse Supercomputer
Zum Start jeder neuen Bundesligasaison werden mir etliche Artikel in die Timeline gespült, "Supercomputer prognostiziert Bundesliga", "Supercomputer Bundesliga Vorhersage". Ich glaube kaum, dass man dafür einen Supercomputer braucht. Skeptisch gegenüber dem Begriff beginne ich eine Recherche. Und tatsächlich ist das Modell, was da läuft, auch absolut lauffähig auf einem normalen Computer. Challenge accepted, denke ich. Ich will meine eigene Vorhersage bauen.
Wer gewinnt ein Spiel?
Wie aber bringt man dem Computer bei, Bundesligaspiele vorherzusagen? Man gießt die echte Welt in ein Modell. Fragt mich jemand nach Bayern gegen Elversberg, würde ich auf Bayern tippen. Es ist das spielstärkere Team, es wir meistens gewinnen. Wichtig hier ist das Wort meistens, wenn ich eins in diesem Projekt gelernt habe, dann dass man die Zufallskomponente im Fußball nicht unterschätzen darf. Die Frage "Wer gewinnt ein Spiel?" ist eigentlich auch keine gute Frage, um sie mit einem Modell zu beantworten. Dazu aber später mehr.
Grundlage für das Modell ist: Das spielstärkere Team gewinnt. Und woher weiß ich, wie stark ein Team ist? Ich lerne es einfach. Über eine Fußball-API ziehe ich mir die letzten 10 Bundesligasaisons mit allen Spielen. Jedes Team startet mit derselben Spielstärke. Dann gehe ich alle Spiele durch, dem Sieger erhöhe ich die Spielstärke, dem Verlierer ziehe ich was ab. Gewinnt ein sehr starkes Team gegen ein sehr schwaches, bekommt es weniger Plus, als wenn es gegen ein gleichstarkes oder gar stärkeres gewinnt. Am Ende habe ich ein Modell, ich gebe ihm 2 Mannschaften, es sagt mir, wer gewinnt, genauer: es gibt mir einen Expected-Goals-Wert.
Ist das Modell gut? Nicht wirklich, es gibt in der echten Welt viel mehr Effekte, die Spielergebisse beeinflussen. Ich kein mein Modell aber verbessern, sie mit einfließen lassen. Am besten die, die am meisten ausmachen.
Das Modell verbessern
Das Erste, was ich lerne: Der Heimvorteil existiert tatsächlich. Die durchschnittliche Mannschaft ist in einem Heimspiel besser als auswärts. Das muss mein Modell natürlich lernen. Und meine bisherige "Teamstärke" ist zu allgemein. Es gibt Teams, die viele Tore schießen, aber auch viele kassieren, und welche mit sehr stabiler Abwehr, aber vielleicht schwachem Angriff. Aus der Teamstärke wird also eine Angriffs- und Verteidigungsstärke.
Was ist noch ungenau am Modell? Der Faktor Zeit wird überhaupt nicht berücksichtigt. Dass der 1. FC Köln vor 10 Saisons gegen Bayern mal gewonnen hat, hat dieselben Auswirkungen, wie dass sie letzte Saison verloren haben. Natürlich müssen aktuelle Ergebnisse aber aussagekräftiger sein. Also bekommt mein Modell einen "Zeitverfall", aktuelle Ergebnisse sind mehr wert.
Und so geht das dann weiter: Ich verbessere das Modell, trainiere es auf den letzten 10 Saisons (bis auf die aktuellste, die ist meine Kontrollsaison) und schaue dann, wie gut meine Vorhersage für die Kontrollsaison gewesen wäre. Hinzu kommen so: ein "Saisonabschlag"; zum Saisonwechsel wechseln oft viele Spieler und Trainer, es gibt eine neue Spielphilosophie, hier erlaube ich eine schnellere Anpassung der Spielstärken als in der laufenden Saison. Ein Bias zum Ergebnis 1:1, das Modell unterschätzt, wie oft Spiele unentschieden ausgehen. Dann ein Aufsteiger-Prior, eine Hyperparameter-Grid-Search für meine Variablen. Genug des technischen jetzt. Mehr Details gibts im Sourcecode. Letztendlich ist der Modellkern wie folgt:
log lambda_heim = intercept + attack[heim] - defense[gast] + heimvorteil
log lambda_gast = intercept + attack[gast] - defense[heim]
Und ja, damit kann man tatsächlich ziemlich gute Vorhersagen machen. Ich bin jedenfalls überzeugt: Auf lange Sicht schlage ich jeden Hobbytipper.
Die Vorhersage
Irgendwann wird das Modell trotz meiner Anpassungen kaum noch besser. Natürlich ginge noch viel mehr: Marktwert mit einberechnen, Verletzungen von Spielern, Derbybias, ist es ein Spiel, das die Meisterschaft entscheiden kann, oder spielt der hoffnungslos abgestiegene Tabellenletzte gegen irgendwen aus dem Mittelfeld? Aber ich denke, ich habe einen guten Stand erreicht.
Was will ich jetzt aber eigentlich vorhersagen? Der Supercomputer aus den Artikeln sagt die Abschlusstabelle voraus, und das hat auch einen einfachen Grund: Es verringert den Einfluss vom Zufall. Ein einzelnes Spiel richtig vorherzusagen ist größtenteils Glück. Auch bei Bayern gegen Elversberg. Aber zu sagen, dass über die gesamte Saison Bayern vor Elversberg landet, das ist eine treffsichere Vorhersage.
Jetzt gerade gib mein Modell eine Vorhersage für Heim-Tore und Gast-Tore. Wie ich zur Abschlusstabelle komme? Ich rechne sie durch (bzw. lasse den Computer rechnen). Mein Modell liefert mir das wahrscheinlichste Ergebnis und ich aktualisiere die Tabelle entsprechend. Das mache ich nicht nur einmal, ich baue einen kleinen Zufall ein (man könnte es auch Tagesform nennen) und rechne die Saison 10.000-mal durch. Jedes Ergebnis ist leicht anders, und am Ende nehme ich den Durchschnitt. Das Tolle ist, dass ich so nicht nur sagen kann, Bayern wird Meister, ich kann sagen, in wie viel Prozent meiner Vorhersagen sie Meister wurden. Ich kann auch Wahrscheinlichkeiten angeben, dass Köln Champions League spielt oder dass sie absteigen.
Damit auch sichtbar ist wie "schlecht" das Modell darin ist einzelne Spiele vorherzusagen, zeige ich doch auch Spielprognosen. Schau dir gerne die Demoseite an. Du siehst meine Tabelle und kannst die Vorhersage zu jedem Spiel sehen, mit den 3 wahrscheinlichsten Ergebnissen, Expected-Goals-Wert und vielem mehr. Damit brauchst du dich beim nächsten WM-Tippspiel also nicht mehr aufregen, wenn die Person ohne jeglichen Fußballverstand gewinnt, die Stichprobe ist einfach viel zu klein, der Zufall zu groß. Selbst ein Modell, dass alle Spiele der letzten 10 Sasions kennt ist nur ein bisschen besser als du.
Zusätzlich aktualisiert sich meine Prognose jede Woche automatisch, indem sie die neuen Ergebnisse miteinbezieht, gleichzeitig sind aber auch alle alten Prognosen verfügbar. Mal gucken, wie sich die Vorhersage im Laufe der Saison verändern wird. Eine Sache halte ich hier schon mal fest: Der glorreiche 1. FC Köln wird zwischen 29 und 54 Punkte erreichen, zu 7% in der Relegation landen, zu 5% direkt absteigen und sich zu immerhin 1,5% für die Europa League qualifizieren. Man wird ja wohl noch träumen dürfen.