Skip to content

Latest commit

 

History

5 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Detecção de Anomalia em Métricas de Servidor

Live Demo Python

🔗 Dashboard ao vivo: https://machine-learning-upstat.streamlit.app/

Projeto de estudo de ML em séries temporais / detecção de anomalia, com foco no domínio de monitoramento de infraestrutura (CPU, rede, disco, latência, requisições) — pensado para conectar depois com o UpStat.

Vai do baseline estatístico até deep learning, sempre com avaliação correta para séries temporais (sem vazamento, com métricas pontuais e point-adjusted).

Dataset

NAB — Numenta Anomaly Benchmark: séries reais de métricas de servidor (AWS CloudWatch) e falhas de sistema com causa conhecida, todas com janelas de anomalia rotuladas (ground truth). A curadoria das séries está em src/config.py.

Setup

python3 -m venv .venv && source .venv/bin/activate
pip install -r requirements.txt

Como rodar

python scripts/01_download.py          # baixa o NAB (idempotente)
python scripts/02_eda.py               # explora + plota cada série
python scripts/03_baseline.py          # z-score em janela móvel (piso)
python scripts/04_isolation_forest.py  # Isolation Forest sobre features
python scripts/05_lstm_autoencoder.py  # LSTM Autoencoder (requer torch)
python scripts/06_compare.py           # comparativo dos 3 modelos
python scripts/07_pr_curves.py         # tuning de threshold + curvas PR + PR-AUC
python scripts/08_affiliation.py       # métrica affiliation vs point-adjusted
python scripts/09_uptime_forecast.py   # previsão de falha com antecedência (lead time)
python scripts/10_service.py           # treina/persiste o detector como serviço
python -m src.service                  # sobe o servidor HTTP (POST /score)

Os scripts 03/04/05 salvam os scores por ponto em artifacts/scores/, que os passos 06–08 reaproveitam (sem recomputar modelos). Saídas (figuras + tabelas em CSV) vão para artifacts/.

Dashboard web

Interface interativa (Streamlit + Plotly) que reaproveita todo o src/:

streamlit run app.py          # abre em http://localhost:8501

Páginas: Visão geral (explorar séries), Detecção (resultados + métricas por modelo), Comparação de modelos (F1/PR-AUC/affiliation), Previsão de falha (horizonte e lead time interativos) e Serviço ao vivo (injete uma anomalia e veja o AnomalyService pontuar em tempo real).

Para o estágio do LSTM:

pip install torch --index-url https://download.pytorch.org/whl/cpu

Consumindo o serviço

python scripts/10_service.py   # treina + persiste o modelo
python -m src.service          # sobe em http://127.0.0.1:8000

curl -s -X POST http://127.0.0.1:8000/score \
  -H 'Content-Type: application/json' \
  -d '{"timestamps": ["2025-01-01T00:00:00", "..."], "values": [50.1, 88.7]}'
# → {"n_pontos": ..., "n_anomalias": ..., "resultados": [{timestamp, value, anomaly_score, is_anomaly}, ...]}

Arquitetura

src/
  config.py      caminhos + curadoria das séries NAB
  data.py        download, carga, rótulo binário a partir das janelas, split temporal
  features.py    rolling stats, diffs/lags, sazonalidade cíclica
  evaluate.py    F1 pontual + point-adjusted F1 (padrão AIOps)
  affiliation.py affiliation-based precision/recall (Huet et al. 2021)
  scoring.py     persistência dos scores por ponto (reuso entre passos)
  synthetic.py   gerador de métrica com precursor (degradação → falha)
  data_smd.py    loader do SMD (multivariado, 38 métricas/máquina)
  thresholding.py  threshold sem rótulo: quantil e POT/EVT (GPD)
  service.py     AnomalyService + servidor HTTP (POST /score)
  viz.py         plots de série e de detecções (matplotlib, p/ artifacts)
  dashboard_viz.py  gráficos interativos Plotly (usados pelo dashboard)
  models/
    baseline.py    rolling z-score + resíduo STL
    iforest.py     Isolation Forest sobre a matriz de features
    lstm_ae.py     LSTM Autoencoder (erro de reconstrução)
    forecaster.py  previsão de falha com horizonte (RandomForest) + lead time
    multivariate.py  PCA recon, IForest multi, MLP Autoencoder (SMD)
    usad.py        USAD — dois autoencoders adversariais (multivariado temporal)
app.py           dashboard web (Streamlit) — 5 páginas interativas
scripts/         pipeline executável, um passo por arquivo (01–10)
artifacts/       figuras, scores, métricas e modelo serializado

Conceitos centrais (o porquê de cada decisão)

  • Split temporal, nunca aleatório. Embaralhar séries temporais vaza o futuro no treino. data.temporal_split corta no tempo.
  • Métrica pontual vs. point-adjusted. A pontual (acertar o ponto exato) é rígida; a point-adjusted dá a janela inteira por acerto. Veja os resultados abaixo — a escolha da métrica muda quem "vence".
  • Treinar no normal (LSTM AE). O autoencoder aprende só o padrão normal (início da série) e detecta anomalia pelo erro de reconstrução alto.

