El método de descenso de gradiente y ecuación normal para resolver la regresión lineal da diferentes soluciones

Estoy trabajando en un problema de aprendizaje automático y quiero usar la regresión lineal como algoritmo de aprendizaje. He implementado 2 métodos diferentes para encontrar parámetros.theta del modelo de regresión lineal: descenso de gradiente (más pronunciado) y ecuación normal. En los mismos datos ambos deben dar aproximadamente igualtheta vector. Sin embargo no lo hacen.

Ambostheta Los vectores son muy similares en todos los elementos, pero el primero. Ese es el usado para multiplicar el vector de todos los 1 agregados a los datos.

Aquí es cómo elthetas parece que (la primera columna es la salida de Pendiente descendente, la segunda salida de la ecuación Normal):

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

¿Qué puede causar la diferencia entheta(1, 1) regresado por pendiente de gradiente en comparación contheta(1, 1) devuelto por la ecuación normal? ¿Tengo error en mi código?

Aquí está mi implementación de la ecuación normal en Matlab:

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

Aquí está el código para el descenso del gradiente:

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

Yo paso exactamente los mismos datosX yy a ambas funciones (no normalizoX).

Edición 1:

Basándome en las respuestas y los comentarios, revisé algunos códigos y realicé algunas pruebas.

Primero quiero comprobar si el problema puede deberse a que X esté cerca del singular como lo sugiereLa respuesta de @ user1489497. Así que reemplacé a pinv por inv, y cuando lo ejecuté realmente obtuve una advertenciaMatrix is close to singular or badly scaled.. Para asegurarme de que ese no es el problema, obtuve un conjunto de datos mucho más grande y ejecuté pruebas con este nuevo conjunto de datos. Esta vezinv(X) no mostró la advertencia y el usopinv yinv Dio los mismos resultados. Así que espero queX Ya no está cerca de singular.

EntoncesCambiénormalEque código como se sugiere porastillas de madera así que ahora se ve como:

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

Sin embargo el problema sigue ahí.. NuevonormalEque Funcionar sobre nuevos datos que no están cerca de singular da diferentestheta comogradientDesc.

Para averiguar qué algoritmo tiene errores, he ejecutado el algoritmo de regresión lineal del software de minería de datos Weka en los mismos datos. Weka computa theta muy similar a la salida denormalEque pero diferente a la salida degradientDesc. Así que supongo quenormalEque es correcto yhay un error engradientDesc.

Aquí está la comparación dethetas calculado por Weka,normalEque yGradientDesc:

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

También calculé errores según lo sugerido porLa respuesta de justin peel. Salida denormalEque da un error al cuadrado ligeramente menor pero la diferencia es marginal. Qué es máscuando calculo gradiente de costo detheta usando la funcióncost (igual a la utilizada porgradientDesc) Tengo gradiente cerca de cero. Lo mismo se hace en la salida degradientDesc No da gradiente cerca de cero. Esto es lo que quiero decir:

>> [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

Esto sugeriría que el descenso del gradiente simplemente no converge al mínimo global ... Pero ese no es el caso, ya que lo ejecuto durante miles de iteraciones.Entonces, ¿dónde está el error?

Respuestas a la pregunta(4)

Su respuesta a la pregunta