Detectando Alterações em Séries Temporais (Exemplo R)

18

Gostaria de detectar alterações nos dados de séries temporais, que geralmente têm a mesma forma. Até agora, trabalhei com o changepointpacote para R e as funções cpt.mean(), cpt.var()e cpt.meanvar(). cpt.mean()com o método PELT funciona bem quando os dados geralmente permanecem em um nível. No entanto, eu também gostaria de detectar alterações durante descidas. Um exemplo de alteração, eu gostaria de detectar, é a seção em que a curva preta cai repentinamente enquanto ela deve seguir a linha pontilhada vermelha do exemplo. Eu experimentei a função cpt.var (), mas não consegui bons resultados. Você tem alguma recomendação (essas não precisam necessariamente usar o R)?

Alterar curva

Aqui estão os dados com a alteração (como objeto R):

dat.change <- c(12.013995263488, 11.8460207231808, 11.2845153487846, 11.7884417180764, 
11.6865425802022, 11.4703118125303, 11.4677576899063, 11.0227199625084, 
11.274775836817, 11.03073498338, 10.7771805591742, 10.7383206158923, 
10.5847230134625, 10.2479315651441, 10.4196381241735, 10.467607842288, 
10.3682422713283, 9.7834431752935, 9.76649842404295, 9.78257968297228, 
9.87817694914062, 9.3449034905713, 9.56400153361727, 9.78120084558148, 
9.3445162813738, 9.36767436354887, 9.12070987223648, 9.21909859069157, 
8.85136359917466, 8.8814423003979, 8.61830163359642, 8.44796977628488, 
8.06957847272046, 8.37999165387824, 7.98213210294954, 8.21977468333673, 
7.683960439316, 7.73213584532496, 7.98956476021092, 7.83036046746187, 
7.64496198988985, 4.49693528397253, 6.3459274845112, 5.86993447552116, 
4.58301192892403, 5.63419551523625, 6.67847511602895, 7.2005344054883, 
5.54970477623895, 6.00011922569104, 6.882667104467, 4.74057284230894, 
6.2140437333397, 6.18511450451019, 5.83973575417525, 6.57271194428385, 
5.36261938326723, 5.48948831338016, 4.93968645996861, 4.52598133247377, 
4.56372558828803, 5.74515428123725, 5.45931581984165, 5.58701112949141, 
6.00585679276365, 5.41639695946931, 4.55361875158434, 6.23720558202826, 
6.19433060301002, 5.82989415940829, 5.69321394985076, 5.53585871082265, 
5.42684812413063, 5.80887522466946, 5.56660158483312, 5.7284521523444, 
5.25425775891636, 5.4227645808924, 5.34778016248718, 5.07084809927736, 
5.324066161355, 5.03526881241705, 5.17387528516352, 5.29864121433813, 
5.36894461582415, 5.07436929444317, 4.80619983525015, 4.42858947882894, 
4.33623051506001, 4.33481791951228, 4.38041031792294, 3.90012900415342, 
4.04262777674943, 4.34383842876647, 4.36984816425014, 4.11641092254315, 
3.83985887104645, 3.81813419810962, 3.85174630901311, 3.66434598962311, 
3.4281724860426, 2.99726515704766, 2.96694634792395, 2.94003031547181, 
3.20892607367132, 3.03980832743458, 2.85952185077593, 2.70595278908964, 
2.50931109659839, 2.1912274016859)
mlee
fonte
Observe que, se você estiver solicitando apenas o código R, isso seria fora de tópico aqui. Se você está pedindo conselhos metodológicos gerais, tudo bem. Pode vir com algum código R, mas, novamente, talvez não.
gung - Restabelece Monica
1
Boa observação, estou interessado em uma solução geral, usar R seria conveniente.
mlee 27/02

Respostas:

17

Você pode usar a detecção de outlier de séries temporais para detectar alterações nas séries temporais. Os procedimentos de Tsay ou Chen e Liu são métodos populares de detecção de séries temporais. Veja minha pergunta anterior neste site.

O pacote tsoutlier de R usa o método de Chen e Liu para detectar valores extremos. O SAS / SPSS / Autobox também pode fazer isso. Veja abaixo o código R para detectar alterações nas séries temporais.

library("tsoutliers")
dat.ts<- ts(dat.change,frequency=1)
data.ts.outliers <- tso(dat.ts)
data.ts.outliers
plot(data.ts.outliers)

A função tso no pacote tsoultlier identifica os seguintes outliers. Você pode ler a documentação para descobrir o tipo de discrepâncias.

Outliers:
  type ind time coefhat   tstat
1   TC  42   42 -2.9462 -10.068
2   AO  43   43  1.0733   4.322
3   AO  45   45 -1.2113  -4.849
4   TC  47   47  1.0143   3.387
5   AO  51   51  0.9002   3.433
6   AO  52   52 -1.3455  -5.165
7   AO  56   56  0.9074   3.710
8   LS  62   62  1.1284   3.717
9   AO  67   67 -1.3503  -5.502

o pacote também oferece ótimas parcelas. ver abaixo. A trama mostra onde estão os outliers e também o que teria acontecido se não houvesse outliers.

