Implementation of deep learning models for time series in PyTorch.

Overview

List of Implementations:

Currently, the reimplementation of the DeepAR paper(DeepAR: Probabilistic Forecasting with Autoregressive Recurrent Networks https://arxiv.org/abs/1704.04110) is available in PyTorch. More papers will be coming soon.

Authors:

  • Yunkai Zhang([email protected]) - University of California, Santa Barbara

  • Qiao Jiang - Brown University

  • Xueying Ma - Columbia University

  • Acknowledgement: Professor Xifeng Yan's group at UC Santa Barbara. Part of the work was done at WeWork.

To run:

  1. Install all dependencies listed in requirements.txt. Note that the model has only been tested in the versions shown in the text file.

  2. Download the dataset and preprocess the data:

    python preprocess_elect.py
  3. Start training:

    python train.py
    • If you want to perform ancestral sampling,

      python train.py --sampling
    • If you do not want to do normalization during evaluation,

      python train.py --relative-metrics
  4. Evaluate a set of saved model weights:

    python evaluate.py
  5. Perform hyperparameter search:

     python search_params.py

Results

​ The model is evaluated on the electricity dataset, which contains the electricity consumption of 370 households from 2011 to 2014. Under hourly frequency, we use the first week of September, 2014 as the test set and all time steps prior to that as the train set. Following the experiment design in DeepAR, the window size is chosen to be 192, where the last 24 is the forecasting horizon. History (number of time steps since the beginning of each household), month of the year, day of the week, and hour of the day are used as time covariates. Notice that some households started at different times, so we only use windows that contain non-missing values.

​ Under Gaussian likelihood, we use the Adam optimizer with early stopping to train the model for 20 epoches. The same set of hyperparameters is used as outlined in the paper. Weights with the best ND value is selected, where ND = 0.06349, RMSE = 0.452, rou90 = 0.034 and rou50 = 0.063.

​ Sample results on electricity. The top 10 plots are sampled from the test set with the highest 10% ND values, whereas the bottom 10 plots are sampled from the rest of the test set.

Sample results on electricity. The top 10 plots are sampled from the test set with the highest 10% ND values, whereas the bottom 10 plots are sampled from the rest of the test set.

Comments
  • I think I found mistakes

    I think I found mistakes

    Hello, Thanks for your effort. I'm verifying your code.

    In model.test() in net.py, decoding part seems unnatural.

    The task is to predict indices from 168 ~ 191 (24 time samples) using 0 ~ 167 samples (168 time samples). It is assumed that we do not know predicting part.

    In your source, however, at iter 0, we already know 168 index from original data, and it occurred last time step to be discarded due to out of index.

    I thinks it can be fixed like this:

    for t in range(self.params.predict_steps):
       mu_de, sigma_de, decoder_hidden, decoder_cell = self(x[self.params.predict_start+(t-1)].unsqueeze(0), id_batch, decoder_hidden, decoder_cell)
       sample_mu[:, t] = mu_de * v_batch[:, 0] + v_batch[:, 1]
       sample_sigma[:, t] = sigma_de * v_batch[:, 0]
       x[self.params.predict_start+t, :, 0] = mu_de
    
    opened by sjhan91 7
  • is there any implemented Negative binomial distributions likelihood loss function

    is there any implemented Negative binomial distributions likelihood loss function

    Hello, thank you that i have implemented the DeepAR model for my data set. but i want to implement negative Binomial distributions likelihood loss function since it is in the paper. I am very beginner in PyTorch but somehow I have implemented your Gaussian implementation in for my dataset. Pytorch itself has a Negative Binomial Class which contains total count, logits, probs as a parameter. actually I cant relate which of these parameters indicates the zero index, mu, sigma I have tried with my intuitions. but my y_prediction output is showing inappropriate value. I am looking for your suggestion which might be helpful for me to solve this

    opened by kb007 4
  • confusion in the net.test function ,line 87

    confusion in the net.test function ,line 87

    In the /model/net.py file, line 87, when the model do inference from [predict_start ,predict_start+ predict_step] , it can use the true information of them, which is not properly for model test. In the test stage, the model only input the true value of x[predict_start], and the following step should input the last predict mu instead.

    opened by hihihihiwsf 3
  • Question abouthe offset in `preprocess_elect.py` function - is this an error?

    Question abouthe offset in `preprocess_elect.py` function - is this an error?

    Hello. Thanks so much for creating this repository. I was going through the preprocessing code, and it seems like there is an error in the code. But I wanted to check with you, in case I was just misinterpreting it.

    So in the preprocess_elect.py module, in the prep_data() function there is a set of lines like:

                x_input[count, 1:, 0] = data[window_start:window_end-1, series]  # <--- QUESTION
                x_input[count, :, 1:1+num_covariates] = covariates[window_start:window_end, :]
                x_input[count, :, -1] = series
    

    The problem is that the x_input[count, 1:, 0] begins at index 1 instead of 0. So that will actually make the window size 191 instead of 192. And it is not clear what the benefit of starting every window with 0 will be. But further, the other arrays, such as labels goes from window_start to window_end. If that is the case, then the x_input array and the labels array is off by an increment.

    So I was not sure which is the right way to do it, or whether this is written accurately. Would you mind clarifying if you have a chance. Thanks.

    opened by 00krishna 2
  • Elaboration on the results

    Elaboration on the results

    Hi there, thanks for sharing the code. Can you also elaborate on the results/graphs that you have plotted. I believe the blue line is the actual time series data(ground truth) and the red line is our Gaussian likelihood function for which we are also measuring those metrics like ND and RMSE. This is done on 200 samples/days from the time series at a time, is my understanding correct? In my case, I have taken 150 days of data(130 days train and 20 days test) , so I don't understand how the graph I got after training has portions after 150, will you please expain. Thanks!

    opened by padmaksha18 1
  • Some confusion about calculate distribution_mu&sigma

    Some confusion about calculate distribution_mu&sigma

    first,thanks for ur code!it‘s very helpful! in your code, when your calculate the mu&sigma use the h from all three layers。 image

    but in the deepar paper calculate the mu&sigma use the h from the last layers 。

    image

    which one is better?

    opened by chenjw505 1
  • bug in gen_covariates

    bug in gen_covariates

    the signature of gen_covariates in preprocess_elect.py takes a parameter num_covariates, and uses it to reshape the array it returns. However, this will crash for num_covariates < 4, since the shape of the containing array is set by num_covariates and column indices 1, 2, 3 are accessed while it is being populated with data. If the containing array is (n, 3), the function will crash when it tries to put the month in covariates[i, 3].

    def gen_covariates(times, num_covariates):
        covariates = np.zeros((times.shape[0], num_covariates))
        for i, input_time in enumerate(times):
            covariates[i, 1] = input_time.weekday()
            covariates[i, 2] = input_time.hour
            covariates[i, 3] = input_time.month
        for i in range(1,num_covariates):
            covariates[:,i] = stats.zscore(covariates[:,i])
        return covariates[:, :num_covariates]
    
    opened by jonathanstrong 1
  • Can you make a example of inference for specific Time window

    Can you make a example of inference for specific Time window

    Hello, I am new in PyTorch but i implemented DeepAR model by your implementation. I need a help to make time window inference. i am saving model as .pkl in the base model and I have modified the evaluate.py code a bit. what i need is predict function that will take a time window and give the prediction result. so far I have done this

    # -*- coding: utf-8 -*-
    """
    Created on Sat Jun 13 13:42:11 2020
    
    """
    
    import argparse
    import logging
    import os
    
    import numpy as np
    import torch
    from torch.utils.data.sampler import RandomSampler
    from tqdm import tqdm
    
    import utils
    import model.net as net
    from dataloader import *
    
    import matplotlib
    matplotlib.use('Agg')
    import matplotlib.pyplot as plt
    import pandas as pd
    
    logger = logging.getLogger('DeepAR.Eval')
    
    parser = argparse.ArgumentParser()
    parser.add_argument('--dataset', default='test_dataset', help='Name of the dataset')
    parser.add_argument('--data-folder', default='data', help='Parent dir of the dataset')
    parser.add_argument('--model-name', default='base_model', help='Directory containing params.json')
    parser.add_argument('--relative-metrics', action='store_true', help='Whether to normalize the metrics by label scales')
    parser.add_argument('--sampling', action='store_true', help='Whether to sample during evaluation')
    parser.add_argument('--restore-file', default='best',
                        help='Optional, name of the file in --model_dir containing weights to reload before \
                        training')
    
    
    
    def evaluate(model, loss_fn, test_loader, params, plot_num, sample=True):
        '''Evaluate the model on the test set.
        Args:
            model: (torch.nn.Module) the Deep AR model
            loss_fn: a function that takes outputs and labels per timestep, and then computes the loss for the batch
            test_loader: load test data and labels
            params: (Params) hyperparameters
            plot_num: (-1): evaluation from evaluate.py; else (epoch): evaluation on epoch
            sample: (boolean) do ancestral sampling or directly use output mu from last time step
        '''
        model.eval()
        with torch.no_grad():
          print("In model .eval")  
          plot_batch = np.random.randint(len(test_loader))
          print("plot_batch value in evaluation", plot_batch)
    
          summary_metric = {}
          raw_metrics = utils.init_metrics(sample=sample)
    
          # Test_loader: 
          # test_batch ([batch_size, train_window, 1+cov_dim]): z_{0:T-1} + x_{1:T}, note that z_0 = 0;
          # id_batch ([batch_size]): one integer denoting the time series id;
          # v ([batch_size, 2]): scaling factor for each window;
          # labels ([batch_size, train_window]): z_{1:T}.
          for i, (test_batch, id_batch, v, labels) in enumerate(tqdm(test_loader)):
              test_batch = test_batch.permute(1, 0, 2).to(torch.float32).to(params.device)
              id_batch = id_batch.unsqueeze(0).to(params.device)
              v_batch = v.to(torch.float32).to(params.device)
              labels = labels.to(torch.float32).to(params.device)
              batch_size = test_batch.shape[1]
              input_mu = torch.zeros(batch_size, params.test_predict_start, device=params.device) # scaled
              input_sigma = torch.zeros(batch_size, params.test_predict_start, device=params.device) # scaled
              hidden = model.init_hidden(batch_size)
              cell = model.init_cell(batch_size)
    
              for t in range(params.test_predict_start):
                  # if z_t is missing, replace it by output mu from the last time step
                  zero_index = (test_batch[t,:,0] == 0)
                  if t > 0 and torch.sum(zero_index) > 0:
                      test_batch[t,zero_index,0] = mu[zero_index]
    
                  mu, sigma, hidden, cell = model(test_batch[t].unsqueeze(0), id_batch, hidden, cell)
                  input_mu[:,t] = v_batch[:, 0] * mu + v_batch[:, 1]
                  input_sigma[:,t] = v_batch[:, 0] * sigma
    
              if sample:
                  samples, sample_mu, sample_sigma = model.test(test_batch, v_batch, id_batch, hidden, cell, sampling=True)
                  raw_metrics = utils.update_metrics(raw_metrics, input_mu, input_sigma, sample_mu, labels, params.test_predict_start, samples, relative = params.relative_metrics)
              else:
                  sample_mu, sample_sigma = model.test(test_batch, v_batch, id_batch, hidden, cell)
                  raw_metrics = utils.update_metrics(raw_metrics, input_mu, input_sigma, sample_mu, labels, params.test_predict_start, relative = params.relative_metrics)
    
              if i == plot_batch:
                  if sample:
                      sample_metrics = utils.get_metrics(sample_mu, labels, params.test_predict_start, samples, relative = params.relative_metrics)
                  else:
                      sample_metrics = utils.get_metrics(sample_mu, labels, params.test_predict_start, relative = params.relative_metrics)                
                  # select 10 from samples with highest error and 10 from the rest
                  top_10_nd_sample = (-sample_metrics['ND']).argsort()[:batch_size // 10]  # hard coded to be 10
                  chosen = set(top_10_nd_sample.tolist())
                  all_samples = set(range(batch_size))
                  not_chosen = np.asarray(list(all_samples - chosen))
                  if batch_size < 100: # make sure there are enough unique samples to choose top 10 from
                      random_sample_10 = np.random.choice(top_10_nd_sample, size=10, replace=True)
                  else:
                      random_sample_10 = np.random.choice(top_10_nd_sample, size=10, replace=False)
                  if batch_size < 12: # make sure there are enough unique samples to choose bottom 90 from
                      random_sample_90 = np.random.choice(not_chosen, size=10, replace=True)
                  else:
                      random_sample_90 = np.random.choice(not_chosen, size=10, replace=False)
                  combined_sample = np.concatenate((random_sample_10, random_sample_90))
    
                  label_plot = labels[combined_sample].data.cpu().numpy()
                  predict_mu = sample_mu[combined_sample].data.cpu().numpy()
                  predict_sigma = sample_sigma[combined_sample].data.cpu().numpy()
                  plot_mu = np.concatenate((input_mu[combined_sample].data.cpu().numpy(), predict_mu), axis=1)
                  plot_sigma = np.concatenate((input_sigma[combined_sample].data.cpu().numpy(), predict_sigma), axis=1)
                  plot_metrics = {_k: _v[combined_sample] for _k, _v in sample_metrics.items()}
                  plot_eight_windows(params.plot_dir, plot_mu, plot_sigma, label_plot, params.test_window, params.test_predict_start, plot_num, plot_metrics, sample)
    
          summary_metric = utils.final_metrics(raw_metrics, sampling=sample)
          metrics_string = '; '.join('{}: {:05.3f}'.format(k, v) for k, v in summary_metric.items())
          logger.info('- Full test metrics: ' + metrics_string)
        return summary_metric
    
    
    
    
    def plot_eight_windows(plot_dir,
                           predict_values,
                           predict_sigma,
                           labels,
                           window_size,
                           predict_start,
                           plot_num,
                           plot_metrics,
                           sampling=False):
    
        x = np.arange(window_size)
        f = plt.figure(figsize=(8, 42), constrained_layout=True)
        nrows = 21
        ncols = 1
        ax = f.subplots(nrows, ncols)
    
        for k in range(nrows):
            if k == 10:
                ax[k].plot(x, x, color='g')
                ax[k].plot(x, x[::-1], color='g')
                ax[k].set_title('This separates top 10 and bottom 90', fontsize=10)
                continue
            m = k if k < 10 else k - 1
            # for 24 hour predictioon
            
            print('iteration',k)
            predict_or_df=pd.DataFrame(predict_values[m,predict_start:],columns=['y_pred'])
            predict_next_df=pd.DataFrame(labels[m,predict_start:],columns=['y_true'])
            y_lower= predict_values[m,predict_start:]-predict_sigma[m,predict_start:]
            y_lower_df=pd.DataFrame(y_lower,columns=['y_lower'])
            y_upper=predict_values[m,predict_start:]+ predict_sigma[m,predict_start:]
            y_upper_df=pd.DataFrame(y_upper,columns=['y_upper'])
    
            y2_lower=predict_values[m,predict_start:] - 2 * predict_sigma[m,predict_start:]
            y2_lower_df=pd.DataFrame(y2_lower,columns=['y2_lower'])
            y2_upper=predict_values[m,predict_start:] + 2 * predict_sigma[m,predict_start:]
            y2_upper_df=pd.DataFrame(y2_upper,columns=['y2_upper'])
    
            frames=[predict_next_df,predict_or_df,y_lower_df,y_upper_df,y2_lower_df,y2_upper_df]
            summarydf=pd.concat(frames,axis=1)
            print(summarydf)
            summarydf.to_csv('/Users/kalyan.admin/KalyanWork/Timeseries_covid/experiments/csvfiles_inferenceset/pytorch_report_"%s".csv'%(k))
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
           #Visualgraph for 192 hour windows that is  week based hourly prediction
            ax[k].plot(x, predict_values[m], color='b')
            ax[k].fill_between(x[predict_start:], predict_values[m, predict_start:] - 2 * predict_sigma[m, predict_start:],
                             predict_values[m, predict_start:] + 2 * predict_sigma[m, predict_start:], color='blue',
                             alpha=0.2)
            ax[k].plot(x, labels[m, :], color='r')
            ax[k].axvline(predict_start, color='g', linestyle='dashed')
    
            #metrics = utils.final_metrics_({_k: [_i[k] for _i in _v] for _k, _v in plot_metrics.items()})
    
    
            plot_metrics_str = f'ND: {plot_metrics["ND"][m]: .3f} ' \
                f'RMSE: {plot_metrics["RMSE"][m]: .3f}'
            if sampling:
                plot_metrics_str += f' rou90: {plot_metrics["rou90"][m]: .3f} ' \
                                    f'rou50: {plot_metrics["rou50"][m]: .3f}'
    
            ax[k].set_title(plot_metrics_str, fontsize=10)
    
        f.savefig(os.path.join(plot_dir, str(plot_num) + '.png'))
        plt.close()
    
    
    
    if __name__ == '__main__':
        # Load the parameters
        args = parser.parse_args()
        model_dir = os.path.join('experiments', args.model_name) 
        json_path = os.path.join(model_dir, 'params.json')
        data_dir = os.path.join(args.data_folder, args.dataset)
        assert os.path.isfile(json_path), 'No json configuration file found at {}'.format(json_path)
        params = utils.Params(json_path)
    
        utils.set_logger(os.path.join(model_dir, 'eval.log'))
    
        params.relative_metrics = args.relative_metrics
        params.sampling = args.sampling
        params.model_dir = model_dir
        params.plot_dir = os.path.join(model_dir, 'figures')
        
        cuda_exist = torch.cuda.is_available()  # use GPU is available
    
        # Set random seeds for reproducible experiments if necessary
        if cuda_exist:
            params.device = torch.device('cuda')
            # torch.cuda.manual_seed(240)
            logger.info('Using Cuda...')
            model = net.Net(params).cuda()
        else:
            params.device = torch.device('cpu')
            # torch.manual_seed(230)
            logger.info('Not using cuda...')
            model = net.Net(params)
    
        # Create the input data pipeline
        logger.info('Loading the datasets...')
    
        test_set = TestDataset(data_dir, args.dataset, params.num_class)
        test_loader = DataLoader(test_set, batch_size=params.predict_batch, sampler=RandomSampler(test_set), num_workers=4)
        print("testloader",type(test_loader))
        #print(test_loader)
        logger.info('- done.')
    
        print('model: ', model)
        loss_fn = net.loss_fn
    
        logger.info('Starting evaluation')
    
        # Reload weights from the saved file
        utils.load_checkpoint(os.path.join(model_dir, args.restore_file + '.pkl'), model)
    
        test_metrics = evaluate(model, loss_fn, test_loader, params, -1, params.sampling)
        save_path = os.path.join(model_dir, 'metrics_test_{}.json'.format(args.restore_file))
        utils.save_dict_to_json(test_metrics, save_path)
    
    

    so up to this in plot window function plot_eight_windows i am calculating my y_pred, y_true, y_upper,y_lower, and save those files into a folder. what i have done is i have processed a test dataset and saved it in differnt folder for only inference purposes. and i use this it is in pretrained model in best_pkl. I am getting result but i am in confusion like , am i evaluating here or doing actual inference. what if I call a time range

    2020-04-25 00:00:00 and want to predict the related values o. using my pretrained model. Kindly help me to sort it out

    opened by kb007 0
  • Elaboration on the results.

    Elaboration on the results.

    @zhykoties Hi there, I just wanted to understand the uncertainty estimation graph. Here, red line denotes the likelihood function and the blue denotes the actual ground truth data. In that case, the X-axis is the sample size of the data which is 200 here but I did not understand the Y-axis, what does the Y-axis represent exactly, will you please explain. Also, the values change in the Y-axis. Thanks!

    opened by padmaksha18 1
  • possible bug in preprocessing script related to calculation of z-score (normalization of data)

    possible bug in preprocessing script related to calculation of z-score (normalization of data)

    hello, why is it that v_input is initialized with 2 columns (mean and std i presume) but only one of them is changed. It also looks strange that instead of subtracting the mean, the series is divided by the mean as in the following lines:

    v_input[count, 0] = np.true_divide(x_input[count, 1:input_size, 0].sum(),nonzero_sum)+1
    x_input[count, :, 0] = x_input[count, :, 0]/v_input[count, 0]
    
    opened by super-shayan 0
  • Is it possible to access to the preprocessing done on traffic and parts datasets?

    Is it possible to access to the preprocessing done on traffic and parts datasets?

    I would like to access to the preprocessing realised on these others dataset that appears on the original papers to validate the results, is it possible? Regards.

    opened by fmorenopino 0
  • ValueError: 'a' cannot be empty unless no samples are taken

    ValueError: 'a' cannot be empty unless no samples are taken

    for different train test split dataset I am getting this error

    Traceback (most recent call last):
    
      File "<ipython-input-4-6b0715d9506b>", line 6, in <module>
        args.restore_file)
    
      File "<ipython-input-1-a393da520de1>", line 121, in train_and_evaluate
        test_loader, params, epoch)
    
      File "<ipython-input-1-a393da520de1>", line 83, in train
        test_metrics = evaluate(model, loss_fn, test_loader, params, epoch, sample=args.sampling)
    
      File "/Users/kalyan.admin/KalyanWork/Timeseries_covid/evaluate.py", line 95, in evaluate
        random_sample_10 = np.random.choice(top_10_nd_sample, size=10, replace=True)
    
      File "mtrand.pyx", line 773, in numpy.random.mtrand.RandomState.choice
    

    the implementation worked well. But right now I am getting it for several train test splitting. what will be the solution

    opened by KalyanBanik 1
