Почему эти модели, выпущенные в Caret, не идентичны?

Я действительно пытаюсь понять, почему два куска кода не создают одинаковые модели. Чтобы создать первую нейронную сеть (NN1), я использовал (код ниже) перекрестную проверку в train Функция пакета Caret позволяет найти лучшие параметры. На странице 2 виньетки пакета указывается, что он "подгонит итоговую модель ко всем данным обучения, используя оптимальный набор параметров".

Поэтому в приведенном ниже коде я ожидаю, что NN1 будет отражать полный тренировочный набор с лучшими параметрами, которые будут иметь размер =5 и затухание =0,1.

Мой план состоял в том, чтобы использовать параметры этого шага, чтобы создать модель для ввода в эксплуатацию с использованием комбинированных данных обучения и испытаний. Прежде чем создать эту производственную модель, я хотел убедиться, что я использую выходные данные train работает правильно.

Поэтому я создал вторую модель (NN2) с функцией поезда, но без настройки. Вместо этого я указал параметры size=5 и decay=0.1. С теми же данными, теми же параметрами (и тем же начальным числом) я ожидал идентичных моделей, но это не так. Почему эти модели не идентичны?

# Create some data
library(caret)
set.seed(2)
xy<-data.frame(Response=factor(sample(c("Y","N"),534,replace = TRUE,prob=c(0.5,0.5))),
               GradeGroup=factor(sample(c("G1","G2","G3"),534,replace=TRUE,prob=c(0.4,0.3,0.3))),
               Sibling=sample(c(TRUE,FALSE),534,replace=TRUE,prob=c(0.3,0.7)),
               Dist=rnorm(534))

xyTrain <- xy[1:360,]
xyTest <- xy[361:534,]

# Create NN1 using cross-validation
tc <- trainControl(method="cv", number = 10, savePredictions = TRUE, classProbs = TRUE)
set.seed(2)
NN1 <- train(Response~.,data=xyTrain,
             method="nnet",
             trControl=tc,
             verbose=FALSE,
             metric="Accuracy")

# Create NN2 using parameters from NN1
fitControl <- trainControl(method="none", classProbs = TRUE)
set.seed(2)
NN2 <- train(Response~.,data=xyTrain,
             method="nnet",
             trControl=fitControl,
             verbose=FALSE,
             tuneGrid=data.frame(size=NN1$bestTune[[1]],decay=NN1$bestTune[[2]]),
             metric="Accuracy")

Вот результаты

> # Parameters of NN1
> NN1$bestTune
  size decay
1    1     0
> 
> # Code to show results of NN1 and NN2 differ
> testFitted <- data.frame(fitNN1=NN1$finalModel$fitted.values,
+                          fitNN2=NN2$finalModel$fitted.values)
> 
> testPred<-data.frame(predNN1=predict(NN1,xyTest,type="prob")$Y,
+                      predNN2=predict(NN2,xyTest,type="prob")$Y)
> # Fitted values are different
> head(testFitted)
      fitNN1    fitNN2
X1 0.4824096 0.4834579
X2 0.4673498 0.4705441
X3 0.4509407 0.4498603
X4 0.4510129 0.4498710
X5 0.4690963 0.4753655
X6 0.4509160 0.4498539
> # Predictions on test set are different
> head(testPred)
    predNN1   predNN2
1 0.4763952 0.4784981
2 0.4509160 0.4498539
3 0.5281298 0.5276355
4 0.4512930 0.4498993
5 0.4741959 0.4804776
6 0.4509335 0.4498589
> 
> # Accuracy of predictions are different
> sum(predict(NN1,xyTest,type="raw")==xyTest$Response)/nrow(xyTest)
[1] 0.4655172
> sum(predict(NN2,xyTest,type="raw")==xyTest$Response)/nrow(xyTest)
[1] 0.4597701
> 
> # Summary of models
> summary(NN1)
a 4-1-1 network with 7 weights
options were - entropy fitting 
 b->h1 i1->h1 i2->h1 i3->h1 i4->h1 
 -8.38   6.58   5.51  -9.50   1.06 
 b->o h1->o 
-0.20  1.39 
> summary(NN2)
a 4-1-1 network with 7 weights
options were - entropy fitting 
 b->h1 i1->h1 i2->h1 i3->h1 i4->h1 
 10.94  -8.27  -7.36   8.50  -0.76 
 b->o h1->o 
 3.15 -3.35 

1 ответ

Я считаю, что это связано со случайным семенем. Когда вы делаете перекрестную проверку, вы подходите многим моделям из этого начального семени (set.seed(2)). Конечная модель соответствует тем же параметрам, но начальное значение того, что итоговая модель соответствовала внутри перекрестной проверки, не совпадает с тем, когда вы пытаетесь просто согласовать эту конечную модель с этими параметрами самостоятельно. Вы видите это здесь, потому что веса в каждом вызове нейронной сети (nnet) генерируются случайным образом каждый раз.

Другие вопросы по тегам