Python contre R : magie du sucre syntaxique

Publié: 2022-07-22

Mon palais de développement s'est élargi depuis que j'ai appris à apprécier la douceur trouvée dans Python et R. La science des données est un art qui peut être abordé sous plusieurs angles mais qui nécessite un équilibre délicat entre langage, bibliothèques et expertise. Les capacités étendues de Python et R fournissent du sucre syntaxique : une syntaxe qui facilite notre travail et nous permet de résoudre des problèmes complexes avec des solutions courtes et élégantes.

Ces langages nous offrent des moyens uniques d'explorer notre espace de solutions. Chaque langue a ses propres forces et faiblesses. L'astuce pour utiliser chacun efficacement est de reconnaître quels types de problèmes bénéficient de chaque outil et de décider comment nous voulons communiquer nos résultats. Le sucre syntaxique dans chaque langue nous permet de travailler plus efficacement.

R et Python fonctionnent comme des interfaces interactives au-dessus du code de niveau inférieur, permettant aux data scientists d'utiliser le langage de leur choix pour l'exploration, la visualisation et la modélisation des données. Cette interactivité nous permet d'éviter la boucle incessante d'édition et de compilation de code, qui complique inutilement notre travail.

Ces langages de haut niveau nous permettent de travailler avec un minimum de friction et de faire plus avec moins de code. Le sucre syntaxique de chaque langue nous permet de tester rapidement nos idées dans une REPL (boucle de lecture-évaluation-impression), une interface interactive où le code peut être exécuté en temps réel. Cette approche itérative est un élément clé du cycle moderne de traitement des données.

R vs Python : expressif et spécialisé

La puissance de R et Python réside dans leur expressivité et leur flexibilité. Chaque langage a des cas d'utilisation spécifiques dans lesquels il est plus puissant que l'autre. De plus, chaque langage résout des problèmes selon différents vecteurs et avec des types de sortie très différents. Ces styles ont tendance à avoir différentes communautés de développeurs où une langue est préférée. Au fur et à mesure que chaque communauté se développe de manière organique, leur langage préféré et leurs ensembles de fonctionnalités tendent vers des styles de sucre syntaxiques uniques qui réduisent le volume de code requis pour résoudre les problèmes. Et à mesure que la communauté et la langue mûrissent, le sucre syntaxique de la langue devient souvent encore plus doux.

Bien que chaque langage offre un ensemble d'outils puissants pour résoudre les problèmes de données, nous devons aborder ces problèmes de manière à exploiter les atouts particuliers des outils. R est né en tant que langage de calcul statistique et dispose d'un large éventail d'outils disponibles pour effectuer des analyses statistiques et expliquer les données. Python et ses approches d'apprentissage automatique résolvent des problèmes similaires, mais uniquement ceux qui s'inscrivent dans un modèle d'apprentissage automatique. Considérez l'informatique statistique et l'apprentissage automatique comme deux écoles de modélisation de données : bien que ces écoles soient fortement interconnectées, leurs origines et leurs paradigmes de modélisation de données sont différents.

R aime les statistiques

R a évolué pour devenir une riche offre de packages pour l'analyse statistique, la modélisation linéaire et la visualisation. Parce que ces packages font partie de l'écosystème R depuis des décennies, ils sont matures, efficaces et bien documentés. Lorsqu'un problème nécessite une approche de calcul statistique, R est le bon outil pour le travail.

Les principales raisons pour lesquelles R est aimé par sa communauté se résument à :

  • Méthodes discrètes de manipulation, de calcul et de filtrage de données.
  • Opérateurs de chaînage flexibles pour connecter ces méthodes.
  • Un sucre syntaxique succinct qui permet aux développeurs de résoudre des problèmes complexes en utilisant des méthodes statistiques et de visualisation confortables.

Un modèle linéaire simple avec R

Pour voir à quel point R peut être succinct, créons un exemple qui prédit les prix des diamants. Premièrement, nous avons besoin de données. Nous utiliserons le jeu de données par défaut des diamonds , qui est installé avec R et contient des attributs tels que la couleur et la coupe.

Nous démontrerons également l'opérateur pipe de R ( %>% ), l'équivalent de l'opérateur pipe de ligne de commande Unix ( | ). Cette partie populaire de la fonction de sucre syntaxique de R est mise à disposition par la suite de packages tidyverse. Cet opérateur et le style de code qui en résulte changent la donne dans R car ils permettent le chaînage des verbes R (c'est-à-dire les fonctions R) pour diviser et conquérir un large éventail de problèmes.

