Detecção de anomalia — Parte 1: O que é e como utilizar em dados unidimensionais não rotulados com métodos estatísticos e PyOD
Técnica de aprendizado de máquina não supervisionado, muito usada em mineração de dados para identificar padrões fora do comum. Essa publicação é a primeira de uma série sobre o assunto, nela veremos o que é detecção de anomalias, quais as aplicações em negócios e como utilizá-la com dados unidimensionais em python, usando métodos estatísticos e PyOD. Não deixe de acompanhar, também, o próximo post da série.
O que é detecção de anomalia
A detecção de anomalia é uma técnica que envolve a identificação de dados que se desviam significativamente do comportamento esperado ou padrão, aqueles considerados anômalos. Ela distingue os dados em duas categorias: inliers, ou o que consideramos pontos de dados normais, e outliers, que são observações raras que diferem estatisticamente e parecem inconsistentes do restante dos dados.
Essa identificação é realizada sem usar dados como exemplo para treinamento rotulado. Por isso, a detecção de anomalia se enquadra na categoria mais ampla de aprendizado de máquina não supervisionado. Aprender sem supervisão parece mais difícil, mas às vezes é a única abordagem prática. Por exemplo, se uma das duas classes for muito rara, o aprendizado supervisionado não funcionará muito bem e serão necessárias alternativas para contornar essa condição, como a preparação de dados desbalanceados abordada nesse outro post. Além disso, se houver a possibilidade de mudança rápida no conjunto de dados, é muito improvável que os exemplos passados representem o futuro. Deste modo, procurar padrões “anormais” com metodologia não supervisionada é uma estratégia melhor.
Casos de uso
A detecção de anomalias tem aplicações em muitos setores, como segurança cibernética, encontrando vazamentos e ataques de segurança, medicina — detecção de tumores ou células cancerígenas, e finanças e serviços bancários, como detecção de fraudes. Em casos de uso como esses, as técnicas de detecção de anomalias podem ser usadas para investigar se valores extremos afetam negativamente análises e modelos estatísticos. Além de permitir uma ação rápida e adequada para mitigar riscos ou tomar decisões informadas.
Como aplicar detecção de anomalia
Existem várias abordagens para a detecção de anomalia, incluindo métodos estatísticos, algoritmos de aprendizado supervisionado e não supervisionado, técnicas de processamento de sinais e abordagens baseadas em regras. De modo geral, vamos sempre iniciar a exploração com as estatísticas descritivas do conjunto observado. A depender do caso, podemos nos deparar com dados unidimensionais ou multidimensionais:
Dados unidimensionais
Para detectar valores discrepantes em dados unidimensionais, ou univariados, podemos utilizar:
- Média e variância: São duas das estatísticas resumidas mais comuns, por isso é importante avaliar como elas estão sendo afetadas pelos valores discrepantes. Isso pode ser feito comparando seus valores no conjunto de dados com e sem os outliers.
- Histogramas: Representam graficamente a distribuição dos dados, mostrando como os valores estão distribuídos ao longo de diferentes intervalos o(bins). Uma sugestão prática a ser usada para o número de bins é a raiz quadrada do número de observações, conforme trecho abaixo.
# EXEMPLO DE HISTOGRAMA EM PYTHON USANDO MATPLOTLIB
# Encontrar a raiz quadrada do comprimento de vendas
n_bins = np.sqrt(len(vendas))
# Converter para um número inteiro
n_bins = int(n_bins)
# Gerar o gráfico
plt.figure(figsize=(8, 4))
plt.hist(vendas, bins=n_bins, color='red')
- Dispersão: Usando um gráfico de dispersão, podemos dar continuidade aos insights do histograma. Como na Figura 1, onde podemos ver o intervalo em que os pontos de dados normais se encontram e também identificar os valores discrepantes como o pontos mais altos do gráfico.
- Boxplot: Mostra a alocação dos registros dentro de cada percentil, além de possuir um par de bigodes abaixo e acima da caixa que indicam os limites inferior e superior dos valores discrepantes na distribuição (Figura 2).
- Intervalo Interquartil — IQR: Os comprimentos desses limites dependem do IQR (onde IQR = Q1 - Q3), juntamente com um fator de multiplicação (geralmente, é usado 1,5). Portanto: o limite inferior = Q1 - (1,5 * IQR), enquanto o limite superior = Q3 + (1,5 * IQR). Os pontos de dados que estão fora dos limites serão marcados como valores discrepantes.
- Z-Score: O escore z de uma amostra, que foi extraída de uma distribuição normal, nos diz quantos desvios padrão a amostra está longe da média. A ideia de usar o z-score para detecção de outliers vem da regra empírica da estatística. A regra empírica diz que a porcentagem de valores que estão dentro de 1, 2, e 3 desvios padrão da média, os quais são 68, 95 e 99.7%, respectivamente. Valores fora da faixa de 3 desvios padrão são considerados discrepantes. Porém, lembre-se: só é apropriado quando os dados provêm de uma distribuição normal. Além disso, cuidado: z-score se baseia em métricas que são influenciadas por outliers. Sua eficácia será prejudicada se houver muitos valores discrepantes nos dados, pois distorcerão a média e o desvio padrão. Em python, podemos usar o pacote zscore da biblioteca scipy.stats. Com o trecho de código, abaixo, aplicado a minha variável de exemplo, obtive o valor de 90. Ou seja, existem 90 registros de vendas que são outliers, pois estão acima de 3 desvios padrão distante da média.
from scipy.stats import zscore
scores = zscore(vendas)
acima_de_3 = np.abs(scores) > 3
outliers = vendas[acima_de_3]
print(len(outliers))
- Desvio absoluto mediano — MAD: Outra alternativa é o z-score modificado. Nos bastidores, ele usa uma pontuação chamada MAD, que é mais resistente a valores discrepantes, pois usa a mediana. Então, em vez de perguntar “Quantos desvios padrão estão longe da média?”, perguntamos: “Quantos desvios absolutos medianos estão longe da mediana?”. Para obter o MAD em python, usamos o pacote Python Outlier Detection (PyOD), uma biblioteca popular de detecção de anomalias que inclui mais de 40 algoritmos implementados com sintaxe semelhante ao sklearn.
Exemplo: Importamos pyod.models.mad e o inicializamos com um limite padrão e recomendado de 3.5, esse limite é o z-score modificado. O estimador calcula a pontuação MAD e marcará como outlier quaisquer pontos além desse limite. Em seguida, convertemos a coluna de vendas em um array NumPy e a remodelamos em um array 2D, que, como o scikit-learn, é exigido por todos os modelos no pyod. Em seguida, o fit_predict gera rótulos para vendas_reformed: retorna 0 para inliers e 1 para outliers. Nesse caso, usando z-score modificado, encontrei o total de 83 outliers (invés dos 90 anteriores) e podemos confiar que esse resultado é mais robusto.
from pyod.models.mad import MAD
# threshold é o z-score modificado, por padrão aqui é 3.5
mad = MAD(threshold=3.5)
# aplicar reshape em vendas
vendas_reshaped = vendas.values.reshape(-1, 1)
labels = mad.fit_predict(vendas_reshaped)
print(labels.sum())
Dados multivariadas
Definimos outliers multivariados como pontos de dados com dois ou mais atributos, que quando examinados individualmente não são, necessariamente, anômalos, mas são diferentes dos demais quando todos os seus atributos são considerados ao mesmo tempo.
E esse será o tema da parte 2 dessa série, que contará com mais técnicas como floresta de isolamento — um classificador de outliers baseado em árvore, e também explorará detectores baseados em distância e densidade: KNN e Local Outlier Factor. Até a próxima!
Referências e publicações recomendadas: