Méthodes d'ensemble : des techniques élégantes pour produire de meilleurs résultats d'apprentissage automatique
Publié: 2022-03-11Les méthodes d'ensemble sont des techniques qui créent plusieurs modèles, puis les combinent pour produire des résultats améliorés. Les méthodes d'ensemble produisent généralement des solutions plus précises qu'un modèle unique. Cela a été le cas dans un certain nombre de concours d'apprentissage automatique, où les solutions gagnantes utilisaient des méthodes d'ensemble. Lors du populaire concours Netflix, le gagnant a utilisé une méthode d'ensemble pour mettre en œuvre un puissant algorithme de filtrage collaboratif. Un autre exemple est KDD 2009 où le gagnant a également utilisé des méthodes d'ensemble. Vous pouvez également trouver les gagnants qui ont utilisé ces méthodes dans les concours Kaggle, par exemple voici l'interview du gagnant du concours CrowdFlower.
Il est important que nous comprenions quelques terminologies avant de continuer avec cet article. Tout au long de l'article, j'ai utilisé le terme "modèle" pour décrire la sortie de l'algorithme qui s'est entraîné avec des données. Ce modèle est ensuite utilisé pour faire des prédictions. Cet algorithme peut être n'importe quel algorithme d'apprentissage automatique tel que la régression logistique, l'arbre de décision, etc. Ces modèles, lorsqu'ils sont utilisés comme entrées de méthodes d'ensemble, sont appelés "modèles de base".
Dans cet article de blog, je couvrirai les méthodes d'ensemble pour la classification et décrirai certaines méthodes d'ensemble largement connues : vote, empilement, bagging et boosting.
Méthodes d'ensemble basées sur le vote et la moyenne
Le vote et la moyenne sont deux des méthodes d'ensemble les plus simples. Ils sont à la fois faciles à comprendre et à mettre en œuvre. Le vote est utilisé pour la classification et la moyenne est utilisée pour la régression.
Dans les deux méthodes, la première étape consiste à créer plusieurs modèles de classification/régression à l'aide d'un ensemble de données d'apprentissage. Chaque modèle de base peut être créé en utilisant différentes divisions du même ensemble de données d'apprentissage et du même algorithme, ou en utilisant le même ensemble de données avec différents algorithmes, ou toute autre méthode. Le pseudo-code Python suivant montre l'utilisation du même jeu de données d'entraînement avec différents algorithmes.
train = load_csv("train.csv") target = train["target"] train = train.drop("target") test = load_csv("test.csv") algorithms = [logistic_regression, decision_tree_classification, ...] #for classification algorithms = [linear_regression, decision_tree_regressor, ...] #for regression predictions = matrix(row_length=len(target), column_length=len(algorithms)) for i,algorithm in enumerate(algorithms): predictions[,i] = algorithm.fit(train, target).predict(test)
Selon le pseudocode ci-dessus, nous avons créé des prédictions pour chaque modèle et les avons enregistrées dans une matrice appelée prédictions où chaque colonne contient les prédictions d'un modèle.
Vote à la majorité
Chaque modèle fait une prédiction (votes) pour chaque instance de test et la prédiction de sortie finale est celle qui reçoit plus de la moitié des votes. Si aucune des prédictions n'obtient plus de la moitié des votes, on peut dire que la méthode d'ensemble ne peut pas faire de prédiction stable pour cette instance. Bien qu'il s'agisse d'une technique largement utilisée, vous pouvez essayer la prédiction la plus votée (même si elle représente moins de la moitié des votes) comme prédiction finale. Dans certains articles, vous verrez peut-être cette méthode appelée « vote à la pluralité ».
Vote pondéré
Contrairement au vote majoritaire, où chaque modèle a les mêmes droits, on peut augmenter l'importance d'un ou plusieurs modèles. Dans le vote pondéré, vous comptez plusieurs fois la prédiction des meilleurs modèles. C'est à vous de trouver un ensemble raisonnable de poids.
Moyenne simple
Dans la méthode de moyenne simple, pour chaque instance d'ensemble de données de test, les prédictions moyennes sont calculées. Cette méthode réduit souvent le surajustement et crée un modèle de régression plus fluide. Le pseudo-code suivant illustre cette méthode simple de calcul de la moyenne :
final_predictions = [] for row_number in len(predictions): final_predictions.append( mean(prediction[row_number, ]) )
Moyenne pondérée
La moyenne pondérée est une version légèrement modifiée de la moyenne simple, où la prédiction de chaque modèle est multipliée par le poids, puis leur moyenne est calculée. Le pseudo-code suivant montre la moyenne pondérée :
weights = [..., ..., ...] #length is equal to len(algorithms) final_predictions = [] for row_number in len(predictions): final_predictions.append( mean(prediction[row_number, ]*weights) )
Empiler plusieurs modèles d'apprentissage automatique
L'empilement, également connu sous le nom de généralisation empilée, est une méthode d'ensemble dans laquelle les modèles sont combinés à l'aide d'un autre algorithme d'apprentissage automatique. L'idée de base est de former des algorithmes d'apprentissage automatique avec un ensemble de données d'apprentissage, puis de générer un nouvel ensemble de données avec ces modèles. Ensuite, ce nouvel ensemble de données est utilisé comme entrée pour l'algorithme d'apprentissage automatique du combinateur.
Le pseudocode d'une procédure d'empilement est résumé comme suit :
base_algorithms = [logistic_regression, decision_tree_classification, ...] #for classification stacking_train_dataset = matrix(row_length=len(target), column_length=len(algorithms)) stacking_test_dataset = matrix(row_length=len(test), column_length=len(algorithms)) for i,base_algorithm in enumerate(base_algorithms): stacking_train_dataset[,i] = base_algorithm.fit(train, target).predict(train) stacking_test_dataset[,i] = base_algorithm.predict(test) final_predictions = combiner_algorithm.fit(stacking_train_dataset, target).predict(stacking_test_dataset)
Comme vous pouvez le voir dans le pseudocode ci-dessus, l'ensemble de données d'apprentissage pour l'algorithme de combinateur est généré à l'aide des sorties des algorithmes de base. Dans le pseudocode, l'algorithme de base est généré à l'aide d'un ensemble de données d'apprentissage, puis le même ensemble de données est à nouveau utilisé pour faire des prédictions. Mais comme nous le savons, dans le monde réel, nous n'utilisons pas le même ensemble de données d'entraînement pour la prédiction, donc pour surmonter ce problème, vous pouvez voir certaines implémentations d'empilement où l'ensemble de données d'entraînement est divisé. Ci-dessous, vous pouvez voir un pseudocode dans lequel l'ensemble de données d'entraînement est divisé avant d'entraîner les algorithmes de base :

