Descenso del gradiente en Python para aproximación.
Estoy tratando de implementar un descenso de gradiente para aproximar los datos. Con la función Y = P0 + P1*X (o y=kx+b), el modelo funciona bien. Aquí está el código completo:
import numpy as np
import matplotlib.pyplot as plt
from sklearn.linear_model import SGDRegressor
def gradient(x, y):
P0 = P1 = P2 = 0
iterations = 100
learning_rate = 100
l = len(x)
for i in range(iterations):
y_predicted = P0 + P1*x
err = (1/l) * sum([val**2 for val in (y-y_predicted)])
if (err) <= 1e-6:
break
# derivetives
P0d = - (2/l) * sum(y - y_predicted)
P1d = - (2/l) * sum(x * (y - y_predicted))
P0 = P0 - learning_rate * P0d
P1 = P1 - learning_rate * P1d
return P0, P1
X = np.asarray([1, 2, 4, 5, 6])
Y = np.asarray([2, 4, 6, 8, 10])
P0, P1 = gradient(X, Y)
pred = P0 + P1*X
plt.figure(1, figsize=(6,4), dpi=120)
plt.scatter(x=X, y=Y, c='red', marker='o', label='Data')
plt.plot(X, pred, '--m', label='Model')
plt.legend()
Pero con la función Y = P0 + P1X + P2(X**2), hay algunos resultados extraños:
import numpy as np
import matplotlib.pyplot as plt
from sklearn.linear_model import SGDRegressor
def gradient(x, y):
P0 = P1 = P2 = 0
iterations = 100
learning_rate = 0.01
l = len(x)
for i in range(iterations):
y_predicted = P0 + P1*x + P2*(x**2)
err = (1/l) * sum([val**2 for val in (y-y_predicted)])
if (err) <= 1e-6:
break
# derivetives
P0d = - (2/l) * sum(y - y_predicted)
P1d = - (2/l) * sum(x * (y - y_predicted))
P2d = - (2/l) * sum(x**2 * (y - y_predicted))
P0 = P0 - learning_rate * P0d
P1 = P1 - learning_rate * P1d
P2 = P2 - learning_rate * P2d
return P0, P1, P2
X = np.asarray([1, 2, 4, 5, 6])
Y = np.asarray([2, 4, 6, 8, 10])
P0, P1, P2 = gradient(X, Y)
pred = P0 + P1*X + P2*X**2
plt.figure(1, figsize=(6,4), dpi=120)
plt.scatter(x=X, y=Y, c='red', marker='o', label='Data')
plt.plot(X, pred, '--m', label='Model')
plt.legend()
Así es como se ve la matemática para el primer modelo:
https://i.stack.imgur.com/8Lznm.png
Estas derivadas me están volviendo loco. Añadí otra derivada parcial Pd3 para el tercer parámetro – ¿por qué salió mal?
davy.ai
La razón por la cual el segundo modelo con Y = P0 + P1X + P2(X**2) no está funcionando como se esperaba es porque las derivadas no son correctas. Cuando hay múltiples parámetros, necesitamos calcular la derivada parcial con respecto a cada parámetro de forma separada.
Para el segundo modelo, las derivadas parciales correctas deberían ser:
– P0d = – (2/l) * suma(y – y_predicho)
– P1d = – (2/l) * suma(x * (y – y_predicho))
– P2d = – (2/l) * suma(x**2 * (y – y_predicho))
Agregando la derivada parcial correcta para P2 debería darnos los valores correctos para los tres parámetros.