Le code suivant charge les bibliothèques requises, traite nos données et génère un modèle linéaire :

 library(tidyverse) library(ggplot2) mode <- function(data) { freq <- unique(data) freq[which.max(tabulate(match(data, freq)))] } data <- diamonds %>% mutate(across(where(is.numeric), ~ replace_na(., median(., na.rm = TRUE)))) %>% mutate(across(where(is.numeric), scale)) %>% mutate(across(where(negate(is.numeric)), ~ replace_na(.x, mode(.x)))) model <- lm(price~., data=data) model <- step(model) summary(model)
 Call: lm(formula = price ~ carat + cut + color + clarity + depth + table + x + z, data = data) Residuals: Min 1Q Median 3Q Max -5.3588 -0.1485 -0.0460 0.0943 2.6806 Coefficients: Estimate Std. Error t value Pr(>|t|) (Intercept) -0.140019 0.002461 -56.892 < 2e-16 *** carat 1.337607 0.005775 231.630 < 2e-16 *** cut.L 0.146537 0.005634 26.010 < 2e-16 *** cut.Q -0.075753 0.004508 -16.805 < 2e-16 *** cut.C 0.037210 0.003876 9.601 < 2e-16 *** cut^4 -0.005168 0.003101 -1.667 0.09559 . color.L -0.489337 0.004347 -112.572 < 2e-16 *** color.Q -0.168463 0.003955 -42.599 < 2e-16 *** color.C -0.041429 0.003691 -11.224 < 2e-16 *** color^4 0.009574 0.003391 2.824 0.00475 ** color^5 -0.024008 0.003202 -7.497 6.64e-14 *** color^6 -0.012145 0.002911 -4.172 3.02e-05 *** clarity.L 1.027115 0.007584 135.431 < 2e-16 *** clarity.Q -0.482557 0.007075 -68.205 < 2e-16 *** clarity.C 0.246230 0.006054 40.676 < 2e-16 *** clarity^4 -0.091485 0.004834 -18.926 < 2e-16 *** clarity^5 0.058563 0.003948 14.833 < 2e-16 *** clarity^6 0.001722 0.003438 0.501 0.61640 clarity^7 0.022716 0.003034 7.487 7.13e-14 *** depth -0.022984 0.001622 -14.168 < 2e-16 *** table -0.014843 0.001631 -9.103 < 2e-16 *** x -0.281282 0.008097 -34.740 < 2e-16 *** z -0.008478 0.005872 -1.444 0.14880 --- Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1 Residual standard error: 0.2833 on 53917 degrees of freedom Multiple R-squared: 0.9198, Adjusted R-squared: 0.9198 F-statistic: 2.81e+04 on 22 and 53917 DF, p-value: < 2.2e-16

R rend cette équation linéaire simple à programmer et à comprendre avec son sucre syntaxique. Maintenant, portons notre attention sur l'endroit où Python est roi.

Python est le meilleur pour l'apprentissage automatique

Python est un langage puissant et polyvalent, avec l'une de ses principales communautés d'utilisateurs axées sur l'apprentissage automatique, exploitant des bibliothèques populaires telles que scikit-learn, unbalanced-learn et Optuna. La plupart des kits d'outils d'apprentissage automatique les plus influents, tels que TensorFlow, PyTorch et Jax, sont écrits principalement pour Python.

Le sucre syntaxique de Python est la magie que les experts en apprentissage automatique adorent, y compris la syntaxe succincte du pipeline de données, ainsi que le modèle fit-transform-predict de scikit-learn :

  1. Transformez les données pour les préparer pour le modèle.
  2. Construire un modèle (implicite ou explicite).
  3. Monter le modèle.
  4. Prédire de nouvelles données (modèle supervisé) ou transformer les données (non supervisé).
    • Pour les modèles supervisés, calculez une métrique d'erreur pour les nouveaux points de données.

La bibliothèque scikit-learn encapsule des fonctionnalités correspondant à ce modèle tout en simplifiant la programmation pour l'exploration et la visualisation. Il existe également de nombreuses fonctionnalités correspondant à chaque étape du cycle d'apprentissage automatique, fournissant une validation croisée, un réglage des hyperparamètres et des pipelines.

Un modèle d'apprentissage automatique Diamond

Nous allons maintenant nous concentrer sur un exemple simple d'apprentissage automatique utilisant Python, qui n'a pas de comparaison directe dans R. Nous allons utiliser le même ensemble de données et mettre en évidence le modèle fit-transform-predict dans un morceau de code très serré.

Suivant une approche d'apprentissage automatique, nous diviserons les données en partitions d'entraînement et de test. Nous appliquerons les mêmes transformations sur chaque partition et enchaînerons les opérations contenues avec un pipeline. Les méthodes (ajustement et score) sont des exemples clés de puissantes méthodes d'apprentissage automatique contenues dans scikit-learn :

 import numpy as np import pandas as pd from sklearn.linear_model LinearRegression from sklearn.model_selection import train_test_split from sklearn.preprocessing import StandardScaler from sklearn.preprocessing import OneHotEncoder from sklearn.impute import SimpleImputer from sklearn.pipeline import Pipeline from sklearn.compose import ColumnTransformer from pandas.api.types import is_numeric_dtype diamonds = sns.load_dataset('diamonds') diamonds = diamonds.dropna() x_train,x_test,y_train,y_test = train_test_split(diamonds.drop("price", axis=1), diamonds["price"], test_size=0.2, random_state=0) num_idx = x_train.apply(lambda x: is_numeric_dtype(x)).values num_cols = x_train.columns[num_idx].values cat_cols = x_train.columns[~num_idx].values num_pipeline = Pipeline(steps=[("imputer", SimpleImputer(strategy="median")), ("scaler", StandardScaler())]) cat_steps = Pipeline(steps=[("imputer", SimpleImputer(strategy="constant", fill_value="missing")), ("onehot", OneHotEncoder(drop="first", sparse=False))]) # data transformation and model constructor preprocessor = ColumnTransformer(transformers=[("num", num_pipeline, num_cols), ("cat", cat_steps, cat_cols)]) mod = Pipeline(steps=[("preprocessor", preprocessor), ("linear", LinearRegression())]) # .fit() calls .fit_transform() in turn mod.fit(x_train, y_train) # .predict() calls .transform() in turn mod.predict(x_test) print(f"R squared score: {mod.score(x_test, y_test):.3f}")

Nous pouvons voir à quel point le processus d'apprentissage automatique est rationalisé en Python. De plus, les classes sklearn de Python aident les développeurs à éviter les fuites et les problèmes liés à la transmission de données via notre modèle tout en générant du code structuré et au niveau de la production.

Que peuvent faire d'autre R et Python ?

Outre la résolution d'applications statistiques et la création de modèles d'apprentissage automatique, R et Python excellent dans les rapports, les API, les tableaux de bord interactifs et la simple inclusion de bibliothèques de code externes de bas niveau.

Les développeurs peuvent générer des rapports interactifs à la fois dans R et Python, mais il est beaucoup plus simple de les développer dans R. R prend également en charge l'exportation de ces rapports au format PDF et HTML.

Les deux langages permettent aux data scientists de créer des applications de données interactives. R et Python utilisent respectivement les bibliothèques Shiny et Streamlit pour créer ces applications.

Enfin, R et Python prennent tous deux en charge les liaisons externes au code de bas niveau. Ceci est généralement utilisé pour injecter des opérations hautement performantes dans une bibliothèque, puis appeler ces fonctions depuis le langage de votre choix. R utilise le package Rcpp, tandis que Python utilise le package pybind11 pour y parvenir.

Python et R : de plus en plus doux chaque jour

Dans mon travail de data scientist, j'utilise régulièrement R et Python. La clé est de comprendre où chaque langue est la plus forte, puis d'ajuster un problème pour qu'il s'intègre dans une solution codée avec élégance.

Lorsqu'ils communiquent avec les clients, les scientifiques des données veulent le faire dans la langue la plus facile à comprendre. Par conséquent, nous devons peser si une présentation statistique ou d'apprentissage automatique est plus efficace, puis utiliser le langage de programmation le plus approprié.

Python et R fournissent chacun une collection toujours croissante de sucre syntaxique, qui simplifient à la fois notre travail en tant que data scientists et facilitent sa compréhensibilité pour les autres. Plus notre syntaxe est raffinée, plus il est facile d'automatiser et d'interagir avec nos langages préférés. J'aime mon langage de science des données doux, et les solutions élégantes qui en résultent sont encore plus douces.

Lectures complémentaires sur le blog Toptal Engineering :

  • Une introduction à la théorie de l'apprentissage automatique et à ses applications : un didacticiel visuel avec des exemples
  • Modèles de conception Python : pour un code élégant et à la mode
  • Analyse des réseaux sociaux dans R et Gephi : creuser dans Twitter
  • Explorer les algorithmes d'apprentissage automatique supervisé
  • Garantir un code propre : un regard sur Python, paramétré