2

我正在尝试在java中实现线性回归。我的假设是 theta0 + theta1 * x[i]。我试图找出 theta0 和 theta1 的值,以使成本函数最小。我正在使用梯度下降来找出值 -

在里面

while(repeat until convergence)
{
   calculate theta0 and theta1 simultaneously.
}

这是什么重复直到收敛?我知道这是局部最小值,但我应该在 while 循环中放入的确切代码是什么?

我对机器学习非常陌生,刚刚开始编写基本算法以获得更好的理解。任何帮助将不胜感激。

4

5 回答 5

15

梯度下降是最小化给定函数的迭代方法。我们从解决方案的初始猜测开始,然后在该点获取函数的梯度。我们在梯度的负方向上逐步求解,并重复该过程。该算法最终将在梯度为零的地方收敛(对应于局部最小值)。所以你的工作是找出使损失函数最小化的 theta0 和 theta1 的值[例如最小二乘误差]。术语“收敛”意味着您达到了局部最小值,并且进一步的迭代不会影响参数的值,即 theta0 和 theta1 的值保持不变。让我们看一个例子 注意:假设它在这个解释的第一象限。

在此处输入图像描述

假设您必须最小化函数 f(x) [在您的情况下的成本函数]。为此,您需要找出使 f(x) 的函数值最小化的 x 值。这是使用梯度下降法找出 x 值的分步过程

  1. 您选择 x 的初始值。假设它在图中的 A 点。
  2. 您计算 f(x) 在 A 处相对于 x 的梯度。
  3. 这给出了函数在 A 点的斜率。由于函数在 A 处增加,因此将产生一个正值。
  4. 您从 x 的初始猜测中减去这个正值并更新 xie 的值x = x - [Some positive value]。这使 x 更接近 D [即最小值] 并降低了 f(x) [来自图] 的函数值。假设在第 1 次迭代之后,您到达了 B 点。
  5. 在 B 点,您重复步骤 4 中提到的相同过程并到达 C 点,最后到达 D 点。
  6. 在 D 点,因为它是局部最小值,所以当你计算梯度时,你得到 0 [或非常接近 0]。现在您尝试更新 x ie 的值x = x - [0]。您将获得相同的 x [或更接近前一个 x 的值]。这种情况称为“收敛”。上述步骤用于增加斜率,但同样适用于减小斜率。例如,G 点处的梯度会导致某个负值。当您更新 x 即x = x - [ negative value] = x - [ - some positive value] = x + some positive value。这增加了 x 的值,并使 x 接近点 F [或接近最小值]。

有多种方法可以解决这种梯度下降。正如@mattnedrich 所说,两种基本方法是

  1. 使用固定的迭代次数 N,因为这个伪代码将是

    iter = 0
    while (iter < N) {
      theta0 = theta0 - gradient with respect to theta0
      theta1 = theta1 - gradient with respect to theta1
      iter++
    }
    
  2. 重复直到 theta0 和 theta1 的两个连续值几乎相同。@Gerwin 在另一个答案中给出了伪代码。

梯度下降是线性回归中最小化函数的方法之一。也有直接的解决办法。批处理(也称为正规方程)可用于在单个步骤中找出 theta0 和 theta1 的值。如果 X 是输入矩阵,y 是输出向量,theta 是您要计算的参数,那么对于平方误差方法,您可以使用此矩阵方程一步找到 theta 的值

theta = inverse(transpose (X)*X)*transpose(X)*y

但是由于这包含矩阵计算,当矩阵 X 的大小很大时,显然它比梯度下降的计算成本更高。我希望这可以回答您的问题。如果没有,请告诉我。

于 2014-01-13T05:53:44.433 回答
4

梯度下降是一种优化算法(准确地说是最小化,最大化也有梯度上升)。在线性回归的情况下,我们最小化成本函数。它属于基于梯度的优化家族,其思想是当成本被负梯度减去时,会将其从成本曲面的山坡上移至最优。

