ความแตกต่างในการใช้งานของการแยกไบนารีในต้นไม้การตัดสินใจ


12

ผมอยากรู้เกี่ยวกับการดำเนินการในทางปฏิบัติของการแยกไบนารีในต้นไม้ตัดสินใจ - เป็นที่เกี่ยวกับระดับของเด็ดขาดทำนาย{J}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

ในความเป็นจริงมีสองประเภทของปัจจัย - สั่งซื้อ (เช่นเล็ก <เล็ก <กลาง <ใหญ่ <ใหญ่) และไม่มีการเรียงลำดับ (แตงกวา, แครอท, ยี่หร่า, Aubergine)
ชั้นเฟิสต์คลาสเหมือนกันต่อเนื่อง - ง่ายต่อการตรวจสอบ pivots ทั้งหมดเท่านั้นนอกจากนี้ยังไม่มีปัญหาในการขยายรายการระดับ
สำหรับคลาสที่สองคุณต้องสร้างชุดขององค์ประกอบที่จะนำไปสู่สาขาหนึ่งโดยปล่อยให้ส่วนที่เหลือเป็นส่วนอื่น - ในกรณีนี้คุณสามารถ:

  1. โยนผิดพลาด
  2. สมมติว่าคลาสที่มองไม่เห็นเข้าไปในสาขาที่คุณชื่นชอบ
  3. ปฏิบัติต่อสิ่งนี้ในฐานะ NA และเลือกสาขาในวิธีการสุ่มน้อยลง

ตอนนี้การรักษาปัจจัยที่ไม่ได้จัดเรียงโดยตรงนั้นซับซ้อนมาก "อัลกอริทึม" โกง "และอ้างถึงปัจจัยที่ไม่ได้จัดเรียงตามลำดับที่ได้รับคำสั่งดังนั้นพวกเขาจึงไม่แม้แต่จะเจอปัญหานี้ ส่วนที่เหลือมักจะใช้หน้ากาก int คือเพิ่มประสิทธิภาพจำนวนจำนวนเต็มจากที่จะและรักษาบิต -th กับการเลือกสาขาในระดับปัจจัยฉัน(เคยสงสัยบ้างไหมว่าทำไมมีขีด จำกัด ถึง 32 ระดับบ่อยครั้ง) ในการตั้งค่านี้มันค่อนข้างเป็นธรรมชาติที่ระดับที่มองไม่เห็นเข้าไปเงียบ ๆ ในสาขา "0" แต่นี่ดูเหมือนจะไม่ "ถูกต้อง" เกินไปเพราะเหตุใดเราควรทำเช่นนี้? แล้วจำนวนของระดับที่ต้องใช้ในการเลือกใช้แอตทริบิวต์ของเอนโทรปีล่ะ12#categories11ii

ฉันจะบอกว่าความคิดที่สมเหตุสมผลที่สุดคือการทำให้ผู้ใช้กำหนดชุดเต็มของปัจจัย (เช่น R ทำสิ่งนี้แบบอินทรีย์รักษาระดับผ่านการดำเนินการย่อย) และใช้ตัวเลือกที่ 1 สำหรับระดับที่ไม่ได้ประกาศและตัวเลือกที่ 2 สำหรับการประกาศ . ตัวเลือก 3 อาจสมเหตุสมผลถ้าคุณมีโครงสร้างพื้นฐานการจัดการ NA อยู่แล้ว

*) นอกจากนี้ยังมีกลยุทธ์ด้านข้างเพื่อทำการเข้ารหัสซ้ำระดับที่ไม่สำคัญเป็นตัวเลขเช่นการเข้ารหัส Breiman เช่นนี้ทำให้เกิดปัญหามากขึ้น


1
คุณกำลังบอกว่า ctree หรือ tree ในตัวอย่างของฉันถือว่าปัจจัยที่ไม่มีการจัดเรียงนี้เป็นปัจจัยสั่งและส่งมันไปยังสาขา "0" หรือไม่?
B_Miner

@mbq คุณช่วยอธิบายได้ว่าทำไมจำนวนทั้งหมดที่คุณสามารถแยกได้คือ 2 ^ (# หมวดหมู่ + 1) - 2 ฉันไม่เข้าใจว่าทำไมส่วน "-2"
honeybadger

อืมดูเหมือนว่าฉันเมาสูตรนี้แล้ว มีคำเหมือน 2 ^ n n บิต แต่เราไม่นับทั้งคำ a และ ~ a ดังนั้น 2 ^ (n-1) และเราไม่ชอบแยกที่ไม่หกเลยดังนั้น 2 ^ (n-1) -1 (กล่าวอีกนัยหนึ่งเรานับจาก 1) n = 1 เป็นกรณีพิเศษ
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.