Notez que je comprends l'algorithme des moindres carrés. Et je l'ai écrit en Python.

Aperçu

Décrit la méthode des moindres carrés. Tout d'abord, calculez avec des valeurs numériques concrètes, puis trouvez la formule générale et enfin implémentez-la en Python.

Quelle est la méthode du carré minimum?

L'analyse de régression est une méthode permettant de dériver la formule qui correspond le mieux aux données de l'échantillon et de prédire la valeur numérique des nouvelles données, ce qui est l'une des méthodes typiques. Dérivez une expression relationnelle qui minimise l'erreur entre les exemples de données et la valeur obtenue à partir de l'expression.

Exemple concret

Supposons que vous prédisiez la croissance du radis Hatsuka. Actuellement, le 4e jour, nous mesurons le nombre de centimètres de feuilles qui sortent chaque jour.

Jour 1 Jour 2 Jour 3 Jour 4
0.3 1.9 2.8 4.3

J'ai fait un graphique de ces données. L'axe $ x $ est le nombre de jours et l'axe $ y $ est la longueur de la feuille.

radish1.png

Soit la fonction hypothétique une fonction linéaire. L'équation de la fonction linéaire est

y = ax + b 

Donc, calculez ce que devraient être les valeurs de $ a $ et $ b $ pour créer une fonction agréable. En tant qu'image, trouvez une fonction linéaire qui correspond le plus possible aux données, comme indiqué dans le graphique rouge.

radish2.png

Tout d'abord, à partir de la fonction hypothétique $ y = ax + b $, la valeur de $ y $ du 0e au 4e jour (le nombre de jours est $ x $) est calculée, et l'erreur des données de croissance réelle est calculée. (Le jour 0 est le jour où les graines sont enterrées)

Journées(x) Jour 0 Jour 1 Jour 2 Jour 3 Jour 4
Record 0.0cm 0.3cm 1.9cm 2.8cm 4.3cm
Calculé à partir de la formule(y) b a+b 2a+b 3a+b 4a+b
Erreur(y-Record) b-0 (a+b)-0.3 (2a+b)-1.9 (3a+b)-2.8 (4a+b)-4.3

L'erreur est la longueur de la partie rose dans le graphique ci-dessous.

radish2_2.png

Carré, puis additionnez pour que l'erreur ne soit pas négative. En supposant que l'erreur totale est de $ J $, le calcul est le suivant.

J = b^2+((a+b)-0.3)^2+((2a+b)-1.9)^2+((3a+b)-2.8)^2+((4a+b)-4.3)^2\\
\\
  =30a^2+20ab-59.4a+5b^2-18.6b+30.03

Trouvez $ a $ et $ b $ qui minimisent ce $ J $ et vous avez terminé.

Si $ J $ est partiellement différencié en fonction de $ a $ comme 0, et $ J $ est partiellement différencié en fonction de $ b $ comme 0, et que deux équations simultanées sont résolues, $ J $ est le minimum. Naru $ a $ et $ b $ sont calculés.

Voir ici pour la valeur minimale d'une fonction bidimensionnelle à deux variables. http://mathtrain.jp/quadratic

La formule ci-dessus est partiellement différenciée par $ a $ ($ \ frac {∂J} {∂a} $), et la formule inférieure est partiellement différenciée par $ b $ ($ \ frac {∂J} {∂b) } $).

