基于时间序列基础模型的异常检测
基于 AWS Chronos-2 的实践者指南
AI模型价格对比 | AI工具导航 | ONNX模型库 | Vibe Coding教程 | PLC在线仿真器 | Tripo 3D | Meshy AI | ElevenLabs | KlingAI | ArtSpace | Phot.AI | InVideo
在工业时间序列分析中,异常检测是我们面临的最常见的任务之一。它回答的问题很简单:
系统是否按预期运行?
这个问题无处不在:电表、制造传感器、物流需求、医疗监控等等。而回答它会带来巨大的价值,比如在设备故障级联之前发现它们、标记欺诈、在流程偏差仍可廉价修复时发现它等。
那么实践者通常如何处理这个问题?常见做法是为特定问题构建专用的异常检测器。这可以工作,但也意味着生成的检测器范围非常狭窄,你需要为下一个异常检测项目从头开始重建整个流程。
这自然引出以下问题:
与其使用许多狭窄的模型,我们能否构建一个单一的、通用的模型,能够开箱即用地处理许多问题?
事实上,这个问题并不新鲜。
在语言、视觉、语音和视频领域,该领域已经收敛到相同的方案:在足够的数据上预训练大型神经网络,然后将其应用于下游任务,几乎不需要或完全不需要针对每个任务进行调整。
这就是基础模型的概念,它们已成为一个又一个模态的默认起点。
时间序列是另一个正在经历相同转变的模态。
这里的赌注是我们可能能够预训练一个大型时间序列基础模型(TSFM),并开箱即用地应用于许多时间序列。事实上,已经有大量工作沿着这条路走下去,我们现在看到了一系列这样的模型,例如:Google 的 TimesFM、Salesforce 的 MOIRAI、Lag-Llama、TimeGPT 以及 AWS 的 Chronos 系列。
但问题在于。TSFM 通常是一个时间序列预测模型。它获取历史上下文并预测接下来会发生什么。它不是通常意义上的异常检测器,当然也不会直接给我们一个"异常分数"。
那么,我们如何将预测模型用于异常检测呢?
这正是本文的主题。我们将使用 Chronos-2(Chronos 系列中的最新模型)作为预测引擎,并将其转变为异常检测器。我们将通过一个带有注入异常事件的合成建筑电力需求案例研究,看看 Chronos-2 能够多好地标记它们。
在此过程中,我们将回答四个面向实践者的问题:
- 时间序列基础模型如何用于异常检测?
- 我们如何将 Chronos-2 的预测转化为异常分数?
- 这个工作流程在实践中是什么样子的?
- 这种方法可以在哪里工作,有哪些陷阱?
最后,你将获得一个在预测之外使用 TSFM 的实用工作流程。你可以在这里找到完整的笔记本演练。
1. 时间序列基础模型可以用于异常检测吗?
乍一看,这可能听起来有点奇怪。毕竟,Chronos-2 是一个预测模型,它将历史时间序列作为输入上下文,并预测未来的样子。它不是原生的异常检测模型,我们当然不能指望它直接返回"异常分数"。
那么,我们到底如何使用它来进行异常检测呢?
关键观察是,许多异常检测问题可以重新表达为期望问题。让我详细说明。
异常检测非常关注观察到的行为是否是期望的。但要说某事是期望的,我们首先需要一个参考,一个正常应该是什么样子的概念。
这正是预测可以给我们的。
然后,一旦获得实际测量值,我们可以将观察值与预测的、期望的值进行比较。如果我们发现偏差足够大,我们可以将其标记为潜在的异常。
这就是我们将预测能力转化为异常检测能力的方式。
这种框架对时间序列特别有效。一个关键原因是,对于现实的时间序列,正常的概念通常会随时间变化。在这些场景中,异常性不是关于值在绝对意义上是大还是小。相反,它取决于该值是否符合我们认为在那个时刻应该发生的事情。
我们可以用建筑的电力需求轻松说明这一点:对于一栋建筑,280 kW 在炎热的工作日下午是完全正常的,因为人们在建筑内,HVAC 正在运行。然而,在周日凌晨 2 点的相同 280 kW 就完全不同了。如果我们采用 200 kW 这样的静态阈值,我们就会错误地将下午标记为异常。换句话说,缺少上下文会导致误报。
因此,一个有用的工作流程可能是:
- 使用 Chronos-2 预测期望行为。
- 将实际测量值与该期望进行比较。
- 根据差异标记异常。
这就是我们将在本文中使用的联系。
2. 我们如何将 Chronos-2 的预测转化为异常分数?
现在我们有了这个想法,接下来我们使这个想法可操作。
最简单的方法是使用绝对预测误差作为异常分数。然后,如果绝对误差很小,即异常分数很小,我们将该点视为正常。否则,我们将其标记为可疑。
这绝对是一个合理的起点,但在实践中,这还不够。
这是因为我们还没有考虑模型不确定性。
如果我们有一个完美的预测模型,原始绝对误差可能就足够了。但当然,我们没有完美的预测模型。Chronos-2 归根结底只能近似系统未来的行。
因此,当我们看到预测误差时,我们不应立即将该误差解释为异常的度量。一些预测误差可能只是普通的预测缺陷。
相反,一个更稳健的框架是:这个误差是否大于模型本身认为合理的误差?
幸运的是,Chronos-2 原生返回预测分位数,这为我们提供了一种表示预测不确定性的实用方法。具体来说,除了中位数预测外,Chronos-2 在内部训练以生成 21 个预测分位数的网格:
[0.01, 0.05, 0.10, 0.15, ..., 0.90, 0.95, 0.99]
这是通过分位数回归目标实现的,通常称为 pinball 损失。使用 API 时,我们可以通过 quantile_levels 指定我们想要的分位数。在这项工作中,我们使用
quantile_levels=[0.025, 0.5, 0.975]
这不仅会给我们中位数预测,还会给我们一个 95% 的预测区间。由于 0.025 和 0.975 水平不是 Chronos-2 原生网格的一部分,推理代码会从训练的分位数中进行插值。
在我们的异常检测工作流程中,我们使用这个 95% 的预测区间作为自适应容忍带,我们采用的异常分数公式如下:

