En data science, construire un modèle performant ne se limite pas à obtenir de bons résultats sur les données d'entraînement. Un modèle de Machine Learning peut sembler excellent initialement, affichant une précision impressionnante, mais échouer lamentablement lorsqu'il est confronté à de nouvelles données. Imaginez un modèle de prédiction de la satisfaction client, basé sur un sondage historique. Il affiche une performance bluffante, avec un score de 95% sur les données de ce sondage, mais sa capacité à prédire la satisfaction sur un nouveau sondage s'avère catastrophique, chutant à 50%.
Ce phénomène est souvent dû au surapprentissage (overfitting), un ennemi redoutable en Machine Learning. Le surapprentissage est un problème majeur et constitue un obstacle constant dans la création de modèles fiables et généralisables. Pour éviter de tels scénarios, il est impératif d'utiliser une méthode rigoureuse pour évaluer la capacité d'un modèle à généraliser et à faire des prédictions sur des données inconnues.
C'est là que la fonction train_test_split
de scikit-learn entre en jeu, tel un gardien contre le surapprentissage. Cet outil simple, mais puissant, est la première étape cruciale pour garantir que votre modèle est capable de faire des prédictions précises sur des données qu'il n'a jamais vues auparavant. La fonction train_test_split
permet de diviser votre jeu de données en deux sous-ensembles distincts : un ensemble d'entraînement, utilisé pour construire le modèle, et un ensemble de test, utilisé pour évaluer sa performance sur des données non vues.
Pourquoi utiliser train_test_split ? L'Importance de la validation et de la généralisation en machine learning
L'utilisation de train_test_split
est essentielle dans tout projet de Machine Learning, car elle permet d'évaluer la capacité d'un modèle à généraliser, c'est-à-dire sa capacité à faire des prédictions précises sur des données qu'il n'a pas utilisées pendant l'entraînement. Sans cette étape cruciale, vous risquez de surestimer les performances de votre modèle et de vous retrouver avec un modèle qui fonctionne mal en situation réelle, entraînant une perte de temps et de ressources.
Surapprentissage expliqué en détail : le piège de la mémorisation
Le surapprentissage se produit lorsqu'un modèle apprend trop bien les données d'entraînement, au point de mémoriser le bruit et les particularités spécifiques de ces données. Au lieu d'apprendre les tendances générales et les relations sous-jacentes, le modèle s'adapte aux détails idiosyncrasiques des données d'entraînement. Cela conduit à une excellente performance, atteignant parfois un score de 99%, sur les données d'entraînement, mais à une performance médiocre, chutant parfois à 60%, sur les nouvelles données, car il est incapable de généraliser.
Imaginez un modèle polynomial d'ordre très élevé, par exemple d'ordre 10, ajusté à un ensemble de données. Ce modèle peut passer exactement par chaque point de données dans l'ensemble d'entraînement, ce qui donne une erreur d'entraînement de zéro. Cependant, en dehors de ces points, la courbe polynomiale peut osciller de manière erratique et produire des prédictions très imprécises. C'est un exemple typique de surapprentissage, où le modèle a mémorisé les données plutôt que d'apprendre les relations générales.
Les courbes d'apprentissage sont un outil visuel précieux pour détecter le surapprentissage. Elles tracent la performance du modèle, mesurée par exemple par la précision ou le F1-score, sur les ensembles d'entraînement et de validation en fonction de la quantité de données d'entraînement utilisées. Un signe de surapprentissage est une divergence croissante entre les performances sur l'ensemble d'entraînement (qui continuent de s'améliorer) et l'ensemble de validation (qui plafonnent ou diminuent). Cette divergence indique que le modèle s'adapte de plus en plus aux particularités des données d'entraînement, au détriment de sa capacité à généraliser.
Le besoin de données de validation : simuler le monde réel
Évaluer un modèle uniquement sur les données d'entraînement fournit une évaluation biaisée et trompeuse de ses performances réelles. Le modèle a déjà "vu" ces données et a eu l'occasion d'apprendre, voire de mémoriser, les relations spécifiques qui s'y trouvent. Par conséquent, l'évaluation sur les données d'entraînement ne reflète pas la capacité du modèle à généraliser à de nouvelles données, simulant ainsi des conditions réelles d'utilisation.
L'utilisation d'un ensemble de test distinct, composé de données que le modèle n'a jamais vues pendant l'entraînement, permet d'obtenir une estimation plus réaliste et impartiale de ses performances. Le test set simule des données réelles que le modèle rencontrera lorsqu'il sera déployé. Il permet d'évaluer si le modèle a appris les tendances générales ou s'il s'est simplement adapté aux particularités des données d'entraînement. C'est un peu comme un examen final pour s'assurer que le modèle a bien compris la matière.
Le test set doit être utilisé une seule fois, à la fin du processus de développement du modèle, pour obtenir une estimation finale et impartiale de ses performances. Utiliser le test set de manière répétée pour ajuster le modèle conduirait à une forme de surapprentissage sur le test set, ce qui invaliderait son utilité et compromettrait la fiabilité de l'évaluation.
Amélioration du choix du modèle : le meilleur généraliste gagne
Lorsque vous comparez différents modèles, train_test_split
vous permet de choisir celui qui généralise le mieux. Vous pouvez entraîner chaque modèle sur l'ensemble d'entraînement et ensuite évaluer ses performances sur l'ensemble de test, en utilisant des métriques comme la précision, le rappel ou le F1-score. Le modèle qui obtient les meilleures performances sur l'ensemble de test est généralement considéré comme le meilleur modèle, car il a la meilleure capacité à généraliser à de nouvelles données, se comportant ainsi comme un bon généraliste.
Cependant, dans de nombreux cas, vous aurez besoin d'un ensemble de *validation* en plus des ensembles d'entraînement et de test. L'ensemble de validation est utilisé pour optimiser les hyperparamètres du modèle, tels que le taux d'apprentissage, la régularisation ou la profondeur maximale d'un arbre de décision. Les hyperparamètres sont des paramètres qui ne sont pas appris directement à partir des données, mais qui doivent être définis par l'utilisateur. L'ensemble de validation permet d'évaluer la performance du modèle avec différentes configurations d'hyperparamètres et de choisir la configuration qui donne les meilleures performances sans pour autant "contaminer" le test set. Il est donc important de ne pas confondre ces 3 ensembles.
Comment fonctionne train_test_split ? le code et les paramètres essentiels pour une division optimale
La fonction train_test_split
de scikit-learn est simple à utiliser, mais il est important de comprendre ses paramètres et leur impact sur la division des données, pour garantir une division optimale et éviter les pièges courants.
Syntaxe de base et exemple de code : une division en quelques lignes
La syntaxe de base de train_test_split
est la suivante :
from sklearn.model_selection import train_test_split X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)
Où :
-
X
est la matrice des caractéristiques (features), représentant les variables indépendantes. -
y
est le vecteur des étiquettes (labels) ou de la variable cible, représentant la variable dépendante. -
test_size
est la proportion des données à inclure dans l'ensemble de test (par exemple, 0.2 pour 20%). -
random_state
est une valeur entière utilisée pour initialiser le générateur de nombres aléatoires, garantissant la reproductibilité de la division, ce qui est crucial pour la science reproductible.
Voici un exemple de code minimaliste et fonctionnel utilisant des données factices, illustrant la simplicité d'utilisation de train_test_split
:
import numpy as np from sklearn.model_selection import train_test_split # Création de données factices X = np.array([[1, 2], [3, 4], [5, 6], [7, 8], [9, 10]]) y = np.array([0, 1, 0, 1, 0]) # Division des données en ensembles d'entraînement et de test X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.3, random_state=42) print("X_train:n", X_train) print("X_test:n", X_test) print("y_train:n", y_train) print("y_test:n", y_test)
Dans cet exemple, les données sont divisées de sorte que 70% des données sont utilisées pour l'entraînement et 30% pour le test. La valeur de `random_state`, fixée à 42, garantit que la division est la même à chaque exécution, facilitant ainsi la comparaison et la reproductibilité des résultats.
Explication détaillée des paramètres clés : les clés d'une division réussie
test_size et train_size : trouver le juste équilibre
Les paramètres test_size
et train_size
contrôlent la proportion des données qui seront utilisées pour l'ensemble de test et l'ensemble d'entraînement, respectivement. Seul l'un de ces paramètres doit être spécifié; l'autre sera calculé automatiquement, car ils sont complémentaires. Si ni l'un ni l'autre n'est spécifié, test_size
est par défaut à 0.25, ce qui correspond à une division 75/25.
Le choix du ratio de division dépend de la taille de votre ensemble de données. Pour les ensembles de données de grande taille (par exemple, plus de 100 000 échantillons), un ratio de 80/20 (80% pour l'entraînement, 20% pour le test) est souvent approprié, car il permet de conserver une taille suffisante pour l'ensemble d'entraînement tout en ayant un ensemble de test représentatif. Pour les ensembles de données de taille plus modeste, contenant par exemple 1000 échantillons, un ratio de 70/30 ou même 60/40 peut être préférable pour garantir que l'ensemble d'entraînement est suffisamment grand pour entraîner efficacement le modèle. Un ensemble d'entraînement plus grand peut améliorer les performances du modèle, mais réduit la fiabilité de l'évaluation. Le compromis entre la taille de l'ensemble d'entraînement et la fiabilité de l'évaluation doit donc être soigneusement considéré.
random_state : la clé de la reproductibilité
Le paramètre random_state
est essentiel pour la reproductibilité des résultats, un pilier de la science reproductible. train_test_split
utilise un générateur de nombres aléatoires pour diviser les données. En définissant random_state
à une valeur entière spécifique, par exemple 42 ou 123, vous garantissez que la division sera la même à chaque exécution du code. Cela est important pour pouvoir reproduire les résultats, comparer différents modèles ou différentes configurations d'hyperparamètres, et assurer la transparence de votre travail.
Si vous ne définissez pas random_state
, la division sera différente à chaque exécution, ce qui peut rendre difficile la comparaison des résultats et compromettre la reproductibilité de votre analyse. Utiliser 42 est une convention, inspirée par le roman "Le Guide du voyageur galactique", mais n'importe quel entier fera l'affaire, tant qu'il reste constant.
shuffle : mélanger pour éviter les biais
Le paramètre shuffle
contrôle si les données sont mélangées avant d'être divisées. Par défaut, shuffle
est défini sur True
, ce qui signifie que les données sont mélangées aléatoirement avant la division. Le mélange des données est généralement nécessaire pour éviter les biais dus à l'ordre des données, garantissant ainsi une représentation équilibrée dans les ensembles d'entraînement et de test.
Par exemple, si vos données sont triées par classe, une situation fréquente dans les ensembles de données réels, la division sans mélange pourrait entraîner un ensemble d'entraînement contenant principalement des échantillons d'une classe et un ensemble de test contenant principalement des échantillons d'une autre classe. Cela conduirait à une évaluation biaisée des performances du modèle, car il serait entraîné et évalué sur des distributions de données différentes.
Il existe cependant des situations où vous ne devez pas mélanger les données. L'exemple le plus courant est celui des séries temporelles, telles que les données boursières, les mesures de température ou les enregistrements de capteurs. Dans les séries temporelles, l'ordre des données est intrinsèquement important, et le mélange des données détruirait la structure temporelle et rendrait le modèle inutile, car il ne serait plus capable d'apprendre les tendances et les dépendances temporelles.
stratify : préserver les proportions pour les classes déséquilibrées
Le paramètre stratify
est particulièrement important pour les problèmes de classification avec des classes déséquilibrées, une situation courante dans de nombreux domaines, tels que la détection de fraude, le diagnostic médical ou la maintenance prédictive. Les classes déséquilibrées se produisent lorsque certaines classes ont beaucoup plus d'échantillons que d'autres. Par exemple, dans un problème de détection de fraude, il peut y avoir 99% de transactions légitimes et seulement 1% de transactions frauduleuses.
Si vous ne stratifiez pas la division, il est possible que l'ensemble de test ne contienne aucun échantillon de la classe minoritaire (par exemple, les transactions frauduleuses). Cela conduirait à une évaluation biaisée des performances du modèle, car il ne serait pas testé sur la classe qui est la plus importante à prédire correctement, compromettant ainsi sa capacité à détecter les fraudes.
- Comprendre l'importance des données manquantes.
- Choisir une méthode d'imputation appropriée.
- Évaluer l'impact de l'imputation sur les performances du modèle.
En définissant stratify=y
, vous demandez à train_test_split
de maintenir les proportions des classes dans les ensembles d'entraînement et de test, garantissant ainsi que chaque classe est représentée de manière adéquate dans les deux ensembles. Cela garantit que l'ensemble de test contient suffisamment d'échantillons de chaque classe pour permettre une évaluation réaliste des performances du modèle. Voici un exemple de code :
from sklearn.model_selection import train_test_split import numpy as np # Création d'un dataset déséquilibré X = np.array([[1, 2], [3, 4], [5, 6], [7, 8], [9, 10], [11, 12], [13, 14], [15, 16], [17, 18], [19, 20]]) y = np.array([0, 0, 0, 0, 0, 0, 0, 0, 0, 1]) # Classe 0 est majoritaire, Classe 1 minoritaire # Division avec stratification X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42, stratify=y) print("y_train:", y_train) print("y_test:", y_test)
Dans cet exemple, vous pouvez observer que la proportion de la classe 1 (la classe minoritaire) est de 10% dans l'ensemble de données original. En utilisant `stratify=y`, on s'assure que cette proportion est maintenue dans les ensembles d'entraînement et de test, ce qui permet une évaluation plus fiable des performances du modèle sur la classe minoritaire.
Scénarios avancés et bonnes pratiques : au-delà de la division de base
Bien que train_test_split
soit un outil simple, il existe des scénarios plus avancés où il est important de prendre des précautions supplémentaires pour garantir une division appropriée des données et optimiser les performances du modèle.
Gestion des données temporelles : respecter l'ordre chronologique
Comme mentionné précédemment, l'utilisation de train_test_split
avec shuffle=True
est inappropriée pour les séries temporelles. En effet, le mélange des données détruit la structure temporelle, ce qui rend le modèle incapable d'apprendre les tendances temporelles et de faire des prédictions significatives.
Au lieu de cela, vous devez diviser les données temporelles de manière chronologique, en utilisant les données les plus anciennes pour l'entraînement et les données les plus récentes pour le test. Cela garantit que le modèle est évalué sur sa capacité à prédire le futur à partir du passé, simulant ainsi des conditions réelles de prédiction.
Il existe plusieurs méthodes alternatives pour diviser les données temporelles. L'une d'elles est la division chronologique simple, où vous divisez les données en deux ensembles en fonction d'une date de coupure, par exemple en utilisant les données jusqu'à 2022 pour l'entraînement et les données de 2023 pour le test. Une autre méthode est la validation croisée temporelle, où vous utilisez plusieurs divisions train/test, chacune utilisant une période de temps différente pour l'entraînement et le test, permettant ainsi une évaluation plus robuste des performances du modèle.
Validation croisée (cross-validation) : une évaluation plus robuste
La validation croisée est une technique plus robuste et fiable que train_test_split
pour estimer la performance du modèle. Au lieu d'utiliser une seule division train/test, la validation croisée utilise plusieurs divisions différentes et calcule la performance moyenne sur toutes les divisions, fournissant ainsi une estimation plus stable et généralisable.
Dans la validation croisée K-fold, les données sont divisées en K plis (sous-ensembles) égaux. Pour chaque pli, le modèle est entraîné sur les K-1 autres plis et évalué sur le pli restant. La performance finale est la moyenne des performances sur tous les plis. Par exemple, avec une validation croisée 5-fold, les données sont divisées en 5 plis, et le modèle est entraîné et évalué 5 fois, chaque fois en utilisant un pli différent comme ensemble de test.
StratifiedKFold
est une variante de K-fold qui garantit que les proportions des classes sont maintenues dans chaque pli. Cela est particulièrement important pour les problèmes de classification avec des classes déséquilibrées, car cela permet d'éviter une sous-représentation de la classe minoritaire dans certains plis.
- Choisir une stratégie de validation croisée adaptée à votre problème.
- Interpréter les résultats de la validation croisée.
- Utiliser la validation croisée pour comparer différents modèles.
Scikit-learn fournit les fonctions cross_val_score
et cross_validate
pour faciliter l'utilisation de la validation croisée. Voici un exemple :
from sklearn.model_selection import cross_val_score from sklearn.linear_model import LogisticRegression import numpy as np # Exemple avec LogisticRegression et validation croisée X = np.array([[1, 2], [3, 4], [5, 6], [7, 8], [9, 10]]) y = np.array([0, 1, 0, 1, 0]) model = LogisticRegression() scores = cross_val_score(model, X, y, cv=5) # cv=5 pour 5-fold cross-validation print("Cross-validation scores:", scores) print("Mean cross-validation score:", scores.mean())
Validation set (ensemble de validation) : optimiser les hyperparamètres
Comme mentionné précédemment, un ensemble de validation distinct est nécessaire pour l'optimisation des hyperparamètres. Lorsque vous optimisez les hyperparamètres, vous évaluez la performance du modèle avec différentes configurations d'hyperparamètres et choisissez la configuration qui donne les meilleures performances sur l'ensemble de validation.
Si vous utilisez l'ensemble de test pour optimiser les hyperparamètres, vous risquez de surapprendre sur l'ensemble de test, ce qui invaliderait son utilité pour l'évaluation finale des performances du modèle. C'est pourquoi il est important d'utiliser un ensemble de validation distinct pour l'optimisation des hyperparamètres, garantissant ainsi une évaluation impartiale des performances du modèle.
Pour créer un ensemble de validation, vous pouvez diviser l'ensemble d'entraînement en deux sous-ensembles : un ensemble d'entraînement pour l'entraînement du modèle et un ensemble de validation pour l'optimisation des hyperparamètres. Cela peut être fait en utilisant train_test_split
deux fois : une fois pour diviser les données originales en ensembles d'entraînement et de test, puis une deuxième fois pour diviser l'ensemble d'entraînement en ensembles d'entraînement et de validation, créant ainsi les trois ensembles nécessaires: entraînement, validation et test.
Pré-traitement des données : éviter la fuite d'informations
Il est important d'appliquer le pré-traitement des données (normalisation, standardisation, encodage, etc.) *après* avoir effectué la division train/test. Appliquer le pré-traitement avant la division peut introduire une fuite d'informations du test set vers le training set, ce qui conduirait à une évaluation biaisée et optimiste des performances du modèle, car il aurait eu accès à des informations du futur.
Par exemple, si vous normalisez les données avant la division, vous utiliserez des informations de l'ensemble de test pour normaliser l'ensemble d'entraînement, ce qui donnerait au modèle un avantage injuste lors de l'entraînement. Il est donc crucial d'éviter cette fuite d'informations pour obtenir une évaluation réaliste.
Pour éviter cela, vous devez appliquer le pré-traitement séparément à l'ensemble d'entraînement et à l'ensemble de test. Scikit-learn fournit la classe Pipeline
pour faciliter cette tâche. Pipeline
permet d'encapsuler le pré-traitement et le modèle en un seul objet, ce qui garantit que le pré-traitement est appliqué correctement aux ensembles d'entraînement et de test, évitant ainsi la fuite d'informations et simplifiant le processus.
from sklearn.model_selection import train_test_split from sklearn.preprocessing import StandardScaler from sklearn.linear_model import LogisticRegression from sklearn.pipeline import Pipeline import numpy as np # Création de données factices X = np.array([[1, 2], [3, 4], [5, 6], [7, 8], [9, 10]]) y = np.array([0, 1, 0, 1, 0]) # Division en ensembles d'entraînement et de test X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42) # Création d'un pipeline avec StandardScaler et LogisticRegression pipeline = Pipeline([ ('scaler', StandardScaler()), ('classifier', LogisticRegression()) ]) # Entraînement du pipeline sur l'ensemble d'entraînement pipeline.fit(X_train, y_train) # Évaluation du pipeline sur l'ensemble de test accuracy = pipeline.score(X_test, y_test) print("Accuracy:", accuracy)
Gérer les données déséquilibrées : donner une voix aux minorités
Comme mentionné précédemment, il est important d'utiliser stratify=y
pour éviter d'avoir des classes sous-représentées dans le test set. Cela garantit que l'ensemble de test contient suffisamment d'échantillons de chaque classe pour permettre une évaluation réaliste des performances du modèle, en particulier sur la classe minoritaire, souvent la plus importante à prédire correctement.
En plus de `stratify`, vous pouvez également utiliser des techniques de suréchantillonnage (SMOTE, ADASYN) et sous-échantillonnage (RandomUnderSampler, TomekLinks) pour équilibrer les classes dans le *training set* (après la division). Ces techniques consistent à créer des copies d'échantillons de la classe minoritaire (suréchantillonnage) ou à supprimer des échantillons de la classe majoritaire (sous-échantillonnage) pour équilibrer les classes et améliorer les performances du modèle sur la classe minoritaire.
Alternatives à train_test_split et quand les utiliser : choisir la bonne méthode
Bien que train_test_split
soit un outil précieux et largement utilisé, il existe des alternatives qui peuvent être plus appropriées dans certaines situations spécifiques, en fonction de la taille et de la structure de votre ensemble de données.
Leave-one-out Cross-Validation (LOOCV) et Leave-P-Out Cross-Validation (LPOCV) : pour les petits ensembles de données
LOOCV et LPOCV sont des techniques de validation croisée où chaque échantillon (LOOCV) ou chaque groupe de P échantillons (LPOCV) est utilisé comme ensemble de test, tandis que les échantillons restants sont utilisés comme ensemble d'entraînement. Ces méthodes sont particulièrement adaptées aux petits ensembles de données, contenant par exemple moins de 50 échantillons, où il est important d'utiliser autant de données que possible pour l'entraînement.
Cependant, elles peuvent être coûteuses en termes de calcul, car elles nécessitent d'entraîner et d'évaluer le modèle un grand nombre de fois. Par exemple, pour un dataset de 100 échantillons, LOOCV nécessitera d'entraîner et d'évaluer le modèle 100 fois, ce qui peut prendre un temps considérable.
Groupkfold : pour les données groupées
GroupKFold
est une variante de K-fold qui est utilisée lorsque les observations sont groupées (par exemple, patients dans une étude médicale, étudiants dans une classe). GroupKFold
garantit que les observations d'un même groupe restent dans le même ensemble (entraînement ou test), évitant ainsi une fuite d'informations et assurant une évaluation plus réaliste.
Cela est important pour éviter une fuite d'informations entre l'ensemble d'entraînement et l'ensemble de test. Par exemple, si vous avez des données sur les patients d'une étude médicale, il est important de s'assurer que tous les échantillons d'un même patient se trouvent dans le même ensemble, car les échantillons d'un même patient sont susceptibles d'être corrélés.
Timeseriessplit : pour les séries temporelles
Comme mentionné précédemment, TimeSeriesSplit
est la solution pour les séries temporelles, où l'ordre des données est crucial. Elle crée des ensembles d'entraînement et de test où les données de test sont toujours postérieures aux données d'entraînement, préservant ainsi l'ordre temporel des données et permettant d'évaluer la capacité du modèle à prédire le futur à partir du passé.
Erreurs courantes à éviter avec train_test_split : les pièges à déjouer
Il est important d'éviter certaines erreurs courantes lors de l'utilisation de train_test_split
pour garantir une division appropriée et une évaluation fiable des performances du modèle.
Oublier de fixer random_state : compromettre la reproductibilité
Oublier de fixer random_state
conduit à des résultats non reproductibles. La division des données sera différente à chaque exécution, ce qui peut rendre difficile la comparaison des résultats et compromettre la transparence de votre travail.
Appliquer le pré-traitement avant la division : introduire une fuite d'informations
Appliquer le pré-traitement avant la division introduit une fuite de données, ce qui conduit à une évaluation biaisée et optimiste des performances du modèle, car il aurait eu accès à des informations du futur.
Ne pas utiliser stratify avec des classes déséquilibrées : biaiser l'évaluation
Ne pas utiliser stratify
avec des classes déséquilibrées conduit à une évaluation biaisée des performances du modèle, en particulier sur la classe minoritaire, souvent la plus importante à prédire correctement.
Utiliser train_test_split avec shuffle=true pour les séries temporelles : détruire la structure temporelle
Utiliser train_test_split
avec shuffle=True
pour les séries temporelles conduit à une fuite de données et à des prédictions irréalistes, car cela détruit la structure temporelle des données.
La fonction `train_test_split` de scikit-learn est un outil fondamental et indispensable pour créer des modèles de Machine Learning robustes et généralisables. En utilisant cette fonction correctement et en évitant les erreurs courantes, vous pouvez éviter le surapprentissage, évaluer la performance réelle de vos modèles et choisir le meilleur modèle pour votre problème, augmentant ainsi vos chances de succès.