임의의 숲에서 지식 얻기


127

임의의 숲은 블랙 박스로 간주되지만 최근에는 임의의 숲에서 어떤 지식을 얻을 수 있다고 생각하고 있었습니까?

가장 명백한 것은 변수의 중요성이며, 가장 간단한 변형에서는 변수의 발생 횟수를 계산하여 수행 할 수 있습니다.
두 번째로 생각한 것은 상호 작용입니다. 나무의 수가 충분히 크면 변수 쌍의 발생 횟수를 테스트 할 수 있다고 생각합니다 (카이 제곱 독립과 같은 것). 세 번째는 비선형 변수입니다. 내 첫 번째 아이디어는 가변 Vs 점수의 차트를 보는 것이지만 아직 의미가 있는지 확실하지 않습니다.

2012 년 1 월 23 일 추가됨
동기

이 지식을 사용하여 로짓 모델을 개선하고 싶습니다. 간과 된 상호 작용과 비선형 성을 찾을 수 있다고 생각합니다.


1
R을 사용 하면 랜덤 포레스트로 측정 할 때 가변 중요도 의 도트 차트 를 생성 할 수 있습니다 .
George Dontas

1
확률 적 그라디언트 트리 부스팅을위한 변수 중요도 측정 방법에 관한 관련 스레드
Antoine

아마도 이것이 너무 늦다는 것을 알고 있지만 로짓 모델을 개선하고 싶다면 왜 post-lasso logistic regression을 사용하지 않습니까? 처벌 / 수축없이 선택 후 선택한 계수를 사용하여 모델을 다시 맞출 수 있습니다. 튜닝 절차를 약간 조정해야하지만 이것은 정확히 원하는 것을 수행하는 훨씬 직접적인 옵션입니다.
ilprincipe

답변:


122

랜덤 포레스트는 거의 블랙 박스가 아닙니다. 의사 결정 트리를 기반으로하며 해석하기 매우 쉽습니다.

#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)

간단한 의사 결정 트리가 생성됩니다.

> 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) *

Petal.Length <4.95 인 경우이 트리는 관측치를 "기타"로 분류합니다. 4.95보다 크면 관측치를 "virginica"로 분류합니다. 랜덤 포레스트는 각 트리가 임의의 데이터 하위 집합에 대해 훈련되는 여러 트리의 모음입니다. 그런 다음 각 트리는 각 관측치의 최종 분류에 "투표"합니다.

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

rf에서 개별 트리를 꺼내어 그 구조를 볼 수도 있습니다. 형식은 rpart모델과 약간 다르지만 원하는 경우 각 트리를 검사하여 데이터 모델링 방법을 확인할 수 있습니다.

또한 데이터 집합의 각 변수에 대해 예측 된 반응과 실제 반응을 조사 할 수 있기 때문에 진정한 블랙 박스가 아닙니다. 이것은 어떤 종류의 모델을 작성하든 관계없이 좋은 아이디어입니다.

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)

음모

변수 (sepal 및 petal length 및 width)를 0-1 범위로 정규화했습니다. 응답은 또한 0-1이며 0은 다른 것이고 1은 virginica입니다. 보시다시피 무작위 포리스트는 테스트 세트에서도 좋은 모델입니다.

또한 임의 포리스트는 다양한 중요도 측정 값을 계산하므로 매우 유익 할 수 있습니다.

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

이 표는 각 변수를 얼마나 많이 제거하면 모형의 정확도가 감소하는지 나타냅니다. 마지막으로, 랜덤 포레스트 모델에서 블랙 박스에서 무슨 일이 일어나고 있는지 볼 수있는 다른 많은 플롯이 있습니다 :

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)])

이러한 각 기능에 대한 도움말 파일을보고 표시되는 내용을 더 잘 이해할 수 있습니다.


6
답변 주셔서 감사합니다, 유용한 정보가 많이 있지만, 내가 정확히 찾고있는 것은 아닙니다. 어쩌면 나는이 질문의 배후에있는 동기를 더 명확히해야 할 것입니다. 무작위 포리스트를 사용하여 로짓 모델을 개선하고 싶습니다. 개선을 통해 상호 작용을 추가하거나 비선형 변환을 사용하려고합니다.
Tomek Tarczynski

