Bei der verzögerten Auswertung handelt es sich um eine Auswertungsstrategie, bei der die Auswertung eines Ausdrucks verzögert wird, bis sein Wert benötigt wird. In Kombination mit Memoisation vermeidet die Strategie der verzögerten Auswertung wiederholte Auswertungen und kann die Ausführungszeit bestimmter Funktionen erheblich verringern.
Die Zeitreihenbibliothek verwendet die verzögerte Auswertung zur Verarbeitung von Daten. Theoretisch wird ein Ausführungsdiagramm anhand von Zeitreihendaten erstellt, deren Auswertung erst ausgelöst wird, wenn ihre Ausgabe gespeichert wird. Angenommen, ein Objekt bewegt sich in einem eindimensionalen Raum, dessen Position von x(t) erfasst wird. Sie können die harte Beschleunigung/Bremsung (h(t)
) dieses Objekts anhand der Geschwindigkeitszeitreihe (v(t)
) und der Beschleunigungszeitreihe (a(t)
) wie folgt bestimmen:
# 1d location timeseries
x(t) = input location timeseries
# velocity - first derivative of x(t)
v(t) = x(t) - x(t-1)
# acceleration - second derivative of x(t)
a(t) = v(t) - v(t-1)
# harsh acceleration/braking using thresholds on acceleration
h(t) = +1 if a(t) > threshold_acceleration
= -1 if a(t) < threshold_deceleration
= 0 otherwise
Dies führt zu einem einfachen Ausführungsdiagramm der folgenden Form:
x(t) --> v(t) --> a(t) --> h(t)
Auswertungen werden nur ausgelöst, wenn eine Aktion ausgeführt wird, z. B. compute h(5...10)
, d. h. compute h(5), ..., h(10)
. Die Bibliothek erfasst enge temporale Abhängigkeiten zwischen Zeitreihen. In diesem Beispiel erfordert h(5...10)
a(5...10)
, was wiederum v(4...10)
und dann x(3...10)
erfordert. Nur die relevanten Anteile von a(t)
, v(t)
und x(t)
werden ausgewertet.
h(5...10) <-- a(5...10) <-- v(4...10) <-- x(3...10)
Darüber hinaus sind Auswertungen memorisiert und können so in nachfolgenden Aktionen für h
wiederverwendet werden. Beispiel: Wenn eine Anforderung für h(7...12)
einer Anforderung für h(5...10)
folgt, werden die memorisierten Werte h(7...10)
verwendet. Darüber hinaus würde h(11...12)
mit a(11...12), v(10...12)
und x(9...12)
ausgewertet, was wiederum memorisierten v(10)
und x(9...10)
aus der vorherigen Berechnung nutzt.
In einem allgemeineren Beispiel könnten Sie eine geglättete Geschwindigkeitszeitreihe wie folgt definieren:
# 1d location timeseries
x(t) = input location timeseries
# velocity - first derivative of x(t)
v(t) = x(t) - x(t-1)
# smoothened velocity
# alpha is the smoothing factor
# n is a smoothing history
v_smooth(t) = (v(t)*1.0 + v(t-1)*alpha + ... + v(t-n)*alpha^n) / (1 + alpha + ... + alpha^n)
# acceleration - second derivative of x(t)
a(t) = v_smooth(t) - v_smooth(t-1)
In diesem Beispiel hat h(l...u)
folgende zeitliche Abhängigkeit. Die Auswertung vonh(l...u)
würde diese zeitliche Abhängigkeit mit der Memorisierung strikt einhalten.
h(l...u) <-- a(l...u) <-- v_smooth(l-1...u) <-- v(l-n-1...u) <-- x(l-n-2...u)
Beispiel:
Das folgende Beispiel zeigt ein Python-Code-Snippet, mit dem ein abruptes Beschleunigen für eine einfache, speicherinterne Zeitreihe implementiert wird. Die Bibliothek enthält einige integrierte Transformationen. In diesem Beispiel wird die Differenztransformation zweimal auf die Positionszeitreihe angewendet, um die Beschleunigungszeitreihe zu berechnen. Eine Kartenoperation wird auf die Beschleunigungszeitreihe mit einer harten Lambda-Funktion angewendet, die nach der Codestichprobe definiert wird und die Beschleunigung entweder +1
(abruptes Beschleunigen), -1
(abruptes Bremsen) oder 0
(anderweitig) zuordnet. Die Filteroperation wählt nur Instanzen aus, in denen entweder ein abruptes Beschleunigen oder ein abruptes Bremsen beobachtet wird. Vor dem Aufruf von get_values
wird ein Ausführungsdiagramm erstellt. Es werden jedoch keine Berechnungen durchgeführt. Beim Aufruf von get_values(5, 10)
wird die Auswertung mit Memorisierung für die engste mögliche zeitliche Abhängigkeit im Ausführungsdiagramm ausgeführt.
import tspy
from tspy.builders.functions import transformers
x = tspy.time_series([1.0, 2.0, 4.0, 7.0, 11.0, 16.0, 22.0, 29.0, 28.0, 30.0, 29.0, 30.0, 30.0])
v = x.transform(transformers.difference())
a = v.transform(transformers.difference())
h = a.map(harsh).filter(lambda h: h != 0)
print(h[5, 10])
Die abrupte Lambda-Funktion wird wie folgt definiert:
def harsh(a):
threshold_acceleration = 2.0
threshold_braking = -2.0
if (a > threshold_acceleration):
return +1
elif (a < threshold_braking):
return -1
else:
return 0
Weitere Informationen
Informationen zur Verwendung von tspy
Python SDK finden Sie in der tspy
Python SDK-Dokumentation.
Übergeordnetes Thema: Zeitreihenanalyse