Qual algoritmo devo usar para detectar anomalias em séries temporais?

70

fundo

Estou trabalhando no Network Operations Center, monitoramos os sistemas de computadores e seu desempenho. Uma das principais métricas a serem monitoradas é o número de visitantes \ clientes atualmente conectados aos nossos servidores. Para torná-lo visível, nós (equipe de operações) coletamos métricas como dados de séries temporais e desenhamos gráficos. O Grafite nos permite fazer isso, ele possui uma API bastante rica que eu uso para criar um sistema de alerta para notificar nossa equipe se quedas repentinas (principalmente) e outras alterações ocorrerem. Por enquanto, eu configurei um limite estático com base no valor médio, mas não funciona muito bem (há muitos falsos positivos) devido à carga diferente durante o dia e a semana (fator de sazonalidade).

Parece algo como isto: um número de usuários por sistema

Os dados reais (um exemplo para uma métrica, intervalo de 15 minutos; o primeiro número é um número de usuários, o segundo registro de data e hora):

[{"target": "metric_name", "datapoints": [[175562.0, 1431803460], [176125.0, 1431803520], [176125.0, 1431803580], [175710.0, 1431803640], [175710.0, 1431803700], [175733.0, 1431803760], [175733.0, 1431803820], [175839.0, 1431803880], [175839.0, 1431803940], [175245.0, 1431804000], [175217.0, 1431804060], [175629.0, 1431804120], [175104.0, 1431804180], [175104.0, 1431804240], [175505.0, 1431804300]]}]

O que estou tentando realizar

Criei um script Python que recebe pontos de dados recentes, os compara com a média histórica e alerta se houver uma mudança ou queda repentina. Devido à sazonalidade, o limite "estático" não funciona bem e o script gera alertas de falsos positivos. Quero melhorar um algoritmo de alerta para ser mais preciso e fazê-lo funcionar sem ajustar constantemente o limite de alerta.

Que conselhos eu preciso e coisas que descobri

Ao pesquisar no Google, percebi que estava procurando algoritmos de aprendizado de máquina para detecção de anomalias (não supervisionados). Uma investigação mais aprofundada mostrou que existem muitos deles e é muito difícil entender qual deles é aplicável no meu caso. Devido ao meu conhecimento limitado de matemática, não consigo ler trabalhos acadêmicos sofisticados e estou procurando algo simples para um iniciante no campo.

Eu gosto de Python e estou familiarizado com R, por isso ficarei feliz em ver exemplos para essas linguagens. Por favor, recomende um bom livro ou artigo que me ajude a resolver meu problema. Obrigado pelo seu tempo e com licença para uma descrição tão longa

Links Úteis

Perguntas semelhantes:

Fontes externas:

Ilya Khadykin
fonte
11
Você deu uma olhada em um dos algoritmos mais simples como o CUSUM?
Vladislavs Dovgalecs
@xeon, ainda não. Eu sou novo no assunto e preciso de algum tempo para digerir tudo. Obrigado por trazer isso, é um bom ponto de partida, eu posso implementá-lo agora
Ilya Khadykin
11
Essa é uma ótima pergunta, @ ma-ge. Eu tenho um cenário semelhante. Minha abordagem foi configurar alertas criando previsões periódicas contínuas usando a auto.arimafunção do excelente forecastpacote de R (consulte jstatsoft.org/v27/i03/paper ). Você pode ajustar os níveis de confiança ajustando o levelparâmetro, por exemplo data.model <- auto.arima(data.zoo, ic = c("bic")); data.prediction.warningLimits <- forecast(data.model, h=1, level=0.99).
Alex Woolford
3
Caras do Twitter escreveram artigos muito interessantes sobre esse assunto. Confira: blog.twitter.com/2015/…
ognjenz
Hey @IlyaKhadykin Espero que você esteja bem! você já teve alguma solução para esse problema? Estou fazendo algo exatamente igual em que a cada minuto estamos tendo certos usuários e também recebemos muitos falsos positivos. A partir de agora, estamos calculando a pontuação para cada 5 minutos de dados do intervalo e combinando-os com o padrão histórico. SE VOCÊ TIVER ALGORITMO ESPECÍFICO, PODE COMPARTILHAR COMO VOCÊ O FAZ. Desde já, obrigado!
ak3191 4/10

Respostas:

24

Eu acho que a chave é um qualificador "inesperado" no seu gráfico. Para detectar o inesperado, você precisa ter uma idéia do que é esperado .

yt=c+ϕyt1+Φ24yt24+Φ25yt25+εttet=yty^t é "muito grande", você lança um alerta.

σεεt|et|<3σεet>3σε

O número de visitantes é provavelmente bastante persistente, mas super sazonal. Talvez funcione melhor para tentar manequins sazonais em vez da sazonalidade multiplicativa; tente o ARMAX, onde X representa variáveis ​​exógenas, que podem ser algo como manequim de férias, manequins de hora, manequins de fim de semana etc.

