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

Я работаю над проблемой машинного обучения и хочу использовать линейную регрессию в качестве алгоритма обучения. Я реализовал 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).

Редактировать 1:

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

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

Затем я изменил normalEqueкод, предложенный на древесной щепе , так что теперь он выглядит так:

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

Однако проблема осталась . Новая функция normalEqueна новых данных, которые не близки к сингулярным, дает разные thetaкак gradientDesc.

Чтобы выяснить, какой алгоритм содержит ошибки, я запустил алгоритм линейной регрессии программного обеспечения для интеллектуального анализа данных Weka на тех же данных. Weka вычислил тета, очень похожий на вывод normalEque, но отличающийся от вывода gradientDesc. Итак, я предполагаю, что normalEqueправильный и в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дает немного меньшую квадратичную ошибку, но разница незначительна. Более того , когда я вычисляю градиент стоимости theta, используя функциюcost(такой же, как тот, который используетсяgradientDesc)Я получил градиент около нуля . То же самое, сделанное на выходе 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

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

6
задан Community 23 May 2017 в 12:00
поделиться