\left\{
\begin{array}{ll}
0 = 60a+20b-59.4 \\
0 = 20a+10b-18.6 
\end{array}
\right.

Lorsque vous résolvez les équations simultanées,

\left\{
\begin{array}{ll}
a = 1.11 \\
b=-0.36
\end{array}
\right.

La porte à côté

y = 1.11x - 0.36 

J'ai pu dériver la fonction. Après avoir dessiné avec un graphique

radish3_ans.png

Ça fait du bien !!

radish_plot.py


import matplotlib.pyplot as plt
import numpy as np
# data set
plt.plot([0,0.3,1.9,2.8,4.3], "bo") 

plt.title("radish growth")
plt.xlabel("X:days")
plt.ylabel("Y:length")
plt.xlim([0,4])
plt.xticks(np.arange(1,5,1))
plt.ylim([0,4])
plt.yticks(np.arange(0,6,1))

# Graph
x = np.arange(0,10,0.01)
y = 1.11*x -0.36
plt.plot(x,y,"r-")    
plt.show()              

Formule générale

Dans l'exemple concret, la fonction hypothétique est une fonction linéaire, mais elle peut être plus appropriée pour une fonction quadratique ou une fonction cubique. C'est peut-être généralement une relation plus complexe.

Si vous adaptez l'exemple du radis Hatsuka à une fonction quadratique,

radish4.png

Et cela peut être considéré comme une meilleure formule. En outre, la croissance du radis Hatsuka peut être affectée non seulement par le nombre de jours, mais aussi par la quantité de soleil et la quantité d'eau.

Par conséquent, considérons un exemple concret en le convertissant en une formule générale.

S'il y a des facteurs $ x_ {1} $, $ x_ {2} $ qui déterminent la longueur de la feuille, tels que le nombre de jours, la quantité d'ensoleillement, la quantité d'eau à donner et $ \ cdots $$ n $, respectivement. , $ x_ {3} $ $ \ cdots $ $ x_ {n} $. Soit le coefficient de $ x_ {n} $ $ \ theta_ {n} $.

La fonction et la fonction d'hypothèse que vous souhaitez finalement dériver peuvent être exprimées par la formule suivante. ($ X_ {1} $ ne signifie pas $ x $ au carré, c'est une fonction qui dépend de $ x $. Il peut être utile de regarder le dernier code Python.)

h_{\theta}(x) = \theta_{0}x_{0} + \theta_{1}x_{1} + \theta_{2}x_{2} +\cdots + \theta_{n}x_{n}

$ \ Theta_ {0} $ est la partie $ b $ de l'exemple concret et est considéré comme $ x_ {0} = 1 $. Soudainement, $ h_ {\ theta} (x) $ est sorti, mais $ y $ dans l'exemple concret est la longueur de la feuille.

La fonction hypothétique ci-dessus peut être liée à la fonction d'exemple concrète $ y = 1,11x --0,36 $ comme suit.

y = -0.36 × 1 + 1.11 × x
h_{\theta}(x) = \theta_{0} × x_{0} + \theta_{1} × x_{1}

Supposons qu'il existe plusieurs exemples de données pour cette fonction hypothétique et que les données soient les suivantes.

x_{0}
(1 fixe)
x_{1}
(Journées)
x_{2}
(Heure du soleil h)
x_{3}
(Teneur en eau ml)
\cdots y
(Longueur des feuilles cm)
1 1 14 150 \cdots 0.3
1 2 14 100 \cdots 1.9
1 3 14.1 160 \cdots 2.8
1 4 14.1 160 \cdots 4.3

Les données de la colonne $ j $ de la ligne $ i $ peuvent être représentées par $ x_ {j} ^ {(i)} $, $ y ^ {(i)} $, et une fois mappées, cela ressemble à ceci. C'est une forme. Cela ressemble à un exposant, mais il ne montre que les données.

x_{0}
(1 fixe)
x_{1}
(Journées)
x_{2}
(Heure du soleil h)
x_{3}
(Teneur en eau ml)
\cdots y
(Longueur des feuilles cm)
x_{0}^{(1)} x_{1}^{(1)} x_{2}^{(1)} x_{3}^{(1)} \cdots y^{(1)}
x_{0}^{(2)} x_{1}^{(2)} x_{2}^{(2)} x_{3}^{(2)} \cdots y^{(2)}
x_{0}^{(3)} x_{1}^{(3)} x_{2}^{(3)} x_{3}^{(3)} \cdots y^{(3)}
x_{0}^{(4)} x_{1}^{(4)} x_{2}^{(4)} x_{3}^{(4)} \cdots y^{(4)}

Lorsque les données de la première colonne sont affectées à $ h_ {\ theta} (x) $, elles sont exprimées comme $ h_ {\ theta} (x ^ {(1)}) $.

De cette manière, l'erreur totale de la fonction hypothétique peut être réécrite comme la fonction suivante. $ m $ est le nombre d'ensembles de données. Dans l'exemple du tableau ci-dessus, c'est 4.

J(\theta_{0},\theta_{1}, \cdots,\theta_{n})= \sum_{i=1}^{m} (h_{\theta}(x^{(i)})-y^{(i)})^2 

L'erreur totale $ J (\ theta_ {0}, \ theta_ {1}, \ cdots, \ theta_ {n}) $ est la plus petite $ \ theta_ {0}, \ theta_ {1}, \ cdots, \ theta_ Le but est de dériver un ensemble de {n} $.

À partir de là, remplaçons-le par une matrice. Une matrice est un élément puissant qui peut calculer des données à la fois.

Premièrement, pour représenter la fonction hypothétique $ h_ {\ theta} (x) $ comme une matrice, $ \ theta_ {0} $, $ \ theta_ {1} $, $ \ cdots $ $ \ theta_ {n} $, $ X_ {0} $, $ x_ {1} $, $ \ cdots $ $ x_ {n} $ est représenté par une matrice.

\theta=\begin{bmatrix}
\theta_{0} \\
\theta_{1} \\
\vdots\\
\theta_{n} 
\end{bmatrix}
,
  x=\begin{bmatrix}
x_{0} \\
x_{1} \\
\vdots\\
x_{n} 
\end{bmatrix}

Placé de cette façon, $ h_ {\ theta} (x) $ peut être représenté par le produit de la matrice transposée de $ \ theta $ et de la matrice $ x $.

h_{\theta}(x)= \theta^T x\\

Veuillez vous référer ici pour la translocation et l'empilement de la matrice. http://www.sist.ac.jp/~kanakubo/research/hosoku/trans_gyoretu.html

L'ensemble de données $ x ^ {(i)} $ dans la colonne $ i $ est représenté par une matrice, et la matrice $ X $ étant donné tous les ensembles de données est représentée par la matrice transposée de chaque colonne. $ y ^ {(i)} $ est également représenté par une matrice.

x^{(i)}=\begin{bmatrix}
x_{0}^{(i)} \\
x_{1}^{(i)} \\
\vdots\\
x_{n}^{(i)}
\end{bmatrix}
,  
X=\begin{bmatrix}
(x^{(1)})^T \\
(x^{(2)})^T  \\
\vdots\\
(x^{(m)})^T 
\end{bmatrix}
=
\begin{bmatrix}
x_{0}^{(1)} & x_{1}^{(1)} & \cdots & x_{n}^{(1)} \\
x_{0}^{(2)} & x_{1}^{(2)} & \cdots & x_{n}^{(2)} \\
\vdots & \vdots & & \vdots\\
x_{0}^{(m)} & x_{1}^{(m)} & \cdots & x_{n}^{(m)} \\
\end{bmatrix}
,  
y=\begin{bmatrix}
y^{(1)} \\
y^{(2)} \\
\vdots\\
y^{(m)}
\end{bmatrix}

Cela semble déroutant, mais je viens de convertir le tableau ci-dessus en matrice.

Et l'histoire saute aussitôt.

Lorsqu'il est placé de cette manière, $ \ theta $, qui minimise l'erreur totale $ J (\ theta) $, peut être obtenu en résolvant l'équation matricielle suivante.

\theta =
(X^tX)^{-1}X^ty

Voir ici pourquoi cette formule est utilisée. http://mathtrain.jp/leastsquarematrix

De plus, $ X ^ {-1} $ est appelé la matrice inverse de $ X $, voir ici. http://mathtrain.jp/inversematrix

Mettez l'ensemble de données dans cette formule pour trouver $ \ theta $, et placez-le dans $ \ theta_ {0}, \ theta_ {1}, \ cdots, \ theta_ {n} $ de $ h (\ theta) $ pour obtenir le minimum La formule de la fonction (fonction modèle) par la méthode du carré est terminée.

Je l'ai écrit en Python

J'ai écrit cette méthode des moindres carrés en Python. On vous demandera $ \ theta $ en une seule ligne! !!

Le premier est l'ensemble de données. Un nombre aléatoire est ajouté à la fonction $ y = 3 + 2 \ cos (x) + \ frac {1} {2} x $ pour générer une erreur.

linalg_lstsq.py


x = arange(-3, 10, 0.1)
y = 3 + 2 * np.cos(x) + (1/2) * x + np.random.normal(0.0, 1.0, len(x)) 

Dans la formule générale, $ x_ {1} $ est $ \ cos (x) $ et $ x_ {2} $ est $ x $. Si les coefficients à calculer peuvent être calculés de sorte que $ \ theta_ {0} $ soit proche de $ 3 $, $ \ theta_ {1} $ est proche de $ 2 $, et $ \ theta_ {2} $ est proche de $ \ frac {1} {2} $. C'est bon.

Créez une matrice $ X $ avec tous les jeux de données.

linalg_lstsq.py


n = 3
X = np.zeros((len(x), n), float)
X[:,0] = 1
X[:,1] = np.cos(x)
X[:,2] = x

L'expression pour $ \ theta $ est cette seule ligne utilisant linalg.lstsq dans la bibliothèque Numpy.

linalg_lstsq.py


(theta, residuals, rank, s) = linalg.lstsq(X, y)

https://docs.scipy.org/doc/numpy/reference/generated/numpy.linalg.lstsq.html

En conséquence, c'est devenu comme ça.

linalg_lstsq.py


import numpy as np
import matplotlib.pyplot as plt

# data-set
x = np.arange(-3, 10, 0.1)
y = 3 + 2 * np.cos(x) + (1/2) * x + np.random.normal(0.0, 1.0, len(x)) 

n = 3
X = np.zeros((len(x), n), float)
X[:,0] = 1
X[:,1] = np.cos(x)
X[:,2] = x

# Least square method
(theta, residuals, rank, s) = np.linalg.lstsq(X, y)

# data-set plot
plt.plot(x, y, 'b.')
# h(theta) plot
plt.plot(x, theta[0] + theta[1] * X[:,1] + theta[2] * X[:,2], 'r-')

plt.title("linalg.lstsq")
plt.xlabel("X-axis")
plt.ylabel("Y-axis")

plt.show()

print('θ[0]: %s' % theta[0])
print('θ[1]: %s' % theta[1])
print('θ[2]: %s' % theta[2])

lstsqrs3.png lstsqrs_2-3.png

J'ai pu obtenir une valeur assez proche, et même si vous regardez le graphique, cela correspond! !!

fin

Depuis que je viens de commencer à étudier l'apprentissage automatique, j'apprends les algorithmes et les idées standard. Je ne peux rien écrire de nouveau, mais j'espère que cela aide quelqu'un.

30d067ead81320ed8a9112ee25b96762_s.jpg

Recommended Posts

Notez que je comprends l'algorithme des moindres carrés. Et je l'ai écrit en Python.
Notez que je comprends l'algorithme du classificateur Naive Bayes. Et je l'ai écrit en Python.
J'ai essayé la méthode des moindres carrés en Python
J'ai écrit la file d'attente en Python
J'ai écrit la pile en Python
Je l'ai écrit en langage Go pour comprendre le principe SOLID
J'ai défini des variables d'environnement dans Docker et je les ai affichées en Python.
Un mémo que j'ai écrit un tri rapide en Python
J'ai écrit une classe en Python3 et Java
[Examen d'ingénieur d'information de base] J'ai écrit l'algorithme de la méthode de division mutuelle euclidienne en Python.
Comprenez attentivement la distribution exponentielle et dessinez en Python
Tracer et comprendre la distribution normale multivariée en Python
Comprendre attentivement la distribution de Poisson et dessiner en Python
J'ai écrit python en japonais
Je veux remplacer les variables dans le fichier de modèle python et le produire en masse dans un autre fichier
Je comprends Python en japonais!
Notez qu'il prend en charge Python 3
[Python] J'ai installé le jeu depuis pip et j'ai essayé de jouer
J'ai essayé de programmer le test du chi carré en Python et Java.
J'ai écrit un script qui divise l'image en deux
J'ai écrit python3.4 dans .envrc avec direnv et je l'ai autorisé, mais j'ai eu une erreur de syntaxe
Algorithme de tri et implémentation en Python
J'ai écrit Fizz Buzz en Python
J'ai essayé le mouvement Python3 qui change la direction dans le système de coordonnées
J'ai écrit le code pour écrire le code Brainf * ck en python
[python] Une note que j'ai commencé à comprendre le comportement de matplotlib.pyplot
Notez que Python décode l'image au format base64 et l'enregistre localement
J'ai acheté et analysé la loterie jumbo de fin d'année avec Python qui peut être exécutée dans Colaboratory
J'ai essayé de trouver la différence entre A + = B et A = A + B en Python, alors notez
J'ai écrit un tri-arbre qui peut être utilisé pour l'implémentation de dictionnaire à grande vitesse en langage D et Python
[Examen d'ingénieur d'information de base] J'ai écrit un algorithme pour la valeur maximale d'un tableau en Python.
[Python] Doux Est-ce doux? À propos des suites et des expressions dans les documents officiels
Celui qui divise le fichier csv, le lit et le traite en parallèle
J'ai créé un bot Discord en Python qui se traduit quand il réagit
Tri sélect écrit en C
Le nom du fichier était mauvais en Python et j'étais accro à l'importation
[Python débutant] J'ai rassemblé les articles que j'ai écrits
Trouvez-le dans la file d'attente et modifiez-le
J'ai écrit l'aile coulissante dans la création.
Je pensais que c'était la même chose que python, et j'étais accro au problème que l'interpréteur ruby ne démarre pas.
Notez que cibuildwheel construit python bwheel (y compris le module C ++) en masse avec CI et le télécharge sur PyPI
[Python] Précautions lors de l'acquisition de données en grattant et en les mettant dans la liste
[Examen d'ingénieur d'information de base] J'ai écrit un algorithme de recherche linéaire en Python.
Parlez des fonctionnalités dont les pandas et moi étions en charge dans le projet
J'ai comparé la vitesse des expressions régulières en Ruby, Python et Perl (version 2013)
D'une manière ou d'une autre, le code que j'ai écrit a fonctionné et j'ai été impressionné, alors je vais le poster
J'ai écrit un module PyPI qui étend le style de paramètre dans le module sqlite3 de Python
Je veux obtenir le nom du fichier, le numéro de ligne et le nom de la fonction dans Python 3.4
Quand j'essaye matplotlib en Python, il dit 'cairo.Context'
J'ai essayé de simuler "Birthday Paradox" avec Python
J'ai écrit "Introduction à la vérification des effets" en Python
À propos de la différence entre "==" et "is" en python
[Note] À propos du rôle du trait de soulignement "_" en Python
J'ai essayé d'implémenter la fonction gamma inverse en python
POST JSON avec Python et recevez avec PHP
Celui qui affiche la barre de progression en Python
Je veux afficher la progression en Python!