R: อะไรที่ฉันเห็นในการพึ่งพาบางส่วนของ gbm และ RandomForest


14

ที่จริงแล้วฉันคิดว่าฉันเข้าใจสิ่งที่เราสามารถแสดงด้วยพล็อตการพึ่งพาบางส่วน แต่ใช้ตัวอย่างสมมุติง่าย ๆ ฉันรู้สึกงงงวย ในกลุ่มของรหัสต่อไปฉันจะสร้างสามตัวแปรอิสระ ( , B , C ) และขึ้นอยู่กับตัวแปร ( Y ) กับแสดงให้เห็นความสัมพันธ์เชิงเส้นใกล้ชิดกับปีขณะที่และเป็น uncorrelated กับY ฉันทำการวิเคราะห์การถดถอยด้วยต้นไม้การถดถอยที่เพิ่มขึ้นโดยใช้แพ็คเกจ R :gbm

a <- runif(100, 1, 100)
b <- runif(100, 1, 100)
c <- 1:100 + rnorm(100, mean = 0, sd = 5)
y <- 1:100 + rnorm(100, mean = 0, sd = 5)
par(mfrow = c(2,2))
plot(y ~ a); plot(y ~ b); plot(y ~ c)
Data <- data.frame(matrix(c(y, a, b, c), ncol = 4))
names(Data) <- c("y", "a", "b", "c")
library(gbm)
gbm.gaus <- gbm(y ~ a + b + c, data = Data, distribution = "gaussian")
par(mfrow = c(2,2))
plot(gbm.gaus, i.var = 1)
plot(gbm.gaus, i.var = 2)
plot(gbm.gaus, i.var = 3)

ไม่น่าแปลกใจสำหรับตัวแปรและแปลงพึ่งพาผลผลิตบางส่วนเส้นแนวนอนรอบเฉลี่ยของ สิ่งที่ฉันปริศนาเป็นพล็อตของตัวแปรค ฉันได้รับเส้นแนวนอนสำหรับช่วง <40 และ > 60 และแกน y ถูก จำกัด ให้ค่าใกล้เคียงกับค่าเฉลี่ยของปี ตั้งแต่และBมีความสมบูรณ์ไม่เกี่ยวข้องกับY (และความสำคัญจึงมีตัวแปรในรูปแบบเป็น 0), ที่คาดผมที่จะแสดงการพึ่งพาบางส่วนตามช่วงทั้งหมดแทนที่จะเป็นรูปร่าง sigmoid สำหรับช่วงที่ จำกัด ของค่า ฉันพยายามค้นหาข้อมูลใน Friedman (2001) "การประมาณฟังก์ชั่นโลภ: เครื่องเร่งการไล่ระดับสี" และใน Hastie et al (2011) "องค์ประกอบของการเรียนรู้ทางสถิติ" แต่ทักษะทางคณิตศาสตร์ของฉันต่ำเกินไปที่จะเข้าใจสมการและสูตรทั้งหมดในนั้น ดังนั้นคำถามของฉัน: สิ่งที่กำหนดรูปร่างของพล็อตพึ่งพาบางส่วนสำหรับตัวแปรc ? (โปรดอธิบายด้วยคำที่เข้าใจได้ยากสำหรับผู้ที่ไม่ใช่นักคณิตศาสตร์!)

เพิ่มเมื่อวันที่ 17 เมษายน 2014:

ในขณะที่รอการตอบสนองผมใช้ข้อมูลตัวอย่างเช่นเดียวกันสำหรับการวิเคราะห์กับ randomForestR-แพคเกจ แผนการพึ่งพาอาศัยบางส่วนของ randomForest มีลักษณะคล้ายกับสิ่งที่ฉันคาดหวังจากแผนการ gbm: การพึ่งพาบางส่วนของตัวแปรอธิบายaและbแตกต่างกันแบบสุ่มและใกล้เคียงประมาณ 50 ในขณะที่ตัวแปรอธิบายcแสดงการพึ่งพาบางส่วนตลอดช่วงทั้งหมด ช่วงทั้งหมดของy ) อะไรคือสาเหตุของรูปทรงที่แตกต่างกันของแผนการพึ่งพาบางส่วนในgbmและrandomForest?

แปลงบางส่วนของ gbm และ randomForest

นี่คือรหัสที่ดัดแปลงเพื่อเปรียบเทียบแปลง:

a <- runif(100, 1, 100)
b <- runif(100, 1, 100)
c <- 1:100 + rnorm(100, mean = 0, sd = 5)
y <- 1:100 + rnorm(100, mean = 0, sd = 5)
par(mfrow = c(2,2))
plot(y ~ a); plot(y ~ b); plot(y ~ c)
Data <- data.frame(matrix(c(y, a, b, c), ncol = 4))
names(Data) <- c("y", "a", "b", "c")

library(gbm)
gbm.gaus <- gbm(y ~ a + b + c, data = Data, distribution = "gaussian")

library(randomForest)
rf.model <- randomForest(y ~ a + b + c, data = Data)

