2017-10-31 18 views
12

दिखाता है मेरे पास 3% से कम की इवेंट दर वाला डेटासेट है (यानी वर्ग 0 के साथ कक्षा 1 और 27000 रिकॉर्ड के साथ लगभग 700 रिकॉर्ड हैं)।rpart का परिणाम एक रूट है, लेकिन डेटा सूचना लाभ

ID   V1 V2  V3 V5  V6 Target 
SDataID3 161 ONE  1 FOUR 0 0 
SDataID4 11 TWO  2 THREE 2 1 
SDataID5 32 TWO  2 FOUR 2 0 
SDataID7 13 ONE  1 THREE 2 0 
SDataID8 194 TWO  2 FOUR 0 0 
SDataID10 63 THREE 3 FOUR 0 1 
SDataID11 89 ONE  1 FOUR 0 0 
SDataID13 78 TWO  2 FOUR 0 0 
SDataID14 87 TWO  2 THREE 1 0 
SDataID15 81 ONE  1 THREE 0 0 
SDataID16 63 ONE  3 FOUR 0 0 
SDataID17 198 ONE  3 THREE 0 0 
SDataID18 9 TWO  3 THREE 0 0 
SDataID19 196 ONE  2 THREE 2 0 
SDataID20 189 TWO  2 ONE  1 0 
SDataID21 116 THREE 3 TWO  0 0 
SDataID24 104 ONE  1 FOUR 0 0 
SDataID25 5 ONE  2 ONE  3 0 
SDataID28 173 TWO  3 FOUR 0 0 
SDataID29 5 ONE  3 ONE  3 0 
SDataID31 87 ONE  3 FOUR 3 0 
SDataID32 5 ONE  2 THREE 1 0 
SDataID34 45 ONE  1 FOUR 0 0 
SDataID35 19 TWO  2 THREE 0 0 
SDataID37 133 TWO  2 FOUR 0 0 
SDataID38 8 ONE  1 THREE 0 0 
SDataID39 42 ONE  1 THREE 0 0 
SDataID43 45 ONE  1 THREE 1 0 
SDataID44 45 ONE  1 FOUR 0 0 
SDataID45 176 ONE  1 FOUR 0 0 
SDataID46 63 ONE  1 THREE 3 0 

मैं निर्णय पेड़ का उपयोग करके विभाजित करने की कोशिश कर रहा हूं। लेकिन पेड़ का परिणाम केवल 1 रूट है।

> library(rpart) 
> tree <- rpart(Target ~ ., data=subset(train, select=c(-Record.ID)),method="class") 
> printcp(tree) 

Classification tree: 
rpart(formula = Target ~ ., data = subset(train, select = c(-Record.ID)), method = "class") 

Variables actually used in tree construction: 
character(0) 

Root node error: 749/18239 = 0.041066 

n= 18239 

    CP nsplit rel error xerror xstd 
1 0  0   1  0 0 

StackOverflow पर संसाधनों का सबसे पढ़ने के बाद, मैं ढीला/नियंत्रण पैरामीटर्स जो मुझे वांछित निर्णय वृक्ष दिया फेरबदल।

> tree <- rpart(Target ~ ., data=subset(train, select=c(-Record.ID)),method="class" ,control =rpart.control(minsplit = 1,minbucket=2, cp=0.00002)) 
> printcp(tree) 

Classification tree: 
rpart(formula = Target ~ ., data = subset(train, select = c(-Record.ID)), 
    method = "class", control = rpart.control(minsplit = 1, minbucket = 2, 
     cp = 2e-05)) 

Variables actually used in tree construction: 
[1] V5   V2      V1   
[4] V3   V6 

Root node error: 749/18239 = 0.041066 

n= 18239 

      CP nsplit rel error xerror  xstd 
1 0.00024275  0 1.00000 1.0000 0.035781 
2 0.00019073  20 0.99466 1.0267 0.036235 
3 0.00016689  34 0.99199 1.0307 0.036302 
4 0.00014835  54 0.98798 1.0334 0.036347 
5 0.00002000  63 0.98665 1.0427 0.036504 

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

