2012-04-26 14 views
10

मैं आर के साथ तय हो गई प्रभाव रेखीय प्रतीपगमन करने के लिए कोशिश कर रहा हूँ मेरे डेटा लग रहा हैमैट्रिक्स गुणा गुणांक के लिए ठीक काम करता है जबकि एलएम स्मृति से बाहर क्यों चलाता है?

तरह
dte yr id v1 v2 
    . . . . . 
    . . . . . 
    . . . . . 

मैं तो बस yr एक कारक बना कर ऐसा करते हैं और प्रयोग lm करने का फैसला किया:

lm(v1 ~ factor(yr) + v2 - 1, data = df) 

हालांकि, ऐसा लगता है कि स्मृति से बाहर निकलता है। मेरे कारक में 20 स्तर हैं और df 14 मिलियन पंक्तियां हैं जो लगभग 2 जीबी स्टोर करने में लगती हैं, मैं इसे इस प्रक्रिया के लिए समर्पित 22 जीबी वाली मशीन पर चला रहा हूं। t20 को t1 करके मेरी वर्षों में से प्रत्येक के लिए डमी चर बनाने:

मैं तो बातें पुराने जमाने तरह से कोशिश करने का फैसला किया

df$t1 <- 1*(df$yr==1) 
df$t2 <- 1*(df$yr==2) 
df$t3 <- 1*(df$yr==3) 
... 

और बस की गणना:

solve(crossprod(x), crossprod(x,y)) 

यह बिना चलाता है एक समस्या और जवाब लगभग तुरंत उत्पन्न करता है।

मैं विशेष रूप से उत्सुक हूं कि यह एलएम के बारे में क्या है जो इसे गुणांक से बाहर निकाल देता है जब मैं गुणांक की गणना कर सकता हूं ठीक है? धन्यवाद।

+5

कारण है कि आप को कम करने की कोशिश नहीं है '' बजाय lm' की lm.fit' मुसीबत? 'lm.fit' क्यूआर अपघटन के माध्यम से बस कम या कम" कच्चा "रैखिक मॉडल फिटिंग करता है - मॉडल मैट्रिक्स सृजन आदि के बारे में अपर्याप्त सामानों में से कोई भी नहीं .. यदि आपको 'lm.fit' के साथ मेमोरी समस्याएं भी मिलती हैं, तो @ जेक का जवाब मुद्दा होगा (सामान्य समीकरण बनाम क्यूआर)। –

उत्तर

8

अब तक के किसी भी उत्तर ने सही दिशा की ओर इशारा नहीं किया है।

@idr द्वारा स्वीकृत उत्तर lm और summary.lm के बीच भ्रम पैदा कर रहा है। lm सभी पर कोई नैदानिक ​​आंकड़े नहीं बनाते हैं; इसके बजाय, summary.lm करता है। तो वह summary.lm के बारे में बात कर रहा है।

@Jake का उत्तर क्यूआर कारककरण और LU/Choleksy कारककरण की संख्यात्मक स्थिरता पर एक तथ्य है। Aravindakshan का जवाब दोनों परिचालनों के पीछे फ्लोटिंग पॉइंट ऑपरेशंस की मात्रा को इंगित करके, इसे विस्तारित करता है (हालांकि जैसा कि उसने कहा था, वह मैट्रिक्स क्रॉस उत्पाद की गणना के लिए लागत में नहीं गिना गया था)। लेकिन, स्मृति लागत के साथ एफएलओपी गणना को भ्रमित मत करो। वास्तव में दोनों विधिओं में LINPACK/LAPACK में समान स्मृति उपयोग होता है। विशेष रूप से, उनका तर्क है कि क्यूआर विधि Q कारक को स्टोर करने के लिए अधिक रैम खर्च करती है, यह एक फर्जी है। lm(): What is qraux returned by QR decomposition in LINPACK/LAPACK में समझाया गया कॉम्पैक्ट स्टोरेज स्पष्ट करता है कि क्यूआर कारककरण की गणना और संग्रह कैसे किया जाता है। क्यूआर बनाम की गति मुद्दा चोल मेरे उत्तर में विस्तृत है: Why the built-in lm function is so slow in R?, और faster lm पर मेरा उत्तर Choleksy विधि का उपयोग करके एक छोटी दिनचर्या lm.chol प्रदान करता है, जो क्यूआर विधि से 3 गुना तेज है।

