Memperoleh pengetahuan dari hutan acak


127

Hutan acak dianggap kotak hitam, tetapi baru-baru ini saya berpikir pengetahuan apa yang bisa diperoleh dari hutan acak?

Hal yang paling jelas adalah pentingnya variabel, dalam varian paling sederhana dapat dilakukan hanya dengan menghitung jumlah kemunculan suatu variabel.
Hal kedua yang saya pikirkan adalah interaksi. Saya berpikir bahwa jika jumlah pohon cukup besar maka jumlah kemunculan pasangan variabel dapat diuji (seperti independensi chi square). Yang ketiga adalah variabel nonlinier. Gagasan pertama saya adalah hanya melihat grafik skor Vs variabel, tapi saya belum yakin apakah itu masuk akal.

Ditambahkan 23.01.2012
Motivasi

Saya ingin menggunakan pengetahuan ini untuk meningkatkan model logit. Saya pikir (atau setidaknya saya berharap) bahwa adalah mungkin untuk menemukan interaksi dan nonlinier yang diabaikan.


1
Menggunakan R Anda dapat menghasilkan Dotchart dengan variabel penting yang diukur dengan Hutan Acak.
George Dontas

1
utas terkait tentang bagaimana langkah-langkah penting variabel dihitung untuk meningkatkan pohon gradien stokastik
Antoine

Saya menyadari ini mungkin sudah terlambat, tetapi jika Anda hanya ingin meningkatkan model logit, mengapa Anda tidak menggunakan regresi logistik post-lasso? Anda cukup mereparasi model menggunakan koefisien yang dipilih setelah pemilihan tanpa penalti / penyusutan. Anda harus sedikit mengubah prosedur penyetelan, tetapi ini adalah opsi yang jauh lebih langsung yang melakukan apa yang Anda inginkan.
ilprincipe

Jawaban:


122

Hutan Acak bukan kotak hitam. Mereka didasarkan pada pohon keputusan, yang sangat mudah ditafsirkan:

#Setup a binary classification problem
require(randomForest)
data(iris)
set.seed(1)
dat <- iris
dat$Species <- factor(ifelse(dat$Species=='virginica','virginica','other'))
trainrows <- runif(nrow(dat)) > 0.3
train <- dat[trainrows,]
test <- dat[!trainrows,]

#Build a decision tree
require(rpart)
model.rpart <- rpart(Species~., train)

Ini menghasilkan pohon keputusan sederhana:

> model.rpart
n= 111 

node), split, n, loss, yval, (yprob)
      * denotes terminal node

1) root 111 35 other (0.68468468 0.31531532)  
  2) Petal.Length< 4.95 77  3 other (0.96103896 0.03896104) *
  3) Petal.Length>=4.95 34  2 virginica (0.05882353 0.94117647) *

Jika Petal. Panjang <4,95, pohon ini mengklasifikasikan pengamatan sebagai "lain." Jika lebih besar dari 4,95, itu mengklasifikasikan pengamatan sebagai "virginica." Hutan acak adalah kumpulan sederhana dari banyak pohon seperti itu, di mana masing-masing dilatih pada bagian acak data. Setiap pohon kemudian "memberikan suara" pada klasifikasi akhir dari setiap pengamatan.

model.rf <- randomForest(Species~., train, ntree=25, proximity=TRUE, importance=TRUE, nodesize=5)
> getTree(model.rf, k=1, labelVar=TRUE)
  left daughter right daughter    split var split point status prediction
1             2              3  Petal.Width        1.70      1       <NA>
2             4              5 Petal.Length        4.95      1       <NA>
3             6              7 Petal.Length        4.95      1       <NA>
4             0              0         <NA>        0.00     -1      other
5             0              0         <NA>        0.00     -1  virginica
6             0              0         <NA>        0.00     -1      other
7             0              0         <NA>        0.00     -1  virginica

Anda bahkan dapat menarik pohon secara individu dari rf, dan melihat strukturnya. Formatnya sedikit berbeda dari rpartmodel, tetapi Anda bisa memeriksa setiap pohon jika Anda mau dan melihat bagaimana memodelkan data.

Selain itu, tidak ada model yang benar-benar kotak hitam, karena Anda dapat memeriksa respons yang diprediksi vs respons aktual untuk setiap variabel dalam dataset. Ini adalah ide yang bagus terlepas dari model apa yang Anda bangun:

