[PYTHON] J'ai essayé d'approfondir ma compréhension en créant mon propre discriminateur qui peut classer les valeurs binaires à l'aide de la régression logistique.

introduction

Cette fois, je vais résumer le contenu qui a approfondi ma compréhension en implémentant la régression logistique sans utiliser un cadre tel que scicit learn.

Le contour est ci-dessous.

Analyse régressive et régression logistique

Avant de discuter de la régression logistique, résumons l'analyse de régression. La régression est l'expression de la variable objective $ y $ en utilisant la variable explicative $ x $. Et ce $ y $ prend des valeurs consécutives. Si $ x $ est unidimensionnel, on l'appelle régression simple, et s'il est bidimensionnel ou plus, on l'appelle régression multiple. Par exemple

Etc. Vous pouvez voir que le prix du terrain et le nombre de visiteurs sont des valeurs continues. La régression logistique, en revanche, est une méthode d'estimation de la probabilité d'appartenir à une classe (par exemple, si un e-mail est du spam) à partir de variables explicatives. Comme pour la régression linéaire, effectuez des calculs linéaires basés sur des variables explicatives. Cependant, au lieu de sortir le résultat du calcul tel quel, ** renvoie la logistique du résultat. ** **

Logistique signifie sortir une valeur de 0 à 1. À ce stade, la fonction utilisée pour la régression logistique est appelée la fonction sigmoïde.

f(x) = \frac{1}{1+e^{-x}} \\
x = β_0×α_0 +β_1

004.png

$ β_0 × α_0 + β_1 $ est l'équation de régression utilisée en régression linéaire ($ β_0, β_1 $ sont des constantes et $ α_0 $ sont des variables). Cette fois, à titre d'exemple, il est défini comme l'expression linéaire de $ \ alpha $. $ f (x) $ renvoie 0 à 1.

La différence entre la régression linéaire et la régression logistique est brièvement présentée ci-dessous. image.png

Mettre en œuvre la régression logistique et essayer de comprendre

D'ailleurs, cette fois, j'aimerais procéder à une régression logistique tout en créant la mienne sans utiliser un framework tel que sckit learn.

  1. Générez 100 points aléatoires (2D)
  2. Sur la base d'une certaine ligne droite unidimensionnelle (f (x, y) = 2x + 3y-1 cette fois), les 100 points ci-dessus sont classés par f (x, y)> 0 ou <0.
  3. Créez un classificateur approprié $ w $ (vecteur 3D). Sortie de 0 à 1 de la combinaison $ w et φ $ avec la fonction de base $ φ = (x, y, 1) $ avec la fonction sigmoïde
  4. Mettez à jour le paramètre en 3. avec la méthode de descente probabiliste pour rendre f (x, y) distinguable.
  5. Le discriminateur peut identifier f (x, y)

Génère 100 points aléatoires (2D)

Tout d'abord, générez 100 points aléatoires dans un plan bidimensionnel avec la méthode np.random.randn () pour les points x et y.

logistic.ipynb


N = 100#Nombre de points de données
np.random.seed(0)#Séquence de nombres aléatoires fixe pour les points de données
X = np.random.randn(N, 2)#Générer une matrice aléatoire N × 2=N points aléatoires dans l'espace 2D

Sur la base d'une ligne droite unidimensionnelle (f (x, y) = 2x + 3y-1 cette fois), les 100 points ci-dessus sont classés par f (x, y)> 0 ou <0.

Ensuite, tracez une ligne droite unidimensionnelle (f (x, y) = 2x + 3y-1 cette fois) et classez au hasard cent points par f (x, y)> 0 ou <0.

logistic.ipynb


def f(x, y):
    return 2 * x + 3 * y - 1  #Vrai plan de séparation 2x+ 3y = 1

T = np.array([ 1 if f(x, y) > 0 else 0 for x, y in X])
plt.figure(figsize=(6, 6)) 
plt.plot(X[T==1,0], X[T==1,1], 'o', color='red')
plt.plot(X[T==0,0], X[T==0,1], 'o', color='blue')
plt.show()

005.png

J'ai vu une ligne droite que je voulais classer.

Créez un classificateur approprié $ w $ (vecteur tridimensionnel). Sortie 0 à 1 de la combinaison $ w et φ $ avec la fonction de base $ φ = (x, y, 1) $ avec la fonction sigmoïde

Ensuite, générez un vecteur tridimensionnel $ w $ comme classificateur. Définissez ensuite $ φ = (x, y, 1) $ comme fonction de base. Trouvez ce produit intérieur (multiplié par chaque composant). Pour les problèmes de régression linéaire, cette valeur de produit interne est utilisée pour la prédiction. Cependant, dans la ** régression logistique, il s'agit de prédire davantage à partir de la valeur de 0 à 1 obtenue en substituant cette valeur de produit interne dans la fonction sigmoïde. ** ** La mise en œuvre réelle est la suivante.

logistic.ipynb


np.random.seed() #Initialiser un nombre aléatoire
w = np.random.randn(3)  #Initialiser les paramètres de manière aléatoire

def phi(x, y):#Fonction de base
    return np.array([x, y, 1])

seq = np.arange(-3, 3, 0.1)
xlist, ylist = np.meshgrid(seq, seq)
zlist = [sigmoid(np.inner(w, phi(x, y))) for x, y in zip(xlist, ylist)] #Paramètres du produit en interne et fonction de base et attribuer à la fonction sigmoïde
plt.imshow(zlist, extent=[-3,3,-3,3], origin='lower', cmap='bwr')
plt.show()

008.png

La distribution obtenue par le classifieur est illustrée dans la figure ci-dessus. Environ 0,5 ou plus (= [1]) est rouge et 0,5 ou moins (= [0]) est bleu (zone correcte pour les données de l'enseignant). Il réussit si cette zone divisée correspond à la zone déterminée par f (x, y).

Mettez à jour le paramètre en 3. avec la méthode de descente de gradient probabiliste pour rendre f (x, y) distinguable.

Mettez ensuite à jour les paramètres du classificateur avec la méthode de descente de gradient probabiliste. La méthode de descente de gradient stochastique est un exemple d'explication dans un réseau de neurones, mais elle est résumée ici.

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é) https://qiita.com/Fumio-eisan/items/7507d8687ca651ab301d

Voici maintenant la formule de mise à jour des paramètres pour la méthode de descente de gradient stochastique en régression logistique.

\begin{align}
w_{i+1}& = w_i -\eta ・\frac{δE}{δw}\\
&= w_i -\eta ・(y_n-t_n)φ(x_n)
\end{align}

A ce moment, $ w $ est le paramètre du discriminateur, $ \ eta $ est le taux d'apprentissage, $ y $ est la probabilité de 0 à 1 obtenue par la fonction sigmoïde, et les données de l'enseignant indiquant que $ t $ vaut 0 ou 1, $ φ ( x) $ est la fonction de base.

J'ai fait une transformation rapide de la formule, mais la transformation ci-dessous ** est une transformation propre à la régression logistique. ** **

\frac{δE}{δw}=(y_n-t_n)φ(x_n)

Dans un réseau de neurones, etc., il est très mathématiquement compliqué de trouver le gradient de cette fonction de perte, et on craint que la quantité de calcul augmente. Par conséquent, une méthode telle que la méthode de propagation de retour d'erreur est utilisée. Dans la régression logistique, il est possible de l'exprimer sous la forme d'une formule étonnamment simple tout en utilisant également les caractéristiques de la fonction sigmoïde.

En ce qui concerne la transformation de formule, l'URL suivante est expliquée très soigneusement, il serait donc grandement apprécié que vous puissiez vous y référer.

URL de référence http://gihyo.jp/dev/serial/01/machine-learning/0019

À propos, quand il sera effectivement mis en œuvre, ce sera comme suit. Cette fois, le taux d'apprentissage est initialement fixé à 0,1. Et nous diminuons progressivement le taux d'apprentissage cette fois pour faciliter la convergence.

logistic.ipynb



#Valeur initiale du taux d'apprentissage
eta = 0.1

for i in range(len(xlist)):
    list = range(N)
    
    for n in list:
        x_n, y_n = X[n, :]
        t_n = T[n]

        #Probabilité de prédiction
        feature = phi(x_n, y_n)
        predict = sigmoid(np.inner(w, feature))
        w -= eta * (predict - t_n) * feature

    #Diminuez le taux d'apprentissage pour chaque itération
    eta *= 0.9

Le résultat calculé est indiqué sur la figure.

logistic.ipynb


#Dessiner un nuage de points et la distribution prévue
plt.figure(figsize=(6, 6)) 
plt.imshow(zlist, extent=[-3,3,-3,3], origin='lower', cmap='GnBu')
plt.plot(X[T==1,0], X[T==1,1], 'o', color='red')
plt.plot(X[T==0,0], X[T==0,1], 'o', color='blue')
plt.show()

007.png

Nous avons réussi à créer un classificateur qui pourrait séparer les zones bleues et rouges des points aléatoires.

À la fin

Cette fois, j'ai créé mon propre discriminateur de régression logistique. Il était intéressant de suivre comment optimiser mathématiquement la fonction de perte.

Le programme complet peut être trouvé ici. https://github.com/Fumio-eisan/logistic_20200411

Recommended Posts

J'ai essayé d'approfondir ma compréhension en créant mon propre discriminateur qui peut classer les valeurs binaires à l'aide de la régression logistique.
J'ai essayé de publier mon propre module pour pouvoir l'installer
J'ai essayé de créer un pointage de crédit simple avec régression logistique.
J'ai essayé de classer le texte en utilisant TensorFlow
J'ai essayé d'utiliser la bibliothèque Python "pykakasi" qui peut convertir des kanji en romaji.
J'ai essayé de classer les boules de dragon par adaline
J'ai essayé d'apprendre mon propre ensemble de données en utilisant Chainer Trainer
J'ai essayé de classer MNIST par GNN (avec PyTorch géométrique)
[Diplômé de l'encombrement d'articles] J'ai essayé de développer un service qui peut répertorier les articles par objectif
[Python] J'ai créé ma propre bibliothèque qui peut être importée dynamiquement
J'ai essayé Python! ] Puis-je publier sur Kaggle sur iPad Pro?
J'ai essayé d'améliorer la précision de mon propre réseau neuronal
J'ai essayé d'implémenter la régression linéaire bayésienne par échantillonnage de Gibbs en python
J'ai essayé de classer les nombres de mnist par apprentissage non supervisé [PCA, t-SNE, k-means]
J'ai essayé d'analyser la carte du Nouvel An par moi-même en utilisant python