@Gregbiglm के लिए उत्तर/सुझाव अच्छा है, लेकिन यह सवाल का जवाब नहीं देता है। चूंकि biglm का उल्लेख किया गया है, मैं इंगित करता हूं कि QR decomposition differs in lm and biglmbiglm घरेलू प्रतिबिंब की गणना करता है ताकि परिणामस्वरूप R कारक में सकारात्मक विकर्ण हो। विवरण के लिए Cholesky factor via QR factorization देखें। कारण यह है कि biglm ऐसा करता है, परिणामस्वरूप R Cholesky कारक के समान होगा, जानकारी के लिए QR decomposition and Choleski decomposition in R देखें। इसके अलावा, biglm के अलावा, आप mgcv का उपयोग कर सकते हैं। मेरा उत्तर पढ़ें: biglm predict unable to allocate a vector of size xx.x MB और अधिक के लिए।


एक सारांश के बाद, यह समय मेरा उत्तर पोस्ट करने के लिए है।

आदेश एक रेखीय मॉडल फिट करने के लिए, lm होगा

  1. एक मॉडल फ्रेम उत्पन्न करता है;
  2. एक मॉडल मैट्रिक्स उत्पन्न करता है;
  3. क्यूआर कारककरण के लिए lm.fit पर कॉल करें;
  4. क्यूआर कारक के परिणाम के साथ-साथ lmObject में मॉडल फ्रेम का परिणाम देता है।

आपने कहा कि 5 कॉलम के साथ आपका इनपुट डेटा फ्रेम स्टोर करने के लिए 2 जीबी खर्च करता है। 20 कारक स्तरों के साथ परिणामी मॉडल मैट्रिक्स में लगभग 25 कॉलम 10 जीबी स्टोरेज लेते हैं। अब देखते हैं कि जब हम lm पर कॉल करते हैं तो स्मृति उपयोग कैसे बढ़ता है।

  • [वैश्विक वातावरण] शुरू में आप डेटा फ्रेम के लिए 2 जीबी भंडारण है,
  • [lm envrionment] तो यह 2 जीबी की लागत वाले मॉडल फ्रेम पर कॉपी किया गया है;
  • [lm पर्यावरण] तो मॉडल मॉडल मैट्रिक्स उत्पन्न होता है, जिससे 10 जीबी की लागत होती है;
  • [lm.fit पर्यावरण] मॉडल मैट्रिक्स की एक प्रति तब क्यूआर कारककरण द्वारा ओवरराइट की गई है, जो 10 जीबी की लागत है;
  • [lm पर्यावरण]lm.fit का परिणाम वापस आ गया है, 10 जीबी की लागत;
  • [वैश्विक पर्यावरण]lm.fit का परिणाम lm द्वारा वापस लौटाया गया है, और 10 जीबी की लागत है;
  • [वैश्विक पर्यावरण] मॉडल फ्रेम lm द्वारा 2 जीबी की लागत लौटा दिया गया है।

तो, कुल 46 जीबी रैम की आवश्यकता है, जो आपके उपलब्ध 22 जीबी रैम से कहीं अधिक है।

दरअसल यदि lm.fitlm में "रेखांकित" किया जा सकता है, तो हम 20 जीबी लागतों को बचा सकते हैं। लेकिन किसी अन्य आर समारोह में आर फंक्शन को इनलाइन करने का कोई तरीका नहीं है।

हो सकता है कि हम यह देखने के लिए कि क्या चारों ओर lm.fit होता है एक छोटा सा उदाहरण ले सकते हैं:

X <- matrix(rnorm(30), 10, 3) # a `10 * 3` model matrix 
y <- rnorm(10) ## response vector 

tracemem(X) 
# [1] "<0xa5e5ed0>" 

qrfit <- lm.fit(X, y) 
# tracemem[0xa5e5ed0 -> 0xa1fba88]: lm.fit 

तो वास्तव में, X जब lm.fit में पारित कर दिया की नकल की है। क्या qrfit है

