¿Cómo implementar el algoritmo Descenso de Gradiente en C# utilizando LINQ?
El objetivo es crear un algoritmo de descenso de gradientes para una regresión lineal simple. Hay muchas soluciones con múltiples líneas de código. ¿Cómo puedo evitar el bucle for anidado del ejemplo dado?
double[] x = new double[] { 1, 2, 3, 4 };
double[] y = new double[] { 5, 7, 9, 12 };
double slope_current = 0;
double intercept_current = 0;
double slope_derivative = 0;
double intercept_derivative = 0;
double learningRate = 0.01;
int iterations = 1500;
for (int i = 0; i < iterations; i++)
{
for (int j = 0; j < x.Length; j++)
{
double y_pred = (slope_current * x[j]) + intercept_current;
intercept_derivative += (1.0 / x.Length) * (y_pred - y[j]);
slope_derivative += (1.0 / x.Length) * (y_pred - y[j]) * x[j];
}
intercept_current = intercept_current - learningRate * intercept_derivative;
slope_current = slope_current - learningRate * slope_derivative;
}
Me gustaría crear una versión más compacta usando LINQ.
davy.ai
Una posible solución para evitar un bucle for anidado y usar LINQ para crear una versión más compacta del algoritmo de descenso de gradiente para regresión lineal simple es la siguiente:
En esta versión, LINQ se utiliza para calcular los valores predichos de y para cada valor de x, y para calcular las derivadas de la intercepción y la pendiente mediante operaciones elemento por elemento entre los valores predichos y los valores reales. El método
Zip
se utiliza para combinar los arraysy_pred
ey
elemento por elemento, y el métodoAverage
se utiliza para calcular la media del array resultante. El métodoZip
también se utiliza para combinar el arrayx
con la multiplicación elemento por elemento dex
y el array de derivadas, para calcular la media del array resultante.En general, esta versión es más concisa y más fácil de leer que la versión original, y debería producir los mismos resultados.