Owner
Yunkai Zhang
IEOR PhD @ UC Berkeley, math/computing @ UCSB CCS
Yunkai Zhang
Automatically build ARIMA, SARIMAX, VAR, FB Prophet and XGBoost Models on Time Series data sets with a Single Line of Code. Now updated with Dask to handle millions of rows.

Auto_TS: Auto_TimeSeries Automatically build multiple Time Series models using a Single Line of Code. Now updated with Dask. Auto_timeseries is a comp

AutoViz and Auto_ViML 519 Jan 3, 2023
AtsPy: Automated Time Series Models in Python (by @firmai)

Automated Time Series Models in Python (AtsPy) SSRN Report Easily develop state of the art time series models to forecast univariate data series. Simp

Derek Snow 465 Jan 2, 2023
Time series forecasting with PyTorch

Our article on Towards Data Science introduces the package and provides background information. Pytorch Forecasting aims to ease state-of-the-art time

Jan Beitner 2.5k Jan 2, 2023
A Python implementation of GRAIL, a generic framework to learn compact time series representations.

GRAIL A Python implementation of GRAIL, a generic framework to learn compact time series representations. Requirements Python 3.6+ numpy scipy tslearn

null 3 Nov 24, 2021
A machine learning toolkit dedicated to time-series data

tslearn The machine learning toolkit for time series analysis in Python Section Description Installation Installing the dependencies and tslearn Getti

