VotingClassifier dans sсikit-learn: construction et optimisation d'un ensemble de modèles de classification

Dans le cadre de la mise en œuvre de la grande tâche de l'analyse des sentiments (analyse des critiques), j'ai décidé de consacrer un certain temps à une étude supplémentaire de son élément distinct - en utilisant le VotingClassifier du module sklearn.ensemble comme outil pour construire un ensemble de modèles de classification et améliorer la qualité finale des prédictions. Pourquoi est-ce important et quelles sont les nuances?



Il arrive souvent qu'au cours de la résolution du problème appliqué de l'analyse des données, il ne soit pas immédiatement évident (ou pas du tout évident) quel modèle de formation est le mieux adapté. Une solution peut être de sélectionner le modèle le plus populaire et / ou intuitivement approprié en fonction de la nature des données disponibles. Dans ce cas, les paramètres du modèle sélectionné sont optimisés (par exemple, via GridSearchCV) et il est utilisé dans le travail. Une autre approche peut consister à utiliser un ensemble de modèles lorsque les résultats de plusieurs d'entre eux sont simultanément impliqués dans la formation du résultat final. Je dirai tout de suite que le but de l'article n'est pas de décrire les avantages d'utiliser un ensemble de modèles ou les principes de sa construction (cela peut être trouvé ici ), mais plutôt dans une approche appliquée séparément pour résoudre le problème en utilisant un exemple spécifique et en analysant les nuances qui surviennent lors d'une telle solution.

L'énoncé du problème global est le suivant : seulement 100 avis ont été donnés sur les téléphones mobiles comme échantillon de test, et nous avons besoin d'un modèle pré-formé qui montrera le meilleur résultat sur ces 100 avis - à savoir, il déterminera si l'avis est positif ou négatif. Une difficulté supplémentaire, résultant des conditions du problème, est le manque d'un échantillon de formation. Pour surmonter cette difficulté avec l'aide de la bibliothèque Beautiful Soup, 10 000 avis sur les téléphones portables et leurs notes sur l'un des sites russes ont été analysés avec succès.

Sautant les étapes d'analyse, de prétraitement des données et d'étude de leur structure initiale , nous passons au moment où il y a:

  • échantillon de formation, composé de 10 000 avis téléphoniques, chaque avis est marqué binaire (positif ou négatif). Balisage pour la définition des avis avec des notes 1 à 3 négatives et des notes 4 à 5 positives.
  • à l'aide de Count Vectorizer, les données sont présentées sous une forme adaptée à la formation de modèles de classificateurs

Comment décider quel modèle vous convient le mieux? Nous n'avons pas la possibilité d'itérer manuellement les modèles, car un échantillon de test de seulement 100 avis présente un risque énorme qu'un modèle soit tout simplement mieux adapté à cet échantillon de test, mais si vous l'utilisez sur un échantillon supplémentaire qui nous est caché ou dans une «bataille», le résultat sera inférieur à la moyenne.

Pour résoudre ce problème , la bibliothèque Scikit-learn possède un module VotingClassifier , qui est un excellent outil pour utiliser plusieurs modèles d'apprentissage machine différents et différents et les combiner en un seul classificateur. Cela réduit le risque de recyclage, ainsi qu'une interprétation incorrecte des résultats d'un modèle particulier. Le module VotingClassifier est importé avec la commande suivante :
from sklearn.ensemble import VotingClassifier

Détails pratiques lors de l'utilisation de ce module:

1) La première chose et la plus importante est de savoir comment obtenir une seule prédiction prise du classificateur combiné après avoir reçu les prédictions de chacun des modèles qui y sont inclus. Parmi les paramètres VotingClassifier, il y a un paramètre de vote avec deux valeurs possibles: «dur» et «doux».

1.1) Dans le premier cas, la réponse finale du classificateur conjoint correspondra à «l'avis» de la majorité de ses membres. Par exemple, votre classificateur combiné utilise des données de trois modèles différents. Deux d'entre eux sur une observation spécifique prédisent la réponse "rétroaction positive", le troisième - "rétroaction négative". Ainsi, pour cette observation, la prédiction finale sera une «rétroaction positive», puisque nous avons 2 - «pour» et 1 «contre».

1.2) Dans le deuxième cas, c'est-à-dire lorsque vous utilisez la valeur «douce» du paramètre de vote , il existe un «vote» à part entière et une pondération des prédictions du modèle pour chaque classe, de sorte que la réponse finale du classificateur combiné est l'argmax de la somme des probabilités prédites. IMPORTANT! Afin de pouvoir utiliser une telle méthode de «vote», chaque classificateur de ceux inclus dans votre ensemble doit prendre en charge la méthode Predict_Proba () pour obtenir une estimation quantitative de la probabilité d'occurrence dans chacune des classes. Veuillez noter que tous les modèles de classificateurs ne prennent pas en charge cette méthode et, par conséquent, peuvent être utilisés dans le cadre de VotingClassifier lors de l'utilisation de la méthode des probabilités pondérées (vote doux).

Regardons un exemple : il y a trois classificateurs et deux classes d'avis: positifs et négatifs. Chaque classificateur, par le biais de la méthode Predict_Proba, donnera une certaine valeur de probabilité (p), avec laquelle une observation particulière est affectée par lui à la classe 1 et, en conséquence, avec une probabilité (1-p) à la classe deux. Le classificateur combiné, après avoir reçu une réponse de chacun des modèles, effectue la pondération des estimations obtenues et donne le résultat final obtenu comme

