6

私は機械学習の問題に取り組んでおり、学習アルゴリズムとして線形回帰を使用したいと考えています。線形回帰モデルのパラメーターを見つけるためにtheta、最急降下法と法線方程式の2つの異なる方法を実装しました。同じデータで、両方ともほぼ等しいthetaベクトルを与える必要があります。しかし、そうではありません。

両方のthetaベクトルは、最初の要素を除いてすべての要素で非常に似ています。これは、データに追加された1つすべてのベクトルを乗算するために使用されるものです。

sは次のようになります(最初の列は最theta急降下法の出力、2番目の列は正規方程式の出力です):

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:

回答とコメントに基づいて、コードをいくつかチェックし、いくつかのテストを実行しました。

まず、 @ user1489497の回答で示唆されているように、Xビーイングが特異点に近いことが問題の原因であるかどうかを確認したいと思います。だから私はpinvをinvに置き換えました-そしてそれを実行すると本当に警告が出Matrix is close to singular or badly scaled.ました。それが問題ではないことを確認するために、私ははるかに大きなデータセットを取得し、この新しいデータセットでテストを実行しました。今回は警告と使用をinv(X)表示せず、同じ結果になりました。だから私はそれがもう特異に近くないことを願っています。pinvinvX

次に、 woodchipsが提案するようにコードを変更normalEqueしたので、次のようになります。

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

しかし、問題はまだあります。normalEque特異に近くない新しいデータの新しい関数は、thetaとして異なるものを与えますgradientDesc

どのアルゴリズムにバグがあるかを調べるために、同じデータに対してデータマイニングソフトウェアWekaの線形回帰アルゴリズムを実行しました。Wekaは、の出力と非常によく似ていますnormalEqueが、の出力とは異なるシータを計算しましたgradientDescnormalEqueですから、それは正しく、にバグがあるgradientDescと思います。

thetaこれがWekaによって計算されたsの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

Justin Peelの回答で示唆されているように、エラーも計算しました。の出力でnormalEqueは、二乗誤差はわずかに少なくなりますが、差はわずかです。さらに、関数を使用するコストの勾配(で使用されるものと同じ)を計算すると、ゼロに近い勾配が得thetacostgradientDescられました。の出力で同じことを行うと、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

これは、最急降下法が単に大域的最小値に収束しなかったことを示唆します...しかし、私が何千回も繰り返し実行しているので、それはほとんど当てはまりません。では、バグはどこにありますか?

4

4 に答える 4

7

私はついにこれに戻る時間がありました。「バグ」はありません。

行列が特異行列の場合、解は無限にあります。そのセットから任意のソリューションを選択して、同様に良い答えを得ることができます。pinv(X)* y解は、最小ノルム解であるため、多くの人が好む優れた解です。

inv(X)*yを使用する正当な理由はありません。さらに悪いことに、正規方程式で逆関数を使用することです。したがって、inv(X'* X)*X'*yは単なる数値のがらくたです。誰がそれを使うように言ったのかは気にしない、彼らはあなたを間違った場所に案内している。(はい、それはよく調整された問題に対しては許容できるように機能しますが、ほとんどの場合、それがいつあなたにがらくたを与えようとしているのかわかりません。それで、なぜそれを使うのですか?)

正則化された問題を解いている場合でも、通常の方程式は一般に悪いことです。システムの条件数を二乗しないようにする方法はいくつかありますが、この回答が十分に長くなっているので、尋ねられない限り説明しません。

X \ yも、妥当な結果をもたらします。

制約のないオプティマイザを問題にスローする理由はまったくありません。これにより、開始値に完全に依存する不安定な結果が生成されるためです。

例として、私は特異な問題から始めます。

X = repmat([1 2],5,1);
y = rand(5,1);

>> X\y
Warning: Rank deficient, rank = 1, tol =  2.220446e-15. 
ans =
                         0
         0.258777984694222

>> pinv(X)*y
ans =
         0.103511193877689
         0.207022387755377

pinvとバックスラッシュはわずかに異なるソリューションを返します。結局のところ、Xの行空間に任意の量の零空間ベクトルを追加できる基本的な解決策があります。

null(X)
ans =
         0.894427190999916
        -0.447213595499958

pinvは最小ノルム解を生成します。結果として生じた可能性のあるすべてのソリューションの中で、これには最低2ノルムがあります。

対照的に、バックスラッシュは、1つ以上の変数がゼロに設定されるソリューションを生成します。

ただし、制約のないオプティマイザを使用すると、開始値に完全に依存するソリューションが生成されます。繰り返しになりますが、そのヌルベクトルのANLY量をソリューションに追加できますが、エラーの二乗和の値が同じである、完全に有効なソリューションがあります。

特異性警告が返されない場合でも、これは行列が特異に近くないことを意味する必要はないことに注意してください。あなたは問題についてほとんど変わっていないので、それはまだ近いです、ただ警告を引き起こすのに十分ではありません。

于 2012-06-30T15:49:05.700 に答える
2

他の人が述べたように、悪条件のヘッセ行列が問題の原因である可能性があります。

標準勾配降下アルゴリズムが局所最適に到達するために取るステップ数は、ヘッセ行列の最大固有値を最小値で割った関数です(これはヘッセ行列の条件数として知られています)。したがって、行列の条件が悪い場合、最急降下法が最適に収束するまでに非常に多くの反復が必要になる可能性があります。(もちろん、特異な場合は、多くの点に収束する可能性があります。)

制約のない最適化アルゴリズムが問題に対して機能することを確認するために、3つの異なることを試すことをお勧めします(そうする必要があります):1)ランダム入力の既知の線形関数の結果を計算し、少量のガウスノイズを追加して合成データを生成します。ディメンションよりも多くのデータポイントがあることを確認してください。これにより、非特異なヘッセ行列が生成されます。2)正則化項を誤差関数に追加して、ヘッセ行列の条件数を増やします。3)アルゴリズムが収束するために必要なステップ数を減らすために、勾配降下法ではなく共役勾配法やL-BFGSなどの2次法を使用します。(おそらくこれを#2と組み合わせて行う必要があります)。

于 2012-07-02T17:15:15.510 に答える
1

Xがどのように見えるかについてもう少し投稿していただけますか?ムーア・ペンローズ疑似逆行列であるpinv()を使用しています。行列の条件が悪い場合、逆行列の取得で問題が発生する可能性があります。最急降下法の方がマークに近いと思います。

于 2012-06-30T05:46:19.997 に答える
0

どの方法が実際に最小のエラーを与えているかを確認する必要があります。これは、どの方法が苦労しているのかを示します。Xの条件が悪いと、そこで問題が発生する可能性があるため、通常の方程式の方法が問題のある解決策であると思われます。

theta = X\yおそらく、QR分解法を使用して解く通常の方程式の解を置き換える必要があります。

于 2012-06-30T05:36:14.357 に答える