निर्णय पेड़ों में बाइनरी विभाजन के कार्यान्वयन में अंतर


12

मैं एक निर्णय वृक्ष में बाइनरी विभाजन के व्यावहारिक कार्यान्वयन के बारे में उत्सुक हूं - क्योंकि यह एक श्रेणीबद्ध भविष्यवक्ता स्तरों से संबंधित है ।Xj

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

मान लीजिए कि एक चर X स्तरों पर है {A,B,C,D,E}। एक नमूने में, शायद केवल स्तर {A,B,C,D}मौजूद हैं। फिर, जब परिणामी पेड़ का उपयोग भविष्यवाणी के लिए किया जाता है, तो पूरा सेट मौजूद हो सकता है।

इस उदाहरण से जारी रखते हुए, कहते हैं कि एक पेड़ X पर विभाजित होता है और {A,B}बाईं ओर और {C,D}दाईं ओर भेजता है । मैं बाइनरी स्प्लिट के तर्क की अपेक्षा तब करूंगा, जब नए डेटा के साथ सामना करना होगा: "यदि X का मान A या B है, तो बाईं ओर भेजें, अन्यथा, इस मामले को दाईं ओर भेजें"। ऐसा लगता है कि कुछ क्रियान्वयन में क्या होता है "यदि X का मान A या B है, तो बाईं ओर भेजें, यदि X का मान C या D है तो दाईं ओर भेजें"। जब यह मामला मान E पर ले जाता है, तो एल्गोरिथ्म टूट जाता है।

बाइनरी स्प्लिट को संभालने के लिए "सही" तरीका क्या है? ऐसा लगता है कि बहुत अधिक मजबूत तरीका अक्सर लागू किया जाता है, लेकिन हमेशा नहीं (नीचे Rpart देखें)।

यहाँ कुछ उदाहरण दिए गए हैं:

Rpart विफल रहता है, अन्य ठीक हैं।

#test trees and missing values

summary(solder)
table(solder$PadType)

# create train and validation
set.seed(12345)
t_rows<-sample(1:nrow(solder),size=360, replace=FALSE)
train_solder<-solder[t_rows,]
val_solder<-solder[-t_rows,]

#look at PadType
table(train_solder$PadType)
table(val_solder$PadType)
#set a bunch to missing
levels(train_solder$PadType)[train_solder$PadType %in% c('L8','L9','W4','W9')] <- 'MISSING'


#Fit several trees, may have to play with the parameters to get them to split on the variable

####RPART
mod_rpart<-rpart(Solder~PadType,data=train_solder)
predict(mod_rpart,val_solder)
#Error in model.frame.default(Terms, newdata, na.action = na.action, xlev = attr(object,  : 
#factor 'PadType' has new level(s) D6, L6, L7, L8, L9, W4

####TREE
mod_tree<-tree(Solder~PadType,data=train_solder,split="gini")
predict(mod_tree,val_solder) #works fine

####ctree
mod_ctree<-ctree(Solder~PadType,data=train_solder,control = ctree_control(mincriterion = 0.05))
predict(mod_ctree,val_solder) #works fine

जवाबों:


9

वास्तव में दो प्रकार के कारक होते हैं - ऑर्डर किए गए (जैसे टिनी <स्मॉल <मीडियम <बिग <विशाल) और अनऑर्डर किए गए (ककड़ी, गाजर, सौंफ, ऑबर्जिन)।
प्रथम श्रेणी निरंतर लोगों के समान है - सभी पिवोट्स की जांच करने के लिए केवल आसान है, विस्तारित स्तर की सूची के साथ कोई समस्या नहीं है।
दूसरे वर्ग के लिए, आपको उन तत्वों का एक समूह बनाना होगा जो एक शाखा में निर्देशित होंगे, बाकी को दूसरे में छोड़ देंगे - इस मामले में आप या तो कर सकते हैं:

  1. त्रुटि फेंकें
  2. मान लें कि अनदेखी वर्ग आपकी पसंदीदा शाखा में चला जाता है
  3. इसे NA मानें और शाखा को कम-से-कम यादृच्छिक तरीके से चुनें।

अब, अव्यवस्थित कारकों का प्रत्यक्ष उपचार बहुत मुश्किल से "एल्गोरिथ्म" को धोखा देता है और अनियंत्रित कारकों का दावा करता है जैसा कि वे आदेश देते हैं, इसलिए वे इस समस्या को छूते भी नहीं हैं। बाकी आम तौर पर इंट मास्क का उपयोग करते हैं, अर्थात से से एक पूर्णांक संख्या को अनुकूलित करें और -th बिट को एक कारक स्तर लिए शाखा चयन के रूप में व्यवहार करें । (कभी आपने सोचा है कि 32 स्तरों की लगातार सीमा क्यों है?) इस सेटिंग में, यह काफी स्वाभाविक है कि अनदेखी स्तर चुपचाप "0" शाखा में चले जाते हैं। फिर भी यह "सही" नहीं लगता, क्योंकि हमें वास्तव में ऐसा क्यों करना चाहिए? और विशेषता चयन में एन्ट्रापी लीवरेज के लिए आवश्यक स्तरों की संख्या के बारे में क्या?2 #categories - 1 - 1 मैं मैं12#श्रेणियाँ-1-1मैंमैं

मैं कहूंगा कि सबसे समझदार विचार यह है कि उपयोगकर्ता को कारकों के पूर्ण सेट को परिभाषित करने के लिए है (उदाहरण के लिए R यह व्यवस्थित करता है, उप-संचालन के माध्यम से स्तरों को संरक्षित करता है) और विकल्प 1 का उपयोग करें। घोषित स्तरों और विकल्प 2 के लिए। घोषित लोगों के लिए । विकल्प 3. अगर आपके पास पहले से ही कुछ एनए से निपटने के बुनियादी ढांचे हैं, तो समझ में आ सकता है।

*) कुछ गैर-तुच्छ पुन: कोडिंग की संख्याओं को संख्याओं में करने के लिए साइड स्ट्रेटेजी भी है, उदाहरण के लिए ब्रेमन एन्कोडिंग - फिर भी यह और भी अधिक समस्याएं उत्पन्न करता है।


1
क्या आप कह रहे हैं कि मेरे उदाहरण में ctree या ट्री वास्तव में इस अव्यवस्थित कारक को एक आदेशित कारक मानते हैं और इस प्रकार इसे "0" शाखा में भेजते हैं?
B_Miner

@mbq आप यह बता सकते हैं कि आप विभाजन करने के तरीकों की कुल संख्या 2 ^ (# श्रेणियां + 1) क्यों हैं - 2. मुझे समझ नहीं आता कि "-2" भाग क्यों है।
सुहागरात

हम्म, ऐसा लगता है कि मैंने इस सूत्र को खराब कर दिया है; वहाँ 2 ^ n n- बिट शब्द की तरह है, लेकिन हम दोनों शब्दों की गिनती नहीं करते हैं और ~ ए, इसलिए 2 ^ (एन -1), और हम विभाजन को पसंद नहीं करते हैं जो बिल्कुल भी नहीं है, इसलिए 2 ^ (एन -1) -1 (दूसरे शब्दों में, हम 1 से गिनते हैं)। n = 1 तब एक विशेष मामला है।
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.