Zufällige Gesamtstruktur: Wie gehe ich mit neuen Faktorstufen im Testsatz um?

13

Ich versuche Vorhersagen mit einem zufälligen Waldmodell in R zu machen.

Ich erhalte jedoch Fehler, da einige Faktoren im Testsatz andere Werte haben als im Trainingssatz. Beispielsweise hat ein Faktor Cat_2Werte34, 68, 76 usw. in der Testmenge, die nicht in der Trainingsmenge erscheinen. Leider habe ich keine Kontrolle über das Test-Set ... Ich muss es so verwenden, wie es ist.

Meine einzige Problemumgehung bestand darin, die problematischen Faktoren mithilfe von wieder in numerische Werte umzuwandeln as.numeric(). Es funktioniert, aber ich bin nicht sehr zufrieden, da diese Werte Codes sind, die keinen numerischen Sinn haben ...

Glauben Sie, es gäbe eine andere Lösung, um die neuen Werte aus dem Test-Set zu entfernen? Aber ohne alle anderen Faktorwerte (z. B. Werte 1, 2, 14, 32usw.) zu entfernen , die sich sowohl im Training als auch im Test befinden und Informationen enthalten, die möglicherweise für Vorhersagen nützlich sind.

Benoit_Plante
quelle
1
Ich sehe weis warum Werte im Test im Trainingsset sein müssten. Die Idee der Klassifizierung besteht darin, anhand der Trainingsdaten eine Vorstellung davon zu bekommen, wie die klassenbedingten Dichten aussehen. Sie sehen nicht jeden möglichen Wert aus der Dichte. Wenn eine Variable in einem geteilten Baum verwendet wird, bestimmt der geteilte Baum, welcher Zweig für nicht sichtbare Werte sowie für diejenigen, die gesehen wurden, zu folgen ist.
Michael R. Chernick
Sie machen einen gültigen Punkt, aber auf praktischer Ebene ist dies unter Verwendung des speziellen angefragten Werkzeugs (des RF-Pakets in R) nicht zulässig. Meine Antwort in Bezug auf die Imputation ist eine Umgehung, aber sicherlich nicht die beste Lösung. Is bringt den Code zumindest nicht zum Absturz, funktioniert also zumindest für kleine Arbeitswerte.
Bogdanovist
Ähnlich meiner Frage hier: stats.stackexchange.com/questions/18004/… . Ich denke, ich könnte GBM anstelle von RF verwenden, da es mit neuen Faktorstufen besser umzugehen scheint. Haben Sie sich auch die Implementierung von RF in Party angesehen? Ich mochte randomForest wegen dieser Probleme nie (und der Unfähigkeit, mit fehlenden Werten nahtlos umzugehen).
B_Miner

Antworten:

2

Wenn der Testsatz viele dieser Punkte mit neuen Faktorwerten enthält, bin ich mir nicht sicher, was der beste Ansatz ist. Wenn es sich nur um eine Handvoll Punkte handelt, können Sie mit etwas Unsinnigem davonkommen, wie die fehlerhaften Faktorstufen als fehlende Daten zu behandeln und sie mit jedem Ansatz zu belegen, den Sie für richtig halten. Die R-Implementierung bietet mehrere Möglichkeiten, fehlende Daten zu unterstellen. Sie müssen diese Faktorstufen nur auf NA setzen, um anzuzeigen, dass sie fehlen.

Bogdanovist
quelle
8

King und Bonoit , dieses Snippet kann nützlich sein, um Level zu harmonisieren:

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]]))
    }
  }
}

Es wird auch gedruckt, welche Attribute geändert wurden. Ich fand keinen guten Weg, es eleganter zu schreiben (mit ldply oder so). Irgendwelche Tipps sind willkommen.

user41330
quelle
4

Hier ist ein Code, den ich geschrieben habe und der die Antwort von @ King oben anspricht. Es hat den Fehler behoben:

# 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])      
    }
}
lfarb
quelle
hi @ifarb, ich versuche deine lösung zu verstehen: was ist trainingDataSetSMOTEpred und wo ist es im code definiert?
Kasia Kulma
3

Test- und Trainingssatz sollten zu einem Satz zusammengefasst werden und dann die Stufen des Trainingssatzes ändern. Meine Codes sind:

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

Dies funktioniert in allen Fällen, in denen die Anzahl der Teststufen mehr oder weniger als das Training beträgt.

Cscode Li
quelle
2

Ich habe eine miserable Problemumgehung, wenn ich randomForest in R verwende. Es ist wahrscheinlich nicht theoretisch solide, aber es bringt die Sache zum Laufen.

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

oder umgekehrt. Grundsätzlich sagt es R nur, dass es ein gültiger Wert ist, nur dass es 0 Fälle gibt; Also hör auf, mich wegen des Fehlers zu nerven.

Ich bin nicht schlau genug, es so zu codieren, dass es die Aktion automatisch für alle kategorialen Features ausführt. Senden Sie mir den Code, wenn Sie wissen, wie ...

König
quelle
Dies funktioniert jedoch nicht, wenn die Anzahl der Teststufen mehr als das Training beträgt. Dies funktioniert nur, wenn die Testdatenfaktorwerte <= Trainingsdatenfaktorwerte sind.
KarthikS
1

Ich bin mir sicher, dass Sie dies bereits in Betracht gezogen hätten, wenn dies der Fall wäre, aber wenn der Testsatz tatsächliche Werte aufweist und Sie den Testsatz zu Kreuzvalidierungszwecken verwenden, dann teilen Sie den Datenrahmen erneut in Trainings- und Testdatenrahmen auf Wo die beiden auf diese Faktoren ausgewogen sind, würde Ihr Problem vermeiden. Diese Methode wird im Volksmund als geschichtete Kreuzvalidierung bezeichnet .

Goldisfine
quelle