> pruned.tree <- prune(tree, cp = tree$cptable[which.min(tree$cptable[,"xerror"]),"CP"]) 
> printcp(pruned.tree) 

Classification tree: 
rpart(formula = Target ~ ., data = subset(train, select = c(-Record.ID)), 
    method = "class", control = rpart.control(minsplit = 1, minbucket = 2, 
     cp = 2e-05)) 

Variables actually used in tree construction: 
character(0) 

Root node error: 749/18239 = 0.041066 

n= 18239 

      CP nsplit rel error xerror  xstd 
1 0.00024275  0   1  1 0.035781 

पेड़ केवल रूट नोड देने नहीं किया जाना चाहिए क्योंकि गणितीय, किसी दिए गए नोड पर (उदाहरण के प्रदान की गई) हम जानकारी हासिल हो रही है। मुझे नहीं पता कि क्या मैं छंटनी करके गलती कर रहा हूं या कम घटना दर डेटासेट को संभालने में आरपीटी के साथ कोई समस्या है?

NODE p  1-p  Entropy   Weights   Ent*Weight  # Obs 
Node 1 0.032 0.968 0.204324671  0.351398601  0.071799404  10653 
Node 2 0.05 0.95 0.286396957  0.648601399  0.185757467  19663 

Sum(Ent*wght)  0.257556871 
Information gain 0.742443129 
+0

कैसे आप अंतिम सारांश तालिका दिखा जानकारी हासिल मिला? – useR

+0

मैंने Excel का उपयोग करके इसे मैन्युअल रूप से गणना की। –

+0

क्षमा करें, लेकिन मैं समझ नहीं पा रहा हूं कि आप वास्तव में क्या करना चाहते हैं और आरपीटी लाइब्रेरी का उपयोग करने में आपकी प्रेरणा। क्या आप यह वर्णन कर सकते हैं? – Alex

उत्तर

2

डेटा आपके द्वारा दी गई दो लक्ष्य वर्गों के अनुपात को प्रतिबिंबित नहीं करता, तो मैं डेटा बदलाव किया है बेहतर है कि (देखें डेटा अनुभाग) को प्रतिबिंबित करने के:

> prop.table(table(train$Target)) 

     0   1 
0.96707581 0.03292419 

> 700/27700 
[1] 0.02527076 

अनुपात अब कर रहे हैं

Classification tree: 
rpart(formula = Target ~ ., data = train, method = "class") 

Variables actually used in tree construction: 
character(0) 

Root node error: 912/27700 = 0.032924 

n= 27700 

    CP nsplit rel error xerror xstd 
1 0  0   1  0 0 
: अपेक्षाकृत करीब ...

library(rpart) 
tree <- rpart(Target ~ ., data=train, method="class") 
printcp(tree) 

में परिणाम 210

अब, कारण है कि आप केवल अपने पहले मॉडल के लिए रूट नोड देख रहे हैं, शायद इस तथ्य के कारण कि आपके पास अत्यधिक असंतुलित लक्ष्य वर्ग हैं, और इसलिए, आपके स्वतंत्र चर पेड़ को विकसित करने के लिए पर्याप्त जानकारी प्रदान नहीं कर सके। मेरे नमूना डेटा में 3.3% घटना दर है, लेकिन आपके पास केवल 2.5% है!

जैसा कि आपने उल्लेख किया है, पेड़ उगाने के लिए rpart को मजबूर करने का एक तरीका है। यह डिफ़ॉल्ट जटिलता पैरामीटर को ओवरराइड करना है (cp)। जटिलता माप पेड़ के आकार का संयोजन है और पेड़ लक्ष्य वर्गों को कितनी अच्छी तरह से अलग करता है। ?rpart.control, से "कोई भी विभाजन जो सीपी के कारक द्वारा फिट की कुल कमी को कम नहीं करता है, का प्रयास नहीं किया जाता है"। इसका मतलब है कि इस बिंदु पर आपके मॉडल में रूट नोड से अलग विभाजन नहीं है जो विचाराधीन rpart के लिए पर्याप्त जटिलता स्तर को कम करता है। हम कम या नकारात्मक cp (ऋणात्मक cp मूल रूप से पेड़ को अपने पूर्ण आकार में बढ़ने के लिए मजबूर करते हैं) द्वारा "पर्याप्त" माना जाता है, इस सीमा को आराम कर सकते हैं। में

