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.
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
$ β_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.
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.
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
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()
J'ai vu une ligne droite que je voulais classer.
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()
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 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()
Nous avons réussi à créer un classificateur qui pourrait séparer les zones bleues et rouges des points aléatoires.
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