---
title: "Detecção de anomalia em contratos federais com FFT espectral"
description: "O Portal da Transparência tem milhões de contratos. Métodos clássicos de outlier detection se afogam em distribuições multi-modais. A FFT decompõe a série temporal em frequências — e fraude em série deixa assinatura periódica. Como o Cidadão.AI usa entropia espectral para reduzir um oceano a centenas de candidatos."
author: "Anderson Henrique"
date: "2026-05-03T16:45:00Z"
updated: "2026-05-12T16:16:39.244294Z"
category: "technical"
tags: ["anomaly-detection","fft","spectral-analysis","government-transparency","cidadao-ai","python","signal-processing"]
canonical: "https://www.ntlabs.dev/blog/fft-spectral-anomaly-government-contracts"
locale: "pt"
---

# Detecção de anomalia em contratos federais com FFT espectral

O Portal da Transparência expõe milhões de contratos federais. Encontrar superfaturamento, direcionamento ou contrato fictício nesse oceano não é problema de visualização — é problema de busca. E métodos clássicos de outlier detection falham por uma razão específica: a distribuição é multi-modal.

## Por que z-score e IQR não bastam

Pegue contratos de TI por órgão. A distribuição tem três modos óbvios: compras emergenciais (valor alto, prazo curto), licitação tradicional (valor médio, prazo longo) e dispensa por baixo valor (valor baixo, frequência alta). Um contrato emergencial de R$ 500 mil aparece como outlier num z-score global, mas é absolutamente legítimo no contexto de "emergência ambiental". Inversamente, dez contratos de R$ 50 mil distribuídos em cinco órgãos em três meses não disparam alarme nenhum em estatística pontual — mas se forem para a mesma empresa, com ciclo mensal exato, têm assinatura de esquema.

A pergunta certa não é "esse valor é alto?". É "esse padrão temporal existe naturalmente?".

## A intuição da FFT

Toda série temporal pode ser decomposta em frequências. A FFT (Fast Fourier Transform) faz isso em O(n log n). O resultado é um espectro: amplitude por frequência.

Aplicado a contratos públicos, isso responde uma pergunta operacional: existe periodicidade não explicada pela natureza do serviço?

Folha de pagamento tem periodicidade — mensal, óbvia, esperada. Material de escritório tem periodicidade — trimestral, alinhada com orçamento. Mas um contrato de "consultoria estratégica" que pulsa exatamente a cada 28 dias para a mesma empresa, em três órgãos diferentes? Isso é assinatura.

## Entropia espectral como score

A FFT entrega um vetor de amplitudes. Para transformar isso em um score acionável, calculamos a entropia de Shannon sobre o espectro normalizado:

```python
import numpy as np
from scipy.fft import fft

def spectral_entropy(series: np.ndarray) -> float:
    spectrum = np.abs(fft(series - series.mean()))[: len(series) // 2]
    if spectrum.sum() == 0:
        return 0.0
    psd = spectrum / spectrum.sum()  # normalize to probability distribution
    psd = psd[psd > 0]  # avoid log(0)
    return float(-np.sum(psd * np.log2(psd)))
```

Entropia alta = energia distribuída em muitas frequências = ruído natural, contratos legítimos com variação real. Entropia baixa = energia concentrada em poucas frequências = padrão periódico forte = candidato a anomalia.

O limiar não é universal. Para folha de pagamento, entropia baixa é o esperado. Para contratos de consultoria, é red flag. O agente carrega uma tabela de baselines por CNAE/natureza de despesa e compara contra ela.

## Em produção, no Cidadão.AI

O agente Zumbi (homenagem ao Zumbi dos Palmares) consome séries temporais por (órgão, empresa, categoria) extraídas das APIs federais. Para cada série com pelo menos 12 pontos, calcula entropia espectral, normaliza pelo baseline da categoria, e atribui um score de 0 a 1.

Top-K resultados (tipicamente top 100 por dia) entram numa fila de revisão. Não é detecção autônoma — é redução de busca. Um auditor humano que antes precisaria varrer 50 mil contratos por mês olha agora para 100 priorizados por assinatura espectral.

## Os falsos positivos que importam

Dois cuidados reduziram drasticamente o ruído inicial:

1. **Whitelist de naturezas sazonais.** Folha (sempre periódica), aluguel (sempre periódico), energia elétrica (sempre periódica). O baseline desses CNAEs já espera entropia baixa. Não é sinal.

2. **Janela mínima.** Séries com menos de 12 contratos têm FFT instável. O agente ignora histórico curto e espera mais dados. Isso reduz alarme em fornecedores novos, que tinham 80% dos falsos positivos.

## O que não tentamos resolver

A análise espectral encontra padrão periódico, não causalidade. Um contrato pode ter assinatura de fraude e ser legítimo — o cliente é um restaurante universitário que compra ingredientes em ciclo de cardápio fixo. A decisão final é humana, com contexto. O sistema é filtro, não juiz.

E há classes inteiras de fraude que essa abordagem não pega: contratos únicos de alto valor (precisa de outras heurísticas), fracionamento em órgãos distintos sem periodicidade (precisa de análise de grafo), conluio horizontal entre empresas (precisa de análise de rede). FFT espectral é uma lâmina específica para um corte específico.

## Por que vale a pena

A detecção de fraude em escala não é problema de modelo único. É um pipeline de filtros sucessivos, cada um descartando uma classe diferente de "isso é normal". A entropia espectral é o filtro que reduz padrão temporal a um número. O número não é a resposta — é a porta de entrada para a próxima pergunta.
