R: Apa yang saya lihat di plot ketergantungan parsial gbm dan RandomForest?


14

Sebenarnya, saya pikir saya sudah mengerti apa yang bisa ditunjukkan dengan plot ketergantungan sebagian, tetapi menggunakan contoh hipotetis yang sangat sederhana, saya agak bingung. Dalam potongan kode berikut ini saya menghasilkan tiga variabel independen ( a , b , c ) dan satu variabel dependen ( y ) dengan c menunjukkan hubungan linear yang dekat dengan y , sedangkan a dan b tidak berkorelasi dengan y . Saya membuat analisis regresi dengan pohon regresi yang dikuatkan menggunakan paket 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)

Tidak mengherankan, untuk variabel a dan b plot ketergantungan parsial menghasilkan garis horizontal di sekitar rata-rata a . Yang saya tekankan adalah plot untuk variabel c . Saya mendapatkan garis horizontal untuk rentang c <40 dan c > 60 dan sumbu y terbatas pada nilai yang mendekati nilai rata-rata y . Karena a dan b sama sekali tidak berhubungan dengan y (dan dengan demikian ada variabel penting dalam model adalah 0), saya berharap cakan menunjukkan ketergantungan parsial sepanjang seluruh rentang bukannya bentuk sigmoid untuk rentang nilai yang sangat terbatas. Saya mencoba mencari informasi dalam Friedman (2001) "Perkiraan fungsi serakah: mesin peningkat gradien" dan dalam Hastie et al. (2011) "Elemen Pembelajaran Statistik", tetapi keterampilan matematika saya terlalu rendah untuk memahami semua persamaan dan rumus di dalamnya. Jadi pertanyaan saya: Apa yang menentukan bentuk plot ketergantungan parsial untuk variabel c ? (Tolong jelaskan dengan kata-kata yang bisa dipahami oleh orang yang bukan ahli matematika!)

TAMBAH pada 17 April 2014:

Sambil menunggu jawaban, saya menggunakan contoh data yang sama untuk analisis dengan paket-R randomForest. Plot ketergantungan parsial dari randomForest lebih menyerupai apa yang saya harapkan dari plot gbm: ketergantungan parsial variabel penjelas a dan b bervariasi secara acak dan erat di sekitar 50, sedangkan variabel penjelas c menunjukkan ketergantungan parsial atas seluruh rentangnya (dan lebih dari hampir seluruh rentang y ). Apa yang bisa menjadi alasan untuk berbagai bentuk plot ketergantungan parsial ini dalam gbmdan randomForest?

sebagian plot gbm dan randomForest

Di sini kode yang dimodifikasi yang membandingkan plot:

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
Anda mungkin ingin menyetel Hyperparameters dengan sentuhan. Saya tidak yakin berapa jumlah pohon default dalam gbm, tetapi mungkin sangat kecil sehingga tidak punya waktu untuk mempelajari kelengkungan yang sehat.
Shea Parkes

@Shea Parkes - Anda benar. Jumlah pohon defaukt adalah 100 yang tidak cukup untuk menghasilkan model yang baik. Dengan 2000 pohon plot ketergantungan sebagian gbm dan hutan acak hampir identik.
user7417

Jawaban:


7

Saya menghabiskan beberapa waktu untuk menulis "plot.fungsi-plotter" saya sendiri sebelum saya menyadari itu sudah dibundel di perpustakaan R randomForest.

[EDIT ... tapi kemudian saya menghabiskan satu tahun membuat paket CRAN forestFloor , yang menurut saya jauh lebih baik daripada plot ketergantungan parsial klasik]

Contoh plot plotial.fungsi sangat bagus karena contoh simulasi ini Anda tunjukkan di sini, di mana variabel yang menjelaskan tidak berinteraksi dengan variabel lain. Jika setiap variabel yang menjelaskan berkontribusi secara positif pada target-Y oleh beberapa fungsi yang tidak diketahui, metode ini sangat bagus untuk menunjukkan bahwa fungsi tersembunyi diperkirakan. Saya sering melihat perataan di batas fungsi parsial.

Beberapa alasan: randomForsest memiliki argumen yang disebut 'nodesize = 5' yang berarti tidak ada pohon yang akan membagi kelompok yang terdiri dari 5 anggota atau kurang. Karena itu setiap pohon tidak dapat membedakan dengan presisi lebih lanjut. Lapisan bagging / bootstrap ensemble smooths dengan memilih banyak fungsi langkah dari masing-masing pohon - tetapi hanya di tengah-tengah wilayah data. Mendekati batas data mewakili ruang, 'amplitudo' fungsi parsial akan jatuh. Pengaturan nodesize = 3 dan / atau mendapatkan lebih banyak pengamatan dibandingkan dengan noise dapat mengurangi efek flatting perbatasan ini ... Ketika rasio sinyal terhadap noise jatuh secara umum di hutan acak, skala prediksi mengembun. Dengan demikian prediksi tidak sepenuhnya akurat, tetapi hanya berkorelasi linear dengan target. Anda dapat melihat nilai a dan b sebagai contoh dan rasio sinyal terhadap noise yang sangat rendah, dan karena itu fungsi parsial ini sangat datar. Ini adalah fitur bagus dari hutan acak yang sudah Anda miliki dari kisaran prediksi set pelatihan yang dapat menebak seberapa baik kinerja model. OOB.Prediksi juga bagus ..

perataan plot parsial di daerah tanpa data masuk akal: Karena hutan acak dan CART merupakan pemodelan berbasis data, saya pribadi menyukai konsep bahwa model ini tidak mengekstrapolasi. Jadi prediksi c = 500 atau c = 1100 adalah persis sama dengan c = 100 atau dalam banyak kasus juga c = 98.

Berikut adalah contoh kode dengan perataan batas dikurangi:

Saya belum mencoba paket gbm ...

berikut adalah beberapa kode ilustrasi berdasarkan contoh Anda ...

#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

Seperti disebutkan dalam komentar di atas, model gbm akan lebih baik dengan beberapa penyetelan parameter. Cara mudah untuk menemukan masalah dalam model dan kebutuhan untuk parameter tersebut adalah untuk menghasilkan beberapa plot diagnostik. Misalnya, untuk model gbm di atas dengan parameter default (dan menggunakan paket plotmo untuk membuat plot) kami memiliki

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

pemberian yang mana

merencanakan

Di plot sebelah kiri kita melihat bahwa kurva kesalahan belum mencapai dasar. Dan di plot sebelah kanan residu bukan yang kita inginkan.

Jika kita membangun kembali model dengan jumlah pohon yang lebih besar

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

kita mendapatkan

merencanakan

Kami melihat kurva kesalahan keluar dengan sejumlah besar pohon, dan plot residunya lebih sehat. Kita juga dapat memplot plot ketergantungan parsial untuk model gbm baru dan model hutan acak

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

pemberian yang mana

merencanakan

Gbm dan plot model hutan acak sekarang serupa, seperti yang diharapkan.


3

Anda perlu memperbarui interaction.depthparameter saat membangun model yang didukung. Defaultnya adalah 1 dan itu akan menyebabkan semua pohon yang gbmdibangun oleh algoritma hanya akan terbelah sekali masing-masing. Ini berarti setiap pohon hanya terpecah pada variabel cdan tergantung pada sampel pengamatan yang digunakannya akan terbelah sekitar 40 - 60.

Berikut adalah sebagian plot dengan interaction.depth = 3

masukkan deskripsi gambar di sini


Poin yang bagus, itu
Soren Havelund Welling
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.