Resultados

Rode python scripts/06_compare.py para gerar o comparativo. Nas 9 séries:

Modelo F1 pontual pa_f1 Observação
Rolling z-score 0.01–0.06 0.79–0.99 Quase não acerta o ponto; "ganha" via janela
Isolation Forest 0.11–0.49 0.30–0.65 Melhor pontual em 6/9; mais falsos positivos
LSTM Autoencoder 0.11–0.74 0.45–0.93 Melhor em padrões complexos (regime change)

Placar por F1 pontual: IForest 6 vitórias, LSTM AE 3.

A métrica inverte o ranking. Por F1 pontual, IForest/LSTM vencem e o baseline é quase lixo (~0.03). Por point-adjusted, o baseline "vence" quase tudo (0.99) — porque basta 1 acerto por janela para levar a janela inteira (pa_recall=1.0). É a crítica clássica ao point-adjust; métricas como affiliation e VUS-PR são mais honestas. Lição: nunca confie numa métrica só.

Destaque: LSTM AE faz F1=0.74 em cpu_utilization_asg_misconfiguration (>2× o IForest) — mudanças graduais de regime são o forte do autoencoder.

Avaliação avançada (passos 07–08)

  • Tuning de threshold + PR-AUC (07): com o threshold ótimo o baseline sobe de F1≈0.03 → 0.18–0.22, mas o PR-AUC (independe de threshold) confirma que ele é fraco de verdade (~0.10) enquanto IForest/LSTM têm sinal real (0.2–0.78). Lição: olhe sempre uma métrica threshold-independent.
  • Affiliation (08): corrige o ranking enganoso do point-adjust. O baseline trivial deixa de "vencer"; LSTM/IForest dominam as séries difíceis. Em média o point-adjust superestima — não confie numa métrica só.

Previsão de uptime (passo 09)

Reformula como classificação supervisionada: prever se haverá anomalia nas próximas H amostras (horizonte ≈ 1h). Resultado-chave:

Cenário precision recall eventos antecipados lead time médio
NAB (falha abrupta) ~0 ~0 quase nenhum —
Sintético (com precursor) 0.90 0.95 7/7 (100%) 55 min

Previsão só funciona quando há precursor (degradação gradual antes da falha). O NAB não tem → resultado negativo honesto. Falhas reais de servidor geralmente têm → é o caso do UpStat, e aí o modelo antecipa ~1h.

Serviço (passo 10)

AnomalyService treina/persiste o detector (joblib) e expõe POST /score. Treinado no cenário sintético, pega 100% das anomalias (recall=1.0) com alguns falsos positivos (precision≈0.33, contamination~10%).

Caveat de produção (concept drift): treinar o IForest num regime de CPU e pontuar um período em outro nível faz ele marcar tudo como anomalia. Métricas de servidor são não-estacionárias — re-treine periodicamente ou normalize por janela móvel.

Multivariado — SMD (passo 11)

python scripts/11_smd_multivariate.py — detecção em 38 métricas correlacionadas por máquina (Server Machine Dataset, OmniAnomaly). Detectores treinados no tráfego normal: PCA reconstruction, Isolation Forest e MLP Autoencoder. A anomalia aqui costuma estar na correlação entre métricas, não numa série só.

Detectores treinados no tráfego normal: PCA recon, Isolation Forest, MLP Autoencoder e USAD (dois autoencoders adversariais sobre janelas — multivariado temporal). Médias de point-adjusted F1 por forma de threshold:

Modelo PA-F1 quantil PA-F1 POT PA-F1 oracle
IForest (multi) 0.79 0.73 0.92
PCA recon 0.47 0.66 0.91
MLP Autoencoder 0.43 0.44 0.91
USAD 0.56 0.37 0.77

Os "0.90 de F1" dos papers de SMD são oracle — escolhem o threshold olhando o gabarito. Com threshold honesto cai muito (crítica de Kim et al. 2022, reproduzida aqui). O POT (Peaks-Over-Threshold + GPD, src/thresholding.py) escolhe o corte pela cauda da distribuição sem rótulo nem quantil mágico — e no PCA chega a superar o quantil fixo. Sob point-adjust um threshold agressivo infla; no F1 pontual a parcimônia do POT reduz falso alarme.

Próximos passos

  • VUS-PR: métrica threshold-independent robusta a ruído de rótulo.
  • OmniAnomaly (VAE+GRU+flows): o modelo multivariado temporal mais completo.
  • Integração UpStat de fato: plugar o /score no fluxo de métricas real e combinar detecção (passos 04/05/11) com previsão (passo 09).

About

Machine learning project for detecting anomalies and predicting failures in server infrastructure metrics, exploring statistical methods, Isolation Forest, LSTM Autoencoders, multivariate detection, and time-series forecasting.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages