Funções de séries temporais
As funções de séries temporais são funções agregadas que operam em sequências de valores de dados medidos em pontos no tempo.
As seções a seguir descrevem algumas das funções de séries temporais disponíveis em diferentes pacotes de séries temporais.
Transformações
Transformações são funções que são aplicadas em uma série temporal resultando em outra série temporal. A biblioteca de séries temporais suporta vários tipos de transformações, incluindo as transformações fornecidas (usando from tspy.functions import transformers), bem como as transformas definidas pelo usuário.
A amostra a seguir mostra algumas transformações fornecidas:
#Interpolation
>>> ts = tspy.time_series([1.0, 2.0, 3.0, 4.0, 5.0, 6.0])
>>> periodicity = 2
>>> interp = interpolators.nearest(0.0)
>>> interp_ts = ts.resample(periodicity, interp)
>>> interp_ts.print()
TimeStamp: 0 Value: 1.0
TimeStamp: 2 Value: 3.0
TimeStamp: 4 Value: 5.0
#Fillna
>>> shift_ts = ts.shift(2)
print("shifted ts to add nulls")
print(shift_ts)
print("\nfilled ts to make nulls 0s")
null_filled_ts = shift_ts.fillna(interpolators.fill(0.0))
print(null_filled_ts)
shifted ts to add nulls
TimeStamp: 0 Value: null
TimeStamp: 1 Value: null
TimeStamp: 2 Value: 1.0
TimeStamp: 3 Value: 2.0
TimeStamp: 4 Value: 3.0
TimeStamp: 5 Value: 4.0
filled ts to make nulls 0s
TimeStamp: 0 Value: 0.0
TimeStamp: 1 Value: 0.0
TimeStamp: 2 Value: 1.0
TimeStamp: 3 Value: 2.0
TimeStamp: 4 Value: 3.0
TimeStamp: 5 Value: 4.0
# Additive White Gaussian Noise (AWGN)
>>> noise_ts = ts.transform(transformers.awgn(mean=0.0,sd=.03))
>>> print(noise_ts)
TimeStamp: 0 Value: 0.9962378841388397
TimeStamp: 1 Value: 1.9681980879378596
TimeStamp: 2 Value: 3.0289374962174405
TimeStamp: 3 Value: 3.990728648807705
TimeStamp: 4 Value: 4.935338359740761
TimeStamp: 5 Value: 6.03395072999318
Segmentação
Segmentação ou janelas é o processo de divisão de uma série temporal em diversos segmentos. A biblioteca de séries temporais suporta várias formas de segmentação e permite a criação de segmentos definidos pelo usuário também.
Segmentação baseada em janela
Esse tipo de segmentação de uma série temporal é baseado em tamanhos de segmento especificados pelo usuário. Os segmentos podem ser baseados em registro ou tempo. Há opções que permitem a criação de tumbling, bem como os segmentos baseados em janela deslizantes.
>>> import tspy >>> ts_orig = tspy.builder() .add(tspy.observation(1,1.0)) .add(tspy.observation(2,2.0)) .add(tspy.observation(6,6.0)) .result().to_time_series() >>> ts_orig timestamp: 1 Value: 1.0 timestamp: 2 Value: 2.0 timestamp: 6 Value: 6.0 >>> ts = ts_orig.segment_by_time(3,1) >>> ts timestamp: 1 Value: original bounds: (1,3) actual bounds: (1,2) observations: [(1,1.0),(2,2.0)] timestamp: 2 Value: original bounds: (2,4) actual bounds: (2,2) observations: [(2,2.0)] timestamp: 3 Value: this segment is empty timestamp: 4 Value: original bounds: (4,6) actual bounds: (6,6) observations: [(6,6.0)]Segmentação baseada em âncora
A segmentação baseada em âncora é um tipo muito importante de segmentação que cria um segmento ao ancorar em um lambda específico, que pode ser um valor simples. Um exemplo é examinar os eventos que precederam um erro 500 ou examinar valores após observar uma anomalia. As variantes de segmentação baseada em âncora incluem fornecer um intervalo com vários marcadores.
>>> import tspy >>> ts_orig = tspy.time_series([1.0, 2.0, 3.0, 4.0, 5.0]) >>> ts_orig timestamp: 0 Value: 1.0 timestamp: 1 Value: 2.0 timestamp: 2 Value: 3.0 timestamp: 3 Value: 4.0 timestamp: 4 Value: 5.0 >>> ts = ts_orig.segment_by_anchor(lambda x: x % 2 == 0, 1, 2) >>> ts timestamp: 1 Value: original bounds: (0,3) actual bounds: (0,3) observations: [(0,1.0),(1,2.0),(2,3.0),(3,4.0)] timestamp: 3 Value: original bounds: (2,5) actual bounds: (2,4) observations: [(2,3.0),(3,4.0),(4,5.0)]Segmentadores
Existem vários segmentadores especializados fornecidos prontos para uso por meio da importação do pacote
segmenters(usandofrom tspy.functions import segmenters). Um exemplo de segmentador é um que usa regressão para segmentar uma série temporal:>>> ts = tspy.time_series([1.0,2.0,3.0,4.0,5.0,2.0,1.0,-1.0,50.0,53.0,56.0]) >>> max_error = .5 >>> skip = 1 >>> reg_sts = ts.to_segments(segmenters.regression(max_error,skip,use_relative=True)) >>> reg_sts timestamp: 0 Value: range: (0, 4) outliers: {} timestamp: 5 Value: range: (5, 7) outliers: {} timestamp: 8 Value: range: (8, 10) outliers: {}
Redutores
Um redutor é uma função que é aplicada aos valores em um conjunto de séries temporais para produzir um valor único. As funções de série temporal reducer são semelhantes ao conceito redutor usado pelo Hadoop/Spark. Esse valor único pode ser uma coleção, mas, geralmente, é um único objeto. Um exemplo de uma função redutora é estimar os valores em uma série temporal.
Várias funções reducer são suportadas, incluindo:
Redutores de distância
Os redutores de distância são uma classe de redutores que calculam a distância entre duas séries temporais. A biblioteca suporta funções numéricas, bem como as funções de distância categórica em sequências. Isso inclui medidas de distância de time warping, tais como Itakura Parallelogram, Sakoe-Chiba Band, DTW não restrito e restrições não time warping DTW. As distâncias de distribuição, como distância húngara e distâncias do movimentador da Terra, também estão disponíveis.
Para medidas de distância de séries temporais categóricas, é possível usar medidas de distância Damerau Levenshtein e Jaro-Winkler.
>>> from tspy.functions import * >>> ts = tspy.time_series([1.0, 2.0, 3.0, 4.0, 5.0, 6.0]) >>> ts2 = ts.transform(transformers.awgn(sd=.3)) >>> dtw_distance = ts.reduce(ts2,reducers.dtw(lambda obs1, obs2: abs(obs1.value - obs2.value))) >>> print(dtw_distance) 1.8557981638880405Redutores de matemática
Vários redutores de matemática convenientes para séries temporais numéricas são fornecidos. Eles incluem os básicos, como média, soma, desvio padrão e momentos. Entropia, curtose, FFT e variantes, várias correlações e histograma também estão incluídos. Um redutor de sumarização básica conveniente é a função
describeque fornece informações básicas sobre a série temporal.>>> from tspy.functions import * >>> ts = tspy.time_series([1.0, 2.0, 3.0, 4.0, 5.0, 6.0]) >>> ts2 = ts.transform(transformers.awgn(sd=.3)) >>> corr = ts.reduce(ts2, reducers.correlation()) >>> print(corr) 0.9938941942380525 >>> adf = ts.reduce(reducers.adf()) >>> print(adf) pValue: -3.45 satisfies test: false >>> ts2 = ts.transform(transformers.awgn(sd=.3)) >>> granger = ts.reduce(ts2, reducers.granger(1)) >>> print(granger) #f_stat, p_value, R2 -1.7123613937876463,-3.874412217575385,1.0Outro redutor básico que é muito útil para se ter um entendimento de primeira ordem da série temporal é o redutor de descrição. A seguir há uma ilustração desse redutor:
>>> desc = ts.describe() >>> print(desc) min inter-arrival-time: 1 max inter-arrival-time: 1 mean inter-arrival-time: 1.0 top: null unique: 6 frequency: 1 first: TimeStamp: 0 Value: 1.0 last: TimeStamp: 5 Value: 6.0 count: 6 mean:3.5 std:1.707825127659933 min:1.0 max:6.0 25%:1.75 50%:3.5 75%:5.25
Junções temporais
A biblioteca inclui funções para junções temporais ou junção de séries temporais com base em seus registros de data e hora. As funções de junção são semelhantes àquelas em um banco de dados, incluindo esquerda, direita, externa, interna, esquerda externa, direita externa e assim por diante. Os códigos de amostra a seguir mostram algumas dessas funções de junção:
# Create a collection of observations (materialized TimeSeries)
observations_left = tspy.observations(tspy.observation(1, 0.0), tspy.observation(3, 1.0), tspy.observation(8, 3.0), tspy.observation(9, 2.5))
observations_right = tspy.observations(tspy.observation(2, 2.0), tspy.observation(3, 1.5), tspy.observation(7, 4.0), tspy.observation(9, 5.5), tspy.observation(10, 4.5))
# Build TimeSeries from Observations
ts_left = observations_left.to_time_series()
ts_right = observations_right.to_time_series()
# Perform full join
ts_full = ts_left.full_join(ts_right)
print(ts_full)
TimeStamp: 1 Value: [0.0, null]
TimeStamp: 2 Value: [null, 2.0]
TimeStamp: 3 Value: [1.0, 1.5]
TimeStamp: 7 Value: [null, 4.0]
TimeStamp: 8 Value: [3.0, null]
TimeStamp: 9 Value: [2.5, 5.5]
TimeStamp: 10 Value: [null, 4.5]
# Perform left align with interpolation
ts_left_aligned, ts_right_aligned = ts_left.left_align(ts_right, interpolators.nearest(0.0))
print("left ts result")
print(ts_left_aligned)
print("right ts result")
print(ts_right_aligned)
left ts result
TimeStamp: 1 Value: 0.0
TimeStamp: 3 Value: 1.0
TimeStamp: 8 Value: 3.0
TimeStamp: 9 Value: 2.5
right ts result
TimeStamp: 1 Value: 0.0
TimeStamp: 3 Value: 1.5
TimeStamp: 8 Value: 4.0
TimeStamp: 9 Value: 5.5
Previsão
Uma funcionalidade chave fornecida pela biblioteca de séries temporais é a previsão. A biblioteca inclui funções para modelos de previsão simples, bem como complexos, incluindo ARIMA, Exponential, Holt-Winters e BATS. O exemplo a seguir mostra a função para criar um Holt-Winters:
import random
model = tspy.forecasters.hws(samples_per_season=samples_per_season, initial_training_seasons=initial_training_seasons)
for i in range(100):
timestamp = i
value = random.randint(1,10) * 1.0
model.update_model(timestamp, value)
print(model)
Forecasting Model
Algorithm: HWSAdditive=5 (aLevel=0.001, bSlope=0.001, gSeas=0.001) level=6.087789839896166, slope=0.018901997884893912, seasonal(amp,per,avg)=(1.411203455586738,5, 0,-0.0037471500727535465)
#Is model init-ed
if model.is_initialized():
print(model.forecast_at(120))
6.334135728495107
ts = tspy.time_series([float(i) for i in range(10)])
print(ts)
TimeStamp: 0 Value: 0.0
TimeStamp: 1 Value: 1.0
TimeStamp: 2 Value: 2.0
TimeStamp: 3 Value: 3.0
TimeStamp: 4 Value: 4.0
TimeStamp: 5 Value: 5.0
TimeStamp: 6 Value: 6.0
TimeStamp: 7 Value: 7.0
TimeStamp: 8 Value: 8.0
TimeStamp: 9 Value: 9.0
num_predictions = 5
model = tspy.forecasters.auto(8)
confidence = .99
predictions = ts.forecast(num_predictions, model, confidence=confidence)
print(predictions.to_time_series())
TimeStamp: 10 Value: {value=10.0, lower_bound=10.0, upper_bound=10.0, error=0.0}
TimeStamp: 11 Value: {value=10.997862810553725, lower_bound=9.934621260488143, upper_bound=12.061104360619307, error=0.41277640121597475}
TimeStamp: 12 Value: {value=11.996821082897318, lower_bound=10.704895525154571, upper_bound=13.288746640640065, error=0.5015571318964149}
TimeStamp: 13 Value: {value=12.995779355240911, lower_bound=11.50957896664928, upper_bound=14.481979743832543, error=0.5769793776877866}
TimeStamp: 14 Value: {value=13.994737627584504, lower_bound=12.33653268707341, upper_bound=15.652942568095598, error=0.6437557559526337}
print(predictions.to_time_series().to_df())
timestamp value lower_bound upper_bound error
0 10 10.000000 10.000000 10.000000 0.000000
1 11 10.997863 9.934621 12.061104 0.412776
2 12 11.996821 10.704896 13.288747 0.501557
3 13 12.995779 11.509579 14.481980 0.576979
4 14 13.994738 12.336533 15.652943 0.643756
SQL da série temporal
A biblioteca de séries temporais está firmemente integrada com o Apache Spark. Ao usar novos tipos de dados no Spark Catalyst, você é capaz de executar operações SQL de séries temporais que escalam horizontalmente usando o Apache Spark. Isso permite que você use facilmente extensões de séries temporais no IBM Analytics Engine ou em soluções que incluem a funcionalidade IBM Analytics Engine, como os ambientes watsonx.ai Studio Spark.
As extensões SQL abrangem a maioria dos aspectos das funções de série temporal, incluindo segmentação, transformações, redutores, previsão e E/S. Consulte Analisando dados de séries temporais.
Saiba Mais
Para usar o tspy Python SDK, consulte a Documentação do tspy Python SDK.