कम से कम वर्ग वर्ग प्रतिगमन कदम-दर-चरण रैखिक बीजगणित संगणना


22

R में रैखिक-मिश्रित मॉडल के बारे में एक प्रश्न के लिए एक प्रस्तावना के रूप में, और शुरुआती / मध्यवर्ती आंकड़ों aficionados के लिए एक संदर्भ के रूप में साझा करने के लिए, मैंने एक स्वतंत्र "क्यू एंड ए-स्टाइल" के रूप में पोस्ट करने का फैसला किया "मैनुअल की गणना" में शामिल कदम गुणांक और एक सरल रैखिक प्रतिगमन के अनुमानित मूल्यों।

इसका उदाहरण R- निर्मित डेटासेट के साथ है mtcars, और इसे एक गैलन के रूप में मीलों प्रति गैलन की खपत के रूप में स्थापित किया जाएगा, जो स्वतंत्र चर के रूप में कार्य करता है, जो कार के वजन (निरंतर चर) और सिलेंडर की संख्या से अधिक है। तीन स्तरों के साथ कारक (4, 6 या 8) बातचीत के बिना।

EDIT: यदि आप इस प्रश्न में रुचि रखते हैं, तो आप निश्चित रूप से CV के बाहर मैथ्यू ड्र्यूरी द्वारा इस पोस्ट में एक विस्तृत और संतोषजनक उत्तर पाएंगे ।


जब आप "मैनुअल कम्प्यूटेशन" कहते हैं, तो आप क्या चाहते हैं? पैरामीटर अनुमानों और इतने पर (ग्राम-श्मिट orthogonalization के माध्यम से, उदाहरण के लिए, या SWEEP ऑपरेटरों द्वारा) प्राप्त करने के लिए अपेक्षाकृत सरल चरणों की एक श्रृंखला दिखाना अपेक्षाकृत सरल है, लेकिन यह नहीं है कि आर आंतरिक रूप से गणना कैसे करता है; यह (और अधिकांश अन्य आँकड़े पैकेज) क्यूआर अपघटन का उपयोग करता है (साइट पर कई पोस्ट में चर्चा की गई - क्यूआर अपघटन पर एक खोज कई पदों को बदल देती है, जिनमें से कुछ आपको सीधे मूल्य मिल सकते हैं)
Glen_b -Reinstate Monica

हाँ। मेरा मानना ​​है कि एमडी के उत्तर में यह बहुत अच्छी तरह से पता था कि मुझे शायद अपने पोस्ट को संपादित करना चाहिए, शायद मेरे जवाब के पीछे ज्यामितीय दृष्टिकोण पर जोर देना चाहिए - कॉलम स्पेस, प्रोजेक्शन मैट्रिक्स ...
एंटोनी परेलाडा

हां! @ मैथ्यू ड्र्यू क्या आप चाहते हैं कि मैं ओपी में उस लाइन को मिटा दूं, या लिंक को अपडेट करूं?
एंटनी परेलाडा

1
यकीन नहीं है कि अगर आपके पास यह लिंक है, लेकिन यह बारीकी से संबंधित है, और मुझे वास्तव में जेएम का जवाब पसंद है। आँकड़े.स्टैकएक्सचेंज.com
डु

जवाबों:


51

नोट : मैंने अपनी वेबसाइट पर इस उत्तर का एक विस्तारित संस्करण पोस्ट किया है ।

क्या आप कृपया वास्तविक आर इंजन के साथ एक समान उत्तर पोस्ट करने पर विचार करेंगे?

ज़रूर! खरगोश के छेद के नीचे हम जाते हैं।

पहली परत है lm, इंटरफ़ेस आर प्रोग्रामर के संपर्क में। आप lmआर कंसोल पर केवल टाइप करके इसके लिए स्रोत को देख सकते हैं । इसका अधिकांश हिस्सा (अधिकांश उत्पादन स्तर कोड की तरह) इनपुट की जाँच, ऑब्जेक्ट विशेषताओं की स्थापना और त्रुटियों को फेंकने में व्यस्त है; लेकिन यह रेखा चिपक गई

