Estou um pouco confuso: como os resultados de um modelo treinado via sinal de intercalação diferem do modelo na embalagem original? Eu li se o pré-processamento é necessário antes da previsão usando o FinalModel do RandomForest com pacote de interpolação? mas eu não uso nenhum pré-processamento aqui.
Treinei diferentes florestas aleatórias usando o pacote de acento circunflexo e ajustando-me para diferentes valores de manejo.
> 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
Eu achei mtry = 15 o melhor parâmetro no 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.
Avaliei o modelo com uma curva ROC e uma matriz de confusão:
##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")
A matriz de confusão e precisão resultantes:
Confusion Matrix and Statistics
Reference
Prediction No Yes
No 2757 693
Yes 375 6684
Accuracy : 0.8984
....
Agora eu treinei um Random Rorest com os mesmos parâmetros e os mesmos training_data usando o pacote randomForest básico:
randomForestManual <- randomForest(case_success ~ ., data=train_data, mtry = 15, ntree=500,keep.forest=TRUE)
curClassifier = randomForestManual
Novamente, criei previsões para os mesmos dados_de_teste como acima e avaliei a matriz de confusão com o mesmo código acima. Mas agora eu tenho medidas diferentes:
Confusion Matrix and Statistics
Reference
Prediction No Yes
No 2702 897
Yes 430 6480
Accuracy : 0.8737
....
Qual é a razão? o que estou perdendo?
seeds
argumento detrainControl
Respostas:
Penso que a questão, embora um tanto trivial e "programática", à primeira leitura, aborda duas questões principais muito importantes na estatística moderna:
A razão para os diferentes resultados é que os dois procedimentos são treinados usando sementes aleatórias diferentes. Floresta aleatória utiliza um subconjunto aleatório de variáveis do full-conjunto de dados como candidatos em cada divisão (que é o
mtry
argumento e refere-se ao método de subespaço aleatório ), bem como sacos (agregados de bootstrap) o conjunto de dados original para diminuir a variância do modelo. Esses dois procedimentos internos de amostragem aleatória considerados não são determinísticos entre diferentes execuções do algoritmo. A ordem aleatória em que a amostragem é feita é controlada pelas sementes aleatórias utilizadas. Se as mesmas sementes fossem usadas, obteríamos exatamente os mesmos resultados nos dois casos em que arandomForest
rotina é chamada; tanto internamente emcaret::train
bem como externamente ao ajustar manualmente uma floresta aleatória. Anexo um trecho de código simples para mostrar isso. Observe que eu uso um número muito pequeno de árvores (argumento:)ntree
para continuar treinando rapidamente, geralmente deve ser muito maior.Nesse ponto, tanto o
caret.train
objetofitRFcaret
quanto orandomForest
objeto definido manualmentefitRFmanual
foram treinados usando os mesmos dados, mas o mais importante, usando as mesmas sementes aleatórias ao ajustar seu modelo final. Como tal, quando tentarmos prever o uso desses objetos e como não fazemos pré-processamento de nossos dados , obteremos as mesmas respostas exatas.Apenas para esclarecer isso, aponte um pouco mais adiante:
predict(xx$finalModel, testData)
epredict(xx, testData)
será diferente se você definir apreProcess
opção ao usartrain
. Por outro lado, ao usarfinalModel
diretamente, é equivalente usar apredict
função do modelo montado (predict.randomForest
aqui) em vez depredict.train
; nenhuma pré-avaliação ocorre. Obviamente, no cenário descrito na pergunta original, onde nenhum pré-processamento é realizado, os resultados serão os mesmos ao usar o objetofinalModel
ajustado manualmenterandomForest
ou ocaret.train
objeto.Eu sugiro fortemente que você sempre defina a semente aleatória usada por R, MATLAB ou qualquer outro programa usado. Caso contrário, você não poderá verificar a reprodutibilidade dos resultados (o que é bom, pode não ser o fim do mundo) nem excluir um bug ou fator externo que afeta o desempenho de um procedimento de modelagem (o que sim, é meio ruim). Muitos dos principais algoritmos de ML (por exemplo, aumento de gradiente, florestas aleatórias, redes neurais extremas) empregam certos procedimentos internos de reamostragem durante suas fases de treinamento, definindo os estados aleatórios de sementes antes (ou às vezes até dentro) de sua fase de treinamento pode ser importante.
fonte
train
para que seja exatamente equivalente arandomForest
? Eu tentei,method="none"
mas não sei como definir a semente para o valor único. Obrigado.preProcess
ou como elerandomForest
é treinado para começar. Em geral, assumindo que não temos etapas de pré-processamento, precisamos garantir que a semente e os hiperparâmetros (aqui apenasmtry
) usados sejam os mesmos.As previsões de
curClassifier
não são iguais às previsões docurClassifier$finalModel
link . Você reproduziufinalModel
e está comparando com opredict.train
objeto.fonte
predict
devem (e realmente) dão as mesmas previsões no caso em que o OP explora. Esclareço esse ponto um pouco mais no meu post.