forest - diagrama de arbol en r
r error de bosque aleatorio: el tipo de predictores en los datos nuevos no coincide (6)
Estoy tratando de usar la función de bosque de regresión cuantil en R ( quantregForest ) que se basa en el paquete de bosque aleatorio. Recibo un error de falta de coincidencia de tipo que no puedo entender por qué.
Entreno al modelo utilizando
qrf <- quantregForest(x = xtrain, y = ytrain)
que funciona sin problemas, pero cuando intento probar con nuevos datos como
quant.newdata <- predict(qrf, newdata= xtest)
Da el siguiente error:
Error in predict.quantregForest(qrf, newdata = xtest) :
Type of predictors in new data do not match types of the training data.
Mis datos de entrenamiento y prueba provienen de archivos separados (por lo tanto, marcos de datos separados) pero con el mismo formato. He comprobado las clases de los predictores con
sapply(xtrain, class)
sapply(xtest, class)
Aquí está la salida:
> 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"
Son exactamente lo mismo. También comprobé los valores de "NA". Ni xtrain ni xtest tienen un valor de NA. ¿Me estoy perdiendo algo trivial aquí?
Actualización I: ejecutar la predicción en los datos de entrenamiento sigue dando el mismo error
> quant.newdata <- predict(qrf, newdata = xtrain)
Error in predict.quantregForest(qrf, newdata = xtrain) :
names of predictor variables do not match
Actualización II: Combiné mis conjuntos de entrenamiento y prueba para que las filas de 1 a 101 sean los datos de entrenamiento y el resto sea la prueba. quantregForest el ejemplo provisto en ( quantregForest ) como:
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)
¡Y funciona! Apreciaría si alguien pudiera explicar por qué funciona de esta manera y no con la otra.
@mgoldwasser tiene razón en general, pero también hay un error muy desagradable en predict.randomForest
: Incluso si tiene exactamente los mismos niveles en el entrenamiento y en el conjunto de predicciones, es posible obtener este error. Esto es posible cuando tiene un factor en el que ha incrustado NA
como un nivel separado. El problema es que predict.randomForest
esencialmente hace lo siguiente:
# 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
Por lo tanto, siempre descartará el nivel de NA
del conjunto de entrenamiento y siempre verá un nivel adicional en el conjunto de predicción.
Una solución es reemplazar el valor NA
del nivel antes de usar randomForest:
levels(f)[is.na(levels(f))] <- "NA"
levels(f) # => "0" "1" "NA"
# .... note that this is no longer a plain `NA`
Ahora el factor(f)
llamada factor(f)
no descartará el nivel y la verificación se realizará correctamente.
Acabo de resolver haciendo lo siguiente:
## 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>
Ampliando la solución de @ user1849895:
common <- intersect(names(train), names(test))
for (p in common) {
if (class(train[[p]]) == "factor") {
levels(test[[p]]) <- levels(train[[p]])
}
}
Este es un problema con los niveles de cada uno de los diferentes factores. Debe verificar para asegurarse de que sus niveles de factor se mantengan consistentes entre su prueba y los conjuntos de entrenamiento.
Esta es una extraña peculiaridad de bosque al azar, y no tiene sentido para mí.
Esto sucede porque sus variables factoriales en el conjunto de entrenamiento y el conjunto de pruebas tienen niveles diferentes (para ser más precisos, el conjunto de pruebas no tiene algunos de los niveles presentes en el entrenamiento). Por lo tanto, puede resolver esto, por ejemplo, utilizando el código siguiente para todas sus variables de factor .:
levels(test$SectionName) <- levels(train$SectionName)
Yo tuve el mismo problema. Puede intentar usar un pequeño truco para igualar las clases de entrenamiento y conjunto de pruebas. Vincule la primera fila del conjunto de entrenamiento al conjunto de prueba y luego bórrelo. Para tu ejemplo debería verse así:
xtest <- rbind(xtrain[1, ] , xtest)
xtest <- xtest[-1,]