Foresta casuale: come gestire i nuovi livelli di fattore nel set di test?


13

Sto cercando di fare previsioni usando un modello di foresta casuale in R.

Tuttavia, ricevo errori poiché alcuni fattori hanno valori diversi nel set di test rispetto al set di training. Ad esempio, un fattore Cat_2ha valori 34, 68, 76, ecc., Nel set di test che non compaiono nel set di allenamento. Sfortunatamente, non ho il controllo sul set di test ... Devo usarlo così com'è.

La mia unica soluzione era quella di convertire i fattori problematici in valori numerici, usando as.numeric(). Esso funziona ma io non sono molto soddisfatto, dal momento che questi valori sono codici che non hanno alcun senso numerico ...

Pensi che ci sarebbe un'altra soluzione, per eliminare i nuovi valori dal set di test? Ma senza rimuovere tutti gli altri valori dei fattori (diciamo valori 1, 2, 14, 32, ecc.) Che si trovano sia in allenamento che in prova e contengono informazioni potenzialmente utili per le previsioni.


1
Vedo il motivo per cui i valori nel test dovrebbero essere nel set di addestramento. L'idea di classificazione è quella di utilizzare i dati di addestramento per avere un'idea di come siano le densità condizionate alla classe. Non puoi vedere ogni possibile valore dalla densità. Se una variabile viene utilizzata in un albero diviso, allora la divisione determina quale ramo seguire per eventuali valori invisibili e quelli che sono stati visti.
Michael R. Chernick,

Indichi un punto valido, ma a livello pratico utilizzando lo strumento specifico richiesto (il pacchetto RF in R) ciò non è consentito. La mia risposta sull'imputazione è un modo per aggirarla, sebbene certamente non sia la soluzione migliore. Almeno rende il codice non in crash, quindi almeno funziona, per piccoli valori di lavoro.
Bogdanovist,

Simile alla mia domanda qui: stats.stackexchange.com/questions/18004/… . Penso che potrei usare GBM invece di RF in quanto sembra gestire meglio i nuovi livelli di fattore. Inoltre, hai esaminato l'implementazione della RF in party? Non mi è mai piaciuto randomForest a causa di questi problemi (e incapacità di gestire senza problemi i valori mancanti).
B_Miner

Risposte:


2

Se il set di test ha molti di questi punti con nuovi valori di fattore, non sono sicuro di quale sia l'approccio migliore. Se si tratta solo di una manciata di punti, potresti essere in grado di cavartela con qualcosa di complicato come trattare i livelli di fattore erranti come dati mancanti e imputarli con qualsiasi approccio ritieni opportuno. L'implementazione R ha un paio di modi per imputare i dati mancanti, devi solo impostare questi livelli di fattore su NA per indicare che mancano.


8

King and Bonoit , questo frammento può essere utile per armonizzare i livelli:

for(attr in colnames(training))
{
  if (is.factor(training[[attr]]))
  {
    new.levels <- setdiff(levels(training[[attr]]), levels(testing[[attr]]))
    if ( length(new.levels) == 0 )
    { print(paste(attr, '- no new levels')) }
    else
    {
      print(c(paste(attr, length(new.levels), 'of new levels, e.g.'), head(new.levels, 2)))
      levels(testing[[attr]]) <- union(levels(testing[[attr]]), levels(training[[attr]]))
    }
  }
}

Stampa anche quali attributi vengono modificati. Non ho trovato un buon modo per scriverlo in modo più elegante (con ldply o qualcosa del genere). Eventuali suggerimenti sono apprezzati.


4

Ecco un codice che ho scritto che indirizza la risposta di @ King sopra. Risolto l'errore:

# loops through factors and standardizes the levels
for (f in 1:length(names(trainingDataSet))) {
    if (levels(testDataSet[,f]) > levels(trainingDataSet[,f])) {    
            levels(testDataSet[,f]) = levels(trainingDataSet[,f])       
    } else {
            levels(trainingDataSetSMOTEpred[,f]) = levels(testDataSet[,f])      
    }
}

ciao @ifarb, sto cercando di capire la tua soluzione: cos'è trainingDataSetSMOTEpred e dove è definita nel codice?
Kasia Kulma,

3

Il set di test e di allenamento deve essere combinato come un set e quindi modificare i livelli del set di allenamento. I miei codici sono:

totalData <- rbind(trainData, testData)
for (f in 1:length(names(totalData))) {
  levels(trainData[, f]) <- levels(totalData[, f])
}

Funziona in tutti i casi in cui il numero di livelli nel test è superiore o inferiore alla formazione.


2

Ho una pessima soluzione alternativa quando uso randomForest in R. Probabilmente non è teoricamente corretto, ma fa funzionare tutto.

levels(testSet$Cat_2) = levels(trainingSet$Cat_2)

O viceversa. Fondamentalmente, dà solo a R che è un valore valido solo che ci sono 0 casi; quindi smettila di infastidirmi per l'errore.

Non sono abbastanza intelligente da codificarlo in modo tale che esegua automaticamente l'azione per tutte le funzionalità categoriali. Inviami il codice se sai come ...


Ma questo non funziona se il numero di livelli nel test è superiore alla formazione. Funziona solo se i livelli del fattore dati test sono <= livelli fattore dati allenamento.
Karthik

1

Sono sicuro che avresti già pensato a questo se fosse così, ma se il set di test ha valori effettivi e stai utilizzando il set di test per scopi di convalida incrociata, quindi suddividere nuovamente il frame di dati in training e test frame di frame dove i due sono bilanciati su questi fattori eviterebbe il tuo problema. Questo metodo è popolarmente noto come validazione incrociata stratificata .

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.