Rilevamento delle modifiche nelle serie temporali (esempio R)


18

Vorrei rilevare i cambiamenti nei dati delle serie temporali, che di solito hanno la stessa forma. Finora ho lavorato con il changepointpacchetto per R e le funzioni cpt.mean(), cpt.var()e cpt.meanvar(). cpt.mean()con il metodo PELT funziona bene quando i dati di solito rimangono su un livello. Tuttavia, vorrei anche rilevare i cambiamenti durante le discese. Un esempio di cambiamento, vorrei rilevare, è la sezione in cui la curva nera cade improvvisamente mentre in realtà dovrebbe seguire la linea tratteggiata rossa di esempio. Ho sperimentato la funzione cpt.var (), tuttavia non sono riuscito a ottenere buoni risultati. Hai qualche consiglio (quelli non devono necessariamente usare R)?

Cambia curva

Ecco i dati con la modifica (come oggetto 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)

Nota che se stai solo chiedendo il codice R, sarebbe fuori tema qui. Se stai chiedendo una consulenza metodologica generale, va bene. Potrebbe venire con un po 'di codice R, ma poi potrebbe non esserlo.
gung - Ripristina Monica

1
Buona osservazione, sono interessato a una soluzione generale, l'uso di R sarebbe semplicemente conveniente.
sveglia il

Risposte:


17

È possibile utilizzare il rilevamento dei valori anomali delle serie temporali per rilevare i cambiamenti nelle serie temporali. Le procedure di Tsay o Chen e Liu sono popolari metodi di rilevamento anomalo delle serie storiche. Vedi la mia domanda precedente su questo sito.

Il pacchetto tsoutlier di R utilizza il metodo di Chen e Liu per il rilevamento di valori anomali. Anche SAS / SPSS / Autobox possono farlo. Vedi sotto per il codice R per rilevare i cambiamenti nelle serie temporali.

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

La funzione tso nel pacchetto tsoultlier identifica i seguenti valori anomali. Puoi leggere la documentazione per scoprire il tipo di valori anomali.

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

il pacchetto fornisce anche belle trame. vedi sotto. La trama mostra dove sono gli outlier e anche cosa sarebbe successo se non ci fossero outlier.

inserisci qui la descrizione dell'immagine

Ho anche usato il pacchetto R chiamato strucchange per rilevare i cambiamenti di livello. Ad esempio sui tuoi dati

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

Il programma identifica correttamente i punti di interruzione o i cambiamenti strutturali.

Optimal 4-segment partition: 

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

Breakpoints at observation number:
17 41 87 

Corresponding to breakdates:
17 41 87 

Spero che sia di aiuto


1
Grazie, tsofunziona bene, tuttavia è un po 'lento per set di dati più grandi. Le posizioni di breakpoint di struccchange sembrano un po 'arbitrarie (tranne la posizione 41).
Mlee

7

Affronterei questo problema dalle seguenti prospettive . Queste sono solo alcune idee sulla cima della mia testa - per favore prendile con un granello di sale. Tuttavia, spero che questo sia utile.

  • Cluster di serie storiche . Ad esempio, utilizzando il popolare dinamismo dinamico (DTW) o approcci alternativi. Si prega di consultare le mie risposte correlate: su DTW per classificazione / clustering e su DTW o alternative per serie temporali irregolari . L' idea è di raggruppare le serie temporali in categorie "normali" e "anormali" (o simili).

  • Misure di entropia . Vedi la mia risposta pertinente sulle misure entropiche delle serie storiche . L' idea è quella di determinare l'entropia di una serie temporale "normale" e quindi confrontarla con altre serie temporali (questa idea presuppone una deviazione entropica in caso di deviazione dalla "normalità").

  • Rilevazione di anomalie . Vedi la mia risposta pertinente sul rilevamento di anomalie (include risorse R). L' idea è di rilevare direttamente le anomalie tramite vari metodi (consultare i riferimenti). La cassetta degli attrezzi e il Rpacchetto di segnali di allarme precoce (EWS)earlywarnings sembrano particolarmente promettenti.


6

La mia risposta con AUTOBOX è abbastanza simile a @forecaster ma con un modello molto più semplice. Box, Einstein e altri hanno riflettuto sul mantenimento di soluzioni semplici ma non troppo semplici. Il modello che è stato sviluppato automaticamente è stato inserisci qui la descrizione dell'immagine. La trama attuale e pulita è molto simile inserisci qui la descrizione dell'immagine. Un diagramma dei residui (che dovrebbe essere sempre mostrato) è qui inserisci qui la descrizione dell'immagineinsieme all'acf obbligatorio dei residui inserisci qui la descrizione dell'immagine. Le statistiche dei residui sono sempre utili per fare confronti tra "modelli di duello" inserisci qui la descrizione dell'immagine. Il grafico Attuale / Adatta / Previsione è quiinserisci qui la descrizione dell'immagine


1

Sembrerebbe che il tuo problema sarebbe notevolmente semplificato se danneggiassi i tuoi dati. Sembra diminuire linearmente. Una volta detratti i dati, è possibile applicare una vasta gamma di test per non stazionarietà.


3
Questo approccio fallirà perché ci sono piste chiaramente diverse nella storia. A meno che non si incorporino più "tendenze / pendenze" questo approccio non produrrà risultati significativi. Le semplici soluzioni semplici sono spesso troppo semplici.
IrishStat,

1

Tutte ottime risposte, ma qui è semplice, come suggerito da @MrMeritology, che sembra funzionare bene per le serie storiche in questione e probabilmente per molti altri set di dati "simili".

Ecco un frammento di R che produce i grafici autoesplicativi di seguito.

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")

inserisci qui la descrizione dell'immagine inserisci qui la descrizione dell'immagine inserisci qui la descrizione dell'immagine


ci possono essere più cambiamenti di tendenza e più cambiamenti di intercettazione (cambiamenti di livello) ... quindi è necessario trovare soluzioni che effettivamente diagnosticano i dati per determinarli ...
IrishStat

Sì, in effetti, ho letto il tuo commento precedente sopra. Tuttavia, diagnosticare le serie temporali per rilevare più tendenze / livelli è un problema in sé. Il mio punto qui è mostrare che l'approccio semplice sopra descritto funziona a volte, in particolare per i dati dati. Al contrario, nessun approccio singolo funzionerà sempre bene. Un approccio di R.Hyndman (tsoutlier con funzione R) è qualcosa che altrimenti consiglierei.
dnqxt,

AUTOBOX è il singolo approccio che funzionerà sempre bene (almeno per i miliardi di serie storiche che abbiamo visto) e c'è una versione R. Se desideri chattare offline perché non voglio arrivare a "commesso" qui posso spiegare il processo che è completamente comprensibile / trasparente ma non facilmente duplicabile.
IrishStat
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.