library(ggplot2)
pSpecies <- predict(model.rf,test,'vote')[,2]
plotData <- lapply(names(test[,1:4]), function(x){
  out <- data.frame(
    var = x,
    type = c(rep('Actual',nrow(test)),rep('Predicted',nrow(test))),
    value = c(test[,x],test[,x]),
    species = c(as.numeric(test$Species)-1,pSpecies)
    )
  out$value <- out$value-min(out$value) #Normalize to [0,1]
  out$value <- out$value/max(out$value)
  out
})
plotData <- do.call(rbind,plotData)
qplot(value, species, data=plotData, facets = type ~ var, geom='smooth', span = 0.5)

merencanakan

Saya telah menormalkan variabel (panjang dan lebar sepal dan petal) ke rentang 0-1. Responsnya juga 0-1, di mana 0 adalah lainnya dan 1 adalah virginica. Seperti yang Anda lihat, hutan acak adalah model yang baik, bahkan pada set tes.

Selain itu, hutan acak akan menghitung berbagai ukuran variabel penting, yang bisa sangat informatif:

> importance(model.rf, type=1)
             MeanDecreaseAccuracy
Sepal.Length           0.28567162
Sepal.Width           -0.08584199
Petal.Length           0.64705819
Petal.Width            0.58176828

Tabel ini menunjukkan seberapa banyak menghapus setiap variabel mengurangi akurasi model. Terakhir, ada banyak plot lain yang dapat Anda buat dari model hutan acak, untuk melihat apa yang terjadi di dalam kotak hitam:

plot(model.rf)
plot(margin(model.rf)) 
MDSplot(model.rf, iris$Species, k=5)
plot(outlier(model.rf), type="h", col=c("red", "green", "blue")[as.numeric(dat$Species)])

Anda dapat melihat file bantuan untuk masing-masing fungsi ini untuk mendapatkan gambaran yang lebih baik tentang apa yang ditampilkan.


6
Terima kasih atas jawabannya, ada banyak info berguna, tetapi tidak persis apa yang saya cari. Mungkin saya perlu memperjelas motivasi yang ada di balik pertanyaan ini. Saya ingin menggunakan hutan acak untuk meningkatkan model logit, dengan meningkatkan maksud saya menambahkan beberapa interaksi atau menggunakan transformasi nonlinier.
Tomek Tarczynski

@TomekTarczynski itu masalah yang menarik dan mirip dengan yang saya hadapi saat ini. Saya berasumsi dengan "model logit" yang Anda maksud regresi logistik atau sesuatu yang serupa? Saya menggunakan regresi logistik laso (dari paket glmnet R) untuk memilih prediktor dari model dengan interaksi antara semua pasangan variabel. Saya belum menambahkan dalam istilah nonlinier apa pun - tetapi pada prinsipnya itu harus dimungkinkan juga. Satu-satunya masalah yang saya kira adalah memutuskan istilah nonlinear apa yang akan dicoba (istilah polinomial, transformasi eksponensial, dll?). Juga, saya tidak mengambil interaksi tingkat tinggi tetapi itu juga mudah.
Anne Z.

2
@ Tomek, apa yang tidak Anda dapatkan dari jawaban ini? Jika Anda menggunakan paket randomForest di R maka plot yang dijelaskan Zach akan sangat berguna. Khususnya, Anda bisa menggunakan varImpPlot untuk pemilihan fitur dalam model logit Anda dan partialPlot untuk memperkirakan jenis transformasi untuk mencoba prediktor kontinu dalam model logit. Saya akan menyarankan bahwa plot yang terakhir digunakan untuk menentukan di mana hubungan nonlinear antara prediktor dan respons ada dan kemudian memungkinkan Anda untuk membuat transformasi itu secara eksplisit atau menggunakan spline pada variabel itu.
B_Miner

2
@ b_miner - hanya tebakan, tetapi kedengarannya seperti tomek bertanya bagaimana menemukan interaksi non-linear antara variabel karena regresi logistik sudah menangkap hubungan linear.
rm999

@ rm999 Bagaimana Anda mendefinisikan interaksi non linear dalam model logit? Istilah interaksi dibuat antara variabel yang diubah?
B_Miner

52

Beberapa waktu lalu saya harus membenarkan model RF-fit untuk beberapa ahli kimia di perusahaan saya. Saya menghabiskan cukup banyak waktu mencoba berbagai teknik visualisasi. Selama proses, saya tidak sengaja juga menemukan beberapa teknik baru yang saya masukkan ke dalam paket R ( forestFloor ) khusus untuk visualisasi hutan acak.

