Avaliação lenta de série temporal
A avaliação preguiçosa é uma estratégia de avaliação que atrasa a avaliação de uma expressão até que seu valor seja necessário. Quando combinada com memorização, a estratégia de avaliação preguiçosa evita avaliações repetidas e pode reduzir o tempo de execução de determinadas funções por um fator significativo.
A biblioteca da série temporal usa avaliação preguiçosa para processar dados. Teoricamente, um gráfico de execução é construído sobre dados de séries temporais cuja avaliação é acionada somente quando sua saída é materializada. Supondo que um objeto esteja se movendo em um espaço dimensional
cujo local é capturado por x(t). É possível determinar a aceleração/frenagem rigorosa brusca (h(t)) deste objeto usando as séries temporais de velocidade (v(t)) e aceleração (a(t)) da seguinte forma:
# 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
Isso resulta em um gráfico de execução simples no formato:
x(t) --> v(t) --> a(t) --> h(t)
As avaliações são acionadas apenas quando uma ação é executada, como compute h(5...10), ou seja, compute h(5), ..., h(10). A biblioteca captura dependências temporais limitadas entre séries temporais. Neste exemplo, h(5...10) requer a(5...10), que, por sua vez, requer v(4...10), que requer x(3...10). Somente as partes relevantes de a(t), v(t) e x(t) são avaliadas.
h(5...10) <-- a(5...10) <-- v(4...10) <-- x(3...10)
Além disso, as avaliações são memorizadas e podem ser reutilizadas em ações subsequentes no h. Por exemplo, quando uma solicitação para h(7...12) segue uma solicitação para h(5...10), os valores memorizados h(7...10) são alavancados; além disso, h(11...12) seria avaliado usando a(11...12), v(10...12) e x(9...12) que, por sua vez, alavancaria v(10) e x(9...10) memorizados do cálculo anterior.
Em um exemplo mais geral, você poderia definir uma série temporal de velocidade suavizada da seguinte forma:
# 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)
Neste exemplo h(l...u) tem a dependência temporal a seguir. A avaliação de h(l...u) aderiria estritamente a essa dependência temporal com a memorização.
h(l...u) <-- a(l...u) <-- v_smooth(l-1...u) <-- v(l-n-1...u) <-- x(l-n-2...u)
Um exemplo
O exemplo a seguir mostra um trecho de código python que implementa a aceleração brusca em uma série temporal de memória simples. A biblioteca inclui várias transformações integradas. Neste exemplo, a transformação de diferença é aplicada duas vezes à série temporal de localização para calcular séries temporais de aceleração. Uma operação de mapa é aplicada à série temporal de aceleração usando uma função lambda brusca, que é definida após a amostra de código, que mapeia a aceleração para +1 (aceleração brusca), -1 (frenagem brusca) e 0 (caso contrário). A operação de filtro seleciona apenas as instâncias em que a aceleração ou a frenagem brusca é observada. Antes de chamar get_values, um gráfico de execução é criado, mas nenhum cálculo é realizado. Na chamada para get_values(5, 10), a avaliação é executada com memorização na dependência temporal mais limitada possível no gráfico de execução.
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])
O lambda brusco é definido da seguinte forma:
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
Saiba Mais
Para usar o tspy Python SDK, consulte a Documentação do tspy Python SDK.