Algoritmo simples para detecção on-line de uma série temporal genérica

88

Estou trabalhando com uma grande quantidade de séries temporais. Essas séries temporais são basicamente medidas de rede que ocorrem a cada 10 minutos, e algumas são periódicas (ou seja, a largura de banda), enquanto outras não são (ou seja, a quantidade de tráfego de roteamento).

Eu gostaria de um algoritmo simples para fazer uma "detecção de outlier" on-line. Basicamente, quero manter na memória (ou em disco) todos os dados históricos de cada série temporal e quero detectar qualquer erro externo em um cenário ativo (cada vez que uma nova amostra é capturada). Qual é a melhor maneira de alcançar esses resultados?

Atualmente, estou usando uma média móvel para remover algum ruído, mas e depois? Coisas simples, como desvio padrão, louco, ... contra todo o conjunto de dados não funcionam bem (não posso assumir que as séries temporais sejam estacionárias) e gostaria de algo mais "preciso", idealmente uma caixa preta como:

double outlier_detection (vetor duplo *, valor duplo);

em que vetor é a matriz double que contém os dados históricos e o valor de retorno é a pontuação de anomalia para o novo "valor" da amostra.

gianluca
fonte
1
Apenas para fins de esclarecimento, aqui vai a pergunta original no SO: stackoverflow.com/questions/3390458/...
Matt Parker
1
Acho que devemos incentivar os pôsteres a postar links como parte da pergunta, se eles postaram a mesma pergunta em outro site da SE.
Sim, você está completamente certo. Na próxima vez mencionarei que a mensagem está cruzada.
Gianluca
Eu também sugiro que você verifique os outros links relacionados no lado direito da página. Essa é uma pergunta popular e surgiu em uma variedade de perguntas anteriormente. Se eles não forem satisfatórios, é melhor atualizar sua pergunta sobre os detalhes da sua situação.
Andy W
Boa captura, @ Andy! Vamos fundir esta pergunta com a outra.
whuber

Respostas:

75

Aqui está uma função R simples que encontrará discrepantes de séries temporais (e, opcionalmente, mostra-os em um gráfico). Ele lidará com séries temporais sazonais e não sazonais. A idéia básica é encontrar estimativas robustas da tendência e dos componentes sazonais e subtraí-los. Em seguida, encontre valores discrepantes nos resíduos. O teste para outliers residuais é o mesmo que para o boxplot padrão - pontos superiores a 1,5IQR acima ou abaixo dos quartis superior e inferior são considerados outliers. O número de IQRs acima / abaixo desses limites é retornado como uma "pontuação" externa. Portanto, a pontuação pode ser qualquer número positivo e será zero para não-discrepantes.

Sei que você não está implementando isso em R, mas geralmente acho uma função R um bom lugar para começar. A tarefa é traduzir isso para qualquer idioma necessário.

tsoutliers <- function(x,plot=FALSE)
{
    x <- as.ts(x)
    if(frequency(x)>1)
        resid <- stl(x,s.window="periodic",robust=TRUE)$time.series[,3]
    else
    {
        tt <- 1:length(x)
        resid <- residuals(loess(x ~ tt))
    }
    resid.q <- quantile(resid,prob=c(0.25,0.75))
    iqr <- diff(resid.q)
    limits <- resid.q + 1.5*iqr*c(-1,1)
    score <- abs(pmin((resid-limits[1])/iqr,0) + pmax((resid - limits[2])/iqr,0))
    if(plot)
    {
        plot(x)
        x2 <- ts(rep(NA,length(x)))
        x2[score>0] <- x[score>0]
        tsp(x2) <- tsp(x)
        points(x2,pch=19,col="red")
        return(invisible(score))
    }
    else
        return(score)
}
Rob Hyndman
fonte
+1 de mim, excelente. Então> 1,5 X intervalo interquartil é a definição consensual de um outlier para séries dependentes do tempo? Seria bom ter uma referência independente de escala.
doug
O teste outlier é sobre os resíduos, portanto, espero que a dependência do tempo seja pequena. Não sei quanto a um consenso, mas os boxplots geralmente são usados ​​para detecção externa e parecem funcionar razoavelmente bem. Existem métodos melhores se alguém quiser tornar a função um pouco mais sofisticada.
Rob Hyndman
Muito obrigado por sua ajuda, eu realmente aprecio. Estou bastante ocupado no trabalho agora, mas testarei uma abordagem como a sua assim que possível e voltarei com minhas considerações finais sobre esse problema. Um único pensamento: em sua função, pelo que vejo, preciso especificar manualmente a frequência da série temporal (ao construí-la), e o componente de sazonalidade é considerado apenas quando a frequência é maior que 1. Existe uma maneira robusta lidar com isso automaticamente?
Gianluca
1
Sim, assumi que a frequência é conhecida e especificada. Existem métodos para estimar a frequência automaticamente, mas isso complicaria consideravelmente a função. Se precisar estimar a frequência, tente fazer uma pergunta separada sobre isso - e provavelmente fornecerei uma resposta! Mas ele precisa de mais espaço do que eu tenho disponível em um comentário.
Rob Hyndman
2
@ Marcin, eu recomendo dar uma facada nele mesmo. Talvez cole sua solução em gist.github.com e poste uma pergunta SO quando terminar, para que outras pessoas verifiquem seu trabalho?
Ken Williams
27

Uma boa solução terá vários ingredientes, incluindo:

  • Use uma janela resistente e em movimento suave para remover a não estacionaridade.

  • Expresse novamente os dados originais para que os resíduos com relação ao liso sejam distribuídos aproximadamente simetricamente. Dada a natureza dos seus dados, é provável que suas raízes quadradas ou logaritmos gerem resíduos simétricos.

  • Aplique os métodos do gráfico de controle, ou pelo menos o pensamento do gráfico de controle, aos resíduos.

Quanto ao último, o pensamento da carta de controle mostra que os limites "convencionais", como 2 SD ou 1,5 vezes o IQR além dos quartis, funcionam mal porque desencadeiam muitos sinais falsos fora de controle. As pessoas costumam usar 3 DP no trabalho da carta de controle, sendo 2,5 (ou até 3) vezes o IQR além dos quartis seria um bom ponto de partida.

Descrevi mais ou menos a natureza da solução de Rob Hyndman, acrescentando a ela dois pontos principais: a necessidade potencial de reexprimir os dados e a sabedoria de ser mais conservador ao sinalizar valores extremos. Não tenho certeza se Loess é bom para um detector on-line, porque não funciona bem nos terminais. Em vez disso, você pode usar algo tão simples quanto um filtro mediano em movimento (como na suavização resistente de Tukey). Se os outliers não aparecerem em rajadas, você poderá usar uma janela estreita (5 pontos de dados, talvez, que serão quebrados apenas com uma explosão de 3 ou mais outliers em um grupo de 5).

Depois de realizar a análise para determinar uma boa reexpressão dos dados, é improvável que você precise alterar a reexpressão. Portanto, o seu detector on-line realmente precisa apenas fazer referência aos valores mais recentes (a janela mais recente) porque não usará os dados anteriores. Se você tem realmente séries temporais muito longas, analise a autocorrelação e a sazonalidade (como flutuações diárias ou semanais recorrentes) para melhorar o procedimento.