@TomekTarczynski 이것은 흥미로운 문제이며 지금 다루고있는 것과 비슷합니다. "logit model"은 로지스틱 회귀 또는 이와 유사한 것을 의미한다고 가정합니다. (glmnet R 패키지의) 올가미 로지스틱 회귀 분석을 사용하여 모든 변수 쌍 사이의 상호 작용이있는 모델에서 예측 변수를 선택합니다. 비선형 용어를 아직 추가하지 않았지만 원칙적으로는 가능해야합니다. 내가 생각하는 유일한 문제는 어떤 비선형 항 (다항식, 지수 변환 등)을 결정하는 것입니다. 또한, 나는 고차 상호 작용을 선택하지 않지만 쉽지 않습니다.
Anne Z.

2
@Tomek,이 답변에서 무엇을 얻지 못하고 있습니까? R에서 randomForest 패키지를 사용하는 경우 Zach가 설명하는 플롯이 매우 유용합니다. 특히, 로짓 모델의 기능 선택에 varImpPlot을 사용하고 로짓 모델의 연속 예측 변수에 대해 시도 할 변환 유형을 추정하기 위해 partialPlot을 사용할 수 있습니다. 후자의 플롯을 사용하여 예측 변수와 반응 사이의 비선형 관계가 존재하는지 확인한 다음 해당 변환을 명시 적으로 만들거나 해당 변수에 스플라인을 사용할 수 있습니다.
B_Miner

2
@b_miner-추측이지만 tomek은 로지스틱 회귀 분석이 이미 선형 관계를 캡처하기 때문에 변수 간 비선형 상호 작용을 찾는 방법을 묻는 것처럼 들립니다.
rm999

@ rm999 로짓 모델에서 비선형 상호 작용을 어떻게 정의합니까? 변형 된 변수 사이에 생성 된 상호 작용 항?
B_Miner

52

얼마 전에 저는 회사의 일부 화학자에게 RF 모델 적합성을 정당화해야했습니다. 다른 시각화 기술을 시도하는 데 꽤 많은 시간을 보냈습니다. 이 과정에서 우연히 임의의 포리스트 시각화를 위해 R 패키지 ( forestFloor )에 넣은 새로운 기술을 실수로 생각해 냈습니다 .

전통적인 접근 방식은 Rminer (데이터 기반 감도 분석은 부분 의존성을 재발 명함) 또는 randomForest 패키지의 partialPlot에서 지원하는 부분 의존도 플롯 입니다. 상호 의존성 을 발견하는 우아한 방법으로 부분 의존성 패키지 iceBOX 를 찾습니다. edarf 패키지를 사용 하지는 않았지만 RF 전용 시각화가 일부있는 것 같습니다. ggRandomForest의 패키지는 유용한 시각화의 대형 세트가 포함되어 있습니다.

현재 forestFloor는 randomForest 객체를 지원합니다 (다른 RF 구현 지원이 진행 중임). 또한 그라디언트 부스트 트리에 대해 기능 기여도를 계산할 수 있습니다. 훈련 후의 트리는 임의의 포리스트 트리와 크게 다르지 않기 때문입니다. 따라서 forestFloor는 향후 XGBoost를 지원할 수 있습니다. 부분 의존도는 완전히 모형 불변입니다.

모든 패키지는 피쳐 공간에서 대상 공간까지 모델의 기하학적 매핑 구조를 공통적으로 표시합니다. 사인 곡선 y = sin (x)는 x에서 y 로의 매핑이며 2D로 그려 질 수 있습니다. RF 매핑을 직접 플로팅하려면 종종 너무 많은 치수가 필요합니다. 대신에, 전체 매핑 구조가 투영, 슬라이스 또는 분해 될 수있어서, 전체 매핑 구조가 2D 한계 플롯의 시퀀스로 끓여진다. RF 모델이 주요 효과 만 캡처하고 변수 간 상호 작용이없는 경우 기존 시각화 방법만으로도 충분합니다. 그러면 와 같은 모델 구조를 단순화 할 수 있습니다y=F(X)f1(x1)+f2(x2)+...+fd(xd). 그런 다음 각 변수에 의한 각 부분 함수를 사인 곡선처럼 시각화 할 수 있습니다. RF 모델이 상당한 상호 작용을 캡처 한 경우 더 문제가 있습니다. 구조의 3D 슬라이스는 두 피처와 출력 간의 상호 작용을 시각화 할 수 있습니다. 문제는 시각화 할 기능 조합을 아는 것입니다 ( 아이스 박스 는이 문제를 해결합니다). 또한 다른 잠복 상호 작용이 여전히 설명되지 않는지 쉽게 알 수 없습니다.

