Im letzten Beitrag der Serie wurden zunächst die ASHRAE Kaggle Competition vorgestellt und die dort verfügbaren Daten visualisiert. Dabei wurden die Daten aus verschiedenen Blickwinkeln beleuchtet, um ein Gefühl für die Daten zu bekommen. Man konnte sehen, wie in der Realität eigentlich immer üblich, dass der Datensatz einige Makel hat.
Im folgenden Beitrag wollen wir uns nun mit dem Schritt des Data Cleansings beschäftigen und an dem Use Case der Kaggle Competition vorstellen, wie dieser aussehen kann.
Data Cleansing bezeichnet dabei das Vorgehen einen Rohdatensatz zu analysieren, um fehlerhafte bzw. fehlende Datensätze zu erkennen und diese zu korrigieren oder zu löschen. Weiter werden relevante Features identifiziert für die zu erwarten ist, dass die Zielvariable (in unserem Fall meter_reading) von diesen abhängt. Ziel dabei ist es einen wohlgearteten Trainingsdatensatz zu erzeugen, von dem ein Lerner die zugrunde liegenden – unbekannten – Gesetzmäßigkeiten lernen kann.
Im letzten Blogbeitrag haben wir schon sehen können, dass zum einen einige Daten fehlen und zum anderen unsere Zielvariable meter_reading sich je nach meter_type, primary_use und site_id ganz unterschiedlich verhält. In diesem Teil wollen wir die Missstände der Daten nochmal aufzeigen und Möglichkeiten beschreiben, wie man mit diesen umgehen kann.
Die Daten
Wie schon im ersten Beitrag gesehen, lassen sich die Ungleichverteilungen der Daten besonders gut visuell untersuchen. Die Probleme der Daten, die wir nun zu bewältigen haben, wollen wir hier noch einmal kurz beleuchten:
1. Zum einen ist die Gestalt und Menge der Daten je nach gemessenem Energietyp (meter) sehr unterschiedlich.

2. Zum anderen sieht man bei Verwendung einer logarithmierten Skala, dass meter_reading nach meter im Mittel um etwa zwei, nach primary_use sogar um mehr als drei Größenordnungen variiert. Dies wird in den folgenden Abbildungen deutlich:


Wie im ersten Teil der Beitragsserie bereits angesprochen, beschränken wir uns im Folgenden nun auf den meter Chilled Water.
3. Weiter gibt es vereinzelte Gebäude mit einigen großen Ausreißern in den meter_reading Werten (z.B. Das building_id = 954).

4. Außerdem sind, wie schon im ersten Teil gesehen, die Daten je nach site_id (es gibt nur Daten für die site_ids 0, 2, 6, 7, 9) von sehr verschiedener Gestalt (vgl. auch Blogbeitrag 1):

5. Schließlich gibt es noch einige Datensätze mit fehlenden (essenziellen) Attributen, die wir für unseren Lerner verwenden wollen.
Ziel
Wir wollen nun die Daten für Chilled Water so aufbereiten, dass ein Lerner eine möglichst gute Vorhersage für das meter_reading treffen kann. Ein Indiz für gute Voraussetzungen ist die Korrelation der einzelnen Features mit unserer Zielgröße meter_reading. Wenn man sich von dem unbereinigten Datensatz die Korrelationen ansieht (wie im 1. Beitrag bereits gezeigt), stellt man fest, dass es außer zwischen den Features wind_direction und wind_speed sowie dew_temperature und air_temperature kaum Korrelationen gibt. Insbesondere gibt es – außer age – auch keine Größen, die merklich mit unserer Zielgröße korrelieren.