null 2.3k Jan 5, 2023
A unified framework for machine learning with time series

Welcome to sktime A unified framework for machine learning with time series We provide specialized time series algorithms and scikit-learn compatible

The Alan Turing Institute 6k Jan 6, 2023
A machine learning toolkit dedicated to time-series data

tslearn The machine learning toolkit for time series analysis in Python Section Description Installation Installing the dependencies and tslearn Getti

null 2.3k Dec 29, 2022
Python module for machine learning time series:

seglearn Seglearn is a python package for machine learning time series or sequences. It provides an integrated pipeline for segmentation, feature extr

David Burns 536 Dec 29, 2022
Merlion: A Machine Learning Framework for Time Series Intelligence

Merlion is a Python library for time series intelligence. It provides an end-to-end machine learning framework that includes loading and transforming data, building and training models, post-processing model outputs, and evaluating model performance. I

Salesforce 2.8k Jan 5, 2023
Tool for producing high quality forecasts for time series data that has multiple seasonality with linear or non-linear growth.

Prophet: Automatic Forecasting Procedure Prophet is a procedure for forecasting time series data based on an additive model where non-linear trends ar

Facebook 15.4k Jan 7, 2023
Open source time series library for Python

PyFlux PyFlux is an open source time series library for Python. The library has a good array of modern time series models, as well as a flexible array

