基于自监督学习的多元时间序列异常检测算法【附代码】

✅博主简介:本人擅长建模仿真、数据分析、论文写作与指导,项目与课题经验交流。项目合作可私信或扫描文章底部二维码。


多元时序数据的异常检测是时间序列数据挖掘的重要领域之一。有效的异常检测算法能够及时检测生产中出现的故障或问题,避免造成更大的损失。

二、具体内容与方法

  1. 基于注意力机制的时序掩蔽自编码器

    • 提出利用立方 Patching 的方式对多元时序数据进行表示学习。这种方式在保持 patch 内时间序列局部性的同时,借助注意力层的全局特征提取能力,获取更具信息含量的表征。
    • 从多层次深度特征中学习潜在的时序关联,进而定义更具区分性的异常检测判据。
    • 采用掩蔽自编码方法,降低信息冗余量,构造困难且有意义的自监督任务,提升模型的表征和泛化能力,并进一步降低计算量。
  2. 基于时间模式注意力的变分自编码器

    • 该模型由时间模式注意力机制(TPA)和嵌入 GRU 单元的 VAE 模型组成,用于实现对时间序列数据的深度特征提取和异常检测。
    • 首先,引入 Time2Vec 技术获取时间嵌入信息。多元时序数据通过 TPA 提取时序特征后,送入嵌有 GRU 单元的 VAE 中,通过重建数据的方式学习数据的潜在表示和不同时间步长之间的信息相关性。
    • 最终以序列数据的重建概率作为异常分数进行异常检测,并结合基于极值理论的异常阈值选取机制,自适应地选取异常分数的阈值。通过在真实数据集上的实验验证,该方法在多元时序数据的异常检测中具有较高的准确性和鲁棒性。
  3. 服务器集群异常检测系统的设计与实现

    • 基于 Zabbix 的 ServerActive 机制从服务器集群的 agent 端分布式收集数据。
    • 一方面,通过图形化界面向用户进行可视化展示,然后结合 Kafka 和 Flink 技术完成异常检测模型的在线判定。
    • 另一方面,将数据存储于 MySQL 数据库中,作为历史数据用于后台异常检测模型的定期离线训练。

三、各部分的具体实现与效果

  1. 基于注意力机制的时序掩蔽自编码器的实现与效果

    • 在数据表示学习方面,立方 Patching 将多元时序数据划分成多个小的立方块。每个立方块内的时间序列保持局部性,使得模型能够更好地捕捉局部的时间模式。同时,注意力层对这些立方块进行全局特征提取,能够关注到不同部分的重要性,从而获取更丰富的特征表示。
    • 为了提升模型的性能,掩蔽自编码方法随机屏蔽一部分数据,让模型通过学习未被屏蔽的数据来预测被屏蔽的数据。这样的自监督任务增加了模型学习的难度,促使模型学习到更具通用性的特征,提高了表征和泛化能力。同时,减少了信息冗余量,降低了计算量,使得模型在处理大规模多元时序数据时更加高效。
  2. 基于时间模式注意力的变分自编码器的实现与效果

    • Time2Vec 技术为时间序列数据引入了额外的时间嵌入信息,增强了模型对时间维度的理解。TPA 机制能够有针对性地提取多元时序数据中的时间模式特征,突出重要的时间点和时间段。
    • 嵌入 GRU 单元的 VAE 模型通过重建数据的过程,学习到数据的潜在表示和不同时间步长之间的信息相关性。这种潜在表示能够捕捉数据的本质特征,有助于更好地进行异常检测。
    • 基于极值理论的异常阈值选取机制能够根据数据的分布特点自适应地确定异常分数的阈值,提高了异常检测的准确性和可靠性。在实际应用中,该模型能够准确地识别出多元时序数据中的异常点,为及时发现问题提供了有力的支持。
  3. 服务器集群异常检测系统的实现与效果

    • Zabbix 的 ServerActive 机制确保了从服务器集群的 agent 端高效地收集数据。图形化界面为用户提供了直观的可视化展示,使得用户能够方便地了解服务器集群的运行状态。
    • Kafka 和 Flink 技术的结合实现了异常检测模型的在线判定,能够实时监测服务器集群中的数据变化,及时发现异常情况。
    • 将数据存储于 MySQL 数据库中,为后台异常检测模型的定期离线训练提供了丰富的历史数据。通过离线训练,模型可以不断优化和更新,提高异常检测的准确性和性能。
  4. import numpy as np
    import torch
    import torch.nn as nn
    import torch.optim as optim
    
    # 定义一个简单的注意力层
    class AttentionLayer(nn.Module):
        def __init__(self, input_dim, output_dim):
            super(AttentionLayer, self).__init__()
            self.attention_weights = nn.Linear(input_dim, output_dim)
            self.softmax = nn.Softmax(dim=-1)
    
        def forward(self, x):
            attention_scores = self.attention_weights(x)
            attention_weights = self.softmax(attention_scores)
            weighted_sum = torch.sum(attention_weights * x, dim=-2)
            return weighted_sum
    
    # 定义一个简单的掩蔽自编码器
    class MaskedAutoencoder(nn.Module):
        def __init__(self, input_dim, hidden_dim):
            super(MaskedAutoencoder, self).__init__()
            self.encoder = nn.Sequential(
                nn.Linear(input_dim, hidden_dim),
                nn.ReLU()
            )
            self.decoder = nn.Sequential(
                nn.Linear(hidden_dim, input_dim),
                nn.Sigmoid()
            )
    
        def forward(self, x, mask):
            encoded = self.encoder(x)
            masked_encoded = encoded * mask
            decoded = self.decoder(masked_encoded)
            return decoded
    
    # 定义一个简单的时间序列数据生成器
    def generate_time_series_data(num_samples, sequence_length, input_dim):
        data = np.random.randn(num_samples, sequence_length, input_dim)
        return torch.tensor(data, dtype=torch.float32)
    
    # 训练函数
    def train(model, data, mask, optimizer, criterion):
        optimizer.zero_grad()
        reconstructed = model(data, mask)
        loss = criterion(reconstructed, data)
        loss.backward()
        optimizer.step()
        return loss.item()
    
    # 主函数
    if __name__ == "__main__":
        num_samples = 100
        sequence_length = 10
        input_dim = 5
        hidden_dim = 32
        batch_size = 16
        learning_rate = 0.001
    
        data = generate_time_series_data(num_samples, sequence_length, input_dim)
        mask = torch.bernoulli(torch.full((num_samples, sequence_length, input_dim), 0.5)).to(torch.float32)
    
        model = MaskedAutoencoder(input_dim, hidden_dim)
        optimizer = optim.Adam(model.parameters(), lr=learning_rate)
        criterion = nn.MSELoss()
    
        for epoch in range(100):
            total_loss = 0
            for i in range(0, num_samples, batch_size):
                batch_data = data[i:i + batch_size]
                batch_mask = mask[i:i + batch_size]
                loss = train(model, batch_data, batch_mask, optimizer, criterion)
                total_loss += loss
            print(f"Epoch {epoch + 1}, Loss: {total_loss / (num_samples // batch_size)}")

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

坷拉博士

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值