Dans notre volonté d'exploiter pleinement les capacités de Python au sein de JMP, nous avons dû relever le défi d'intégrer la flexibilité de Python à l'expérience utilisateur intuitive et interactive de JMP. Avant JMP 18, nous y parvenions grâce à une solution de contournement : exécuter Python sur un serveur pour contourner l'intégration complexe de Python dans JMP. Cependant, la sortie de JMP 18 a réintroduit l'intégration de Python, simplifiant ainsi ce processus.
Partant de notre concept initial visant à permettre aux utilisateurs de JMP d'exploiter Python sans nécessiter de compétences en programmation, nous avons développé JMPyFacade (JMPy). Cet outil offre une interface familière, similaire à celle de JMP, pour exécuter des services Python prédéfinis via une interface utilisateur générée dynamiquement, tout en masquant le code Python et JSL sous-jacent.
Dans cette présentation, nous explorons l'architecture technique de JMPyFacade et démontrons comment elle assure une intégration efficace entre JMP et Python. Les participants découvriront comment exploiter Python au sein de JMP pour une analyse de données performante et interactive.
Bonjour et bienvenue à ma présentation par affiche sur l'intégration de JMP et Python pour des analyses fluides et interactives. Je m'appelle Jarmo Hirvonen et je travaille chez Murata, en Finlande. Dans cette présentation, j'expliquerai pourquoi utiliser Python dans JMP, ou plutôt l'intégration de Python dans JMP. J'aborderai également certains points concernant cette intégration, ainsi que l'une des applications que nous avons développées chez Murata, en Finlande, avec mon collègue Eero, qui exploite cette intégration. Commençons par examiner les avantages de cette fonctionnalité dans JMP.
JMP est un outil très visuel et interactif doté de bonnes capacités d'analyse. Par ailleurs, Python est devenu le langage de programmation de référence pour de nombreuses tâches liées aux données. Il dispose de nombreuses bibliothèques bien établies, et il est possible que votre entreprise possède déjà des compétences en Python.
Je vois les choses sous deux angles. D'une part, certains utilisateurs initiaux auront accès à des fonctionnalités non disponibles nativement dans JMP, comme certains modèles d'apprentissage automatique (Torch, par exemple), et d'autre part, à des types de fichiers qu'il était impossible d'utiliser autrement dans JMP.
Un exemple concret est celui des fichiers Parquet : vous pouvez les ouvrir dans Python, puis les importer dans JMP. Les utilisateurs de Python bénéficient ainsi d'un accès aux outils visuels et interactifs de JMP, utilisables soit directement dans JMP, soit via une intégration avec Python. JMP propose également des fonctionnalités d'analyse exclusives. Enfin, il est important de noter que Python est installé avec JMP 18.
Le chargement initial de chaque instance JMP est un peu lent. Autrement dit, le premier chargement de la salle dans l'instance JMP prend un certain temps, mais les chargements suivants sont plus rapides si vous ne fermez pas complètement JMP. Il est conseillé d'en tenir compte pour les projets très simples. Il pourrait être judicieux d'essayer de le faire uniquement avec JSL ; c'est plus rapide.
La gestion et l'installation des paquets peuvent parfois poser problème, malgré la documentation disponible. Cependant, leur résolution peut parfois s'avérer fastidieuse. Vous ne disposez que d'un seul environnement ; par conséquent, si vous avez l'habitude de travailler avec des environnements virtuels, l'intégration des tâches n'est pas possible actuellement. Une certaine compréhension des conversions de types de données JSL et Python est nécessaire ; une documentation est disponible à ce sujet sur une page web. La gestion de la portée des variables peut être source de confusion. En Python, la portée est globale, et selon la façon dont vous nommez vos variables, des interférences peuvent survenir entre différents scripts.
Enfin, à mon avis, l'un des principaux inconvénients est que le débogage et le développement en Python peuvent s'avérer fastidieux, et il est parfois difficile de trouver le bon rythme. Cela est dû principalement à l'impossibilité de réinitialiser Python dans JMP ou de redémarrer le noyau, ce qui vous enferme dans un cycle de développement. Vous développez en Python, puis vous souhaitez tester, et vous soupçonnez qu'il y a des éléments à nettoyer dans certaines variables, par exemple.
La seule solution actuelle consiste à fermer l'instance JMP, à relancer les commandes JMP, puis à tout recharger avant de pouvoir tester le code. Il ne s'agit pas d'un cycle, mais d'une interruption, et il faut tout recommencer depuis le début. Cela interrompt le flux d'exécution et peut être frustrant. Il est possible d'atténuer ce problème en fonction de la manière dont vous écrivez votre code Python.
Passons maintenant à notre application : JMPyFacade. Son nom vient de sa capacité à masquer le code complexe de JMP et Python derrière une interface utilisateur assez similaire et familière, proche de celle de JMP. Un système de contrôle de version a été ajouté, offrant aux utilisateurs de JMP un accès à des fonctionnalités Python prédéfinies. Nous les appelons des services. Ces services vont de la création de jeux de données très simples à des modèles d'apprentissage beaucoup plus complexes.
Notre objectif est de permettre à nos utilisateurs JMP d'utiliser les fonctionnalités Python sans même qu'ils s'en rendent compte. Nous avions déjà une solution similaire, mais nous utilisions alors un serveur pour contourner l'intégration Python de JMP, car elle était auparavant complexe. Avec JMP 18, nous pouvons désormais utiliser l'intégration native, et elle fonctionne parfaitement.
Lors du lancement de l'application, l'utilisateur exécute l'extension, qui vérifie ensuite si elle est à jour. Si ce n'est pas le cas, une mise à jour est effectuée et l'utilisateur est invité à relancer l'extension. En l'absence de mise à jour, le processus Python LS est initialisé dans JMP. Cette étape a pour but de mettre à jour les commandes. Sans cette mise à jour, une application de ce type pourrait rencontrer des problèmes si les commandes ne sont pas disponibles.
Une fois ces éléments initialisés, nous allons vérifier auprès de notre gestionnaire de paquets s'il existe des paquets à mettre à jour. Le cas échéant, nous les mettrons à jour. Sinon, nous poursuivrons l'exécution. Nous vérifions également si l'utilisateur a une table ouverte. Si ce n'est pas le cas, nous fermerons l'extension et l'informerons qu'il doit ouvrir une table avant de l'exécuter. Cette procédure est actuellement nécessaire car nous ne prenons en charge qu'une seule table statique.
Ensuite, lorsqu'un utilisateur a une table ouverte et souhaite l'analyser, nous importons les packages. En cas de problème, le processus s'arrête et un journal s'affiche pour indiquer l'erreur rencontrée. Si l'opération réussit, nous initialisons et créons l'interface utilisateur, et les utilisateurs peuvent commencer à utiliser l'outil. Si l'interface utilisateur existe déjà dans l'instance JMP, nous l'affichons simplement au premier plan sans effectuer d'initialisation supplémentaire.
Voici un aperçu du fonctionnement en arrière-plan : nous utilisons des types de données, des classes JMP et, côté Python, le package Pydantic pour créer les modèles que nous utilisons, ainsi que pour la validation des types et des données.
Voici un exemple de HDBSCAN. Prenons par exemple l'argument `features` : il s'agit d'une liste de chaînes de caractères, un champ d'une longueur minimale de un et utilisant le schéma JSON, avec des colonnes numériques. Lorsque JMP reçoit ces données, il crée une classe correspondante. Vous accédez ainsi à un bouton, une liste déroulante de colonnes, où l'utilisateur doit saisir une seule valeur numérique (au moins une colonne numérique est nécessaire au fonctionnement). Différents types d'éléments sont utilisés pour différents types de données : des entiers (8 champs numériques), des cases à cocher (booléens), etc.
Lorsque les utilisateurs sont prêts à exécuter le service, ils remplissent les colonnes, cliquent sur le bouton « Exécuter le service », et le code JMP crée alors un sous-ensemble des données correspondant à ces colonnes et sélectionne celles qui ne sont pas exclues. Ces données sont ensuite utilisées lors de l'appel de la fonction Python. Cela simplifie la gestion côté Python, c'est pourquoi nous procédons ainsi.
Python exécutera son algorithme et mettra à jour les valeurs du sous-ensemble. Lorsque le sous-ensemble et Python auront renvoyé des valeurs, JMP saura que la table d'origine peut être mise à jour. Il la mettra à jour, fermera le sous-ensemble, puis créera des scripts et des propriétés de colonnes pour la table d'origine. À chaque exécution d'un service, de nouvelles colonnes seront créées dans la table si nécessaire.
Voici quelques exemples d'utilisation. Dans cet exemple basique, l'utilisateur exécute le module complémentaire. Ce dernier vérifie la version et, dans ce cas précis, l'utilisateur souhaite exécuter tSNE. Il sélectionne donc tSNE dans le menu de gauche, saisit les colonnes et consulte la documentation officielle de tSNE pour savoir, par exemple, comment il fonctionne et quels sont ses paramètres. Une fois prêt à exécuter le service, l'utilisateur clique sur le bouton « Exécuter le service ». De nouvelles colonnes sont alors créées dans la table JMP, qu'il peut ensuite manipuler comme n'importe quelle table JMP.
Nous visualisons ensuite le script du rapport, qui ici ne contient que les paramètres d'entrée. Voici des exemples plus complexes, voire plus détaillés. Cette démonstration utilise un mode interactif, une de nos meilleures fonctionnalités. Au lieu de créer systématiquement de nouvelles colonnes, ces outils mettent à jour les colonnes statiques et relancent immédiatement leurs algorithmes Python dès que l'utilisateur modifie une valeur dans l'interface. Vous pouvez ainsi exporter des données pour analyser ou affiner des algorithmes.
Ici, l'utilisateur clique simplement sur la flèche du haut du clavier, ce qui relance l'algorithme Python en continu. Le regroupement s'adapte en fonction de l'utilisateur lorsqu'il modifie les valeurs. Plus il y a de vues, plus les composantes changent, ce qui permet d'obtenir des regroupements totalement différents selon les valeurs saisies. Vous pouvez modifier les valeurs de manière interactive, déterminer la meilleure configuration dans ce cas précis, puis l'utiliser dans Python, par exemple.
Nous disposons ensuite d'un service d'évaluation de l'importance des caractéristiques qui utilise plusieurs algorithmes et les valeurs de Shapley pour déterminer les plus pertinentes pour la modélisation ou la prédiction. Après l'exécution des modèles, nous obtenons les valeurs de Shapley [inaudible 00:10:32] ainsi qu'un classement des algorithmes sélectionnés : RGBM, XGBoost et AdaBoost. L'utilisateur peut alors copier-coller ces valeurs et commencer la modélisation dans JMP.
Enfin, les développements futurs de cet outil incluent l'ajout de la prise en charge des tables dynamiques (en plus des tables statiques actuelles), de services supplémentaires, l'analyse d'images et l'intégration de nos propres modèles d'apprentissage automatique personnalisés. L'interactivité sera améliorée, permettant ainsi à Python de créer ou de mettre à jour directement des scripts graphiques. L'exportation et l'importation de modèles Python seront également possibles. L'outil tirera parti des excellentes capacités de JMP en matière de plans d'expériences (DOE) pour l'ajustement précis des paramètres. La création de pipelines permettra d'exécuter plusieurs services en séquence. Nous améliorerons les fonctionnalités dynamiques existantes et, en fonction des nouveautés de JMP19, nous envisagerons une refonte pour optimiser davantage l'outil. Enfin, nous pourrions envisager de le rendre open source afin d'impliquer d'autres contributeurs à son développement. Merci.