Pendekatan klasik adalah plot ketergantungan parsial yang didukung oleh: Rminer (analisis sensitivitas berbasis data diciptakan kembali ketergantungan parsial), atau parsialPlot dalam paket randomForest . Saya menemukan paket ketergantungan parsial iceBOX sebagai cara yang elegan untuk menemukan interaksi. Belum menggunakan paket edarf , tetapi tampaknya memiliki beberapa visualisasi bagus yang didedikasikan untuk RF. The ggRandomForest paket juga mengandung satu set besar visualisasi berguna.

Saat ini forestFloor mendukung objek randomForest (dukungan untuk implementasi RF lainnya sedang dalam perjalanan). Kontribusi fitur juga dapat dihitung untuk pohon yang didorong gradien, karena pohon-pohon ini setelah pelatihan tidak jauh berbeda dari pohon hutan acak. Jadi forestFloor dapat mendukung XGBoost di masa depan. Plot ketergantungan sebagian sepenuhnya invarian model.

Semua paket memiliki kesamaan untuk memvisualisasikan struktur pemetaan geometri model dari ruang fitur ke ruang target. Kurva sinus y = sin (x) akan menjadi pemetaan dari x ke y dan dapat diplot dalam 2D. Untuk memetakan pemetaan RF secara langsung seringkali membutuhkan dimensi yang terlalu banyak. Alih-alih keseluruhan struktur pemetaan dapat diproyeksikan, diiris atau didekomposisi, sehingga seluruh struktur pemetaan diringkas menjadi urutan plot marjinal 2D. Jika model RF Anda hanya menangkap efek utama dan tidak ada interaksi antara variabel, metode visualisasi klasik akan baik-baik saja. Kemudian Anda dapat menyederhanakan struktur model Anda seperti iniy=F(X)f1(x1)+f2(x2)+...+fd(xd). Kemudian setiap fungsi parsial oleh masing-masing variabel dapat divisualisasikan seperti halnya kurva sinus. Jika model RF Anda telah menangkap interaksi yang cukup besar, maka itu lebih bermasalah. Irisan struktur 3D dapat memvisualisasikan interaksi antara dua fitur dan output. Masalahnya adalah untuk mengetahui kombinasi fitur mana yang harus divisualisasikan, ( iceBOX memang mengatasi masalah ini). Juga tidak mudah untuk mengetahui apakah interaksi laten lainnya masih belum diperhitungkan.

Dalam makalah ini , saya menggunakan versi ForestFloor yang sangat awal untuk menjelaskan hubungan biokimia aktual apa yang telah ditangkap oleh model RF yang sangat kecil. Dan dalam makalah ini kami menjelaskan secara menyeluruh visualisasi kontribusi fitur, Visualisasi Lantai Hutan dari Hutan Acak .

Saya telah menempelkan contoh yang disimulasikan dari paket forestFloor, di mana saya menunjukkan cara mengungkap fungsi tersembunyi yang disimulasikan noisey=x12+sin(x2π)+2x3x4+

#1 - Regression example:
set.seed(1234)
library(forestFloor)
library(randomForest)

#simulate data y = x1^2+sin(x2*pi)+x3*x4 + noise
obs = 5000 #how many observations/samples
vars = 6   #how many variables/features
#create 6 normal distr. uncorr. variables
X = data.frame(replicate(vars,rnorm(obs)))
#create target by hidden function
Y = with(X, X1^2 + sin(X2*pi) + 2 * X3 * X4 + 0.5 * rnorm(obs)) 

#grow a forest
rfo = randomForest(
  X, #features, data.frame or matrix. Recommended to name columns.
  Y, #targets, vector of integers or floats
  keep.inbag = TRUE,  # mandatory,
  importance = TRUE,  # recommended, else ordering by giniImpurity (unstable)
  sampsize = 1500 ,   # optional, reduce tree sizes to compute faster
  ntree = if(interactive()) 500 else 50 #speedup CRAN testing
)

#compute forestFloor object, often only 5-10% time of growing forest
ff = forestFloor(
  rf.fit = rfo,       # mandatory
  X = X,              # mandatory
  calc_np = FALSE,    # TRUE or FALSE both works, makes no difference
  binary_reg = FALSE  # takes no effect here when rfo$type="regression"
)


#plot partial functions of most important variables first
plot(ff,                       # forestFloor object
     plot_seq = 1:6,           # optional sequence of features to plot
     orderByImportance=TRUE    # if TRUE index sequence by importance, else by X column  
)

masukkan deskripsi gambar di sini

#Non interacting features are well displayed, whereas X3 and X4 are not
#by applying color gradient, interactions reveal themself 
#also a k-nearest neighbor fit is applied to evaluate goodness-of-fit
Col=fcol(ff,3,orderByImportance=FALSE) #create color gradient see help(fcol)
plot(ff,col=Col,plot_GOF=TRUE) 