$$ affichage $$ max (w1 * p1 + w2 * p1 + w3 * p1, w1 * p2 + w2 * p2 + w3 * p3) $$ affichage $$

, où w1, w2, w3 sont les poids de vos classificateurs inclus dans l'ensemble, ayant par défaut des poids égaux, et p1, p2 est l'évaluation de l'appartenance à la classe 1 ou à la classe 2 de chacun d'eux. Veuillez également noter que les poids des classificateurs lors de l'utilisation du vote souple peuvent être modifiés à l'aide du paramètre de poids, donc l'appel du module devrait ressembler à ceci:
... = VotingClassifier(estimators=[('..', clf1), ('..', clf2), ('...', clf3)], voting='soft', weights=[*,*,*]) , où les astérisques peuvent indiquer les poids requis pour chaque modèle.

2) La possibilité d'utiliser simultanément le module VotingClassifier et GridSearch pour optimiser les hyperparamètres de chacun des classificateurs inclus dans l'ensemble.

Lorsque vous prévoyez d'utiliser un ensemble et que vous souhaitez que les modèles qui y sont inclus soient optimisés, vous pouvez déjà utiliser GridSearch sur le classificateur unifié. Et le code ci-dessous montre comment vous pouvez travailler avec les modèles qui y sont inclus (régression logistique, Bayes naïfs, descente de gradient stochastique) tout en restant dans le cadre du classificateur unifié (VotingClassifier):

 clf1 = LogisticRegression() clf2 = MultinomialNB() clf3 = SGDClassifier(max_iter=1000, loss='log') eclf = VotingClassifier(estimators=[ ('lr', clf1), ('nb', clf2),('sgd', clf3)], voting='hard') #      (hard voting), . . 1.1 <b>params = {'lr__C' : [0.5,1,1.5], 'lr__class_weight': [None,'balanced'], 'nb__alpha' : [0.1,1,2], 'sgd__penalty' : ['l2', 'l1'], 'sgd__alpha': [0.0001,0.001,0.01]} </b> #       ,  ,     grid = GridSearchCV(estimator=eclf, param_grid=params, cv=5, scoring='accuracy', n_jobs=-1) grid = grid.fit(data_messages_vectorized, df_texts['Binary_Rate']) #    ,      5      

Ainsi, le dictionnaire de paramètres doit être défini de sorte que lorsque vous y accédez via GridSearch, vous pouvez déterminer quel paramètre dans l'ensemble de modèles fait référence à un paramètre dont vous souhaitez optimiser la valeur.

C'est tout ce que vous devez savoir pour utiliser pleinement l'outil VotingClassifier comme un moyen de construire un ensemble de modèles et de l'optimiser. Regardons les résultats:

  print grid.best_params_ {'lr__class_weight': 'balanced', 'sgd__penalty': 'l1', 'nb__alpha': 1, 'lr__C': 1, 'sgd__alpha': 0.001} 

Les valeurs optimales des paramètres sont trouvées, il reste à comparer les résultats des travaux pour l'ensemble des classificateurs (VotingClassifier) ​​avec les paramètres optimaux, nous procéderons à une validation croisée sur l'échantillon d'apprentissage et comparerons les modèles avec les paramètres optimaux et l'ensemble constitué d'eux:

 for clf, label in zip([clf1, clf2, clf3, eclf], ['Logistic Regression', 'Naive Bayes', 'SGD', 'Ensemble_HardVoting']): scores = cross_val_score(clf, data_messages_vectorized, df_texts['Binary_Rate'], cv=3, scoring='accuracy') print("Accuracy: %0.2f (+/- %0.2f) [%s]" % (scores.mean(), scores.std(), label)) 

Le résultat final:

Précision: 0,75 (± 0,02) [régression logistique]
Précision: 0,79 (± 0,02) [Bayes naïfs]
Précision: 0,79 (± 0,02) [SGD]
Précision: 0,79 (± 0,02) [Ensemble_HardVoting]

Comme vous pouvez le voir, les modèles se sont montrés un peu différemment dans l'échantillon d'apprentissage (avec des paramètres standard, cette différence était plus notable). De plus, la valeur totale (selon la métrique de précision) de l'ensemble ne doit pas dépasser la meilleure valeur des modèles qui y sont inclus, car l'ensemble est plutôt un modèle plus stable, capable de montrer ± un résultat similaire dans l'ensemble de test et dans la «bataille», ce qui signifie réduire le risque de recyclage, l'adaptation à l'ensemble d'entraînement et d'autres classificateurs de problèmes liés à l'entraînement. Bonne chance dans la résolution des problèmes appliqués et merci de votre attention!

PS Étant donné les spécificités et les règles de publication dans le bac à sable, je ne peux pas fournir de lien vers github et le code source pour l'analyse donnée dans cet article, ainsi que des liens vers Kaggle, dans le cadre du concours InClass qui a fourni un ensemble de test et des outils pour vérifier les modèles dessus. Je peux seulement dire que cet ensemble a battu de manière significative la ligne de base et a pris sa place légitime dans le classement après avoir vérifié un ensemble de tests. J'espère que dans les publications suivantes je pourrai partager.

Source: https://habr.com/ru/post/fr430280/


All Articles