使用 QQ Plot Results 删除现有异常值后出现新异常值
New outliers appear after I remove existing ones using QQ Plot Results
我正在研究 Michael Faraway 的 Linear Models with R(第 11 章,第 164 页)中的 PCA 部分。
PCA 分析对异常值很敏感,马氏距离可以帮助我们识别异常值。
作者通过根据卡方分布的分位数绘制马氏距离来检查异常值。
if require(faraway)==F install.packages("faraway"); require(faraway)
data(fat, package='faraway')
cfat <- fat[,9:18]
n <- nrow(cfat); p <- ncol(cfat)
plot(qchisq(1:n/(n+1),p), sort(md), xlab=expression(paste(chi^2,
"quantiles")),
ylab = "Sorted Mahalanobis distances")
abline(0,1)
我辨识点:
identify(qchisq(1:n/(n+1),p), sort(md))
异常值似乎在行 242:252 中。我删除了这些异常值并重新创建了 QQ 图:
cfat.mod <- cfat[-c(242:252),] #remove outliers
robfat <- cov.rob(cfat.mod)
md <- mahalanobis(cfat.mod, center=robfat$center, cov=robfat$cov)
n <- nrow(cfat.mod); p <- ncol(cfat.mod)
plot(qchisq(1:n/(n+1),p), sort(md), xlab=expression(paste(chi^2,
"quantiles")),
ylab = "Sorted Mahalanobis distances")
abline(0,1)
identify(qchisq(1:n/(n+1),p), sort(md))
唉,现在看来一组新的点(行 234:241)现在是异常值。每次我删除额外的异常值时,这种情况都会发生。
期待了解我做错了什么。
要正确识别点,请确保标签与数据中点的位置相对应。 order
或 sort
与 index.return=TRUE
的函数将给出排序后的索引。这是一个例子,任意删除 md
大于阈值的点。
## Your data
data(fat, package='faraway')
cfat <- fat[, 9:18]
n <- nrow(cfat)
p <- ncol(cfat)
md <- sort(mahalanobis(cfat, colMeans(cfat), cov(cfat)), index.return=TRUE)
xs <- qchisq(1:n/(n+1), p)
plot(xs, md$x, xlab=expression(paste(chi^2, 'quantiles')))
## Use indices in data as labels for interactive identify
identify(xs, md$x, labels=md$ix)
## remove those with md>25, for example
inds <- md$x > 25
cfat.mod <- cfat[-md$ix[inds], ]
nn <- nrow(cfat.mod)
md1 <- mahalanobis(cfat.mod, colMeans(cfat.mod), cov(cfat.mod))
## Plot the new data
par(mfrow=c(1, 2))
plot(qchisq(1:nn/(nn+1), p), sort(md1), xlab='chisq quantiles', ylab='')
abline(0, 1, col='red')
car::qqPlot(md1, distribution='chisq', df=p, line='robust', main='With car::qqPlot')
我正在研究 Michael Faraway 的 Linear Models with R(第 11 章,第 164 页)中的 PCA 部分。
PCA 分析对异常值很敏感,马氏距离可以帮助我们识别异常值。
作者通过根据卡方分布的分位数绘制马氏距离来检查异常值。
if require(faraway)==F install.packages("faraway"); require(faraway)
data(fat, package='faraway')
cfat <- fat[,9:18]
n <- nrow(cfat); p <- ncol(cfat)
plot(qchisq(1:n/(n+1),p), sort(md), xlab=expression(paste(chi^2,
"quantiles")),
ylab = "Sorted Mahalanobis distances")
abline(0,1)
我辨识点:
identify(qchisq(1:n/(n+1),p), sort(md))
异常值似乎在行 242:252 中。我删除了这些异常值并重新创建了 QQ 图:
cfat.mod <- cfat[-c(242:252),] #remove outliers
robfat <- cov.rob(cfat.mod)
md <- mahalanobis(cfat.mod, center=robfat$center, cov=robfat$cov)
n <- nrow(cfat.mod); p <- ncol(cfat.mod)
plot(qchisq(1:n/(n+1),p), sort(md), xlab=expression(paste(chi^2,
"quantiles")),
ylab = "Sorted Mahalanobis distances")
abline(0,1)
identify(qchisq(1:n/(n+1),p), sort(md))
唉,现在看来一组新的点(行 234:241)现在是异常值。每次我删除额外的异常值时,这种情况都会发生。
期待了解我做错了什么。
要正确识别点,请确保标签与数据中点的位置相对应。 order
或 sort
与 index.return=TRUE
的函数将给出排序后的索引。这是一个例子,任意删除 md
大于阈值的点。
## Your data
data(fat, package='faraway')
cfat <- fat[, 9:18]
n <- nrow(cfat)
p <- ncol(cfat)
md <- sort(mahalanobis(cfat, colMeans(cfat), cov(cfat)), index.return=TRUE)
xs <- qchisq(1:n/(n+1), p)
plot(xs, md$x, xlab=expression(paste(chi^2, 'quantiles')))
## Use indices in data as labels for interactive identify
identify(xs, md$x, labels=md$ix)
## remove those with md>25, for example
inds <- md$x > 25
cfat.mod <- cfat[-md$ix[inds], ]
nn <- nrow(cfat.mod)
md1 <- mahalanobis(cfat.mod, colMeans(cfat.mod), cov(cfat.mod))
## Plot the new data
par(mfrow=c(1, 2))
plot(qchisq(1:nn/(nn+1), p), sort(md1), xlab='chisq quantiles', ylab='')
abline(0, 1, col='red')
car::qqPlot(md1, distribution='chisq', df=p, line='robust', main='With car::qqPlot')