Wer wird Weltmeister?

2 Kommentare

Man kann viel über Data Analysis und Machine Learning lesen. Um wirklich zu verstehen, wie es funktioniert und wo die Probleme sind, muss man selbst Hand anlegen. Genau das war eines der Ziele, die wir mit dem DataLab erreichen wollten.

Leider ist es gar nicht so einfach einen Anwendungsfall zu finden, für den genügend frei verfügbare Daten vorhanden sind, der interessant genug ist, um Spaß bei der Arbeit zu haben und der nicht schon von 100 anderen durchgerechnet und damit langweilig ist.

Nach Brainstorming, Mails, Chats, Hangouts und einigem Hin-und-Her konnten wir uns auf eine Idee einigen:

Wir wollen vorhersagen, wer im Sommer die Fußball-Weltmeisterschaft gewinnt!

Zugegeben, die Idee ist nicht sehr originell. Tatsächlich gibt es eine ganze Menge Webseiten, die sich mit der Vorhersage von Sportereignissen beschäftigen (z.B. dataminingsoccer.com). Aber davon ließen wir uns nicht aufhalten. Wir sind alle begeisterte Fußball-Fans und es macht einfach mehr Spaß in den Daten vergangener Weltmeisterschaften zu wühlen, als die Länge und Breite von Schwertlilien zu untersuchen. Außerdem beschäftigen sich die meisten Online-Vorhersagen eher mit nationalen Ligen als mit internationalen Turnieren. Es besteht also noch die Möglichkeit, etwas Neues zu entdecken.

Der Weg ist das Ziel

Doch ohne konkretes Ziel findet man den Weg eher schlecht. Der erste Schritt war also, aus der eher vagen Idee „Lasst uns die WM vorhersagen“ konkrete Ziele abzuleiten. Dabei wurde recht bald klar, dass die Vorhersage des Weltmeisters eher einem Raten gleichkommt. Wesentlich aussagekräftigere Ergebnisse sind dagegen zu erwarten, wenn man sich nur einzelne Partien vornimmt. Damit war das erste Ziel gefunden:

Aus den Daten vergangener Länderspiele soll das Ergebnis eines beliebigen zukünftigen Länderspiels vorhergesagt werden.

Mit „Ergebnis“ ist dabei im einfachsten Fall nur „Heimsieg“, „Unentschieden“ oder „Auwärtssieg“ gemeint. Bei den „Daten vergangener Länderspiele“ waren wir nicht wählerisch. Am interessantesten war natürlich immer der Ausgang der Spiele (also z.B. geschossene Tore oder Tordifferenz).

Daten sammeln

In guter Big-Data-Manier war unser Ansatz sehr simpel: Einfach alles sammeln, was wir kriegen können. Datenformat egal. Quelle egal (solange legal). Alles ist erlaubt, was nicht verboten ist. Hauptsache, wir haben Daten mit denen wir arbeiten können. Um das Säubern der Daten können wir uns später kümmern.

Als gute Datenquelle hat sich (wieder einmal) Wikipedia herausgestellt. Auch wenn es etwas aufwendig ist, die Spielergebnisse aus dem HTML zu extrahieren. Unter www.rsssf.com findet man auch vorgefertigte Datensätze für Länderspiele. Allerdings ist die Seite etwas unübersichtlich. Eine sehr gute und sehr saubere Quelle sind auch verschiedene Anbieter von Sportwetten. Einziger Nachteil: Der Zugriff auf die REST-Schnittstellen ist nicht ganz billig. Letztendlich hat jeder von uns gesammelt, was er für sinnvoll hielt. Es waren sogar einige Buchmacherquoten dabei.

Die gesammelten Daten sowie unseren R, Python, Groovy und Java-Code gibt es wie immer frei zugänglich in einem GitHub-Repository: Soccer 2014.

Daten zusammenführen und säubern

Ohne besondere Absprache war das Format der Daten schon in allen Fällen CSV. Aber CSV ist nicht gleich CSV. Die Spaltennamen waren unterschiedlich (teils englisch, teils deutsch). Die Formate (v.a. Datumsformate) waren unterschiedlich. Um daraus eine gemeinsame saubere Datenbasis zu generieren, gingen wir wie folgt vor:

Unterschiedliche Datumsformate
Das war noch das einfachste Problem. Die R-Funktionen strptime und format leisten hier gute Dienste.

# Eingabeformat z.B. 21.11.1999
INPUTFORMAT <- "%d.%m.%Y"
# Ausgabeformat z.B. 1999-11-21
OUTPUTFORMAT <- "%Y-%m-%d"
 
data <- read.csv2("input.csv")
data$date <- format(strptime(data$date, format=INPUTFORMAT), format=OUTPUTFORMAT)
write.csv2(data, "output.csv")

