当前位置: 首页 > news >正文

【深度学习|学习笔记】异常检测概论 — 从经典算法到深度学习(含实用 Python 示例)

【深度学习|学习笔记】异常检测概论 — 从经典算法到深度学习(含实用 Python 示例)

【深度学习|学习笔记】异常检测概论 — 从经典算法到深度学习(含实用 Python 示例)


文章目录

  • 【深度学习|学习笔记】异常检测概论 — 从经典算法到深度学习(含实用 Python 示例)
    • 异常检测概论 — 从经典算法到深度学习(含实用 Python 示例)
    • 1. 什么是异常检测(Why & What)
      • 定义:
      • 任务形式:
      • 应用场景:
    • 2. 评估指标(怎么衡量好坏)
    • 3. 数据类型与问题细分
    • 4. 经典(非深度)方法(直观 + 优/缺点)
      • 4.1 统计方法
      • 4.2 距离 / 密度基方法
      • 4.3 树 / 集成方法
      • 4.4 线性降维与子空间方法
    • 5. 深度学习方法(近年主流 — 对复杂数据尤其有效)
      • 5.1 自编码器 (AE)
      • 5.2 变分自编码器 (VAE)
      • 5.3 GAN-based 方法(如 AnoGAN / f-AnoGAN)
      • 5.4 对比学习与自监督
      • 5.5 专用架构
      • 5.6 Parameter-efficient / hybrid
    • 6. 时序异常检测(专门技巧)
    • 7. 实践工作流(工程化)
    • 8. 常见挑战与注意点
    • 9. 实战策略(best-practices)
    • 10. Python 示例(A:经典方法;B:深度自编码器)
      • 示例 A — 经典方法(合成数据 + IsolationForest / LOF / OneClassSVM)
      • 示例 B — 深度自编码器(PyTorch,基于 MNIST: 将部分数字设为异常)
    • 11. 进一步阅读 / 常用工具(简短)
    • 12. 小结


欢迎铁子们点赞、关注、收藏!
祝大家逢考必过!逢投必中!上岸上岸上岸!upupup

大多数高校硕博生毕业要求需要参加学术会议,发表EI或者SCI检索的学术论文会议论文。详细信息可扫描博文下方二维码 “学术会议小灵通”或参考学术信息专栏:https://ais.cn/u/mmmiUz


异常检测概论 — 从经典算法到深度学习(含实用 Python 示例)

  • 本文系统性地介绍异常检测(anomaly / outlier detection):定义、任务类型、评价指标、经典方法、现代深度学习方法、时序/图/多模态扩展、实战策略与常见问题。
  • 每个部分给出直观解释、优缺点与实用建议,并在结尾提供两个可直接运行的 Python 示例(经典方法 + 深度自编码器)。

1. 什么是异常检测(Why & What)

定义:

  • 在给定数据集中,找出与大多数样本行为显著不同的样本。异常在不同领域也称离群点、异常样本、故障、入侵、欺诈等。

任务形式:

  • 无监督:只有(或主要)正常/未标注数据(最常见)。
  • 半监督:训练集中只有正常样本,检测异常为目标(one-class 学习)。
  • 有监督:训练数据有异常标签(但通常异常样本稀少且不平衡)。

应用场景:

  • 金融欺诈、网络入侵检测、设备故障预警、医疗异常(影像/生理信号)、制造质量检测、时间序列突变检测等。

2. 评估指标(怎么衡量好坏)

异常检测通常是高度不平衡的分类问题,常用指标:

  • 精确率 (Precision), 召回率 (Recall), F1-score(对不平衡常用)
  • ROC-AUC(对概率评分很常用,但在极端不平衡时可能误导)
  • PR-AUC(Precision-Recall 曲线下面积,在稀有异常时更有价值)
  • 平均检测时间 / 延迟(实时场景)
  • False Positive Rate(工程可容忍范围重要)

实务建议:优先看 Recall@low-FPR 或 PR-AUC,根据业务对误报/漏报的权衡选择阈值。

3. 数据类型与问题细分

  • 静态表格数据(宽表):如信用卡交易的特征向量。
  • 图像数据:制造缺陷、肿瘤检测。
  • 时间序列 / 流式数据:传感器数据、日志、股票数据。
  • 图/网络数据:节点异常、边异常(社交网络)。
  • 多模态数据:图像+文本+结构化信息。

不同类型数据用不同方法或组合策略。

4. 经典(非深度)方法(直观 + 优/缺点)