x11(height = 8, width = 5)
par(mfrow = c(3,2))
par(oma = c(1,1,4,1))
plot(gbm.gaus, i.var = 1)
partialPlot(rf.model, Data[,2:4], x.var = "a")
plot(gbm.gaus, i.var = 2)
partialPlot(rf.model, Data[,2:4], x.var = "b")
plot(gbm.gaus, i.var = 3)
partialPlot(rf.model, Data[,2:4], x.var = "c")
title(main = "Boosted regression tree", outer = TRUE, adj = 0.15)
title(main = "Random forest", outer = TRUE, adj = 0.85)

1
คุณอาจต้องการปรับพารามิเตอร์ไฮเปอร์พารามิเตอร์แบบสัมผัส ฉันไม่แน่ใจว่าจำนวนต้นไม้เริ่มต้นเป็น gbm แต่อาจมีขนาดเล็กมากจนไม่มีเวลาเรียนรู้ความโค้งที่แข็งแรง
Shea Parkes

@Shea Parkes - คุณพูดถูก จำนวน defaukt ของต้นไม้คือ 100 ซึ่งไม่เพียงพอที่จะสร้างแบบจำลองที่ดี ต้นไม้จำนวน 2,000 ต้นมีการพึ่งพาอาศัยบางส่วนของ gbm และป่าสุ่มเกือบเท่ากัน
user7417

คำตอบ:


7

ฉันใช้เวลาเขียน "partial.function-plotter" ของตัวเองก่อนที่ฉันจะรู้ว่ามันถูกรวมอยู่ในไลบรารี R randomForest แล้ว

[แก้ไข ... แต่แล้วฉันใช้เวลาหนึ่งปีในการสร้างแพ็คเกจ CRAN ForestFloorซึ่งตามความเห็นของฉันดีกว่าแปลงพึ่งพาบางส่วนอย่างมีนัยสำคัญ]

พล็อต Partial.function นั้นยอดเยี่ยมในอินสแตนซ์เนื่องจากตัวอย่างการจำลองนี้คุณแสดงที่นี่โดยที่ตัวแปรอธิบายไม่โต้ตอบกับตัวแปรอื่น หากตัวแปรอธิบายแต่ละตัวมีส่วนช่วยเสริมให้กับเป้าหมาย -Y โดยฟังก์ชั่นที่ไม่รู้จักวิธีนี้เป็นวิธีที่ดีในการแสดงฟังก์ชันที่ซ่อนไว้โดยประมาณ ฉันมักจะเห็นความแบนในขอบเขตของฟังก์ชั่นบางส่วน

เหตุผลบางอย่าง: randomForsest มีอาร์กิวเมนต์ที่เรียกว่า 'nodesize = 5' ซึ่งหมายความว่าไม่มีโครงสร้างใดที่จะแบ่งกลุ่มสมาชิก 5 คนหรือน้อยกว่า ดังนั้นต้นไม้แต่ละต้นจึงไม่สามารถแยกความแตกต่างด้วยความแม่นยำเพิ่มเติม การห่อหุ้ม / การบูทสแตรปของชุดชั้นในนั้นจะทำให้ราบรื่นโดยการลงคะแนนฟังก์ชั่นหลายขั้นตอนของต้นไม้แต่ละต้น - แต่อยู่ตรงกลางของพื้นที่ข้อมูล ใกล้ขอบของข้อมูลที่แสดงถึงช่องว่าง 'แอมพลิจูด' ของบางส่วนฟังก์ชั่นจะลดลง การตั้งค่า nodesize = 3 และ / หรือได้รับการสังเกตมากขึ้นเมื่อเทียบกับเสียงสามารถลดผลกระทบการทำให้ขอบเรียบนี้ ... เมื่ออัตราส่วนสัญญาณต่อเสียงลดลงโดยทั่วไปในป่าสุ่มการคาดการณ์การควบแน่น ดังนั้นการคาดการณ์ไม่แม่นยำอย่างแน่นอน แต่มีความสัมพันธ์เชิงเส้นตรงกับเป้าหมายเท่านั้น คุณสามารถดูค่า a และ b เป็นตัวอย่างและอัตราส่วนสัญญาณต่อสัญญาณรบกวนต่ำมาก และฟังก์ชั่นบางส่วนเหล่านี้ค่อนข้างแบน เป็นคุณลักษณะที่ดีของฟอเรสต์แบบสุ่มที่คุณมีอยู่แล้วจากช่วงคาดการณ์ของชุดการฝึกอบรมที่สามารถคาดเดาว่าแบบจำลองนั้นทำงานได้ดีเพียงใด OOB.predictions ยอดเยี่ยมเช่นกัน ..

ความแบนของพล็อตบางส่วนในภูมิภาคที่ไม่มีข้อมูลสมเหตุสมผล: เนื่องจากฟอเรสต์แบบสุ่มและ CART เป็นแบบจำลองการขับเคลื่อนข้อมูลฉันเองชอบแนวคิดที่ว่าแบบจำลองเหล่านี้ไม่คาดการณ์ ดังนั้นการคาดการณ์ของ c = 500 หรือ c = 1100 จึงเหมือนกับ c = 100 หรือในกรณีส่วนใหญ่ก็ c = 98