Aksakal
fonte
5
Essa abordagem pressupõe um modelo ARIMA específico que terá parâmetros tendenciosos com base nas anomalias que foram implicitamente assumidas como inexistentes. Uma abordagem mais geral seria também identificar primeiro as anomalias e, em seguida, um modelo ARIMA ideal, levando a testes de significância em linha. Adicionalmente, as anomalias podem ser mudanças de nível, pulsos sazonais e tendências da hora local, que exigem uma solução mais geral do que a proposta aqui. Veja unc.edu/~jbhill/tsay.pdf para obter um procedimento abrangente. Você também pode procurar no Google "Detecção automática de intervenção" para obter mais informações.
IrishStat
@IrishStat, sugeri o ARIMAX com manequins para eventos. O OP pode dar conta de eventos conhecidos, como falhas no site com manequins. Isso diminuirá a variação do erro e haverá mais alertas. Não há razão para criar o modelo complicado, porque é simplesmente impossível dar conta de tudo quando se trata do tráfego de sites. Os modelos simples funcionarão melhor.
Aksakal
2
@ ma-ge, mais uma coisa: você pode querer usar intervalos sobrepostos. Digamos que você colete dados a cada minuto, mas para modelar você pode escolher uma etapa em 10 minutos. Isso cria alguns problemas para a estimativa (devido à autocorrelação), mas o modelo resultante provavelmente será mais robusto.
Aksakal
Os modelos do @Aksakal devem ser tão simples quanto necessário, mas não muito simples.
IrishStat
17

No blog de tecnologia da Netflix, há um artigo sobre sua ferramenta de detecção robusta de anomalias (RAD). http://techblog.netflix.com/2015/02/rad-outlier-detection-on-big-data.html

Ele lida com a sazonalidade e com conjuntos de dados de volume muito alto, para que possa atender às suas necessidades. O código é de código aberto Java e Apache Pig https://github.com/Netflix/Surus/blob/master/resources/examples/pig/rad.pig

O algoritmo subjacente é baseado em PCA robusto - veja o artigo original aqui: http://statweb.stanford.edu/~candes/papers/RobustPCA.pdf

Paul McGettigan
fonte
12

A maioria dos algoritmos de detecção outlier no pacote de código aberto é para dados de séries temporais de negócios com dados de frequência baixa, diária / semanal / mensal de baixa frequência. Esses dados parecem pertencer a uma área especializada que é capturada em minutos, portanto, não tenho certeza se a detecção de outlier de código aberto seria útil. Você pode tentar adaptar essas abordagens aos seus dados.

Abaixo, descrevo algumas abordagens de pacotes disponíveis em código aberto R:

  1. tsoutliers : implementa o algoritmo de detecção de outlier de Chen e Liu na estrutura arima. veja minha pergunta anterior neste site. Abordagem fantástica, mas muito lenta, não tenho certeza se será capaz de lidar com dados de alta frequência como o seu. Ele tem a vantagem de detectar todos os tipos de discrepâncias, como mencionado na minha pergunta / publicação anterior.
  2. Detecção de anomalias no Twitter : usa o algoritmo de Rosner para detectar anomalias com base em séries temporais. O algoritmo decompõe séries temporais e, em seguida, detecta anomalias. Na minha opinião pessoal, isso não é eficiente e preciso na detecção de bandidos em séries temporais.
  3. tsoutlier no pacote de previsão: semelhante ao algoritmo do twitter em termos de decomposição de séries temporais e detecção de outliers. Somente detectará discrepâncias ou pulsos aditivos.

Existem pacotes comerciais que têm abordagens dedicadas para tentar detectar anomolias. Outra abordagem clássica é o algoritmo de detecção de outlier de séries temporais de Tsay , semelhante à abordagem de Chen e Liu, que detecta diferentes tipos de outliers. Recentemente, também deparei com essa solução de software comercial chamada metafor, que pode ser mais adequada para seus dados.

Espero que isso seja útil

previsor
fonte
Obrigado, me dá uma perspectiva sobre problemas e abordagens semelhantes; agradecimentos especiais pelos links!
Ilya Khadykin
Se alguém está procurando pelo Metafor, fomos adquiridos pelo Splunk. Nossos algoritmos TSAD estão incluídos nas versões recentes do Splunk IT Service Intelligence ("ITSI").
Alex Cruise
5

m

L(m,τ1:m,θ1:(m+1))=i=1m+1p(y(τi1+1):τiθi)

y1,,yn1<τ1<<τm<npθiimchangepoint pacote para R. Se você quiser saber mais, pode verificar as seguintes publicações e as referências que elas fornecem:

Rebecca Killick e Idris A. Eckley. (2013) ponto de mudança: um pacote R para análise de ponto de mudança. (artigo online)

Eckley, IA, Fearnhead, P. e Killick, R. (2011) Análise de modelos de ponto de mudança. [in:] Bayesian Time Series Models , eds. D. Barber, AT Cemgil e S. Chiappa, Cambridge University Press.

