在本 notebook 中,我们将展示如何使用多变量方法检测多个时间序列中的异常。这种方法非常适用于存在多个传感器或相关时间序列的场景。我们还将解释它与单变量方法的工作原理有何不同。

import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
from nixtla import NixtlaClient
# Utility function to plot anomalies
def plot_anomalies(df, unique_ids, rows, cols):
    fig, axes = plt.subplots(rows, cols, figsize=(12, rows * 2))
    for i, (ax, uid) in enumerate(zip(axes.flatten(), unique_ids)):
        filtered_df = df[df['unique_id'] == uid]
        ax.plot(filtered_df['ts'], filtered_df['y'], color='navy', alpha=0.8, label='y')
        ax.plot(filtered_df['ts'], filtered_df['TimeGPT'], color='orchid', alpha=0.7, label='TimeGPT')
        ax.scatter(filtered_df.loc[filtered_df['anomaly'] == 1, 'ts'], filtered_df.loc[filtered_df['anomaly'] == 1, 'y'], color='orchid', label='Anomalies Detected')
        ax.set_title(f"Unique_id: {uid}", fontsize=8); ax.tick_params(axis='x', labelsize=6)
    fig.legend(loc='upper center', ncol=3, fontsize=8, labels=['y', 'TimeGPT', 'Anomaly'])
    plt.tight_layout(rect=[0, 0, 1, 0.95])
    plt.show()
nixtla_client = NixtlaClient(
    # defaults to os.environ.get("NIXTLA_API_KEY")
    api_key = 'my_api_key_provided_by_nixtla'
)

👍 使用 Azure AI 端点

要使用 Azure AI 端点,请设置 base_url 参数

nixtla_client = NixtlaClient(base_url="you azure ai endpoint", api_key="your api_key")

1. 数据集

在本 notebook 示例中,使用了 SMD 数据集。SMD (Server Machine Dataset) 是一个用于多时间序列异常检测的基准数据集。它监控服务器机器数据中的异常模式。

在这里,我们使用来自单个服务器机器 (machine-1-1) 的一组监控数据,该机器包含 38 个时间序列。每个时间序列代表一个不同的监控指标,例如 CPU 使用率、内存使用率、磁盘 I/O 和网络 I/O。

df = pd.read_csv('https://datasets-nixtla.s3.us-east-1.amazonaws.com/SMD_test.csv', parse_dates=['ts'])
df.unique_id.nunique()
38

2. 单变量与 多变量方法

2.1 单变量方法

单变量异常检测独立分析每个时间序列,根据其历史模式的偏差标记异常。这种方法对于检测单个指标中的问题有效,但会忽略多个序列之间的依赖关系。因此,在异常是由多个序列之间的模式引起的场景中(例如系统级故障、相关的财务指标或互连的过程),它可能会漏掉集体异常或标记不相关的异常。这时就需要多变量异常检测了。

anomaly_online = nixtla_client.detect_anomalies_online(
    df[['ts', 'y', 'unique_id']],
    time_col='ts',
    target_col='y',
    freq='h',                        
    h=24,                            
    level=95,                        
    detection_size=475,              
    threshold_method = 'univariate'  # Specify the threshold_method as 'univariate'
)
INFO:nixtla.nixtla_client:Validating inputs...
INFO:nixtla.nixtla_client:Preprocessing dataframes...
WARNING:nixtla.nixtla_client:Detection size is large. Using the entire series to compute the anomaly threshold...
INFO:nixtla.nixtla_client:Calling Online Anomaly Detector Endpoint...
display_ids = ['machine-1-1_y_0', 'machine-1-1_y_1', 'machine-1-1_y_6', 'machine-1-1_y_29']
plot_anomalies(anomaly_online, display_ids, rows=2, cols=2)

2.2 多变量方法

多变量异常检测方法同时考虑多个时间序列。它不是孤立地处理每个序列,而是在所有序列中累积同一时间步长的异常分数,并根据组合分数确定该时间步长是否异常。这种方法在异常只有当多个序列共同指示问题时才显著的场景中特别有用。要应用多变量检测,只需将 threshold_method 参数设置为 multivariate

我们可以看到,由于异常检测依赖于所有序列累积的误差,因此为每个时间序列检测到的异常发生在同一时间步长。

anomaly_online_multi = nixtla_client.detect_anomalies_online(
    df[['ts', 'y', 'unique_id']],
    time_col='ts',
    target_col='y',
    freq='h',
    h=24,
    level=95,
    detection_size=475,
    threshold_method = 'multivariate'   # Specify the threshold_method as 'multivariate'
)
INFO:nixtla.nixtla_client:Validating inputs...
INFO:nixtla.nixtla_client:Preprocessing dataframes...
WARNING:nixtla.nixtla_client:Detection size is large. Using the entire series to compute the anomaly threshold...
INFO:nixtla.nixtla_client:Calling Online Anomaly Detector Endpoint...
plot_anomalies(anomaly_online_multi, display_ids, rows=2, cols=2)

📘 在多序列异常检测中,在每个时间步长聚合来自所有时间序列的误差分数,并应用阈值来识别显著偏差。如果聚合误差超过阈值,则该时间步长将被标记为所有序列的异常,从而捕获系统级模式。