whuber
fonte
3
Esta é uma resposta extraordinária para análise prática. Nunca teria pensado necessário experimentar 3 IQR além dos quartis.
9263 John Robertson
3
@John, 1,5 IQR é a recomendação original de Tukey para os bigodes mais longos em um boxplot e 3 IQR é sua recomendação para marcar pontos como "distantes" (um riff na frase popular dos anos 60). Isso é incorporado a muitos algoritmos de boxplot. A recomendação é analisada teoricamente em Hoaglin, Mosteller e Tukey, Entendendo a análise de dados robusta e exploratória.
whuber
Isso confirma os dados de séries temporais que tenho tentado analisar. Média da janela e também desvios padrão da janela. ((x - avg) / sd)> 3 parecem ser os pontos que eu quero sinalizar como outliers. Bem, pelo menos avisar como outliers, sinalizo algo maior que 10 sd como outliers de erro extremo. O problema que encontro é qual é o tamanho ideal da janela? Estou jogando com qualquer coisa entre 4-8 pontos de dados.
Josh Peak
1
@Neo Sua melhor aposta pode ser experimentar um subconjunto de seus dados e confirmar suas conclusões com testes nos demais. Você também pode realizar uma validação cruzada mais formal (mas é necessário cuidado especial com os dados das séries temporais devido à interdependência de todos os valores).
whuber
17

(Esta resposta respondeu a uma pergunta duplicada (agora fechada) em Detectando eventos pendentes , que apresentou alguns dados em forma gráfica.)


A detecção de outlier depende da natureza dos dados e do que você deseja assumir sobre eles. Métodos de uso geral confiam em estatísticas robustas. O espírito dessa abordagem é caracterizar a maior parte dos dados de uma maneira que não seja influenciada por discrepantes e, em seguida, apontar para quaisquer valores individuais que não se encaixam nessa caracterização.

Por se tratar de uma série temporal, ela acrescenta a complicação de precisar (re) detectar outliers continuamente. Se isso for feito à medida que a série se desenrola, temos permissão apenas para usar dados mais antigos para a detecção, não dados futuros! Além disso, como proteção contra muitos testes repetidos, gostaríamos de usar um método com uma taxa de falsos positivos muito baixa.

Essas considerações sugerem a execução de um teste externo simples e robusto da janela móvel sobre os dados . Existem muitas possibilidades, mas uma simples, fácil de entender e facilmente implementada é baseada em um MAD: desvio absoluto médio da mediana. Essa é uma medida de variação fortemente robusta dentro dos dados, semelhante a um desvio padrão. Um pico externo seria vários MADs ou mais maior que a mediana.

Ainda há alguns ajustes a serem feitos : quanto de um desvio em relação à maior parte dos dados deve ser considerado distante e a que distância do tempo se deve olhar? Vamos deixá-los como parâmetros para experimentação. Aqui está uma Rimplementação aplicada aos dados (com para emular os dados) com os valores correspondentes :n = 1150 yx=(1,2,,n)n=1150y

# Parameters to tune to the circumstances:
window <- 30
threshold <- 5

# An upper threshold ("ut") calculation based on the MAD:
library(zoo) # rollapply()
ut <- function(x) {m = median(x); median(x) + threshold * median(abs(x - m))}
z <- rollapply(zoo(y), window, ut, align="right")
z <- c(rep(z[1], window-1), z) # Use z[1] throughout the initial period
outliers <- y > z

# Graph the data, show the ut() cutoffs, and mark the outliers:
plot(x, y, type="l", lwd=2, col="#E00000", ylim=c(0, 20000))
lines(x, z, col="Gray")
points(x[outliers], y[outliers], pch=19)

Aplicado a um conjunto de dados como a curva vermelha ilustrada na pergunta, ele produz este resultado:

Enredo

Os dados são mostrados em vermelho, a janela de 30 dias dos limiares medianos + 5 * MAD em cinza e os valores extremos - que são simplesmente aqueles valores acima da curva cinza - em preto.

(O limite só pode ser calculado a partir do final da janela inicial. Para todos os dados nessa janela inicial, o primeiro limite é usado: é por isso que a curva cinza é plana entre x = 0 ex = 30).

Os efeitos da alteração dos parâmetros são (a) aumentar o valor de windowtenderá a suavizar a curva cinza e (b) aumentar thresholdaumentará a curva cinza. Sabendo disso, pode-se pegar um segmento inicial dos dados e identificar rapidamente os valores dos parâmetros que melhor segregam os picos externos do restante dos dados. Aplique esses valores de parâmetro para verificar o restante dos dados. Se um gráfico mostrar que o método está piorando com o tempo, isso significa que a natureza dos dados está mudando e os parâmetros podem precisar de um novo ajuste.

