L'évaluation paresseuse est une stratégie d'évaluation qui retarde l'évaluation d'une expression jusqu'à ce que sa valeur soit nécessaire. Lorsqu'elle est associée à la mémorisation, la stratégie d'évaluation paresseuse évite les évaluations répétées et peut réduire considérablement le délai d'exécution de certaines fonctions.
La bibliothèque de séries temporelles utilise une évaluation paresseuse pour traiter les données. En théorie, un graphique d'exécution est construit sur les données de séries temporelles dont l'évaluation n'est déclenchée que si son résultat est matérialisé. Soit un objet se déplaçant dans un espace unidimensionnel dont l'emplacement est capturé par x(t). Vous pouvez déterminer l'accélération/freinage brutal (h(t)
) de cet objet en utilisant ses séries temporelles de vitesse (v(t)
) et d'accélération (a(t)
) comme suit :
# 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
Il en résulte un simple graphique d'exécution de la forme suivante :
x(t) --> v(t) --> a(t) --> h(t)
Les évaluations sont déclenchées uniquement lorsqu'une action est exécutée, par exemple compute h(5...10)
, c'est-à-dire compute h(5), ..., h(10)
. La bibliothèque capture les dépendances temporelles étroites entre les séries temporelles. Dans cet exemple, h(5...10)
requiert a(5...10)
qui nécessite v(4...10)
qui requiert x(3...10)
. Seules les parties pertinentes de a(t)
, v(t)
et x(t)
sont évaluées.
h(5...10) <-- a(5...10) <-- v(4...10) <-- x(3...10)
En outre, les évaluations sont mémorisées et peuvent donc être réutilisées dans des actions ultérieures sur h
. Par exemple, lorsqu'une demande pour h(7...12)
fait suite à une demande pour h(5...10)
, les valeurs mémorisées h(7...10)
sont utilisées. En outre, h(11...12)
est évalué en utilisant a(11...12), v(10...12)
et x(9...12)
qui utilisent à leur tour optimise v(10)
et x(9...10)
mémorisés à partir du calcul précédent.
Dans un exemple plus général, vous pouvez définir une série temporelle des vitesses lissée comme suit :
# 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)
Dans cet exemple, h(l...u)
a la dépendance temporelle suivante. L'évaluation de h(l...u)
adhère strictement à cette dépendance temporelle avec la mémorisation.
h(l...u) <-- a(l...u) <-- v_smooth(l-1...u) <-- v(l-n-1...u) <-- x(l-n-2...u)
Exemple
L'exemple ci-après présente un fragment de code Python qui implémente une accélération rigoureuse sur une série temporelle simple en mémoire. La bibliothèque comprend plusieurs transformations intégrées. Dans cet exemple, la transformation de différence est appliquée deux fois à la série temporelle d'emplacement pour calculer les séries temporelles d'accélérations. Une opération de mappage est appliquée à la série temporelle d'accélération à l'aide d'une fonction lambda dure, qui est définie après l'échantillon de code, et qui mappe l'accélération soit à +1
n (accélération dure), -1
(freinage dur) et 0
(autrement). L'opération de filtrage ne sélectionne que les instances où l'accélération ou la décélération brutale est observé. Avant d'appeler get_values
, un graphique d'exécution est créé, mais aucun calcul n'est effectué. Lors de l'appel de get_values(5, 10)
, l'évaluation est effectuée avec la mémorisation sur la dépendance temporelle la plus étroite possible dans le graphique d'exécution.
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])
Le lambda rigoureux est défini comme suit :
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
En savoir plus
Pour utiliser le kit SDK tspy
Python, voir la documentation du kit SDK tspy
Python.
Rubrique parent: Analyse des séries temporelles