/Time-series-prediction

Deep learning time series prediction with TensorFlow - TFTS

Primary LanguagePythonMIT LicenseMIT


LICENSE PyPI Version Download Build Status Lint Status Docs Status Code Coverage Contributing CodeQL Status

Documentation | Tutorials | Release Notes | 中文

TFTS (TensorFlow Time Series) is an easy-to-use python package for time series, supporting the classical and SOTA deep learning methods in TensorFlow or Keras.

Tutorial

Installation

  • python >= 3.7
  • tensorflow >= 2.4
$ pip install tfts

Basic usage

Open In Colab

import matplotlib.pyplot as plt
import tfts
from tfts import AutoModel, AutoConfig, KerasTrainer

train_length = 24
predict_length = 8
(x_train, y_train), (x_valid, y_valid) = tfts.get_data("sine", train_length, predict_length, test_size=0.2)

model = AutoModel("seq2seq", predict_length=predict_length)
trainer = KerasTrainer(model)
trainer.train((x_train, y_train), (x_valid, y_valid), n_epochs=3)

pred = trainer.predict(x_valid)
trainer.plot(history=x_valid, true=y_valid, pred=pred)
plt.show()

Prepare your own data

You could train your own data by preparing 3D data as inputs, for both inputs and targets

  • option1 np.ndarray
  • option2 tf.data.Dataset

Encoder only model inputs

train_length = 49
predict_length = 10
n_feature = 2

x_train = np.random.rand(1, train_length, n_feature)  # feature: (n, train_length, feature)
y_train = np.random.rand(1, predict_length, 1)  # y: (n, predict_length, 1)
x_valid = np.random.rand(1, train_length, n_feature)
y_valid = np.random.rand(1, predict_length, 1)

model = AutoModel("rnn", predict_length=predict_length)
trainer = KerasTrainer(model)
trainer.train(train_dataset=(x_train, y_train), valid_dataset=(x_valid, y_valid), n_epochs=1)

Encoder-decoder model inputs

# option1: np.ndarray

train_length = 49
predict_length = 10
n_encoder_feature = 2
n_decoder_feature = 3

x_train = (
    np.random.rand(1, train_length, 1),  # x: (n, train_length, 1)
    np.random.rand(1, train_length, n_encoder_feature),  # encoder_feature: (n, train_length, encoder_features)
    np.random.rand(1, predict_length, n_decoder_feature),  # decoder_feature: (n, predict_length, decoder_features)
)
y_train = np.random.rand(1, predict_length, 1)  # y: (n, predict_length, 1)
x_valid = (
    np.random.rand(1, train_length, 1),
    np.random.rand(1, train_length, n_encoder_feature),
    np.random.rand(1, predict_length, n_decoder_feature),
)
y_valid = np.random.rand(1, predict_length, 1)

model = AutoModel("seq2seq", predict_length=predict_length)
trainer = KerasTrainer(model)
trainer.train((x_train, y_train), (x_valid, y_valid), n_epochs=1)
# option2: tf.data.Dataset

class FakeReader(object):
    def __init__(self, predict_length=10):
        train_length = 49
        n_encoder_feature = 2
        n_decoder_feature = 3
        self.x = np.random.rand(15, train_length, 1)
        self.encoder_feature = np.random.rand(15, train_length, n_encoder_feature)
        self.decoder_feature = np.random.rand(15, predict_length, n_decoder_feature)
        self.target = np.random.rand(15, predict_length, 1)

    def __len__(self):
        return len(self.x)

    def __getitem__(self, idx):
        return {
            "x": self.x[idx],
            "encoder_feature": self.encoder_feature[idx],
            "decoder_feature": self.decoder_feature[idx],
        }, self.target[idx]

    def iter(self):
        for i in range(len(self.x)):
            yield self[i]


predict_length = 10
train_reader = FakeReader(predict_length=10)
train_loader = tf.data.Dataset.from_generator(
    train_reader.iter,
    ({"x": tf.float32, "encoder_feature": tf.float32, "decoder_feature": tf.float32}, tf.float32),
)
train_loader = train_loader.batch(batch_size=1)
valid_reader = FakeReader(predict_length=10)
valid_loader = tf.data.Dataset.from_generator(
    valid_reader.iter,
    ({"x": tf.float32, "encoder_feature": tf.float32, "decoder_feature": tf.float32}, tf.float32),
)
valid_loader = valid_loader.batch(batch_size=1)

model = AutoModel("seq2seq", predict_length=predict_length)
trainer = KerasTrainer(model)
trainer.train(train_dataset=train_loader, valid_dataset=valid_loader, n_epochs=1)

Build your own model

The models tfts support to use in AutoModel()

  • rnn
  • tcn
  • bert
  • nbeats
  • seq2seq
  • wavenet
  • transformer

You could build the model based on tfts backbone, especially

  • add custom-defined embeddings for categorical variables
  • add custom-defined head layers for classification or anomaly task
import tensorflow as tf
from tensorflow.keras.layers import Input, Dense
from tfts import AutoModel


def build_model():
    train_length = 24
    train_features = 15
    predict_length = 16

    inputs = Input([train_length, train_features])
    backbone = AutoModel("seq2seq", predict_length=predict_length)
    outputs = backbone(inputs)
    outputs = Dense(1, activation="sigmoid")(outputs)
    model = tf.keras.Model(inputs=inputs, outputs=outputs)
    model.compile(loss="mse", optimizer="rmsprop")
    return model

Examples

  • TFTS-Bert wins the 3rd place in KDD Cup 2022 Baidu-wind power forecasting
  • TFTS-Seq2seq wins the 4th place in Alibaba Tianchi-ENSO prediction 2021

if you prefer other DL frameworks, try pytorch-forecasting, gluonts, paddlets

Citation

If you find tfts project useful in your research, please consider cite:

@misc{tfts2020,
  author = {Longxing Tan},
  title = {Time series prediction},
  year = {2020},
  publisher = {GitHub},
  journal = {GitHub repository},
  howpublished = {\url{https://github.com/longxingtan/time-series-prediction}},
}