Comment améliorer le temps d'exécution pour l'imputation des données R MICE

9

Ma question en bref: existe-t-il des méthodes pour améliorer le temps de fonctionnement de R MICE (imputation de données)?

Je travaille avec un ensemble de données (30 variables, 1,3 million de lignes) qui contient (assez aléatoirement) des données manquantes. Environ 8% des observations dans environ 15 des 30 variables contiennent des NA. Afin d'imputer les données manquantes, j'exécute la fonction MICE, qui fait partie du package MICE .

J'exécute un temps d'exécution assez lent, même sur un sous-ensemble (100 000 lignes), avec method = "fastpmm" et m = 1 et fonctionne pendant environ 15 minutes.

Existe-t-il un moyen d'améliorer le temps de fonctionnement sans perdre trop de performances? (mice.impute.mean est assez rapide, mais s'accompagne d'une importante perte d'informations!).

Code reproductible:

library(mice)
df <- data.frame(replicate(30,sample(c(NA,1:10),1000000,rep=TRUE)))
df <- data.frame(scale(df))

output <- mice(df, m=1, method = "fastpmm")
Dendrobates
la source
1
En général: ces types de questions sont-ils appropriés sur la validation croisée ou mieux adaptés au débordement de pile?
Dendrobates
3
Ce pourrait être un appel au jugement. Parce que (comme principe général) les améliorations les plus substantielles des temps de fonctionnement sont obtenues en comprenant les algorithmes sous-jacents, je m'attends à ce que votre meilleure chance d'obtenir une réponse vraiment efficace soit ici, dans une communauté où les gens pourraient suggérer des approches alternatives . Si vous n'obtenez pas de réponses adéquates dans un jour ou deux, alors signalez simplement ce message pour la migration et nous l'enverrons à SO (avec toutes les réponses et commentaires qu'il aurait pu recueillir entre-temps).
whuber
1
Vous pouvez changer l'option 'fastppm' en 'norm', ça va être plus rapide
marc1s
1
Thx @ marc1s, qui s'est beaucoup amélioré pour les grands ensembles de données. Pour une trame de données aléatoire (comme ci-dessus) avec 10 000 lignes, la méthode "norm" était environ 4 fois plus rapide que "fastpmm". Avec 50 000 lignes, il était même 12 fois plus rapide. Par conséquent, le gain relatif en temps d'exécution augmente du nombre de lignes.
Dendrobates
1
Selon le modèle que vous allez exécuter, il peut être plus rapide d'utiliser l'estimation de la vraisemblance maximale (ou de la vraisemblance maximale complète), qui est asymptotiquement équivalente à l'imputation si le modèle est correctement spécifié. Voici un article auquel j'ai participé, qui compare les différentes méthodes: emeraldinsight.com/doi/abs/10.1108/JCP-02-2015-0007
Jeremy Miles

Réponses:

4

Vous pouvez utiliser à quickpred()partir d'un micepackage à l'aide duquel vous pouvez limiter les prédicteurs en spécifiant le mincor (corrélation minimale) et minpuc (proportion de cas utilisables). Vous pouvez également utiliser les paramètres d'exclusion et d'inclusion pour contrôler les prédicteurs.

Aanish
la source
2

J'ai créé un wrapper pour la micefonction qui inclut un argument supplémentaire droplist, où vous pouvez passer un vecteur de caractères de variables prédictives que vous ne souhaitez pas utiliser dans la partie droite des formules d'imputation. C'était pour la vitesse, car j'ai trouvé que les variables factorielles à plusieurs niveaux ralentiraient considérablement l'imputation . Je n'étais pas au courant de la quickpredfonction référencée par @Aanish, et peut-être pourriez-vous utiliser les deux concepts ensemble.

Ci-dessous est la fonction telle qu'elle apparaît dans mon paquet glmmplus . Si vous le trouvez utile, je peux ouvrir une demande d'extraction dans le micepackage réel .

ImputeData <- function(data, m = 10, maxit = 15, droplist = NULL) {
  if (length(intersect(names(data), droplist)) < length(droplist)) {
    stop("Droplist variables not found in data set")
  }
  predictorMatrix <- (1 - diag(1, ncol(data)))
  for (term in droplist) {
  drop.index <- which(names(data) == term)
    predictorMatrix[, drop.index] <- 0
  }
  mids.out <- mice(data, m = m, maxit = maxit,
                   predictorMatrix = predictorMatrix)
  return(mids.out)
}
Ben Ogorek
la source