Tim
fonte
4

Você já tentou usar as regras de controle estatístico de processos (por exemplo, Western Electric http://en.wikipedia.org/wiki/Western_Electric_rules )?

Eu os uso para dados de séries temporais - geralmente com um toque de intuição sobre os dados - para avaliar se os dados estão indo para algum lugar que eu não quero que vá. Como no seu exemplo, essas regras dizem que se o delta / alteração for consistente em vários pontos de dados, sinaliza que pode haver um problema.

Além disso, o Controle Estatístico de Processo (CEP) pode ser bom para trabalhar se você estiver melhorando ou piorando do que antes.

Um problema com o SPC é que grande parte dele depende de uma distribuição normal que provavelmente não se adequa aos seus dados e que não pode ficar abaixo de zero. Outros melhores do que eu no SPC podem sugerir opções aqui. Gosto de usá-lo para sinalizar um problema, mas, como todos os modelos, é melhor usado com um pouco de conhecimento sobre os próprios dados (e origem).

MarkR
fonte
4

Dado que a periodicidade das séries temporais deve ser bem entendida, um algoritmo simples, mas eficaz, baseado na diferenciação pode ser desenvolvido.

Uma diferenciação simples de uma etapa detectará uma queda repentina de um valor anterior

yt=ytyt1

mas se a série tiver um forte componente periódico, você esperaria que essa queda fosse considerável regularmente. Nesse caso, seria melhor comparar qualquer valor com sua contraparte no mesmo ponto do ciclo anterior, ou seja, um período atrás.

yt=ytytnwhere n=length of period

No caso da pergunta postada, seria natural esperar dois componentes periódicos significativos, um com duração de um dia e outro com duração de uma semana. Mas isso não é uma complicação, pois a duração do período mais longo pode ser bem dividida pela duração do período mais curto.

n247=168

Se as quedas tiverem um caráter mais proporcional, uma simples diferença falhará facilmente em detectar uma queda repentina quando a atividade estiver baixa. Em tais circunstâncias, o algoritmo pode ser modificado para calcular proporções.

yt=ytytn

Eu fiz alguns testes em R usando um conjunto de dados simulado. Nele, os dados são amostrados 6 vezes ao dia e há fortes períodos diários e semanais, juntamente com outros ruídos e flutuações. Gotas foram adicionadas em locais aleatórios e com durações entre 1 e 3.
Para isolar as quedas, as primeiras proporções foram calculadas à distância 42 e, em seguida, um limiar foi fixado em 0,6, pois apenas a alteração negativa de um determinado tamanho é interessante. Em seguida, uma diferença de uma etapa foi calculada e um limite definido em -0,5. No final, um falso positivo parece ter escapado (o do final da semana 16). Os gráficos à esquerda e à direita mostram os mesmos dados, apenas de maneiras diferentes.

insira a descrição da imagem aqui

AkselA
fonte
3

Seria mais útil pensar nas mudanças nas séries temporais como o início de uma nova tendência, em vez de uma anomalia? Tomar a diferença entre pontos adjacentes ajudaria a saber quando a inclinação (derivada) está mudando e pode sinalizar o início de uma nova tendência na data. Também pode ser útil tirar as diferenças dos valores das diferenças (a segunda derivada). Fazer uma pesquisa no Google em "início de tendência da série temporal" pode dar boas sugestões de métodos. Nos dados financeiros, é dada muita atenção às novas tendências (você compra ou vende?), Para que haja documentos sobre esse tópico.

Uma boa introdução à wavelet é "O mundo segundo as wavelets", de Hubbard, acredito ser o autor.

DavidF
fonte
2

Consegui obter bons resultados para séries temporais de várias estações do ano (diariamente, semanalmente) usando dois algoritmos diferentes:

  • Decomposição de tendências sazonais usando loess (ou STL) para estabelecer a série de pontos médios.
  • Regressão não linear para estabelecer limites em torno desse ponto médio, com base na relação entre a variação e o nível.

O STL decompõe suas séries temporais no domínio do tempo em um componente de tendência, um único componente sazonal e o restante. O componente sazonal é a sazonalidade de alta frequência (por exemplo, diariamente), enquanto a tendência inclui a sazonalidade de baixa frequência (por exemplo, semanalmente) e a tendência adequada. Você pode separar os dois simplesmente executando STL novamente na tendência. De qualquer forma, depois de isolar a série restante dos outros componentes, você poderá executar sua detecção de anomalia nessa série.

Fiz um artigo mais detalhado aqui:

https://techblog.expedia.com/2016/07/28/applying-data-science-to-monitoring/

Willie Wheeler
fonte
1

Inspirado por David, você tentou usar o FFT? Pode detectar quedas repentinas porque estão indicando suas anomalias. As anomalias podem aparecer em um espectro estreito. Então você pode capturá-los facilmente.

Romeo Kienzler
fonte