es.davy.ai

Preguntas y respuestas de programación confiables

¿Tienes una pregunta?

Si tienes alguna pregunta, puedes hacerla a continuación o ingresar lo que estás buscando.

¿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.

Tags:  , , ,

Answer

  1. Avatar for 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:

    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 learningRate = 0.01;
    int iterations = 1500;
    
    for (int i = 0; i < iterations; i++)
    {
        double[] y_pred = x.Select(xi => slope_current * xi + intercept_current).ToArray();
        double intercept_derivative = y_pred.Zip(y, (yp, yi) => yp - yi).Average();
        double slope_derivative = x.Zip(y_pred.Zip(y, (yp, yi) => yp - yi), (xi, yd) => xi * yd).Average();
    
        intercept_current -= learningRate * intercept_derivative;
        slope_current -= learningRate * slope_derivative;
    }
    

    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 arrays y_pred e y elemento por elemento, y el método Average se utiliza para calcular la media del array resultante. El método Zip también se utiliza para combinar el array x con la multiplicación elemento por elemento de x 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.

Comments are closed.