caret와 기본 randomForest 패키지를 통한 randomForest의 다른 결과


14

약간 혼란 스러워요 : 캐럿을 통한 훈련 된 모델의 결과는 원래 패키지의 모델과 어떻게 다를 수 있습니까? 캐럿 패키지와 함께 RandomForest의 FinalModel을 사용하여 예측 전에 사전 처리가 필요한지 여부를 읽습니다 .그러나 나는 여기서 전처리를 사용하지 않습니다.

캐럿 패키지를 사용하고 다른 mtry 값을 조정하여 다른 임의의 포리스트를 학습했습니다.

> cvCtrl = trainControl(method = "repeatedcv",number = 10, repeats = 3, classProbs = TRUE, summaryFunction = twoClassSummary)
> newGrid = expand.grid(mtry = c(2,4,8,15))
> classifierRandomForest = train(case_success ~ ., data = train_data, trControl = cvCtrl, method = "rf", metric="ROC", tuneGrid = newGrid)
> curClassifier = classifierRandomForest

mtry = 15가 training_data에서 가장 좋은 매개 변수라는 것을 알았습니다.

> curClassifier
 ...
Resampling results across tuning parameters:

mtry  ROC    Sens   Spec   ROC SD   Sens SD  Spec SD
 4    0.950  0.768  0.957  0.00413  0.0170   0.00285
 5    0.951  0.778  0.957  0.00364  0.0148   0.00306
 8    0.953  0.792  0.956  0.00395  0.0152   0.00389
10    0.954  0.797  0.955  0.00384  0.0146   0.00369
15    0.956  0.803  0.951  0.00369  0.0155   0.00472

ROC was used to select the optimal model using  the largest value.
The final value used for the model was mtry = 15. 

ROC 곡선과 혼동 행렬로 모델을 평가했습니다.

##ROC-Curve
predRoc = predict(curClassifier, test_data, type = "prob")
myroc = pROC::roc(test_data$case_success, as.vector(predRoc[,2]))
plot(myroc, print.thres = "best")

##adjust optimal cut-off threshold for class probabilities
threshold = coords(myroc,x="best",best.method = "closest.topleft")[[1]] #get optimal cutoff threshold
predCut = factor( ifelse(predRoc[, "Yes"] > threshold, "Yes", "No") )


##Confusion Matrix (Accuracy, Spec, Sens etc.)
curConfusionMatrix = confusionMatrix(predCut, test_data$case_success, positive = "Yes")

결과 혼동 매트릭스 및 정확도 :

Confusion Matrix and Statistics
      Reference
Prediction   No  Yes
   No  2757  693
   Yes  375 6684

           Accuracy : 0.8984
 ....

이제 기본 randomForest 패키지를 사용하여 동일한 매개 변수와 동일한 training_data로 Random Rorest를 훈련했습니다.

randomForestManual <- randomForest(case_success ~ ., data=train_data, mtry = 15, ntree=500,keep.forest=TRUE)
curClassifier = randomForestManual

다시 위에서와 동일한 test_data에 대한 예측을 작성하고 위와 동일한 코드로 혼동 행렬을 평가했습니다. 그러나 이제는 다른 조치를 취했습니다.

Confusion Matrix and Statistics

      Reference
Prediction   No  Yes
       No  2702  897
       Yes  430 6480

           Accuracy : 0.8737 
           ....

이유가 무엇입니까? 내가 무엇을 놓치고 있습니까?


3
두 모델의 랜덤 시드에 대해 동일한 값을 사용 했습니까?
mmmmmmmmmm

나도 그렇게 생각해. 데이터 세트를 훈련 및 테스트 데이터로 분할 할 때 코드에서 초기에 시드를 설정 한 다음 캐럿 모델을 훈련시킨 다음 "원본"rf- 모델을 훈련했습니다. 따라서 씨앗은 처음에 설정 한 후에 동일하게 유지되어야합니다.
Malte

"original"rf-model을 교육하기 전에 다른 set.seed를 직접 삽입하려고했습니다. 불행히도 문제를 해결하지 못합니다.
Malte

3
seedstrainControl
topepo

답변:


4

나는 처음에 읽었을 때 다소 사소하고 "프로그래밍"하면서이 문제가 현대 통계에서 매우 중요한 두 가지 주요 이슈에 영향을 미친다고 생각합니다.

  1. 결과의 재현성
  2. 비 결정적 알고리즘.

다른 결과의 이유는 두 가지 절차가 다른 임의의 시드를 사용하여 훈련 되었기 때문입니다. 랜덤 포레스트는 모델의 분산을 줄이기 위해 원래 데이터 세트를 (부트 스트랩 집계) 할 뿐만 아니라 각 분할 ( mtry인수 및 랜덤 서브 스페이스 방법 과 관련) 의 후보로 전체 데이터 세트 변수 의 랜덤 서브 세트를 사용합니다. 이 두 가지의 랜덤 랜덤 샘플링 절차는 알고리즘의 서로 다른 실행간에 결정적이지 않다고 생각했습니다. 샘플링이 수행되는 임의의 순서는 사용 된 임의의 시드에 의해 제어됩니다. 동일한 시드가 사용 된 경우 루틴이 호출 되는 두 경우 모두 동일한 결과를 얻습니다 . 내부적으로randomForestcaret::train랜덤 포레스트를 수동으로 장착 할 때 외부 적으로도 이것을 보여주기 위해 간단한 코드 스 니펫을 첨부합니다. ntree훈련 속도를 높이기 위해 아주 적은 수의 나무 (인수 :)를 사용한다는 점에 유의하십시오 . 일반적으로 훨씬 더 커야합니다.

