1. 基于分布的异常检测
1.1 3σ准则 (3-Sigma Rule)
原理:基于正态分布假设,认为距离均值3个标准差之外的数据点为异常值
数学表达式:
python
def three_sigma_detection(data):mean = np.mean(data)std = np.std(data)lower_bound = mean - 3 * stdupper_bound = mean + 3 * stdoutliers = [x for x in data if x < lower_bound or x > upper_bound]return outliers
优缺点:
-
✅ 简单直观,计算效率高
-
✅ 对正态分布数据效果良好
-
❌ 依赖正态分布假设
-
❌ 对偏态分布敏感
-
❌ 只能检测全局异常
适用场景:质量控制、金融收益率分析
1.2 Z-Score 方法
原理:计算数据点与均值的标准差距离
数学表达式:
def z_score_detection(data, threshold=3):z_scores = np.abs((data - np.mean(data)) / np.std(data))return data[z_scores > threshold]
改进版本:
- 修正Z-Score:使用中位数和MAD(Median Absolute Deviation)
def modified_z_score(data, threshold=3.5):median = np.median(data)mad = np.median(np.abs(data - median))modified_z_scores = 0.6745 * (data - median) / mad # 0.6745为调整系数return data[np.abs(modified_z_scores) > threshold]
1.3 箱线图法 (Boxplot)
原理:基于四分位数和IQR(Interquartile Range)识别异常值
实现:
def boxplot_detection(data):Q1 = np.percentile(data, 25)Q3 = np.percentile(data, 75)IQR = Q3 - Q1lower_bound = Q1 - 1.5 * IQRupper_bound = Q3 + 1.5 * IQRoutliers = [x for x in data if x < lower_bound or x > upper_bound]return outliers
阈值选择:
-
温和异常值:1.5×IQR
-
极端异常值:3×IQR
2. 基于距离的异常检测
2.1 K-最近邻 (K-Nearest Neighbors)
原理:计算每个点与其k个最近邻的距离,距离较大的点视为异常
实现:
python
from sklearn.neighbors import NearestNeighbors
def knn_outlier_detection(X, k=5, threshold=1.5):
neigh = NearestNeighbors(n_neighbors=k)
neigh.fit(X)
distances, indices = neigh.kneighbors(X)
# 计算平均距离
avg_distances = np.mean(distances, axis=1)# 基于百分位数设置阈值
if threshold <= 1:threshold_value = np.percentile(avg_distances, threshold * 100)
else:threshold_value = np.mean(avg_distances) + threshold * np.std(avg_distances)return avg_distances > threshold_value
优缺点:
-
✅ 无需分布假设
-
✅ 可发现任意形状的异常
-
❌ 计算复杂度高 O(n²)
-
❌ 对参数k敏感
-
❌ 高维数据效果差(维度灾难)
2.2 局部异常因子 (LOF - Local Outlier Factor)
原理:比较点的局部密度与其邻居的局部密度
实现:
from sklearn.neighbors import LocalOutlierFactor
def lof_detection(X, contamination=0.1):lof = LocalOutlierFactor(contamination=contamination)return lof.fit_predict(X)
核心概念:
-
k-距离:点到第k个最近邻的距离
-
可达距离:max(k-距离(p), 两点间距离)
-
局部可达密度:k个近邻的平均可达距离的倒数
-
LOF值:近邻的局部可达密度与当前点密度的比值
LOF值解释:
-
≈1:与邻居密度相似
-
<1:密度高于邻居(可能是内点)
-
1:密度低于邻居(可能是异常点)
3. 基于密度的异常检测
3.1 DBSCAN-based 异常检测
原理:基于密度的聚类,将不属于任何簇的点标记为异常
实现:
from sklearn.cluster import DBSCANdef dbscan_outlier_detection(X, eps=0.5, min_samples=5):dbscan = DBSCAN(eps=eps, min_samples=min_samples)labels = dbscan.fit_predict(X)return labels == -1 # -1表示噪声点(异常)
参数选择:
eps
:邻域半径min_samples
:核心点所需的最小邻居数
3.2 局部异常概率 (LoOP - Local Outlier Probability)
原理:基于局部邻域的统计检验计算异常概率
特点:
- 提供0-1之间的异常概率
- 对局部密度变化更鲁棒
4. 基于树的异常检测
4.1 孤立森林 (Isolation Forest)
原理:异常点更容易被随机划分孤立
实现:
from sklearn.ensemble import IsolationForestdef isolation_forest_detection(X, contamination=0.1):iso_forest = IsolationForest(contamination=contamination,random_state=42)return iso_forest.fit_predict(X)
算法流程:
-
随机选择特征和分割值构建孤立树
-
计算每个点的路径长度(从根节点到该点的边数)
-
计算异常分数:$s(x,n) = 2^{-\frac{E(h(x))}{c(n)}}$
-
$E(h(x))$:路径长度的期望
-
$c(n)$:平均路径长度,用于标准化
-
异常分数解释:
-
接近1:很可能是异常
-
远小于0.5:很可能是正常点
-
所有点约0.5:没有明显异常
优缺点:
-
✅ 处理高维数据效果好
-
✅ 线性时间复杂度
-
✅ 无需距离或密度计算
-
❌ 对局部异常检测效果有限
5. 其他重要方法
5.1 一类支持向量机 (One-Class SVM)
原理:在特征空间中找到最优超平面,使大部分数据位于同一侧
from sklearn.svm import OneClassSVMdef one_class_svm_detection(X, nu=0.1):oc_svm = OneClassSVM(nu=nu)return oc_svm.fit_predict(X)
5.2 自编码器 (Autoencoder)
原理:基于重构误差检测异常
from tensorflow.keras.models import Model
from tensorflow.keras.layers import Input, Densedef autoencoder_detection(X, encoding_dim=32, threshold=0.1):# 构建自编码器input_layer = Input(shape=(X.shape[1],))encoded = Dense(encoding_dim, activation='relu')(input_layer)decoded = Dense(X.shape[1], activation='sigmoid')(encoded)autoencoder = Model(input_layer, decoded)autoencoder.compile(optimizer='adam', loss='mse')# 训练并计算重构误差autoencoder.fit(X, X, epochs=50, batch_size=256, verbose=0)reconstructions = autoencoder.predict(X)mse = np.mean(np.power(X - reconstructions, 2), axis=1)return mse > threshold
6. 方法选择指南
方法 | 数据量 | 维度 | 异常类型 | 计算复杂度 | 是否需要标签 |
---|---|---|---|---|---|
3σ/Z-Score | 小-大 | 低 | 全局 | O(n) | 否 |
箱线图 | 小-大 | 低 | 全局 | O(n log n) | 否 |
KNN | 小-中 | 低-中 | 全局 | O(n²) | 否 |
LOF | 小-中 | 低-中 | 局部 | O(n²) | 否 |
孤立森林 | 大 | 高 | 全局 | O(n log n) | 否 |
One-Class SVM | 中 | 中-高 | 全局 | O(n²)-O(n³) | 否 |
自编码器 | 大 | 高 | 复杂模式 | O(epochs×n) | 否 |
7. 最佳实践建议
-
数据预处理:
-
处理缺失值和标准化
-
考虑数据分布特性
-
-
多方法结合:
def ensemble_anomaly_detection(X, methods=['isolation_forest', 'lof']):scores = []if 'isolation_forest' in methods:if_scores = IsolationForest().fit(X).score_samples(X)scores.append(if_scores)if 'lof' in methods:lof_scores = LocalOutlierFactor().fit(X).negative_outlier_factor_scores.append(lof_scores)# 组合分数combined_scores = np.mean(scores, axis=0)return combined_scores
-
阈值选择策略:
- 基于业务知识
- 基于历史数据分布
- 使用自适应阈值
-
验证与调优:
- 使用有标签数据验证(如有)
- 结合业务场景调整参数
- 定期重新训练模型