matlab - अवकल - रेखीय प्रतिगमन को सुलझाने के लिए ढाल वंश और सामान्य समीकरण विधि अलग समाधान प्रदान करता है




रैखिक समीकरण की परिभाषा (3)

अंत में इस पर वापस जाने के लिए समय था। कोई "बग" नहीं है

यदि मैट्रिक्स एकवचन है, तो असीम रूप से कई समाधान हैं। आप उस सेट से कोई भी समाधान चुन सकते हैं, और समान रूप से उतना ही अच्छा जवाब प्राप्त कर सकते हैं। पिनव (एक्स) * वाई सॉल्यूशन एक अच्छा एक है जो बहुत पसंद है क्योंकि यह न्यूनतम आदर्श समाधान है।

Inv (x) * y का उपयोग करने के लिए कोई अच्छा कारण नहीं है इससे भी बदतर, सामान्य समीकरणों में उलटा उपयोग करना है, इस प्रकार inv (एक्स '* एक्स) * एक्स' * 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

पिनव और बैकस्लैश थोड़ा अलग समाधान लौटाते हैं। जैसा कि यह पता चला है, एक बुनियादी समाधान है, जिसके लिए हम एक्स की पंक्ति स्पेस के लिए किसी भी नल स्पेस वेक्टर को जोड़ सकते हैं।

null(X)
ans =
         0.894427190999916
        -0.447213595499958

pinv न्यूनतम आदर्श समाधान उत्पन्न करता है। जिन सभी समाधानों का परिणाम हो सकता है, उनमें से न्यूनतम 2-आदर्श है

इसके विपरीत, बैकस्लैश एक समाधान उत्पन्न करता है जिसमें एक या अधिक चर शून्य पर सेट हो जाएंगे।

लेकिन यदि आप एक अप्रतिबंधित अनुकूलक का उपयोग करते हैं, तो यह एक ऐसा समाधान उत्पन्न करेगा जो आपके शुरुआती मूल्यों पर पूरी तरह निर्भर है। दोबारा, उस शून्य वेक्टर की राशि को आपके समाधान में जोड़ा जा सकता है, और आपके पास पूरी तरह से वैध समाधान है, त्रुटियों के वर्गों के योग के समान मूल्य के साथ।

ध्यान दें कि भले ही कोई विलक्षणता नहीं लौटाया गया हो, इसका मतलब यह नहीं है कि आपका मैट्रिक्स एकवचन के करीब नहीं है। आप समस्या के बारे में थोड़ा बदल गए हैं, इसलिए यह अभी भी बंद है, सिर्फ चेतावनी को ट्रिगर करने के लिए पर्याप्त नहीं है।

मैं मशीन सीखने की समस्या पर काम कर रहा हूं और सीखने एल्गोरिदम के रूप में रैखिक प्रतिगमन का उपयोग करना चाहता हूं। रैखिक प्रतिगमन मॉडल के मापदंडों को खोजने के लिए मैंने 2 अलग-अलग तरीकों को लागू किया है: ग्रेडियंट (सबसे तेज़) वंश और सामान्य समीकरण। एक ही डेटा पर वे दोनों लगभग बराबर theta वेक्टर देनी चाहिए हालांकि वे नहीं करते हैं

दोनों theta वैक्टर सभी तत्वों पर बहुत समान हैं लेकिन पहले एक। यही वह डेटा है जो सभी 1 के वैक्टर को गुणा करने के लिए उपयोग किया जाता है।

ये है कि कैसे theta तरह दिखता है (मुट्ठी स्तंभ, ढाल वंश का उत्पादन, सामान्य समीकरण का दूसरा उत्पादन):

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) मुकाबले ढाल वंश द्वारा लौटकर सामान्य समीकरण द्वारा लौटाया जा सकता है? क्या मेरे कोड में बग है?

यहां मैटलैब में सामान्य समीकरण का मेरा कार्यान्वयन है:

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 संपादित करें:

उत्तर और टिप्पणियों के आधार पर मैंने अपने कोड में कुछ जाँच की और कुछ परीक्षण चलाए।

सबसे पहले मैं यह जानना चाहता हूं कि एक्सएम के पास एक्स बीइंग की वजह से समस्या का कारण हो सकता है जैसा कि यूजर 1489497 के उत्तर ने सुझाव दिया था। इसलिए मैंने inv द्वारा pinv को बदल दिया - और इसे चलाने पर मुझे वाकई चेतावनी मिली कि Matrix is close to singular or badly scaled. । यह सुनिश्चित करने के लिए कि यह समस्या नहीं है, मैंने बहुत अधिक डाटासेट प्राप्त किया है और इस नए डाटासेट के साथ परीक्षण चलाएं। इस बार inv(X) ने चेतावनी प्रदर्शित नहीं की और pinv और pinv का उपयोग करके समान परिणाम दिए। इसलिए मुझे आशा है कि X किसी भी अधिक के करीब नहीं है

