William Baum ( wjbaum ), Statistikstudent im Aufbaustudium, University of New Hampshire
Mein Projekt nutzt die Skriptsprache JMP, um Daten von mehreren Websites abzurufen und so Siege im Profifußball vorherzusagen. Das Skript automatisiert einen ansonsten aufwändigen Prozess der Datenerfassung, -aggregation und -reorganisation für die Analyse. Mehrere Abschnitte des Skripts enthalten verschiedene Funktionen, wie z. B. die Zellenverarbeitung zur Entfernung von Indizes sowie die Verkettung und Verknüpfung mehrerer Datensätze. Ein assoziatives Array wird verwendet, um die Ausgabe von Spaltenformeln in separaten Zeilen zu vergleichen. Abschließend werden die Ergebnisse mehrerer Vorhersagemodelle verglichen. Ziel dieses Projekts ist es, die Verwendung von JSL zur Automatisierung der Prozesse der Datenerfassung, -organisation und -vorhersage auf wiederholbare Weise zu veranschaulichen.
Einführung
Vor etwa zwei Jahren erfuhr ich, dass JMP mithilfe der JMP Scripting Language [JSL] Daten aus dem Internet extrahieren kann. Als Statistikstudent suche ich häufig nach Übungsdaten, um meine analytischen Fähigkeiten zu verfeinern und meine Programmierkenntnisse zu verbessern. Zufällig bin ich ein begeisterter American-Football-Fan, und Sportstatistiken sind online aus vielen verschiedenen Quellen leicht verfügbar. Als Übung versuchte ich, die Gesamtzahl der Siege pro Saison für jedes professionelle Footballteam anhand von Daten aus dem Internet vorherzusagen.
Daten-Scraping- und -Bereinigungstechniken lassen sich auf alle Daten anwenden, die in Form von HTML-Tabellen im Web verfügbar sind. Ich finde es erstaunlich, dass sich mit JSL die Datenbereinigung automatisieren und die Modellierung innerhalb eines einzigen Skripts oder einer Gruppe von Skripten durchführen lässt. Darüber hinaus unterstützt JMP auch Anwender mit wenig Programmiererfahrung, indem es ihnen ermöglicht, Analysen über die grafische Benutzeroberfläche (GUI) durchzuführen und den Vorgang anschließend als wiederverwendbares Skript zu speichern. Dies spart Anwendern viel Zeit bei wiederholten Analysen mit aktualisierten oder neuen Daten.
Aufstellen
Der erste Schritt bestand darin, Ordner für die während der Datenaggregation entstehenden Dateien zu erstellen. Ich habe festgestellt, dass es sich gut eignet, für jede Datenquelle einen eigenen Ordner zu erstellen, um die vielen erzeugten Dateien zu organisieren.

Als Nächstes habe ich den Skriptbenutzer gebeten, einen lokalen Pfad für die Dateispeicherung zuzuweisen, um einen übersichtlicheren Code zu erhalten: dir = Pick Directory(„Verzeichnis für die Dateispeicherung auswählen“, show files(0));
Dieser lokale Pfad kann auch fest codiert sein.
Sobald ein Pfad ausgewählt war, wurden die Daten von mehreren Websites extrahiert und in einzelnen Dateien gespeichert (eine für jede HTML-Tabelle). Auf diese Dateien wurde später in der Datenaggregationsphase verwiesen.
Scraping-Daten
Mit JMP müssen URLs einfach aus der Adressleiste des Browsers kopiert und in den JSL-Code eingefügt werden. Alternativ kann ein Link zur Website direkt in ein Skript eingefügt werden, um die Website während der Bearbeitung des JSL-Codes zu öffnen: Web("http://url_name.com");
Daten importieren
JMP bietet eine Reihe nützlicher Tools für den Datenimport. Zunächst kann man versuchen, eine HTML-Tabelle direkt als JMP-Datei zu speichern. Diese Methode eignet sich am besten, wenn die Daten nur geringfügig reorganisiert werden müssen. Alternativ kann die HTML-Tabelle zunächst als CSV-Datei (Comma Separated Value) gespeichert und anschließend mit den über JSL verfügbaren benutzerdefinierten Einstellungen in JMP importiert werden. Beim Betrachten der importierten Tabelle fielen mir mehrere leere Spalten auf. Mit dem Befehl „Spalten löschen“ konnte ich diese mithilfe eines kurzen Skripts aus meiner Tabelle löschen.

