R:识别2D高斯分布中的异常值

时间:2017-03-21 12:00:51

标签: r normal-distribution outliers n-dimensional

我有二维高斯分布,我试图识别异常值。这不是异常值去除的意义,而是识别与批量最不相似的样本。

http://imgur.com/hlOqjig

data

您是否建议如何最好地处理此数据?我试图在两个维度上拟合正态分布并计算所有数据点的p值,然后将异常值识别为具有最低p值的数据点。但是,我得到以下结果:

http://imgur.com/a/w6SAz

data

这是计算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)
}

我希望解决方案具有普遍性。

2 个答案:

答案 0 :(得分:0)

没有数据,很难做出任何细节回应。但是,您可能需要查看包assertr的最新版本,如下所示:http://www.onthelambda.com/2017/03/20/data-validation-with-the-assertr-package/

我非常喜欢它的工作流程,这是非常普遍的。

例如,如果您要查看数据框(df)中列(col)的数据,则可以使用以下内容:

library(assertr)
library(magrittr)  

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

然后,这个最终函数将通知您所有异常值(即那些与平均值相差超过两个标准偏差的点)。该方案还包括许多不同的评估异常值的措施。

在您的情况下,相关列可能基于PC1和PC2最佳拟合线的残差:

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

我希望能帮助你。

答案 1 :(得分:0)

我最后使用ggplot2的stat_ellipse来识别异常值。我使用了0.999的置信度。

此函数提取椭圆体外的点,并采用ggplot和绘制椭圆体的图层。

# 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))
}

这里我使用椭球选项绘制数据,并提取椭球外的点并将其信息添加到数据框中。

  # 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