Erkennen von Änderungen in Zeitreihen (R-Beispiel)


18

Ich möchte Änderungen in Zeitreihendaten erkennen, die normalerweise die gleiche Form haben. Bisher habe ich mit dem changepointPaket für R und den Funktionen cpt.mean(), cpt.var()und gearbeitet cpt.meanvar(). cpt.mean()mit der PELT-Methode funktioniert gut, wenn die Daten normalerweise auf einer Ebene bleiben. Änderungen möchte ich aber auch bei Abfahrten feststellen. Ein Beispiel für eine Änderung ist der Abschnitt, in dem die schwarze Kurve plötzlich abfällt, während sie eigentlich der beispielhaften rot gepunkteten Linie folgen sollte. Ich habe mit der Funktion cpt.var () experimentiert, konnte jedoch keine guten Ergebnisse erzielen. Haben Sie Empfehlungen (diese müssen nicht unbedingt R verwenden)?

Kurve ändern

Hier sind die Daten mit der Änderung (als R-Objekt):

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)

Beachten Sie, dass dies hier nicht zum Thema gehört, wenn Sie nur nach R-Code fragen. Wenn Sie nach allgemeinen methodischen Ratschlägen fragen, ist das in Ordnung. Es könnte mit einem R-Code kommen, aber vielleicht auch nicht.
gung - Reinstate Monica

1
Gute Anmerkung, ich interessiere mich für eine allgemeine Lösung, mit R wäre nur praktisch.
Mlee

Antworten:


17

Mithilfe der Ausreißererkennung für Zeitreihen können Sie Änderungen in Zeitreihen erkennen. Tsays oder Chens und Lius Verfahren sind beliebte Methoden zur Erkennung von Zeitreihenausreißern. Siehe meine frühere Frage auf dieser Seite.

Das tsoutlier- Paket von R verwendet Chens und Lius Methode zur Erkennung von Ausreißern. SAS / SPSS / Autobox kann dies auch. Im Folgenden finden Sie den R-Code zum Erkennen von Änderungen in Zeitreihen.

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

Diese Funktion in diesem Paket identifiziert folgende Ausreißer. Sie können die Dokumentation lesen, um die Art der Ausreißer herauszufinden.

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

Das Paket bietet auch schöne Grundstücke. siehe unten. Die Grafik zeigt, wo die Ausreißer sind und was passiert wäre, wenn es keine Ausreißer gegeben hätte.

Bildbeschreibung hier eingeben

Ich habe auch das R-Paket strucchange verwendet , um Pegelverschiebungen zu erkennen. Als Beispiel für Ihre Daten

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

Das Programm erkennt Haltepunkte oder strukturelle Änderungen korrekt.

Optimal 4-segment partition: 

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

Breakpoints at observation number:
17 41 87 

Corresponding to breakdates:
17 41 87 

Hoffe das hilft


1
Vielen Dank, tsofunktioniert gut, ist jedoch bei größeren Datenmengen etwas langsam. Die Haltepunktpositionen von struccchange scheinen ein wenig willkürlich zu sein (außer Position 41).
Mlee

7

Ich würde mich diesem Problem aus folgenden Perspektiven nähern . Dies sind nur ein paar Ideen aus meinem Kopf - bitte nehmen Sie sie mit einem Körnchen Salz. Trotzdem hoffe ich, dass dies nützlich sein wird.

  • Zeitreihen-Clustering . Zum Beispiel durch die Verwendung von populärem Dynamic Time Warping (DTW) oder alternativen Ansätzen. Bitte beachten Sie meine verwandten Antworten: zur DTW für Klassifizierung / Clustering und zur DTW oder zu Alternativen für ungerade Zeitreihen . Die Idee ist, Zeitreihen in Kategorien "normal" und "abnormal" (oder ähnlich) zu gruppieren.

  • Entropiemaßnahmen . Siehe meine relevante Antwort zu Zeitreihen-Entropiemaßnahmen . Die Idee ist, die Entropie einer "normalen" Zeitreihe zu bestimmen und sie dann mit anderen Zeitreihen zu vergleichen (diese Idee geht von einer Entropieabweichung im Falle einer Abweichung von der "Normalität" aus).

  • Erkennung von Anomalien . Siehe meine relevante Antwort zur Erkennung von Anomalien (einschließlich R-Ressourcen). Die Idee ist, Anomalien direkt über verschiedene Methoden zu erkennen (siehe Referenzen). Besonders vielversprechend erscheinen die Toolbox und das RPaket für Frühwarnsignale (EWS)earlywarnings .


