2017-02-21 3 views
0

2つのコードが同じモデルを生成しない理由を理解しようとしています。最初のニューラルネットワーク(NN1)を作成するために、私はCaretパッケージのtrain関数でクロスバリデーションを使用して、最良のパラメータを見つけました。 package's vignetteの2ページは、「最適なパラメータセットを使用してすべてのトレーニングデータに最終モデルをフィットさせる」ことを示唆しています。キャレットで生産されるこれらのモデルはなぜ同じではありませんか?

したがって、以下のコードでは、NN1が、サイズ= 5および減衰= 0.1の最良のパラメータを備えた完全なトレーニングセットを反映することを期待しています。

私は、このステップのパラメータを使用して、組み合わせたトレーニングデータとテストデータを使用して生産に投入するモデルを作成することを計画していました。この生産モデルを作成する前に、trainの出力を正しく使用していることを確認したかったのです。

私は列車機能付きの2番目のモデル(NN2)を作成しましたが、without tuningです。代わりに、パラメータ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)の重みが毎回ランダムに生成されるため、ここに表示されます。

+0

これは意味があります。 nnetパッケージの 'Wts'パラメータは初期パラメータベクトルです。行方不明の場合はランダムに選択されます。 キャレットからシードをnnet関数に設定する方法はありますか?私はニューラルネットワークの専門家ではなく、最初の重み(どのくらいの数の範囲、どのような値の範囲)を指定するかについてほとんど考えていません。この[post](http://stackoverflow.com/questions/13773275/specifying-initial-weights-for-nnet-in-r-programming-neural-network)はアイデアを提供するようです。おそらく、私はCaret経由でいくつかの最初の重みをnnetに渡すことができます。 – rmacey

+0

'Wts'パラメータを' train'関数に直接渡すことができると思います。しかし、私は常に同じウェイトを使用することに注意します。私は何が起こっているのか自分自身に証明するためにこれを行うだけです。 – cdeterman

関連する問題