Bei unserem Bestreben, die umfassenden Möglichkeiten von Python in JMP zu nutzen, standen wir vor der Herausforderung, die Flexibilität von Python mit der intuitiven und interaktiven Benutzeroberfläche von JMP zu vereinen. Vor JMP 18 erreichten wir dies durch einen Workaround: Wir führten Python auf einem Server aus, um die umständliche Python-Integration von JMP zu umgehen. Mit der Veröffentlichung von JMP 18 wurde die Python-Integration jedoch wieder eingeführt und dieser Prozess vereinfacht.
Aufbauend auf unserem ursprünglichen Konzept, JMP-Nutzern die Verwendung von Python ohne Programmierkenntnisse zu ermöglichen, haben wir JMPyFacade (JMPy) entwickelt. Dieses Tool bietet eine vertraute Oberfläche, da sie der von JMP ähnelt, zur Ausführung vordefinierter Python-Dienste über eine dynamisch generierte Benutzeroberfläche, während der zugrunde liegende Python- und JSL-Code abstrahiert wird.
In dieser Präsentation stellen wir die technische Architektur von JMPyFacade vor und zeigen, wie sie die Lücke zwischen JMP und Python effektiv schließt. Die Teilnehmer erfahren, wie Python innerhalb von JMP für effiziente und ansprechende Datenanalysen genutzt werden kann.
Hallo und herzlich willkommen zu meiner Posterpräsentation zum Thema „JMP und Python für nahtlose und ansprechende Analysen“. Mein Name ist Jarmo Hirvonen und ich arbeite bei Murata in Finnland. In diesem Poster erkläre ich, warum Sie Python in JMP nutzen sollten, bzw. warum die Python-Integration in JMP sinnvoll ist. Ich zeige Ihnen einige wichtige Punkte zur Integration und stelle Ihnen eine Anwendung vor, die mein Kollege Eero und ich hier bei Murata in Finnland entwickelt haben und die diese Integration nutzt. Beginnen wir mit der Frage: Warum sollte man diese Funktion in JMP überhaupt nutzen?
JMP ist ein sehr visuelles und interaktives Tool mit guten Analysefunktionen. Python hingegen ist die Standardprogrammiersprache für viele datenbezogene Aufgaben. Es gibt zahlreiche etablierte Bibliotheken, und möglicherweise verfügt Ihr Unternehmen sogar über eigene Python-Kenntnisse.
Ich sehe das aus zwei Perspektiven. Wir haben erste Nutzer, die Zugriff auf Funktionen erhalten, die in JMP nicht nativ verfügbar sind, wie beispielsweise einige Modelle für maschinelles Lernen, Torch, um nur ein Beispiel zu nennen, und außerdem Zugriff auf Dateitypen, die man sonst in JMP nicht verwenden könnte.
Ein Beispiel hierfür sind Parquet-Dateien. Diese lassen sich in Python öffnen und anschließend über die Integration in JMP importieren. Python-Nutzer erhalten dadurch Zugriff auf die visuellen und interaktiven Werkzeuge von JMP, die sie entweder direkt in JMP oder integriert in Python verwenden können. Natürlich bietet JMP auch Analysefunktionen, die exklusiv dort verfügbar sind. Wichtig zu wissen ist außerdem, dass Python in JMP 18 standardmäßig installiert ist.
Das Laden der JMP-Instanz beim ersten Mal ist etwas langsam. Das heißt, es dauert eine Weile, bis die Seite in der JMP-Instanz geladen ist. Beim nächsten Laden geht es jedoch schneller, sofern JMP nicht vollständig geschlossen wird. Dies sollten Sie berücksichtigen, wenn Sie nur sehr kleine Projekte bearbeiten. Es könnte sich lohnen, die Implementierung ausschließlich in JSL vorzunehmen, da dies schneller ist.
Paketverwaltung und -installation können gelegentlich Probleme verursachen. Es gibt zwar Dokumentation dazu, aber die Behebung kann mitunter etwas umständlich sein. Da nur eine Umgebung zur Verfügung steht, ist die Arbeit mit virtuellen Umgebungen in der Jobintegration derzeit nicht möglich. Grundkenntnisse der Datentypkonvertierungen zwischen JSL und Python sind erforderlich; dazu gibt es jedoch eine Dokumentation auf einer Webseite. Die Gültigkeitsbereiche können verwirrend sein. Python arbeitet im Prinzip global, und je nach Benennung der Variablen kann es zu Konflikten zwischen verschiedenen Skripten kommen.
Und schließlich ist meiner Meinung nach einer der größten Punkte, dass das Debuggen und Entwickeln mit Python etwas mühsam sein kann und es schwierig ist, in einen flüssigen Arbeitsfluss zu kommen. Das liegt vor allem daran, dass man Python in JMP nicht zurücksetzen oder den Kernel neu starten kann, wodurch man in einer Art Entwicklungszyklus gefangen ist. Man entwickelt in Python, möchte es dann testen und vermutet beispielsweise, dass man einige Variablen bereinigen möchte.
Die einzige Möglichkeit besteht derzeit darin, die JMP-Instanz zu schließen, die JMPs erneut auszuführen, alles neu zu laden und erst dann den Code zu testen. Das ist kein Zyklus, sondern der Code bricht genau hier ab, und man muss alles von vorne beginnen. Das unterbricht den Arbeitsablauf und führt zu Frustration. Je nachdem, wie man seinen Python-Code schreibt, lässt sich das Problem etwas abmildern.
Kommen wir nun zu unserer Anwendung: Was ist JMPyFacade? Der Name leitet sich davon ab, dass sie den komplexen JMP- und Python-Code hinter einer vertrauten, JMP-ähnlichen Benutzeroberfläche verbirgt. Sie bietet eine Versionskontrolle, die JMP-Nutzern Zugriff auf vordefinierte Python-Funktionen ermöglicht. Diese Funktionen bezeichnen wir als Dienste. Sie reichen von der einfachen Erstellung von Datensätzen bis hin zu komplexen Lernmodellen.
Unser Ziel ist es, unseren JMP-Nutzern Zugriff auf Python-Funktionen zu ermöglichen, ohne dass sie überhaupt merken, dass sie Python verwenden. Wir hatten bereits eine ähnliche Lösung, nutzten damals aber einen Server, um die Python-Integration von JMP zu umgehen, da diese zuvor etwas umständlich war. Mit JMP 18 können wir nun die native Integration nutzen, und sie funktioniert einwandfrei.
Der Ablauf der Anwendung sieht folgendermaßen aus: Beim Start der Anwendung lädt der Benutzer das Add-in. Anschließend wird geprüft, ob es aktualisiert ist. Falls nicht, wird es aktualisiert und der Benutzer führt das Add-in erneut aus. Sind keine Aktualisierungen verfügbar, wird LS Python in JMP initialisiert. Dieser Schritt dient im Wesentlichen dazu, die Aktualisierung der Bestellungen zu erstellen. Falls der Benutzer dies nicht getan hat, könnte eine solche Anwendung Probleme verursachen, wenn die Aktualisierungen noch nicht vorhanden sind.
Nach der Initialisierung prüfen wir anhand unserer Paketverwaltung, ob Pakete aktualisiert werden müssen. Falls ja, aktualisieren wir diese. Andernfalls fahren wir fort. Wir prüfen, ob der Benutzer eine Tabelle geöffnet hat. Ist dies nicht der Fall, schließen wir das Add-In und informieren den Benutzer, dass er vor der Ausführung eine Tabelle öffnen soll. Dies ist aktuell notwendig, da wir nur eine einzige statische Tabelle unterstützen.
Wenn ein Benutzer eine Tabelle geöffnet hat und diese analysieren möchte, importieren wir die Pakete. Tritt ein Problem auf, wird der Vorgang abgebrochen und ein Protokoll mit der Fehlerursache angezeigt. Bei erfolgreicher Ausführung initialisieren wir die Benutzeroberfläche, sodass der Benutzer das Tool verwenden kann. Existiert die Benutzeroberfläche bereits in der JMP-Instanz, wird sie direkt in den Vordergrund gebracht, ohne dass eine Initialisierung erforderlich ist.
Um kurz zu erklären, wie es im Hintergrund funktioniert: Wir verwenden Datentypen, JMP-Klassen und auf der Python-Seite das Pydantic-Paket, um die von uns verwendeten Modelle zu erstellen sowie zur Typ- und Datenvalidierung.
Hier sehen wir ein Beispiel für HDBSCAN. Nehmen wir zum Beispiel das Argument `features`: Es handelt sich um eine Liste von Zeichenketten. Dieses Feld hat eine Mindestlänge von eins und verwendet ein JSON-Schema mit numerischen Spalten. Wenn JMP diese Daten empfängt, erstellt es die entsprechende Klasse. Es wird eine Schaltfläche und eine Spaltenliste angezeigt. Der Benutzer muss mindestens eine numerische Spalte eingeben, damit die Anwendung funktioniert. Für verschiedene Datentypen gibt es unterschiedliche Elementtypen: Ganzzahlen, Zahlenfelder und boolesche Felder (Kontrollkästchen) usw.
Wenn Benutzer den Dienst ausführen möchten, füllen sie die Spalten aus, klicken auf die Schaltfläche „Dienst ausführen“ und der JMP-Code erstellt daraufhin eine Teilmenge der Daten, die diese Spalten enthält und die nicht ausgeschlossenen Spalten auswählt. Diese werden dann beim Aufruf der Python-Funktion verwendet. Dies vereinfacht die Verwaltung auf der Python-Seite, daher diese Vorgehensweise.
Python führt seinen Algorithmus aus und aktualisiert die Werte in der Teilmenge. Sobald die Teilmenge und Python Werte liefern, weiß JMP: „Okay, jetzt können wir die Originaltabelle aktualisieren.“ Die Tabelle wird aktualisiert, die Teilmenge geschlossen und anschließend Tabellenskripte und Spalteneigenschaften für die Originaltabelle erstellt. Bei jedem Aufruf eines Dienstes werden, sofern Spalten benötigt werden, neue Spalten in der Tabelle erstellt.
Hier einige Anwendungsbeispiele: Der Benutzer führt das Add-in aus, es prüft die Versionskontrolle, und in diesem Fall möchte der Benutzer tSNE über das Add-in starten. Dazu wählt er tSNE auf der linken Seite aus, gibt die Spalten ein und konsultiert die offizielle Dokumentation von tSNE, um beispielsweise die Funktionsweise, die Funktionen und die Parameter zu erfahren. Sobald der Benutzer den Dienst ausführen möchte, klickt er auf die Schaltfläche „Dienst ausführen“. Daraufhin werden neue Spalten in der JMP-Tabelle erstellt, mit denen er nun wie gewohnt über die JMP-Schaltfläche arbeiten kann.
Anschließend betrachten wir das Berichtsskript, in diesem Fall nur die Eingabeparameter. Hier folgen etwas komplexere, umfangreichere oder detailliertere Beispiele. Diese Demonstration findet im interaktiven Modus statt. Meiner Meinung nach ist dies eine unserer besten Funktionen. Es werden nicht ständig neue Spalten erstellt, sondern statische Spalten aktualisiert und die Python-Algorithmen sofort neu ausgeführt, sobald der Benutzer Werte in der Benutzeroberfläche ändert. Beispielsweise können Sie diese Algorithmen für die Datenanalyse oder die Feinabstimmung von Daten verwenden.
Hier drückt der Benutzer im Prinzip die Pfeiltaste nach oben auf der Tastatur. Dadurch wird der Python-Algorithmus fortlaufend neu ausgeführt, und die Clusterbildung ändert sich basierend auf den Benutzereinstellungen, sobald dieser die Werte aktualisiert. Je nach Ansicht ändern sich auch die Komponenten, sodass je nach den eingegebenen Werten völlig unterschiedliche Cluster entstehen. Sie können die Werte hier interaktiv anpassen, die optimalen Werte für den jeweiligen Fall ermitteln und diese dann beispielsweise in Python verwenden.
Dann gibt es diesen Feature-Importance-Service, der mehrere Algorithmen nutzt und Shapley-Werte verwendet, um die wichtigsten Merkmale für die Modellierung oder Vorhersage zu ermitteln. Wir führen die Modelle aus, erhalten die Shapley-Werte [unverständlich 00:10:32] und das Ranking der ausgewählten Algorithmen. In diesem Fall sind das RGBM, XGBoost und AdaBoost. Benutzer können die Werte von hier kopieren und in JMP mit diesen Spalten modellieren.
Abschließend noch einige zukünftige Arbeiten an diesem Tool: Unterstützung für dynamische Tabellen (derzeit gibt es nur eine statische Tabelle), weitere Dienste, Bildanalyse und unsere eigenen, benutzerdefinierten Machine-Learning-Modelle. Die Interaktivität wird verbessert, sodass Python direkt Grafikskripte erstellen oder aktualisieren kann. Python-Modelle können exportiert und importiert werden. Die hervorragenden DOE-Funktionen von JMP werden für die Feinabstimmung von Parametern genutzt. Es werden Pipelines erstellt, um mehrere Dienste nacheinander auszuführen. Die vorhandenen dynamischen Funktionen werden verbessert, und je nach den Neuerungen in JMP19 sind Refactoring-Maßnahmen geplant, um das Tool weiter zu optimieren. Außerdem wird die Veröffentlichung als Open Source diskutiert, um die Entwicklung durch ein breiteres Team zu ermöglichen. Vielen Dank.