Régression Linéaire : Calcul Matriciel
On reprend le dataset de la partie précédente.
- m nombre d’échantillons dans le dataset ( ici 50 )
- n nombre de variables dans le dataset ( ici 1 )
Le Modèle sous forme matricielle
est une matrice contenant a et b :
X est une matrice contenant :
- l’ensemble des coordonnées x des échantillons
- une colonne de biais ( 1 )
On considère :
En effet :
Je retrouve donc bien, pour chaque i, l’expression de l’équation du modèle :
REMARQUE : Dimension des matrices :
- dim(F) = [m x 1]
- dim(X) = [m*(n + 1)]
- dim()= [(n + 1) x 1]
# Matrice X
X = np.hstack((x,np.ones(x.shape))) # collage de 2 vecteurs l'un à côté de l'autre ( horizontal stack )
# THETA = [a,b] , ce qu'on cherche, y=ax+b
THETA = np .random.randn(2,1) # valeurs initiales aléatoires
print('THETA =', THETA)
MODEL = X.dot(THETA)
plt.scatter(x, y, label="Nuage de points", color="blue", alpha=0.6)
plt.plot(x, MODEL, label="Courbe de tendance y = ax + b", color="red", linewidth=2)
# Ajout des barres entre les points réels et la courbe de tendance
for i in range(len(x)):
plt.plot([x[i][0], x[i][0]], [y[i][0], MODEL[i][0]], color="gray", linestyle="--", linewidth=0.8)
plt.xlabel("X")
plt.ylabel("Y")
plt.title("Nuage de points et courbe de tendance avec erreurs")
plt.legend()
plt.grid(True)
plt.show()
THETA =
[[ 0.76672273]
[-0.02675862]]
Fonction Coût
J est un scalaire ( moyenne de toutes les erreurs ), dim(J) = [1 x 1]
Y est une matrice contenant l’ensemble des coordonnées y des échantillons:
J devient alors :
Calcul du Gradient
Lors de la présentation de la régression linéaire, nous avions :
Nous pouvons alors considérer la matrice :
Reprenons X :
Algorithme de descente du gradient
Devient :
#-----------------------------------------------------------------
def model( X, theta ):
return X.dot(theta)
#-----------------------------------------------------------------
# Fonction coût
def J(X, y, theta):
m=len(y)
return 1/(2*m) * np.sum((model(X,theta) - y)**2)
#-----------------------------------------------------------------
# Calcul du Gradient
def grad(X,y ,theta):
m = len(y)
return (1/m) * X.T.dot( model(X, theta) - y)
#-----------------------------------------------------------------
def gradient_descent(X, y, theta, alpha, n_iterations):
J_history = np.zeros(n_iterations)
for i in range(0, n_iterations):
theta = theta - alpha * grad(X, y, theta)
J_history[i] = J(X, y, theta)
return theta, J_history
#-----------------------------------------------------------------
#-----------------------------------------------------------------
n_iterations = 1000
alpha = 0.01 # learning rate
THETA_final, J_hist = gradient_descent(X, y, THETA, alpha, n_iterations)
print('THETA_final = ',THETA_final)
plt.figure(figsize=(10, 6))
plt.scatter(x, y, label="Nuage de points", color="blue", alpha=0.6)
plt.plot(x,model(X,THETA_final), label="Courbe de tendance y = ax + b", color="red", linewidth=2)
# Ajout des barres entre les points réels et la courbe de tendance
for i in range(len(x)):
plt.plot([x[i][0], x[i][0]], [y[i][0], model(X,THETA_final)[i][0]], color="gray", linestyle="--", linewidth=0.8)
plt.xlabel("X")
plt.ylabel("Y")
plt.title("Modèle déterminé par l'algorithme de la descente du gradient")
plt.legend()
plt.grid(True)
plt.show()
THETA_final =
[[ 56.55848319]
[-38.5156578 ]]
plt.figure()
plt.plot(J_hist)
plt.xlabel("n_iterations")
plt.ylabel("J")
plt.title("Evolution de J")
plt.grid(True)
plt.show()