Voltar para projetos

Case de projeto

  • Projeto demonstrativo
  • Detecção de anomalias
  • Demo com série simulada
  • Repositório privado

Detecção de Anomalias Operacionais

Detecção não supervisionada de anomalias em métricas operacionais, com alertas por WebSocket e gráfico em D3.

Radar que detecta desvios em métricas operacionais com um Isolation Forest por métrica e envia alertas por WebSocket. A API publicada está fora do ar; o painel mostra uma série simulada no navegador.

  • Detecção não supervisionada
  • Um modelo por série
  • Alertas em tempo real
  • API endurecida
Meu papelDesenvolvimento ponta a ponta: API, modelo, tempo real e painel
Tecnologias utilizadas
  • FastAPI
  • scikit-learn
  • SQLAlchemy
  • PostgreSQL
  • WebSocket
  • React
  • D3.js
  • Mais 1 tecnologia

Repositório privado; referência auditada na branch main, commit 67fd464, com CI verde.

Código-fonte privadoAs evidências técnicas verificáveis estão documentadas neste case.
Página inicial do Radar operacional: filtros de fonte, métrica e janela, indicadores e gráfico de uma série temporal simulada.
DETECCAO-DE-ANOMALIAS-OPERACIONAIS.VERCEL.APP / PÁGINA INICIAL

Resumo

Resumo

Desvios em métricas operacionais costumam ser notados tarde, por alguém olhando dashboards. Este radar treina um Isolation Forest para cada fonte e métrica, normaliza o score entre 0 e 1 e, acima de 0,85, grava a anomalia e avisa o painel por WebSocket.

Problema

Limiares fixos por métrica geram alarmes falsos quando as séries têm escalas e ruídos diferentes, e revisar dashboards à mão não escala.

Meu papel

Projeto individual: ingestão, modelo, persistência, tempo real, segurança da API, painel e testes.

Funções de teste no backend
86
Repositório privado / contagem de def test_ em backend/tests / commit 67fd464
Cobertura mínima exigida
80%
Repositório privado / backend/pytest.ini, CI verde / commit 67fd464
Pontos na janela do modelo
200
Repositório privado / configuração em backend/app/core/config.py / commit 67fd464

Dados e premissas

A API recebe métricas por REST em lotes de até 500. Na publicação, a API não responde e o painel gera uma série simulada para a interface nunca ficar vazia.

Janela do modelo
200 pontos
Mínimo para pontuar
50 pontos
Limiar de anomalia
0,85
Chaves em cache
1.000 (LRU)
Estrutura dos dados

Entidades modeladas

  • Métrica (fonte, nome, valor, horário)
  • Anomalia (score, modelo, horário)

Arquitetura

Dois serviços na mesma origem da Vercel: a API em /api/* e o painel no restante.

  1. Ingestão

    Rota REST autenticada que processa o lote em thread pool.

  2. Detecção

    Isolation Forest por chave fonte:métrica, com score normalizado.

  3. Persistência

    SQLAlchemy sobre PostgreSQL para métricas e anomalias.

  4. Tempo real

    Fan-out por WebSocket, com token como subprotocolo.

  5. Painel

    React com D3: série, pontos anômalos, feed e reconexão com backoff.

Indicadores do modelo

O que o radar calcula para cada ponto recebido.

DefiniçãoUnidadeRegra de cálculoUsoLimitação
Score de anomaliaQuão isolado o ponto está na janela recente da série.0 a 1Score do Isolation Forest normalizado por min-max na janela de treino, com corte entre 0 e 1.Decidir se o ponto vira anomalia.Valores fora da faixa de treino saturam em 1.
LimiarCorte único acima do qual o ponto é anomalia.scoreConstante de configuração: 0,85.Gravar a anomalia e enviar o alerta.Não se adapta à sazonalidade da série.

Score de anomalia

Quão isolado o ponto está na janela recente da série.

Unidade
0 a 1
Regra de cálculo
Score do Isolation Forest normalizado por min-max na janela de treino, com corte entre 0 e 1.
Uso
Decidir se o ponto vira anomalia.
Limitação
Valores fora da faixa de treino saturam em 1.

Limiar

Corte único acima do qual o ponto é anomalia.

Unidade
score
Regra de cálculo
Constante de configuração: 0,85.
Uso
Gravar a anomalia e enviar o alerta.
Limitação
Não se adapta à sazonalidade da série.

Decisões técnicas

Isolation Forest univariado por métrica

Motivo
Um modelo simples por série, sem dados rotulados.
Consequência / trade-off
Perde sazonalidade e contexto entre métricas; só pontua depois de 50 pontos.

Normalização min-max com corte

Motivo
Permite um limiar único para todas as séries.
Consequência / trade-off
O modelo treina uma vez por chave; só retreina pelo endpoint /train.

Estratégia híbrida pelo maior score

Motivo
Combina autoencoder e Isolation Forest quando o TensorFlow está instalado.
Consequência / trade-off
O autoencoder vem desligado; na prática a detecção é só o Isolation Forest.
Outras decisões técnicas

Cache LRU de 1.000 chaves

Motivo
As chaves vêm do cliente; a memória precisa de limite.
Consequência / trade-off
Uma chave expulsa perde o estado do modelo.

Fail-fast de segurança

Motivo
A API se recusa a iniciar em produção com segredos fracos.
Consequência / trade-off
Sem as variáveis certas, a publicação responde 500, como hoje.

Evidências

Aplicação verificada sem login; caminhos de código conferidos no repositório privado, commit 67fd464.

Aplicação pública

Painel publicado

Interface com indicadores, feed e gráfico; mostra série simulada enquanto a API está fora.

Abrir evidência

Referência de código

Modelo por métrica

Janela, mínimo, treino e normalização do score.

Referência de códigobackend/app/ml_models/isolation_forest.py

Referência de código

Ingestão e alerta

Grava a métrica, pontua, grava a anomalia e faz o broadcast.

Referência de códigobackend/app/services/ingestion.py

Referência de código

WebSocket do painel

Recebe os alertas e reconecta com backoff exponencial.

Referência de códigofrontend/src/hooks/useOperationalStream.ts

Referências de implementação

Referência de código

Endurecimento

JWT, rate limit, limite de corpo e recusa com segredos fracos.

Referência de códigobackend/app/core/config.py

Código-fonte privado

Repositório privado

Código-fonte privado; a aplicação publicada é a evidência pública.

Medidas de engenharia

medido
86
Testes no backend
Contagem de funções de teste; 52 delas de segurança.
configuração
80%
Cobertura exigida pelo pytest
Configuração em backend/pytest.ini, com CI verde.
configuração
500
Métricas por lote
Limite da rota de ingestão.

O projeto não tem resultado operacional: não há dataset rotulado nem cliente. As medidas abaixo são de engenharia.

Repositório privado, commit 67fd464.

O que o projeto demonstra

  • Detecção de anomalias explicável.
  • API assíncrona com proteções reais.
  • Alertas em tempo real por WebSocket.
  • Visualização de séries em D3.

Limitações e próximos passos

Limitações

  • A API publicada responde HTTP 500; o painel mostra dados simulados.
  • Sem dataset rotulado, precisão e recall não são medidos.
  • As hypertables do TimescaleDB não são criadas; o banco funciona como PostgreSQL comum.

Próximos passos

  • Configurar o banco da publicação para a API voltar a responder.
  • Retreino automático com janela deslizante.
  • Um conjunto rotulado para medir precisão e recall.

Vídeo e mídia

Vídeo de demonstração do projeto.

Captura da página inicial publicada.

Página inicial do Radar operacional: filtros de fonte, métrica e janela, indicadores e gráfico de uma série temporal simulada.
Página inicial do Radar operacional: filtros de fonte, métrica e janela, indicadores e gráfico de uma série temporal simulada.

Detalhes técnicos opcionais

Como executar
  1. O repositório é privado; os passos abaixo valem para quem tem acesso.
  2. cp .env.example .env na raiz do projeto.
  3. docker compose up --build e abra o painel em http://localhost:5173
  4. Sem Docker: uvicorn app.main:app --reload e, no frontend, npm ci && npm run dev

Próximo projeto

Simulador de Decisão Empresarial

Simulador web que projeta lucro, caixa, risco e ponto de equilíbrio a partir de 10 alavancas de negócio, com o cálculo rodando no navegador.

Ver case completo