J'ai essayé d'implémenter la descente de gradient et cela fonctionnait correctement lorsque je l'ai testé sur un exemple de jeu de données, mais cela ne fonctionne pas correctement pour le jeu de données Boston.

Pouvez-vous vérifier ce qui ne va pas avec le code. pourquoi je ne reçois pas un vecteur thêta correct?

import numpy as np
from sklearn.datasets import load_boston
from sklearn.model_selection import train_test_split

X = load_boston().data
y = load_boston().target

X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.3, random_state=42)
X_train1 = np.c_[np.ones((len(X_train), 1)), X_train]
X_test1 = np.c_[np.ones((len(X_test), 1)), X_test]

eta = 0.0001
n_iterations = 100
m = len(X_train1)
tol = 0.00001

theta = np.random.randn(14, 1)

for i in range(n_iterations):
    gradients = 2/m * X_train1.T.dot(X_train1.dot(theta) - y_train)
    if np.linalg.norm(X_train1) < tol:
        break
    theta = theta - (eta * gradients)

Je reçois mon vecteur de poids sous la forme (14, 354). Qu'est-ce que je fais mal ici?

2
user_6396 17 mars 2019 à 21:26

2 réponses

Meilleure réponse

Considérez ceci (déroulé certaines déclarations pour une meilleure visibilité):

for i in range(n_iterations):
    y_hat = X_train1.dot(theta)
    error = y_hat - y_train[:, None]
    gradients = 2/m * X_train1.T.dot(error)

    if np.linalg.norm(X_train1) < tol:
        break
    theta = theta - (eta * gradients)

Puisque y_hat est (n_samples, 1) et y_train est (n_samples,) - pour votre exemple n_samples est 354 - vous devez amener y_train à la même dimension avec un tour d'axe fictif y_train[:, None].

1
Artem Trunov 17 mars 2019 à 21:03

Y_train est ici un tableau NP à 1 dimension (ndim = 1) tandis que X_train1.dot (theta) est un tableau NP 2-D (ndim = 2). Lorsque vous effectuez une soustraction, y_train est diffusé dans la même dimension que l'autre. Pour résoudre ce problème, vous pouvez également convertir le y_train en un tableau 2D. Vous pouvez le faire par y_train.reshape (-1,1).

for i in range(n_iterations):
gradients = 2/m * X_train1.T.dot(X_train1.dot(theta) - y_train.reshape(-1,1))
if np.linalg.norm(X_train1) < tol:
    break
theta = theta - (eta * gradients)
1
RebornCodeLover 17 mars 2019 à 21:22