4.1 统计方法

  • Z-score / IQR / Boxplot:基于单变量分布;简单但不能捕捉复杂关联。
  • 高斯模型 / 多元正态(Mahalanobis 距离):对协方差考虑,适合近似高斯的数据;对高维和非高斯分布受限。
  • KDE(核密度估计):估计概率密度,低密度处为异常;受维度诅咒。

4.2 距离 / 密度基方法

  • kNN distance / LOF (Local Outlier Factor):基于密度局部比较;能检测局部异常,但对大规模数据和高维度慢。
  • DBSCAN / 层次聚类异常分支:聚类后小簇或噪声点可视为异常。

4.3 树 / 集成方法

  • Isolation Forest:通过随机切分来“隔离”样本,异常更易被隔离,计算效率高,适合高维。常用且鲁棒。
  • One-Class SVM:找出将数据包围的超平面(或超球);对复杂分布不够灵活、对核和参数敏感。

4.4 线性降维与子空间方法

  • PCA / Robust PCA:用重构误差判断异常(异常样本在主子空间外)。适合线性可表示的数据;对复杂非线性结构有限。

5. 深度学习方法(近年主流 — 对复杂数据尤其有效)

5.1 自编码器 (AE)

  • 思想:训练一个压缩-重构网络,正常样本重构误差低,异常高。
  • 变体:Denoising AE、Sparse AE、Contractive AE。
  • 优点:对图像、序列可直接端到端;可与卷积/LSTM结合。
  • 缺点:若训练数据含大量异常,或异常与正常在重构上差异小,效果差。

5.2 变分自编码器 (VAE)

  • 给出概率生成模型与重构,使用似然/重构损失 + KL 做评分。善于建模数据分布。

5.3 GAN-based 方法(如 AnoGAN / f-AnoGAN)

  • GAN 学习正常数据分布,使用判别器/生成器辅助评分或通过反求 z 重构误差判断异常。训练不稳定,调参复杂。

5.4 对比学习与自监督

  • 通过构造预text task(旋转预测、patch-prediction、contrastive tasks)学习表征,再在表征空间做经典检测(kNN、LOF)或在 head 上做一类分类。对少标签与跨域泛化有优势。

5.5 专用架构

  • Reconstruction + Forecasting:时序中用预测误差(LSTM预测下一步)作为异常指标。
  • 序列到序列自编码器、Transformer-based 检测器:对长序列模式更灵活。
  • Graph Neural Networks (GNN):图数据异常检测(节点/边的异常分数)。

5.6 Parameter-efficient / hybrid

  • Use pretrained encoders (ImageNet) + apply AE/one-class head; 或用 contrastive pretrained features + simple detector(实践中非常有效)。

6. 时序异常检测(专门技巧)

  • 点异常 vs 突变(change point) vs 事件(collective) 区分重要。
  • 方法:ARIMA / Prophet(统计预测)/ LSTM autoencoder / Seq2Seq prediction / Transformer forecasting / Matrix profile(SAX/matrix-profile),以及基于滑动窗口的重构或预测误差。
  • 关键:考虑季节性、趋势、上下文窗口、延迟容忍度。

7. 实践工作流(工程化)

  1. 明确异常定义与业务代价(FP vs FN)。
  2. 数据准备:清洗、缺失值处理、特征工程(时序滑窗、聚合)、归一化。
  3. 选择基线(IsolationForest、LOF、OneClassSVM、AE)。
  4. 训练 & 验证:用合成/历史标签与人工标注子集进行评估;做交叉验证或时序分割验证。
  5. 阈值选择:基于验证集或按照业务策略(固定FPR/固定Recall)。
  6. 部署监控:在线评分、漂移检测、阈值自适应、重训练策略。

8. 常见挑战与注意点

  • 数据稀有与标签稀少:常用无监督或半监督方法 + 人工回顾。
  • 类别/概念漂移:模型过时需定期重训练或自适应。
  • 高维诅咒:经典密度/核方法失效,需降维或用深表征。
  • 评估困难:真实异常稀少,模拟异常可能不真实,需 domain expert。
  • 误报成本高:在工业场景中要控制 FPR,可能牺牲部分 Recall。

9. 实战策略(best-practices)

  • 先用简单鲁棒的方法(IsolationForest、LOF)做 baseline。
  • 若是图像/时序,先用预训练 encoder + 简单 detector(kNN on features 或 AE on features)。
  • 使用对比学习/预训练表征+轻量检测器,在小样本/跨域情况下优于直接训练深模型。
  • 多模型融合(ensemble)常显著降低误报。
  • 设计评价指标贴合业务(例如 Recall@FPR=0.01)。