tree <- rpart(Target ~ ., data=train, method="class" ,parms = list(split = 'information'), 
       control =rpart.control(minsplit = 1,minbucket=2, cp=0.00002)) 
printcp(tree) 

परिणाम:

Classification tree: 
rpart(formula = Target ~ ., data = train, method = "class", parms = list(split = "information"), 
    control = rpart.control(minsplit = 1, minbucket = 2, cp = 2e-05)) 

Variables actually used in tree construction: 
[1] ID V1 V2 V3 V5 V6 

Root node error: 912/27700 = 0.032924 

n= 27700 

      CP nsplit rel error xerror  xstd 
1 4.1118e-04  0 1.00000 1.0000 0.032564 
2 3.6550e-04  30 0.98355 1.0285 0.033009 
3 3.2489e-04  45 0.97807 1.0702 0.033647 
4 3.1328e-04 106 0.95504 1.0877 0.033911 
5 2.7412e-04 116 0.95175 1.1031 0.034141 
6 2.5304e-04 132 0.94737 1.1217 0.034417 
7 2.1930e-04 149 0.94298 1.1458 0.034771 
8 1.9936e-04 159 0.94079 1.1502 0.034835 
9 1.8275e-04 181 0.93640 1.1645 0.035041 
10 1.6447e-04 193 0.93421 1.1864 0.035356 
11 1.5664e-04 233 0.92654 1.1853 0.035341 
12 1.3706e-04 320 0.91228 1.2083 0.035668 
13 1.2183e-04 344 0.90899 1.2127 0.035730 
14 9.9681e-05 353 0.90789 1.2237 0.035885 
15 2.0000e-05 364 0.90680 1.2259 0.035915 

आप देख सकते हैं, पेड़ एक आकार कि cp की एक न्यूनतम से जटिलता के स्तर को कम कर देता हो गई है। दो बातें ध्यान रखें:

  1. शून्य nsplit में CP पहले से ही 0 के रूप में के रूप में कम है।0004, जहां rpart में डिफ़ॉल्ट cp के रूप में 0.01 पर सेट किया गया है।
  2. nsplit == 0 से शुरू, क्रॉस सत्यापन त्रुटि (xerror) बढ़ जाती है क्योंकि आप विभाजन की संख्या बढ़ाते हैं।
इनमें से

दोनों संकेत मिलता है कि अपने मॉडल, nsplit == 0 में और उससे आगे डेटा overfitting है अपने मॉडल में अधिक स्वतंत्र चर जोड़ पर्याप्त जानकारी (सीपी में अपर्याप्त कमी) पार सत्यापन त्रुटि को कम करने के लिए जोड़ नहीं होता। ऐसा कहा जा रहा है कि, आपके रूट नोड मॉडल इस मामले में सबसे अच्छा मॉडल है, जो बताता है कि आपके प्रारंभिक मॉडल में केवल रूट नोड क्यों है। में

pruned.tree <- prune(tree, cp = tree$cptable[which.min(tree$cptable[,"xerror"]),"CP"]) 
printcp(pruned.tree) 

परिणाम:

Classification tree: 
rpart(formula = Target ~ ., data = train, method = "class", parms = list(split = "information"), 
    control = rpart.control(minsplit = 1, minbucket = 2, cp = 2e-05)) 

Variables actually used in tree construction: 
character(0) 

Root node error: 912/27700 = 0.032924 

n= 27700 

      CP nsplit rel error xerror  xstd 
1 0.00041118  0   1  1 0.032564 

छंटाई भाग के लिए, यह अब स्पष्ट क्यों अपने कम कर दिए हैं पेड़ रूट नोड पेड़ है, एक पेड़ है कि 0 विभाजन के बाद से परे चला जाता है पार सत्यापन त्रुटि बढ़ रही है । न्यूनतम xerror के साथ पेड़ लेना आपको अपेक्षित के रूप में रूट नोड पेड़ के साथ छोड़ देगा।

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

