Source code for autopycoin.data.generate

"""
These functions are used to generate time series.
"""

import numpy as np
from typing import Union, List, Optional

import tensorflow as tf
from keras.backend import floatx

from ..utils import range_dims


[docs]def random_ts( n_steps: int = 100, trend_degree: int = 2, periods: List[int] = [10], fourier_orders: List[int] = [10], trend_mean: Optional[int] = 0, trend_std: Optional[int] = 1, seasonality_mean: Optional[int] = 0, seasonality_std: Optional[int] = 1, batch_size: Optional[Union[List[int], int]] = None, n_variables: Optional[int] = 1, noise: Optional[bool] = False, seed: Optional[int] = None, ) -> tf.Tensor: """ Generate random time series composed by a trend and seasonality components. Coefficients for the trend and seasonality components are generated by Gaussian distributions. Parameters ---------- n_steps : int Number of steps. trend_degree : int Number of degree for the trend function. Usually 1 or 2. periods : list[int] Computes the seasonality component. A period lower than n_step leads to a pattern which is repeating. fourier_orders : list[int] Computes the complexity of the seasonality component. Higher order means higher complexity. trend_mean : int Mean value associated to the trend component. Default to 0. trend_std : int Deviation value associated to the trend component. Default to 1. seasonality_mean : int Mean value associated to the seasonality component. Default to 0. seasonality_std : int Deviation value associated to the seasonality component. Default to 1. batch_size : int or list[int] or None Computes the batch_size of the time series. Default to None. n_variables : int Number of variables. Default to 1. noise : boolean Add centered normal distributed noise to the series. Default to False. seed : int or None Allow reproducible results. Default to None. Returns ------- time_series : `tensor of shape [D0, ..., n_steps, n_variables]` Time series defined by a random process. Examples -------- >>> from autopycoin.data import random_ts >>> data = random_ts(n_steps=10, ... trend_degree=2, ... periods=[10], ... fourier_orders=[10], ... trend_mean=0, ... trend_std=1, ... seasonality_mean=0, ... seasonality_std=1, ... batch_size=None, ... n_variables=1, ... noise=True, ... seed=42) >>> data.shape TensorShape([10, 1]) """ tf.random.set_seed(seed) if isinstance(batch_size, int): batch_size = [batch_size] elif batch_size is None: batch_size = [] degree = range_dims(trend_degree, shape=(1, -1, 1)) time = range_dims(n_steps, shape=(-1, 1, 1)) # Workout random trend coefficients trend_coef = tf.random.normal( (*batch_size, 1, trend_degree, n_variables), mean=trend_mean, stddev=trend_std, dtype=floatx(), seed=seed, ) # trend component added to ts time_series = tf.reduce_sum(trend_coef * ((time / n_steps) ** degree), axis=-2) # Shape (-1, 1) in order to broadcast periods to all time units periods = tf.reshape(periods, shape=(-1, 1, 1)) periods = tf.cast(periods, dtype=floatx()) for fourier_order, period in zip(fourier_orders, periods): time = 2 * np.pi * time / period fourier_order = range_dims(fourier_order, shape=(-1, 1)) seasonality = time * fourier_order # Workout cos and sin seasonality coefficents seasonality = tf.concat((tf.cos(seasonality), tf.sin(seasonality)), axis=-2) # Workout random seasonality coefficents seas_coef = tf.random.normal( (*batch_size, 1, seasonality.shape[-1], n_variables), mean=seasonality_mean, stddev=seasonality_std, dtype=floatx(), seed=seed, ) seasonality = tf.reduce_sum(seasonality * seas_coef, axis=-2) # Seasonality coefficients added to ts time_series = time_series + seasonality if noise: noise = tf.random.normal( (n_steps, 1), mean=0.0, stddev=1, dtype=floatx(), seed=seed ) return time_series + noise return time_series