web-dev-qa-db-ja.com

式を使用してキャレットのtrain()でトレーニングされたrandomForestオブジェクトでpredict()を使用するとエラーが発生します

64ビットLinuxマシンでキャレット6.0-41およびrandomForest4.6-10とともにR3.2.0を使用する。

数式を使用してrandomForestパッケージのpredict()関数でトレーニングされたcaretオブジェクトでtrain()メソッドを使用しようとすると、関数はエラー。数式ではなくrandomForest()を介して、および/またはx=y=を使用してトレーニングする場合、すべてがスムーズに実行されます。

これが実際の例です:

library(randomForest)
library(caret)

data(imports85)
imp85     <- imports85[, c("stroke", "price", "fuelType", "numOfDoors")]
imp85     <- imp85[complete.cases(imp85), ]
imp85[]   <- lapply(imp85, function(x) if (is.factor(x)) x[,drop=TRUE] else x) ## Drop empty levels for factors.

modRf1  <- randomForest(numOfDoors~., data=imp85)
caretRf <- train( numOfDoors~., data=imp85, method = "rf" )
modRf2  <- caretRf$finalModel
modRf3  <- randomForest(x=imp85[,c("stroke", "price", "fuelType")], y=imp85[, "numOfDoors"])
caretRf <- train(x=imp85[,c("stroke", "price", "fuelType")], y=imp85[, "numOfDoors"], method = "rf")
modRf4  <- caretRf$finalModel

p1      <- predict(modRf1, newdata=imp85)
p2      <- predict(modRf2, newdata=imp85)
p3      <- predict(modRf3, newdata=imp85)
p4      <- predict(modRf4, newdata=imp85)

最後の4行のうち、2番目の行p2 <- predict(modRf2, newdata=imp85)のみが次のエラーを返します。

Error in predict.randomForest(modRf2, newdata = imp85) : 
variables in the training data missing in newdata

このエラーの理由は、predict.randomForestメソッドがrownames(object$importance)を使用して、ランダムフォレストobjectのトレーニングに使用される変数の名前を決定しているためと思われます。そして見るとき

rownames(modRf1$importance)
rownames(modRf2$importance)
rownames(modRf3$importance)
rownames(modRf4$importance)

私たちは見る:

[1] "stroke"   "price"    "fuelType"
[1] "stroke"   "price"    "fuelTypegas"
[1] "stroke"   "price"    "fuelType"
[1] "stroke"   "price"    "fuelType"

したがって、どういうわけか、数式でcarettrain()関数を使用すると、importanceオブジェクトのrandomForestフィールドの(factor)変数の名前が変更されます。 。

それは本当にキャレットtrain()関数の数式バージョンと非数式バージョンの間の矛盾ですか?それとも私は何かが足りないのですか?

10
Adrien Combaz

まず、ほとんどありません予測に_$finalModel_オブジェクトを使用します。 _predict.train_を使用します。これはその理由の良い例の1つです。

一部の関数(randomForesttrainを含む)がダミー変数を処理する方法には、いくつかの矛盾があります。数式メソッドを使用するRのほとんどの関数は、モデルがデータの数値表現を必要とするため、因子予測子をダミー変数に変換します。これに対する例外は、ツリーベースおよびルールベースのモデル(カテゴリカル予測子で分割できる)、単純ベイズ、およびその他のいくつかです。

したがって、randomForest(y ~ ., data = dat)を使用すると、randomForestnotダミー変数を作成しますが、train(およびほとんどその他)train(y ~ ., data = dat)のような呼び出しを使用します。

fuelTypeが要因であるため、エラーが発生します。 trainによって作成されたダミー変数は同じ名前を持っていないため、_predict.randomForest_はそれらを見つけることができません。

trainで非公式メソッドを使用すると、因子予測子がrandomForestに渡され、すべてが機能します。

TL; DR

同じレベルが必要な場合は、trainで非数式メソッドを使用しますまたは _predict.train_を使用します

マックス

28
topepo

これはあなたの質問に対する答えではありませんが、私を助けてくれたので、他の人にも役立つと思います。トレーニングデータの列で使用されたテストデータの列に欠落しているNAがある場合、予測は機能しません。最初にこれらの値を代入する必要があります。

0
Corey Levinson

別の方法は、model.matrixを使用してテストデータを明示的にコーディングすることです。

p2 <- predict(modRf2, newdata=model.matrix(~., imp85))
0
WeimusT

このエラーが発生する理由は2つあります。

1。トレインセットとテストセットのカテゴリ変数のカテゴリが一致しません。これを確認するには、次のようなものを実行できます。

さて、まず第一に、独立変数/特徴をリストに保持することは良い習慣です。そのリストが「vars」であると言います。そして、あなたは「データ」を「トレーニング」と「テスト」に分けたとしましょう。行こう:

for (v in vars){
  if (class(Data[,v]) == 'factor'){
    print(v)
    # print(levels(Train[,v])) 
    # print(levels(Test[,v]))
    print(all.equal(levels(Train[,v]) , levels(Test[,v])))
  }  
}

一致しないカテゴリ変数を見つけたら、戻ってテストデータのカテゴリをトレインデータに課し、モデルを再構築できます。上記と同様のループで、nonMatchingVarごとに次のことができます。

levels(Test$nonMatchingVar) <- levels(Train$nonMatchingVar)

2。ばかげたもの。従属変数を誤って独立変数のセットに残してしまうと、このエラーメッセージが表示される場合があります。私はその間違いをしました。解決策:もっと注意してください。

0
FatihAkici