A zealous learner aspiring to advance in the domain of…

## Table of contents

**Introduction**

TimeSynth is a powerful open-source Python library for synthetic time series generation, so is its name (**Time **series **Synth**esis). It was introduced by J. R. Maat, A. Malali and P. Protopapas as “TimeSynth: A Multipurpose Library for Synthetic Time Series Generation in Python” (available here) in 2017.

Before going into the details of the library, since it is used for generating time series, have a quick overview of what the term ‘time series’ means.

**What is a time series?**

Time series is a sequence of data points recorded at successive uniform intervals of time. It is thus a sequence of discrete-time data. It can be taken on any variable that changes over time. As the data is collected at adjacent time periods, the observations are correlated. This is in contrast with cross-sectional data wherein an entity is observed at a single point in time. Some examples of time series data include population records, monthly sunspot observations, heights of ocean tides, stock prices and so on. Visit this page to learn more about time series.

**Overview of TimeSynth library**

TimeSynth can generate regular and irregular time series. It enables users to match different signals with various architectures allowing a wide variety of signals to be generated.

**NOTE**: TimeSynth supports Python 3.6+ versions. It is supported by PyPI.

**Signal types available in TimeSynth**

The types of signals that can be generated using TimeSynth are as follows:

- Sinusoidal (harmonic) signals: Signals which are periodic functions based on sine or cosine function of trigonometry.
- Signals generated using AR model: In an AutoRegression(AR) model, the variable of interest is forecasted using a linear combination of past values of the variable. The term “auto” regression indicates that it is a regression of the variable against itself (‘auto’ means ‘self’).

- In the AR(1) model (first-order autoregression), the current value of a variable is based on the immediately preceding value
- In the AR(2) model (second-order autoregression), the current value is based on the previous two values.

- Signals generated using CAR model (Continuous AutoRegression model)
- Signals generated using Mackey-Glass delay differential equation
- Signals generated using Gaussian process
- Signals generated using NARMA model (Nonlinear AutoRegressive Moving Average model)
- Pseudoperiodic signals

**Noise types available in TimeSynth**

Following two types of noise can be generated using TimeSynth:

- White noise: It is a random signal having equal intensity at various frequencies. In terms of sound, white noise refers to sounds which mask other surrounding sounds in the environment. The noise produced by a whining fan is an example of white noise.
- Red noise: Red noise or Brown/Brownian noise (named after Robert Brown) is a signal having higher energy at lower frequencies. The sound produced by strong waterfalls is an example of red noise.

**Classes available in TimeSynth**

The classes associated with the TimeSynth library are as follows:

**General classes**

- TimeSampler: This class determines how and when samples will be taken from noise and signal.
- TimeSeries: A TimeSeries object is the main interface for sampling time-series data.

**Classes for noise generation**

- GaussianNoise: This class adds uncorrelated, additive (i.e. white) noise to the signal.
- RedNoise: It adds correlated (i.e. red) noise to your signal.
- BaseNoise: It contains the signature of both the noise classes mentioned above.

**Classes for signal generation**

- BaseSignal: It contains the signature of all the signal classes.
- AutoRegressive: It generates autoregressive (AR) signals. The autoregressive lag is defined by the number of parameters in its ‘ar_param’ parameter. It should only be used with regularly sampled signals.
- CAR: It generates continuously autoregressive signals.
- MackeyGlass: It generates the Mackey-Glass delay differential equation (DDE).
- GaussianProcess: It samples time series from Gaussian Process with the selected kernel (linear, exponential etc).
- NARMA: Non-linear AutoRegressive Moving Average generator
- PseudoPeriodic: It generates pseudo periodic waves.
- Sinusoidal: It generates harmonic(sine) waves.

**Practical implementation of TimeSynth**

Here’s a demo of using TimeSynth library in Google Colab with Python version 3.6.9.

Clone the GitHub repository

` !pip install git+https://github.com/TimeSynth/TimeSynth.git`

Import the TimeSynth library

`import timesynth as ts`

Import Matplotlib library for visualizing the outputs

import matplotlib.pyplot as plt %matplotlib inline %config InlineBackend.figure_format = 'retina'

In the above lines of code,

- %matplotlib inline enables the output of plotting commands to be displayed ‘inline’ i.e. within the frontend (here colab notebook).
- %config InlineBackend.figure_format = ‘retina’ displays the output in ‘retina’ mode i.e. the figures look better with greater resolution

The above steps are common. Steps to generate and plot time series using specific types of signals have been explained below:

**Harmonic signal generation (with white noise)**

- Initialize TimeSampler

`time_sampler = ts.TimeSampler(stop_time=20)`

Setting stop_time=20 stops the sampling of time series after 20s. (Default value of the parameter is 10).

- Sampling irregular time samples

irregular_time_samples = time_sampler.sample_irregular_time(num_points=500, keep_percentage=50)

sample_irregular_time() samples irregularly spaced time using num_points (number of points in time series) or resolution (resolution of time series) parameter. Only one of these parameters need to be specified. Here, the time series will have 500 data points. keep_percentage=50 means 50% of the data points (i.e. 250 out of 500) will be retained in the irregular series.