10. Python 示例(A:经典方法;B:深度自编码器)

  • 下面给出两个可运行示例,分别使用 sklearn(经典)和 PyTorch(AE)。运行前确保安装 scikit-learn, torch, torchvision, matplotlib, numpy

示例 A — 经典方法(合成数据 + IsolationForest / LOF / OneClassSVM)

# Classic methods demo
import numpy as np
import matplotlib.pyplot as plt
from sklearn.datasets import make_blobs
from sklearn.ensemble import IsolationForest
from sklearn.neighbors import LocalOutlierFactor
from sklearn.svm import OneClassSVM# 生成数据:一个正态簇 + 少量异常
X, _ = make_blobs(n_samples=300, centers=[[0,0]], cluster_std=0.6, random_state=0)
rng = np.random.RandomState(42)
n_outliers = 20
outliers = rng.uniform(low=-6, high=6, size=(n_outliers, 2))
X_all = np.vstack([X, outliers])# 方法1: Isolation Forest
iso = IsolationForest(contamination=n_outliers/(len(X_all)), random_state=0).fit(X_all)
scores_iso = -iso.decision_function(X_all)  # higher -> more abnormal
pred_iso = iso.predict(X_all)  # 1 normal, -1 outlier# 方法2: LOF (returns -1 for outliers)
lof = LocalOutlierFactor(n_neighbors=20, contamination=n_outliers/(len(X_all)))
pred_lof = lof.fit_predict(X_all)
scores_lof = -lof.negative_outlier_factor_# 方法3: OneClassSVM
ocsvm = OneClassSVM(nu=0.05, kernel="rbf", gamma=0.1).fit(X_all)
pred_ocsvm = ocsvm.predict(X_all)
scores_ocsvm = -ocsvm.decision_function(X_all)# 可视化
plt.figure(figsize=(12,4))
for i,(name,pred,scores) in enumerate([("IsolationForest", pred_iso, scores_iso),("LOF", pred_lof, scores_lof),("OneClassSVM", pred_ocsvm, scores_ocsvm),
]):plt.subplot(1,3,i+1)plt.title(name)normals = X_all[pred==1]outs = X_all[pred==-1]plt.scatter(normals[:,0], normals[:,1], s=10, label='normal')plt.scatter(outs[:,0], outs[:,1], color='r', s=20, label='outlier')plt.legend()
plt.tight_layout()
plt.show()
  • 说明:IsolationForest 通常在高维与大规模数据中表现稳定;LOF 对局部密度敏感;OneClassSVM 对核/参数敏感。

示例 B — 深度自编码器(PyTorch,基于 MNIST: 将部分数字设为异常)

# AE anomaly detection on MNIST (train on digits 0-4 as 'normal', test includes 5-9 as anomalies)
import torch, torch.nn as nn, torch.optim as optim
from torchvision import datasets, transforms
from torch.utils.data import DataLoader, Subset
import numpy as npdevice = torch.device("cuda" if torch.cuda.is_available() else "cpu")# 数据:把 0-4 视为正常,5-9 视为异常(演示用)
transform = transforms.Compose([transforms.ToTensor()])
train_ds = datasets.MNIST(root="data", train=True, download=True, transform=transform)
test_ds = datasets.MNIST(root="data", train=False, download=True, transform=transform)# 训练集只用 labels 0-4
train_idx = [i for i,(x,y) in enumerate(train_ds) if y in range(0,5)]
train_subset = Subset(train_ds, train_idx)
train_loader = DataLoader(train_subset, batch_size=128, shuffle=True, num_workers=2)# 测试集保留全部,用于评估异常分数
test_loader = DataLoader(test_ds, batch_size=256, shuffle=False, num_workers=2)# 简单卷积自编码器
class ConvAE(nn.Module):def __init__(self, zdim=32):super().__init__()self.encoder = nn.Sequential(nn.Conv2d(1, 16, 3, stride=2, padding=1), nn.ReLU(),nn.Conv2d(16, 32, 3, stride=2, padding=1), nn.ReLU(),nn.Flatten(),nn.Linear(32*7*7, zdim))self.decoder = nn.Sequential(nn.Linear(zdim, 32*7*7),nn.Unflatten(1, (32,7,7)),nn.ConvTranspose2d(32,16,3,stride=2,padding=1,output_padding=1), nn.ReLU(),nn.ConvTranspose2d(16,1,3,stride=2,padding=1,output_padding=1), nn.Sigmoid())def forward(self,x):z = self.encoder(x)xrec = self.decoder(z)return xrecmodel = ConvAE().to(device)
opt = optim.Adam(model.parameters(), lr=1e-3)
loss_fn = nn.MSELoss()# 训练
for epoch in range(10):model.train()tot=0for x,y in train_loader:x = x.to(device)xr = model(x)loss = loss_fn(xr, x)opt.zero_grad(); loss.backward(); opt.step()tot += loss.item()*x.size(0)print(f"Epoch {epoch+1}, train_loss={tot/len(train_loader.dataset):.6f}")# 测试:用重构误差作为异常分数
model.eval()
scores=[]; labels=[]
with torch.no_grad():for x,y in test_loader:x = x.to(device)xr = model(x)mse = ((xr-x)**2).view(x.size(0), -1).mean(dim=1).cpu().numpy()scores.append(mse)# label: 0-4 normal -> 0, 5-9 anomaly -> 1labels.append((y.numpy()>=5).astype(int))
scores = np.concatenate(scores)
labels = np.concatenate(labels)# 简单评估:ROC AUC, PR AUC
from sklearn.metrics import roc_auc_score, average_precision_score
print("ROC AUC:", roc_auc_score(labels, scores))
print("PR AUC:", average_precision_score(labels, scores))
  • 说明:在实际应用中可以使用更复杂的 AE 变体(VAE、Denoising AE)或结合预训练特征(用 ResNet 的中间特征作为 AE 的输入)以获得更好效果。