JMP ruft die Informationen automatisch aus dem Internet ab und speichert sie in Dateien. Diese Dateien müssen nicht unbedingt gespeichert werden, aber die aus dem Internet abgerufenen Daten können manchmal etwas unübersichtlich sein. Das Speichern der Daten in einer Datei erleichtert das Debuggen, da man die importierten Tabellen einsehen und den Code bei Bedarf anpassen kann.
Methode 1
Daten werden importiert und zunächst als CSV-Datei gespeichert:
Objektname = Öffnen(„http//:url_name1.com“, HTML-Tabelle(#))<< Name festlegen(„Tabellenname1“) << Speichern(dir||„Dateiname1.csv“);
Methode 2
Daten werden direkt in JMP importiert und gespeichert:
Objektname = Öffnen(“http://url_name2.com“, HTML-Tabelle(#)<< Name festlegen(„Tabellenname2“) << Speichern(dir||„Dateiname2.jmp“);

Zellverarbeitung
Beim Sortieren von Zeichendaten in einem Skript können selbst geringfügige Abweichungen in importierten Zeichenfolgen den Code beeinträchtigen. In diesem Fall standen die Playoffs kurz bevor, und um den Titelgewinn von New England zu signalisieren, wurde ein „z“ in den Namen eingefügt. Glücklicherweise bietet JMP eine Vielzahl von Befehlen zur Bearbeitung von Zeichenfolgen in Zellen.

Im folgenden Skript durchläuft JMP jede Zeile der Spalte „Team“ und löscht die angegebenen Buchstaben, falls diese am Anfang der Zeichenfolge stehen. Der Befehl „For Each Row“ vereinfacht die Schleife, indem er auf jede Zeile einen Prozess anwendet. Die Bedingung „Wenn, Dann“ gibt JMP an, was zu tun ist, wenn die jeweiligen Bedingungen zutreffen. Der Befehl „Enthält“ gibt die Position eines angegebenen Elements innerhalb der Zeichenfolge zurück. Der Befehl „Substr“ (Teilzeichenfolge) gibt einen Teil der Zeichenfolge zurück: Ab einer bestimmten Position gibt er die angegebene Anzahl von Zeichen zurück.

Kombinieren von Tabellen
Das Kombinieren von Tabellen in JMP ist über das Menü „Tabellen“ ganz einfach. Das Menü „Tabellen“ bietet mehrere Optionen. Normalerweise verwende ich „Verbinden“, um Tabellen mit unterschiedlichen Spalten, aber gleichen Zeilenbeschriftungen zu kombinieren. „Verketten“ verwende ich, wenn ich Tabellen mit unterschiedlichen Zeilenbeschriftungen, aber gleichen Spalten kombiniere. In diesem Fall habe ich Informationen aus mehreren Tabellen verknüpft. Für jede Teamabteilung wurde eine Tabelle erstellt. Anschließend habe ich die Zeilen der resultierenden Datei alphabetisch nach Teamnamen sortiert, um sicherzustellen, dass ähnliche Zeilen beim späteren Zusammenführen übereinstimmen.

Erstellen einer neuen Tabelle
Ich finde es hilfreich, vor dem Verknüpfen von Tabellen eine neue Tabelle zu erstellen. JMP bietet verschiedene Möglichkeiten, neue Tabellen zu erstellen. Dies kann über die GUI erfolgen. Alternativ ist auch ein Skript möglich. In diesem Fall habe ich den Befehl „Neue Tabelle“ verwendet, um eine neue Tabelle mit der entsprechenden Zeilenanzahl zu erstellen: eine für jede Fußballmannschaft. Anschließend habe ich die Spalte mit den Mannschaftsnamen mit dem Befehl „Neue Spalte“ hinzugefügt und die Werte in einer Liste festgelegt.

Tabellen verbinden
Ohne JMP ist das Verknüpfen von Tabellen eine lästige Aufgabe. Zum Glück bietet JMP im Menü „Tabellen“ eine benutzerfreundliche Benutzeroberfläche zum Verknüpfen von Tabellen. Obwohl Namenskonventionen immer wichtig sind, benennt JMP Spalten aus verschiedenen Tabellen mit gleichem Namen automatisch um. In diesem Fall habe ich die Tabellen über die Benutzeroberfläche verknüpft und anschließend das Tabellenskript der resultierenden Tabelle einfach in mein größeres, benutzerdefiniertes Skript kopiert und eingefügt. Andernfalls hätte ich vor dem Verknüpfen der Tabellen viel Tipparbeit (Spalten umbenennen) leisten müssen. Ich habe den Verknüpfungsvorgang mehrmals wiederholt.

Umbenennen und Neuformatieren von Spalten
Nach Abschluss der Verknüpfungen fielen mir viele seltsam klingende Spaltennamen auf. Um Verwirrung zu vermeiden, habe ich diese Spalten umbenannt. Dazu habe ich zunächst eine Liste mit bevorzugten Namen erstellt. Anschließend habe ich die Spalten mithilfe einer Schleife und der Funktion „Name festlegen“ umbenannt.

Manchmal importiert JMP Daten als Zeichenfolge, der Benutzer benötigt jedoch ein anderes Spaltenformat, beispielsweise die Zeitangabe. Dies lässt sich einfach in der JMP-Benutzeroberfläche ändern, kann aber auch in einem JSL-Skript umgesetzt werden. In diesem Fall teilte ich JMP mit, dass die Spalte kontinuierliche Zeitinformationen statt Zeicheninformationen enthielt.
Spalten neu anordnen
Sobald die Daten aggregiert und neue Spalten erstellt wurden, kann die Reihenfolge der Spalten in der Datentabelle geändert werden. Dies ist in JSL mit dem Befehl „Ausgewählte Spalten verschieben“ ganz einfach möglich.

Datentabellenansicht
Hier ist eine Teilansicht der vollständigen Datentabelle.

Assoziatives Array entwickeln
Nachdem ich die Daten aggregiert hatte, ging es an die Analyse. Zunächst wollte ich die relative Stärke verschiedener Teams vergleichen, basierend auf ihrem Spielplan bis zu diesem Zeitpunkt der Saison. Mein Ziel war es, die zukünftige Leistung eines Teams vorherzusagen, nicht nur basierend auf seiner eigenen Leistung in der Vergangenheit, sondern auch im Vergleich zur Leistung seiner zukünftigen Gegner. Dazu musste ich Informationen aus Zellen in verschiedenen Zeilen und Spalten meiner Tabelle vergleichen. Die Erstellung eines assoziativen Arrays (auch bekannt als Dictionary oder Hash Map) war hierfür sehr hilfreich.
In JMP können Listen, Matrizen oder Spalten in einem assoziativen Array verwendet werden. In diesem Fall habe ich zwei Spalten mit einem Standardwert (null) verwendet. Die Schlüsselspalte „TEAM“ enthielt die abgekürzten Städtenamen der einzelnen Teams. Die Wertespalte „Stärke“ war eine Formelspalte, die einen Index berechnete, der Siege und Nettopunkte kombinierte. Ich habe jede Woche (eine Spalte) des 17-wöchigen Spielplans als Schlüssel verwendet, um die Werte des assoziativen Arrays für diese Woche zu referenzieren.
17-Wochen-Plan: Schlüssel

Im Skript habe ich das assoziative Array definiert und anschließend eine Formelspalte erstellt, um darauf zu verweisen. Auch hier referenziert die Formel den korrekten Wert über einen Index des assoziativen Arrays, wobei der wöchentliche Gegner als Schlüssel verwendet wird. Wenn der Wert in der Schlüsselspalte nicht im assoziativen Array enthalten ist, gibt die Funktion einen Nullwert zurück (funktioniert gut mit spielfreien Wochen im Zeitplan).

Anschließend habe ich für jede Woche eine neue Spalte erstellt, um die Teamstärke zu vergleichen. Diese beiden Formeln hätten verknüpft werden können, ich habe sie jedoch getrennt gehalten, um die verschiedenen Kennzahlen in der Datentabelle visualisieren zu können.

Als Nächstes zählte ich die Anzahl der prognostizierten Siege für die Saison. Eine einfache Möglichkeit, die Spaltenergebnisse zu zählen, bestand darin, eine neue Formelspalte zu erstellen, die die Summe einer Reihe von „Wenn-Dann“-Bedingungen für jede der 17 Spalten enthielt. In diesem Fall wurde die Vorhersage als Sieg gewertet, wenn die Stärkedifferenz positiv war.

Erstellen Sie Vorhersagemodelle
JMP bietet verschiedene Modellierungstechniken zur Vorhersage. Viele Techniken sind über das Menü „Analysieren“ zugänglich, darunter die Plattformen „Modell anpassen“ und „Neural“. Beim Erstellen eines benutzerdefinierten Skripts empfehle ich, zunächst optimale Modelle in den JMP-Plattformen zu entwickeln. Anschließend kann das Modellskript in der Datentabelle (über die GUI) gespeichert und der Code in das benutzerdefinierte Skript kopiert und eingefügt werden. Modellskripte können auch mit JSL in einer Datentabelle gespeichert werden. Dies bietet Benutzern die Flexibilität, das Modell automatisch auszuführen oder es in der Liste der Datentabellenskripte der vom benutzerdefinierten Skript erstellten Tabelle verfügbar zu machen.
Hier ist ein Beispiel.

Erweiterte Modellierungstechniken in JMP Pro
JMP Pro bietet mehrere erweiterte Modellierungstechniken, die in der Standardversion von JMP nicht enthalten sind. Zwei Beispiele sind die erweiterte Version des neuronalen Netzes und die generalisierte Elastic-Net-Regressionstechnik. Ein weiterer Vorteil von JMP ist die Möglichkeit, eine Holdback-Validierung mit einem benutzerdefinierten Anteil durchzuführen und dabei automatisch eine Zufallsstichprobe aus einem Datensatz auszuwählen. Dies erleichtert sowohl die Validierung als auch den Modellvergleich.
Verstärktes neuronales Netz

Elastisches Netz

Manchmal kann der Durchschnitt mehrerer Modellvorhersagen die Leistung einzelner Modelle übertreffen.
Hier habe ich eine Formelspalte in JSL erstellt, die den Durchschnitt zweier Vorhersageformeln berechnet.

JMP Pro verfügt über eine Modellvergleichsplattform, mit der Benutzer die relative Effektivität mehrerer Modelle nebeneinander vergleichen können. Die Plattform ermöglicht es Benutzern außerdem, mehrere Modelle mit nur wenigen Klicks zu mitteln.
Modellvergleiche

In diesem Fall schnitt der Durchschnitt der Neural Net- und Elastic Net-Modelle (mit Holdback-Validierung [HB]) etwas besser ab als jedes der beiden Einzelmodelle allein. Ein weiteres nützliches Feature der Modellvergleichsplattform sind die Diagramme „Ist-zu-Vorhergesagt“ und „Residuen-zu-Zeilen“.
Modellvergleichsdiagramme

Abschluss
Mit der JMP Scripting Language [JSL] kann JMP Daten aus verschiedenen Webquellen extrahieren, verarbeiten, mehrere Vorhersagen durchführen, vergleichen und anzeigen – alles in einem einzigen Skript. Der effektive Einsatz von JSL kann viel Zeit sparen, insbesondere bei regelmäßigen Analysen.