Science des données : Julia, R ou Python ?
Un petit aperçu des avantages et inconvénients du langage Julia

Le , par dourouc05, Responsable Qt
Le langage Python a été inventé dans les années 1990 pour des tâches d'administration système. Ces dernières années, il est devenu de plus en plus utilisé dans le contexte de la science des données : analyser des jeux de données, apprendre des modèles statistiques, créer des graphiques, etc. Ainsi, l'écosystème a évolué avec bon nombre de bibliothèques, d'outils et autres applications.

Peu après les débuts de Python, mais bien avant son utilisation pour en science des données, R a été développé spécifiquement pour les besoins de statisticiens. Avec les années, son écosystème s'est considérablement enrichi dans le domaine, au point où le langage est une référence en termes de fonctionnalités de haut niveau disponibles, tant pour l'analyse de données que la création de graphes.

Julia est un autre langage fort utilisé en science des données : moins populaire que les deux derniers, il prend néanmoins son envol. Ses premières versions ne datent que de 2012 (la 1.0 n'est toujours pas sortie). Ses objectifs sont proches de ceux de R (faciliter le calcul scientifique, notamment statistique), mais avec une excellente performance (là où tant Python et R pêchent).

Quels sont les avantages des uns et des autres ?

Avantages de Julia :

  • la performance par défaut : bien qu'il soit possible d'accélérer des programmes R ou Python (en réécrivant certaines parties en un autre langage, par exemple), Julia propose une excellente performance sans artéfact ;
  • une syntaxe plaisante pour les mathématiques, très proche des notations habituelles. Par exemple, un produit matriciel s'écrit avec * en Julia, mais avec %*% en R ou @ en Python (uniquement depuis la version 3.6) ;
  • le parallélisme facile, tant sur les différents cœurs d'une machine (ce qui est syntaxiquement plus difficile en Python), R proposant le même genre de facilités, que sur plusieurs machines (Julia propose des abstractions, alors que R et Python se contentent de bibliothèques comme MPI).

Inconvénients de Julia :

  • la jeunesse du langage, qui fait que sa syntaxe continue d'évoluer (probablement plus pour très longtemps) ;
  • le peu de paquets disponibles par rapport à R ou Python, même s'il est possible assez facilement d'utiliser les bibliothèques pour d'autres langages ;
  • une communauté en cours de création, un corollaire assez direct de la jeunesse du langage.

Points communs :

  • la gestion automatique de la mémoire, il est inutile d'allouer et de libérer la mémoire explicitement (même si on peut le faire pour gagner en performance).


Et vous, quel langage préférez-vous pour la science des données ?

Article inspiré de Julia vs. Python: Julia language rises for data science.


Vous avez aimé cette actualité ? Alors partagez-la avec vos amis en cliquant sur les boutons ci-dessous :


 Poster une réponse

Avatar de RyzenOC RyzenOC - Membre éclairé https://www.developpez.com
le 16/01/2018 à 22:22
python, avec numpy+scipy

une syntaxe plaisante pour les mathématiques, très proche des notations habituelles. Par exemple, un produit matriciel s'écrit avec * en Julia, mais avec %*% en R ou @ en Python (uniquement depuis la version 3.6) ;
bah moi en python avec numpy cela donne :

Code : Sélectionner tout
1
2
3
4
a = np.array([[ 5, 1 ,3], [ 1, 1 ,1], [ 1, 2 ,1]])
b = np.array([1, 2, 3])

print a*b
C'est complètement débile de faire du calcul scientifique en python pure. Il est impératif d'utiliser la lib numpy et/ou scipy, scipy qui au passage contient pleins de formule toute prete à l'emploie dans tous les domaines (mécanique, électronique, astronomique, biologie...) comme la transformation de fourier que j'ai utilisé récemment.
https://docs.scipy.org/doc/scipy/reference/fftpack.html

on en reviens a l'argument des performances. Python pure c'est de la merde, mais avec numpy le calcule matriciel est très performant ! Je sais pas si c'est plus performant que Julia mais en tous cas numpy change radicalement ce paramètre, sur google je trouve des benchs parfois meilleurs pour Julia, parfois meilleur pour python.

le parallélisme facile, tant sur les différents cœurs d'une machine (ce qui est syntaxiquement plus difficile en Python),
entièrement d'accord. le parallélisme en python est une calamité à gérer. J’espère que ce point sera améliorer dans python 4
J'ai en tous cas pu voir des travaux allant dans ce sens, en conservant le gil des chercheurs avait quand même réussie à faire du multicœurs (sans recourir au multiprocessing)

edit: pour être honnête, je connais aucun langage à par le Go ou le parallélisme est bien conçue
redit: je connais R et Python mais pas Julia, mais je n'ai aucun doute qu'il fasse mieux que Python niveau parallélisme.
Avatar de SimonDecoline SimonDecoline - Membre éclairé https://www.developpez.com
le 17/01/2018 à 0:32
Julia est performant et productif mais il faut quand même nuancer le "par défaut" car, pour être vraiment performant, le code doit être écrit dans un style particulier (et un peu déroutant au début). Heureusement, il y a une bonne doc (https://docs.julialang.org/en/stable...formance-tips/) et une bonne communauté (https://discourse.julialang.org/t/ab...-category/6422).
Avatar de dourouc05 dourouc05 - Responsable Qt https://www.developpez.com
le 17/01/2018 à 3:04
Citation Envoyé par RyzenOC Voir le message
bah moi en python avec numpy cela donne :
Sauf que ce n'est pas un produit matriciel, mais un produit élément par élément (https://docs.scipy.org/doc/numpy-dev...sic-operations). Pour la performance, tout le code lourd ne fait pas que du calcul matriciel (qui doit être similaire entre NumpPy et Julia, les deux faisant appel à une implémentation de BLAS), c'est là qu'on voit les différences.

Citation Envoyé par RyzenOC Voir le message
edit: pour être honnête, je connais aucun langage à par le Go ou le parallélisme est bien conçue
redit: je connais R et Python mais pas Julia, mais je n'ai aucun doute qu'il fasse mieux que Python niveau parallélisme.
Le meilleur est probablement toujours à venir : on a déjà @distributed pour lancer un calcul automatiquement sur plusieurs processus (potentiellement distants) — jusqu'il y a peu, c'était @parallel, mais ça a été renommé pour faire de la place à du multifil plus traditionnel.

Citation Envoyé par SimonDecoline Voir le message
Julia est performant et productif mais il faut quand même nuancer le "par défaut" car, pour être vraiment performant, le code doit être écrit dans un style particulier (et un peu déroutant au début). Heureusement, il y a une bonne doc (https://docs.julialang.org/en/stable...formance-tips/) et une bonne communauté (https://discourse.julialang.org/t/ab...-category/6422).
Tu cites une liste d'astuces pour aller encore plus vite : comme pour tous les langages, le compilateur ne peut pas tout faire lui-même, il faut un peu l'aider. Par contre, Julia te permet d'atteindre, sans entrer dans ce genre de délires, une très bonne performance — comme partout ailleurs, plus tu pousses loin, plus tu peux améliorer, évidemment.
Avatar de Madmac Madmac - Membre confirmé https://www.developpez.com
le 17/01/2018 à 6:51
Il manque deux langages à cette liste: Fortran et APL. Je sais, ce ne sont pas des langage récents, mais pour ce qui est des calculs, ce sont les champions incontestés à détrôner.

Je trouve Julia intéressant, mais il manque des fonctions qui pourrait permettrait de spécifier que certaines opérations effectué sur un tableau puisse être fait en parallèle. Je ne comprend pas que personne n'a pensé à ajouter ce genre de fonctionnalité pour un langage qui utilise intensément les tableaux et le matrice.
Avatar de SimonDecoline SimonDecoline - Membre éclairé https://www.developpez.com
le 17/01/2018 à 8:32
Citation Envoyé par dourouc05 Voir le message
Tu cites une liste d'astuces pour aller encore plus vite : comme pour tous les langages, le compilateur ne peut pas tout faire lui-même, il faut un peu l'aider. Par contre, Julia te permet d'atteindre, sans entrer dans ce genre de délires, une très bonne performance — comme partout ailleurs, plus tu pousses loin, plus tu peux améliorer, évidemment.
Non, c'est vraiment un style particulier qu'il vaut mieux apprendre dès le début. Si tu prends un script python et que tu le traduis en julia, les performances ne seront vraiment pas bonnes et donc ça n'a pas vraiment d'intéret de passer en julia. Ce serait comme faire du java en mettant tout le code dans une seule classe. Avec julia, il faut prendre l'habitude de bien découper en petites fonctions, de savoir choisir des structures de données mutables ou non, de faire des boucles ou pas ou en fait si, etc...
Avatar de Lyons Lyons - Membre confirmé https://www.developpez.com
le 17/01/2018 à 18:01
N'utilisant aucun des langages mentionnés à des fins mathématiques, quel est leur intérèt par rapport à C++ par exemple?
J'ai du mal à m'imaginer un cas où un de ces langages serait plus efficace (à la fois niveau productivité et performance) que C++ avec Eigen ou TensorFlow.
Avatar de redbullch redbullch - Membre confirmé https://www.developpez.com
le 17/01/2018 à 18:03
Le plus gros des calculs se fait maintenant sur un ou plusieurs GPU, le plus souvent avec CUDA. Le langage n'est, d'après moi, pas si significatif pour des calculs conséquents sur GPU.

Vu qu'on parle de la science des données, vous suivez peut-être les derniers frameworks de "Deep Learning" tels que Tensorflow, Pytorch et CNTK. Tous ces frameworks ont choisit python comme interface principale et cela n'affecte pas tant que ça les performances (car les calculs ne sont pas fait en python derrière).

Je suis d'accord sur les critiques du langage python. Le GIL est vraiment une plaie, on est pour l'instant obligé de faire du multiprocessing si on souhaite utiliser tous les cœurs. Beaucoup de débutants ne comprennent pas qu'il y a des coûts de sérialisations/dé-sérialisations en passant par des processus, contrairement aux threads.

Concernant la manière d'exprimer le parallélisme, j'aime beaucoup l'approche de Scala.

Code : Sélectionner tout
1
2
3
val list = (1 to 10000).toList
list.map(_ + 42) // créer un nouvelle liste en ajoutant 42 à chaque élément de "list".
list.par.map(_ + 42) // créer un nouvelle liste en ajoutant 42 à chaque élément de "list", en parallèle.
En python, ce n'est pas aussi élégant. Il n'est même pas possible d'utiliser un lambda avec multiprocessing car le serializer n'arrive pas à sérialiser ceux-ci:
Code : Sélectionner tout
1
2
3
4
5
6
7
8
9
10
11
from multiprocessing import Pool

def plus_42(a):
        return a+42

if __name__ == '__main__':
    my_list = list(range(1, 10000))

    with Pool() as p:
        #  impossible de faire: res = p.map(lambda x: x+42, my_list) 
        res = p.map(plus_42, my_list)
Malgré tous ces défauts, je reste un pythonist convaincu, mais je ne suis pas allergique aux autres langages (sauf R).
Avatar de SimonDecoline SimonDecoline - Membre éclairé https://www.developpez.com
le 17/01/2018 à 18:26
Il est possible d'utiliser tensorflow en julia : https://github.com/malmaud/TensorFlow.jl. Et tensorflow ce n'est pas pas vraiment un bon exemple car il faut écrire le graphe de calcul explicitement, du coup le code est plus du DSL tensorflow que du python. Pytorch est beaucoup plus propre de ce point de vue, il parait.

Un avantage de julia, c'est que justement on n'a plus à gérer 2 langages (python pour la productivité et C++ pour la performance).
Avatar de redbullch redbullch - Membre confirmé https://www.developpez.com
le 17/01/2018 à 19:05
Citation Envoyé par Lyons Voir le message
N'utilisant aucun des langages mentionnés à des fins mathématiques, quel est leur intérêt par rapport à C++ par exemple?
J'ai du mal à m'imaginer un cas où un de ces langages serait plus efficace (à la fois niveau productivité et performance) que C++ avec Eigen ou TensorFlow.
Voici un scénario que j'ai vécu où python est à mon sens plus adapté que C++:

Un client qui gère des machines de production nous contacte pour un projet de maintenance prédictive.

Le client a par chance déjà un historique de données sur ses machines (températures, charges, états, pannes, ...). Il nous envoi ces données (plusieurs fichiers json de plusieurs Go) afin qu'on les analyse.

En quelques lignes de python, je suis capable de:
  • Charger les données json
  • Afficher un graphe interactif avec les données dans le temps
  • Sortir les statistiques habituels (distributions, moyennes, écart-type, ...)
  • Mettre en évidence les éventuels corrélations


Suivant les conclusions des résultats ci-dessus, partir sur un modèle qui permet de prédire le temps restant avant la panne X.

De nouveau, en quelques lignes:
  • Pré-traiter les données (filtrer, normaliser, faire des séquences, ...)
  • Utiliser un ou plusieurs modèles de machine learning
  • Évaluer la performance du modèle
  • Afficher la prédiction dans le temps et tirer des conclusions avec le client


Voilà pour un exemple concret où je trouve que python et son écosystème est intéressant.

Python est très utile dans les phases d'explorations où il faut "essayer des trucs".

Après je suis d'accord qu'une fois qu'on est à la phase de production, qu'on sait ce qu'on va faire, C++ est très bien.
Avatar de Madmac Madmac - Membre confirmé https://www.developpez.com
le 17/01/2018 à 19:45
Lyon a dit
N'utilisant aucun des langages mentionnés à des fins mathématiques, quel est leur intérèt par rapport à C++ par exemple?
J'ai du mal à m'imaginer un cas où un de ces langages serait plus efficace (à la fois niveau productivité et performance) que C++ avec Eigen ou TensorFlow.
Ce qui est intéressant dans des applications qui font du calcul est qu'il est possible de faire du streams processing.

Imagine les taches suivantes:

A : Initialiser un tableau avec les valeurs de 0 à 100
B: Additionner une valeur aléatoire de 1 à 10
C: Imprimer le tableau

Et bien si tu imagine ton programme de la façon suivante:

Tu utilise une queue (queue 1) a la place d'un tableau pour faire la tâche A
Tu utilise la queue 1 comme entrée pour la tache B et tu envoie le résultat dans une autre queue (queue 2)
Tu utilise la queue 2 comme entrée pour la tache C (impression)

Ton code sera supérieur pour deux raisons:

Parce que tu peux faire du pipeline. (Dès que la deuxième valeur est entrée dans la queue 1, tu peux commence la tâche B, Et dès que tu a la deuxième valeur d'entrée dans la queue 2, tu peux exécuté la tâche C). Donc en pratique, il est possible de faire un langage qui supporte implicitement la parallélisme (sans que le programmeur soit un expert du parallélisme), si tu donne la possibilité d'écrire un directive à ta tâche pour faire du pipeline.

La deuxième raison est que le stream processing permet le tail-recursion. APL est le langage interprété le plus rapide du monde, justement pour cette raison. Le tail-recursion permet de faire des tâches avec le minimum de mémoire. Donc tu réduis au minimum travail ramassage-miette (garbage-collection)

Donc comme tu vois la façon d'imaginer ton langage peut avoir un grand impact sur les performances, si tu exploite les astuces développés depuis 40 ans.

https://fr.wikipedia.org/wiki/R%C3%A9cursion_terminale (tail-recursion)
https://en.wikipedia.org/wiki/Stream_processing (Stream processing)
https://fr.wikipedia.org/wiki/Pipeli...s_processeurs) (Pas la meilleur description, mais suffisante pour comprendre que ce n'est pas du batch processing)
Contacter le responsable de la rubrique Accueil