Einerseits bedeutet dies nicht, dass jeder Lerner, der mit den Rohdaten trainiert wird, zum Scheitern verurteilt wäre. Ein Indiz für eine erfolgreiche Vorhersage unserer Zielvariablen ist es aber auch nicht.
Ziel ist nun, die verfügbaren Daten so aufzubereiten, dass wir möglichst Korrelationen zwischen unseren Messgrößen und unserer Zielvariablen meter_reading finden.
Der Aufbereitungsprozess
Im Folgenden werden wir die von uns unternommenen Schritte beschreiben, um die im vorherigen Abschnitt aufgezeigten Probleme anzugehen.
1. Da es sich bei der Energieart um einen kategorisches Attribut handelt, haben wir uns wie bereits vorher angekündigt dazu entschlossen nur die Energieart Chilled Water zu betrachten. Damit verbleibt uns eine Grundmenge aus 4182440 Datensätze, die wir bereinigen wollen. So müssen wir uns nicht mit der Konsolidierung der verschiedenen Energiearten auseinandersetzen. Um Vorhersagen für die anderen drei Energiearten zu machen, würde man für diese gesondert eigene Modelle trainieren.
2. Auch bei dem primary_use handelt es sich um ein kategorisches Attribut. Dieses könnte wie die Energieart in 1. behandelt werden, indem man sich auf einen primary_use konzentriert und für die anderen gesondert Modelle trainiert. Allerdings würde man dadurch die Anzahl der verfügbaren Daten drastisch reduzieren und hätte letztendlich nicht mehr ausreichend Daten um vernünftig ein Modell zu trainieren:
primary_use | Anzahl Datensätze |
Education | 1823125 |
Entertainment/public assembly | 371663 |
Food sales and service | 35132 |
Healthcare | 111324 |
Lodging/residential | 457833 |
Manufacturing/industrial | 6677 |
Office | 1117099 |
Other | 22684 |
Parking | 8781 |
Public services | 179877 |
Religious worship | 7327 |
Retail | 16039 |
Technology/science | 16106 |
Utility | 8783 |
Wenn man doch diesen Weg gehen will, müsste man sich überlegen, wie man geschickt seine Daten vermehrt oder doch verschiedene primary_uses zusammenfassen. Wir werden unser Modell auf allen primary_uses trainieren. Wenn keine ausreichende Genauigkeit des Modells erzielt werden kann, wäre dies ein Punkt an dem man die Daten noch verbessern könnte.
3. Skaliert man das meter_reading linear auf das Intervall [0, 1], so ergibt sich für die für das Maximum der meter_reading Werte je Gebäude folgende Grafik:

Man sieht deutlich, dass der Großteil der Gebäude ein meter_reading von weniger als 0,1 hat. Gebäude mit einem größeren meter_reading werten wir als Ausreißer (wie oben). Damit verbleiben uns etwa 99,97% der Datensätze (4181281).
4. Da sich die Sites strukturell sehr unterscheiden, haben wir uns dazu entschieden nur Daten von site_id = 2 zu verwenden. Die Daten von Site 2 sehen ziemlich homogen aus und können daher vermutlich gut für einen Lerner verwendet werden. Damit verlieren wir einige Datensätze und haben noch 863845. Um die Varianz noch etwas zu verringern, mitteln wir die stündlichen Daten noch jeweils über einen Tag und erhalten 36134 Datenpunkte. Damit sind wir noch im Rahmen der für LightGBM empfohlenen Mindestgröße von 10000 Datensätzen. Für andere Sites sind allerdings noch deutlich weniger Daten vorhanden. Diese müsste man dann mit anderen Sites zusammenfassen, um LightGBM auf diesen zu trainieren.
5. Schaut man sich nun die Korrelationen an, so stellt man fest, dass meter_reading, age, air_temperature sowie dew_temperature korreliert scheinen:

Daher werden wir uns nun auf diese Features einschränken und zu guter letzt alle Datensätze vernachlässigen, die dort fehlende Informationen haben.
Damit verbleiben uns insgesamt 27375 Datensätze, um einen Lerner zu trainieren. Wie schon angemerkt, reicht dies aus, um den LightGBM Algorithmus auf unseren bereinigten Datensatz anzuwenden. Wäre der Datensatz merklich kleiner, so könnte allein durch unsere mangelnde Datensatzgröße Overfitting auftreten. Mit unseren 27375 haben wir zwar einen kleineren Datensatz, aber noch nicht zu klein für unser Vorhaben.
Fazit
Das Resultat des Data Cleansings sieht für unsere Einschränkungen erfolgsversprechend aus. Um die anderen Energietypen und Sites zu untersuchen, wäre ähnlich vorzugehen.
Fachlich wäre zu erwarten, dass der Energieverbrauch jeweils eine Saisonalität aufweist. Anhand der zur Verfügung stehenden Daten wird diese allerdings nicht von einem Lerner erkannt werden können. Um diese dem Modell doch beizubringen, wäre es zum Beispiel eine Option fiktive Daten für 2015 als Duplikat derer von 2016 zu generieren.
Im letzten Teil dieser Beitragsserie wollen wir den LightGBM Algorithmus vorstellen, mit dem präparierten Datensatz trainieren und dabei zeigen, was für einen Einfluss das Data Cleansing auf die Güte des Lerners hat.