에서 본 논문 , 나는 아주 작은 RF 모델을 캡처 한 생화학 실제 어떤 관계를 설명하기 위해 forestFloor의 초기 버전을 사용했다. 그리고 본 논문에서는 기능 기여의 시각화, 랜덤 포레스트의 포레스트 플로어 시각화에 대해 자세히 설명 합니다.

forestFloor 패키지에서 시뮬레이션 예제를 붙여 넣었습니다. 여기서 시뮬레이션 숨겨진 함수 noise 를 찾아내는 방법을 보여줍니다y=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  
)

여기에 이미지 설명을 입력하십시오

#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) 

여기에 이미지 설명을 입력하십시오

#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)

여기에 이미지 설명을 입력하십시오 여기에 이미지 설명을 입력하십시오

마지막으로 J.Friedman에 의해 기술 된 A.Liaw에 의해 코딩 된 부분 의존도에 대한 코드. 주요 효과에 적합합니다.

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

여기에 이미지 설명을 입력하십시오


이전에 부스트 트리에 대한 기능 기여도를 계산할 수 있다고 가정했습니다. 테스트 알고리즘을 작성했으며 가능합니다. 불행히도, 강화 된 나무에 대한 기능 기여는 포장 된 나무와 동일한 유익한 특성을 나타내지 않습니다. 한 기능의 효과는 모든 기능에 영향을 미치므로 시각화가 매우 혼란스러워집니다.
Soren Havelund Welling

웁스! 테스트 알고리즘에서 모든 문제가 사라지는 버그를 발견했습니다. forestFloor는 그라디언트 향상 트리에서 제대로 작동하도록 업데이트 할 수 있습니다.
Soren Havelund Welling

3
gbm 객체를 허용하도록 forestFloor가 업데이트됩니까?
Misha

지금까지 randomForest 구현을 완전한 기능적 그라디언트 부스팅 머신으로 래핑하고 기능 기여도를 계산하는 몇 가지 방법을 정의하는 리버스 구현을 수행했습니다. 구현이 실제로 효율적이라고 생각합니다. 여기에서 코드를 찾을 수 있습니다 : github.com/sorhawell/forestFloor/blob/master/inst/examples/…
Soren Havelund Welling

전체 포트를 만드는 것은 어려운 일입니다. :)이 구현은 몇 줄로 이루어졌습니다.
Soren Havelund Welling

24

이러한 정밀한 응답을 보충하기 위해 그라디언트 부스트 트리 (예 : RGBM 패키지)를 사용한다고 언급합니다 . R에서는 대치가 필요한 randomForest와 비교할 때 누락 된 값이 허용되므로 R을 임의 포리스트보다 선호합니다. 로짓 모델에서 피처 선택 및 비선형 변환 탐색을 지원하기 위해 변수 중요도 및 부분 그림 (randomForest에서와 같이)을 사용할 수 있습니다. 또한, 가변 상호 작용은 프리드먼의 H- 통계량 ( interact.gbm)으로 다루어진다 J.H. Friedman and B.E. Popescu (2005). “Predictive Learning via Rule Ensembles.” Section 8.1. Salford Systems에서 TreeNet이라는 상용 버전을 사용할 수 있으며이 비디오 프레젠테이션은 가변 상호 작용 추정 비디오에 대해 설명 합니다.


2
GBM은 임의 포리스트의 논리적 다음 단계입니다.
Zach

@B_miner : 좋아요! 어떻게 해야할지 모르겠지만 GBM을 간과했습니다. GBM을 사용하면 상호 작용 및 비선형 성을 쉽게 감지 할 수 있습니다.
Tomek Tarczynski

15

