Récemment, l'apprentissage automatique, l'intelligence artificielle, etc. sont devenus populaires, et je pense que la connaissance des statistiques qui en constituent la base est importante. Par conséquent, je voudrais essayer d'expliquer le principe de l'analyse de régression, dont l'effet est facile à comprendre même en statistique, dans le but de pouvoir le comprendre conceptuellement tout en calculant et en dessinant des graphiques en Python. Je ne suis pas statisticien, donc si vous avez des suggestions ou des commentaires, n'hésitez pas à me contacter. Je pense qu'il y a certains points qui ne sont pas mathématiquement stricts, mais pardonnez-moi s'il vous plaît ...
Tout d'abord, récupérez l'ensemble de données.
Cette page utilise Python pour l'explication, mais les données utilisées sont les données des voitures de l'ensemble de données dans le logiciel d'analyse statistique R. Veuillez télécharger et utiliser les données csv depuis ici. (Cependant, selon la description de ces données, cela ressemble aux données des années 1920, il ne s'agit donc que d'un exemple de données.) Dans cette explication, on suppose qu'il est enregistré sous "cars.csv".
teble definition of cars data
[,0] index
[,1] speed numeric Speed (mph)
[,2] dist numeric Stopping distance (ft)
Une explication détaillée des données peut être trouvée sur ici, mais la vitesse de la voiture et son Ce sont des données qui collectent 50 ensembles de distance d'arrêt lorsque le frein est actionné à grande vitesse.
Python utilise la version 2.7. On suppose également que les bibliothèques suivantes sont déjà installées.
Importez-les.
import numpy as np
import matplotlib.pyplot as plt
Lisez les données et dessinez d'abord un diagramme de dispersion. Pour obtenir une image des données, il est facile de dessiner un graphique.
Soit dit en passant, étant donné que les données d'origine sont une unité qui n'est pas familière aux Japonais, comme les miles et les pieds, nous convertirons l'unité en mètres.
1 pied ≒ 0,3048 mètres 1 mph ≒ 1.61 km/h Alors, convertissez l'unité de données comme suit.
data= np.loadtxt('cars.csv',delimiter=',',skiprows=1)
data[:,1] = map(lambda x: x * 1.61, data[:,1]) #km de mph/Convertir en h
data[:,2] = map(lambda y: y * 0.3048, data[:,2]) #Convertir de ft en m
Ensuite, dessinez un diagramme de dispersion basé sur ces données.
fig = plt.figure(figsize=(10,6))
ax = fig.add_subplot(111)
ax.set_title("Stopping Distances of Cars")
ax.set_xlabel("speed(km/h)")
ax.set_ylabel("distance(m)")
plt.scatter(data[:,1],data[:,2])
En utilisant ces données, une analyse de régression peut être utilisée pour déterminer dans quelle mesure une voiture roulant à une certaine vitesse peut s'arrêter complètement lorsqu'elle freine brusquement. En d'autres termes
distance = \alpha * speed + \beta
Il peut être exprimé par une équation linéaire comme indiqué dans. C'est ce qu'on appelle une analyse de régression simple. (Puisqu'il n'y a qu'une seule variable, elle est "unique".) Cet ajustement linéaire est parfois appelé une approximation du premier ordre. $ \ Alpha $ est la pente de la ligne droite et $ \ beta $ est la valeur de la section. Appelons cette ligne droite une ligne droite approximative.
J'essaierai d'appliquer une ligne droite à cela visuellement. Le graphique que j'ai appliqué visuellement est ci-dessous, mais j'ai mis $ \ alpha $ à 0,74 et $ \ beta $ à -5. comment c'est? N'est-il pas probable qu'une telle ligne droite puisse être appliquée d'une manière ou d'une autre?
# y = 0.74x -5 lignes droites((0,-5),(50,32)Traverser)
x = [0, 50]
y = [-5, 32]
plt.plot(x,y)
Cependant, je viens de l'appliquer visuellement, donc je ne sais pas si c'est vraiment la meilleure ligne droite. Voyons comment trouver les optimales $ \ alpha $ et $ \ beta $, la méthode des moindres carrés.
Quelle est la méthode des moindres carrés et quel est le «minimum»? Qu'est-ce que vous «carré»?
Le minimum est l'erreur entre la ligne droite et les données. L'erreur est la ligne verticale tracée de chaque point à la ligne droite approximative. Voir le graphique ci-dessous.
# line: y = 0.74 -5
x = [0, 50]
y = [-5, 32]
plt.plot(x,y)
# draw errors
for d in data:
plt.plot([d[1],d[1]],[d[2],d[1]*0.74-5],"k")
L'erreur est représentée par cette ligne noire. Intuitivement, j'estime que la ligne droite qui additionne toutes ces erreurs est la moins appropriée pour ces données.
Voyons ce qui se passe lorsque vous modifiez $ \ alpha $ ou $ \ beta $ pour la ligne droite que vous avez appliquée visuellement précédemment.
Tout d'abord, jetons un œil à la ligne droite qui a changé $ \ alpha $.
# line: y = 0.54x -5
x = [0, 50]
y = [-5, 72]
plt.plot(x,y)
# draw errors
for d in data:
plt.plot([d[1],d[1]],[d[2],d[1]*1.54-5],"k")
Jetons un coup d'œil au $ \ beta $ modifié.
# line: y = 0.74x +15
x = [0, 50]
y = [15, 52]
plt.plot(x,y)
# draw errors
for d in data:
plt.plot([d[1],d[1]],[d[2],d[1]*0.74+15],"k")
Comment c'est? Il semble que cette erreur soit petite lorsque vous dessinez pour la première fois une ligne droite approximative qui semble bonne visuellement et celle qui ose décaler $ \ alpha $ et $ \ beta $. La méthode des moindres carrés est une méthode pour trouver $ \ alpha $ et $ \ beta $ qui minimise cette erreur.
Cela corrige également l'erreur. La raison est que je veux trouver la distance entre la ligne droite et la ligne droite reliant les points de chaque donnée, mais si elle est laissée telle quelle, l'erreur sera positive pour les données au-dessus de la ligne droite et négative pour les données en dessous, donc au carré. Ensuite, prenez le plus et le moins et rendez tout positif.
Maintenant que vous savez ce qu'il faut mettre au carré et minimiser, procédons au calcul concret.
D'abord de la définition des termes. La $ i $ th donnée est $ x_i, y_i $, et son approximation est $ \ hat {y} _i $.
Aussi, laissez l'erreur être $ \ epsilon_i $. Développons les 19èmes données.
i = 18
x_i = data[i,1]
y_i = data[i,2]
y_hat = x_i*0.74-5
ax.set_ylim(0,y_i+3)
ax.set_xlim(x_i-5,x_i+5)
plt.plot([x_i,x_i],[y_i,y_hat],"k")
plt.plot(x,y)
plt.scatter([x_i],[y_i])
Maintenant, si vous corrigez cette erreur et ajoutez toutes les données,
S = \sum_i^n\epsilon_i^2=\sum_i^n (y_i-\hat{y}_i )^2
Peut être exprimé comme.
\hat{y}_i = \alpha x_i + \beta
Donc, si vous remplacez les données de valeur approximative, ce sera comme suit.
S = \sum_i^n \epsilon_i^2 = \sum_i^n ( y_i-\alpha x_i - \beta )^2
La droite approximative optimale peut être obtenue en différenciant ce $ S $ avec les paramètres $ \ alpha et \ beta $ et en trouvant la valeur minimale. Exprimant ce $ S $ par l'équation de $ \ alpha $,
S(\alpha) = \left( \sum_i^n x_i^2 \right) \alpha^2
+ 2\left( \sum_i^n (x_i\beta - x_i y_i ) \right) \alpha
+ n\beta^2 - 2\beta\sum_i^n y_i + \sum_i^n y_i^2
Sera. Quel genre de fonction est ce $ S (\ alpha) $? C'est une fonction quadratique de $ \ alpha $. Puisque le coefficient de $ \ alpha $ est la somme des carrés, il vaut toujours 0 ou une valeur positive, il s'agit donc d'une fonction quadratique convexe vers le bas. Ici, dessinons un graphique en supposant que $ \ beta = 0 $ pour donner une image de la forme.
S(\alpha) = \left( \sum_i^n x_i^2 \right) \alpha^2
- 2\left( \sum_i^n x_i y_i \right) \alpha
+ \sum_i^n y_i^2 ... (if \beta = 0 )
Ça sera facile. Calculons ce coefficient à partir des données.
sum_x2 = np.sum([x ** 2 for x in data[:,1]]) # \sum x_i^2
sum_y2 = np.sum([x ** 2 for y in data[:,2]]) # \sum y_i^2
sum_xy = data[:,1].dot(data[:,2]) # \sum x_i y_i
print sum_x2
>>> 34288.2988
print sum_y2
>>> 11603.8684051
print sum_xy
>>> 18884.194896
Donc,
S(\alpha) ≒ 34288 \alpha^2 - 37768 \alpha + 11604
Lorsque vous dessinez ce graphique,
x1 = np.linspace(-1,5,200)
x1_2 = np.array([x ** 2 for x in x1])
#34288α2−37768α+ 11604
y1 = np.array(34288 * x1_2) - (37768 * x1) + 11604
plt.plot(x1,y1)
# Y =Ligne de 11604
plt.plot([-1,5],[11604, 11604])
plt.plot([0,0],[13000, 0], "--k")
Si vous décalez $ \ alpha $, vous trouverez la valeur minimale quelque part.
De même pour $ \ beta $
S(\beta) = n\beta^2
+ 2 \left( \sum_i^n (x_i\alpha - y_i) \right) \beta
+ \alpha^2\sum_i^n x_i^2 - 2\alpha \sum_i^n x_iy_i + \sum_i^n y_i^2
Trouvons un graphique en supposant que $ \ alpha = 0 $.
S(\beta) = n\beta^2
- 2 \left( \sum_i^n y_i \right) \beta + \sum_i^n y_i^2
... (if \alpha = 0 )
Puisqu'il n'y avait pas de $ \ sum y_i $ dans la valeur calculée précédemment, quand je l'ai calculée (et aussi $ \ sum x_i $),
sum_x = np.sum(data[:,1])
print sum_x
>>> 1239.7
sum_y = np.sum(data[:,2])
print sum_y
>>> 655.0152
Par conséquent, l'équation quadratique pour $ \ beta $ est
S(\beta) ≒ 50\beta^2 - 1310 \beta + 11604
Et dessinez un graphique
x1 = np.arange(-100,100,0.01)
x1_2 = np.array([x ** 2 for x in x1])
n = len(data[:,2])
# nβ^2-1310β+11604
y1 = np.array(n * x1_2) - (1310 * x1) + 11604
fig = plt.figure(figsize=(10,6))
ax = fig.add_subplot(111)
ax.set_xlim(-5,30)
ax.set_ylim(0,20000)
ax.set_xlabel("beta")
plt.plot([-50,30],[11604,11604],"g")
plt.plot([0,0],[30000,0],"--k")
plt.plot(x1,y1)
Et, après tout, si vous décalez $ \ beta $, vous pouvez voir qu'un certain $ \ beta $ prend la valeur minimale.
Passez à la Partie 2.
Recommended Posts