insira a descrição da imagem aqui

Também usei o pacote R chamado strucchange para detectar mudanças de nível. Como um exemplo nos seus dados

library("strucchange")
breakpoints(dat.ts~1)

O programa identifica corretamente pontos de interrupção ou alterações estruturais.

Optimal 4-segment partition: 

Call:
breakpoints.formula(formula = dat.ts ~ 1)

Breakpoints at observation number:
17 41 87 

Corresponding to breakdates:
17 41 87 

Espero que isto ajude

previsor
fonte
1
Obrigado, tsofunciona bem, no entanto, é um pouco lento para conjuntos de dados maiores. As posições de ponto de interrupção da mudança de estratégia parecem um pouco arbitrárias (exceto a posição 41).
quer
7

Eu abordaria esse problema das seguintes perspectivas . Estas são apenas algumas idéias que vêm da minha cabeça - leve-as com um grão de sal. No entanto, espero que isso seja útil.

  • Agrupamento de séries temporais . Por exemplo, usando o popular DTW (Dynamic Time Warping) ou abordagens alternativas. Por favor, veja minhas respostas relacionadas: no DTW para classificação / agrupamento e no DTW ou alternativas para séries temporais irregulares . A idéia é agrupar séries temporais em categorias "normal" e "anormal" (ou similar).

  • Medidas de entropia . Veja minha resposta relevante sobre medidas de entropia de séries temporais . A idéia é determinar a entropia de uma série temporal "normal" e compará-la com outras séries temporais (essa idéia pressupõe um desvio de entropia em caso de desvio da "normalidade").

  • Detecção de anomalias . Veja minha resposta relevante sobre detecção de anomalias (inclui recursos de R). A idéia é detectar diretamente anomalias através de vários métodos (consulte as referências). Caixa de ferramentas e Rpacote de sinais de alerta precoce (EWS)earlywarnings parecem especialmente promissores.

Aleksandr Blekh
fonte
6

Minha resposta usando o AUTOBOX é bastante semelhante ao @forecaster, mas com um modelo muito mais simples. Box, Einstein e outros refletiram em manter soluções simples, mas não muito simples. O modelo que foi desenvolvido automaticamente foi insira a descrição da imagem aqui. A trama atual e limpa é muito semelhante insira a descrição da imagem aqui. Um gráfico dos resíduos (que sempre deve ser mostrado) está aqui, insira a descrição da imagem aquijuntamente com a ACF obrigatória dos resíduos insira a descrição da imagem aqui. As estatísticas dos resíduos são sempre úteis para fazer comparações entre "modelos de duelo" insira a descrição da imagem aqui. O gráfico Real / Ajustado / Previsão está aquiinsira a descrição da imagem aqui

IrishStat
fonte
1

Parece que seu problema seria bastante simplificado se você prejudicasse seus dados. Parece diminuir linearmente. Depois de prejudicar os dados, você poderá aplicar uma ampla variedade de testes para não estacionariedade.

MrMeritology
fonte
3
Essa abordagem falhará porque existem claramente diferentes inclinações na história. A menos que você esteja incorporando várias "tendências / inclinações", essa abordagem não produzirá resultados significativos. Soluções simples e diretas geralmente são simples demais.
IrishStat
1

Todas as respostas são ótimas, mas aqui está uma simples, conforme sugerido pelo @MrMeritology, que parece funcionar bem para as séries temporais em questão e provavelmente para muitos outros conjuntos de dados "semelhantes".

Aqui está um trecho R produzindo os gráficos auto-explicativos abaixo.

outl = rep( NA, length(dat.change))
detr = c( 0, diff( dat.change))

ix = abs(detr) > 2*IQR( detr)
outl[ix] = dat.change[ix]

plot( dat.change, t='l', lwd=2, main="dat.change TS")
points( outl, col=2, pch=18)

plot( detr, col=4, main="detrended TS", t='l', lwd=2 )
acf( detr, main="ACF of detrended TS")

insira a descrição da imagem aqui insira a descrição da imagem aqui insira a descrição da imagem aqui

dnqxt
fonte
pode haver várias mudanças de tendência e várias alterações de interceptação (mudanças de nível) ... portanto, é necessário encontrar soluções que efetivamente diagnosticem os dados para determinar essas ...
IrishStat
Sim, de fato, eu li o seu comentário anterior acima. No entanto, diagnosticar as séries temporais para detectar várias tendências / níveis é um problema em si. Meu objetivo aqui é mostrar que a abordagem simples acima funciona algumas vezes, principalmente para os dados fornecidos. Por outro lado, nenhuma abordagem única funcionará bem sempre. Uma abordagem de R.Hyndman (tsoutliers da função R) é algo que eu recomendaria de outra forma.
dnqxt 5/03
A AUTOBOX é a única abordagem que funcionará bem sempre (pelo menos nos zilhões de séries temporais que vimos) e existe uma versão R. Se você deseja conversar off-line, já que não quero "vender" aqui, posso explicar o processo que é totalmente compreensível / transparente, mas que não é facilmente duplicado.
IrishStat 5/03