Observe o quão pouco esse método assume sobre os dados: eles não precisam ser normalmente distribuídos; eles não precisam exibir periodicidade; eles nem precisam ser negativos. Tudo pressupõe que os dados se comportam de maneiras razoavelmente semelhantes ao longo do tempo e que os picos externos são visivelmente mais altos que o restante dos dados.


Se alguém quiser experimentar (ou comparar alguma outra solução à oferecida aqui), eis o código que usei para produzir dados como os mostrados na pergunta.

n.length <- 1150
cycle.a <- 11
cycle.b <- 365/12
amp.a <- 800
amp.b <- 8000

set.seed(17)
x <- 1:n.length
baseline <- (1/2) * amp.a * (1 + sin(x * 2*pi / cycle.a)) * rgamma(n.length, 40, scale=1/40)
peaks <- rbinom(n.length, 1,  exp(2*(-1 + sin(((1 + x/2)^(1/5) / (1 + n.length/2)^(1/5))*x * 2*pi / cycle.b))*cycle.b))
y <- peaks * rgamma(n.length, 20, scale=amp.b/20) + baseline
whuber
fonte
Essa é uma solução realmente interessante e eu aprecio poder implementá-la sem usar o R ​​(apenas usando JavaScript simples em um aplicativo da web). Obrigado!
hgoebl
15

Se você está preocupado com suposições com qualquer abordagem específica, uma abordagem é treinar vários alunos em sinais diferentes, use métodos de conjunto e agregue os "votos" de seus alunos para fazer a classificação externa.

BTW, isso pode valer a pena ser lido ou lido, pois faz referência a algumas abordagens do problema.

ars
fonte
5

Suponho que o modelo sofisticado de séries temporais não funcione para você por causa do tempo necessário para detectar discrepâncias usando essa metodologia. Portanto, aqui está uma solução alternativa:

  1. Primeiro, estabeleça padrões de tráfego 'normais' de linha de base para um ano com base na análise manual de dados históricos, que representam a hora do dia, o dia da semana versus o final de semana, o mês do ano etc.

  2. Use esta linha de base juntamente com algum mecanismo simples (por exemplo, média móvel sugerida por Carlos) para detectar valores extremos.

Você também pode revisar a literatura de controle estatístico de processos para obter algumas idéias.


fonte
1
Sim, é exatamente isso que estou fazendo: até agora, divido manualmente o sinal em períodos, para que, para cada um deles, eu possa definir um intervalo de confiança dentro do qual o sinal deve ser estacionário e, portanto, posso usar métodos padrão como como desvio padrão, ... O verdadeiro problema é que não consigo decidir o padrão esperado para todos os sinais que tenho que analisar, e é por isso que estou procurando algo mais inteligente.
Gianluca
Aqui está uma idéia: Etapa 1: implemente e estime um modelo genérico de séries temporais com base em dados históricos. Isso pode ser feito offline. Etapa 2: use o modelo resultante para detectar valores discrepantes. Etapa 3: em alguma frequência (talvez todos os meses?), Recalibre o modelo de série temporal (isso pode ser feito offline) para que a detecção de outliers da etapa 2 não fique muito fora de sintonia com os padrões de tráfego atuais. Isso funcionaria para o seu contexto?
Sim, isso pode funcionar. Eu estava pensando em uma abordagem semelhante (recalculando a linha de base toda semana, o que pode exigir muita CPU, se você tiver centenas de séries temporais univariadas para analisar). Aliás, a verdadeira questão difícil é "qual é o melhor algoritmo no estilo blackbox para modelar um sinal completamente genérico, considerando ruído, estimativa de tendência e sazonalidade?". AFAIK, toda abordagem na literatura requer uma fase realmente difícil de "ajuste de parâmetros", e o único método automático que encontrei é um modelo ARIMA da Hyndman ( robjhyndman.com/software/forecast ). Estou esquecendo de algo?
Gianluca
Lembre-se de que não tenho preguiça de investigar esses parâmetros, o ponto é que esses valores precisam ser definidos de acordo com o padrão esperado do sinal e, no meu cenário, não posso fazer nenhuma suposição.
Gianluca
Os modelos ARIMA são modelos clássicos de séries temporais que podem ser usados ​​para ajustar dados de séries temporais. Gostaria de encorajá-lo a explorar a aplicação dos modelos ARIMA. Você pode esperar que Rob esteja on-line e talvez ele tenha algumas idéias.
5