นี่คือตัวอย่างรหัสที่มีการทำให้ขอบแบนราบลดลง:

ฉันยังไม่ได้ลองแพ็คเกจ gbm ...

นี่คือตัวอย่างรหัสตาม eaxample ของคุณ ...

#more observations are created...
a <- runif(5000, 1, 100)
b <- runif(5000, 1, 100)
c <- (1:5000)/50 + rnorm(100, mean = 0, sd = 0.1)
y <- (1:5000)/50 + rnorm(100, mean = 0, sd = 0.1)
par(mfrow = c(1,3))
plot(y ~ a); plot(y ~ b); plot(y ~ c)
Data <- data.frame(matrix(c(y, a, b, c), ncol = 4))
names(Data) <- c("y", "a", "b", "c")
library(randomForest)
#smaller nodesize "not as important" when there number of observartion is increased
#more tress can smooth flattening so boundery regions have best possible signal to             noise, data specific how many needed

plot.partial = function() {
partialPlot(rf.model, Data[,2:4], x.var = "a",xlim=c(1,100),ylim=c(1,100))
partialPlot(rf.model, Data[,2:4], x.var = "b",xlim=c(1,100),ylim=c(1,100))
partialPlot(rf.model, Data[,2:4], x.var = "c",xlim=c(1,100),ylim=c(1,100))
}

#worst case! : with 100 samples from Data and nodesize=30
rf.model <- randomForest(y ~ a + b + c, data = Data[sample(5000,100),],nodesize=30)
plot.partial()

#reasonble settings for least partial flattening by few observations: 100 samples and nodesize=3 and ntrees=2000
#more tress can smooth flattening so boundery regions have best possiblefidelity
rf.model <- randomForest(y ~ a + b + c, data = Data[sample(5000,100),],nodesize=5,ntress=2000)
plot.partial()

#more observations is great!
rf.model <- randomForest(y ~ a + b + c,
 data = Data[sample(5000,5000),],
 nodesize=5,ntress=2000)
plot.partial()

4

ดังที่ได้กล่าวไว้ในความคิดเห็นด้านบนโมเดล gbm น่าจะดีกว่าด้วยการปรับพารามิเตอร์บางอย่าง วิธีง่าย ๆ ในการสังเกตปัญหาในโมเดลและความต้องการพารามิเตอร์ดังกล่าวคือการสร้างพล็อตการวินิจฉัยบางอย่าง ตัวอย่างเช่นสำหรับโมเดล gbm ด้านบนพร้อมกับพารามิเตอร์เริ่มต้น (และใช้ แพคเกจplotmoเพื่อสร้างแปลง) เรามี

gbm.gaus <- gbm(y~., data = Data, dist = "gaussian")
library(plotmo)   # for the plotres function
plotres(gbm.gaus) # plot the error per ntrees and the residuals

ซึ่งจะช่วยให้

พล็อต

ในพล็อตซ้ายเราจะเห็นว่าเส้นโค้งข้อผิดพลาดไม่ได้ผ่านจุดต่ำสุด และในพล็อตขวาคนตกค้างไม่ใช่สิ่งที่เราต้องการ

ถ้าเราสร้างแบบจำลองด้วยต้นไม้จำนวนมากขึ้น

gbm.gaus1 <- gbm(y~., data = Data, dist = "gaussian",
                 n.trees=5000, interact=3)
plotres(gbm.gaus1)

เราได้รับ

พล็อต

เราเห็นข้อผิดพลาดโค้งออกมาด้านล่างด้วยต้นไม้จำนวนมากและพล็อตที่เหลือมีสุขภาพดี เรายังสามารถพล็อตแผนการพึ่งพาบางส่วนสำหรับโมเดล gbm ใหม่และโมเดลฟอเรสต์แบบสุ่ม

library(plotmo)
plotmo(gbm.gaus1, pmethod="partdep", all1=TRUE, all2=TRUE)
plotmo(rf.model,  pmethod="partdep", all1=TRUE, all2=TRUE)

ซึ่งจะช่วยให้

พล็อต

ตอนนี้แบบจำลอง gbm และการสุ่มฟอเรสต์คล้ายกันตามที่คาดไว้


3

คุณต้องอัปเดตinteraction.depthพารามิเตอร์ของคุณเมื่อคุณสร้างแบบจำลองที่ได้รับการสนับสนุน มันเริ่มต้นที่ 1 และจะทำให้ต้นไม้ทั้งหมดที่gbmอัลกอริทึมสร้างเพื่อแยกเพียงครั้งเดียว นี่หมายความว่าต้นไม้ทุกต้นเพิ่งแยกตัวแปรcและขึ้นอยู่กับตัวอย่างของการสังเกตที่ใช้มันจะแยกบางส่วนประมาณ 40 - 60

นี่คือแผนการบางส่วนที่มี interaction.depth = 3

ป้อนคำอธิบายรูปภาพที่นี่


จุดดีก็คือ
Soren Havelund Welling
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.