这个分数很容易解释。对于一个时间戳的观察值:
- 如果观察值在预测区间内,其异常分数为零。
- 如果观察值在区间外,其异常分数将为正。
- 异常分数越大,观察值越远离预测区间表示的合理范围。
3. 这个工作流程在实践中是什么样子的?
在本节中,让我们动手实践,通过一个合成建筑电力需求案例研究来演示异常检测工作流程。
3.1 案例研究设置
对于我们案例研究,我们使用一个包含八栋商业建筑的合成数据集,每栋建筑都有小时级电力需求。数据来自物理模拟器,这使我们能够生成现实的负载模式,并且重要的是,让我们完全控制什么是"正常"和"异常"行为。
我们关注的目标是 total_load_kw,即建筑的总电力需求,它是其基础负载、插座负载、照明负载和 HVAC 负载的总和。除了目标之外,模拟器还提供几个已知未来协变量:室外温度、占用率、太阳辐照度和周末指示器。这些是我们可以合理预先知道的信号,正如我们稍后将看到的,将它们馈送到 Chronos-2 会对检测质量产生真正的影响。
在建模方面,Chronos-2 通过 chronos-forecasting 包提供,我们直接使用预训练的检查点,无需微调。加载模型给我们一个 pipeline 对象,我们将在下面的所有预测中重用它:
import torch
from chronos import Chronos2Pipeline
MODEL_ID = "amazon/chronos-2"
device_map = "cuda" if torch.cuda.is_available() else "cpu"
pipeline = Chronos2Pipeline.from_pretrained(MODEL_ID, device_map=device_map)
模型准备好后,其余设置遵循标准预测协议。Chronos-2 接收 45 天的历史上下文作为输入(2025-05-30 到 2025-07-13),并预测一周的预测范围(2025-07-14 到 2025-07-20),我们将其视为观察的测试周。

异常检测的关键转折点是我们在这个测试周期间做什么。在观察的测试周中,我们注入四种类型的合成异常事件,每栋建筑一种:

值得一提的是,这些异常仅注入到观察的测试周中。历史上下文只包含正常数据。这样,模型仍然可以执行通常的预测任务。之后,可以通过将观察的测试周测量值与预测行为进行比较来完成异常检测。
最后一点:在以下分析中,我们开箱即用地使用 Chronos-2,无需任何微调。
3.2 从预测到异常检测
数据设置好后,我们可以运行实际的异常检测工作流程。
我们从通常的预测步骤开始:我们给 Chronos-2 一个干净的历史上下文,并要求它预测测试周。在这项工作中,我使用协变量信息设置作为主要方法。
此模式通过 predict_df 的输入调用,而不是通过单独的模式标志。历史数据框 context_df 包含序列 ID(building)、时间索引(timestamp)、目标(total_load_kw)和协变量,如温度、占用率、太阳辐照度和周末标志。然后我们传递 future_df,其中包含这些协变量的未来值,以便 Chronos-2 在预测目标的同时,同时考虑历史目标行为和已知的未来协变量。
具体来说,设置如下:
context_df = clean_df[
(clean_df["timestamp"] >= "2025-05-30")
& (clean_df["timestamp"] < "2025-07-14")
][["building", "timestamp", "total_load_kw"] + known_future_columns]
future_covariates_df = clean_df[
(clean_df["timestamp"] >= "2025-07-14")
& (clean_df["timestamp"] < "2025-07-21")
][["building", "timestamp"] + known_future_columns]
然后我们调用 Chronos-2:
forecast_df = pipeline.predict_df(
context_df,
future_df=future_covariates_df,
prediction_length=168,
quantile_levels=[0.025, 0.5, 0.975],
id_column="building",
timestamp_column="timestamp",
target="total_load_kw",
)
forecast_df 包含每个建筑和时间戳的中位数预测和 95% 预测区间。
下一步是将此预测与测试周中的观察测量值进行比较,并按照图 1 中的定义计算异常分数:
scored = observed_test_df.merge(
forecast_df[
["building", "timestamp", "predictions", "0.025", "0.975"]
],
on=["building", "timestamp"],
)
upper_scale = (scored["0.975"] - scored["predictions"]).clip(lower=1e-6)
lower_scale = (scored["predictions"] - scored["0.025"]).clip(lower=1e-6)
high_score = (
(scored["total_load_kw"] - scored["0.975"]) / upper_scale
).clip(lower=0.0)
low_score = (
(scored["0.025"] - scored["total_load_kw"]) / lower_scale
).clip(lower=0.0)
scored["anomaly_score"] = np.maximum(high_score, low_score)
我们还没有完成。最后一步是将这些分数转化为二进制的正常/异常标签。实现这一目标的最简单方法是采用基于阈值的方法,即所有异常分数高于阈值的时间戳都被标记为异常。在实践中,我们会根据专用验证数据集调整阈值,考虑我们可以容忍多少误报率等。对于当前的工作,我们只是选择了一个合理的值用于说明:
scored["is_flagged"] = scored["anomaly_score"] >= 0.25
3.3 检测结果
现在让我们看看检测结果:

在上图中,每行显示一个特定异常事件的检测结果,其中橙色点是检测到的异常。
总体而言,结果令人鼓舞。
对于 03 号建筑,HVAC 卡住事件被完全检测到。Chronos-2 期望夜间负载下降,但观察值保持高位,因此所有 8 个异常小时都被标记。
对于 05 号建筑,电表突然尖峰也被完全检测到。我们可以看到观察到的负载在几个小时内跳跃到相当高的水平,超出了 Chronos-2 模型产生的预期范围。
06 号建筑的传感器掉线也被完全检测到。在这里,观察到的负载在 Chronos-2 期望正常白天需求的期间崩溃到极低的值。
08 号建筑的逐渐负载偏移是具有挑战性的。负载在两天内逐渐向上漂移。Chronos-2 标记了 48 个异常小时中的 33 个,并且错过了漂移开始时的时间戳。这是可以理解的,因为一旦漂移累积到足够大的水平,检测器就可以开始标记它。
另外,请注意 Chronos-2 在 06 号建筑的注入异常窗口之外产生了 2 个误报。在当前的工作中,我们没有调整阈值。但在实际的监控系统中,我们绝对应该校准阈值。另一种常用于减少误报的方法是定义一个最小时间跨度,只有当分数连续时间戳保持在阈值以上时才标记异常。但这是未来的工作。
简要总结一下,在本案例研究中,我们展示了 Chronos-2 可以为我们提供建筑电力需求的期望行为,并且通过将实际观察值与期望进行比较,我们可以执行异常检测并检测不同类型的事件,如尖峰、掉线、错误操作状态和逐渐负载漂移。
3.4 使用协变量有帮助吗?
作为快速消融研究,我们想看看如果去掉协变量,当前的异常检测工作流程表现如何。实际上,我们使用相同的异常评分逻辑;唯一的区别是 Chronos-2 只看到历史 total_load_kw,不接收未来的温度、占用率、太阳辐照度或周末信息。
结果显示如下:

与上图所示的协变量信息预测相比,我们可以清楚地看到,仅目标预测与观察到的需求模式不太一致。此外,预测区间扩展了不少。
这直接影响了异常检测器。在仅目标情况下,我们可以看到在注入异常窗口之外标记了更多的橙色点。它们是误报,因为仅目标预测没有足够好地跟踪正常负载模式。
与此同时,我们看到逐渐负载偏移事件的许多异常时间戳没有被标记。存在假阴性,因为仅目标预测产生了更大的不确定性,并使正常边界变宽。结果,一些异常观察仍然落在容忍范围内,没有被标记。
以下是汇总数字:

