Aller au contenu principal

Module 7 — Algorithmes disponibles et leurs contraintes

Spark ML n'est pas une réimplémentation exhaustive de scikit-learn. Le catalogue est plus court, car chaque algorithme distribué demande une mécanique dédiée pour éviter le brassage à chaque itération. Voici ce que MLlib propose, ce qu'elle ne propose pas, et les alternatives quand un algorithme manque.

Modèles linéaires

LogisticRegression, LinearRegression, GeneralizedLinearRegression, AFTSurvivalRegression (survie). Ils s'appuient sur L-BFGS ou un solveur IRLS, tous deux distribués. La régularisation L1, L2 et élastique (elasticNetParam) est intégrée.

from pyspark.ml.regression import LinearRegression

reg = LinearRegression(
featuresCol="features", labelCol="retard_minutes",
maxIter=100, regParam=0.01, elasticNetParam=0.5, standardization=True,
)

standardization=True normalise en interne — pratique, mais rappelez-vous qu'un StandardScaler explicite dans le pipeline reste préférable pour maîtriser la fuite (module 6).

Arbres et forêts

DecisionTreeClassifier, DecisionTreeRegressor, RandomForestClassifier, RandomForestRegressor. La forêt entraîne des arbres indépendamment, ce qui se distribue bien. Le paramètre maxBins — utilisé pour discrétiser les variables continues avant recherche de la meilleure séparation — doit être supérieur au nombre de catégories distinctes des colonnes catégorielles ; sinon Spark refuse avec un message clair.

from pyspark.ml.classification import RandomForestClassifier

foret = RandomForestClassifier(
featuresCol="features", labelCol="retard_15min",
numTrees=200, maxDepth=8, maxBins=200, subsamplingRate=0.8, seed=42,
)

Gradient boosting

GBTClassifier, GBTRegressor. Le gradient boosting de Spark suit l'idée classique : arbres séquentiels sur les résidus. La grande limite comparée aux implémentations modernes est que la classification multiclasse n'est pas prise en charge — seulement binaire. Sur du multiclasse, il faut passer par RandomForest, ou par XGBoost distribué (voir plus bas).

Regroupement

KMeans, BisectingKMeans, GaussianMixture, LDA (allocation de Dirichlet latente pour la découverte de sujets). Le KMeans a besoin d'initialisations et d'itérations globales : plusieurs brassages par itération, coûteux sur très gros volume. Toujours mettre à l'échelle les variables avant, sinon l'algorithme est dominé par la colonne à plus grande variance.

Système de recommandation

ALS (Alternating Least Squares) est le seul algorithme de recommandation officiel. Il apprend des vecteurs latents pour les utilisateurs et les objets, et il est conçu pour la distribution. Sur des jeux à cent millions d'interactions, il reste très compétitif face à un système monomachine.

from pyspark.ml.recommendation import ALS

als = ALS(
userCol="utilisateur_idx", itemCol="objet_idx", ratingCol="note",
rank=32, maxIter=15, regParam=0.05, coldStartStrategy="drop",
)

coldStartStrategy="drop" supprime les utilisateurs ou objets inconnus en évaluation, sans quoi la prédiction est NaN et casse l'évaluateur.

Réduction de dimension et texte

PCA pour la réduction de dimension linéaire, Word2Vec et Tokenizer / HashingTF / IDF pour du texte basique. Le NLP moderne (BERT, transformeurs) n'est pas dans MLlib ; on passe par Spark NLP de John Snow Labs, ou on précalcule les embeddings ailleurs et on les lit en Parquet.

Évaluation

  • BinaryClassificationEvaluator : areaUnderROC (défaut), areaUnderPR.
  • MulticlassClassificationEvaluator : accuracy, f1, weightedPrecision, weightedRecall, logLoss.
  • RegressionEvaluator : rmse (défaut), mae, r2, mse.
  • RankingEvaluator : meanAveragePrecision, ndcgAtK pour les systèmes de recommandation.

Ce qui n'existe pas dans MLlib

C'est aussi important que ce qui existe. Ne cherchez pas dans MLlib :

  • XGBoost, LightGBM, CatBoost : pas dans MLlib. Le paquet séparé xgboost.spark (XGBoost 1.7+) offre une intégration SparkXGBClassifier qui suit l'API MLlib et distribue l'entraînement — c'est le choix de référence pour du gradient boosting sérieux sur Spark.
  • SVM à noyau : MLlib ne propose que LinearSVC. Un SVM à noyau ne passe pas à l'échelle par nature.
  • Réseaux de neurones : seul MultilayerPerceptronClassifier, très limité. Pour du deep learning, sortir de Spark : PyTorch ou TensorFlow, avec Spark utilisé pour le prétraitement puis l'écriture Parquet consommée par les entraîneurs.
  • Modèles bayésiens complexes, processus gaussiens, modèles à effets mixtes : rien.

Quand entraîner localement plutôt qu'en distribué

Deuxième leçon du module : Spark distribue bien la lecture et le prétraitement, moins bien l'entraînement. Sur un jeu de vols réduit à 5 millions de lignes par un sample(0.1), un GBTClassifier peut prendre 45 minutes en Spark, contre 4 minutes en xgboost monomachine sur le même volume. La chaîne « Spark pour préparer, monomachine pour entraîner » est très fréquente en pratique :

train_pd = pipeline_prep.fit(vols_train).transform(vols_train).toPandas()
# entraînement en xgboost sur train_pd

On y perd la scalabilité illimitée, on y gagne un facteur dix sur l'entraînement lui-même dès que les données préparées tiennent en mémoire.

Choisir un algorithme absent

La bonne réaction à « on veut du LightGBM sur Spark » n'est pas d'improviser un RandomForest. C'est de basculer sur xgboost.spark, ou d'accepter d'entraîner en dehors de Spark après un toPandas(). Substituer un algorithme pour rester dans MLlib est souvent un mauvais compromis.

En résumé

  • MLlib couvre linéaire, arbres, forêts, GBT (binaire seulement), KMeans, ALS, PCA et NLP basique — c'est court, mais couvre 80 % des besoins de production.
  • maxBins en forêt doit dépasser la cardinalité des colonnes catégorielles ; coldStartStrategy="drop" en ALS évite les NaN.
  • Manquent XGBoost/LightGBM, SVM à noyau, réseaux profonds : passer par xgboost.spark ou entraîner localement après toPandas.
  • Distribuer n'est pas toujours plus rapide : sur un extrait qui tient en mémoire, monomachine bat souvent Spark d'un ordre de grandeur.

Module suivant : le réglage fin — partitions, mémoire, brassage — quand l'algorithme est choisi.