lm.fit(x, y, offset = offset, singular.ok = singular.ok, 
                ...)

lm.fitएक और आर फ़ंक्शन है, आप इसे स्वयं कह सकते हैं। हालांकि lm, सूत्र और डेटा फ़्रेम के साथ आसानी से काम करता है, lm.fitमैट्रिसेस चाहता है, इसलिए यह एब्सट्रैक्शन का एक स्तर हटा दिया गया है। lm.fitअधिक व्यस्तता, और निम्नलिखित वास्तव में दिलचस्प लाइन के लिए स्रोत की जाँच करना

z <- .Call(C_Cdqrls, x, y, tol, FALSE)

अब हम कहीं पहुँच रहे हैं। .CallC कोड में कॉल करने का R का तरीका है। कहीं न कहीं R स्रोत में C फ़ंक्शन, C_Cdqrls है, और हमें इसे खोजने की आवश्यकता है। यहाँ यह है

सी फ़ंक्शन को देखते हुए, फिर से, हम ज्यादातर सीमा जाँच, त्रुटि सफाई, और व्यस्त काम पाते हैं। लेकिन यह लाइन अलग है

F77_CALL(dqrls)(REAL(qr), &n, &p, REAL(y), &ny, &rtol,
        REAL(coefficients), REAL(residuals), REAL(effects),
        &rank, INTEGER(pivot), REAL(qraux), work);

तो अब हम अपनी तीसरी भाषा पर हैं, R ने C को बुलाया है जिसे फोरट्रान कहा जाता है। यहाँ फोरट्रान कोड है

पहली टिप्पणी यह ​​सब बताती है

c     dqrfit is a subroutine to compute least squares solutions
c     to the system
c
c     (1)               x * b = y

(दिलचस्प रूप से, ऐसा लगता है कि इस दिनचर्या का नाम किसी बिंदु पर बदल दिया गया था, लेकिन कोई व्यक्ति टिप्पणी अपडेट करना भूल गया)। इसलिए हम अंत में उस बिंदु पर हैं जहां हम कुछ रैखिक बीजगणित कर सकते हैं, और वास्तव में समीकरणों की प्रणाली को हल कर सकते हैं। यह इस तरह की बात है कि फोरट्रान वास्तव में अच्छा है, जो बताता है कि हम यहां पहुंचने के लिए इतनी सारी परतों से क्यों गुजरे।

टिप्पणी यह ​​भी बताती है कि कोड क्या करने जा रहा है

c     on return
c
c        x      contains the output array from dqrdc2.
c               namely the qr decomposition of x stored in
c               compact form.

इसलिए फोरट्रान अपघटन का पता लगाकर सिस्टम को हल करने जा रहा है ।QR

पहली चीज जो होती है, और अब तक सबसे महत्वपूर्ण है, वह है

call dqrdc2(x,n,n,p,tol,k,qraux,jpvt,work)

यह dqrdc2हमारे इनपुट मैट्रिक्स पर फोरट्रान फ़ंक्शन को कॉल करता है x। यह क्या है?

 c     dqrfit uses the linpack routines dqrdc and dqrsl.

इसलिए हमने आखिरकार इसे लिनपैक कर दिया है । Linpack एक फोरट्रान रैखिक बीजगणित पुस्तकालय है जो लगभग 70 के दशक से है। सबसे गंभीर रेखीय बीजगणित की घटना लिनेपैक के लिए अपना रास्ता ढूंढती है। हमारे मामले में, हम dqrdc2 फ़ंक्शन का उपयोग कर रहे हैं

c     dqrdc2 uses householder transformations to compute the qr
c     factorization of an n by p matrix x.

यह वह जगह है जहाँ वास्तविक काम किया जाता है। मेरे लिए एक अच्छा पूरा दिन लगेगा कि यह कोड क्या कर रहा है, यह उतना ही निम्न स्तर है जितना वे आते हैं। लेकिन आम तौर पर, हमारे पास एक मैट्रिक्स और हम इसे एक उत्पाद एक्स = क्यू आर में बदलना चाहते हैं जहां क्यू एक ऑर्थोगोनल मैट्रिक्स है और आर एक ऊपरी त्रिकोणीय मैट्रिक्स है। यह करने के लिए एक स्मार्ट चीज है, क्योंकि एक बार जब आप क्यू और आर करते हैं, तो आप प्रतिगमन के लिए रैखिक समीकरणों को हल कर सकते हैंXX=QRQRQR

