Метод градиентного спуска и нормального уравнения для решения линейной регрессии дает разные решения

Я работаю над проблемой машинного обучения и хочу использовать линейную регрессию в качестве алгоритма обучения. Я реализовал 2 разных метода, чтобы найти параметрыtheta модели линейной регрессии: градиентный (самый крутой) спуск и нормальное уравнение. По одним и тем же данным они оба должны давать примерно равныеtheta вектор. Однако они этого не делают.

И то и другоеtheta векторы очень похожи на все элементы, кроме первого. Это тот, который используется для умножения вектора на все 1, добавленные к данным.

Вот какthetas выглядит как (первый столбец - это градиентный спуск, второй вывод нормального уравнения):

Grad desc Norm eq
-237.7752 -4.6736
-5.8471   -5.8467
9.9174    9.9178
2.1135    2.1134
-1.5001   -1.5003
-37.8558  -37.8505
-1.1024   -1.1116
-19.2969  -19.2956
66.6423   66.6447
297.3666  296.7604
-741.9281 -744.1541
296.4649  296.3494
146.0304  144.4158
-2.9978   -2.9976
-0.8190   -0.8189

Что может вызвать разницу вtheta(1, 1) возвращается градиентным спуском по сравнению сtheta(1, 1) вернулся по нормальному уравнению? У меня есть ошибка в моем коде?

Вот моя реализация нормального уравнения в Matlab:

function theta = normalEque(X, y)
    [m, n] = size(X);
    X = [ones(m, 1), X];
    theta = pinv(X'*X)*X'*y;
end

Вот код для градиентного спуска:

function theta = gradientDesc(X, y)
    options = optimset('GradObj', 'on', 'MaxIter',  9999);
    [theta, ~, ~] = fminunc(@(t)(cost(t, X, y)),...
                    zeros(size(X, 2), 1), options);
end

function [J, grad] = cost(theta, X, y)
    m = size(X, 1);
    X = [ones(m, 1), X];
    J = sum((X * theta - y) .^ 2) ./ (2*m);
    for i = 1:size(theta, 1)
        grad(i, 1) = sum((X * theta - y) .* X(:, i)) ./ m;
    end
end

Я передаю точно такие же данныеX а такжеy к обеим функциям (я не нормализуюX).

Edit 1:

Основываясь на ответах и комментариях, я немного проверил свой код и провел несколько тестов.

Сначала я хочу проверить, может ли проблема быть вызвана тем, что X находится вблизи единственного числа, как это было предложено@ user1489497 ответ, Поэтому я заменил pinv на inv - и когда я его запустил, я действительно получил предупреждениеMatrix is close to singular or badly scaled., Чтобы убедиться, что это не проблема, я получил гораздо больший набор данных и провел тесты с этим новым набором данных. Этот разinv(X) не отображать предупреждение и использованиеpinv а такжеinv дал те же результаты. Так что я надеюсь чтоX is not close to singular any more.

затемI changed normalEque code as suggested отщепки так что теперь это выглядит так:

function theta = normalEque(X, y)
    X = [ones(size(X, 1), 1), X];
    theta = pinv(X)*y;
end

However the problem is still there, новыйnormalEque Функция на новых данных, которые не близки к единственному, дает разныеtheta какgradientDesc.

Чтобы выяснить, какой алгоритм содержит ошибки, я запустил алгоритм линейной регрессии программного обеспечения для интеллектуального анализа данных Weka на тех же данных. Weka вычислил тета очень похожий на выводnormalEque но отличается от выводаgradientDesc, Так что я думаю, чтоnormalEque правильно иthere is a bug in gradientDesc.

Вот сравнениеthetas вычисляется Weka,normalEque а такжеGradientDesc:

Weka(correct) normalEque    gradientDesc
779.8229      779.8163      302.7994
  1.6571        1.6571        1.7064
  1.8430        1.8431        2.3809
 -1.5945       -1.5945       -1.5964
  3.8190        3.8195        5.7486
 -4.8265       -4.8284      -11.1071
 -6.9000       -6.9006      -11.8924
-15.6956      -15.6958      -13.5411
 43.5561       43.5571       31.5036
-44.5380      -44.5386      -26.5137
  0.9935        0.9926        1.2153
 -3.1556       -3.1576       -1.8517
 -0.1927       -0.1919       -0.6583
  2.9207        2.9227        1.5632
  1.1713        1.1710        1.1622
  0.1091        0.1093        0.0084
  1.5768        1.5762        1.6318
 -1.3968       -1.3958       -2.1131
  0.6966        0.6963        0.5630
  0.1990        0.1990       -0.2521
  0.4624        0.4624        0.2921
-12.6013      -12.6014      -12.2014
 -0.1328       -0.1328       -0.1359

Я также рассчитал ошибки, как это было предложеноОтвет Джастина Пила, Выход изnormalEque дает немного меньшую квадратичную ошибку, но разница незначительна. Что большеwhen I compute gradient of cost of theta using function cost (the same as the one used by gradientDesc) I got gradient near zero, То же самое сделано на выходеgradientDesc не дает градиент около нуля. Вот что я имею в виду:

>> [J_gd, grad_gd] = cost(theta_gd, X, y, size(X, 1));
>> [J_ne, grad_ne] = cost(theta_ne, X, y, size(X, 1));
>> disp([J_gd, J_ne])
  120.9932  119.1469
>> disp([grad_gd, grad_ne])
  -0.005172856743846  -0.000000000908598
  -0.026126463200876  -0.000000135414602
  -0.008365136595272  -0.000000140327001
  -0.094516503056041  -0.000000169627717
  -0.028805977931093  -0.000000045136985
  -0.004761477661464  -0.000000005065103
  -0.007389474786628  -0.000000005010731
   0.065544198835505  -0.000000046847073
   0.044205371015018  -0.000000046169012
   0.089237705611538  -0.000000046081288
  -0.042549228192766  -0.000000051458654
   0.016339232547159  -0.000000037654965
  -0.043200042729041  -0.000000051748545
   0.013669010209370  -0.000000037399261
  -0.036586854750176  -0.000000027931617
  -0.004761447097231  -0.000000027168798
   0.017311225027280  -0.000000039099380
   0.005650124339593  -0.000000037005759
   0.016225097484138  -0.000000039060168
  -0.009176443862037  -0.000000012831350
   0.055653840638386  -0.000000020855391
  -0.002834810081935  -0.000000006540702
   0.002794661393905  -0.000000032878097

Это предполагает, что градиентный спуск просто не сходится к глобальному минимуму ... Но это вряд ли так, поскольку я запускаю его тысячи итераций.So where is the bug?

Ответы на вопрос(4)

Ваш ответ на вопрос