- Initialize Sinusoidal signal

`sinusoid = ts.signals.Sinusoidal(frequency=0.25)`

‘frequency’ parameter represents frequency (in Hertz) of the harmonic signal formed. Its default value is 1.0

- Initialize Gaussian noise for adding white noise to the harmonic signal

`white_noise = ts.noise.GaussianNoise(std=0.3)`

‘std’ is a float-value parameter representing the standard deviation of the noise. You can optionally specify its mean using the ‘mean’ parameter.

- Initialize TimeSeries class with the signal and noise objects

timeseries = ts.TimeSeries(signal_generator=sinusoid, noise_generator=white_noise)

‘signal_generator’ and ‘noise_generator’ are signal object and noise object for the time series respectively. You must specify at least one signal generator while the noise generator is optional.

- Sample using the irregular time samples

samples, signals, errors = timeseries.sample(irregular_time_samples)

sample() method samples time from the specified time series (here ‘irregular_time_samples’)

- Plot the series

plt.plot(irregular_time_samples, samples, marker='o', markersize=4) plt.xlabel('Time') #name of variable plotted on X-axis plt.ylabel('Magnitude') #name of variable on Y-axis plt.title('Irregularly sampled sinusoid with noise'); #title of the plot

**Output**:

### **Harmonic signal generation (with red noise)**

- Initialize Red Noise

`red_noise = ts.noise.RedNoise(std=0.5, tau=0.8)`

‘std’ is the standard devastation for the noise and ‘tau’ signifies pulse interval in seconds.

- Initialize TimeSeries class with the signal and noise objects

`timeseries_corr = ts.TimeSeries(sinusoid, noise_generator=red_noise)`

Again, as explained in step (8), ‘signal_generator’ and ‘noise_generator’ are the signal and noise objects for time series creation respectively.

- Sample using the irregular time samples

`samples, signals, errors = timeseries_corr.sample(irregular_time_samples)`

sample() method samples the ‘irregular_time_samples’ time series. It returns the samples as well as signals and errors produced from them, which are stored in the respective arrays on the LHS of the above line of code.

- Plot the samples

plt.plot(irregular_time_samples, samples, marker='o') plt.xlabel('Time') #X-axis label plt.ylabel('Magnitude') #Y-axis label plt.title('Irregularly sampled sinusoid with red noise') #title of the plot

**Output**:

- Plot the red noise

plt.plot(irregular_time_samples, errors, marker='o') plt.xlabel('Time') #X-axis label plt.ylabel('Magnitude') #Y-axis label plt.title('Red noise'); #title of the plot

**Output**:

**Pseudoperiodic signal generation**

- Initialize TimeSampler

time_sampler_pp = ts.TimeSampler(stop_time=20) #stop sampling after 20s

- Sample irregular time samples

irregular_time_samples_pp = time_sampler_pp.sample_irregular_time(resolution=0.05, keep_percentage=50)

The first parameter represents the resolution of the time series while keep_percentage=50 retains 50% of the total generated data points in the time series.

- Initialize Pseudoperiodic signal

pseudo_periodic = ts.signals.PseudoPeriodic(frequency=2, freqSD=0.01, ampSD=0.5)

‘frequency’ denotes the frequency of the signal (default 1.0Hz), ‘freqSD’ denotes frequency standard deviation (default 0.1) and ‘ampSD’ is amplitude standard deviation (default 0.1).

- Initialize TimeSeries class with the pseudoperiodic signal

`timeseries_pp = ts.TimeSeries(pseudo_periodic)`

- Perform sampling using the irregular time samples

samples_pp, signals_pp, errors_pp = timeseries_pp.sample(irregular_time_samples_pp)

samples_pp, signals_pp and errors_pp are the arrays which will store the samples, signals generated from the samples and resulting errors respectively.

- Plot the series

plt.plot(irregular_time_samples_pp, samples_pp, marker='o') plt.xlabel('Time') #X-axis label plt.ylabel('Magnitude') #Y-axis label plt.title('Pseudoperiodic signal'); #title of the plot

**Output**:

**Gaussian process signal generation**

- Initialize the time sampler

` gp = ts.signals.GaussianProcess(kernel='Matern', nu=3./2)`

GaussianProcess() method samples the time series with the specified covariance function (kernel). Here, ‘Matern’ kernel has been used which requires the ‘nu’ parameter to be specified, representing the mean of the variables used in the Gaussian process. Other possible kernel types and required parameter to be specified for each can be found here.

- Initialize the TimeSampler object with gp as the signal generator

`gp_series = ts.TimeSeries(signal_generator=gp)`

- Sample the time series

`samples = gp_series.sample(irregular_time_samples)[0]`

sample() returns a tuple of three arrays (samples, signals and errors – in this order). [0] in the above line of code means the first array in the tuple i.e. that of the samples.

- Plot the signal

plt.plot(irregular_time_samples, samples, marker='o', markersize=4) plt.xlabel('Time') #X-axis label plt.ylabel('Value') #Y-axis label plt.title('Gaussian Process signal with Matern 3/2-kernel');#title of plot

