Alter der DataFrames 2: Polars Ausgabe
23.05.2024
•
Wouter Gins
In dieser Veröffentlichung präsentiere ich einige Tricks und Funktionen von Polars.
Als eines der neueren Kids auf dem Block bietet Polars eine spannende Alternative zu PySpark für kleine bis mittelgroße Datensätze, wie bereits in anderen Blogbeiträgen nachgewiesen. Hier werden wir unsere Füße in das Wasser tauchen mit einem fokussierteren Thema, um zu zeigen, wie leistungsstark und ausdrucksstark Polars sein kann: E-Sports-Vorhersagen. Wir werden einen Blick auf ein Turnier des Videospiels Age of Empires II: Definitive Edition (AoE) werfen und versuchen, eine Vorhersage zu treffen, wie die erste Runde verlaufen wird. Abgesehen von einem ähnlichen Alter (Polars hatte sein erstes Commit im Juni 2020, AoE wurde im November 2019 veröffentlicht), hat die AoE-Community viele Community-Projekte hervorgebracht, um riesige Datenbanken zu pflegen, was es ideal für ein kleines Projekt wie dieses macht. Ich hoffe, dass Sie am Ende dieses Blogbeitrags meine Freude über die Funktionen von Polars, die einfach funktionieren 😄, teilen werden.
Um eine Vorhersage zu treffen, werde ich zuerst einige der Daten betrachten, die von der Community gesammelt wurden, dann ein einfaches Modell zur Berechnung einer Gewinnchance erstellen und schließlich dieses Modell auf das Turnier anwenden.
Wenn Sie mit diesen Konzepten experimentieren möchten, hier ist ein Link zum GitHub-Repo, mit dem Sie die Daten herunterladen und starten können.
📖 Datenquelle
Für unsere Daten haben wir von aoestats.io gescraped, das eine Datenbank von gespielten Online-Spielen pflegt. Ich interessiere mich derzeit nur für offiziell gerankte Spiele, was entspricht, dass raw_match_type zwischen 6 und 9 (einschließlich) liegt. Ich werde dies als Filter für das Lesen hinzufügen.
Ich habe die Daten bereits vorverarbeitet und ein wenig bereinigt. Nach der Filterung nach dem Spieltyp sehen die Daten so aus:

Ein pfiffiger Trick, den Polars bietet, ist der .shrink_dtype()
-Ausdruck, der numerische Typen auf die kleinste Version reduziert, die die derzeitigen Werte im DataFrame unterstützt. Sehr nützlich, um den Speicherverbrauch zu minimieren!
Warum filtern: Wachsame Leser werden auch von der Existenz des Semi-Joins wissen, den ich auch hätte verwenden können, um die Daten zu filtern, indem ich ein kleines DataFrame mit einer raw_match_type-Spalte erstelle. In Tests fand ich einen minimalen Leistungsunterschied zwischen den beiden (0,4s gegenüber 0,6s). Mein Fazit hier ist, dass der Semi-Join wahrscheinlich etwas Overhead hat. Für Filterung über größere Mengen von Werten oder über Werte, die vorher nicht bekannt sind, würde ich den Semi-Join empfehlen.
Nun, neben den Matches benötige ich auch die Daten der Spieler, die an diesen Spielen beteiligt sind. Dies ist ein idealer Fall für den Semi-Join!

Da der Datensatz fast 12 Millionen gespielte Spiele und 42 Millionen Aufzeichnungen von Spielern in diesen Spielen enthält, ist der Datensatz groß genug, um herumzuspielen und gerade klein genug, um auf meinem bescheidenen Laptop gespeichert zu werden (wenn ich Chrome schließe 😉).
🔮 Gewinnchance-Vorhersage: Erstellung einer Nachschlagetabelle
Von besonderem Interesse in diesem Datensatz sind die rating oder elo-Spalten, die eine Zahl darstellen, die zeigt, wie stark ein Spieler ist. Dieses Konzept stammt aus dem Schach und wird in verschiedenen E-Sports weit verbreitet genutzt, um Spieler zu bewerten. Als naive Schätzung für die Gewinnchance eines Spielers können wir den Unterschied in der Bewertung verwenden. Lassen Sie uns zuerst die Daten transformieren, damit sie einem Klassifikator zugeführt werden können, und dann eine Nachschlagetabelle für den Bewertungsunterschied erstellen:

Für den Klassifikator habe ich einfach den Gaussian Naive Bayes-Klassifikator verwendet, der in scikit-learn verfügbar ist. Dies ist nicht unbedingt die am besten geeignete Wahl, und ich werde die Daten auch nicht in ein Trainings- und Testset aufteilen. Um gute Modelle zu erstellen, sind diese Schritte absolut entscheidend, aber ich möchte mich darauf konzentrieren, wie man Polars verwendet und nicht auf Machine Learning 😉 Nur zum Spaß habe ich das Modell auch bewertet, um zu sehen, wie es abschneidet:
Unser Klassifikator erzielt 55%, also etwas besser als ein einfacher Münzwurf! Die Klassifikation wählt aus, wer die höhere Gewinnquote hat, was etwas langweilig ist. Das Modell kann jedoch auch die Gewinnquote angeben, was nicht so langweilig ist! Lassen Sie uns dies in Schritten von 5 ELO-Punkten über einen anständigen Bereich auswerten, damit wir sehen können, wie sich die Gewinnchance sanft ändert. Da wir mit dem Klassifikator interagieren müssen, ist die Polars-Version einer benutzerdefinierten Funktion erforderlich, die entweder map_elements(...)
oder map_batches(...)
sein kann. Der genaue Unterschied ist ziemlich nuanciert, und es gibt einen großen Eintrag in der Dokumentation. In dieser Situation kann map_batches
verwendet werden, um alle Daten auf einmal auszuwerten, anstatt Datensatz für Datensatz auszuwerten.
Latest
Why not to build your own data platform
A round-table discussion summary on imec’s approach to their data platform
Securely use Snowflake from VS Code in the browser
A primary activity among our users involves utilizing dbt within the IDE environment.
The benefits of a data platform team
For years, organizations have been building and using data platforms to get value out of data.