2017-03-21 1 views
0

J'ai une distribution gaussienne bidimensionnelle, et j'essaie d'identifier les valeurs aberrantes. Ce n'est pas dans le sens de l'élimination des valeurs aberrantes, mais plutôt pour identifier les échantillons qui sont les plus dissemblables à la masse.R: Identification des valeurs aberrantes dans la distribution gaussienne 2D

http://imgur.com/hlOqjig

data

Avez-vous une suggestion comment cela est mieux fait pour ces données? J'ai essayé d'ajuster une distribution normale sur les deux dimensions et de calculer les valeurs p pour tous les points de données, puis d'identifier les valeurs aberrantes comme les points de données avec les p-valeurs les plus faibles. Cependant, je reçois le résultat suivant:

http://imgur.com/a/w6SAz

data

Voici le code pour le calcul des valeurs P:

library(fitdistrplus) 

norm_pvalue <- function(input_dist, input_values) { 
    # Fitting normal distribution 
    fit <- fitdist(input_dist, "norm") 

    # Calculating p-values 
    p_values <- unlist(lapply(input_values, function(x) dnorm(x = x, mean=  fit$estimate[['mean']], sd= fit$estimate[['sd']]))) 

    return(p_values) 
} 

Je voudrais que la solution soit généralisable.

+0

trouver Mahalanobis distance depuis le centroïde? –

Répondre

0

Je viens de finir en utilisant stat_ellipse de ggplot2 pour identifier les valeurs aberrantes. J'ai utilisé un niveau de confiance de 0,999.

Cette fonction extrait des points à l'extérieur de l'ellipsoïde et prend un ggplot et la couche dans laquelle l'ellipsoïde est tracée.

# Function for identifying points outside ellipse 
outside_ellipse <- function(ggplot, ellipsoid_layer_number) { 
    # Extracting components 
    build <- ggplot_build(ggplot)$data 
    points <- build[[1]] 
ell <- build[[ellipsoid_layer_number]] 

    # Finding points are inside the ellipse, and add this to the data 
    df <- data.frame(points[1:2], 
       in.ell = as.logical(point.in.polygon(points$x, points$y, ell$x, ell$y))) 

    # Plot the result 
    ggplot(df, aes(x, y)) + 
    geom_point(aes(col = in.ell)) + 
    stat_ellipse() 

    # Returning indices of outliers 
    return(which(df$in.ell == FALSE)) 
} 

Ici, je tracer mes données avec l'option ellipsoïde, et extraire les points à l'extérieur du ellipsoïde et ajouter leurs informations au dataframe.

# Saving plot with confidence ellipsoid 
    plotData <- ggplot(pc_df, aes(PC1, PC2)) + geom_point() + stat_ellipse(level = 0.999) 

    # Identifying points outside ellipsoid 
    outside <- outside_ellipse(plotData, 2) 
    pc_df$in_ellipsoid <- rep(FALSE, dim(pc_df)[1]) 
    pc_df$in_ellipsoid[outside] <- TRUE 
0

Sans les données, il est difficile de répondre dans les moindres détails. Cependant, vous voudrez peut-être vérifier la dernière version du paquet assertr, noté ici: http://www.onthelambda.com/2017/03/20/data-validation-with-the-assertr-package/. J'aime beaucoup son flux de travail, qui est très généralisable.

Par exemple, si vous cherchez à consulter les données d'une colonne (col) dans une trame de données (df), vous utiliseriez quelque chose comme:

library(assertr) 
library(magrittr) 

df %>% insist(within_n_sds(2), col) 

Cette dernière fonction serait alors vous informer de toutes les valeurs aberrantes (c.-à-d. les points qui sont supérieurs à deux écarts-types par rapport à la moyenne). Le forfait comprend également de nombreuses mesures différentes pour évaluer les valeurs aberrantes.

Dans votre cas, la colonne en question serait probablement basée sur les résidus de la ligne de meilleur ajustement de PC1 et PC2:

PCA.lm = lm(PC2 ~ PC1, data=df) 
PCA.res = resid(PCA.lm) 

J'espère que vous aide.

+0

Merci pour votre réponse. Je ne peux malheureusement pas joindre les données dues au travail. Je ne regarde pas les relations entre les variables, comme vous le suggérez en appliquant une régression linéaire. Au lieu de cela, je cherche les points de données les plus éloignés de la zone dense de l'intrigue. J'ai envisagé d'utiliser la mise en grappes de densité, puis de mesurer la distance au centroïde. Ceci, cependant, ne fonctionne pas pour les données avec ce type de distribution. –