library(caret)

set.seed(321)
trainData <- twoClassSim(5000, linearVars = 3, noiseVars = 9)
testData  <- twoClassSim(5000, linearVars = 3, noiseVars = 9)

set.seed(432)
mySeeds <- sapply(simplify = FALSE, 1:26, function(u) sample(10^4, 3))
cvCtrl = trainControl(method = "repeatedcv", number = 5, repeats = 5, 
                      classProbs = TRUE, summaryFunction = twoClassSummary, 
                      seeds = mySeeds)

fitRFcaret = train(Class ~ ., data = trainData, trControl = cvCtrl, 
                   ntree = 33, method = "rf", metric="ROC")

set.seed( unlist(tail(mySeeds,1))[1])
fitRFmanual <- randomForest(Class ~ ., data=trainData, 
                            mtry = fitRFcaret$bestTune$mtry, ntree=33) 

이 시점에서 caret.train개체 fitRFcaret와 수동으로 정의 된 randomForest개체 모두fitRFmanual 는 모두 동일한 데이터를 사용하여 훈련되었지만 최종 모델을 피팅 할 때 동일한 랜덤 시드를 사용하는 것이 중요합니다. 따라서 이러한 객체를 사용하여 예측하려고 할 때 데이터의 전처리가 없으므로 동일한 정확한 답변을 얻을 수 있습니다.

all.equal(current =  as.vector(predict(fitRFcaret, testData)), 
          target = as.vector(predict(fitRFmanual, testData)))
# TRUE

그냥이 나중에 조금 더 포인트 명확히 : predict(xx$finalModel, testData)predict(xx, testData)하나 개의 설정합니다 경우 다를 수 있습니다 preProcess사용하는 옵션을 때 train. 반면에 finalModel직접 사용하는 경우 대신 predict장착 된 모델 ( predict.randomForest여기) 의 기능을 사용하는 것과 동일합니다 predict.train. 사전 협의는 이루어지지 않습니다. 사전 처리가 수행되지 않은 원래 질문에 요약 된 시나리오에서 분명히 결과는finalModel , 수동으로 장착 된 randomForest객체 또는 객체를caret.train 합니다.

all.equal(current =  as.vector(predict(fitRFcaret$finalModel, testData)), 
          target = as.vector(predict(fitRFmanual, testData)))
 # TRUE

all.equal(current =  as.vector(predict(fitRFcaret$finalModel, testData)),
          target = as.vector(predict(fitRFcaret, testData)))
# TRUE

항상 R, MATLAB 또는 다른 프로그램에서 사용하는 임의의 시드를 설정 하는 것이 좋습니다 . 그렇지 않으면 결과의 재현성을 확인할 수 없으며 (괜찮아도 세계의 끝이 아닐 수도 있음) 모델링 절차의 성능에 영향을 미치는 버그 또는 외부 요인을 배제 할 수 없습니다 (그렇습니다. 많은 주요 ML 알고리즘 (예 : 그라디언트 부스팅, 랜덤 포레스트, 극한 신경망)은 훈련 단계에서 특정 내부 리샘플링 절차를 사용하므로 훈련 단계 이전 (또는 때로는 내부)에 무작위 시드 상태를 설정하는 것이 중요 할 수 있습니다.


중요한 부분은 "seeeds"인수를 사용하여 "trainControl"에 seed 인수를 명시 적으로 설정하는 것이 었습니다.
Malte

물론입니다. 왜 이것이 필요한지에 대한 문제가 완전히 명확 해지기를 원했습니다.
usεr11852는 Reinstate Monic

어떻게 실행합니까 train는 정확하게 동등하다는 그래서 randomForest? method="none"시드를 단일 값으로 설정하는 방법을 시도 했지만 확실하지 않습니다. 감사.
Simon Woodward

사과하지만 당신이 시작하기 위해 훈련 된 preProcess방법이 있는지 확실하지 않습니다 randomForest. 일반적으로 전처리 단계가 없다고 가정 할 때 사용 된 시드 하이퍼 파라미터 (여기서는 mtry)가 동일해야합니다.
usεr11852는 Reinstate Monic이

0

의 예측은 링크의curClassifier 예측과 다릅니다 . 를 재현 하여 객체 와 비교하고 있습니다.curClassifier$finalModel finalModelpredict.train


1
당신이 말하는 것은 사실이지만, 불행히도 OP에 의해 사전 처리가 수행되지 않기 때문에 현재 설정에서 약간 오도됩니다. 둘 다 predict해야한다 (실제로 않는) 경우 같은 예측에게 영업 탐구를 제공합니다. 내 게시물 에서이 점을 좀 더 명확하게 설명합니다.
usεr11852는 Reinstate Monic
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.