R : gbm과 RandomForest의 부분 의존도에서 무엇을 볼 수 있습니까?


14

실제로, 나는 부분 의존성 플롯으로 보여줄 수있는 것을 이해했다고 생각했지만 매우 간단한 가상의 예를 사용하여 다소 당황했습니다. 다음 코드 청크에서 나는 3 개의 독립 변수 ( a , b , c )와 하나의 종속 변수 ( y )를 생성하고 cy 와 밀접한 선형 관계를 나타내는 반면 aby 와 상관이 없습니다 . 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)

놀랍지 않게도, 변수 ab의 경우 부분 의존도는 a 의 평균 주위에 수평선을 생성 합니다 . 내가 당황하는 것은 변수 c에 대한 줄거리입니다 . 전 범위에 대한 가로줄 얻을 C <40 (C) > (60) 및 Y 축이 확대를 의미하는 값으로 제한되고 , Y가 . 이후 및 B는 완전히 관련되지 않은 Y , I는 (모델에 따라서이 변수 중요도 0) 예상 C를매우 제한된 범위의 값에 대한 S 자 모양 대신 전체 범위에 부분 의존성을 나타냅니다. Friedman (2001) "Greedy function approximation : gradient boosting machine"과 Hastie et al. (2011) "통계학 학습 요소"이지만 수학 기술이 너무 낮아서 모든 방정식과 공식을 이해할 수 없습니다. 따라서 내 질문 : 변수 c에 대한 부분 의존도의 모양을 결정하는 것은 무엇입니까 ? (수학자가 아닌 사람이 이해할 수있는 단어로 설명하십시오!)

2014 년 4 월 17 일에 추가됨 :

응답을 기다리는 동안 R-package 분석에 동일한 예제 데이터를 사용했습니다 randomForest. randomForest의 부분 의존도 플롯은 gbm 플롯에서 예상 한 것과 훨씬 더 유사합니다. 설명 변수 ab 의 부분 의존도는 무작위로 거의 50에 가까우며 설명 변수 c 는 전체 범위에 대한 부분 의존성을 보여줍니다. y의 전체 범위 ). 의 부분 의존 플롯의 서로 다른 모양의 원인은 무엇을 할 수 gbmrandomForest?

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-맞습니다. 기본 트리 수는 100으로, 좋은 모델을 생성하기에는 충분하지 않습니다. 2000 그루의 나무에서 gbm과 랜덤 포레스트의 부분 의존도는 거의 동일합니다.
user7417

답변:


7

R randomForest 라이브러리에 이미 번들되어 있음을 깨닫기 전에 자신의 "partial.function-plotter"를 작성하는 데 시간을 보냈습니다.

[편집 ...하지만 1 년 동안 CRAN 패키지 forestFloor를 만드는 데 보냈습니다. 이는 고전적인 부분 의존도보다 훨씬 나은 의견입니다.]

Partial.function 플롯은 설명하는 변수가 다른 변수와 상호 작용하지 않는이 시뮬레이션 예제와 같이 인스턴스에서 유용합니다. 각각의 설명 변수가 알려지지 않은 함수에 의해 target-Y에 부가 적으로 기여하는 경우,이 방법은 추정 된 숨겨진 함수를 보여주는 데 좋습니다. 나는 종종 부분적인 기능의 경계에서 그러한 평탄화를 봅니다.

몇 가지 이유 : randomForsest에는 'nodesize = 5'라는 인수가 있습니다. 즉, 트리가 5 명 이하의 그룹을 세분화하지 않습니다. 따라서 각 트리는 더 정밀하게 구분할 수 없습니다. engingple의 bagging / bootstrapping 레이어는 개별 트리의 많은 단계 기능을 투표하여 데이터 영역의 중간에만 매끄럽게합니다. 공간을 나타내는 데이터의 경계 근처에서 partial.function의 '진폭'이 떨어집니다. 노이즈와 비교하여 노드 크기를 3으로 설정하거나 더 많은 관측 값을 얻으면이 경계 평탄화 효과를 줄일 수 있습니다 ... 신호 대 노이즈 비율이 일반적으로 임의 포리스트에서 떨어지면 예측 규모가 축소됩니다. 따라서 예측은 절대적으로 정확한 용어가 아니라 대상과 선형 적으로 만 관련됩니다. 신호 대 잡음비가 매우 낮고 예를 들어 a와 b 값을 볼 수 있습니다. 따라서 이러한 부분 기능은 매우 평평합니다. 훈련 세트의 예측 범위에서 이미 모델의 성능을 추측 할 수있는 랜덤 포레스트의 멋진 기능입니다. OOB. 예측도 훌륭합니다 ..

데이터가없는 지역에서 부분 플롯의 평탄화는 합리적입니다. 랜덤 포레스트와 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.