2017-12-12 4 views
0

Ich habe einen Datenrahmen mit 20 plus Spalten, und für jede dieser Spalten möchte ich ein glm-Modell, das ich dann erstellen auf dem gleichen Testset evaluieren. Hier ist mein Versuch:Schleife durch einen Datenrahmen und erstellen Sie ein Modell für jede Spalte, die auf dem gleichen Testsatz ausgewertet wird

# Train-test splitting 
smp_size <- floor(0.70 * nrow(x)) 
index <- sample(seq_len(nrow(x)),size = smp_size) 
train <- x[index, ] 
test <- x[-index, ] 

for (i in 1:22) { 

    names(train)[names(train) == names(train[i])] <- 'variab' 
    names(test)[names(test) == names(test[i])] <- 'variab' 

    mod <- glm(Y ~ variab, family = binomial, data = train) 

    assign(paste0("val", sep = "_", letters[i]), as.numeric(performance(
    prediction(predict(mod, newdata = test, type = "response"),test$Y), 
    measure = "auc")@y.values[[1]])) 
} 

Allerdings funktioniert das nicht, es weist nur den Namen „variab“ zu jeder Spalte und endet das gleiche Modell für jede Spalte ausgeführt wird. Wie kann ich diese Schleife durch jede Spalte im Datenrahmen iterieren lassen?

Antwort

1

Hier ist eine Idee für Sie. Ich hoffe, dass dies Ihren Bedürfnissen entspricht. Ich weiß nicht, woher Ihre performance() oder Funktionen kamen, also habe ich sie aus meinem Beispiel entfernt.

data(iris) 
predictors <- names(iris)[-1] 
response <- names(iris)[1] 

# due to a ill chosen example data: 
iris[,response] <- iris[,response]/max(iris[,response]) 

# sample 
smp_size <- floor(.7*nrow(iris)) 
set.seed(20171212) 
idx <- sample(seq_len(nrow(iris)), size=smp_size) 
train <- iris[idx,] 
test <- iris[-idx,] 


for (i in predictors) { 
    tmp.test <- data.frame(pred=get(i,test), resp=get(response, test)) 
    tmp.train <- data.frame(pred=get(i,train), resp=get(response, train)) 


    mod <- glm(resp ~ pred, family=binomial, data=tmp.train) 

    assign(paste0("val", sep="_", i), data.frame(predicted=as.numeric(predict(mod, newdata=tmp.test, type="response")), actual=get(response,test))) 
    } 

Grundsätzlich ist es das, was Sie bereits getan haben. Sie haben bereits die assign() Funktion verwendet, und ich denke an get() als seine Ergänzung und ebenso nützlich. Ich bin auch ein Befürworter der Verwendung von numerischen Indizes, wenn möglich und beim Durchlaufen von Namen, wenn ich eine Schleife verwende, weil es einfach und einfach ist, effektive Nachrichten zu schreiben.

+0

Vielen Dank für Ihre Antwort! Die einzige Sache ist, dass, wenn ich Ihren Code ausführen, bekomme ich die folgende Fehlermeldung: "Warnmeldungen: 1: In Eval (Familie $ initialisieren): Nicht-Integer # Success in einem Binom Glm! 2: 'Newdata' hatte 45 Zeilen, aber gefundene Variablen haben 105 Zeilen "Ist das normal? –

+0

Das kommt von dem Befehl: 'Vorhersage (Objekt = mod, newdata = Test, Typ =" Antwort ")'. Es scheint tatsächlich, dass aus irgendeinem Grund vorhersagen nicht Test verwendet wird, sondern für das newdata Argument trainieren, trotz eines expliziten Arguments anders. Ich habe das vorher nicht gesehen, aber ich werde es lösen und meinen Beitrag bearbeiten. – Nate

+0

Die aktualisierte Antwort behebt das Problem und funktioniert ordnungsgemäß. Beachten Sie, dass die assign-Anweisung in der Schleife geändert wurde, um bessere Ergebnisse zu erzielen, da ich nicht Ihre ursprünglichen 'performance()' - oder 'precision()' -Funktionen verwende. Sie sollten in Ihrem Beispiel kein Problem mit der Warnung 'Nicht ganzzahlige Erfolge' haben, da Ihre Daten wahrscheinlich tatsächlich Binärdaten sind (ich habe schlechte Beispieldaten gewählt). – Nate

Verwandte Themen