多变量异常检测方法
异常检测是数据分析中的一项关键任务,涉及识别那些显著偏离预期模式或行为的观测值。在高维数据分析中,由于变量之间存在复杂的交互关系,检测这些异常带来了独特的挑战。本文探讨了七种强大的多变量数据异常检测方法,提供了数学基础、代码实现。
多变量异常检测简介
多变量异常检测超越了简单的单变量离群点检测,通过同时考虑多个变量之间的关系和相关性。这在高维数据集中尤为重要,因为在孤立检查单个变量时,异常可能并不明显。
本文讨论的方法代表了解决这一挑战的多种不同方法,从经典统计技术到现代机器学习算法都有涉及。
1. 马氏距离检测器
定义与概念
马氏距离是一种统计测量方法,它量化了数据点距离分布均值的标准差数量,同时考虑了数据的协方差结构。与欧几里德距离不同,马氏距离考虑了变量之间的相关性,并且具有尺度不变性。
数学公式
对于来自均值向量为 μ \mu μ 和协方差矩阵为 Σ \Sigma Σ 的分布的多变量观测值 x x x,马氏距离定义为:
D M ( x ) = ( x − μ ) T Σ − 1 ( x − μ ) D_M(x) = \sqrt{(x - \mu)^T \Sigma^{-1} (x - \mu)} DM(x)=(x−μ)TΣ−1(x−μ)
其中:
- x x x 是观测向量
- μ \mu μ 是分布的均值向量
- Σ \Sigma Σ 是协方差矩阵
- Σ − 1 \Sigma^{-1} Σ−1 是协方差矩阵的逆
实现方法
实现首先计算数据集的均值向量和协方差矩阵。对于样本数少于特征数的高维数据,建议使用收缩估计器(如Ledoit-Wolf)来确保协方差矩阵的稳定性。
def mahalanobis_distance_detector(data, threshold_percentile=95):"""使用马氏距离检测异常"""# 计算均值向量mean_vector = np.mean(data, axis=0)# 计算协方差矩阵 - 当n_samples < n_features时使用收缩估计以提高稳定性n_samples, n_features = data.shapeif n_samples < n_features:print("由于高维性,使用收缩估计器计算协方差")from sklearn.covariance import LedoitWolfcov = LedoitWolf().fit(data).covariance_else:cov = np.cov(data, rowvar=False)# 为每个数据点计算马氏距离inv_cov = np.linalg.pinv(cov) # 使用伪逆以提高稳定性mahalanobis_distances = []for point in data:distance = mahalanobis(point, mean_vector, inv_cov)mahalanobis_distances.append(distance)# 确定异常检测阈值threshold = np.percentile(mahalanobis_distances, threshold_percentile)# 识别异常anomalies = np.where(np.array(mahalanobis_distances) > threshold)[0]return {"distances": mahalanobis_distances,"threshold": threshold,"anomaly_indices": anomalies,"anomaly_scores": mahalanobis_distances,}
该实现使用了SciPy的mahalanobis
函数,并采用协方差矩阵的伪逆以增强数值稳定性。异常被识别为马氏距离超过指定百分位阈值的观测值。
优势与局限性
优势:
- 考虑了数据中的相关结构
- 具有尺度不变性
- 对椭圆分布效果良好
局限性:
- 假设数据遵循多变量正态分布
- 对可能扭曲协方差矩阵的极端异常值敏感
- 对于非常高维的数据计算成本高
- 需要至少与维度一样多的观测值才能得到非奇异协方差矩阵
2. 稳健Z-分数检测器
定义与概念
稳健Z-分数方法通过使用中位数和中位数绝对偏差(MAD)替代均值和标准差,扩展了传统的Z-分数方法。这使得该方法对数据中的离群值更具抵抗力。
数学公式
对于单变量分布中的观测值 x i x_i xi,稳健Z-分数计算如下:
Z i = ∣ x i − median ( X ) ∣ c ⋅ MAD Z_i = \frac{|x_i - \text{median}(X)|}{c \cdot \text{MAD}} Zi=c⋅MAD∣xi−median(X)∣
其中:
- MAD = median ( ∣ X − median ( X ) ∣ ) \text{MAD} = \text{median}(|X - \text{median}(X)|) MAD=median(∣X−median(X)∣) 是中位数绝对偏差
- c = 0.6745 c = 0.6745 c=0.6745 是一个常数,使MAD与正态分布的标准差可比
对于多变量数据,这种方法应用于每个维度,并使用所有维度中的最大稳健Z-分数作为异常分数。
实现方法
实现计算每个特征的中位数值,然后计算MAD。然后对所有特征的每个观测值计算稳健Z-分数,并使用最大分数来识别异常。
def robust_zscore_detector(data, threshold=3.5):"""使用基于中位数和MAD的稳健Z-分数检测异常"""# 计算中位数向量median_vector = np.median(data, axis=0)# 计算每个特征的中位数绝对偏差mad = np.me