**Output**:

**Continuous AutoRegressive (CAR) signal generation**

- Initialize CAR model

`car = ts.signals.CAR(ar_param=0.9, sigma=0.01)`

‘ar_param’ is a parameter of the AR(1) process. ’sigma’ denotes the standard deviation of the signal. Both the parameters have default value 1.0

- Instantiate TimeSeries object with ‘car’ as the signal generator

`car_series = ts.TimeSeries(signal_generator=car)`

- Sample the time series

`samples = car_series.sample(irregular_time_samples)`

- Plot the time series

plt.plot(irregular_time_samples, samples[0], marker='o', markersize=4) plt.xlabel('Time') #X-axis label plt.ylabel('Value') #Y-axis label plt.title(' Continuous Autoregressive process'); #title of the plot

**Output**:

**AR model for regularly sampled timestamps**

- Initialize TimeSampler object

time_sampler = ts.TimeSampler(stop_time=20) #sampling stops after 20s

- Sample regular time series

`regular_time_samples = time_sampler.sample_regular_time(num_points=500)`

500 of the total data points will be retained in the time series.

- Initialize AR(2) model

`ar_p = ts.signals.AutoRegressive(ar_param=[1.5, -0.75])`

‘ar_param’ is the list containing phi_1 and phi_2 (parameters of the AR(2) process (understand them here))

- Initialize TimeSeries object with the signal generator

`ar_p_series = ts.TimeSeries(signal_generator=ar_p)`

- Perform sampling of the time series

`samples = ar_p_series.sample(regular_time_samples)`

- Plot the time series

plt.plot(regular_time_samples, samples[0], marker='o', markersize=4) plt.xlabel('Time') #X-axis label plt.ylabel('Value') #Y-axis label plt.title('Autoregressive process - Second order'); #title of the plot

**Output:**

**Mackey-Glass signal generation**

- Initialize TimeSampler object

time_sampler = ts.TimeSampler(stop_time=1500) #stop sampling after 1500s

- Sample irregular time samples

irregular_time_samples = time_sampler.sample_irregular_time(num_points=1500, keep_percentage=75)

1500 data points will be there in the time series out of which 75% i.e. 1125 points will be retained.

- Instantiate MackeyGlass class

`mg = ts.signals.MackeyGlass() `

’tau’ can be specified as a delay parameter; omitting it will assume its default value of 17

- Instantiate GaussianNoise for adding white noise to the signal

`noise = ts.noise.GaussianNoise(std=0.1)`

‘std’ is the standard deviation for the noise.

- Initialize TimeSeries object with the signal and noise generators.

`mg_series = ts.TimeSeries(signal_generator=mg, noise_generator=noise)`

- Sample the irregular time series

`mg_samples, mg_signals, mg_errors = mg_series.sample(irregular_time_samples)`

‘mg_samples’ , ‘mg_signals’ and ‘mg_errors’ are errors which store the samples, generated signals and resulting errors respectively.

- Plot the time series without noise

plt.plot(irregular_time_samples, mg_signals, marker='o', markersize=4) plt.xlabel('Time') #X-axis label #X-axis label plt.ylabel('Value') #Y-axis label #Y-axis label #title of plot plt.title('Mackey-Glass differential equation with $\\tau=17$');

**Output**:

- Plot the time series with noise

plt.plot(irregular_time_samples, mg_samples, marker='o', markersize=4) plt.xlabel('Time') #X-axis label plt.ylabel('Value') #Y-axis label #title of plot plt.title('Mackey-Glass ($\\tau=17$) with noise ($\\sigma = 0.1$)');

**Output**:

**NARMA series**

- Initialize TimeSampler object

time_sampler = ts.TimeSampler(stop_time=500) #sampling stops after 500s

- Sample irregular time samples

`times = time_sampler.sample_regular_time(resolution=1.)`

- Instantiate NARMA

`narma_signal = ts.signals.NARMA(order=10)`

‘order’ specifies the order of nonlinear interactions in the NARMA formula given here.

- Initialize TimeSeries object with ‘narma_signal’ as the signal generator

`series = ts.TimeSeries(narma_signal)`

- Perform sampling

`samples, signals, errors = series.sample(times)`

The samples, signals and errors will be stored in the respective LHS arrays on executing the above line of code.

- Plot the time series

plt.plot(times, samples, marker='o', markersize=4) plt.xlabel('Time') #X-axis label plt.ylabel('Magnitude') #Y-axis label plt.title('10th-order NARMA Series'); #title of the plot

**Output**:

**Google colab notebook**with the above types of signals generated using TimeSynth can be found here.

**References**

Refer to the following weblinks to dive deeper into the TimeSynth library:

## Subscribe to our Newsletter

Get the latest updates and relevant offers by sharing your email.##### You can write for us and be one of the 500+ experts who have contributed stories at AIM. Share your nominations here.

A zealous learner aspiring to advance in the domain of AI/ML. Eager to grasp emerging techniques to get insights from data and hence explore realistic Data Science applications as well.