base_algorithms = [logistic_regression, decision_tree_classification, ...] #for classification stacking_train_dataset = matrix(row_length=len(target), column_length=len(algorithms)) stacking_test_dataset = matrix(row_length=len(test), column_length=len(algorithms)) for i,base_algorithm in enumerate(base_algorithms): for trainix, testix in split(train, k=10): #you may use sklearn.cross_validation.KFold of sklearn library stacking_train_dataset[testcv,i] = base_algorithm.fit(train[trainix], target[trainix]).predict(train[testix]) stacking_test_dataset[,i] = base_algorithm.fit(train).predict(test) final_predictions = combiner_algorithm.fit(stacking_train_dataset, target).predict(stacking_test_dataset)
Agrégation Bootstrap
Le nom Bootstrap Aggregating, également connu sous le nom de « Bagging », résume les éléments clés de cette stratégie. Dans l'algorithme de bagging, la première étape consiste à créer plusieurs modèles. Ces modèles sont générés à l'aide du même algorithme avec des sous-échantillons aléatoires de l'ensemble de données qui sont tirés de l'ensemble de données d'origine de manière aléatoire avec la méthode d'échantillonnage bootstrap. Dans l'échantillonnage bootstrap, certains exemples originaux apparaissent plus d'une fois et certains exemples originaux ne sont pas présents dans l'échantillon. Si vous souhaitez créer un sous-ensemble de données avec m éléments, vous devez sélectionner un élément aléatoire de l'ensemble de données d'origine m fois. Et si l'objectif est de générer n ensemble de données, vous suivez cette étape n fois.
À la fin, nous avons n ensembles de données où le nombre d'éléments dans chaque ensemble de données est m. Le pseudo-code Python suivant montre l'échantillonnage bootstrap :
def bootstrap_sample(original_dataset, m): sub_dataset = [] for i in range(m): sub_dataset.append( random_one_element(original_dataset) ) return sub_dataset
La deuxième étape du bagging consiste à agréger les modèles générés. Des méthodes bien connues, telles que le vote et la moyenne, sont utilisées à cette fin.
Le pseudocode global ressemble à ceci :
def bagging(n, m, base_algorithm, train_dataset, target, test_dataset): predictions = matrix(row_length=len(target), column_length=n) for i in range(n): sub_dataset = bootstrap_sample(train_dataset, m) predictions[,i] = base_algorithm.fit(original_dataset, target).predict(test_dataset) final_predictions = voting(predictions) # for classification final_predictions = averaging(predictions) # for regression return final_predictions
Dans l'ensachage, chaque sous-échantillon peut être généré indépendamment l'un de l'autre. Ainsi, la génération et la formation peuvent se faire en parallèle.
Vous pouvez également trouver l'implémentation de la stratégie de bagging dans certains algorithmes. Par exemple, l'algorithme Random Forest utilise la technique de bagging avec quelques différences. Random Forest utilise une sélection aléatoire de caractéristiques et son algorithme de base est un algorithme d'arbre de décision.
Boosting : Convertir les modèles faibles en modèles forts
Le terme "boosting" est utilisé pour décrire une famille d'algorithmes capables de convertir des modèles faibles en modèles forts. Le modèle est faible s'il a un taux d'erreur substantiel, mais la performance n'est pas aléatoire (entraînant un taux d'erreur de 0,5 pour la classification binaire). Le boosting construit progressivement un ensemble en entraînant chaque modèle avec le même jeu de données mais où les poids des instances sont ajustés en fonction de l'erreur de la dernière prédiction. L'idée principale est de forcer les modèles à se concentrer sur les instances difficiles. Contrairement au bagging, le boosting est une méthode séquentielle, et vous ne pouvez donc pas utiliser d'opérations parallèles ici.
La procédure générale de l'algorithme de boosting est définie comme suit :
def adjust_dataset(_train, errors): #create a new dataset by using the hardest instances ix = get_highest_errors_index(train) return concat(_train[ix], random_select(train)) models = [] _train = random_select(train) for i in range(n): #n rounds model = base_algorithm.fit(_train) predictions = model.predict(_train) models.append(model) errors = calculate_error(predictions) _train = adjust_dataset(_train, errors) final_predictions = combine(models, test)
La fonction adjust_dataset renvoie un nouvel ensemble de données contenant les instances les plus difficiles, qui peuvent ensuite être utilisées pour forcer l'algorithme de base à apprendre.
Adaboost est un algorithme largement connu qui est une méthode de boosting. Les fondateurs d'Adaboost ont remporté le prix Godel pour leur travail. Généralement, l'algorithme d'arbre de décision est préféré comme algorithme de base pour Adaboost et dans la bibliothèque sklearn, l'algorithme de base par défaut pour Adaboost est l'arbre de décision (AdaBoostRegressor et AdaBoostClassifier). Comme nous l'avons vu dans le paragraphe précédent, la même méthode incrémentale s'applique pour Adaboost. Les informations recueillies à chaque étape de l'algorithme AdaBoost sur la "dureté" de chaque échantillon d'apprentissage sont introduites dans le modèle. L'étape « ajustement de l'ensemble de données » est différente de celle décrite ci-dessus et l'étape « combinaison de modèles » est calculée en utilisant un vote pondéré.
Conclusion
Bien que les méthodes d'ensemble puissent vous aider à gagner des compétitions d'apprentissage automatique en concevant des algorithmes sophistiqués et en produisant des résultats avec une grande précision, elles ne sont souvent pas préférées dans les industries où l'interprétabilité est plus importante. Néanmoins, l'efficacité de ces méthodes est indéniable et leurs avantages dans des applications appropriées peuvent être considérables. Dans des domaines tels que la santé, même la plus petite amélioration de la précision des algorithmes d'apprentissage automatique peut être quelque chose de vraiment précieux.
- Une introduction à la théorie de l'apprentissage automatique et à ses applications : un didacticiel visuel avec des exemples
- Machines et confiance : comment atténuer les biais de l'IA