Soru R rasgele orman hatası - yeni verilerdeki yordayıcıların türü eşleşmiyor


R'de kuantum regresyon ormanı fonksiyonunu kullanmaya çalışıyorum.quantregForest) Random Forest paketi üzerine inşa edilmiştir. Nedenini tam olarak anlayamadığım bir tür uyumsuzluğu hatası alıyorum.

Modeli kullanarak eğitiyorum

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

sorun olmadan çalışır, ancak yeni verilerle test etmeye çalıştığımda

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

aşağıdaki hatayı verir:

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

Eğitim ve test verilerim ayrı dosyalardan (dolayısıyla ayrı veri karelerinden) geliyor ancak aynı formatta. İle yordayıcıların sınıflarını kontrol ettim

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

İşte çıktı:

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

Onlar tamamen aynı. Ayrıca "NA" değerlerini kontrol ettim. Ne xtrain ne de xtest'in içinde NA değeri yoktur. Burada önemsiz bir şey eksik miyim?

Güncelleştirme I: eğitim verilerinin tahminini yürütmek hala aynı hatayı verir

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

Güncelleme II: Eğitim ve test setlerimi birleştirdim, böylece 1'den 101'e kadar olan satırlar eğitim verisi ve geri kalanı testtir. Sağlanan örneği değiştirdim (quantregForest) gibi:

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)

Ve çalışıyor! Kimsenin neden bu şekilde çalıştığını ve başka yollarla olmadığını açıklayabilir miyiz?


19
2017-07-18 16:19


Menşei


İki sahip olmak pred1 Farklı türlere sahip değerler harika bir fikir gibi görünmüyor. Belki de 'pred1.factor' olarak adlandırılacak faktörü değiştirebilir miyim? - Andy Clifton
İşaret ettiğin için teşekkürler. Onu değiştirdim ve özdekleri yeniden yaptım. Yine aynı hatayı hem yeni verilerle hem de xtrain ve yeni data = xtest ile elde etmek - Gizem
Az sayıda belirleyiciden başlayıp her seferinde bir tane eklerseniz ne olur? - Andy Clifton
Her iki kümedeki faktörlerin aynı seviyeleri içerip içermediğini biliyor musunuz? Örneğin, egzersiz verilerinizde T / F varsa, test verilerinizdeki ilgili sütunda hem T hem de F var mı? - Karan
@Karanın faktörleri, tahmin edicilerin en az biri için farklıdır. Ayrı bir eğitim - test verileri için neden sorun olur, ancak eğitim ve test olarak bölümlenmiş tek bir veri seti için değil? - Gizem


Cevaplar:


@mgoldwasser genel olarak haklı, ama aynı zamanda çok kötü bir böcek var predict.randomForest: Eğitimde ve tahmin setinde tam olarak aynı seviyelere sahip olsanız bile, bu hatayı almak mümkündür. Bu, gömdüğünüz bir faktörünüz olduğunda mümkündür NA ayrı bir seviye olarak. Problem şu predict.randomForest aslında aşağıdakileri yapar:

# 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

Yani, her zaman NA eğitim setindeki seviye ve tahmin setinde her zaman bir ek seviye görecektir.

Bir geçici çözüm değeri değiştirmek NA randomForest kullanmadan önce seviyenin

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

Şimdi arıyor factor(f) Seviye atılmayacak ve kontrol başarılı olacaktır.


16
2017-12-18 16:55



3 ya da öylesine günler için bir orman çalıştırdıktan sonra bu sorunu yaşadım ... gerçekten tekrar çalıştırmak istemedim: / bu düzeltmek için görünüyordu: rf$forest$xlevels$my_factor_name[myNAlevelIdx] <- "NA" - da_steve101


Bunun nedeni, antrenman setindeki ve test setindeki faktör değişkenlerinizin farklı seviyelere sahip olmasından kaynaklanmaktadır (daha hassas test setinin, eğitimde mevcut olan seviyelerden bazıları yoktur). Yani bunu örneğin aşağıdakileri kullanarak çözebilirsiniz:

seviyeleri (test $ SectionName) <- seviyeleri ($ SectionName'i eğitin)

tüm faktör değişkenleriniz için.


14
2018-06-21 15:04



Çözümü genişletmek için: common <- intersect(names(train), names(test))     için (p ortak) {if (sınıf (tren [[p]]) == "factor") {seviyeleri (test [[p]]) <- seviyeleri (tren [[p]])}} - James Hirschorn
@JamesHirschorn Müthiş! - Isilmë O.
Önerilerinizi deniyorum: kodumdaki (test $ SectionName) seviyeleri (test $ SectionName) kodumda 342k satır ve testte 32k satır var, ama RStudio'm (32bit) yarım saatten fazla tepki göstermedi. Çalışıp çalışmadığını nasıl bilebilirim? RStudio (tekrar) sonlandırmak istemiyorum. - Jan Luba
@JamesHirschorn, yorumunuzu yanıt olarak eklemenizi öneriyorum, bu yüzden benim gibi insanlar bunu daha kolay bulabilir. Sorunumu çözdü! Teşekkürler! - Eduardo
@Eduaro İyi fikir :) Bitti! - James Hirschorn


Bende aynı problem vardı. Eğitim sınıflarını ve test setini eşitlemek için küçük bir hile kullanmayı deneyebilirsiniz. İlk set eğitim setini test setine bağlayın ve silin. Örneğiniz için şöyle görünmelidir:

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

13
2018-06-29 10:47



Bu cevap hile yapar ve kabul edilmeli. - Eduardo Barbaro
Bu gerçekten tamir ediyor, her türlü tuhaf eşi karmaşık döngüler / uygulanabilir / kontrol ettim ve bu sadece gg düzeltiyor - CapnShanty


@ User1849895’in çözümünü genişletme:

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

11
2018-03-23 05:13



Güzel bir çözüm - Rohit Haritash


Bu, farklı faktörlerin her birinin seviyeleri ile ilgili bir sorundur. Test seviyelerinizin test ve antrenman setlerinizde tutarlı kaldığından emin olmak için kontrol etmeniz gerekir.

Bu, rastgele bir ormanın tuhaf tuhafı ve benim için mantıklı değil.


2
2017-09-30 17:55





Sadece aşağıdakileri yaparak çözdüm:

## 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
2018-02-12 19:14