2017-07-10 5 views
2

Wenn ich mit dem mlr-Paket eine Vorhersage über neue Daten treffen möchte, wie kann ich die neuen Daten so vorprozessieren, dass die Informationen aus der Vorverarbeitung der Originaldaten verwendet werden . Z.B. Wenn ich kleine Faktorstufen fusioniere und die Häufigkeiten in der neuen Datenmenge sich von denen der ersten Datenmenge unterscheiden, können sich die resultierenden Faktorstufen unterscheiden und eine Vorhersage ist nicht möglich. Hinweis: Ich gehe hier davon aus, dass zum Zeitpunkt des Trainings des Modells die neuen Daten noch nicht verfügbar sind, es geht nicht um Testdaten, sondern um Vorhersagen für neue Daten. Wie also soll die Vorverarbeitung neuer Daten in mlr erfolgen? Hier ist ein Beispiel, wo ich eine neue Aufgabe, den neuen Datensatz zu Vorprozess geschaffen, die zu einem Fehler führt:Vorverarbeitung neuer Daten für die Vorhersage mit dem mlr-Paket

library(mlr) 
a <- data.frame(y=factor(c(1,1,1,1,1,1,1,1,0,0,1,0)), 
       x1=rep(c("a","b", "c"), times=c(10,1,1))) 
# most frequent x1 factor is "a" 
aTask <- makeClassifTask(data = a, target = "y", positive="1") 
aTask <- mergeSmallFactorLevels(aTask, cols=c("x1"), min.perc=0.1) 
# combines "b" and "c" into factor ".merged" 
getTaskData(aTask) 

aLearner <- makeLearner("classif.rpart", predict.type = "prob") 
model <- train(aLearner, aTask) 

b <- data.frame(y=factor(c(1,0,1,1,1,1,1,1,0,0,1,0)), 
       x1=rep(c("a","b", "c"), times=c(1,10,1))) 
# most frequent x1 factor is "b" 
# target would be made up, because at this stage there would be now target 
# variable availabel 
newdataTask <- makeClassifTask(data = b, target = "y", positive="1") 
newdataTask <- mergeSmallFactorLevels(newdataTask, cols="x1", 
             min.perc = 0.1) 
# combines "a" and "c" into factor ".merged" 
getTaskData(newdataTask) 

pred <- predict(model, newdataTask) 

#Error in model.frame.default(Terms, newdata, na.action = na.action, 
#        xlev = attr(object, : 
#Faktor 'x1' hat neue Stufen b (= factor 'x1' has new level b) 

Ein weiteres Problem mit meiner Lösung besteht darin, dass eine neue Aufgabe, eine Zielgröße zu erfordern scheint, die nicht zur Verfügung stehen würde für neue Datensätze.

Antwort

2

mlr nichts bieten dies automatisch zu tun, aber Sie können die Faktorstufen leicht überprüfen, haben in den neuen Daten entsprechend ersetzt worden und umbenennen:

library(plyr) 
to.replace = setdiff(levels(b$x1), levels(getTaskData(aTask)$x1)) 
b$x1 = mapvalues(b$x1, from = to.replace, to = rep(".merged", times = length(to.replace))) 

Komplettes Beispiel:

library(mlr) 
a = data.frame(y=factor(c(1,1,1,1,1,1,1,1,0,0,1,0)), 
       x1=rep(c("a","b", "c"), times=c(10,1,1))) 
aTask = makeClassifTask(data = a, target = "y", positive="1") 
aTask = mergeSmallFactorLevels(aTask, cols=c("x1"), min.perc=0.1) 

aLearner = makeLearner("classif.rpart", predict.type = "prob") 
model = train(aLearner, aTask) 

b = data.frame(y=factor(c(1,0,1,1,1,1,1,1,0,0,1,0)), 
       x1=rep(c("a","b", "c"), times=c(1,10,1))) 
library(plyr) 
to.replace = setdiff(levels(b$x1), levels(getTaskData(aTask)$x1)) 
b$x1 = mapvalues(b$x1, from = to.replace, to = rep(".merged", times = length(to.replace))) 

newdataTask = makeClassifTask(data = b, target = "y", positive="1") 

pred = predict(model, newdataTask) 

Für solche Dinge ist es oft besser, einen Lernenden mit der Vorverarbeitung zu verschmelzen, damit dies beim Trainieren und Vorhersagen transparent und automatisch geschieht. In diesem Fall würde ein vollständiges Beispiel wie folgt aussehen:

lrn = makeLearner("classif.rpart", predict.type = "prob") 
trainfun = function(data, target, args) { 
    task = makeClassifTask(data = data, target = target, positive = "1") 
    new.task = mergeSmallFactorLevels(task, cols = c("x1"), min.perc = 0.1) 
    return(list(data = getTaskData(new.task), control = list(levels(getTaskData(new.task)$x1)))) 
} 
predictfun = function(data, target, args, control) { 
    library(plyr) 
    to.replace = setdiff(levels(data$x1), control[[1]]) 
    data$x1 = mapvalues(data$x1, from = to.replace, to = rep(".merged", times = length(to.replace))) 
    return(data) 
} 
lrn = makePreprocWrapper(lrn, train = trainfun, predict = predictfun) 

a = data.frame(y=factor(c(1,1,1,1,1,1,1,1,0,0,1,0)), 
       x1=rep(c("a","b", "c"), times=c(10,1,1))) 
aTask = makeClassifTask(data = a, target = "y", positive="1") 
model = train(lrn, aTask) 

b = data.frame(y=factor(c(1,0,1,1,1,1,1,1,0,0,1,0)), 
       x1=rep(c("a","b", "c"), times=c(1,10,1))) 
newdataTask = makeClassifTask(data = b, target = "y", positive = "1") 
pred = predict(model, newdataTask) 

Dies ist nur ein Proof of Concept - Sie wahrscheinlich Argumente für Spezifizierungs haben wollen würde, die verarbeitet werden Funktionen sollte und was die Schwelle und passen Sie den predictfun Code an, um eine beliebige Anzahl von verarbeiteten Features zu behandeln.

Verwandte Themen