Machine Learning ist – zusammen mit Big Data oder Artificial Intelligence (AI) – seit einiger Zeit eines der Top-Themen bei Data Scientists. Und dies nicht ohne Grund: Die in Aussicht gestellten Anwendungsfälle und Ergebnisse – von vollautomatischer Bilderkennung bis zur Vorhersage von Marktentwicklungen – sind äusserst vielversprechend. Allerdings scheinen für viele die Einstiegshürden hoch. Dieser Blogpost soll anhand eines Praxisbeispiels zeigen, wie der Einstieg in Machine Learning mit Cloud Plattformen wie Azure einfach gelingen kann.
Der vorliegende Blogpost ist der zweite Teil einer kleinen Serie zu Machine Learning mit Azure. Im ersten Teil habe ich die Azure Cloud-Plattform und ihre Machine Learning-Komponenten eingeführt.
Praxisbeispiel: Marktanteil von Elektroautos
Elektromobilität ist populärer denn je. Dies trifft insbesondere auf das Segment der Elektro-PKW zu, von denen die Hersteller zurzeit fast wöchentlich neue Modelle vorstellen. Hinsichtlich Effizienz und lokalem Schadstoffausstoss sind die Elektroautos ihren Verbrenner-Kollegen bekanntlich deutlich überlegen. Zudem erfreuen sie sich einem stetig wachsenden Ladestellennetz und – in der Schweiz zurückhaltenden – staatlichen Förderungen. In der Konsequenz sind sie im Strassenverkehr immer öfters anzutreffen. Grund genug für mich, um Elektroautos als Praxisbeispiel für Azure ML zu untersuchen.
Konkret will ich herausfinden, ob der steigende Marktanteil an neu zugelassenen Elektroautos der letzten Jahre erklärt werden kann durch die Preisentwicklung konventioneller Treibstoffe und das wachsende Netz an Ladestationen. In der Machine Learning-Sprache ausgedrückt will ich anhand von zwei Features (Treibstoffpreis und Anzahl Ladestationen) ein Modell trainieren, das zuverlässig Werte für das Label (Markanteil neu zugelassener Fahrzeuge) schätzen kann. Dieses Modell möchte ich anschliessend nutzen, um den künftigen Marktanteil bei veränderten Rahmenbedingungen zu schätzen (z.B. bei einem höherem Treibstoffpreis). Das Ziel bleibt dabei aber das Aufzeigen der Anwendung von Machine Learning in der Praxis, nicht die Konstruktion eines cleveren Modells mit hoher Validität und Erklärungskraft.
Vorbereitung ist alles – auch bei Daten
Wie so häufig ist der erste Knackpunkt die Datengrundlage. Historische Daten zur Verbreitung von Ladestationen zu finden, erwies sich als äusserst schwierig. Bei GoingElectric wurde ich schliesslich fündig, wenn auch nicht ganz in der erhofften Form. Mittels eines nützlichen kleinen Hilfsmittel namens WebPlotDigitizer und etwas händischer Nachbearbeitung konnte ich die Grafik in verarbeitbare Daten überführen.
Für die Treibstoffpreise habe ich als Proxy-Mass auf Handelspreise für Diesel und Benzin von finanzen.ch abgestützt. Zwar entsprechen diese nicht den realen Tankstellenpreisen, dürften aber gemittelt auf den monatlichen Durchschnittspreis ungefähr denselben Schwankungen unterliegen wie die Endkundenpreise. Da die Features vor dem Training des ML-Modells normalisiert werden, sind die absoluten Werte ohnehin weniger wichtig als die relativen Veränderungen.
Die Fahrzeug-Neuzulassungen liessen sich komfortabel über das Tool STAT-TAB vom Bundesamt für Statistik beziehen.
Im Designer von Azure ML finden sich zahlreiche Werkzeuge zur Aufbereitung der Inputdaten, etwa für spaltenbasierte Berechnungen oder Joins. Für die umfangreichen benötigten Transformationen, insbesondere der Neuzulassungsdaten, hätte sich sinnvollerweise nur das Modul Execute Python/R Script angeboten. Da sich Code einerseits besser in einer vollwertigen IDE schreiben lässt und das Schreiben von Code in Azure ML andererseits auch nicht das eigentliche Ziel des No Code-Ansatzes ist, habe ich die Datenaufbereitung aus Azure ML ausgelagert.
Meine Werkzeuge der Wahl zur Datenkonversion waren Visual Studio Code und die Pandas-Library für Python. Die Rohdaten wurden über die ganze Schweiz sowie nach Treibstoffart aggregiert und erhielten einen Zeitstempel im Format YYYY-MM. Anschliessend wurden die Datentabelle transformiert, sodass dass jeder Record einen Zeitstand abbildet, mit dem Zeitstempel in der ersten Spalte und den Treibstoffarten in den restlichen Spalten. Auf dieser Basis konnte anschliessend der prozentuale Marktanteil der rein elektrischen Fahrzeuge (also ohne Plug-In-Hybrid- oder Mild-Hybrid-Systeme) berechnet werden.
Der Marktanteil begann sich gemäss den Neuzulassungsdaten in der Schweiz erst ab 2009 schwach zu regen. Interessanterweise entspricht dies zeitlich in etwa dem Release des ersten Modells Roadster von Tesla. Der Prius von Toyota bleibt hier übrigens unberücksichtigt, da es sich nicht um ein reines Elektrofahrzeug handelt. Eine markante Zunahme des Markanteils fand in den letzten zwei Jahren statt, wobei diese Zunahme jeweils ausgeprägten monatlichen Schwankungen unterlag.
Schliesslich habe ich die einzelnen Datensätze in einen einzelnen Dataframe und somit in eine CSV-Datei gepackt. Dann konnte ich die fertig aufbereiteten Daten als Datasets auf Azure ML hochladen und registrieren, so dass sie für den Designer nutzbar sind. Der von allen Datensätzen abgedeckte Zeitraum umfasst die Monate von 2013 bis und mit 2019, also 84 Datensätze.
Bau einer Machine Learning-Pipeline
Im Designer können mittels Drag & Drop die passenden Module auf der Leinwand angeordnet und zu einer Pipeline für die Datenanalyse verbunden werden. Eine solche Pipeline besteht in der Regel aus folgenden Bestandteilen: Datenvorbereitung, Modelltraining und Validierung. An diesem Schema habe ich mich auch hier orientiert.
Zur Datenvorbereitung wurde mittels Execute Python Script nachträglich der Unix-Timestamp hinzugefügt, sollte er denn gebaucht werden, die Daten auf Werte zwischen 0 und 1 normalisiert (Normalize Data) und in Testdaten (70%, randomized) und Validierungsdaten (30%) aufgeteilt (Split Data). Das bedeutet, das von den 84 Samples 70% zufällig ausgewählt werden für das Training des Modells. Die restlichen 30% dienen später zur Überprüfung der Güte des Modells.
Für die Auswahl des Modells stehen zahlreiche Kandidaten bereit. Erst nachdem diese Modelle mit Trainingsdaten angelernt (und anschliessend überprüft!) wurden, sind sie bereit zur Verwendung. Die Dokumentation von Azure stellt ein praktisches Cheat Sheet zur Verfügung, um die Auswahl des Algorithmus zu erleichtern. Da das Ziel ist, numerische Werte (Marktanteil) (und nicht zum Beispiel diskrete Werte wie Klassenzugehörigkeit) vorherzusagen, konzentriere ich mich auf Regressionen.
Als simpler, aber weit verbreiteter Algorithmus ist Linear Regression als erster Kandidat gesetzt. Die Bayesian Linear Regression wäre aufgrund ihrer Eignung für geringe Datenmengen ebenfalls interessant, aber leider vorübergehend nicht verfügbar. Der zweite Kandidat ist Decision Forest Regression, der nicht-lineare Beziehungen abbilden kann und robust gegenüber Datenfehlern (Noise) ist – eine nützliche Eigenschaft bei den verfügbaren Quelldaten. Schliesslich bildet die Neural Network Regression den dritten Kandidaten für den Vergleich.
Für jeden der drei Algorithmen habe ich eine eigene Kopie der Pipeline im Designer erstellt, die abgesehen vom Modell identisch sind. Die Pipelines wurden jeweils mit drei verschieden konfigurierten Modelvarianten gestartet. Die zu vorhersagende Eigenschaft (Label) wird in Train Model angegeben, welches den jeweils gewählten Algorithmus anhand der Trainingsdaten trainiert. Dabei wird das Rohmodell so angepasst, dass es aus den Features möglichst gut den Wert des bekannten Label schätzt.
Wie gut das trainierte Modell bei unbekannten neuen Daten funktioniert, wird anhand der Validierungsdaten im Score Model-Schritt bestimmt. Hier wird das Modell nur mit den Features gefüttert und muss das unbekannte Label selbst schätzen. Dieser Schätzwert wird anschliessend mit den bekannten Werten in den Validierungsdaten verglichen. Die Güte des Modells kann dadurch anhand fünf verschiedener Masse überprüft werden.
Die ersten vier Masse geben uns die Diskrepanz zwischen dem geschätzten und dem tatsächlichen Wert des Labels an. Der Relative Absolute Error (RAE) beispielsweise hat Werte zwischen 0 und 1. Mit 0.62 ist der Fehler des hier gezeigten Linear Regression-Durchlaufs sehr hoch. Die geschätzten Marktanteile sind also recht weit entfernt von den tatsächlichen Werten. Dies bestätigt auch der Coefficient of Determination (R2), der die Erklärungsgüte des Modells als Wert zwischen 0 und 1 angibt. Mit 0.53 liegt der Output des Modells in der Mitte zwischen – salopp gesagt – «zufälligem Ergebnis» und «perfekter Erklärung».
Für die Auswahl des Modells und seiner Hyperparameter gibt es zum Teil lose Anhaltspunkte und Best Practices, andererseits kann man auch systematisches Hyperparameter-Tuning durchführen. Im hier gezeigten Beispiel habe ich aber einfach ein wenig «Trial and Error» zugelassen: Ich habe pro Algorithmus jeweils drei Varianten konfiguriert und die Modelle trainieren lassen. Um die Resultate der einzelnen Durchläufe auch später nachprüfen zu können, wurde der Pipeline ein weiteres Execute Python Script Modul hinzugefügt. Dieses loggt die Gütemasse, so dass sie später bequem beim Menüreiter Experimente ausgelesen werden können. Folgende Resultate wurden erzielt:
Modell | MAE | RMSE | RSE | RAE | R2 |
Linear Regression 1 | 0.071 | 0.111 | 0.466 | 0.608 | 0.534 |
Linear Regression 2 | 0.072 | 0.112 | 0.474 | 0.622 | 0.526 |
Linear Regression 3 | 0.071 | 0.111 | 0.469 | 0.612 | 0.531 |
Decision Forest Regression 1 | 0.074 | 0.106 | 0.424 | 0.638 | 0.576 |
Decision Forest Regression 2 | 0.078 | 0.120 | 0.546 | 0.674 | 0.454 |
Decision Forest Regression 3 | 0.073 | 0.102 | 0.395 | 0.630 | 0.653 |
Neural Network Regression 1 | 0.088 | 0.131 | 0.645 | 0.757 | 0.355 |
Neural Network Regression 2 | 0.135 | 0.167 | 1.047 | 1.164 | -0.047 |
Neural Network Regression 3 | 0.138 | 0.160 | 0.969 | 1.184 | 0.031 |
Allein aufgrund der Gütemasse beurteilt performt die Methode «Decision Forest Regression 3» am besten. Während einige andere Modelle ähnlich gute oder leicht bessere Resultate bei den Error-Metriken liefern, spricht der bessere Coefficient of Determination für dieses Modell.
Absolut betrachtet sind die Resultate aller Modelle eher bescheiden. Dies hat viele Gründe: Die verwendete Datenbasis ist klein (kurze Zeitreihe und nur wenige Features bzw. erklärende Variablen) und zudem auch mit einigen Ungenauigkeiten behaftet. Der Marktanteil von Elektrofahrzeugen hängt in der Realität natürlich noch von weiteren Faktoren ab als nur dem Treibstoffpreis konventioneller Fahrzeuge und dem vorhandenen Ladestationsnetz. Weitere bestimmende Faktoren könnten der technische Fortschritt von Elektroautos (insbesondere der Reichweite) sein, der gesellschaftliche Diskurs über Mobilität oder die mit der Zeit steigende Akzeptanz neuer Technologien.
Bei Azure ML gibt es zudem auch (noch) kein Modell zur Auswahl, das explizit für die Vorhersage von Zeitreihen vorgesehen ist und von der zeitlichen Abfolge unserer Daten Gebrauch machen könnte, wie das etwa Long Short-Term Memory Network Modelle bzw. Recurrent Neural Networks (RNNs) können. Solche komplexeren Modelle wären mit dem ebenfalls in Azure bereitgehaltenen SDK (siehe erster Blogpost) und einer der Python-Machine Learning-Libraries umzusetzen.
Ausbau zum Vorhersage-Service
Bisher diente das trainierte Modell lediglich zur Schätzung bekannter Werte (Labels), um die Gütemasse zu bestimmen. Doch was für Werte liefert das trainierte Modell bei verschiedenen zukünftigen Rahmenbedingungen?
Um das Modell zur Schätzung neuer Labels einzusetzen, kann in Azure per Knopfdruck auf Basis der bestehenden Trainingspipeline eine «Echtzeit-Rückschlusspipeline» (Inference Pipeline) erzeugt. Dabei werden automatisch einige Änderungen an der Training-Pipeline im Designer vorgenommen: Das Rohmodell samt Training-Modul wird durch das trainierte Modell ersetzt und es kommen Module für den Dateninput sowie Datenoutput via Web-Schnittstelle hinzu. Wenn ein entsprechendes «Compute Target» (vom Typ Inference Cluster) erzeugt wird, kann die Pipeline auf diesem publiziert werden. Dies ermöglicht die Eingabe der Inputdaten und das Auslesen der Resultate via REST-Schnittstelle über eine definierte URL.
In unserem Praxisbeispiel verzichte ich auf die Publikation der REST-Schnittstelle. Die dabei kontinuierlich anfallenden Kosten (aufgrund des durchgehend aktiven Inference Clusters) lohnen sich für ein Demoprojekt mit Testdaten nicht. Stattdessen kommt ein Enter Data Manually-Modul hinzu, um die Daten händisch zu hinterlegen. Mittels Execute Python Script können die erhaltenen Schätzungen ausgelesen werden.
Diese nun produktive Pipeline habe ich mit drei Testszenarien für Ende 2021 gestartet: Einmal ein verteuerter Treibstoff (CHF 2.00 pro Liter) bei gleich vielen Ladestationen (855), einmal mit stabilem Treibstoffpreis (CHF 1.35 pro Liter, gemäss Börsenkurs) und deutlich ausgebautem Netz an Ladestationen (1’200) und einmal mit einer Kombination daraus (CHF 2.00 pro Liter und 1’200 Stationen). Was hat das Modell hierfür geschätzt?
Szenario | Marktanteil |
Teurerer Treibstoff | 4.69 % |
Mehr Ladestationen | 31.0 % |
Kombiniert | 27.5 % |
Hier zeigt sich, dass unser «toy example» kein realistisches Modell ergeben hat. Sagen wir es mal so: Der Umgang mit dem Treibstoffpreis ist fragwürdig… Eine Verteuerung alleine führt zu einem ganz leicht schrumpfenden Marktanteil von Elektroautos gegenüber dem letzten bekannten Wert (4.8%) und eine Verteuerung mit Ausbau des Ladestationsnetzes reduziert den Marktanteil gegenüber einem ausschliesslichen Ausbau des Ladestellennetzes. Letztere Massnahme alleine führt hingegen gemäss Modellschätzung zu einem wahren Durchbruch der Elektromobilität. Zumindest ich bin bei diesen «Prognosen» sehr gespannt, was uns die Zukunft bringen wird!
Zwei Punkte illustriert unser einfacher Test aber gut: Machine Learning-Modelle dürfen nicht nur aufgrund abstrakter Qualitätsmasse evaluiert werden. Und der Variablenauswahl und dem Feature Engineering sollte genug Gewicht und vor allem auch Fachexpertise zukommen.
Machine Learning leicht gemacht?
Azure stellt zahlreiche Services zur Verfügung, um Machine Learning zu betreiben – einige davon in sehr spezifischen Fachbereichen. Dennoch existiert mit dem Azure Machine Learning Studio auch ein Angebot, das die Einstiegshürden sehr tief legt und zum Experimentieren einlädt. Natürlich benötigt auch diese Plattform etwas Einarbeitungszeit, nur schon in die Terminologie. Warum genau ein Compute-Cluster (und nicht etwa eine Compute-Instanz) benötigt wird oder worin sich Pipelines von Experimenten unterscheiden, ist nicht selbsterklärend. Auch der Designer bietet viele Module und Einstellungen, so dass das Erstellen einer funktionierenden und vor allem einer sinnvoll konfigurierten Training Pipeline keine Selbstverständlichkeit ist.
Und doch erlaubt es diese Plattform, sich auf die Bedeutung und die Zusammenhänge der einzelnen Schritte im Machine Learning-Prozess zu konzentrieren, ohne sich in den Details und Fallstricken des Codings im SDK zu verirren. Dies alleine erleichtert den Einstieg und fördert das Verständnis für Machine Learning und Cloud Computing ungemein.
Ein Manko hat das Azure Machine Learning Studio meiner Meinung nach allerdings: Während es das «Doing» des maschinellen Lernens vereinfacht, kann es beim «Thinking» nicht sehr stark unterstützen (wobei das eigentlich nicht der Plattform angelastet werden kann). Ob nun für einen Anwendungsfall die Decision Forest Regression oder die Neural Network Regression geeigneter ist und mit welchen Parametern diese konfiguriert werden soll, lässt sich nur durch ein genaues Studium der Dokumentation von Azure und vor allem von Machine Learning-Literatur bzw. durch Vorwissen von Expertinnen und Experten fundiert beantworten.
Mit dem einfachen Handling besteht natürlich ein bisschen die Gefahr, dass unbewusst unzureichende Modelle trainiert werden, die auch entsprechende Schätzungen abliefern. Obiges Modell zur Elektromobilität ist ein gutes Beispiel dafür: Obwohl der R2-Wert und die Error-Masse gemessen an den wenigen Features und Inputdaten einigermassen brauchbare Resultate versprechen, sorgen die produzierten Schätzwerte doch eher für Stirnrunzeln als Aha-Momente. Hier wäre (neben einer umfangreicheren Datenbasis mit einer längeren Zeitreihe und mehr Features) die Verwendung eines spezifisch für Zeitreihen ausgelegten, etwas komplexeren Modells sicherlich die bessere Wahl gewesen.
Dennoch würde ich Azure Machine Learning Studio jeder und jedem empfehlen, die bzw. der einen gut zugänglichen Einstieg in dieses Thema absolvieren möchte. Für das Ausprobieren und Testen eigener Pipelines und Modelle hält das Azure Machine Learning Studio unter dem Modul Sample datasets sogar über ein Dutzend Datensätze bereit.
In diesem Sinne: Happy Machine Learning!