str(qrfit) 
#List of 8 
# $ coefficients : Named num [1:3] 0.164 0.716 -0.912 
# ..- attr(*, "names")= chr [1:3] "x1" "x2" "x3" 
# $ residuals : num [1:10] 0.4 -0.251 0.8 -0.966 -0.186 ... 
# $ effects  : Named num [1:10] -1.172 0.169 1.421 -1.307 -0.432 ... 
# ..- attr(*, "names")= chr [1:10] "x1" "x2" "x3" "" ... 
# $ rank   : int 3 
# $ fitted.values: num [1:10] -0.466 -0.449 -0.262 -1.236 0.578 ... 
# $ assign  : NULL 
# $ qr   :List of 5 
# ..$ qr : num [1:10, 1:3] -1.838 -0.23 0.204 -0.199 0.647 ... 
# ..$ qraux: num [1:3] 1.13 1.12 1.4 
# ..$ pivot: int [1:3] 1 2 3 
# ..$ tol : num 1e-07 
# ..$ rank : int 3 
# ..- attr(*, "class")= chr "qr" 
# $ df.residual : int 7 

ध्यान दें कि कॉम्पैक्ट क्यूआर मैट्रिक्स qrfit$qr$qr मॉडल मैट्रिक्स X के रूप में बड़ा है पर एक नजर है। यह lm.fit के अंदर बनाया गया है, लेकिन lm.fit के बाहर निकलने पर, इसकी प्रतिलिपि बनाई गई है। तो कुल मिलाकर, हमारे पास X की 0 "प्रतियां" होंगी:

  • वैश्विक वातावरण में मूल एक;
  • एक को lm.fit में कॉपी किया गया, क्यूआर कारककरण द्वारा ओवरराइट किया गया;
  • एक lm.fit द्वारा लौटाया गया।

आपके मामले में, X 10 जीबी है, इसलिए स्मृति lm.fit के साथ जुड़े लागत अकेले पहले से ही 30 जीबी है। lm से जुड़े अन्य लागतों को अकेले छोड़ दें।


दूसरी ओर, के पर

solve(crossprod(X), crossprod(X,y)) 

X लेता है 10 जीबी एक नजर डालते हैं, लेकिन crossprod(X) केवल एक 25 * 25 मैट्रिक्स है, और crossprod(X,y) सिर्फ लंबाई -25 वेक्टर है। वे X की तुलना में बहुत छोटे हैं, इस प्रकार स्मृति उपयोग बिल्कुल बढ़ता नहीं है।

शायद आप चिंतित हैं कि की स्थानीय प्रतिलिपि बनाई जाएगी जब crossprod कहा जाता है? हर्गिज नहीं! lm.fit के विपरीत जो X पर पढ़ और लिखते हैं, crossprod केवल X पढ़ता है, इसलिए कोई प्रतिलिपि नहीं बनाई जाती है। हम से हमारे खिलौना मैट्रिक्स X के साथ इस की पुष्टि कर सकते हैं:

tracemem(X) 
crossprod(X) 

आप कोई नकल संदेश देखेंगे!


यदि आपने उपरोक्त सभी के लिए एक संक्षिप्त सारांश चाहते हैं, यहाँ यह है:lm.fit(X, y) के लिए

  • स्मृति लागत (या यहां तक ​​कि .lm.fit(X, y)) कि solve(crossprod(X), crossprod(X,y)) के लिए जितनी बड़ी तीन बार है,
  • मॉडल फ्रेम से मॉडल मैट्रिक्स कितना बड़ा है, इस पर निर्भर करता है कि lm के लिए मेमोरी लागत solve(crossprod(X), crossprod(X,y)) के लिए 3 ~ 6 गुना अधिक है। निचला बाउंड 3 कभी नहीं पहुंचा है, जबकि ऊपरी बाउंड 6 तब तक पहुंच जाती है जब मॉडल मैट्रिक्स मॉडल फ्रेम के समान होता है। यह मामला है जब है वहाँ कोई कारक चर या "कारक एक जैसे" शब्द, bs() और poly(), आदि जैसे
7

