utiliser les informations du voisin pour imputer des données ou trouver des données hors-ligne (dans R)

13

J'ai un ensemble de données avec l'hypothèse que les voisins les plus proches sont les meilleurs prédicteurs. Juste un exemple parfait de gradient bidirectionnel visualisé-

entrez la description de l'image ici

Supposons que nous ayons un cas où peu de valeurs manquent, nous pouvons facilement prédire en fonction des voisins et de la tendance.

entrez la description de l'image ici

Matrice de données correspondante dans R (exemple factice pour l'entraînement):

miss.mat <- matrix (c(5:11, 6:10, NA,12, 7:13, 8:14, 9:12, NA, 14:15, 10:16),ncol=7, byrow = TRUE)
miss.mat 
    [,1] [,2] [,3] [,4] [,5] [,6] [,7]
[1,]    5    6    7    8    9   10   11
[2,]    6    7    8    9   10   NA   12
[3,]    7    8    9   10   11   12   13
[4,]    8    9   10   11   12   13   14
[5,]    9   10   11   12   NA   14   15
[6,]   10   11   12   13   14   15   16

Remarques: (1) La propriété des valeurs manquantes est supposée être aléatoire , elle peut se produire n'importe où.

(2) Tous les points de données proviennent d'une seule variable, mais leur valeur est supposée être influencée par la neighborsligne et la colonne adjacentes. La position dans la matrice est donc importante et peut être considérée comme une autre variable.

Mon espoir dans certaines situations, je peux prédire des valeurs hors-prix (peut-être des erreurs) et corriger le biais (juste un exemple, permet de générer une telle erreur dans les données fictives):

> mat2 <- matrix (c(4:10, 5, 16, 7, 11, 9:11, 6:12, 7:13, 8:14, 9:13, 4,15, 10:11, 2, 13:16),ncol=7, byrow = TRUE)
> mat2

    [,1] [,2] [,3] [,4] [,5] [,6] [,7]
[1,]    4    5    6    7    8    9   10
[2,]    5   16    7   11    9   10   11
[3,]    6    7    8    9   10   11   12
[4,]    7    8    9   10   11   12   13
[5,]    8    9   10   11   12   13   14
[6,]    9   10   11   12   13    4   15
[7,]   10   11    2   13   14   15   16

Les exemples ci-dessus ne sont qu'une illustration (on peut y répondre visuellement) mais le véritable exemple peut être plus déroutant. Je cherche s'il existe une méthode robuste pour effectuer une telle analyse. Je pense que cela devrait être possible. Quelle serait la méthode appropriée pour effectuer ce type d'analyse? des suggestions de programme / package R pour effectuer ce type d'analyse?

entrez la description de l'image ici

rdorlearn
la source
Pouvez-vous supposer que les données manquantes sont MAR (dans la terminologie de Rubin (1976))?
user603
oui, les valeurs peuvent être supposées manquantes au hasard (MAR). Voir mes modifications récentes.
rdorlearn

Réponses:

7

La question demande des moyens d'utiliser les voisins les plus proches de manière robuste pour identifier et corriger les valeurs aberrantes localisées. Pourquoi ne pas faire exactement ça?

La procédure consiste à calculer un lissage local robuste, à évaluer les résidus et à éliminer ceux qui sont trop grands. Cela répond directement à toutes les exigences et est suffisamment flexible pour s'adapter à différentes applications, car on peut faire varier la taille du voisinage local et le seuil d'identification des valeurs aberrantes.

(Pourquoi la flexibilité est-elle si importante? Parce qu'une telle procédure a de bonnes chances d'identifier certains comportements localisés comme étant "éloignés". En tant que telles, toutes ces procédures peuvent être considérées comme plus lisses . Elles élimineront certains détails ainsi que les valeurs aberrantes apparentes. L'analyste a besoin d'un certain contrôle sur le compromis entre conserver les détails et ne pas détecter les valeurs aberrantes locales.)

Un autre avantage de cette procédure est qu'elle ne nécessite pas de matrice rectangulaire de valeurs. En fait, il peut même être appliqué à des données irrégulières en utilisant un lisseur local adapté à ces données.

R, ainsi que la plupart des progiciels de statistiques complets, disposent de plusieurs lisseurs locaux robustes, tels que loess. L'exemple suivant a été traité à l'aide de celui-ci. La matrice a lignes et79 colonnes - près de 4000 entrées. Il représente une fonction compliquée ayant plusieurs extrema locaux ainsi qu'une ligne entière de points où il n'est pas différenciable (un "pli"). Pourpeu plus de 5 % des points - une proportion très élevée pour être considérée comme « périphériques » - ont été ajoutéeserreurs gaussiennes dontécart type est seulement 1 / 20 de l'écarttype des donnéesorigine. Cet ensemble de données synthétiques présente ainsi bon nombre des caractéristiques difficiles des données réalistes.4940005%1/20

Les figures

Notez que (selon les Rconventions) les lignes de la matrice sont dessinées sous forme de bandes verticales. Toutes les images, à l'exception des résidus, sont ombrées pour aider à afficher de petites variations dans leurs valeurs. Sans cela, presque toutes les valeurs aberrantes locales seraient invisibles!

En comparant les images "imputées" (fixées) aux images "réelles" (originales non contaminées), il est évident que la suppression des valeurs aberrantes a lissé une partie, mais pas la totalité, du pli (qui va de vers le bas à ( 49 , 30 ) ; il apparaît comme une bande angulaire cyan clair dans le graphique "Résidus").(0,79)(49,30)

Les taches dans l'intrigue "Résiduels" montrent les valeurs aberrantes locales isolées évidentes. Ce graphique affiche également d'autres structures (telles que la bande diagonale) attribuables aux données sous-jacentes. On pourrait améliorer cette procédure en utilisant un modèle spatial des données ( via des méthodes géostatistiques), mais le décrire et l'illustrer nous mènerait trop loin ici.

BTW, ce code a signalé avoir trouvé seulement des 200102200 valeurs aberrantes qui ont été introduites. Ce n'est pas un échec de la procédure. Parce que les valeurs aberrantes étaient normalement distribuées, environ la moitié d'entre elles étaient si proches de zéro - ou moins en taille, par rapport aux valeurs sous-jacentes ayant une plage de plus de 600 - qu'elles n'ont fait aucun changement détectable dans la surface. 3600

#
# Create data.
#
set.seed(17)
rows <- 2:80; cols <- 2:50
y <- outer(rows, cols, 
           function(x,y) 100 * exp((abs(x-y)/50)^(0.9)) * sin(x/10) * cos(y/20))
y.real <- y
#
# Contaminate with iid noise.
#
n.out <- 200
cat(round(100 * n.out / (length(rows)*length(cols)), 2), "% errors\n", sep="")
i.out <- sample.int(length(rows)*length(cols), n.out)
y[i.out] <- y[i.out] + rnorm(n.out, sd=0.05 * sd(y))
#
# Process the data into a data frame for loess.
#
d <- expand.grid(i=1:length(rows), j=1:length(cols))
d$y <- as.vector(y)
#
# Compute the robust local smooth.
# (Adjusting `span` changes the neighborhood size.)
#
fit <- with(d, loess(y ~ i + j, span=min(1/2, 125/(length(rows)*length(cols)))))
#
# Display what happened.
#
require(raster)
show <- function(y, nrows, ncols, hillshade=TRUE, ...) {
  x <- raster(y, xmn=0, xmx=ncols, ymn=0, ymx=nrows)
  crs(x) <- "+proj=lcc +ellps=WGS84"
  if (hillshade) {
    slope <- terrain(x, opt='slope')
    aspect <- terrain(x, opt='aspect')
    hill <- hillShade(slope, aspect, 10, 60)
    plot(hill, col=grey(0:100/100), legend=FALSE, ...)
    alpha <- 0.5; add <- TRUE
  } else {
    alpha <- 1; add <- FALSE
  }
  plot(x, col=rainbow(127, alpha=alpha), add=add, ...)
}

par(mfrow=c(1,4))
show(y, length(rows), length(cols), main="Data")

y.res <- matrix(residuals(fit), nrow=length(rows))
show(y.res, length(rows), length(cols), hillshade=FALSE, main="Residuals")
#hist(y.res, main="Histogram of Residuals", ylab="", xlab="Value")

# Increase the `8` to find fewer local outliers; decrease it to find more.
sigma <- 8 * diff(quantile(y.res, c(1/4, 3/4)))
mu <- median(y.res)
outlier <- abs(y.res - mu) > sigma
cat(sum(outlier), "outliers found.\n")

# Fix up the data (impute the values at the outlying locations).
y.imp <- matrix(predict(fit), nrow=length(rows))
y.imp[outlier] <- y[outlier] - y.res[outlier]

show(y.imp, length(rows), length(cols), main="Imputed")
show(y.real, length(rows), length(cols), main="Real")
whuber
la source
whuber: Dois-je bien comprendre que vous supposez que les valeurs aberrantes sont des cellules isolées? Si oui, sauriez-vous à quel point cette approche est sensible à la violation de cette hypothèse?
user603
@ user603 Je ne suppose pas que les valeurs aberrantes sont isolées - beaucoup d'entre elles dans l'exemple ne le sont pas - mais je suppose que la proportion de valeurs aberrantes dans n'importe quel quartier local est suffisamment faible pour ne pas briser le lissage local. Sans doute, s'il y a un quartier avec une très grande proportion de ces valeurs aberrantes, ils ne peuvent plus être considérés comme des valeurs aberrantes locales!
whuber
1
@ user603 Absolument! Mais cela semble nous sortir de la situation présumée où «les voisins les plus proches sont les meilleurs prédicteurs». Par respect pour cela, tout ce que nous faisons lors du traitement des données doit préserver cette prévisibilité locale. Si une colonne a une "échelle très différente" de celle de son voisin, cette circonstance violerait assez fortement cette hypothèse énoncée. (Je me demande également à quel point vous vous concentrez sur les colonnes: en relisant la question, je ne détecte aucune asymétrie dans les rôles des colonnes et des lignes.)
whuber
1
p
1
@whuber c'est une excellente solution, merci - j'essayais d'introduire au moins quelques valeurs manquantes, ce qui est toujours une situation réelle - un mélange de valeurs manquantes (par exemple 50 valeurs manquantes) et de valeurs aberrantes (100 valeurs aberrantes). passionnant !
rdorlearn
4

Je vous conseille de consulter cet article [0]. Le problème qu'il prétend résoudre semble plutôt bien correspondre à votre description, sauf que la méthode proposée par l'auteur est légèrement plus raffinée que la saisie NN (bien qu'elle utilise quelque chose de similaire comme point de départ).

XXnp

k

La première étape de chaque itération est l'étape d'imputation des données. Cela se fait comme dans l'algorithme EM: les cellules manquantes sont remplies par la valeur qu'elles devraient avoir (c'est l'étape E).

Dans la deuxième partie de la procédure itérative en deux étapes, on adapte un PCA (robuste) aux données augmentées obtenues à l'étape précédente. Il en résulte une décomposition spectrale deXXttRppkLLkkDDkp

Pour résumer l'article, voici l'algorithme général qu'ils proposent:

  • l=0WW0XX (la matrice de données d'origine).

  • Ensuite, faites jusqu'à convergence:

    une. faire PCA robuste surWWl(ttl,LLl,DDl)

    l=l+1

    c. utilisationYYl=LLl1(WWl1ttl1)(LLl1)

    WWlWWlN(ttl1,LLl1DDl1(LLl1))YYl

||WWl1WWl||F(tt,LL,DD) .

(ttl-1,LLl-1l-1)

N(ttl-1,LL(LL)) mais cette fois pour les éléments non manquants de votre matrice de données et voyez dans quelle mesure la distribution des données générées (contrefactuelles) correspond à la valeur observée pour chacune des cellules non manquantes.

Je ne connais pas d'implémentation R prête à l'emploi pour cette approche, mais une peut être facilement produite à partir des sous-composants (principalement un algorithme PCA robuste), et ceux-ci sont bien implémentés dans R, voir le rrcov package (le document est calme informatif à ce sujet).

  • [0] Serneels S. et Verdonck, T. (2008). Analyse en composantes principales pour les données contenant des valeurs aberrantes et des éléments manquants. Computational Statistics & Data Analysis vol: 52 question: 3 pages: 1712-1727.
user603
la source
merci, mon objectif ici n'est pas de prédire les valeurs aberrantes (en ce sens qu'elles sont éloignées de la distribution), mais plutôt les valeurs hors-normes (valeurs aberrantes) qui ne correspondent pas au modèle.
rdorlearn
Je pense que vous avez mal compris ma réponse. Cette approche produira une prédiction pour n'importe quelle valeur, mais les valeurs aberrantes ne seront pas très bien prédites: c'est parce qu'elles ne sont pas autorisées à influencer l'ajustement PCA. Je vous conseille de lire le papier.
user603
merci, l'approche semble intéressante et la supposition peut aussi bien fonctionner. Mais sans codes appropriés sera difficile à mettre en œuvre - trop sophistiqué pour moi au moins!
rdorlearn