Comment effectuer l'imputation de valeurs dans un très grand nombre de points de données?

12

J'ai un très grand ensemble de données et il manque environ 5% de valeurs aléatoires. Ces variables sont corrélées entre elles. L'exemple de jeu de données R suivant n'est qu'un exemple de jouet avec des données corrélées factices.

set.seed(123)

# matrix of X variable 
xmat <- matrix(sample(-1:1, 2000000, replace = TRUE), ncol = 10000)
colnames(xmat) <- paste ("M", 1:10000, sep ="")
rownames(xmat) <- paste("sample", 1:200, sep = "")
#M variables are correlated 

N <- 2000000*0.05 # 5% random missing values 
inds <- round ( runif(N, 1, length(xmat)) )
xmat[inds] <- NA 
> xmat[1:10,1:10]
         M1 M2 M3 M4 M5 M6 M7 M8 M9 M10
sample1  -1 -1  1 NA  0 -1  1 -1  0  -1
sample2   1  1 -1  1  0  0  1 -1 -1   1
sample3   0  0  1 -1 -1 -1  0 -1 -1  -1
sample4   1  0  0 -1 -1  1  1  0  1   1
sample5  NA  0  0 -1 -1  1  0 NA  1  NA
sample6  -1  1  0  1  1  0  1  1 -1  -1
sample7  NA  0  1 -1  0  1 -1  0  1  NA
sample8   1 -1 -1  1  0 -1 -1  1 -1   0
sample9   0 -1  0 -1  1 -1  1 NA  0   1
sample10  0 -1  1  0  1  0  0  1 NA   0

Existe-t-il un (meilleur) moyen d'imputer les valeurs manquantes dans cette situation? L'algorithme Random Forest est-il utile? Toute solution de travail en R serait très appréciée.

Modifications:

(1) Les valeurs manquantes sont distribuées de manière aléatoire entre les variables et les échantillons. Comme le nombre de variables est très grand (ici dans l'exemple - 10000), alors que le nombre d'échantillons est petit ici dans l'exemple factice ci-dessus, il est d'environ 200. Donc, lorsque nous examinons tout échantillon sur toutes les variables (10000), il y a de fortes chances qu'il manque une valeur à une variable - en raison du grand nombre de variables. La suppression de l'échantillon n'est donc pas une option.

(2) La variable peut être traitée à la fois comme quantitative ou qualitative (binaire) en cours d'imputation. Le seul jugement est de savoir dans quelle mesure nous pouvons le prédire (précision). Ainsi, des prédictions comme 0,98 au lieu de 1 pourraient être acceptables plutôt que 0 contre 1 ou -1 contre 1. Je pourrais avoir besoin de faire un compromis entre le temps de calcul et la précision.

(3) Le problème que je me pose est de savoir comment le sur-ajustement peut affecter les résultats car le nombre de variables est important par rapport au nombre d'échantillons.

(4) La quantité totale de valeurs manquantes étant d'environ 5% et aléatoire (non concentrée dans des variables ou des échantillons, car des précautions ont été prises pour supprimer les variables ou les échantillons qui ont des valeurs manquantes très élevées)

(5) Rendre les données complètes pour l'analyse est le premier objectif et la précision est secondaire. Donc pas trop sensible à la précision.

John
la source
1
La raison pour laquelle les données manquent dépend fortement du choix de la technique appropriée. Par exemple, si les données manquent complètement au hasard, vous perdrez peu en supprimant tous les cas avec des valeurs manquantes (car l'ensemble de données est volumineux et relativement peu de valeurs sont manquantes); mais si le manque est lié à des variables importantes dans l'analyse, l'abandon de ces cas peut introduire un biais.
whuber
1
@whuber Je suis d'accord, il n'est pas possible de supprimer pour un ensemble de données de cette taille car chaque cas aura une valeur manquante au moins pour une variable. Cela entraînera une perte totale de données.
John
4
Cela modifie considérablement la question, John, car dans sa forme actuelle, il indique explicitement le contraire: il affirme que seulement 5% des valeurs sont manquantes. Même si nous comprenons que les 5% s'appliquent à toutes les entrées dans la matrice de données, plutôt que 5% des cas, toute personne prenant l'exemple comme indicatif de la nature de vos données conclurait valablement que pas plus de 10 * 5% = 50 % des cas ont des valeurs manquantes. Les trois éléments les plus importants à décrire dans ces questions sont (1) le but de l'analyse, (2) la nature de la lacune et (3) la quantité de la lacune.
whuber

Réponses:

8

Il peut y avoir deux façons de traiter un problème de grande variable et de petit échantillon (observation), selon votre situation et votre ensemble de données.

(1) il suffit d'utiliser des échantillons (observations) comme variable à condition que les scores entre les variables soient identiques ou normalisés.

(2) Utiliser des variables comme variable mais faire un échantillonnage aléatoire tout en imputant de sorte que la variable numérique soit inférieure au nombre d'échantillons et enfin fusionner les données.

Ce qui suit est une séance d'entraînement, vous pouvez vous adapter à vos besoins. J'ai l'hypothèse que la variable est continue, mais vous vous entraînez de la même manière pour les variables discrètes. Ici, je donne un petit exemple pour une vérification rapide.

Premièrement, pour l'entraînement générant des données corrélées, ici les observations (échantillons) sont corrélées, peuvent être réalistes dans des situations où les variables sont supposées indépendantes tandis que les observations sont corrélées. Mais dans d'autres situations où les observations et les variables sont corrélées.

# example correlated data, correlated by observations 
# number of observations 
nobs = 200
nvars = 100
# number of variables 
# covariance matrix matrixCR to create correlated data 
matrixCR <- matrix(NA, nrow = nobs, ncol = nobs)
diag(matrixCR) <- 1
matrixCR[upper.tri (matrixCR, diag = FALSE)] <- 0.5
matrixCR[lower.tri (matrixCR, diag = FALSE)] <- 0.5
matrixCR[1:10,1:10]
L = chol(matrixCR)# Cholesky decomposition
nvars = dim(L)[1]
set.seed(123)
rM = t(L) %*% matrix(rnorm(nvars*nobs), nrow=nvars, ncol=nobs)
rownames(rM) <- paste("V", 1:nvars, sep = "") 
colnames(rM) <- paste("O", 1:nobs, sep = "")
rM[1:10,1:10]



# introduce missing values in random places 
N <- round(nobs*nvars*0.05,0) # 5% random missing values 
set.seed(123)
inds <- round ( runif(N, 1, length(rM)) )
rM1 <- rM
rM1[inds] <- NA

J'utilise le missForestpackage pour l'imputation, qui dépend du randomForestpackage pour le faire. Vous pouvez faire du calcul parallèle si vous avez un très grand nombre de points de données à imputer.

# now use the rM1 matrix in imputation. 
require(missForest)
out.m <- missForest(rM1, maxiter = 10, ntree = 300)
# imputed 
imp.rM1 <- out.m$ximp

Comme il s'agit d'un ensemble de données simulées, nous avons le luxe d'estimer la précision de l'imputation en comparant l'original avant les valeurs manquantes introduites avec l'imputé.

# actual values that were made missing 
aval <- rM[inds]
impv <- imp.rM1[inds]

# accuracy - defined as correlation between actual (before na introduction) and imputed values 
cor(aval,impv)
[1] 0.6759404

Vous pouvez contourner pour augmenter la précision. Bonne chance !

Ram Sharma
la source
5

Il existe des livres complets d'imputation de données, il est donc difficile de donner une réponse dans ce cadre.

La chose la plus simple à faire dans ce cas est de choisir une des colonnes ( ) et de collecter l'autre dans une matrice .xyx

Un modèle est formé et les valeurs manquantes sont remplacées par les valeurs prédites par notre modèle. Vos données semblent être catégoriques, la forêt aléatoire peut donc être un bon choix.y=f(x)

Si votre jeu de données est très volumineux, assurez-vous d'utiliser un algorithme rapide ou évolutif.

Donbeo
la source
merci, avez-vous des suggestions de livres?
John
rien en particulier. mais si vous imputez des données sur Google, vous pouvez trouver beaucoup de choses
Donbeo
Quoi qu'il en soit, si seulement quelques valeurs manquent, vous pouvez simplement supprimer toute la ligne. De vos jeux de données
Donbeo
3
Bien que vous puissiez toujours simplement supprimer les cas avec des valeurs manquantes, ce serait parfois un mauvais choix, selon la raison pour laquelle les données sont manquantes.
whuber
@whuber, je suis totalement d'accord avec vous, mais souvent, c'est le choix le plus sûr.
Donbeo
5

C'est une question vraiment intéressante. Je cherche aussi la même chose. En fait, il existe de nombreuses façons de le gérer.

La première chose, à mon avis, sera de déterminer quel type de données manquantes vous avez - manquant complètement au hasard (MCAR), manquant au hasard (MAR), ou manquant pas au hasard (NMAR). C'est difficile et controversé à prouver, mais cet article montre une façon intéressante de regarder les données MAR.

Pour gérer l'imputation multiple, R a quelques packages:

  • MICE (qui semble très utilisé),
  • randomForest,
  • Hmisc
  • Amelia
  • mi

Ce ne sont que quelques-uns des packages que j'ai trouvés jusqu'à présent.

MICE a également mis en œuvre la forêt aléatoire et quelques autres méthodes, comme l'appariement prédictif moyen.

Ce n'est pas beaucoup, mais cela peut vous aider à comprendre certaines choses. Dès que j'aurai des résultats ou déciderai de quelle méthode je vais procéder, je modifierai le message.

Bonne chance!

psoares
la source
Mes données sont MCAR.
John
1
Si vos données sont MCAR, vous ne pouvez utiliser qu'une analyse de cas complète. De nombreux articles signalent que l'utilisation d'une analyse de cas complète avec des données MCAR est la meilleure solution. Au moins, certains des articles que j'ai trouvés le rapportent, même en les comparant à d'autres méthodes d'imputation
psoares
3

Question interessante. L'astuce est que, pour effectuer une imputation multiple, vous avez besoin de plus qu'un simple modèle prédictif (qui pourrait / serait facile à obtenir, par exemple, dans une approche d'apprentissage automatique). Nous appellerons ces modèles des modèles de simulation, car ils ne sont pas tout à fait des modèles de probabilité.

L'aspect combiné de la sélection des caractéristiques (grand ) et de la formation d'un modèle de simulation me fait penser qu'une approche bayésienne est la meilleure. Cela signifie également qu'il n'y a pas d'approche claire à ce sujet. Pour moi, la meilleure approche aurait l'approche suivante:p

  1. Identifier tous les modèles de disparitions
  2. Pour chaque modèle, utilisez une approche de sélection des caractéristiques bayésiennes pour attribuer des poids postérieurs aux cas complets dans les données.
  3. Échantillonner au hasard des cas complets de manière itérative pour générer des trames de données complètes.
AdamO
la source
3

Votre problème semble sur mesure pour une sorte de complétion de matrice de bas rang. Essayez d'utiliser la impute.svd()fonction du bcvpackage . Je suggérerais d'utiliser un petit rang (l'argument k) - quelque chose comme 5.

Innuo
la source