lm आपकी इनपुट सुविधाओं के लिए गुणांक खोजने के अलावा बहुत कुछ करता है। उदाहरण के लिए, यह नैदानिक ​​आंकड़े प्रदान करता है जो आपको अपने स्वतंत्र चरों पर गुणांक के बारे में अधिक बताता है जिसमें मानक त्रुटि और आपके प्रत्येक स्वतंत्र चर के टी मान शामिल हैं।

मुझे लगता है कि इन नैदानिक ​​आंकड़ों को समझना महत्वपूर्ण है जब यह समझने के लिए कि आपके प्रतिगमन कितना मान्य है।

ये अतिरिक्त गणना lm को रिग्रेशन के लिए मैट्रिक्स समीकरणों को हल करने के बजाय धीमे होने के कारण होती है।

उदाहरण के लिए

, mtcars डेटासेट का उपयोग करके:

>data(mtcars) 
>lm_cars <- lm(mpg~., data=mtcars) 
>summary(lm_cars) 

Call:               
lm(formula = mpg ~ ., data = mtcars)       

Residuals:              
    Min  1Q Median  3Q  Max      
-3.4506 -1.6044 -0.1196 1.2193 4.6271      

Coefficients:             
      Estimate Std. Error t value Pr(>|t|)    
(Intercept) 12.30337 18.71788 0.657 0.5181    
cyl   -0.11144 1.04502 -0.107 0.9161    
disp   0.01334 0.01786 0.747 0.4635    
hp   -0.02148 0.02177 -0.987 0.3350    
drat   0.78711 1.63537 0.481 0.6353    
wt   -3.71530 1.89441 -1.961 0.0633 .    
qsec   0.82104 0.73084 1.123 0.2739    
vs   0.31776 2.10451 0.151 0.8814    
am   2.52023 2.05665 1.225 0.2340    
gear   0.65541 1.49326 0.439 0.6652    
carb  -0.19942 0.82875 -0.241 0.8122    
---               
Signif. codes: 0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1 

Residual standard error: 2.65 on 21 degrees of freedom   
Multiple R-squared: 0.869,  Adjusted R-squared: 0.8066  
F-statistic: 13.93 on 10 and 21 DF, p-value: 3.793e-07  
+3

हाँ, यह सच है। लेकिन उन अन्य गतिविधियों में से कोई भी एलएम को स्मृति से बाहर निकलने का कारण नहीं बनायेगा – Alex

10

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

9

आप biglm पैकेज का उपयोग करने पर विचार करना चाहेंगे। यह डेटा के छोटे हिस्सों का उपयोग करके एलएम मॉडल फिट बैठता है।

5

जेक के बिंदु पर विस्तार करने के लिए। मान लें कि आपका प्रतिगमन हल करने का प्रयास कर रहा है: y = Ax (ए डिज़ाइन मैट्रिक्स है)। एम अवलोकन और एन स्वतंत्र चर के साथ ए एक एमएक्सएन मैट्रिक्स है। फिर क्यूआर की लागत ~ m*n^2 है। आपके मामले में यह एम = 14x10^6 और एन = 20 जैसा दिखता है। तो m*n^2 = 14*10^6*400 एक महत्वपूर्ण लागत है।

हालांकि सामान्य समीकरणों के साथ आप A'A ('ट्रांसपोज़ इंगित करता है) को घुमाने की कोशिश कर रहे हैं, जो वर्ग और आकार nxn है। हल आमतौर पर लू का उपयोग करके किया जाता है जो n^3 = 8000 खर्च करता है। यह क्यूआर की कम्प्यूटेशनल लागत से बहुत छोटा है। बेशक इसमें मैट्रिक्स की लागत गुणा नहीं है।

आगे अगर क्यूआर रूटीन क्यू मैट्रिक्स को स्टोर करने की कोशिश करता है जो आकार mxm=14^2*10^12 (!) है, तो आपकी याददाश्त अपर्याप्त होगी। यह समस्या नहीं होने के लिए क्यूआर लिखना संभव है। यह जानना दिलचस्प होगा कि क्यूआर का संस्करण वास्तव में उपयोग किया जा रहा है। और क्यों वास्तव में lm कॉल स्मृति से बाहर चलाता है।

संबंधित मुद्दे