1. 异常检测概述

说起异常检测,很多刚入行的朋友第一反应就是「找不一样的数据点」。嗯,这么理解倒也没错,但实际做起来远没那么简单。

我个人习惯先把异常检测拆成三个字来看。异常,就是那些明显偏离正常行为模式的数据;检测,就是要在数据流里把它们揪出来。你想想看,在金融交易里一笔突然大额转账,在工厂产线上一台设备温度飙升,在服务器日志里凌晨三点出现大量失败登录——这些都属于异常。

但真正做项目的工程师都知道,定义「正常」这件事本身就够头疼的。我曾经在信贷风控项目里花了两周才把「正常用户画像」搞明白,结果上线第一天就误报了一堆大促时的正常交易。

1.1 三类最常见的异常

异常类型定义典型例子
点异常单个数据点明显偏离全局分布信用卡单笔消费 100 万
上下文异常在特定上下文中异常,全局看正常夏天空调耗电 3000 度(正常) vs 冬天同样度数(异常)
集体异常一组数据点整体异常,单个看都正常连续 10 次小额试探转账后突然大额

我记得刚带团队时,有个新人把集体异常当成多个点异常来打标,导致模型学习到了完全错误的模式。这里我建议:一定要先跟业务方确认异常的定义,别拍脑袋。

1.2 三大核心应用场景

金融领域

反欺诈、反洗钱、异常交易监控。说白了就是跟钱有关的异常,一个误报可能导致客户投诉,一个漏报可能损失几百万。我在银行做过一套规则引擎,第一版把 95% 的正常双十一交易都拦下来了——运营同学差点拿键盘砸我。

工业领域

设备预测性维护、质量缺陷检测。传感器数据往往有很强的时序相关性。我曾经遇到一个案子:振动传感器的值偏高,但因为是缓慢漂移,阈值规则根本没发现。用了统计模型才抓住。

网络安全

入侵检测、DDoS 识别、用户行为分析。攻击者的手法天天变,规则引擎容易过时,这时候 ML 模型的优势就出来了。

一个结论:业务不同,异常的定义天差地别。别妄想一套方案打天下。

1.3 核心挑战:误报与样本不平衡

做异常检测绕不开两个坑。

第一:误报率

规则引擎的报警如果太多,运维人员会直接忽略——这叫「报警疲劳」。我见过一个工业项目,每天 2000 条告警,真正需要处理的只有 3 条。你想想看,这跟狼来了有什么区别?
解决方向:用 ML 模型对规则引擎的输出做二次过滤,或者引入人工反馈的闭环。

第二:样本不平衡

正常数据占 99.9%,异常数据可能只有 0.1%。大部分监督学习算法在这种分布下根本学不到东西。我曾经试过用 XGBoost 硬跑,结果模型把所有样本都判成了正常,准确率 99.9%——但毫无意义。

常用对策包括:
- 重采样(过采样、欠采样)
- 代价敏感学习
- 无监督或半监督方法( Isolation Forest、Autoencoder 等)

避坑提醒:我曾经直接用 SMOTE 过采样产生了一大堆「假异常」,导致模型上线后误报率飙升。后来改用基于生成式模型的合成样本,效果才稳定下来。

1.4 异常检测的知识体系

下面这张图把本章的核心逻辑串起来了——从定义到场景再到挑战,是后续所有章节的基础框架。

异常检测知识体系 异常检测定义 金融风控 工业设备检测 网络安全监控 误报率高 样本极不平衡 定义不清 / 概念漂移 规则引擎 + ML 模型联合方案 图1-1 异常检测知识图谱:中心是定义,左侧是三大应用场景,右侧是核心挑战,底部是课程主要方案。

1.5 一个小示例:简单的阈值规则引擎

在看 ML 模型之前,先感受一下最基础的规则引擎是怎么写的。下面这段 Python 代码就是一个每分钟 CPU 使用率的单维度阈值检测器。

import pandas as pd

def detect_cpu_anomaly(cpu_usage, threshold=95, window=5):
    """
    简单的滑动窗口阈值检测
    cpu_usage: list of float
    threshold: 告警阈值
    window: 连续多少点超过阈值才报警
    """
    anomalies = []
    count = 0
    for i, val in enumerate(cpu_usage):
        if val > threshold:
            count += 1
        else:
            count = 0
        if count >= window:
            anomalies.append(i)
    return anomalies

# 示例数据
data = [30, 45, 96, 97, 98, 35, 92, 93, 94, 95, 50]
result = detect_cpu_anomaly(data)
print(f"异常点索引: {result}")

小提示:实际生产里阈值不是拍脑袋定的,一般会用均值+3σ或者百分位数来动态计算。我习惯先拉一个月的历史数据,把 P99 作为初始阈值,上线后再用反馈调优。

到这里,我们对异常检测有了宏观认识。接下来的课程里,我会带着你一步步搭建规则引擎、训练 ML 模型,再把两者组装成一套能落地的生产级系统。