web-dev-qa-db-ja.com

rランダムフォレストエラー-新しいデータの予測子のタイプが一致しません

Random Forestパッケージ上に構築されたR( quantregForest )で分位点回帰フォレスト関数を使用しようとしています。型の不一致エラーが表示されますが、その理由はわかりません。

を使用してモデルをトレーニングします

qrf <- quantregForest(x = xtrain, y = ytrain)

問題なく動作しますが、次のような新しいデータでテストしようとすると

quant.newdata <- predict(qrf, newdata= xtest)

次のエラーが発生します。

Error in predict.quantregForest(qrf, newdata = xtest) : 
Type of predictors in new data do not match types of the training data.

私のトレーニングデータとテストデータは、別々のファイルから取得されているため(別々のデータフレーム)、同じ形式です。予測子のクラスをチェックしました

sapply(xtrain, class)
sapply(xtest, class)

出力は次のとおりです。

> sapply(xtrain, class)
pred1     pred2     pred3     pred4     pred5     pred6     pred7     pred8 
"factor" "integer" "integer" "integer"  "factor"  "factor" "integer"  "factor" 
pred9    pred10    pred11    pred12 
"factor"  "factor"  "factor"  "factor" 


> sapply(xtest, class)
pred1     pred2     pred3     pred4     pred5     pred6     pred7     pred8 
"factor" "integer" "integer" "integer"  "factor"  "factor" "integer"  "factor" 
pred9    pred10    pred11    pred12 
"factor"  "factor"  "factor"  "factor" 

それらはまったく同じです。 「NA」の値もチェックしました。 xtrainもxtestもNA値を持ちません。ここで些細なことを見逃していますか?

更新I:トレーニングデータで予測を実行しても同じエラーが発生する

> quant.newdata <- predict(qrf, newdata = xtrain)
Error in predict.quantregForest(qrf, newdata = xtrain) : 
names of predictor variables do not match

更新II:1〜101の行がトレーニングデータで、残りがテストになるように、トレーニングセットとテストセットを組み合わせました。 ( quantregForest )で提供されている例を次のように変更しました。

data <-  read.table("toy.txt", header = T)
n <- nrow(data)
indextrain <- 1:101
xtrain <- data[indextrain, 3:14]
xtest <- data[-indextrain, 3:14]
ytrain <- data[indextrain, 15]
ytest <- data[-indextrain, 15]

qrf <- quantregForest(x=xtrain, y=ytrain)
quant.newdata <- predict(qrf, newdata= xtest)

そしてそれは動作します!なぜこのように機能し、他の方法では機能しないのかを説明できれば幸いです?

24
Gizem

同じ問題がありました。小さなトリックを使用して、トレーニングクラスとテストセットを均等化することができます。トレーニングセットの最初の行をテストセットにバインドし、削除します。たとえば、次のようになります。

    xtest <- rbind(xtrain[1, ] , xtest)
    xtest <- xtest[-1,]
22

これは、トレーニングセットとテストセットの因子変数のレベルが異なるために発生します(より正確には、テストセットにはトレーニングに存在するレベルの一部がありません)。したがって、たとえば、すべての因子変数に以下のコードを使用することで、これを解決できます。

levels(test$SectionName) <- levels(train$SectionName)
15

@ user1849895のソリューションの拡張:

common <- intersect(names(train), names(test)) 
for (p in common) { 
  if (class(train[[p]]) == "factor") { 
    levels(test[[p]]) <- levels(train[[p]]) 
  } 
}
12
James Hirschorn

これは、さまざまな要因のそれぞれのレベルに関する問題です。テストセットとトレーニングセット間で因子レベルの一貫性が維持されていることを確認する必要があります。

これはランダムフォレストの奇妙な癖であり、私には意味がありません。

2
mgoldwasser

私はこの方法で解決しようとしましたが、うまくいきました。

rfモデル自体から直接因子レベルを取得

levels(PredictData$columnName) <- rfmodels$forest$xlevels$columnName
0
XYT

私はちょうど次のことを解決しました:

## Creating sample data
values_development=factor(c("a", "b", "c")) ## Values used when building the random forest model
values_production=factor(c("a", "b", "c", "ooops")) ## New values to used when using the model

## Deleting cases which were not present when developing
values_production=sapply(as.character(values_production), function(x) if(x %in% values_development) x else NA)

## Creating the factor variable, (with the correct NA value level)
values_production=factor(values_production)

## Checking
values_production # =>  a     b     c  <NA> 
0
pablo_sci