XtXβ=XtY

बहुत आसानी से। वास्तव में

XtX=RtQtQR=RtR

तो पूरी व्यवस्था बन जाती है

RtRβ=RtQty

लेकिन ऊपरी त्रिकोणीय है और इसमें एक्स टी एक्स के समान रैंक है , इसलिए जब तक हमारी समस्या अच्छी तरह से सामने आती है, यह पूर्ण रैंक है, और हम केवल कम सिस्टम को हल कर सकते हैंRXtX

Rβ=Qty

लेकिन यहां कमाल की बात है। ऊपरी त्रिकोणीय है, इसलिए यहां अंतिम रैखिक समीकरण बस है , इसलिए t n के लिए हल करना तुच्छ है। इसके बाद आप पंक्तियाँ, एक के बाद एक तक जा सकता है, और में स्थानापन्न βRconstant * beta_n = constantβnβQR


4
यह सबसे मजेदार गणितीय / कोडिंग लघु निबंध है जिसकी कोई कल्पना कर सकता है। मुझे पता है कि कोडिंग के बारे में कुछ भी नहीं पता है, लेकिन एक सहज रूप से सहज आर फ़ंक्शन के हिम्मत के माध्यम से आपका "दौरा" वास्तव में आंख खोलने वाला था। बेहतरीन लेखन! चूंकि "कृपया" चाल किया ... आप कर सकते हैं कृपया पर विचार यह एक एक संबंधित चुनौती के रूप में? :-)
एंटोनी परेलादा

6
+1 मैंने इससे पहले अच्छा सारांश नहीं देखा था। बस मामले में थोड़ी जानकारी जोड़ने के लिए @Antoni हाउसहोल्डर परिवर्तनों से परिचित नहीं है; यह अनिवार्य रूप से एक रेखीय परिवर्तन है जो आपको आर मैट्रिक्स के एक हिस्से को शून्य करने की अनुमति देता है जिसे आप उन हिस्सों को बिना हिलाए जिन्हें आप पहले ही निपटा चुके हैं (जब तक आप इसे सही क्रम में जाते हैं), इसे आदर्श बनाते हुए मैट्रिसेस को ऊपरी त्रिकोणीय रूप में बदलने के लिए (Givens rotations एक समान काम करते हैं और शायद कल्पना करना आसान है, लेकिन थोड़ा धीमा हैं)। जैसा कि आप R का निर्माण करते हैं, आपको उसी समय Q
Glen_b -Reinstate Monica का

2
मैथ्यू (+1), मेरा सुझाव है कि आप अपने पोस्ट को अपने अधिक विस्तृत राइट-अप madrury.github.io/jekyll/update/2016/07/20/lm-in-R.html के लिंक के साथ शुरू या समाप्त करें ।
अमीबा का कहना है कि मोनिका को बहाल करो

3
-1 मशीन से कोडिंग के लिए और नीचे नहीं जाने के लिए।
एस। कोलासा - मोनिका को बहाल करना

3
(क्षमा करें, बस मजाक कर ;-)
एस। कोलासा -

8

R में वास्तविक चरण-दर-चरण गणनाओं को मैथ्यू ड्र्यू द्वारा इस एक ही सूत्र में उत्तर में खूबसूरती से वर्णित किया गया है। इस उत्तर में मैं स्वयं को साबित करने की प्रक्रिया से गुजरना चाहता हूं कि एक सरल उदाहरण के साथ R में परिणाम स्तंभ स्थान पर अनुमानों के रैखिक बीजगणित और विभिन्न पदों में सचित्र (डॉट उत्पाद) त्रुटियों की अवधारणा के बाद पहुंचा जा सकता है। , और रेखीय बीजगणित और इसके अनुप्रयोगों में डॉ। स्ट्रैंग द्वारा अच्छी तरह से समझाया गया है , और यहां आसानी से पहुँचा जा सकता है