Unterschiedliche Teamnamen
Ländernamen sind eindeutig. Möchte man meinen. Doch Ländernamen können deutsch oder englisch sein. Um nun die Ergebnisse aus unterschiedlichen Datenquellen zusammenzuführen, verwendeten wir ISO-Ländercodes. Die Vorteile liegen auf der Hand: Für alle benötigten Sprachen gibt es Tabellen, die Ländernamen auf ISO-Codes abbilden. Die ISO-Codes sind einheitlich. Außerdem wirken die Daten mit ISO-Codes aufgeräumter und übersichtlicher. Durch die Umwandlung in ISO-Codes kamen auch einige Rechtschreibfehler zum Vorschein, die auch schnell behoben werden konnten.

# CSV-Datei mit Ländernamen (erste Spalte) und ISO-Codes (zweite Spalte)
iso_code_data <- read.csv2("iso-codes.csv")
 
# Lookup-Tabelle für Zuordnung Ländername -> ISO-Code
iso_codes_by_country <- iso_code_data[,1]
names(iso_codes_by_country) <- iso_code_data[,2]
 
data <- read.csv("data.csv")
data$team_a <- sapply(data$team_a, function(country) { 
    return(iso_codes_by_country[as.character(country)]) 
})

Widersprüchliche Daten
Natürlich gab es Unstimmigkeiten in den Daten. Nachdem alle Quellen auf ein einheitliches Format gebracht wurden, war es auch nicht schwer, diese Unstimmigkeiten zu finden (das R-Kommando merge leistet hier wertvolle Dienste). Bei Nachforschungen kamen auch recht interessante Fakten heraus: So gab es im Laufe der Geschichte Spiele, die aus unterschiedlichen Gründen abgesagt oder abgebrochen wurden. Unter anderem fand das Spiel Spanien-UdSSR im Jahr 1960 niemals statt. Franco verweigerte der Mannschaft der UdSSR die Einreise nach Spanien. Das Spiel wurde als Sieg für die UdSSR gewertet und die UdSSR wurde anschließend Europameister.

Das Zusammenführen, Vereinheitlichen, Bereinigen und Auflösen von Konflikten übernimmt ein kleines Python-Skript. Das Ergebnis ist ein Datensatz mit 6487 Spielen verteilt über die Zeit von Juli 1930 bis Januar 2014. Davon 3276 Heimsiege, 1864 Auswärtssiege und 1347 Unentschieden. Einen ersten Eindruck der Daten geben auch die folgenden Histogramme:

gesamtdaten-histogramme

Automatisierung

Daten sind nicht statisch. Nach der WM ist vor der WM. Neue Länderspiele können in die Analyse mit aufgenommen werden. Der Wiki-Analyse-Job kann jederzeit verbessert und neu angestoßen werden. Auch die Skripte zur Datensäuberung werden stetig weiterentwickelt. Deshalb ist es nötig, so viel wie möglich zu automatisieren. Im Idealfall ist nach jeder Änderung nur ein Knopfdruck nötig, um die ganze Pipeline von Datensäuberung, Datenzusammenführung, Feature-Extraktion, Training und Validierung anzustoßen.

Da wir im Laufe des Projekts viele verschiedene Programmiersprachen und Tools eingesetz haben (curl, wget, python, groovy, R, …) entschieden wir uns für einen pragmatischen Ansatz: Good old Makefiles. Die Verwendung dieser Makefiles, sowie die Ausgabe eines Beispieldurchlaufs, finden sich im GitHub-Repository Soccer-Prediction-2014.

Fazit

Ich kann nun verstehen, warum bei Data Analysis Projekten oft davon die Rede ist, dass die Vorbereitung der Daten wesentlich aufwändiger ist, als die eigentliche Analyse. Wir mussten eine Menge Arbeit investieren um an Daten zu kommen und die Daten zu säubern. Nachdem das geschafft war, kam der interessante Teil: Die Berechnung von sinnvollen Features, die Bewertung dieser Features und letztendlich das Trainieren eines Modells und die Vorhersage des Fußball-Weltmeisters 2014. Das sind auch die Themen für die kommenden Blog-Posts. Stay tuned…


Weitere Artikel der Data Analytics Serie

Teil 1 – Daten sammeln und bereinigen
Teil 2 – Ist Deutschland eine Turniermannschaft?
Teil 3 – Feature Engineering
Teil 4 – Feature Selection
Teil 5 – Logistische Regression und Random Forest
Teil 6 – Die Heimspielproblematik und Vorhersagen für die KO-Runde

Michael Lex ist agiler Softwareentwickler bei codecentric. Neben der täglichen Arbeit mit Java EE oder Spring gilt sein besonderes Interesse dem weiten Feld der Datenanalyse, insbesondere Machine-Learning-Algorithmen.

Share on FacebookGoogle+Share on LinkedInTweet about this on TwitterShare on RedditDigg thisShare on StumbleUpon

Artikel von Michael Lex

Konferenzen

Spark Summit Europe 2015

Data Science

WM-Vorhersage – Das Finale

Weitere Inhalte zu Data Science

Kommentare

  • 12. Mai 2014 von Maik Jäkel

    Ein wirklich schön zu lesender Artikel mit spannendem Inhalt! Ich bin schon auf die Folgeartikel gespannt!

Kommentieren

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert.