Wie vorhersehbar ist Fantasy Football? Viele Fußballfans, mich eingeschlossen, fragen sich Jahr für Jahr, ob es überhaupt einen Weg zu dauerhaftem Erfolg in Fantasy-Ligen gibt. Finden wir es mit JMP heraus!
Dank der verbesserten Python-Integration in JMP ist es jetzt einfacher denn je, Ihre Fantasy-Football-Ligadaten in JMP zu importieren. Nach einer kurzen Einführung in die Nutzung der nativen HTTP-Request-Funktionalität von JMP für den Zugriff auf dokumentierte APIs von Fantasy-Football-Anbietern wie ESPN und Sleeper konzentriert sich dieser Vortrag auf die Verwendung bestehender API-Wrapper aus der Python-Community, um jahrelange Daten aus Fantasy-Ligen abzurufen. Von Ligatabellen, Playoff-Ergebnissen, NFL-Spielerstatistiken und Fantasy-Ergebnissen bis hin zu Draft-Erfolgen und -Flops – es gibt unzählige Daten zu entdecken!
Sobald die Daten importiert und in Tabellen organisiert sind, können wir mit den statistischen Analysetools von JMP unsere ligaspezifischen Daten untersuchen und analysieren, um mögliche Trends und Muster zu finden, die uns einen Vorteil verschaffen.
Hängt der Erfolg hauptsächlich vom perfekten Draft ab oder von erfolgreichen Trades und Neuverpflichtungen im Laufe des Jahres? Können Spieler ihre herausragenden Fantasy-Leistungen Jahr für Jahr wiederholen? Wie wichtig ist es, einen der drei besten Fantasy-Spieler im Team zu haben? Sind Running Backs immer noch die einflussreichsten Positionen im Fantasy Football oder hat sich das Blatt zugunsten von Wide Receivern und Quarterbacks gewendet? Diesen Fragen gehen wir nach, um herauszufinden, ob JMP Ihnen helfen kann, Ihre nächste Liga zu gewinnen.
Hallo zusammen. Mein Name ist Nick Holmes. Ich bin Testingenieur bei JMP. Schön, dass Sie heute dabei sind. Heute geht es darum, wie Sie mit JMP Ihre Fantasy-Football-Liga gewinnen können. Ich habe bewusst „vielleicht“ gesagt, denn im Fantasy Football gibt es natürlich keine Garantien. Wir werden heute unsere Fantasy-Football-Daten in JMP importieren, einige Analysen durchführen und sehen, was wir herausfinden können.
Kurz zu mir: Ich bin ein leidenschaftlicher Fantasy-Football-Spieler. Seit etwa 2015 leite ich eine Redraft-Liga mit zwölf Spielern. Die Daten dieser Liga dienen uns heute als Grundlage für unsere Beispiele und Analysen. Hintergrund dieser Präsentation bzw. dieses Projekts ist, dass ich die Liga 2022 gewonnen und 2023 den letzten Platz belegt habe. Ich suche nach Möglichkeiten, meine Ergebnisse im Fantasy Football vorherzusagen.
Ich bin kein Statistiker, aber ich werde mein Bestes geben. Wir werden Daten von ESPN und Sleeper verwenden. ESPN ist euch wahrscheinlich allen bekannt, es ist ein Anbieter für Fantasy Football. Sleeper ist im Prinzip dasselbe, nur eine andere Plattform für eure Fantasy-Football-Liga. Wir werden Daten von beiden Plattformen importieren und für unsere Analyse nutzen.
Ich habe SPN von etwa 2015 bis 2020 und Sleeper von 2021 bis heute genutzt, daher benötigten wir Daten von beiden Plattformen. Dies ist ein kurzer Überblick darüber, wie wir die Daten heute in JMP importieren und analysieren werden. Zunächst müssen wir die Daten mithilfe von APIs importieren. Dies geschieht auf zwei Arten: einmal über eine neue HTTP-Anfrage und einmal über die JMP-Python-Integration.
Anschließend werden wir diese Anfragen in JMP-Klassen oder JMP-Klassenobjekte organisieren – oder ich zeige Ihnen, wie Sie das tun können. Sobald die Daten in JMP vorliegen, müssen sie in JMP-Datentabellen organisiert werden. Dafür gibt es verschiedene Methoden. Ich gebe Ihnen einen Überblick über die JSON-zu-Datentabelle-Funktion, die in JMP integriert ist, sowie über die Arbeit mit assoziativen Arrays und die Verwendung von JSL zum Erstellen von JMP-Datentabellen.
Sobald die Daten in JMP-Datentabellen vorliegen, werden wir sie untersuchen und analysieren. Zunächst bearbeiten wir die Datentabellen. Ich zeige Ihnen das anhand des Workflow Builders. Anschließend visualisieren wir die Daten in JMP und führen Analysen auf verschiedenen JMP-Plattformen durch.
Okay, was ist also eine API? Die Definition einer API finden Sie dort am Rand, aber kurz gesagt: Eine API ist eine Möglichkeit, Daten von einem Webserver abzurufen. Es gibt einige Methoden im Zusammenhang mit HTTP: GET, POST, DELETE und PUT. Heute konzentrieren wir uns auf die wahrscheinlich einfachste: GET. Wir senden eine GET-Anfrage an eine URL oder einen API-Endpunkt. Der Server liefert uns dann einen JSON-String zurück, den wir anschließend verwenden, um in JMP ein assoziatives Array und unsere JMP-Datentabellen zu erstellen.
Die Funktion `new HTTP request` in JMP ermöglicht die Kommunikation mit REST-APIs über JSL und unterstützt, wie bereits erwähnt, die Methoden `get`, `post`, `put` und `delete`. Heute konzentrieren wir uns hauptsächlich auf `get` und zeigen, wie einfach sich Daten mithilfe von `new HTTP request` in JMP importieren lassen.
Ich möchte Ihnen zunächst zeigen, wie Sie Daten von Fantasy League Sleeper abrufen. Wenn Sie kurz in Google nach deren API suchen, finden Sie eine sehr gute Dokumentation, die Ihnen genau erklärt, welchen HTTP-Anfrage-Endpunkt Sie verwenden müssen und welche Art von Daten Sie erwarten können.
Das ist der Idealfall für die Arbeit mit einer API: Der Anbieter stellt eine sehr übersichtliche API bereit, beschreibt genau, welche Daten man erhält und liefert eine klare Dokumentation. Wie man der Dokumentation entnehmen kann, wird beschrieben, wie man Ligadaten und Kaderdaten in JMP importiert. Anscheinend ist für die meisten dieser Schritte lediglich die Liga-ID als URL-Angabe erforderlich.
In diesem Beispiel sehen Sie eine Skizze, wie das in JMP aussehen könnte. Wir geben unsere Liga-ID an und definieren sie als URL-Variable. Anschließend senden wir die Anfrage mit einem neuen HTTP-Request und übergeben die URL mit der Methode GET. Nach dem Absenden der Anfrage parsen wir das an JMP zurückgesendete JSON.
Nachdem wir uns angesehen haben, wie diese Anfrage aussehen könnte, schauen wir uns nun an, wie sie sich in JMP verhält. Hier ist ein JMP-Skriptfenster geöffnet. In der definierten URL sehen Sie unsere Liga-ID und die Anfrage, die Sie in der Folie gesehen haben. Wenn wir diese Anfrage hier ausführen, erhalten wir einen JSON-String zurück. Um diese Daten in JMP besser verarbeiten zu können, wandeln wir sie in ein assoziatives JMP-Array um. Genau dafür ist die Funktion „JSON parsen“ gedacht.
Sie sehen, dass uns ein assoziatives Array zugewiesen wird. Wenn wir dieses Array betrachten und dann den Index verwenden, um den Namen unserer Liga zu erhalten, sehen Sie, dass wir „liga-zertifiziertes Fantasy Football“ zurückgeben, also den Namen der Liga. Nachdem ich Ihnen eine sehr einfache Demo gezeigt habe, möchte ich Ihnen nun zeigen, wie wir unsere Abfragen in JMP-Klassen organisieren können, um unsere HTTP-Anfrage zu strukturieren. Schließen wir dieses Fenster und öffnen wir unsere Projektdatei. Wenn Sie sich diese Projektdatei hier ansehen, werden Sie sehen, dass wir Klassen definiert haben, um unsere Abfragen zu organisieren.
Wir haben diese Liga-Klasse. Wie Sie hier sehen können, basiert sie auf einer Python-API, deren Struktur ich übernommen habe. Darauf gehen wir später noch genauer ein, wenn wir über unsere JMP-Python-Integration sprechen. In dieser Klasse sehen Sie, dass wir Klassen für Liga-Benutzer, Spieler, Draft und Statistiken haben. Alle diese Klassen im Backend rufen die übergeordnete API auf, die unsere neue HTTP-Anfrage im Hintergrund auslöst.
Schauen wir uns an, wie wir diese Klasse verwenden können, um unsere Daten zu erhalten. Ich zeige Ihnen die Klassendefinition und scrolle dann hier nach unten zu den Beispielen. Entschuldigen Sie, falls Ihnen vom Scrollen schwindelig wird. Sie sehen nun, dass ich ein Liga-Objekt definiere. Auch hier übergebe ich ihm meine Liga-ID. Sie sehen hier die Klassendefinition, und jetzt können wir die für dieses Objekt definierten Methoden verwenden, um die Kader der Liga abzurufen. Wir können die Benutzer der Liga abrufen und so weiter. All dies wurde in einem assoziativen Array zurückgegeben.
Wir werden uns jetzt nicht genauer mit dem Inhalt befassen, sondern Ihnen lediglich die zurückgegebenen Daten zeigen. Dasselbe gilt nun für Benutzer, Spieler und Drapierungen. Ich werde all dies zusammen mit den Folien als Präsentationsmaterial mit der JMP-Community teilen. Sie sollten diese Klassen in der später gezeigten verwenden können, um Ihre Daten in JMP zu importieren.
Bei Sleeper war der Datenzugriff sehr einfach. Es gab eine klar definierte API, mit der wir unsere HTTP-Anfrage erstellen konnten. Bei ESPN scheint das leider nicht der Fall zu sein. Eine kurze Suche nach „ESPN API“ oder „ESPN Fantasy API“ liefert lediglich eine von jemandem erstellte Python-Klasse. Eine öffentlich zugängliche Dokumentation der API scheint nicht zu existieren.
Was tun wir? Nun, jetzt ist der perfekte Zeitpunkt, um mit Ihnen über JMP und die neue Python-Integration in JMP 18 zu sprechen. In JMP 18 ist Python bereits vorinstalliert. Wir können Python-Pakete mit minimalem Aufwand nutzen. Anstatt die Klassen und Methodendefinitionen selbst zu erstellen, können wir – wie bereits erwähnt – das Python-Paket mithilfe der hier gezeigten Skriptzeile installieren und mit Python interagieren, um die Daten in JMP zu importieren.
Da dies für ESPN bereits existiert, können wir nun dasselbe für ESPN tun. Da es keine gute Dokumentation dazu gibt, können wir stattdessen auf die bereits vorhandene Python-API zurückgreifen. Welche Vorteile bietet die Python-Integration? Die ganze Arbeit wird uns abgenommen. Wir müssen weder die Logik der API-Aufrufe noch andere Datenmanipulationen für die gewünschten Funktionen programmieren. Wir können einfach auf die Funktionen und die Dokumentation zurückgreifen, die andere in Python geschrieben haben.
Wir rufen einfach die Python-Funktionen auf und senden die Daten zurück an JMP. Hier ist ein einfaches Beispiel dafür. Entschuldigung, falls es etwas schwer zu erkennen ist, aber ich wollte alles auf den Bildschirm bekommen. Diese Folien werden Ihnen später zur Verfügung gestellt, aber Sie können es auch schon an der Größe der Funktionsdefinition erkennen. Eine eigene Funktion zum Abrufen der Scoreboard-Daten zu finden, ist deutlich komplizierter, als die Python-Integration zu nutzen, um die bereits in Python definierte Funktion `get_scoreboard` aufzurufen.
Schauen wir uns nun an, wie die Integration von ESP und Python aussehen könnte. Damit schließen wir diesen Abschnitt ab. Wir werden uns diese Sleeper-Klassen später noch einmal ansehen, diesmal jedoch mit Python-Integration. Anhand unserer Liga-Klasse können Sie sehen, dass wir eine Reihe von Python-Submit- und Python-Get-Anweisungen verwenden, um mit der bereits vorhandenen Python-API zu interagieren.
Um unsere Liga-Informationen zu erhalten, würden wir einfach eine Python-Submit-Anweisung ausführen, um eine Liga-Info-Variable zu definieren. Anschließend würden wir mit dieser Liga-Info-Variable und der Funktion `get_league` die Informationen für diese Variable abrufen und diese Variable dann mit `get` aus Python an JMP zurücksenden.
Alle diese Funktionen arbeiten exakt so wie zuvor mit der JSL-Implementierung der neuen HTTP-Anfrage. Der einzige Unterschied besteht darin, dass die HTTP-Anfrage abstrahiert wurde und nun auf Python-Ebene verarbeitet wird. Dadurch vereinfachen sich die Methodendefinitionen unserer Klasse erheblich. Betrachten wir nun ESPN, die Plattform, mit der die meisten von Ihnen wahrscheinlich am besten vertraut sind. Hier sehen Sie, dass wir für ESPN dieselben oder ähnliche Klassen verwenden.
Die Python-API ist jedoch eher objektorientiert aufgebaut. Die Liga liefert Team- und Spielerobjekte usw. Mit diesen Objekten greifen wir dann über Methoden auf ihre Attribute zu. Ich zeige Ihnen nun anhand dieser Klassendefinition einige Beispiele, wie wir unsere Daten von ESPN abrufen und mit diesen Klassenobjekten interagieren können.
Hier rufe ich meine privaten Liga-Informationen ab. Das entsprechende Objekt wurde bereits definiert. Wir verwenden die Methode `getteams` der Liga, um die Teaminformationen zu erhalten. Nun haben wir ein assoziatives Array definiert. Mit einer `foreach`-Schleife durchlaufen wir dieses Array, um die Namen aller Teams auszugeben. Wie Sie hier sehen, ist dies der Name meines Teams. Um auf mein Team zuzugreifen, verwende ich den Index der `teams`-Variable. Wenn ich nun die Methode `getwins` für dieses Team ausführe, sehe ich, wie viele Siege ich in der siebten Saison erzielt habe – also eher mittelmäßig.
Wenn ich mir nun den Kader dieses Teams ansehen wollte, würde ich die Funktion `get roster` verwenden und anschließend den Kader analysieren, um die Spielernamen zu erhalten. Wie Sie hier sehen, würde ich alle Spieler sehen, die ich für diese Saison in meinem Kader hatte. Wie bereits erwähnt, stehen Ihnen diese Klassen zur Verfügung. Ich habe mir die Mühe gemacht, sie ausführlich zu kommentieren, damit Sie sie nutzen können, um auf Ihre eigenen Teaminformationen zuzugreifen.
Nachdem wir die Daten nun in JMP importiert haben, müssen wir sie für die Analyse in JMP-Datentabellen umwandeln. Wie bereits erwähnt, gibt es dafür verschiedene Möglichkeiten. Wenn Sie Daten von einer API abrufen, werden diese üblicherweise als JSON-String zurückgegeben. JMP bietet eine integrierte Funktion namens „JSON zu Datentabelle“, mit der wir – wie Sie in diesem Beispiel sehen – aus unserem JSON-String eine Datentabelle erstellen können.
Dies ist wahrscheinlich die einfachste Methode. JMP bietet außerdem einen JSON-Importassistenten, mit dem Sie die zu importierenden Spalten und die gewünschten Daten aus Ihrer Tabelle anpassen können. Eine andere Möglichkeit, die sich – wie Sie sich vorstellen können – bei der Arbeit mit unseren ESPN-Daten aufgrund ihrer objektorientierten Struktur als nützlicher erweisen könnte, besteht darin, die Tabelle manuell mit JSL zu definieren und anschließend die Objektmethoden zum Befüllen der Spalten zu verwenden.
Wie Sie hier sehen, durchlaufen wir die Teamobjekte, um die Teams einer Liga aufzulisten. Um die Daten für eine bestimmte Spalte zu definieren, verwenden wir einfach die entsprechende Methode. Für die Spalte „Siege“ würden wir beispielsweise `get wins`, `get losss` usw. verwenden. Bei verschachtelten Objekten können wir diese durchlaufen, um beispielsweise eine Liste von Spieler-IDs für eine Spalte zu erstellen.
Das können Sie für jeden Ausdruck dort sehen. Jetzt zeige ich Ihnen, wie wir diese Datentabellen in JMP erstellen. Ich habe separate Dateien für die Sleeper-Daten und die ESPN-Daten. Für die Sleeper-Daten importieren wir unsere Klassen, da wir diese Methoden zum Abrufen der Daten verwenden. Ich scrolle hier kurz durch, hebe aber die Methode hervor, die ich bereits besprochen habe: JSON zu Datentabelle. Damit definieren wir unsere Spalten und erstellen eine Datentabelle für die Teams einer Liga.
Ich werde diese Dateien wieder mit Ihnen teilen. Falls Sie Daten einer Sleeper League haben, müssen Sie, um alle Daten für jedes Jahr seit Bestehen der Liga zu erhalten, lediglich diese letzte Zeile hier ausführen. Sie nutzt alle zuvor in dieser Datei definierten Funktionen, die Sie sich bei Gelegenheit ansehen können. Für ESPN haben wir ein ähnliches Verfahren. Wie Sie in der Folie gesehen haben, erstellen wir unsere Tabellen hier etwas anders: Wir definieren eine Tabelle mit JSL und verwenden dann Objektmethoden, um diese Tabellen zu füllen.
Um Ihre ESPN-Daten zu erhalten, müssen Sie hoffentlich nur diese letzte Zeile ausführen. Schauen wir uns an, wie diese Daten in JMP aussehen. Nach dem Ausführen der Dateien sollte ein Verzeichnis mit dem Namen Ihrer Liga erstellt werden. Für jedes Ligajahr sollten die folgenden Tabellen vorhanden sein: die Draft-Tabelle, die Mitgliedertabelle, die Teamtabelle sowie die individuellen Kader für jeden Benutzer der Liga.
Wir sehen uns das mal an. Hier ist eine Liste der Teams. Ich versuche mal, die Spalten zu vergrößern. Hoffentlich ist es jetzt gut lesbar. Für jedes Team wird der Benutzername angezeigt. Ich verkleinere die Anzeige etwas, damit man alles besser erkennen kann. Für jedes Team werden die Ligamitglieder und ihre Siege und Niederlagen angezeigt. Sie können auf die Spalte „Spieler“ klicken und die Spieler eines bestimmten Kaders auswählen.
Wir werden eine Datentabelle für den Draft erstellen, in der die gedrafteten Spieler nach Runde und Picknummer aufgelistet sind. Durch Klicken auf einen Benutzer können Sie sehen, welcher Spieler in dessen Draft ausgewählt wurde. Zusätzlich gibt es eine Tabelle für die Ligamitglieder. Sie können sich vorstellen, welche Analysemöglichkeiten diese Tabellen bieten.
Bevor wir zur Analyse kommen, möchte ich Ihnen, wie bereits erwähnt, die Motivation dafür erläutern. 2022 belegte ich den ersten Platz in meiner Liga, 2023 hingegen leider den letzten. Ich suche hier nach Vorhersagbarkeit und ähnlichen Ergebnissen. Wie Sie im Streudiagramm links sehen, hatte ich in meiner Liga einen Top-Tight-End und einen Top-Quarterback, während ich in der Liga, in der ich Letzter wurde, keine dieser beiden Positionen unter den Top Fünf hatte.
Ich hatte allerdings einen besseren Wide Receiver, daher kann ich anhand dieser beiden Diagramme nicht genau sagen, was meinen Erfolg in dem einen Jahr im Vergleich zum anderen ausgemacht hat. Das ist der Ausgangspunkt meiner Analyse. Was werden wir uns heute ansehen? Zunächst einmal: Die Fantasy-Liga beginnt mit dem Draft. Manche Picks im Draft sind besser als andere.
Als Nächstes schauen wir uns die Trends und Veränderungen im Fantasy Football der letzten zehn Jahre an. Welche Draft-Strategien bieten die besten Gewinnchancen? Eine konservative oder riskante Herangehensweise? Ganz unten seht ihr mein Liga-Layout, das ziemlich typisch ist: ein Quarterback, zwei Right Receiver, zwei Running Backs, zwei Flex-Positionen, ein Kicker und eine Defense mit Half-PPR-Wertung. Ich denke, das sind gängige Liga-Einstellungen.
Hoffentlich können die Erkenntnisse aus unserer Analyse auch für Ihre Liga hilfreich sein. Beeinflusst die Pickposition den Erfolg? Wir werden mit den Datentabellen arbeiten, die ich Ihnen vorhin gezeigt habe, um einige Analysen durchzuführen. Dazu verwenden wir einen Workflow-Builder, der die einzelnen Schritte zur Organisation der Tabellen und zur Durchführung der Analyse übersichtlich darstellt.
Hier können Sie sich den Workflow ansehen. Zunächst definieren wir den Liganamen, der dem Workflow mitteilt, woher die Daten stammen. Ich zeige Ihnen das Schritt für Schritt. Für jedes Ligajahr führen wir die folgenden Schritte durch: Wir öffnen eine Draft-Tabelle und anschließend eine Team-Tabelle.
Für unsere Draft-Tabelle filtern wir die Daten nach der Anzahl der Liga-Teilnehmer, um die Draft-Position jedes einzelnen Teilnehmers zu ermitteln. Das sieht dann ungefähr so aus. Anschließend fügen wir diese Datentabelle wieder in unsere Teamtabelle ein, um eine Tabelle wie diese zu erhalten. Diese enthält nun die Anzahl der Siege des jeweiligen Spielers bzw. Liga-Mitglieds sowie dessen Draft-Position. Diesen Vorgang wiederholen wir für jedes Liga-Jahr und fügen die Tabellen anschließend zusammen, um unsere Analyse durchzuführen.
Ich werde die restlichen Schritte hier durchgehen. Einige dieser Tabellen werden auf einem separaten Bildschirm angezeigt, aber ich zeige Ihnen hier nur die endgültige Ausgabetabelle sowie die Analyse. Wie Sie in diesem Diagramm sehen können, haben wir unsere Pick-Nummer auf der X-Achse und auf der Y-Achse sowohl die Anzahl der Siege des Teams als auch seine endgültige Platzierung.
Wenn ich mir diese Grafik ansehe, erkenne ich keinen großen Unterschied oder Zusammenhang zwischen der Draftposition und dem Endergebnis. Ich betrachte hier die Siege. Man sieht, dass die durchschnittliche Anzahl an Siegen in meiner Ligahistorie etwas höher ist, wenn man früh im Draft wählt, und dass es dann im mittleren Teil des Drafts einen leichten Abfall gibt. Meine Interpretation daraus ist, dass man unabhängig von der Draftposition eine Chance hat, seine Liga zu gewinnen.
Schauen wir uns nun an, wie sich die Draft-Strategie in den neun Jahren meiner Liga verändert hat. Um Zeit zu sparen, zeige ich euch die einzelnen Schritte. Wir öffnen im Prinzip alle unsere Draft-Tabellen, führen sie zusammen und erstellen dann Teilmengen. Um Zeit zu sparen, gehe ich den Workflow aber direkt durch und zeige euch das Ergebnis.
Wir haben hier zwei Diagramme. Wir sehen uns das genauer an. Ich erkläre Ihnen das Hauptdiagramm, und Sie können sich das andere daneben ansehen, wenn Sie interessiert sind. Es handelt sich hierbei um eine Übersicht der Buy-Around-Daten. Im Wesentlichen sehen wir hier das Jahr auf der X-Achse und die Anzahl der Spieler, die in den ersten vier Runden an einer bestimmten Position gedraftet wurden, auf der Y-Achse.
Anhand dieser Grafik lässt sich erkennen, wie viele Quarterbacks, Running Backs, Tight Ends und Wide Receiver in den ersten vier Runden des Drafts ausgewählt wurden. Die Daten beziehen sich auf die gesamte Liga. Von 2015 bis 2020 stieg die Anzahl der gedrafteten Running Backs, ging aber in den letzten drei Jahren deutlich zurück. Die Anzahl der gedrafteten Receiver verlief ähnlich wie bei den Running Backs, stagnierte und lag danach etwas über der der Running Backs. Die Beliebtheit der Quarterbacks im frühen Draft-Bereich sank, stieg aber zuletzt leicht an.
Die Leistung der Tight Ends hat sich in den letzten Jahren mit einem leichten Anstieg relativ konstant gehalten. Wie Sie in dieser Grafik sehen können, haben wir eine detaillierte Aufschlüsselung nach Spielrunden. Ich teile diese gerne mit der Community, falls Sie sie genauer betrachten möchten.
Wir haben uns angesehen, wie sich die Draft-Strategie über die Jahre verändert hat. Nun möchte ich untersuchen, ob eine veränderte Draft-Strategie überhaupt funktioniert. Für diese Analyse betrachten wir die Anzahl der Spieler, die in den ersten sechs Runden auf jeder Position ausgewählt wurden, und zwar nur für die letzten drei Jahre. Die einzelnen Schritte dieser Analyse sind hier dargestellt. Ich beginne mit der Einrichtung. Für jedes Jahr öffnen wir die Draft-Tabelle und anschließend die Teamtabelle. Wir filtern die Draft-Tabelle nach den ersten sechs Runden. Dann erstellen wir eine Übersichtstabelle, die die Anzahl der ausgewählten Spieler pro Position und Benutzer anzeigt. Diesen Vorgang wiederholen wir für jedes Jahr und führen die Ergebnisse anschließend zusammen, um unsere Analyse durchzuführen.
Betrachten wir zunächst dieses Diagramm des Graph Builders. Wir sehen, dass die Anzahl der in den ersten sechs Runden gedrafteten Running Backs tendenziell leicht negativ mit der Anzahl der Siege korreliert. Dies bestätigt den Trend unserer letzten Analyse, wonach die Anzahl der gedrafteten Running Backs rückläufig ist. Bei den Wide Receivern ist ein Höchstwert zu erkennen: Zwei wurden in den ersten sechs Runden gedraftet, gefolgt von einem leichten Rückgang auf drei.
Den steilsten Anstieg sehen wir hier beim Tight End, worauf wir gleich zurückkommen. Dies zeigt, dass die Wahl eines Tight Ends in den ersten sechs Runden tendenziell eine recht positive Korrelation mit der Anzahl der zu erwartenden Siege in der Saison aufweist. Ähnliches gilt für den Quarterback, allerdings mit einem etwas flacheren Anstieg. Betrachten wir dies nun statistischer mithilfe eines Anpassungsmodells. Hier sehen wir diesen sehr steilen Anstieg für den Tight End. Schauen wir uns dazu unsere Parameterschätzungen unten links an.
Man kann statistisch signifikant sehen, dass es eine ziemlich starke positive Korrelation zwischen der Wahl eines Tight Ends in den ersten sechs Runden und der zu erwartenden Anzahl an Siegen in einer Saison gibt. Ich würde sagen, das ist wahrscheinlich die wichtigste Erkenntnis dieser Analyse: Obwohl man weniger Running Backs wählen sollte, ist die Wahl eines Tight Ends in den ersten sechs Runden, wie diese negative Korrelation zeigt, ein ziemlich starker Indikator für die Anzahl der Siege in einer Saison.
Nun möchte ich untersuchen, ob die Leistungen der Top-Spieler von Jahr zu Jahr vorhersehbar sind. Genauer gesagt, möchte ich herausfinden, wie viel Prozent der zwölf besten Fantasy-Punkte-Scorer pro Position jedes Jahr gleich bleiben und ob sich daraus Rückschlüsse auf die Spieler ziehen lassen, auf die man sich beim Draft konzentrieren sollte.
Um hier etwas Zeit zu sparen, gehe ich den Workflow kurz durch. Die einzelnen Schritte werden Ihnen währenddessen am Rand angezeigt. Der Vorgang dauert nur einen kurzen Moment. Ich werde nun auf die Vorteile von Workflows für Ihre Analyse eingehen. Sie ermöglichen es Ihnen, die verschiedenen Analyseschritte iterativ durchzuführen und Problembereiche zu identifizieren.
Wenn Ihre Kollegen ebenfalls einfachen Zugriff auf die von Ihnen verwendeten Daten haben, können sie Ihre Analyse und die dazugehörigen Schritte problemlos nachvollziehen. Ich zeige Ihnen hier die Diagramme und die Daten, die diese Analyse ergeben hat. Die Daten finden Sie hier an der Seite. Sie zeigen Ihnen im Wesentlichen, welcher Prozentsatz der Top 12 pro Position im Jahresvergleich gleich geblieben ist.
Betrachtet man diese Grafik, fällt auf, dass die Anzahl der Running Backs (blaue Linie) in den letzten Jahren tendenziell abgenommen hat. Das bedeutet, dass die Leistungen von Running Backs im Vergleich zum Vorjahr etwas unberechenbarer geworden sind. Im Gegensatz dazu sind die Leistungen von Wide Receivern und Tight Ends etwas besser vorhersehbar. Eine Erkenntnis daraus ist beispielsweise, dass die zwölf besten Running Backs des Jahres 2023 in den letzten zwei Jahren nur 33 % der Laufversuche absolvierten. Diese Positionen sind möglicherweise etwas schwieriger vorherzusagen als beispielsweise Wide Receiver und Tight Ends.
Unsere letzte Analyse hier. Wir schauen uns an, wen wir als Nächstes im Draft auswählen sollten. Wir betrachten alle Trends und Muster. Welche Draft-Strategien sollten wir verfolgen? In dieser Analyse untersuchen wir den Draft-Wert und wie Spieler, die im Verhältnis zu ihrer Draft-Position überdurchschnittlich performen, den Erfolg unseres Teams beeinflussen. Ich möchte diese Analyse noch einmal genauer beleuchten, da ich sie für ziemlich interessant halte.
Nach der Einrichtung wiederholen wir den Vorgang für jedes Jahr. Zuerst öffnen wir die Draft-Tabelle und anschließend die Teamtabelle. Die nächsten beiden Schritte können Sie ignorieren, sie dienen lediglich der Organisation. Nun führen wir eine bivariate Analyse unserer Draft-Tabelle durch, um den Zusammenhang zwischen der Pick-Nummer eines Spielers und seiner Gesamtpunktzahl zu untersuchen.
Betrachtet man dies anhand einer Variablenanalyse, so ergibt sich eine Aufschlüsselung nach Positionen. Auf der X-Achse wird die Pick-Nummer und die Gesamtpunktzahl des jeweiligen Spielers dargestellt. Besonders interessant sind die Punkte in diesem Diagramm, die über bzw. unter dem erwarteten Wert liegen, also dem Wert, der laut Regression für die jeweilige Position erwartet wird.
Ich möchte sehen, wie sich diese Leistungen ober- und unterhalb der vorhergesagten linearen Regression auf unsere Gewinnchancen auswirken. Genau das wird der Rest dieser Analyse untersuchen. Wir werden diese Regressionswerte und Residuen aus diesen Diagrammen in unsere Draft-Tabelle übertragen, wie Sie hier sehen können. Anschließend werden wir die Runden in früh, mittel und spät gruppieren. Nehmen Sie hier eine kurze Umkodierung für unsere Rundenspalte vor.
Wir haben nun eine Aufschlüsselung nach frühen, mittleren und späten Runden. Wir können sehen, wie sich die Leistung von Spielern in den jeweiligen Rundenkategorien auf den Sieg auswirkt. Ich werde die restliche Analyse nun erläutern. Einen Moment bitte, die Daten werden geladen. Entschuldigung für die Verzögerung. Wir sind fast fertig. Sie sehen nun eine Datentabelle, die alle Daten des Jahres enthält. Wir haben jetzt die Anzahl der extremen Über- und Unterperformer pro Kategorie für jeden Nutzer im Laufe eines bestimmten Jahres. Diese Daten liegen uns für alle Jahre vor. Ziel dieser Analyse ist es, zu sehen, wie sich extreme Über- und Unterperformer in den jeweiligen Runden, in denen sie gedraftet wurden, auf unsere Gewinnchancen auswirken.
Wir können uns hier das angepasste Modell ansehen. Ich denke, das ist die interessanteste Analyse des Tages. Schauen wir uns nun einige der Hebeldiagramme an und achten wir besonders auf die extremen Überperformer in den mittleren Runden und die extremen Unterperformer in den frühen Runden. Anhand unserer Parameterschätzungen sehen wir, dass ein Überperformer in den mittleren Runden statistisch signifikant mit der Anzahl der Siege in der Saison korreliert. Je mehr Überperformer es in den mittleren Runden gibt, desto höher ist die Wahrscheinlichkeit für mehr Fantasy-Siege.
Im Gegensatz dazu korreliert ein Spieler, der in den frühen Runden extrem unter den Erwartungen liegt, sehr negativ mit der Anzahl der zu erwartenden Siege in der Saison. Daraus lässt sich schließen, dass man in den mittleren Runden riskantere Entscheidungen treffen sollte. Ich werde versuchen, Spieler zu draften, die das Potenzial für große Erfolge haben, und mir keine Sorgen machen, wenn ich sie verfehle. Wie man sieht, scheint es nicht so schlimm zu sein, einen Spieler zu draften, der in den mittleren Runden extrem unter den Erwartungen liegt.
Du solltest ruhig nach den Top-Spielern greifen und versuchen, die Spieler zu bekommen, die dir das größte Ligapotenzial und die besten Gewinnchancen bieten, zumal du nicht allzu sehr bestraft wirst, wenn du sie verpasst. Im Gegensatz dazu kann es deinem Erfolg im Fantasy Football sehr schaden, wenn du früh im Draft einen Spieler verpasst und dich für einen verletzungsanfälligen Spieler entscheidest.
Vielen Dank, dass Sie die Analysen mitverfolgt haben. Hier sind einige wichtige Erkenntnisse: Die vergangene Saison wiederholt sich nie. Wie wir in einer unserer Analysen gesehen haben, sind die Top-Fantasy-Spieler einer Saison, insbesondere Running Backs, von Saison zu Saison deutlich weniger vorhersehbar.
In gängigen Formaten verlieren Running Backs an Wert und, wie bereits erwähnt, an Berechenbarkeit, während Wide Receiver etwas wertvoller und deutlich berechenbarer als Running Backs werden. Wir dürfen die Positionen des Quarterbacks und insbesondere des Tight Ends nicht länger vernachlässigen, denn wie wir gesehen haben, führt die frühe Auswahl eines Tight Ends im Draft oft zum Erfolg der Liga. Frühe Draft-Picks entscheiden zwar nicht über den Liga-Sieg, können aber über den Liga-Verlust entscheiden, und in den mittleren Runden ist in Ligen alles möglich.
Setzen Sie auf Spieler mit hohem Potenzial, aus den bereits genannten Gründen. Jetzt sind Sie an der Reihe. Ich habe Ihnen die Klassen und die API zur Verfügung gestellt, mit der ich Daten von Sleeper und ESPN in JMP importiere. Sie können diese APIs nutzen, um Ihre Analysen in der JMP-Community zu teilen. Falls Ihre Fantasy-Liga nicht bei Sleeper oder ESPN gelistet ist, können Sie die Anleitung zur Python-Integration verwenden, um beliebige Python-Repositories zu nutzen und die Daten in JMP zu importieren und Ihre Analysen durchzuführen.
Ich möchte euch allen ganz herzlich für eure Zeit heute danken. Ich bin sehr gespannt auf eure Analysen und hoffe, ihr könnt mir helfen, meine nächste Fantasy-Football-Liga zu gewinnen. Vielen Dank!