马氏距离(Mahalanobis distance)、高斯分布、奇异值分解(SVD)以及主成分分析(PCA)有内在联系。本文用一个简单的示例来揭示这层联系并且掌握它的实际应用。
1装备
library(ggplot2)
library(ggthemes)
c(R.version$os, R.Version()$version.string)
'linux-gnu'
'R version 3.6.1 (2019-07-05)'
2数据和内置函数
假设我们采集了一批共 16 个人的身高、体重数据,先把它们放入一个数据框。
hw 164, 167, 168, 169, 169, 170, 170, 170, 171, 172, 172, 173, 173, 175, 176, 178),
Weight.kg=c( 54, 57, 58, 60, 61, 60, 61, 62, 62, 64, 62, 62, 64, 56, 66, 70))
首先,我们先用最简单的方法来检测离群值。将那些离平均身高或平均体重超过两个标准差的点标记为离群值/异常值。
is.height.outlier 2
is.weight.outlier 2
pch 16
plot(hw, col=c("#56B4E9"), pch=pch)
上图中实心点是所谓的异常值,然而,(175,56) 这个人明显偏瘦,直觉上很明显它应该是个异常值,可是上面的方法并没有检测出来。从散点图也可以看出来它偏离了正常点。
为了能够把它检测出来,我们不妨换个思路。换什么呢?换距离的计算方式。
我们先用 R 语言内置的计算马氏距离的函数 mahalanobis
来求解。
# 将离中心马氏距离最大的 3 个点选出来作为异常值
n.outliers 3
m.dist.order TRUE)
is.outlier FALSE, nrow(hw))
is.outlier[m.dist.order[1:n.outliers]] TRUE
pch 16
plot(hw, col=c("#56B4E9"), pch=pch)