RF는 비선형 성을 처리 할 수 있지만 계수를 제공 할 수 없기 때문에 랜덤 포레스트를 사용하여 가장 중요한 피쳐를 수집 한 다음 계수를 얻기 위해 해당 피쳐를 다중 선형 회귀 모델에 연결하는 것이 현명합니까?
RF는 비선형 성을 처리 할 수 있지만 계수를 제공 할 수 없기 때문에 랜덤 포레스트를 사용하여 가장 중요한 피쳐를 수집 한 다음 계수를 얻기 위해 해당 피쳐를 다중 선형 회귀 모델에 연결하는 것이 현명합니까?
답변:
RF는 비선형 성을 처리 할 수 있지만 계수를 제공 할 수 없기 때문에 랜덤 포레스트를 사용하여 가장 중요한 피처를 수집 한 다음 해당 피처를 다중 선형 회귀 모델에 연결하여 부호를 설명하는 것이 현명합니까?
OP의 한 문장 질문은 OP가 다음 분석 파이프 라인의 바람직 함을 이해하고 싶다는 의미로 해석합니다.
나는이 파이프 라인이 당신이 원하는 것을 성취 할 것이라고 생각하지 않습니다. 랜덤 포레스트에서 중요한 변수는 반드시 결과와 선형 적으로 부가적인 관계를 가질 필요는 없습니다. 이 말은 놀라운 일이 아닙니다. 이는 임의의 숲이 비선형 관계를 발견하는 데 매우 효과적입니다.
다음은 예입니다. 10 개의 노이즈 기능, 2 개의 "신호"기능 및 순환 결정 경계로 분류 문제를 만들었습니다.
set.seed(1)
N <- 500
x1 <- rnorm(N, sd=1.5)
x2 <- rnorm(N, sd=1.5)
y <- apply(cbind(x1, x2), 1, function(x) (x%*%x)<1)
plot(x1, x2, col=ifelse(y, "red", "blue"))
lines(cos(seq(0, 2*pi, len=1000)), sin(seq(0, 2*pi, len=1000)))
RF 모델을 적용 할 때 이러한 기능이 모델에서 중요하게 쉽게 선택할 수 있다는 사실에 놀라지 않습니다. (주의 :이 모델은 조정되지 않는다 전혀 .)
x_junk <- matrix(rnorm(N*10, sd=1.5), ncol=10)
x <- cbind(x1, x2, x_junk)
names(x) <- paste("V", 1:ncol(x), sep="")
rf <- randomForest(as.factor(y)~., data=x, mtry=4)
importance(rf)
MeanDecreaseGini
x1 49.762104
x2 54.980725
V3 5.715863
V4 5.010281
V5 4.193836
V6 7.147988
V7 5.897283
V8 5.338241
V9 5.338689
V10 5.198862
V11 4.731412
V12 5.221611
그러나이 두 가지 유용한 기능 만 선택하면 결과 선형 모델이 끔찍합니다.
summary(badmodel <- glm(y~., data=data.frame(x1,x2), family="binomial"))
요약의 중요한 부분은 잔차 이탈과 영 이탈을 비교하는 것입니다. 모델이 기본적으로 이탈을 "이동"시키는 것은 아무 것도 없다는 것을 알 수 있습니다. 또한, 계수 추정치는 본질적으로 0이다.
Call:
glm(formula = as.factor(y) ~ ., family = "binomial", data = data.frame(x1,
x2))
Deviance Residuals:
Min 1Q Median 3Q Max
-0.6914 -0.6710 -0.6600 -0.6481 1.8079
Coefficients:
Estimate Std. Error z value Pr(>|z|)
(Intercept) -1.398378 0.112271 -12.455 <2e-16 ***
x1 -0.020090 0.076518 -0.263 0.793
x2 -0.004902 0.071711 -0.068 0.946
---
Signif. codes: 0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1
(Dispersion parameter for binomial family taken to be 1)
Null deviance: 497.62 on 499 degrees of freedom
Residual deviance: 497.54 on 497 degrees of freedom
AIC: 503.54
Number of Fisher Scoring iterations: 4
두 모델의 차이점은 무엇입니까? 자, 우리가 배우고 자하는 결정 경계는 두 가지 "신호"기능의 선형 기능이 아닙니다. 회귀를 추정하기 전에 의사 결정 경계의 기능적 형태를 알고 있다면 회귀가 발견 할 수있는 방식으로 데이터를 인코딩하기 위해 약간의 변환을 적용 할 수 있습니다 ... 이 경우 클래스 레이블에 노이즈가없는 합성 데이터 세트의 두 가지 신호 기능 만 사용하므로 클래스 간의 경계는 플롯에서 매우 분명합니다. 그러나 실제 데이터를 현실적인 차원으로 작업 할 때는 덜 명확합니다.
또한 임의 포리스트는 일반적으로 다른 모델을 데이터의 다른 하위 집합에 맞출 수 있습니다. 더 복잡한 예에서는 단일 플롯에서 무슨 일이 일어나고 있는지 분명하지 않으며 유사한 예측력의 선형 모델을 작성하는 것이 훨씬 어려울 것입니다.
우리는 두 가지 차원에만 관심이 있기 때문에 예측 표면을 만들 수 있습니다. 예상대로 랜덤 모델은 원점 주변이 중요하다는 것을 알게됩니다.
M <- 100
x_new <- seq(-4,4, len=M)
x_new_grid <- expand.grid(x_new, x_new)
names(x_new_grid) <- c("x1", "x2")
x_pred <- data.frame(x_new_grid, matrix(nrow(x_new_grid)*10, ncol=10))
names(x_pred) <- names(x)
y_hat <- predict(object=rf, newdata=x_pred, "vote")[,2]
library(fields)
y_hat_mat <- as.matrix(unstack(data.frame(y_hat, x_new_grid), y_hat~x1))
image.plot(z=y_hat_mat, x=x_new, y=x_new, zlim=c(0,1), col=tim.colors(255),
main="RF Prediction surface", xlab="x1", ylab="x2")
우리의 abysmal 모델 출력에서 알 수 있듯이 감소 변수 로지스틱 회귀 모델의 예측 표면은 기본적으로 평평합니다.
bad_y_hat <- predict(object=badmodel, newdata=x_new_grid, type="response")
bad_y_hat_mat <- as.matrix(unstack(data.frame(bad_y_hat, x_new_grid), bad_y_hat~x1))
image.plot(z=bad_y_hat_mat, x=x_new, y=x_new, zlim=c(0,1), col=tim.colors(255),
main="Logistic regression prediction surface", xlab="x1", ylab="x2")
보다 "임의의 포리스트에 적합한"문제에 올바르게 실행 된 임의 포리스트는 노이즈를 제거하고 다른 분석 도구에 대한 입력으로 더 유용한 결과를 만드는 필터로 작동 할 수 있습니다.
면책 조항 :
나는 "스파이더"를 만든 나의 "청중들"에게 "소리"를 주어야합니다. ( 링크 ) 그들의 예를 들어, 문제는 내 접근 방식을 알렸다. ( 링크 ) 나는 또한 Theil-센 추정량을 사랑하고, 내가 Theil과 상원 의원에 소품을 줄 수 있으면 좋겠다
내 대답은 잘못하는 방법이 아니라 대부분 제대로 이해하면 어떻게 작동하는지에 관한 것입니다. "사소한"노이즈를 사용하는 동안 "사소하지 않은"또는 "구조화 된"노이즈에 대해 생각하고 싶습니다.
임의 포리스트의 장점 중 하나는 고차원 문제에 얼마나 잘 적용되는지입니다. 깨끗한 시각적 방법으로 20k 열 (일명 20k 공간)을 표시 할 수 없습니다. 쉬운 일이 아닙니다. 그러나 20k 차원의 문제가있는 경우 대부분의 다른 사람들이 "얼굴"에 평평하게 떨어지면 임의 포리스트가 좋은 도구가 될 수 있습니다.
랜덤 포레스트를 사용하여 신호에서 노이즈를 제거하는 예입니다.
#housekeeping
rm(list=ls())
#library
library(randomForest)
#for reproducibility
set.seed(08012015)
#basic
n <- 1:2000
r <- 0.05*n +1
th <- n*(4*pi)/max(n)
#polar to cartesian
x1=r*cos(th)
y1=r*sin(th)
#add noise
x2 <- x1+0.1*r*runif(min = -1,max = 1,n=length(n))
y2 <- y1+0.1*r*runif(min = -1,max = 1,n=length(n))
#append salt and pepper
x3 <- runif(min = min(x2),max = max(x2),n=length(n)/2)
y3 <- runif(min = min(y2),max = max(y2),n=length(n)/2)
x4 <- c(x2,x3)
y4 <- c(y2,y3)
z4 <- as.vector(matrix(1,nrow=length(x4)))
#plot class "A" derivation
plot(x1,y1,pch=18,type="l",col="Red", lwd=2)
points(x2,y2)
points(x3,y3,pch=18,col="Blue")
legend(x = 65,y=65,legend = c("true","sampled","false"),
col = c("Red","Black","Blue"),lty = c(1,-1,-1),pch=c(-1,1,18))
여기서 무슨 일이 일어나고 있는지 설명하겠습니다. 아래 이미지는 클래스 "1"에 대한 교육 데이터를 보여줍니다. 클래스 "2"는 동일한 도메인 및 범위에서 균일합니다. "1"의 "정보"는 대부분 나선형이지만 "2"의 재질로 손상되었습니다. 데이터의 33 %가 손상되면 많은 피팅 도구에서 문제가 될 수 있습니다. Theil-Sen은 약 29 %에서 저하되기 시작합니다. ( 링크 )
이제 우리는 정보가 분리되고 소음이 무엇인지에 대한 아이디어 만 갖습니다.
#Create "B" class of uniform noise
x5 <- runif(min = min(x4),max = max(x4),n=length(x4))
y5 <- runif(min = min(y4),max = max(y4),n=length(x4))
z5 <- 2*z4
#assemble data into frame
data <- data.frame(c(x4,x5),c(y4,y5),as.factor(c(z4,z5)))
names(data) <- c("x","y","z")
#train random forest - I like h2o, but this is textbook Breimann
fit.rf <- randomForest(z~.,data=data,
ntree = 1000, replace=TRUE, nodesize = 20)
data2 <- predict(fit.rf,newdata=data[data$z==1,c(1,2)],type="response")
#separate class "1" from training data
idx1a <- which(data[,3]==1)
#separate class "1" from the predicted data
idx1b <- which(data2==1)
#show the difference in classes before and after RF based filter
plot(data[idx1a,1],data[idx1a,2])
points(data[idx1b,1],data[idx1b,2],col="Red")
피팅 결과는 다음과 같습니다.
어려운 문제에 대해 적절한 방법의 강점과 약점을 동시에 보여줄 수 있기 때문에 나는 이것을 정말로 좋아합니다. 중앙 근처를 보면 필터링이 적은 방법을 볼 수 있습니다. 정보의 기하학적 규모는 작으며 임의의 포리스트에는 해당 정보가 없습니다. 클래스 2의 노드 수, 나무 수 및 샘플 밀도에 대해 말합니다. (-50, -50) 근처에 "갭"이 있으며 여러 위치에 "제트"가 있습니다. 그러나 일반적으로 필터링은 괜찮습니다.
SVM과 비교
다음은 SVM과 비교할 수있는 코드입니다.
#now to fit to svm
fit.svm <- svm(z~., data=data, kernel="radial",gamma=10,type = "C")
x5 <- seq(from=min(x2),to=max(x2),by=1)
y5 <- seq(from=min(y2),to=max(y2),by=1)
count <- 1
x6 <- numeric()
y6 <- numeric()
for (i in 1:length(x5)){
for (j in 1:length(y5)){
x6[count]<-x5[i]
y6[count]<-y5[j]
count <- count+1
}
}
data4 <- data.frame(x6,y6)
names(data4) <- c("x","y")
data4$z <- predict(fit.svm,newdata=data4)
idx4 <- which(data4$z==1,arr.ind=TRUE)
plot(data4[idx4,1],data4[idx4,2],col="Gray",pch=20)
points(data[idx1b,1],data[idx1b,2],col="Blue",pch=20)
lines(x1,y1,pch=18,col="Green", lwd=2)
grid()
legend(x = 65,y=65,
legend = c("true","from RF","From SVM"),
col = c("Green","Blue","Gray"),lty = c(1,-1,-1),pch=c(-1,20,15),pt.cex=c(1,1,2.25))
다음 이미지가 생성됩니다.
이것은 괜찮은 SVM입니다. 회색은 SVM에서 클래스 "1"과 연결된 도메인입니다. 파란색 점은 RF에 의해 클래스 "1"과 연관된 샘플입니다. RF 기반 필터는 명시 적으로 부과되지 않고 SVM과 비슷한 성능을 제공합니다. 나선의 중심 근처의 "밀착 데이터"는 RF에 의해 훨씬 더 "밀밀하게"해결됨을 알 수 있습니다. RF가 SVM과 관련이없는 것을 발견하는 "꼬리"에 대한 "섬"도 있습니다.
나는 즐겁다. 배경 지식이 없어도, 나는 현장에서 매우 훌륭한 공헌자가 한 초기 일 중 하나를 수행했습니다. 원저자는 "참조 배포"( link , link )를 사용했습니다.
편집하다:
이 모델에 랜덤 포레스트 적용 :
user777은 CART가 랜덤 포레스트의 요소라고 생각하지만 랜덤 포레스트의 전제는 "약한 학습자의 앙상블 집계"입니다. CART는 약한 학습자로 알려져 있지만 원격으로 "앙상블"에 가까운 것은 아닙니다. 랜덤 포레스트에서의 "앙상블"은 "많은 샘플의 한계"로 의도되었다. 산점도에서 user777의 대답은 최소 500 개의 샘플을 사용하며이 경우 사람의 가독성과 샘플 크기에 대해 말합니다. 인간 시각 시스템 (자신의 학습자 앙상블)은 놀라운 센서 및 데이터 프로세서이며 처리가 용이하도록 그 가치가 충분하다는 것을 알게됩니다.
임의 포리스트 도구에서 기본 설정을 사용하는 경우 처음 몇 개의 트리에서 분류 오류의 동작이 증가하는 것을 볼 수 있으며 약 10 개의 트리가 나올 때까지 한 트리 수준에 도달하지 않습니다. 초기에 오류가 커짐 오류 감소는 60 그루의 나무 주위에서 안정적이됩니다. 안정적으로 나는
x <- cbind(x1, x2)
plot(rf,type="b",ylim=c(0,0.06))
grid()
"최소 약한 학습자"를 보는 대신 도구의 기본 설정에 대해 매우 간단한 휴리스틱이 제안한 "최소 약한 앙상블"을 보면 결과가 약간 다릅니다.
"선"을 사용하여 근사치 위의 모서리를 나타내는 원을 그렸습니다. 불완전하지만 단일 학습자의 품질보다 훨씬 낫다는 것을 알 수 있습니다.
원래 샘플링에는 88 개의 "내부"샘플이 있습니다. 샘플 크기를 늘리면 (앙상블 적용 가능) 근사치 품질도 향상됩니다. 20,000 개의 샘플을 가진 동일한 수의 학습자가 놀랍도록 더 잘 맞습니다.
훨씬 높은 품질의 입력 정보를 통해 적절한 수의 나무를 평가할 수도 있습니다. 수렴을 검사하면 데이터를 잘 표현하기 위해 20 개의 나무가이 특별한 경우에 최소 수를 나타냅니다.