2011-06-23 12 views
8

मैं alway मुसीबत कैसे S3 पद्धतियों को बुलाया जाता संबंधी दस्तावेज़ को समझने, और इस समय यह मुझे वापस काट रहा है लिया है के आदेश।S3 और कक्षाओं

मैं एक से अधिक सवाल पूछने के लिए सामने माफी माँगता हूँ, लेकिन वे सभी बारीकी से जुड़े हुए हैं। कार्यों के जटिल सेट के दिल में गहराई से, मैं विशेष रूप से लॉजिस्टिक वाले glmnet फिट करता हूं। अब, glmnet दस्तावेज दोनों वर्गों "ग्लैमनेट" और (लॉजिस्टिक रिग्रेशन के लिए) "लॉगनेट" रखने के लिए इसके वापसी मूल्य को निर्दिष्ट करता है। वास्तव में, ये इस क्रम में निर्दिष्ट हैं।

हालांकि, glmnet के कार्यान्वयन के अंत में की तलाश में, Righter करने के लिए कॉल (आंतरिक समारोह) lognet, कि fit के वर्ग सेट के बाद करने के लिए "lognet", मैं सिर्फ वापसी से पहले कोड की इस पंक्ति को देखने के (चर fit) का:

class(fit) = c(class(fit), "glmnet") 

इस से, मैं निष्कर्ष निकालना होगा कि वर्गों के आदेश "lognet" वास्तव में, "glmnet" है।

दुर्भाग्य से, फिट मैं था, था (doc की तरह चलता है):

> class(myfit) 
[1] "glmnet" "lognet" 

इस के साथ समस्या यह रास्ता S3 तरीकों इसके लिए भेज दिया जाता है विशेष रूप से predict में, है। यहाँ predict.lognet के लिए कोड है:

function (object, newx, s = NULL, type = c("link", "response", 
    "coefficients", "class", "nonzero"), exact = FALSE, offset, 
    ...) 
{ 
    type = match.arg(type) 
    nfit = NextMethod("predict") #<- supposed to call predict.glmnet, I think 
    switch(type, response = { 
     pp = exp(-nfit) 
     1/(1 + pp) 
    }, class = ifelse(nfit > 0, 2, 1), nfit) 
} 

मैं अपने तर्क समझाने के लिए एक टिप्पणी जोड़ दिया है। अब जब मैं एक नया DataMatrix mydata और type="response" के साथ इस myfit पर भविष्यवाणी कहते हैं, इस तरह:

predict(myfit, newx=mydata, type="response") 

, मुझे नहीं पता, प्रलेखन के अनुसार, भविष्यवाणी की संभावनाओं, लेकिन रैखिक संयोजन हो जाता है, जो वास्तव में तुरंत predict.glmnet पर कॉल करने का नतीजा।

मैं वर्गों के आदेश को पलटने की कोशिश की है, इसलिए जैसे:

orgclass<-class(myfit) 
class(myfit)<-rev(orgclass) 

और फिर कर भविष्यवाणी फिर से फोन: लो और निहारना: यह काम करता है! मैं संभावनाएं प्राप्त करता हूं।

तो, यहाँ कुछ सवाल आते हैं:

  1. हूँ सही में 'सीखा होने' कि S3 तरीकों आदेश कक्षाओं की उपस्थिति के में भेज दिया जाता है मैं?
  2. मैं सही glmnet में कोड संभालने predict का सही भेजने के लिए गलत क्रम का कारण होता है में हूं?
  3. मेरे कोड में कुछ भी नहीं है कि manipulates कक्षाएं स्पष्ट रूप से/दिख मेरी जानकारी के लिए वहाँ है। में परिवर्तन का कारण क्या हो सकता है?

पूर्णता 'खातिर: यहाँ के साथ चारों ओर खेलने के लिए (के रूप में मैं अपने आप को अब कर रहा हूँ) कुछ नमूना कोड:

library(glmnet) 
y<-factor(sample(2, 100, replace=TRUE)) 
xs<-matrix(runif(100), ncol=1) 
colnames(xs)<-"x" 
myfit<-glmnet(xs, y, family="binomial") 
mydata<-matrix(runif(10), ncol=1) 
colnames(mydata)<-"x" 
class(myfit) 
predict(myfit, newx=mydata, type="response") 
class(myfit)<-rev(class(myfit)) 
class(myfit) 
predict(myfit, newx=mydata, type="response") 
class(myfit)<-rev(class(myfit))#set it back 
class(myfit) 