6

Meine Antwort mit AUTOBOX ist @forecaster ziemlich ähnlich, aber mit einem viel einfacheren Modell. Box und Einstein und andere haben darüber nachgedacht, Lösungen einfach, aber nicht zu einfach zu halten. Das Modell, das automatisch entwickelt wurde, war Bildbeschreibung hier eingeben. Die tatsächliche und gereinigte Handlung ist sehr ähnlich Bildbeschreibung hier eingeben. Eine Darstellung der Residuen (die immer angezeigt werden sollte) ist hier Bildbeschreibung hier eingebenzusammen mit der obligatorischen ACF der Residuen Bildbeschreibung hier eingeben. Die Statistiken der Residuen sind immer nützlich, um Vergleiche zwischen "Duellmodellen" anzustellen Bildbeschreibung hier eingeben. Das Diagramm "Ist / Fit / Prognose" befindet sich hierBildbeschreibung hier eingeben


1

Es scheint, dass sich Ihr Problem stark vereinfacht, wenn Sie Ihre Daten beschädigen. Es scheint linear abzunehmen. Sobald Sie die Daten gelöscht haben, können Sie eine Vielzahl von Tests auf Nichtstationarität anwenden.


3
Dieser Ansatz wird scheitern, weil es in der Geschichte deutlich unterschiedliche Steigungen gibt. Wenn Sie nicht mehrere "Trends / Steigungen" einbeziehen, werden mit diesem Ansatz keine aussagekräftigen Ergebnisse erzielt. Einfache, unkomplizierte Lösungen sind oft einfach zu einfach.
IrishStat

1

Alles gute Antworten, aber hier ist eine einfache, wie von @MrMeritology vorgeschlagen, die für die fraglichen Zeitreihen und wahrscheinlich für viele andere "ähnliche" Datensätze gut zu funktionieren scheint.

Hier ist ein R-Snippet, aus dem die folgenden selbsterklärenden Grafiken hervorgehen.

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

Bildbeschreibung hier eingeben Bildbeschreibung hier eingeben Bildbeschreibung hier eingeben


Es kann mehrere Trendänderungen und mehrere Intercept-Änderungen (Pegelverschiebungen) geben ... daher muss man Lösungen finden, die die Daten tatsächlich diagnostizieren, um diese zu bestimmen ...
IrishStat

Ja, in der Tat habe ich Ihren vorherigen Kommentar oben gelesen. Die Diagnose der Zeitreihen zur Erkennung mehrerer Trends / Ebenen ist jedoch ein Problem für sich. Ich möchte hier zeigen, dass der obige einfache Ansatz manchmal funktioniert, insbesondere für die angegebenen Daten. Umgekehrt wird kein einzelner Ansatz immer gut funktionieren. Ein Ansatz von R.Hyndman (R-function tsoutliers) würde ich ansonsten empfehlen.
Donnerstag,

AUTOBOX ist der einzige Ansatz, der immer gut funktioniert (zumindest für die zig Millionen von Zeitreihen, die wir gesehen haben), und es gibt eine R-Version. Wenn Sie offline chatten möchten, da ich hier nicht zu "salesy" kommen möchte, kann ich den Vorgang erklären, der vollständig verständlich / transparent ist, aber nicht leicht zu duplizieren ist.
IrishStat
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.