Ajuste os dados sazonalmente para que um dia normal pareça mais plano. Você pode coletar a amostra das 17:00 de hoje e subtrair ou dividir a média dos 30 dias anteriores às 17:00. Em seguida, procure N desvios padrão (medidos usando dados pré-ajustados) em busca de outliers. Isso pode ser feito separadamente para as "estações" semanais e diárias.

James Roth
fonte
Novamente, isso funciona muito bem se o sinal tiver uma sazonalidade assim, mas se eu usar uma série temporal completamente diferente (ou seja, o tempo médio de ida e volta do TCP ao longo do tempo), esse método não funcionará (pois seria melhor para lidar com aquele com uma média global simples e desvio padrão usando uma janela deslizante contendo dados históricos).
Gianluca
1
A menos que você esteja disposto a implementar um modelo geral de séries temporais (que traz seus contras em termos de latência, etc.), sou pessimista quanto a encontrar uma implementação geral que, ao mesmo tempo, seja simples o suficiente para trabalhar para todos os tipos de séries temporais.
Outro comentário: eu sei que uma boa resposta pode ser "para que você possa estimar a periodicidade do sinal e decidir o algoritmo a ser usado de acordo com ele", mas não encontrei uma solução realmente boa para esse outro problema. bit com análise espectral usando DFT e análise de tempo usando a função de autocorrelação, mas meu séries temporais contêm uma grande quantidade de ruído e tais métodos dar alguns resultados mosts loucos da época)
Gianluca
Um comentário ao seu último comentário: é por isso que estou procurando uma abordagem mais genérica, mas preciso de um tipo de "caixa preta" porque não posso fazer nenhuma suposição sobre o sinal analisado e, portanto, não consigo criar o "melhor conjunto de parâmetros para o algoritmo de aprendizado".
Gianluca
@gianluca Como você sugeriu, a estrutura ARIMA subjacente pode mascarar a anomalia. Formulação incorreta, se possível, variáveis ​​de causa como hora do dia, dia da semana, efeitos de férias etc. também podem mascarar a anomalia. A resposta é bastante clara: você precisa ter uma boa ação para detectar efetivamente anomalias. Para citar Bacon, "Para quem conhece os caminhos da natureza, mais facilmente notará seus desvios e, por outro lado, quem conhece seus desvios descreverá com mais precisão seus caminhos".
precisa saber é o seguinte
3

Uma alternativa à abordagem descrita por Rob Hyndman seria usar a Holt-Winters Forecasting . As faixas de confiança derivadas de Holt-Winters podem ser usadas para detectar discrepâncias. Aqui está um artigo que descreve como usar Holt-Winters para "Detecção de comportamento aberrante em séries temporais para monitoramento de rede". Uma implementação para o RRDTool pode ser encontrada aqui .

Peter Prettenhofer
fonte
2

A análise espectral detecta periodicidade em séries temporais estacionárias. A abordagem no domínio da frequência baseada na estimativa da densidade espectral é uma abordagem que eu recomendaria como seu primeiro passo.