답은 forestFloor늦었지만 자동화 된 방식으로이 "비 블랙 박스"작업을 수행하는 데 도움이 되는 최근 R 패키지 (2015)를 발견했습니다. 매우 유망 해 보인다!

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))

다음과 같은 플롯을 생성합니다.

여기에 이미지 설명을 입력하십시오

또한 상호 작용을 찾고 있다면 3 차원 시각화를 제공합니다.


4
마지막 줄 대신 ggplot2에 대한 지원을 제거했습니다. 예 : plot (ff, 1 : 9, col = fcol (ff, 1 : 4))
Soren Havelund Welling

9

Zach가 언급했듯이 모형을 이해하는 한 가지 방법은 예측 변수가 다양 할 때 반응을 도표로 나타내는 것입니다. plotmo R 패키지를 사용하여 "모든"모델에 대해이 작업을 쉽게 수행 할 수 있습니다 . 예를 들어

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")

어느 것이

음모

변수 하나를 중간 값으로 유지하면서 변수 하나를 변경합니다. 교호 작용도의 경우 두 변수가 변경됩니다. (2016 년 11 월 추가됨 : plotmo이제 부분 의존도도 지원합니다.)

위의 예는 두 개의 변수 만 사용합니다. 한 번에 하나 또는 두 개의 변수를 보면보다 복잡한 모델을 단편적으로 시각화 할 수 있습니다. "기타"변수는 중간 값으로 유지되므로 데이터 조각 만 표시하지만 여전히 유용 할 수 있습니다. 일부 예제는 plotmo 패키지비 네트에 있습니다. 다른 예는 rpart.plot 패키지를 사용하여 rpart 트리 플로팅의 10 장에 있습니다.


4

나는 이러한 유형의 질문에 매우 관심이 있습니다. 임의의 포리스트에서 얻을 수있는 많은 정보가 있다고 생각합니다.

상호 작용에 대해서는 Breiman과 Cultier 가 이미 분류 RF에 대해 이미 살펴 보려고 한 것 같습니다 .

내가 알기로는, 이것은 randomForest R 패키지에서 구현되지 않았습니다. 간단하지 않을 수도 있고 "가변 상호 작용"의 의미가 문제에 크게 의존하기 때문일 수 있습니다.

비선형성에 대해, 나는 당신이 찾고있는 것을 확신하지 못합니다. 회귀 포리스트는 어떤 유형의 비선형 함수를 사용할 지에 대한 사전 결정없이 비선형 다중 회귀 문제에 사용됩니다.


3

게임이 늦었지만 LIMESHAP 와 같은 새로운 개발이 있습니다. 또한 검사 할 가치가있는 패키지는 DALEX입니다 (특히 R을 사용하지만 어떤 경우에는 멋진 치트 시트 등이 포함되어있는 경우). 그러나 현재 상호 작용을 다루지는 않습니다. 그리고 이들은 모두 모델에 구애받지 않으므로 임의의 포리스트, GBM, 신경망 등에서 작동합니다.


(+1) 멋진 자원!
mkt

2

데이터에 대한 자세한 정보를 제공하는 임의 포리스트를 약간 수정하면 최근에 개발 된 인과 포리스트 방법이 있습니다. 여기 에서 GRF R 패키지 및 동기 부여 용지를 참조하십시오 . 아이디어는 임의 포리스트 기준선 방법을 사용하여 인과 관계 효과에서 이질성을 찾는 것입니다.

이전 논문 ( here )은 간단한 인과 숲에 대한 자세한 접근 방식을 제공합니다. 이 논문의 9 페이지는 인과 나무를 키우기위한 단계별 절차를 제공하며, 일반적인 절차에 따라 숲으로 확장 될 수 있습니다.2017 Athey and Wager 9 페이지에서 발췌

방정식 4 :

방정식 4

방정식 5 : 방정식 5


1
인과 트리 절차를 보여주기 위해 이전 논문과 해당 논문의 스크린 샷에 대한 링크로 업데이트되었습니다.
gannawag

1

내 질문과 관련된 늦은 답변은 여기에 있습니다 ( 시드를 수정하여 랜덤 포레스트를 100 % 해석 할 수 있습니까? ) :

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

이것은 트리 집계에 기반한 모든 앙상블 방법에도 적용됩니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.