फिर मैं normalEque द्वारा सुझाए अनुसार normalEque कोड को बदल दिया, अब यह ऐसा दिखता है:

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

हालांकि समस्या अभी भी वहां है नया normalEque नए डेटा पर कार्य करना जो एकवचन के करीब नहीं हैं, को अलग- normalEque को gradientDesc रूप में देता gradientDesc

यह पता लगाने के लिए कि बग़ी एल्गोरिथ्म क्या है, मैंने एक ही डेटा पर डेटा खनन सॉफ्टवेयर के Weik को रेखीय प्रतिगमन एल्गोरिदम चलाया है। Weka की गणना थीटा बहुत सामान्य के उत्पादन के समान है, लेकिन gradientDesc के उत्पादन के लिए अलग है। इसलिए मुझे लगता है कि normalEque है सही है और normalEque में एक बग है

यहां Weka, normalEque और GradientDesc normalEque द्वारा की गई theta तुलना है:

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

जस्टिन पील के जवाब में मैंने भी त्रुटियों की गणना की है । सामान्य का आउटपुट थोड़ा कम चुकता त्रुटि देता है लेकिन अंतर सीमांत है। जब मैं थिटे की लागत के ढाल की गणना करता है तो फ़ंक्शन 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

यह सुझाव दे सकता है कि ढाल वाले वंश को केवल वैश्विक न्यूनतम तक नहीं पहुंचना पड़ा ... लेकिन यह शायद ही मामला है क्योंकि मैं इसे हजारों पुनरावृत्तियों के लिए चलाता हूं। तो बग कहां है?


आपको यह देखना चाहिए कि वास्तव में आपको छोटी सी त्रुटि कह रही है। इससे संकेत मिलता है कि किस पद्धति में संघर्ष हो रहा है। मुझे संदेह है कि सामान्य समीकरण विधि परेशान समाधान है क्योंकि अगर एक्स असंगत है तो आपको वहां कुछ समस्याएं हो सकती हैं।

आपको शायद अपने सामान्य समीकरण समाधान को theta = X\y बदलना चाहिए, जो इसे हल करने के लिए QR-decomposition विधि का उपयोग करेगा।


जैसा कि अन्य लोगों ने उल्लेख किया है, एक असुरक्षित हेसियन मैट्रिक्स संभावना आपकी समस्या का कारण है।

मानक ढाल वंश एल्गोरिदम स्थानीय इष्टतम तक पहुंचने के लिए उठाए गए कदमों की संख्या हैसिसियन के सबसे बड़े eigenvalue का एक कार्य है जो छोटे से विभाजित है (यह हेसियन की स्थिति संख्या के रूप में जाना जाता है)। इसलिए, यदि आपका मैट्रिक्स खराब है, तो यह ढाल के वंश के लिए इष्टतम के लिए एक बड़ी संख्या में पुनरावृत्तियों को ले सकता है। (एकवचन के मामले में, यह निश्चित रूप से कई बिंदुओं तक पहुंच सकता है।)

मैं यह सत्यापित करने के लिए सुझाव दे सकता हूं कि आपकी समस्या के लिए एक अपरिमित अनुकूलन एल्गोरिथ्म काम करता है (जो इसे करना चाहिए): 1) यादृच्छिक इनपुट के लिए एक ज्ञात रैखिक फ़ंक्शन के परिणाम की गणना करके और गाऊसी शोर की एक छोटी राशि को जोड़कर कुछ सिंथेटिक डेटा जेनरेट करें । सुनिश्चित करें कि आपके आयाम से अधिक डेटा बिंदु हैं यह एक गैर-विलक्षण हेस्सियन का उत्पादन करना चाहिए। 2) हेसियन की कंडीशन संख्या को बढ़ाने के लिए अपने त्रुटि फ़ंक्शन के लिए एक नियमित नियम जोड़ें। 3) एक दूसरे ऑर्डर पद्धति का प्रयोग करें जैसे संयुग्मक ढाल या एल-बीएफजीएस, बजाय ढाल वंश को एकजुट करने के लिए एल्गोरिदम के लिए आवश्यक चरणों की संख्या को कम करने के लिए। (आपको संभवत: इसे # 2 के साथ संयोजन में करने की आवश्यकता होगी)।