उत्पन्न डेटा के आधार पर, अंतर कम या ज्यादा स्पष्ट (है मेरे सच्चे डेटासेट में मैंने तथाकथित संभावनाओं में नकारात्मक मूल्यों को देखा, इस तरह मैंने समस्या को उठाया), लेकिन आपको वास्तव में एक अंतर देखना चाहिए।

किसी भी इनपुट के लिए धन्यवाद।

संपादित:

मैं सिर्फ भयानक सच्चाई पता चला: या तो आदेश glmnet 1.5.2 (जो सर्वर जहाँ मैं वास्तविक कोड भाग गया, वर्ग आदेश के साथ फिट है, जिसके परिणामस्वरूप पर मौजूद है में काम किया उलट दिया गया), लेकिन 1.6 से कोड को "लॉगनेट", "ग्लैमनेट" होने की आवश्यकता होती है। मैंने अभी तक जांच नहीं की है कि 1.7 में क्या होता है।

सूचनाओं की मूल बातें याद दिलाने के लिए @Aaron के लिए धन्यवाद ('अगर सब कुछ विफल हो जाता है, फिर से शुरू करें': 'अपने संस्करणों की जांच करें')। मैंने गलती से यह माना था कि सांख्यिकीय सीखने के देवताओं द्वारा एक पैकेज इस प्रकार की त्रुटि से संरक्षित किया जाएगा), और @Gavin को S3 कैसे काम करता है इसके पुनर्निर्माण की पुष्टि के लिए।

+2

जब मैं अपना कोड चलाता हूं तो मुझे पहले 'कक्षा' कॉल के बाद ऑर्डर '' लॉगनेट "" ग्लैनेट "मिलता है, जो आपको जो मिलता है उससे पीछे है। मेरे पास glmnet 1.7 है; आपके पास क्या संस्करण है? – Aaron

उत्तर

6

हां, प्रेषण का क्रम उस क्रम में है जिसमें कक्षा गुण श्रेणी में सूचीबद्ध हैं। सरल, हर दिन के मामले में, हां, पहली निर्दिष्ट कक्षा विधि विधि प्रेषण द्वारा पहली बार चुनी जाती है, और केवल तभी जब वह उस वर्ग के लिए कोई विधि नहीं ढूंढ पाती है (या NextMethod कहा जाता है) यह दूसरी कक्षा में चलेगा , या default विधि के लिए उस खोज को विफल कर रहा है।

नहीं, मुझे नहीं लगता कि आप सही हैं कि कक्षाओं में आदेश कोड में गलत है। दस्तावेज गलत दिखाई देता है। इरादा predict.lognet() पहले कॉल करने के लिए स्पष्ट रूप से है, ग्लैमनेट द्वारा फिट किए गए सभी प्रकार के लासो/लोचदार नेट मॉडल के लिए बुनियादी गणना करने के लिए वर्कहोर predict.glmnet() का उपयोग करें, और आखिरकार उन सामान्य भविष्यवाणियों के कुछ पोस्ट प्रोसेसिंग करें। predict.glmnet()ग्लैमनेट NAMESPACE से निर्यात किया गया है, जबकि अन्य विधियां शायद बता रही हैं।

predict(myfit, newx=mydata, type="response") 

गलत है:

मैं क्यों आप इस से उत्पादन लगता है यकीन नहीं है? मुझे 10 पंक्तियों और 21 स्तंभों का एक मैट्रिक्स मिलता है, जिसमें लैम्ब्डा के 20 मूल्यों पर इंटरसेप्ट-केवल मॉडल भविष्यवाणी और भविष्यवाणियों से संबंधित कॉलम होते हैं, जिस पर लासो/लोचदार नेट पथ के साथ मॉडल गुणांक गणना की जाती है। ये रैखिक संयोजन प्रतीत नहीं होते हैं और आपके अनुरोध के अनुसार एक प्रतिक्रिया पैमाने हैं।

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

+0

ग्रेट उत्तर, लेकिन एक छोटा सा झुकाव: आप विधि प्रेषण के दौरान कक्षा को बदल नहीं सकते हैं: https://gist.github.com/1043952 (ठीक है आप कर सकते हैं, यह प्रेषण को प्रभावित नहीं करता है) – hadley

+0

इसके अलावा, ऐसा लगता है कि इरादा 'predict.lognet' है तो 'predict.glmnet'। लेकिन जैसा कि मैंने इसे पढ़ा है, ओपी का कहना है कि यह अपने सिस्टम पर पहले 'predict.glmnet' चला रहा है क्योंकि कक्षाओं का क्रम उलट दिया गया है। – Aaron

+0

@ हैडली इसे इंगित करने के लिए धन्यवाद। मैंने उस पर गलत समझा होगा। अब तय –

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