web-dev-qa-db-fra.com

r erreur de forêt aléatoire - le type de prédicteur dans les nouvelles données ne correspond pas

J'essaie d'utiliser la fonction de forêt de régression quantile dans R ( quantregForest ) qui est construite sur le paquet Random Forest. Je reçois une erreur d'incompatibilité de type que je ne peux pas comprendre pourquoi.

Je forme le modèle en utilisant

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

qui fonctionne sans problème, mais quand j'essaie de tester avec de nouvelles données comme

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

cela donne l'erreur suivante:

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

Mes données de formation et de test proviennent de fichiers séparés (donc de trames de données distinctes) mais ayant le même format. J'ai vérifié les classes des prédicteurs avec

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

Voici la sortie:

> 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" 

Ils sont exactement les mêmes. J'ai également vérifié les valeurs "NA". Ni xtrain ni xtest n'a de valeur NA. Est-ce que je manque quelque chose de trivial ici?

Mise à jour I: l'exécution de la prédiction sur les données d'apprentissage génère toujours la même erreur

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

Mise à jour II: J'ai combiné mes ensembles de formation et de test pour que les lignes de 1 à 101 soient les données de formation et le reste, les tests. J'ai modifié l'exemple fourni dans ( quantregForest ) en tant que:

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)

Et il fonctionne! J'apprécierais que quelqu'un puisse expliquer pourquoi cela fonctionne de cette façon et non de l'autre.

22
Gizem

J'ai eu le même problème. Vous pouvez essayer d’utiliser une petite astuce pour égaliser les classes d’entraînement et de test. Liez la première ligne d’entraînement au jeu d’essai et supprimez-le. Pour votre exemple, cela devrait ressembler à ceci:

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

@mgoldwasser a raison en général, mais il y a aussi un très mauvais bogue dans predict.randomForest: même si vous avez exactement les mêmes niveaux dans la formation et dans l'ensemble de prédiction, il est possible d'obtenir cette erreur. Cela est possible lorsque vous avez un facteur dans lequel vous avez incorporé NA en tant que niveau séparé. Le problème est que predict.randomForest fait essentiellement ce qui suit:

# Assume your original factor has two "proper" levels + NA level:
f <- factor(c(0,1,NA), exclude=NULL)

length(levels(f)) # => 3
levels(f)         # => "0" "1" NA

# Note that
sum(is.na(f))     # => 0
# i.e., the values of the factor are not `NA` only the corresponding level is.

# Internally predict.randomForest passes the factor (the one of the training set)
# through the function `factor(.)`.
# Unfortunately, it does _not_ do this for the prediction set.
# See what happens to f if we do that:
pf <- factor(f)

length(levels(pf)) # => 2
levels(pf)         # => "0" "1"

# In other words:
length(levels(f)) != length(levels(factor(f))) 
# => sad but TRUE

Ainsi, il écartera toujours le niveau NA de l'ensemble d'apprentissage et verra toujours un niveau supplémentaire dans l'ensemble de prédiction.

Une solution de contournement consiste à remplacer la valeur NA du niveau avant d'utiliser randomForest:

levels(f)[is.na(levels(f))] <- "NA"
levels(f) # => "0"  "1"  "NA"
          #              .... note that this is no longer a plain `NA`

Appeler maintenant factor(f) ne supprimera pas le niveau et la vérification aboutira.

16
bluenote10

Cela se produit parce que vos variables factorielles dans les ensembles de formation et de test ont différents niveaux (pour être plus précis, l'ensemble de tests n'a pas certains des niveaux présents dans la formation). Vous pouvez donc résoudre ce problème, par exemple, en utilisant le code ci-dessous pour toutes vos variables factorielles.

levels(test$SectionName) <- levels(train$SectionName)
14
Rohit Kumar Singh

Étendre la solution de @ 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

Ceci est un problème avec les niveaux de chacun des différents facteurs. Vous devez vérifier que vos niveaux de facteurs restent cohérents entre vos tests et vos formations.

C'est une bizarrerie bizarre de forêt aléatoire, et cela n'a aucun sens pour moi.

2
mgoldwasser

Je viens de résoudre ce qui suit:

## 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