Merci. Cette fois, j'ai écrit un article sur la façon d'implémenter la méthode des moindres carrés en Python. Comme je l'ai mentionné plus tôt, je ne sais pas si je n'ai pas les connaissances mathématiques suivantes.
・ Fonctions de base telles que les fonctions linéaires et quadratiques ・ Différenciation et différenciation partielle ・ Nombre total (Σ), moyenne
Si vous avez des connaissances en mathématiques jusqu'au lycée, il ne devrait y avoir aucun problème. Voyons donc à quoi cela ressemble.
Supposons que vous ayez ce type de données. (Graphique ci-dessous) Il est impossible de dire: «Dessinez une fonction linéaire qui minimise l'erreur à partir de chaque point». La méthode qui rend cela possible est la ** méthode du carré minimum (méthode du carré minimum) **. Il peut être utilisé lorsque les données de mesure $ y $ sont la somme de la fonction modèle (fonction d'origine) $ f (x) $ et de l'erreur $ \ varepsilon $. Il est exprimé comme ci-dessous.
y = f(x) + \varepsilon
Cela signifie que vous ne pouvez pas utiliser la méthode des moindres carrés avec des données aléatoires.
Maintenant, puisque ces données semblent être capables d'approximer une fonction linéaire, approchons-la en l'utilisant comme fonction de modèle. La formule de la fonction linéaire est la suivante.
f(x) = ax + b
Trouvez les paramètres appropriés pour $ a $ et $ b $ en utilisant la méthode des moindres carrés. Tout d'abord, trouvez la somme des carrés de la différence entre les données réelles, qui est également le nom, et la fonction du modèle. La formule est la suivante.
J=\sum_{i=1}^n(y_i-f(x_i))^2=\sum_{i=1}^n(y_i-ax_i-b)^2
La raison de trouver le carré de l'erreur est de l'empêcher comme une fonction quadratique car s'il y a à la fois des erreurs positives et négatives, elles s'annulent et ne peuvent pas être trouvées avec précision.
La somme des carrés des erreurs, $ J $, est partiellement différenciée par $ a $ et $ b $. La différenciation partielle est la suivante.
\frac{\partial J}{\partial a}=-2\sum_{i=1}^nx_i(y_i-ax_i-b)=-2(\sum_{i=1}^n x_iy_i - a\sum_{i=1}^n x_i^2 - b\sum_{i=1}^n x_i)\tag{1}
\frac{\partial J}{\partial b}=-2\sum_{i=1}^n(y_i-ax_i-b)=-2(\sum_{i=1}^n y_i - a\sum_{i=1}^n x_i - nb)\tag{2}
Trouvez $ a $ et $ b $ lorsque ces deux équations sont égales à 0. Tout d'abord, transformez l'équation (2) en une équation de $ b = $.
b=\frac{1}{n}\sum_{i=1}^n y_i - \frac{a}{n}\sum_{i=1}^n x_i\tag{3}
Remplacez l'équation (3) par l'équation (1) et ne laissez que $ a $ comme variable pour $ a = $.
a=\frac{n\sum_{i=1}^n x_iy_i-\sum_{i=1}^n x_i \sum_{i=1}^n y_i}{n\sum_{i=1}^n x_i^2-(\sum_{i=1}^n x_i)^2}
Après cela, vous pouvez le remplacer par l'équation (3) pour trouver les paramètres de $ a $ et $ b $ ... mais Σ est trop et c'est foiré. Mettons les lettres de manière à ce qu'elles soient un peu plus faciles à voir.
a=\frac{nXY_{sum}-X_{sum}Y_{sum}}{nX^2_{sum}-(X_{sum})^2}\tag{4}
b=Y_{ave}-aX_{ave}\tag{5}
Et à propos de ça. Est-ce un peu plus facile à voir? Les significations des lettres sont les suivantes.
En passant, si vous divisez la molécule et le dénominateur de l'équation (4) par $ n ^ 2 $, vous pouvez également les trouver tous par la moyenne de chacun.
a=\frac{XY_{ave}-X_{ave}Y_{ave}}{X^2_{ave}-(X_{ave})^2}\tag{6}
Maintenant que nous connaissons le principe, calculons avec Python.
Pour les données, nous avons utilisé les données du graphique présenté en premier. Le code source est indiqué ci-dessous. De plus, ** numpy ** a été utilisé pour le calcul numérique.
import numpy as np
import matplotlib.pyplot as plt
#Données à utiliser
X = np.array([1, 2, 3, 4, 5, 6, 7, 8, 9])
Y = np.array([2, 5, 3, 7, 12, 11, 15, 16, 19])
plt.scatter(X, Y, color = 'red')
#Nombre de données
n = Y.size
#Produit de X et Y
XY = X * Y
#Carré de chaque élément de X
X_2 = X * X
#Dérivation des paramètres
a = (n * np.sum(XY) - np.sum(X) * np.sum(Y)) / (n * np.sum(X_2) - (np.sum(X)**2))
b = np.average(Y) - a * np.average(X)
print('a', a)
print('b', b)
Y = a * X + b
plt.plot(X, Y)
plt.show()
La sortie du résultat vers la commande est indiquée ci-dessous.
a 2.15
b -0.75
Il semble que la pente soit de 2,15 et la section de -0,75. Le graphique est également présenté ci-dessous. Comme vous pouvez le voir, j'ai pu bien dessiner une fonction linéaire. En passant, le changement d'erreur peut être exprimé comme une fonction à deux variables de $ J (a, b) $. Le graphique 3D est présenté ci-dessous. Les coordonnées du point rouge $ (x, y, z) = (2.15, -0.75, 16.6) $ indiquent les valeurs de $ a $ et $ b $ obtenues cette fois, et la valeur de l'erreur $ J $. Comme vous pouvez le voir sur le graphique, cette coordonnée est la valeur minimale. Pour le moment, je publierai le code source, alors essayez-le et voyez par vous-même.
import numpy as np
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D
fig = plt.figure()
ax = Axes3D(fig)
#Définition de la fonction J
def Er(a, b, y_2, xy, y, x_2, x, n):
return y_2-2*a*xy-2*b*y+a**2*x_2+2*a*b*x+n*b**2
#Données à utiliser
X = np.array([1, 2, 3, 4, 5, 6, 7, 8, 9])
Y = np.array([2, 5, 3, 7, 12, 11, 15, 16, 19])
#Nombre de données
n = Y.size
#Produit de X et Y
XY = X * Y
#Carré de chaque élément de X
X_2 = X * X
#Dérivation des paramètres
a = (n * np.sum(XY) - np.sum(X) * np.sum(Y)) / (n * np.sum(X_2) - (np.sum(X)**2))
b = np.average(Y) - a * np.average(X)
print(a)
print(b)
A = np.arange(a, a+0.1, 0.00001)
B = np.arange(b, b+0.1, 0.00001)
A, B = np.meshgrid(A, B)
J = Er(A, B, np.sum(Y*Y), np.sum(XY), np.sum(Y), np.sum(X_2), np.sum(X), n)
ax.plot_wireframe(A, B, J)
j = Er(a, b, np.sum(Y*Y), np.sum(XY), np.sum(Y), np.sum(X_2), np.sum(X), n)
print(j)
ax.scatter(a, b, j, color='red')
ax.set_xlabel("A")
ax.set_ylabel("B")
ax.set_zlabel("J")
plt.show()
Cette fois, c'est une histoire que j'ai essayé d'implémenter la méthode des moindres carrés en Python. La méthode des moindres carrés est l'une des statistiques, et c'est un domaine nécessaire lors de l'étude de l'IA. J'étudie actuellement, donc je vais le laisser comme mémo. Si vous avez des questions, laissez un commentaire.
Recommended Posts