Optimiser le code dans une boucle pour gagner temps calcul

Postez ici vos questions, réponses, commentaires ou suggestions - Les sujets seront ultérieurement répartis dans les archives par les modérateurs

Modérateur : Groupe des modérateurs

myriam desanlis
Messages : 27
Enregistré le : 10 Avr 2009, 08:19

Optimiser le code dans une boucle pour gagner temps calcul

Messagepar myriam desanlis » 25 Juil 2014, 08:22

Bonjour,

n'étant pas une pro du codage sous R, je voulais savoir s'il y avait des améliorations à apporter à mon code pour gagner en temps de calcul lorsque je fais tourner mon programme !
L'objectif de ce code est de faire une validation croisée de mon modèle. J'ai 3 années de données, j'en sélectionne 2 pour optimiser et je teste la validité du modèle sur la 3ème.

Voilà la bête :

Code : Tout sélectionner

Data_champi=read.delim2("Donnees_obs.txt", header= TRUE)
Data_meteo=read.delim2("Meteo.txt", header= TRUE)


#Création des jeux de données pour tester validité modèle
Donnees_pred1=subset(Data_champi,Data_champi$Annee==2010)
Donnees_pred2=subset(Data_champi,Data_champi$Annee==2011)
Donnees_pred3=subset(Data_champi,Data_champi$Annee==2012)

#Création des jeux de données pour optimiser modèle
Annee1=c(2011,2012)
Annee2=c(2010,2012)
Annee3=c(2010,2011)

Donnees_obs1=Data_champi[is.element(Data_champi$Annee, Annee1), ]
Donnees_obs2=Data_champi[is.element(Data_champi$Annee, Annee2), ]
Donnees_obs3=Data_champi[is.element(Data_champi$Annee, Annee3), ]

Phoma_Obs <- vector(mode = "list", length = 3)
Phoma_Pred <- vector(mode = "list", length = 3)

for(i in 1:3){
   Phoma_Obs[[i]] <- paste("Donnees_obs", i, sep="")
   Phoma_Pred[[i]] <- paste("Donnees_pred", i, sep="") 
   }

#initialisation des paramètres et des vecteurs récupérants les valeurs de simulation
r0=0.5
HR0=10
param=c(r0,HR0)
lowerParam=c(0.001,0)
upperParam=c(1,24)

param_r0=c()
param_HR0=c()
conv=c()
SC=c()
SCRcum=c()
Sdiffcum=c()

#boucle pour effectuer la validation croisée
for(i in 1:3){
  Data_obs <- get(Phoma_Obs[[i]])
  res <- nlminb(start=param,objective=s2,dataobs=Data_obs,lower=lowerParam,upper=upperParam) #fonction d'optimisation qui fait appel à mon modèle
  #Récupération des valeurs issues de l'optimisation du modèle
  conv=rbind(conv,res$convergence)
  SC=rbind(SC,res$objective)
  r0opt=res$par[1]
  HR0opt=res$par[2]
  param_r0=rbind(param_r0,res$par[1])
  param_HR0=rbind(param_HR0,res$par[2])
  paramopt=c(r0opt,HR0opt)

#test validité modèle sur le 2ème jeux de données
  Data_pred <- get(Phoma_Pred[[i]])
  sim=f(paramopt,Data_pred)
  obs=Data_pred$Phoma
  SCR=sum((obs-sim)^2)
  Sdiff=sum(obs-sim)
  SCRcum=rbind(SCRcum,SCR)
  Sdiffcum=rbind(Sdiffcum,Sdiff)

#récupération données dans fichier
  dat <- data.frame(convergence=conv,obj=SC,r=param_r0,HR=param_HR0,SCR=SCRcum,SD=Sdiffcum)
  filename <- paste("bouclePluie101112_essai", i, ".csv", sep="")
  write.csv(dat, filename)
}


Merci d'avance

Eric Casellas
Messages : 767
Enregistré le : 06 Jan 2009, 14:59

Messagepar Eric Casellas » 25 Juil 2014, 10:49

Bonjour,

Pour pouvoir faire ça bien il faudrait utiliser des outils de profiling pour trouver quels morceaux de ton code prennent le plus de temps de calcul (voir par exemple http://adv-r.had.co.nz/Profiling.html ou http://www.noamross.net/blog/2013/4/25/faster-talk.html)

Sinon si on se limite aux règles générales de bonnes pratique, il faut tant que faire ce peut éviter dans tes boucle d'utiliser rbind/cbind pour faire grossir tes objets car ça le ralentis, il vaux mieux fixer la taille finale de l'objet avant la boucle et affecter directement l’élément déjà existant dans la boucle (tu as fait comme il faut dans ta 1ere boucle mais pas la 2nd)

Si les différentes itérations de ta boucle sont indépendantes alors tu peut a priori les paralléliser pour pouvoir utiliser plus de processeurs de ta machine (par exemple le paquet foreach permet relativement facilement de // une boucle for classique)
Eric

myriam desanlis
Messages : 27
Enregistré le : 10 Avr 2009, 08:19

Messagepar myriam desanlis » 25 Juil 2014, 11:54

Bonjour,

merci pour les pistes. Mes itérations étant indépendantes, je vais explorer la parallélisation et changer un peu mon code pour supprimer les cbind.


Retourner vers « Questions en cours »

Qui est en ligne

Utilisateurs parcourant ce forum : Aucun utilisateur enregistré et 1 invité