假阴性率定义为错过的异常小时除以异常小时,误报率定义为正常小时上的错误标记除以正常小时。
要点:对于基于预测的异常检测,协变量可以提高预测质量,从而提高检测器比较的参考行为的质量。有了更清晰的参考,异常检测器自然会变得更干净。
4. 这种方法可以在哪里工作,有哪些陷阱?
在总结之前,让我们退后一步问这个问题:我们的方法什么时候会有效,什么时候会失败?
实际上,我们当前的异常检测策略是基于预测的,它包含一个特定的世界观:异常是位于模型对未来期望之外的点。这是一个概率性惊奇的定义。它绝对是一个有用的定义,但也不是唯一的定义。
4.1 这种方法在哪些地方效果好
让我们首先谈谈愉快的领域:
- 模型可以学习其结构的系统。TSFM 是模式匹配模型。因此,它们自然适合显示强烈且可学习正常模式的时间序列。随着 TSFM 预测精度的提高,预测和观察之间的偏差变得更加有意义,从而产生更清晰的异常检测。
- 当有信息丰富的协变量可用时。正如我们在案例研究中看到的,馈送协变量(温度、占用率等)不仅可以提高预测精度,还可以收紧预测区间并大幅减少误报。在此基础上构建的检测器可以非常有效。
- 与预期行为的明显、持续偏差。我们在案例研究中看到,尖峰、掉线、水平偏移等异常都被完美捕获。这些是基于预测的异常检测策略容易分离的异常类型。
- 当标签很少时。许多现实问题没有足够的异常标签。基于预测的异常检测不需要任何标签就可以开始。这在冷启动情况下尤其重要,当引入新资产或监控罕见故障系统时。
4.2 需要注意的地方
这是现实介入的地方。在我看来,需要警惕几个陷阱:
- "意外"和"异常"并不总是同一回事。这直接与基于预测的异常检测方法的基本假设相关。例如,真正的状态变化,如建筑租户搬出、新服务投入运行、政策变化,会在一段时间内出乎意料,然后再次成为新的正常。对于这些情况,基于预测的方法可能会引入操作员可能不喜欢的误报。
- 某些类型的异常很难检测。基于预测的方法本质上是逐点检查。因此,缓慢漂移、逐渐退化和渐进偏差等异常会在区间内停留很长时间才会跨越它。我们已经在 08 号建筑中看到了这一点,漂移在开始时被错过,只有在累积到足够大时才被捕获。对于许多实际情况,缓慢退化的早期检测非常重要。仅基于预测的检测方法是不够的。
- 上下文可能被污染。我们当前的方法假设上下文窗口代表"正常"行为。实际上,这个上下文窗口只是最近的历史。如果异常已经发生,上下文窗口就不再纯净。对于实际部署,我们可能需要一个反馈循环,以确保标记的点在返回上下文之前被遮蔽或插补。
- 预测质量非常重要。预测质量直接影响异常检测质量。如果预测不好,检测器可能会产生误报;如果预测产生过宽的预测区间,检测器可能会产生假阴性。这对实际部署意味着什么,我们必须仔细评估预测器本身,不仅是使用均方根误差等指标的点预测质量,还有其不确定性量化质量,使用经验区间覆盖等指标。
- 分位数校准是假设的,不是保证的。这一点与前面的点相关,但我想单独说明。Chronos-2 产生分位数作为不确定性的度量很好。但不要对此过于放心,因为它的分位数可能没有得到很好的校准。经验上,对于 95% 的置信区间,它应该覆盖 95% 的干净数据。当使用 Chronos-2 预测分布外数据时,其原生产生的分位数和预测区间可能不可信。由于我们的异常分数依赖于区间,分数本身也变得不太可信。
- 成本和延迟是真实的工程权衡。TSFM 运行成本不低,特别是如果你需要高频检测或跨大型车队检测。对于实际部署,你需要仔细考虑如何协调预测范围、上下文窗口长度、预测频率等的选择。
5. 结束语
在这篇文章中,我们研究了如何将 Chronos-2 模型扩展到预测之外,并将其用作异常检测的基础。通过一个具体的案例研究,我们看到了该工作流程在实际环境中的表现。此外,我们还讨论了这种基于预测的异常检测策略何时效果最佳以及常见的陷阱是什么。
要点:使用 TSFM 进行基于预测的异常检测是一个强大的基线检测器。它设置非常便宜,不需要标签,可以让你快速获得有意义的结果。但它不会是一个完整的异常检测系统。你可能还需要上下文管理、不确定性校准、阈值校准、与其他模型的集成、人工审核等,以达到高质量的生产环境。
不要将 TSFM 视为整个检测器。将其视为其他组件构建的期望行为来源之一。
原文链接: How to Use a Time Series Foundation Model for Anomaly Detection
汇智网翻译整理,转载请标明出处