11. 进一步阅读 / 常用工具(简短)

  • Python 库scikit-learn(IsolationForest, OneClassSVM, LOF),pyod(专门异常检测库,包含大量方法),alibi-detect(工业检测工具),deepforest/tensorboard用于监控,tsfresh/ruptures(时序分析 change point)。
  • 研究方向:对比学习在无监督异常检测中的应用、基于概率密度的深度生成模型、图异常检测、元学习与少样本异常检测。

12. 小结

  • 异常检测是高度场景依赖的问题:没有“万能方法”。
  • 工程实践通常从简单、可解释且高效的方法(IsolationForest、LOF、PCA)开始;对复杂数据(图像/序列)逐步引入深度表征(自编码器、VAE、对比学习、Transformer)。
  • 评估需贴合业务代价(FP/FN 的不对称成本),并把阈值选择与在线监控纳入设计。
  • 实务建议:用预训练表征 + 简单检测器作为 baseline,再尝试专用深模型;使用多模型融合与人类在环(human-in-loop)提高可靠性。
http://www.dtcms.com/a/588938.html

相关文章:

  • 如何建立一个视频网站html5 手机网站页面实例
  • FlutterPlugin接口实现与插件架构设计
  • 图漾GM461-E1相机专栏
  • Flutter与鸿蒙原生MethodChannel通信机制深度解析
  • Navigation2 行为树架构源码级分析与设计原理
  • 基于时频域霍夫变换的汽车雷达互干扰抑制——论文阅读
  • 贵阳网站建设建站系统怎么找网站是由什么建的
  • 一本通网站1128题:图像模糊处理
  • DrissionPage遇到iframe
  • 基于信号分解的FMCW雷达相互干扰抑制——论文阅读
  • 未来的一些想法和规划
  • 线代强化NO3|线性方程组|特征值和特征向量|矩阵的相似性|实对称矩阵|二次型
  • K8S RD: Docker与Kubernetes运维核心技术整合指南
  • PERL Docker 容器化部署指南
  • root@lll:/data# sudo docker compose up -d 输入这个命令 控制台一直没有任何的反应 我需要如何排查呢?
  • 佛山白坭网站建设wordpress加密修改密码
  • 网站主体必须要与域名注册人相同医院做网站的意义
  • tcprewrite使用方法
  • Rust 练习册 :探索三角形的几何世界
  • SPT:选择性提示调优——让模型自动学习最佳提示插入策略
  • 【Linux篇】信号从哪来?到哪去?—— Linux信号的产生方式与保存机制
  • linux服务-firewalld原理及示例详解
  • 数学基础---四元数
  • 《jQuery Prettydate》深入解析与应用
  • 开发公司自己买自己的商品房西安seo外包机构
  • 【数据结构】单调栈(模板 + 练习)
  • 整体设计 全面梳理复盘 之26 九宫格框架与一体化开发 编程 之5
  • LeetCode算法学习之有效的字母异位词
  • 【算法】递归算法的深度实践:深度优先搜索(DFS)从原理到LeetCode实战
  • BFS 图论【各种题型+对应LeetCode习题练习】