2016-11-04 1 views
0

J'utilise cette fonction pour effectuer une validation croisée n fois. Le taux de mauvaise classification ne varie pas au cours des plis, par ex. si je lance 10 ou 50. Je reçois également un avertissement:Erreur «predict» lors d'une validation croisée n-fold pour mon GLM

"message d'avertissement:

'newdata' avait 19 lignes, mais les variables trouvées ont 189 lignes"

Si je cours le code sans faire partie d'une fonction, c'est faire ce que je veux -> eg pour les plis == 1, il sort 10%, exécute le modèle sur 90% des données, et prédire les 10% restants. Est-ce que quelqu'un a des idées pour expliquer pourquoi il ne montre pas de variation par variable et le nombre de plis?

library("MASS") 
data(birthwt) 
data=birthwt 

n.folds=10 

jim = function(x,y,n.folds,data){ 

    for(i in 1:n.folds){ 
    folds <- cut(seq(1,nrow(data)),breaks=n.folds,labels=FALSE)  
    testIndexes <- which(folds==i,arr.ind=TRUE) 
    testData <- data[testIndexes, ] 
    trainData <- data[-testIndexes, ] 
    glm.train <- glm(y ~ x, family = binomial, data=trainData) 
    predictions=predict(glm.train, newdata =testData, type='response') 
    pred.class=ifelse(predictions< 0, 0, 1) 
    } 

    rate=sum(pred.class!= y)/length(y) 
    print(head(rate)) 
    } 

jim(birthwt$smoke, birthwt$low, 10, birthwt) 
+0

Merci pour cela - les prédictions doivent être (<0,5, 0,1). La fonction n'est toujours pas correcte, mais merci pour votre observation. – user7090012

+0

Je veux que pred.class soit un vecteur qui a toutes les prédictions de chaque pli. Dans cette fonction, je récupère juste 19, quand il devrait être 189. Ensuite, je produis le taux en utilisant ce vecteur de longueur 189. – user7090012

Répondre

0

Je fais maintenant mes commentaires dans une réponse.

jim <- function(x, y, n.folds, data) { 

    pred.class <- numeric(0) ## initially empty; accumulated later 
    for(i in 1:n.folds){ 
    folds <- cut(seq(1,nrow(data)), breaks = n.folds, labels = FALSE) 
    testIndexes <- which(folds == i) ## no need for `arr.ind = TRUE` 
    testData <- data[testIndexes, ] 
    trainData <- data[-testIndexes, ] 
    ## `reformulate` constructs formula from strings. Read `?reformulate` 
    glm.train <- glm(reformulate(x, y), family = binomial, data = trainData) 
    predictions <- predict(glm.train, newdata = testData, type = 'response') 
    ## accumulate the result using `c()` 
    ## change `predictions < 0` to `predictions < 0.5` as `type = response` 
    pred.class <- c(pred.class, ifelse(predictions < 0.5, 0, 1)) 
    } 

    ## to access a column with string, use `[[]]` not `$` 
    rate <- sum(pred.class!= data[[y]])/length(data[[y]]) 
    rate ## or `return(rate)` 
    } 

jim("smoke", "low", 10, birthwt) 
# [1] 0.3121693 

Remarque:

  1. Pas besoin de mettre arr.ind = TRUE ici, même si elle n'a pas d'effet secondaire.
  2. Il y a un problème avec votre classification. Vous définissez type = "response", puis vous utilisez ifelse(predictions < 0, 0, 1). Pensez-y, vous obtenez toujours 1 pour pred.class.
  3. Chaque itération de votre boucle for écrase la pred.class. Je pense que vous voulez accumuler le résultat. Alors faites pred.class <- c(pred.class, ifelse(predictions < 0.5, 0, 1));
  4. Mauvaise utilisation de glm et predict. Il est faux de mettre $ dans la formule du modèle. S'il vous plaît lire Predict() - Maybe I'm not understanding it. Ici, j'ai changé votre fonction pour accepter les noms de variables (comme une chaîne), et utiliser la bonne formule du modèle à l'intérieur glm. Notez que ce changement nécessite de placer y avec data[[y]] dans rate = sum(pred.class!= y)/length(y).
  5. Vous souhaitez probablement renvoyer rate plutôt que de simplement l'imprimer à l'écran. Remplacez donc votre ligne print par explicite return(rate), ou implicitement rate.
  6. Vous pouvez remplacer ifelse(predictions < 0.5, 0, 1) par as.integer(predictions < 0.5), bien que je ne l'ai pas modifié ci-dessus.
+0

Merci. Le taux devrait être% des prédictions qui ne sont pas les mêmes que y. Les prédictions doivent être une pile des prédictions de chaque prédiction dans la boucle. Je vois maintenant que chaque itération écrase pred.class. Comment puis-je retourner des prédictions et ensuite calculer le taux? – user7090012

+0

Merci pour cela. Cependant, si vous entrez d'autres variables dans jim ("smoke", "low", 10, birthwt), par ex. "age", "low" ou "race" "low", vous obtenez toujours 31%. De plus, si vous changez n.folds pour dire 50, vous obtenez toujours 31%. C'est là que le problème est. Quelque chose ne va pas. – user7090012

+0

Je vois maintenant. C'est drôle que pour les plis> 10, le taux ne change pas. Merci beaucoup pour ça. J'apprécie beaucoup votre temps pour m'aider avec ça! Peut-être qu'un jour je pourrai contribuer! – user7090012