如何使用 LINQ 在 C# 中实现梯度下降算法?
Posted
技术标签:
【中文标题】如何使用 LINQ 在 C# 中实现梯度下降算法?【英文标题】:How to implement Gradient Descent algorithm in C# using LINQ? 【发布时间】:2022-01-04 12:46:48 【问题描述】:目标是为简单的线性回归创建梯度下降算法。有很多具有多行代码的解决方案。如何避免给定示例中的嵌套 for 循环?
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;
我想使用 LINQ 创建一个更紧凑的版本。
【问题讨论】:
我会问 - 为什么?使用嵌套的 for 循环,代码更具可读性。如果将(1.0 / x.Length) * (y_pred - y[j])
重构为单独的变量,它的可读性会更高。
是的,那样会更易读。但我很好奇 LINQ ***者的解决方案。
【参考方案1】:
可以使用 LINQ 将 for 循环替换为 Sum
和 Zip
函数。
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 = 5000;
for (int i = 0; i < iterations; i++)
double intercept_derivative = (1.0 / x.Length) * x.Zip(y, (x_i, y_i) => (slope_current * x_i + intercept_current) - y_i).Sum();
double slope_derivative = (1.0 / x.Length) * x.Zip(y, (x_i, y_i) => ((slope_current * x_i + intercept_current) - y_i) * x_i).Sum();
slope_current = slope_current - learningRate * slope_derivative;
intercept_current = intercept_current - learningRate * intercept_derivative;
【讨论】:
以上是关于如何使用 LINQ 在 C# 中实现梯度下降算法?的主要内容,如果未能解决你的问题,请参考以下文章
.NET(C#) System.Linq中实现多列group by(分组)的示例代码