[PYTHON] J'ai essayé de bien le comprendre en implémentant l'algorithme Adaboost en machine learning (+ j'ai approfondi ma compréhension du calcul de tableaux)

introduction

Voici un résumé du boosting d'origine tel que XGBoost, qui est souvent utilisé dans Kaggle. J'aimerais comprendre Adaboost tout en l'implémentant parmi les algorithmes de boosting.   J'ai utilisé cet article de @amber_kshz et je l'ai implémenté.

Implémentation de PRML Chapter 14 Bagging et Ada Boost en Python https://qiita.com/amber_kshz/items/8869d8ef7f9743b16d8d

** En particulier, j'ai pu apprendre à calculer efficacement et rapidement à l'aide d'un tableau. ** Je voudrais résumer comment faire cela.

Les principaux points sont les suivants.

Comprendre Boosting

La méthode de combinaison d'apprenants appelés apprenants faibles est appelée ** apprentissage d'ensemble **. L'apprentissage d'ensemble typique peut être divisé en quatre.

  1. Ensachage (distinguer les données de formation avec plusieurs apprenants faibles et la moyenne (échantillonnage ** avec duplication **))
  2. Stimulation (distinguer les données de formation avec plusieurs apprenants faibles et la moyenne (échantillonnage ** pas de duplication **))
  3. Empilement (moyenne de la charge compte tenu de l'importance des apprenants faibles)
  4. ** (Cette fois) Boosting (améliorer la précision des apprenants faibles pour devenir des apprenants forts) **

Dans l'apprentissage d'ensemble, l'algorithme qui forme en permanence l'apprenant faible et le modifie pour améliorer la précision est appelé ** boosting **. Nous visons à rendre l'apprenant plus précis en prêtant attention au mauvais échantillon (= mal classé) et en effectuant l'apprentissage suivant.

La figure ci-dessous montre le flux. $ M $ est le nombre d'essais, et le nombre d'essais augmente du coin supérieur gauche au coin inférieur droit. Je voudrais classer les cercles bleus et rouges, mais les échantillons mal classés sont en grande partie ** encerclés **. Vous pouvez voir que la ligne de classification verte se déplace pour séparer en quelque sorte l'échantillon mal classé.

image.png

Un apprenant similaire est ** Bagging **. Pour l'ensachage, les résultats de l'apprentissage autonome sont moyennés. Bien que chacun de ces apprenants soit indépendant, la différence est que dans le cas de la stimulation, les résultats appris plus tôt sont utilisés dans l'apprentissage ultérieur.

Comprendre l'algorithme d'Adaboost

Maintenant, comprenons l'algorithme d'Adaboost. Adaboost est une abréviation de Adaptive Boosting. Il s'agit d'un algorithme annoncé en 1997. Adaboost applique l'idée d'utiliser le nouveau prédicteur pour apporter des corrections qui accordent une attention particulière aux parties qui ont été mal évaluées par le prédicteur précédent.

A Decision-Theoretic Generalization of On-Line Learning and an Application to Boosting https://www.sciencedirect.com/science/article/pii/S002200009791504X

L'algorithme spécifique est le suivant.

** Supposition **

algorithme

  1. Entrée: Les données d'apprentissage sont $ (X, T) $, le classificateur de base est $ y $ et le nombre de classificateurs est $ M $.
  2. Initialisez le poids des données d'entraînement $ (w_0, w_1, \ dots, w_ {N-1}) $ à $ w ^ {(0)} _ {n} = 1 / N $.
  3. Répétez ce qui suit pour $ m = 0,1, .... M-1 $. (a) Alignez le classificateur $ y_m (x) $ avec les données de test pour minimiser la fonction d'erreur $ J_m $ représentée ci-dessous. $ \begin{align} J_m = \sum_{n=0}^{N-1} w^{(m)}\_{n} I \left[ y(x_n, \theta_m) \neq t_n \right] \end{align} $

⇒ À ce moment, $ I \ left [y (x_n, \ theta_m) \ neq t_n \ right] $ est ** 0 (= bonne réponse) si les données de test et la valeur prédite correspondent, et 1 si elles sont erronées. Je vais. Par conséquent, si le nombre de réponses correctes est grand, $ J_m $ sera petit ** (= il joue le rôle d'une fonction d'erreur et est OK).

(b) Calculez $ \ epsilon_m et \ alpha_m $ à partir de l'erreur du classificateur de base. $ \ Epsilon_m $ représente le taux d'erreur, et $ \ alpha_m $ est le coefficient à refléter dans le paramètre de pondération. $ \begin{align} \varepsilon_m &:= \frac{\sum_{n=0}^{N-1} w^{(m)}\_{n} I \left[ y(x_n, \theta_m) \neq t_n \right]}{\sum_{n=0}^{N-1} w^{(m)}\_{n}} \\\ \alpha_m &:= \log \left(\frac{1 - \varepsilon_m}{\varepsilon_m} \right) \end{align} $

(c) Utilisez le $ \ alpha_m $ trouvé à l'étape précédente pour définir le poids $ w $ $ \begin{align} \tilde{w}^{(m+1)}\_{n} &= w^{(m)}\_{n} \exp\left\\{ \alpha_m I \left[ y(x_n, \theta_m) \neq t_n \right] \right\\} \\\ \end{align} $ Mettre à jour comme.

⇒ À ce stade, si la valeur prédite et les données de test correspondent, $ I $ indique $ 0 $. Au contraire, si c'est faux, ce sera $ 1 $, donc la pondération sera mise à jour avec le $ \ alpha $ précédent.

Approfondissez votre compréhension en mettant en œuvre Adaboost

Ensuite, je voudrais passer à la mise en œuvre.

Comprendre le moignon de décision

Cette fois, l'apprenant faible utilise la tension déterminée. Un stock décisif est de sélectionner l'une des variables d'entrée de ** certaines données, de définir un seuil en fonction de la valeur et de la classer. ** En bref, je comprends que c'est un arbre de décision de profondeur 1. Maintenant, le programme ci-dessous définit la classe de stock déterminée.

adaboost.ipynb



    def fit_onedim(self, X, y, sample_weight, axis):

        N = len(X)

        # Here we sort everything according the axis-th coordinate of X
        sort_ind = np.argsort(X[:, axis])
        sorted_label = y[sort_ind]
        sorted_input = X[sort_ind]
        sorted_sample_weight = sample_weight[sort_ind]

        pred = -2*np.tri(N-1, N, k=0, dtype='int') + 1 
        mistakes = (pred != sorted_label ).astype('int')

        # The (weighted) error is calculated for each classifier
        errs = np.zeros((2, N-1))
        errs[0] = mistakes @ sorted_sample_weight
        errs[1] = (1 - mistakes) @ sorted_sample_weight

        # Here, we select the best threshold and sign
        ind = np.unravel_index(np.argmin(errs, axis=None), errs.shape)
        sign = -2*ind[0] + 1
        threshold = ( sorted_input[ind[1], axis] + sorted_input[ind[1] + 1, axis] ) / 2
        err = errs[ind]
        return sign, threshold, err

En savoir plus sur les calculs

Cette fois, comme indiqué ci-dessous, nous utilisons le jeu de données makemoons. Prenons le cas où le nombre d'exemples de données est de 100 $, comme indiqué dans l'image ci-dessous, et il y a des données à 50 $ avec une étiquette $ 1 $ et des données à 50 $ avec une étiquette $ -1 $.

image.png

Cet ensemble de données est stocké dans $ X = (x_1, x_2) $. Pour plus de commodité, utilisez le np.argsort suivant pour définir l'index avant de le réorganiser par ordre croissant.

image.png

Ensuite, exécutez la méthode «np.tri» (génération de matrice triangulaire supérieure et inférieure) comme matrice «pred» qui donne une valeur prédite provisoire. image.png

Définissez ensuite ce pred-y comme une matrice erreur. En conséquence, 99 ensembles de tables d'exactitude ont été créés. image.png

Enfin, multipliez ce tableau d'exactitude et ce poids pour trouver la fonction de perte. image.png

La ligne de frontière est la valeur moyenne de $ x_1 ^ m, x_1 ^ {m + 1} $, qui est la limite lorsque la valeur minimale de cette fonction de perte est prise. Dans le cas d'Adaboost, il existe également un processus pour mettre à jour le poids de l'étiquette incorrecte ici.

(Supplément) Déterminez s'ils correspondent

Voici quelques-unes des choses que je pensais être un bon moyen de le faire. Le fait que la valeur prédite soit correcte ou non est déterminé par la valeur de vérité (type booléen). Dans le contenu de la fonction d'erreur plus tôt, c'était $ 0 $ s'il était touché, et $ 1 $ s'il ne l'était pas, donc je vais le travailler comme ça.

sample.ipynb


a = np.array([[1,1,1,1],[1,1,1,1],[1,1,0,1]])
b = np.array([1,1,1,0])
c1 = (a != b )
c2 = (a != b ).astype('int')

print(c1)
print(c2)
[[False False False  True]
 [False False False  True]
 [False False  True  True]]
[[0 0 0 1]
 [0 0 0 1]
 [0 0 1 1]]

Voici un exemple simple. Soit $ a $ la valeur prédite et $ b $ l'étiquette correcte à déterminer. Vous pouvez voir que le programme renvoie $ 0 $ pour False cette fois, et $ 1 $ pour True s'il est désactivé.

Déplacer réellement + évaluer la différence due au nombre d'essais

Déplaçons-le réellement. Essayez de passer de 1 $ à 9 $ en tant que nombre d'essais.

adaboost.ipynb



num_clf_list = [1, 2, 3, 4, 5, 6,7,8,9]
clfs = [AdaBoost(DecisionStump, num_clfs=M) for M in num_clf_list]

fig, axes = plt.subplots(3, 3, figsize=(15,15))

for i in range(len(clfs)):
    clfs[i].fit(X, y)
    plot_result(ax=np.ravel(axes)[i], clf=clfs[i], xx=xx, yy=yy, X=X, y=y)
    np.ravel(axes)[i].set_title(f'M = {num_clf_list[i]}')

002.png

Vous pouvez voir que les lignes à classer sont progressivement séparées et qu'il est susceptible de devenir un classificateur précis. Dans le cas d'un stock déterminé, comme vous pouvez le voir à partir de la définition, il est difficile de classer avec une courbe non linéaire car il essaie de classer avec une ligne droite.

À la fin

Cette fois, j'ai approfondi ma compréhension d'Adaboost avec sa mise en œuvre. Bien que l'algorithme lui-même soit facile à comprendre, quand il s'agit de l'implémenter, j'ai constaté que je ne pouvais pas continuer sans une bonne compréhension des calculs matriciels tels que «numpy». À partir de là, j'aimerais améliorer mes compétences analytiques en comprenant les algorithmes souvent utilisés dans Kaggle tels que XG boost.

Le programme complet est ici. https://github.com/Fumio-eisan/adaboost_20200427

Recommended Posts

J'ai essayé de bien le comprendre en implémentant l'algorithme Adaboost en machine learning (+ j'ai approfondi ma compréhension du calcul de tableaux)
(Apprentissage automatique) J'ai essayé de comprendre attentivement l'algorithme EM dans la distribution gaussienne mixte avec l'implémentation.
[Apprentissage automatique] J'ai essayé de résumer la théorie d'Adaboost
Notez que je comprends l'algorithme du classificateur Naive Bayes. Et je l'ai écrit en Python.
J'ai essayé de comprendre attentivement la fonction d'apprentissage dans le réseau de neurones sans utiliser la bibliothèque d'apprentissage automatique (deuxième moitié)
J'ai essayé de comprendre attentivement la fonction d'apprentissage dans le réseau de neurones sans utiliser la bibliothèque d'apprentissage automatique (première moitié)
J'ai essayé de créer Othello AI avec tensorflow sans comprendre la théorie de l'apprentissage automatique ~ Introduction ~
J'ai essayé de comprendre l'apprentissage supervisé de l'apprentissage automatique d'une manière facile à comprendre, même pour les ingénieurs serveurs 1
J'ai essayé de comprendre l'apprentissage supervisé de l'apprentissage automatique d'une manière facile à comprendre, même pour les ingénieurs serveurs 2
J'ai essayé de créer Othello AI avec tensorflow sans comprendre la théorie de l'apprentissage automatique ~ Implémentation ~
(Apprentissage automatique) J'ai essayé de comprendre attentivement la régression linéaire bayésienne avec l'implémentation
J'ai essayé de créer Othello AI avec tensorflow sans comprendre la théorie de l'apprentissage automatique ~ Battle Edition ~
J'ai essayé d'organiser les index d'évaluation utilisés en machine learning (modèle de régression)
J'ai essayé de prédire la présence ou l'absence de neige par apprentissage automatique.
J'ai essayé de prédire l'évolution de la quantité de neige pendant 2 ans par apprentissage automatique
Je n'ai pas compris le redimensionnement de TensorFlow, alors je l'ai résumé visuellement.
J'ai essayé de compresser l'image en utilisant l'apprentissage automatique
[Introduction] J'ai essayé de l'implémenter moi-même tout en expliquant pour comprendre la dichotomie
J'ai essayé de visualiser les paroles de GReeeen, que j'écoutais de façon folle dans ma jeunesse mais que je ne l'écoutais plus.
J'ai essayé de comparer la précision des modèles d'apprentissage automatique en utilisant kaggle comme thème.
J'ai essayé de vérifier la classification yin et yang des membres hololive par apprentissage automatique
Je l'ai écrit en langage Go pour comprendre le principe SOLID
J'ai essayé "Implémentation d'un algorithme génétique (GA) en python pour résoudre le problème du voyageur de commerce (TSP)"
Comment utiliser l'apprentissage automatique pour le travail? 01_ Comprendre l'objectif de l'apprentissage automatique
J'ai essayé d'améliorer la précision de mon propre réseau neuronal
J'ai essayé de classer les accords de guitare en temps réel en utilisant l'apprentissage automatique
J'ai essayé de comprendre l'arbre de décision (CART) pour classer soigneusement
J'ai essayé de visualiser le modèle avec la bibliothèque d'apprentissage automatique low-code "PyCaret"
J'ai essayé d'afficher la valeur d'altitude du DTM dans un graphique
J'ai essayé l'histoire courante de l'utilisation du Deep Learning pour prédire la moyenne Nikkei
Enregistrez les étapes pour comprendre l'apprentissage automatique
Je voulais connaître le nombre de lignes dans plusieurs fichiers et j'ai essayé de l'obtenir avec une commande
J'ai essayé de comprendre attentivement la machine vectorielle de support (Partie 1: J'ai essayé le noyau polynomial / RBF en utilisant MakeMoons comme exemple).
Notez que je comprends l'algorithme des moindres carrés. Et je l'ai écrit en Python.
[Azure] J'ai essayé de créer une machine virtuelle Linux avec Azure de Microsoft Learn
J'ai essayé de traiter et de transformer l'image et d'élargir les données pour l'apprentissage automatique
J'ai essayé de récupérer les données de l'ordinateur portable en le démarrant sur Ubuntu
J'ai essayé d'optimiser le séchage du linge
J'ai essayé de corriger la forme trapézoïdale de l'image
J'ai essayé de vectoriser les paroles de Hinatazaka 46!
[Introduction] J'ai essayé de l'implémenter moi-même tout en expliquant l'arbre de dichotomie
J'ai essayé d'extraire le texte du fichier image en utilisant Tesseract du moteur OCR
J'ai essayé de mettre HULFT IoT (Agent) dans la passerelle Rooster de Sun Electronics
[First data science ⑥] J'ai essayé de visualiser le prix du marché des restaurants à Tokyo
J'ai essayé de faciliter la modification du paramètre du proxy authentifié sur Jupyter
J'ai essayé de déplacer l'apprentissage automatique (détection d'objet) avec TouchDesigner
J'ai essayé de représenter graphiquement les packages installés en Python
J'ai essayé de résumer la forme de base de GPLVM
À propos des tests dans la mise en œuvre de modèles d'apprentissage automatique
Je veux bien comprendre les bases de Bokeh
J'ai essayé d'implémenter GA (algorithme génétique) en Python
J'ai essayé de visualiser les informations spacha de VTuber
J'ai essayé d'effacer la partie négative de Meros
J'ai étudié l'algorithme d'apprentissage de renforcement du trading d'algorithmes
J'ai essayé d'implémenter le calcul automatique de la preuve de séquence
J'ai essayé de classer les voix des acteurs de la voix
J'ai essayé de résumer les opérations de chaîne de Python
J'ai essayé de visualiser la consommation électrique de ma maison avec Nature Remo E lite