masukkan deskripsi gambar di sini

#feature contributions of X3 and X4 are well explained in the context of X3 and X4
# as GOF R^2>.8


show3d(ff,3:4,col=Col,plot_GOF=TRUE,orderByImportance=FALSE)

masukkan deskripsi gambar di sini masukkan deskripsi gambar di sini

Terakhir kode untuk plot ketergantungan sebagian dikodekan oleh A.Liaw yang dijelaskan oleh J.Friedman. Yang bagus untuk efek utama.

par(mfrow=c(2,3))
for(i in 1:6) partialPlot(rfo,X,x.var=names(X)[i])

masukkan deskripsi gambar di sini


Saya mendalilkan sebelumnya bahwa kontribusi fitur juga dapat dihitung untuk pohon yang ditingkatkan. Saya menulis algoritma pengujian dan itu mungkin. Sayangnya, fitur kontribusi untuk pohon-pohon yang dikuatkan, tidak menunjukkan sifat menguntungkan yang sama seperti pohon-pohon yang dikantongi. Efek dari satu fitur cenderung tersebar di semua kontribusi fitur, sehingga visualisasi menjadi cukup membingungkan.
Soren Havelund Welling

Oups! Saya menemukan bug dalam algoritma pengujian saya yang membuat semua masalah hilang. forestFloor dapat dimutakhirkan agar berfungsi dengan baik untuk pohon-pohon yang didorong gradien.
Soren Havelund Welling

3
Apakah forestFloor diperbarui untuk menerima objek gbm?
Misha

Sejauh ini, saya telah melakukan implementasi terbalik, yang membungkus implementasi randomForest menjadi mesin peningkat gradien yang berfungsi penuh dan mendefinisikan beberapa metode untuk menghitung kontribusi fitur. Saya pikir implementasi sebenarnya cukup efisien. Anda dapat menemukan kode di sini: github.com/sorhawell/forestFloor/blob/master/inst/examples/…
Soren Havelund Welling

Untuk membuat port penuh adalah kerja keras :) Implementasi ini dilakukan dalam beberapa baris.
Soren Havelund Welling

24

Untuk melengkapi tanggapan yang baik ini, saya akan menyebutkan penggunaan gradient boosted tree (mis. Paket GBM di R ). Dalam R, saya lebih suka ini dari hutan acak karena nilai yang hilang diizinkan dibandingkan dengan randomForest di mana imputasi diperlukan. Variabel kepentingan dan plot parsial tersedia (seperti dalam randomForest) untuk membantu dalam pemilihan fitur dan eksplorasi transformasi nonlinier dalam model logit Anda. Selanjutnya, interaksi variabel ditangani dengan H-statistik Friedman ( interact.gbm) dengan referensi yang diberikan sebagai J.H. Friedman and B.E. Popescu (2005). “Predictive Learning via Rule Ensembles.” Section 8.1. Versi komersial yang disebut TreeNet tersedia dari Salford Systems dan penyajian video ini berbicara untuk mereka tentang Video estimasi interaksi variabel .


2
Saya setuju, GBM adalah langkah logis berikutnya dari hutan acak.
Zach

@ B_miner: Hebat! Saya tidak tahu caranya, tetapi saya telah mengabaikan GBM. Tampaknya menggunakan GBM mudah mendeteksi interaksi dan nonlinier.
Tomek Tarczynski

15

Jawaban terlambat, tetapi saya menemukan paket R baru-baru ini forestFloor(2015) yang membantu Anda melakukan tugas "unblackboxing" ini secara otomatis. Itu terlihat sangat menjanjikan!

library(forestFloor)
library(randomForest)
#simulate data
obs=1000
vars = 18
X = data.frame(replicate(vars,rnorm(obs)))
Y = with(X, X1^2 + sin(X2*pi) + 2 * X3 * X4 + 1 * rnorm(obs))
#grow a forest, remeber to include inbag
rfo=randomForest(X,Y,keep.inbag = TRUE,sampsize=250,ntree=50)
#compute topology
ff = forestFloor(rfo,X)
#ggPlotForestFloor(ff,1:9)
plot(ff,1:9,col=fcol(ff))

Menghasilkan plot berikut:

masukkan deskripsi gambar di sini

Ini juga menyediakan visualisasi tiga dimensi jika Anda mencari interaksi.


4
Saya menghapus dukungan untuk ggplot2, daripada mencoba baris terakhir, misalnya: plot (ff, 1: 9, col = fcol (ff, 1: 4))
Soren Havelund Welling

