R:识别二维高斯分布中的异常值

R: Identifying outliers in 2D gaussian distribution

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

http://imgur.com/hlOqjig

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

http://imgur.com/a/w6SAz

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

我希望解决方案具有通用性。

没有数据,很难详细回答。但是,您可能想要查看最新版本的软件包 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)

希望对你有所帮助。

我刚刚结束使用 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