Ross Taylor 2k Jan 2, 2023
Automatic extraction of relevant features from time series:

tsfresh This repository contains the TSFRESH python package. The abbreviation stands for "Time Series Feature extraction based on scalable hypothesis

Blue Yonder GmbH 7k Jan 6, 2023
A statistical library designed to fill the void in Python's time series analysis capabilities, including the equivalent of R's auto.arima function.

pmdarima Pmdarima (originally pyramid-arima, for the anagram of 'py' + 'arima') is a statistical library designed to fill the void in Python's time se

alkaline-ml 1.3k Dec 22, 2022
Probabilistic time series modeling in Python

GluonTS - Probabilistic Time Series Modeling in Python GluonTS is a Python toolkit for probabilistic time series modeling, built around Apache MXNet (

Amazon Web Services - Labs 3.3k Jan 3, 2023
A python library for easy manipulation and forecasting of time series.

Time Series Made Easy in Python darts is a python library for easy manipulation and forecasting of time series. It contains a variety of models, from

Unit8 5.2k Jan 4, 2023
STUMPY is a powerful and scalable Python library for computing a Matrix Profile, which can be used for a variety of time series data mining tasks

STUMPY STUMPY is a powerful and scalable library that efficiently computes something called the matrix profile, which can be used for a variety of tim

TD Ameritrade 2.5k Jan 6, 2023
A Python package for time series classification

pyts: a Python package for time series classification pyts is a Python package for time series classification. It aims to make time series classificat

Johann Faouzi 1.4k Jan 1, 2023
A Python toolkit for rule-based/unsupervised anomaly detection in time series

Anomaly Detection Toolkit (ADTK) Anomaly Detection Toolkit (ADTK) is a Python package for unsupervised / rule-based time series anomaly detection. As

Arundo Analytics 888 Dec 30, 2022
A python library for Bayesian time series modeling

PyDLM Welcome to pydlm, a flexible time series modeling library for python. This library is based on the Bayesian dynamic linear model (Harrison and W

Sam 438 Dec 17, 2022