9

Seperti yang disebutkan oleh Zach, salah satu cara memahami model adalah memplot respons karena prediktornya berbeda-beda. Anda dapat melakukan ini dengan mudah untuk model "apa saja" dengan paket plotmo R. Sebagai contoh

library(randomForest)
data <- iris
data$Species <- factor(ifelse(data$Species=='virginica','virginica','other'))
mod <- randomForest(Species~Sepal.Length+Sepal.Width, data=data)
library(plotmo)
plotmo(mod, type="prob")

pemberian yang mana

merencanakan

Ini mengubah satu variabel sambil memegang yang lain pada nilai mediannya. Untuk plot interaksi, ini mengubah dua variabel. (Catatan ditambahkan Nov 2016: plotmosekarang juga mendukung plot ketergantungan parsial.)

Contoh di atas hanya menggunakan dua variabel; model yang lebih rumit dapat divisualisasikan secara sedikit demi sedikit dengan melihat satu atau dua variabel sekaligus. Karena variabel "lain" dipegang pada nilai mediannya, ini hanya menunjukkan sebagian data, tetapi masih bisa bermanfaat. Beberapa contoh ada dalam sketsa untuk paket plotmo . Contoh lain ada di Bab 10 dari Merencanakan pohon rpart dengan paket rpart.plot .


4

Saya sendiri sangat tertarik dengan jenis pertanyaan ini. Saya pikir ada banyak informasi yang bisa kita dapatkan dari hutan acak.

Tentang Interaksi, sepertinya Breiman dan Cultier sudah mencoba melihatnya, terutama untuk RF klasifikasi.

Setahu saya, ini belum diimplementasikan dalam paket R randomForest. Mungkin karena itu mungkin tidak sesederhana dan karena arti "interaksi variabel" sangat tergantung pada masalah Anda.

Tentang nonlinier, saya tidak yakin apa yang Anda cari, hutan regresi digunakan untuk masalah regresi berganda nonlinier tanpa ada prior tentang jenis fungsi nonlinear yang digunakan.


3

Terlambat dalam permainan tetapi ada beberapa perkembangan baru di depan ini, misalnya LIME dan SHAP . Juga paket yang layak diperiksa adalah DALEX (khususnya jika menggunakan R tetapi dalam kasus apa pun mengandung lembar contekan yang bagus, dll.), Meskipun sepertinya tidak mencakup interaksi saat ini. Dan ini semua model-agnostik sehingga akan bekerja untuk hutan acak, GBM, jaringan saraf, dll.


(+1) Sumber daya yang bagus!
mkt

2

Sedikit modifikasi dari hutan acak yang menyediakan lebih banyak informasi tentang data adalah metode hutan kausal yang baru dikembangkan. Lihat paket-GRF dan makalah yang memotivasi di sini . Idenya adalah untuk menggunakan metode baseline hutan acak untuk menemukan heterogenitas dalam efek sebab akibat.

Makalah sebelumnya (di sini ) memberikan pendekatan terperinci untuk hutan sebab akibat yang sederhana. Halaman 9 dari makalah ini memberikan prosedur langkah demi langkah untuk menumbuhkan pohon kausal, yang kemudian dapat diperluas ke hutan dengan cara yang biasa.Diambil dari Halaman 9 dari Athey and Wager 2017

Persamaan 4:

Persamaan 4

Persamaan 5: Persamaan 5


1
Diperbarui dengan tautan ke kertas sebelumnya dan tangkapan layar dari kertas itu untuk menunjukkan prosedur pohon sebab-akibat.
gannawag

1

Jawaban terlambat terkait dengan pertanyaan saya di sini ( Bisakah kita membuat Random Forest 100% dapat ditafsirkan dengan memperbaiki benih? ):

z1z2

  1. z1mD1(z1)D2(z1)D3(z1)Dm(z1)
  2. mT1(z1,z2)T2(z1,z2)T3(z1,z2)Tm(z1,z2)
  3. jth(j=1,2,...,m)xif^j(xi)(in,jm)
    F^(xi)=>1mj=1mf^j(xi)
  4. F^(xi)(z1,z2)xi
  5. xi
    x1F^(x1) - which is fixed> thanks to (z1,z2)
    x2F^(x2) -> which is fixed thanks to (z1,z2)
    x3→>F^(x3) - which is fixed thanks to (z1,z2)
    x4>→F^(x4) - which is fixed thanks to (z1,>z2)
    ....
  6. x1x2

Ini juga berfungsi untuk setiap metode ensembel berdasarkan agregasi pohon.

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.