Se durante certos períodos a irregularidade significa um pico muito mais alto do que o normal para esse período, as séries com tais irregularidades não seriam estacionárias e a anlise espectral não seria apropriada. Mas, supondo que você tenha identificado o período que apresenta as irregularidades, você poderá determinar aproximadamente qual seria a altura normal do pico e, em seguida, poderá definir um limite em algum nível acima dessa média para designar os casos irregulares.

Michael Chernick
fonte
2
Você poderia explicar como essa solução detectaria "irregularidades locais"? Apresentar um exemplo trabalhado seria extremamente útil. (Para ser sincero, estou sugerindo que você faça isso porque, ao realizar um exercício como esse, acredito que você descobrirá que sua sugestão não é eficaz para a detecção de erros
extremos
1
@whuber A análise espectral apenas identificará onde estão todos os picos. O próximo passo seria ajustar um modelo de série yime usando termos seno e cosseno com as frequências determinadas a partir da análise espectral e as amplitudes estimadas a partir dos dados. Se irregularidades significam picos com amplitudes muito altas, acho que um limite na amplitude seria apropriado. Se irregularidades locais significam que por um período a amplitude algumas vezes é significativamente maior que outras, a série não é estacionária e a análise espectral não seria apropriada.
Michael Chernick
1
Não sigo a conclusão sobre falta de estacionariedade. Por exemplo, a soma de uma forma de onda sinusoidal regular e um processo pontual de ponto de Poisson seria estacionária, mas não exibia a periodicidade que você procura. No entanto, você encontrará alguns picos fortes no periodograma, mas eles não diriam nada relevante para os picos de dados irregulares introduzidos pelo componente do processo de Poisson.
whuber
1
Uma série temporal estacionária tem uma média constante. Se o pico de um componente periódico puder mudar ao longo do tempo, ele pode reduzir a média de alterações ao longo do tempo e, portanto, os servidores seriam não estacionários.
Michael Chernick
2

Como se trata de dados de séries temporais, um simples filtro exponencial http://en.wikipedia.org/wiki/Exponential_smoothing suavizará os dados. É um filtro muito bom, pois você não precisa acumular pontos de dados antigos. Compare cada valor de dados recém- suavizado com seu valor não suavizado . Depois que o desvio exceder um determinado limite predefinido (dependendo do que você acredita que seja um erro de informação), ele pode ser facilmente detectado.

No IC, faça o seguinte para uma amostra de 16 bits em tempo real (acredito que isso seja encontrado em algum lugar aqui <Explicação - https://dsp.stackexchange.com/questions/378/what-is-the-best-first-order -iir-aproximação-para-um-filtro-de-média-móvel >)

#define BITS2 2     //< This is roughly = log2( 1 / alpha ), depending on how smooth you want your data to be

short Simple_Exp_Filter(int new_sample) 
{static int filtered_sample = 0;
long local_sample = sample << 16; /*We assume it is a 16 bit sample */
filtered_sample += (local_sample - filtered_sample) >> BITS2;   
return (short) ((filtered_sample+0x8000) >> 16); //< Round by adding .5 and truncating.   
}


int main()
{
newly_arrived = function_receive_new_sample();
filtered_sample = Simple_Exp_Filter(newly_arrived);
if (abs(newly_arrived - filtered_sample)/newly_arrived > THRESHOLD)
    {
    //AN OUTLIER HAS BEEN FOUND
    }
 return 0;   
}
AyodeleO
fonte
1

Você pode usar o desvio padrão das últimas N medidas (você precisa escolher um N adequado). Uma boa pontuação de anomalia seria quantos desvios padrão uma medida é da média móvel.

Carlos Accioly
fonte
Obrigado pela sua resposta, mas e se o sinal exibir uma alta sazonalidade (ou seja, muitas medições de rede são caracterizadas por um padrão diário e semanal ao mesmo tempo, por exemplo, noite versus dia ou fim de semana versus dias úteis)? Uma abordagem baseada no desvio padrão não funcionará nesse caso.
Gianluca
Por exemplo, se eu receber uma nova amostra a cada 10 minutos e estiver fazendo uma detecção externa do uso da largura de banda da rede de uma empresa, basicamente às 18h, essa medida cairá (esse é um padrão totalmente normal esperado) e um desvio padrão calculado sobre uma janela deslizante falhará (porque disparará um alerta com certeza). Ao mesmo tempo, se a medida cair às 16h (divergindo da linha de base usual), isso é realmente muito estranho.
Gianluca
1

o que faço é agrupar as medidas por hora e dia da semana e comparar os desvios padrão disso. Ainda não corrige coisas como feriados e sazonalidade de verão / inverno, mas é correta na maioria das vezes.

A desvantagem é que você realmente precisa coletar um ano ou mais de dados para ter o suficiente para que o stddev comece a fazer sentido.

Aleksandar Ivanisevic
fonte
Obrigado, é exatamente isso que eu estava tentando evitar (tendo muitas amostras como linha de base), porque gostaria de uma abordagem realmente reativa (por exemplo, detecção on-line, talvez "suja", após 1-2 semanas da linha de base)
gianluca
0

Sugiro o esquema abaixo, que deve ser implementado em um dia ou mais:

Treinamento

  • Colete o maior número possível de amostras na memória
  • Remova discrepantes óbvios usando o desvio padrão para cada atributo
  • Calcular e armazenar a matriz de correlação e também a média de cada atributo
  • Calcule e armazene as distâncias de Mahalanobis de todas as suas amostras

Cálculo de "outicidade":

Para a amostra única da qual você deseja conhecer sua "aparência extravagante":

  • Recuperar as médias, matriz de covariância e distância s de Mahalanobis do treinamento
  • Calcule a distância de Mahalanobis "d" para sua amostra
  • Retorne o percentil em que "d" cai (usando as distâncias de Mahalanobis do treinamento)

Essa será sua pontuação outlier: 100% é uma outlier extrema.


PS. Ao calcular a distância de Mahalanobis , use a matriz de correlação, não a matriz de covariância. Isso é mais robusto se as medições da amostra variarem em unidade e número.

Ytsen de Boer
fonte
0

No caso em que é preciso calcular os valores discrepantes rapidamente, pode-se usar a ideia de Rob Hyndman e Mahito Sugiyama ( https://github.com/BorgwardtLab/sampling-outlier-detection , library (spoutlier), função qsp) para calcular os valores extremos da seguinte forma:

library(spoutlier)
rapidtsoutliers <- function(x,plot=FALSE,seed=123)
{
    set.seed(seed)
    x <- as.numeric(x)
    tt <- 1:length(x)
    qspscore <- qsp(x)
    limit <- quantile(qspscore,prob=c(0.95))
    score <- pmax((qspscore - limit),0)
    if(plot)
    {
        plot(x,type="l")
        x2 <- ts(rep(NA,length(x)))
        x2[score>0] <- x[score>0]
        tsp(x2) <- tsp(x)
        points(x2,pch=19,col="red")
        return(invisible(score))
    }
    else
        return(score)
}
orgesleka
fonte
0

A detecção de anomalias requer a construção de uma equação que descreva a expectativa. A detecção de intervenção está disponível em um cenário não causal e causal. Se alguém tem uma série de preditores como preço, as coisas podem ficar um pouco complicadas. Outras respostas aqui não parecem levar em consideração a causa atribuível atribuível a séries de preditores especificadas pelo usuário, como preço, e, portanto, podem ter falhas. A quantidade vendida pode depender do preço, talvez preços anteriores e talvez quantidade vendida no passado. A base para a detecção de anomalias (pulsos, pulsos sazonais, mudanças de nível e tendências da hora local) encontra-se em https://pdfs.semanticscholar.org/09c4/ba8dd3cc88289caf18d71e8985bdd11ad21c.pdf

IrishStat
fonte
O link não está funcionando, você pode corrigi-lo. Graças
Pankaj Joshi
feito ..................
IrishStat