在您的算法中,重复直到收敛意味着直到您达到成本曲面/曲线中的最佳点,这是在某些迭代的梯度非常接近零时确定的。在这种情况下,该算法被称为收敛(可能处于局部最优,很明显梯度下降在许多情况下收敛到局部最优)

要确定您的算法是否已收敛,您可以执行以下操作:

calculate gradient
theta = theta -gradientTheta
while(True):
    calculate gradient
    newTheta = theta - gradient
    if gradient is very close to zero and abs(newTheta-Theta) is very close to zero:
       break from loop # (The algorithm has converged)
    theta = newTheta

有关线性回归和梯度下降以及其他优化的详细信息,您可以遵循 Andrew Ng 的说明:http ://cs229.stanford.edu/notes/cs229-notes1.pdf 。

于 2014-01-13T06:25:43.267 回答
1

您需要在 while 循环中执行以下操作:

while (some condition is not met)
    // 1) Compute the gradient using theta0 and theta1
    // 2) Use the gradient to compute newTheta0 and newTheta1 values
    // 3) Set theta0 = newTheta0 and theta1 = newTheta1

您可以使用几种不同的标准来终止梯度下降搜索。例如,您可以运行梯度下降

  1. 对于固定次数的迭代
  2. 直到 (theta0, theta1) 处的梯度值足够接近零(表示最小值)

每次迭代你都应该越来越接近最优解。也就是说,如果您计算每次迭代的误差(theta0、theta1 模型​​预测数据的好坏),它应该会越来越小。

要了解有关如何实际编写此代码的更多信息,您可以参考:
https ://www.youtube.com/watch?v=CGHDsi_l8F4&list=PLnnr1O8OWc6ajN_fNcSUz9k5gF_E9huF0 https://www.youtube.com/watch?v=kjes46vP5m8&list=PLnnr1O8OWc6asSH0wOMn5JjgSlqNiK2C4

于 2014-01-11T18:31:30.453 回答
1

最初将theta[0]and分配theta[1]给一些任意值,然后计算您假设的值(theta[0] +theta[1]*x1),然后通过梯度下降算法计算theta[0]and theta[1]。通过算法:

theta[0](new) = theta[0](old) - alpha*[partialderivative(J(theta[0],theta[1]) w.r.t theta[0])

theta[1](new) = theta[1](old) - alpha*[partialderivative(J(theta[0],theta[1]) w.r.t theta[1])

其中 alpha:学习率

J(theta[0],theta[1])=cost function

您将获得theta[0]and的新值theta[1]。然后,您需要再次计算假设的新值。重复计算theta[0]and的这个过程theta[1],直到 and 之间的theta[i](new)theta[i](old)小于0.001

详情参考:http ://cs229.stanford.edu/notes/cs229-notes1.pdf

于 2014-04-16T22:47:17.883 回答
1

我对梯度下降不太了解,但我们学习了另一种计算点数线性回归的方法:

http://en.wikipedia.org/wiki/Simple_linear_regression#Fitting_the_regression_line

但如果你真的想添加 while 循环,我建议如下:

最终,theta0 和 theta1 将收敛到某个值。这意味着,无论您应用该公式的频率如何,它都将始终保持在该值附近。(http://en.wikipedia.org/wiki/(%CE%B5,_%CE%B4)-definition_of_limit)。

所以再次应用代码不会对 theta0 和 theta1 有太大的改变,只会改变很小的量。或者:theta0(1) 和下一个 theta0(1) 之间的差异小于一定的量。

这将我们带到以下代码:

double little = 1E-10;
do {
$theta0 = theta0;
$theta1 = theta1;
// now calculate the new theta0, theta1 simultaneously.
} while(Math.abs(theta0-$theta0) + Math.abs(theta1-$theta1)>little);
于 2014-01-11T16:04:54.113 回答