0
votes

Enlever la boucle imbriquée

Je dois supprimer des boucles de ma fonction. Ce n'est pas facile, car j'ai une structure difficile de données et je ne sais pas comment peut-on utiliser appliquer une famille de la famille.

Tout d'abord, j'ai cette structure de données p>

liste

à l'intérieur de cette liste, j'ai d'autres listes avec train et test. Enfin, j'ai des données.frames dans ces niveaux. Je crée des données simul de ma liste avec Iris Dataset. P> xxx pré>

maintenant, j'ai créé une fonction que je souhaite appliquer de ma liste. P>

Kmax<-5
nd<-10
ks<-seq(from=1,to=Kmax,by=1)
kn<-seq(1:nd)

findKNN<-function(listdf,seeds){
  indx<-1

  outs<-matrix(0, nrow = 5*length(listdf[[1]]), ncol = 3)

  for (i in seq_along(listdf[[1]])){
    for (K in 1:5){
      train<- as.data.frame(listdf$train[i])
      test <- as.data.frame(listdf$test[i])

      set.seed(seeds)

      kpreds <- knn(train[,-ncol(train)],test[,-ncol(test)], train[,ncol(train)],k=K)
      Ktable <-table(kpreds ,test[,ncol(test)])

      outs[indx,1] <- (Ktable[1, 2] + Ktable[2, 1]) / sum(Ktable)
      outs[indx,2] <- K
      outs[indx,3] <- i
      indx<-indx+1
    }
  }

  outs<-data.frame(outs)
  names(outs)<-c("error","K","I")
  outs<-aggregate(error ~ K,outs, mean)
}

output<-lapply(flist,seeds=12345,findKNN)


1 commentaires

D'accord avec @Jet que c'est plus pour la lisibilité que l'efficacité, mais je pense toujours que c'est une bonne idée. L'endroit pour commencer est de prendre en compte la logique qui se passe dans les boucles, alors il sera plus intuitif comment remplacer la boucle avec plus de code R-idiomatic.


3 Réponses :


1
votes

Ceci est juste un coup de poignard dans le noir, mais il me semble que la raison des deux boucles est que vous avez structuré les données comme des listes dans une liste? Éventuellement répertorie les listes dans une liste? Pour moi, cela semble être la plus grande question que pour les boucles ne sont pas efficaces.

Juste une idée, mais peut-être restructurer comment vos données sont stockées à quelque chose comme une carte où vous pouvez relier les valeurs aux clés. Donc, vous avez une carte avec des clés "List1" "List2" et toutes les valeurs de la carte sont jumelées à leur clé. Ensuite, vous n'avez besoin que d'un pour une boucle avec un si cela dit si les clés correspondent à ce que je veux prendre des données. Juste une pensée.


1 commentaires

Pourriez-vous l'expliquer? J'ai des données multiples. Pour cette donnée, j'ai 5 données de train et 5 jeux de données de test. Je pensais que cette forme sera la meilleure buf si vous savez quelque chose de bien, votre réponse sera la bienvenue.



1
votes

the appliquer des fonctions ne disposez pas d'un avantage d'efficacité sur le pour boucles, selon Ce fil .

Si votre objectif est uniquement de diminuer le temps d'exécution, il peut y avoir de points à aucun point convertir les boucles vers Appliquer les fonctions . L'avantage de ces fonctions est maintenant principalement de produire du code plus lisible.


0 commentaires

1
votes

Le lieu de démarrage est en facilitant votre code dans des morceaux, où chaque nouvelle fonction fonctionne à chaque niveau des données. Ensuite, vous pouvez appeler chaque pièce de l'autre et collecter les résultats d'une manière plus idiomatique.

Ici, j'ai effectué des fonctions pour 1) le code de base pour chaque paire de train / test, 2) répétant que pour chaque K, et 3 ) répéter que sur les paires possibles.

Je suis d'accord avec @deja qui restructuratant vos données à une méthode de style plus "obligatoire" pourrait entraîner un code encore plus intuitif, mais si vous n'êtes pas utilisé pour penser à De cette façon, c'est probablement plus clair. xxx

pour mettre les données dans un format plus "rangé", vous auriez une ligne par test / paire de train avec des colonnes supplémentaires pour quel ensemble de données et qui le repère est. Un peu maladroit pour y arriver de ce que vous avez commencé, mais voici ce que cela ressemblerait. xxx

Vous serez ensuite en boucle à travers chaque rangée. (Remarque pour faire ce travail, je devais faire le résultat de Runk Be un data.frame.) xxx

Vous retirez ensuite les données d'origine "innest" les données d'erreur "innest" .Frame et résumez sur le jeu de données et k. xxx


4 commentaires

Merci cela fonctionne. Pourriez-vous expliquer "la restructuration de vos données à une méthode de style plus" obligables "? Merci


Oui ça marche très bien merci! Je ne connaissais pas cette option. Le problème est que je ne sais pas si c'est plus rapide ...


1) Ne vous inquiétez que de la vitesse si c'est trop lent. Il est souvent plus rapide de laisser l'ordinateur le faire de manière lente que pour vous de comprendre un moyen plus rapide. 2) Si c'est trop lent, assurez-vous de savoir où se trouve la partie lente. Dans ce code, il est probable que la partie lente soit dans la fonction KNN et toute différence de temps résultant de l'une de ces trois méthodes serait minimale.


Oui merci! Pourrait parler avec vous en privé à propos de ce code? Merci