इस मामले में, cp को कम करने और बाद में परिणामी पेड़ को कम करने के लिए यह वास्तव में समझ में नहीं आता है। चूंकि कम cp सेट करके, आप rpart को विभाजित करने के लिए बता रहे हैं, भले ही यह ओवरफिट्स हो, जबकि ओवरफिट्स के सभी नोड्स को "कट" करें।

डाटा:

ध्यान दें कि मैं पंक्ति सूचकों नमूने के बजाय प्रत्येक स्तंभ और नमूने के लिए पंक्तियों फेरबदल कर रहा हूँ। ऐसा इसलिए है क्योंकि आपके द्वारा प्रदान किया गया डेटा शायद आपके मूल डेटासेट (संभावित पक्षपातपूर्ण) का एक यादृच्छिक नमूना नहीं है, इसलिए मैं मूल रूप से यादृच्छिक रूप से अपने मौजूदा पंक्तियों के संयोजन के साथ नए अवलोकन बना रहा हूं जो आशा करता है कि वह पूर्वाग्रह कम हो जाएंगे।

init_train = structure(list(ID = structure(c(16L, 24L, 29L, 30L, 31L, 1L, 
2L, 3L, 4L, 5L, 6L, 7L, 8L, 9L, 10L, 11L, 12L, 13L, 14L, 15L, 
17L, 18L, 19L, 20L, 21L, 22L, 23L, 25L, 26L, 27L, 28L), .Label = c("SDataID10", 
"SDataID11", "SDataID13", "SDataID14", "SDataID15", "SDataID16", 
"SDataID17", "SDataID18", "SDataID19", "SDataID20", "SDataID21", 
"SDataID24", "SDataID25", "SDataID28", "SDataID29", "SDataID3", 
"SDataID31", "SDataID32", "SDataID34", "SDataID35", "SDataID37", 
"SDataID38", "SDataID39", "SDataID4", "SDataID43", "SDataID44", 
"SDataID45", "SDataID46", "SDataID5", "SDataID7", "SDataID8"), class = "factor"), 
    V1 = c(161L, 11L, 32L, 13L, 194L, 63L, 89L, 78L, 87L, 81L, 
    63L, 198L, 9L, 196L, 189L, 116L, 104L, 5L, 173L, 5L, 87L, 
    5L, 45L, 19L, 133L, 8L, 42L, 45L, 45L, 176L, 63L), V2 = structure(c(1L, 
    3L, 3L, 1L, 3L, 2L, 1L, 3L, 3L, 1L, 1L, 1L, 3L, 1L, 3L, 2L, 
    1L, 1L, 3L, 1L, 1L, 1L, 1L, 3L, 3L, 1L, 1L, 1L, 1L, 1L, 1L 
    ), .Label = c("ONE", "THREE", "TWO"), class = "factor"), 
    V3 = c(1L, 2L, 2L, 1L, 2L, 3L, 1L, 2L, 2L, 1L, 3L, 3L, 3L, 
    2L, 2L, 3L, 1L, 2L, 3L, 3L, 3L, 2L, 1L, 2L, 2L, 1L, 1L, 1L, 
    1L, 1L, 1L), V5 = structure(c(1L, 3L, 1L, 3L, 1L, 1L, 1L, 
    1L, 3L, 3L, 1L, 3L, 3L, 3L, 2L, 4L, 1L, 2L, 1L, 2L, 1L, 3L, 
    1L, 3L, 1L, 3L, 3L, 3L, 1L, 1L, 3L), .Label = c("FOUR", "ONE", 
    "THREE", "TWO"), class = "factor"), V6 = c(0L, 2L, 2L, 2L, 
    0L, 0L, 0L, 0L, 1L, 0L, 0L, 0L, 0L, 2L, 1L, 0L, 0L, 3L, 0L, 
    3L, 3L, 1L, 0L, 0L, 0L, 0L, 0L, 1L, 0L, 0L, 3L), Target = c(0L, 
    1L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 
    0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L 
    )), .Names = c("ID", "V1", "V2", "V3", "V5", "V6", "Target" 
), class = "data.frame", row.names = c(NA, -31L)) 

set.seed(1000) 
train = as.data.frame(lapply(init_train, function(x) sample(x, 27700, replace = TRUE))) 
संबंधित मुद्दे