βप्रतिगमन में ,

mpg=intercept(cyl=4)+β1weight+D1intercept(cyl=6)+D2intercept(cyl=8)[]

D1D2X इस प्रकार,) डमी सिलेंडरों की संख्या के लिए कोडिंग:

attach(mtcars)    
x1 <- wt

    x2 <- cyl; x2[x2==4] <- 1; x2[!x2==1] <-0

    x3 <- cyl; x3[x3==6] <- 1; x3[!x3==1] <-0

    x4 <- cyl; x4[x4==8] <- 1; x4[!x4==1] <-0

    X <- cbind(x1, x2, x3, x4)
    colnames(X) <-c('wt','4cyl', '6cyl', '8cyl')

head(X)
        wt 4cyl 6cyl 8cyl
[1,] 2.620    0    1    0
[2,] 2.875    0    1    0
[3,] 2.320    1    0    0
[4,] 3.215    0    1    0
[5,] 3.440    0    0    1
[6,] 3.460    0    1    0

[] (ऊपर), जहां चार सिलेंडरों की कारों के लिए पहले अवरोधन मेल खाती है, के रूप में lmबिना एक `-1 ', यह सिर्फ लोगों का एक प्रथम स्तंभ की आवश्यकता होगी, लेकिन हम' इस इंटरसेप्ट कॉलम के बिना एक ही परिणाम प्राप्त करेंगे।

βProjMatrix=(XTX)1XT[ProjMatrix][y]=[RegrCoefs](XTX)1XTy=β

X_tr_X_inv <- solve(t(X) %*% X)    
Proj_M <- X_tr_X_inv %*% t(X)
Proj_M %*% mpg

          [,1]
wt   -3.205613
4cyl 33.990794
6cyl 29.735212
8cyl 27.919934

के समान: coef(lm(mpg ~ wt + as.factor(cyl)-1))

HatMatrix=X(XTX)1XT

HAT <- X %*% X_tr_X_inv %*% t(X)

y^X(XTX)1XTyy_hat <- HAT %*% mpg

cyl <- as.factor(cyl); OLS <- lm(mpg ~ wt + cyl); predict(OLS):

y_hat <- as.numeric(y_hat)
predicted <- as.numeric(predict(OLS))
all.equal(y_hat,predicted)
[1] TRUE

1
सामान्य तौर पर, संख्यात्मक कंप्यूटिंग में, मेरा मानना ​​है कि व्युत्क्रम मैट्रिक्स की गणना के बजाय रैखिक समीकरण को हल करना सबसे अच्छा है। इसलिए, मुझे लगता beta = solve(t(X) %*% X, t(X) %*% y)है कि अभ्यास से अधिक सटीक है solve(t(X) %*% X) %*% t(X) %*% y
मैथ्यू डॉरी

आर इसे इस तरह से नहीं करता है - यह एक क्यूआर अपघटन का उपयोग करता है। यदि आप उपयोग किए गए एल्गोरिदम का वर्णन करने जा रहे हैं , तो कंप्यूटर पर मुझे संदेह है कि कोई भी आपके द्वारा दिखाए गए का उपयोग करता है।
मोनिका को बहाल करें - जी। सिम्पसन

एल्गोरिथ्म के बाद नहीं, बस रेखीय बीजगणित के आधार को समझने की कोशिश कर रहा है।
एंटोनी परेलाडा

@AntoniParellada उस मामले में, मैं अभी भी कई स्थितियों में अधिक रोशन रैखिक समीकरणों के संदर्भ में सोच पा रहा हूं।
मैथ्यू ड्र्यू

1
हमारी साइट के उद्देश्यों के लिए इस धागे के परिधीय संबंध को देखते हुए, Rमहत्वपूर्ण गणनाओं के उपयोग को दर्शाने में मूल्य को देखते हुए , मैं यह सुझाव देना चाहूंगा कि आप इसे हमारे ब्लॉग में योगदान देने
whuber
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.