Interpolieren fehlende Werte in einer Zeitreihe mit saisonalen Zyklus
Ich habe eine Zeitreihe, für die ich möchte, um intelligent die fehlenden Werte interpolieren. Der Wert zu einem bestimmten Zeitpunkt beeinflusst wird durch ein multi-Tag-trend, sowie seine position in der täglichen Zyklus.
Hier ist ein Beispiel, in dem der zehnte Beobachtung fehlt myzoo
start <- as.POSIXct("2010-01-01")
freq <- as.difftime(6, units = "hours")
dayvals <- (1:4)*10
timevals <- c(3, 1, 2, 4)
index <- seq(from = start, by = freq, length.out = 16)
obs <- (rep(dayvals, each = 4) + rep(timevals, times = 4))
myzoo <- zoo(obs, index)
myzoo[10] <- NA
Wenn ich hatte, um dies zu implementieren, ich würde verwenden eine gewichtete Mittelwert der in der Nähe mal auf der nahe gelegenen Tage, oder fügen Sie einen Wert für die Tag-Funktion Zeile eingebaut, um die größeren Trends, aber ich hoffe, es existieren bereits einige Paket oder Funktionen, die auf diese situation anzuwenden?
BEARBEITEN: Verändert den code etwas zu klären, mein problem. Es gibt na.*
Methoden, interpolieren von nächsten Nachbarn, aber in diesem Fall Sie nicht erkennen, dass der missing-Wert ist an der Zeit, das ist der niedrigste Wert des Tages. Vielleicht ist die Lösung zur Umgestaltung der Daten im wide format und dann interpolieren, aber ich möchte nicht völlig außer acht lassen die zusammenhängenden Werte vom selben Tag. Es ist erwähnenswert, dass diff(myzoo, lag = 4)
wird ein Vektor von 10. Die Lösung liegen kann, mit einer Kombination von reshape
, na.spline
, und diff.inv
, aber ich kann es einfach nicht herausfinden.
Hier sind drei Ansätze, die nicht funktionieren:
EDIT2. Erzeugte Bild mit dem folgenden code.
myzoo <- zoo(obs, index)
myzoo[10] <- NA # knock out the missing point
plot(myzoo, type="o", pch=16) # plot solid line
points(na.approx(myzoo)[10], col = "red")
points(na.locf(myzoo)[10], col = "blue")
points(na.spline(myzoo)[10], col = "green")
myzoo[10] <- 31 # replace the missing point
lines(myzoo, type = "o", lty=3, pch=16) # dashed line over the gap
legend(x = "topleft",
legend = c("na.spline", "na.locf", "na.approx"),
col=c("green","blue","red"), pch = 1)
- Dieser code wird nicht ausgeführt. index und obs nicht definiert sind.
na.approx
,na.spline
,na.locf
und anderena.*
Funktionen in der zoo-Paket können füllen SieNA
Werte. - Danke, ist eingefügt der richtige block.
- Zeig bitte den code, den Sie zum erstellen der Handlung und erklären, was "funktionieren nicht" bedeutet.
- Grothendieck: Diese drei Interpolationsmethoden nicht funktionieren, weil Sie nur auf die Nachbarn in der Zeitreihe, ohne Rücksicht auf die täglichen Muster.
Du musst angemeldet sein, um einen Kommentar abzugeben.
Versuchen Sie dies:
Die Idee ist es, eine grundlegende Struktur-Modell für die Zeitreihe, die Griffe der fehlende Wert gut mit einem Kalman-filter. Dann ein Kalman-glatt verwendet wird, um zu schätzen, jeden einzelnen Punkt in der Zeit-Serie, einschließlich weggelassen.
Musste ich konvertieren Sie Ihre zoo-Objekt zu einem ts-Objekt mit der Frequenz 4 um StructTS. Ändern Sie ggf. die Einbauküche Werte zurück zu zoo wieder.
fit
ist ziemlich weit Weg (von .85), und die Summe von (x-fit)^2 ~0.96. Aber, wenn Sie ersetzen Sie das x mitx <- ts(rev(myzoo), f = 4)
die Passform perfekt wird. Keine Ahnung, was passiert ist?zoo::na.StructTS
Funktion führt Linien 2-3 leichter:fit2 <- na.StructTS(x)
erstellt eine Reihe identischx
mit NA gefüllt, die über die saisonalen Kalman-filter (30.66, denselben Wert wiefit
in dieser Antwort).In diesem Fall, ich denke, Sie wollen eine Saisonalität Korrektur in das ARIMA-Modell. Es gibt nicht genug hier, um zu passen das saisonale Modell, aber das sollte Ihnen den Einstieg.
In meinen tests hat das ARMA(3, 3) ist sehr eng, aber das ist einfach nur Glück. Mit einer längeren Zeitreihen sollten Sie in der Lage zu Kalibrieren, die saisonale Korrektur, um Ihnen gute Vorhersagen. Es wäre hilfreich, um einen gut vor auf das, was die zugrunde liegenden Mechanismen sowohl das signal und die saisonale Korrektur zu bekommen bessere out-of-sample-performance.
points(na.locf(myzoo)[10], col = "blue")
?points.zoo
).forecast::na.interp
ist ein guter Ansatz. Aus der DokumentationDieses Papier wertet verschiedene Interpolationsmethoden gegen Echtzeit-Serie, und findet, dass
na.interp
ist sowohl präzise und effizient:Ist auch erwähnenswert, dass Rob Hyndman, schrieb die
forecast
Paket, und enthaltenna.interp
nach Abgabe seiner Antwort auf diese Frage. Es ist wahrscheinlich, dassna.interp
ist eine Verbesserung auf diesem Ansatz, auch wenn es schlechter in diesem Fall (wahrscheinlich durch die Angabe der Periode, inStructTS
, wona.interp
zahlen Sie es aus).