Skip to main content

Time-Series Forecasting

Input Limitations

execute is the core method of forecasting algorithms. Before calling this method, the framework configures the historical time-series data used for forecasting in the self.list object attribute.

Output Limitations and Parent Class Attributes

Running the execute method generates the following dictionary objects:

return {
"mse": mse, # Mean squared error of the fit data
"res": res # Result groups [timestamp, forecast results, lower boundary of confidence interval, upper boundary of confidence interval]
}

The parent class AbstractForecastService of forecasting algorithms includes the following object attributes.

AttributeDescriptionDefault
periodSpecify the periodicity of the data, i.e. the number of data points included in each period. If the data is not periodic, enter 0.0
start_tsSpecify the start time of forecasting results.0
time_stepSpecify the interval between consecutive data points in the forecast results.0
fc_rowsSpecify the number of forecast rows to return.0
return_confSpecify 1 to include a confidence interval in the forecast results or 0 to not include a confidence interval in the results. If you specify 0, the mean is returned as the upper and lower boundaries.1
confSpecify a confidence interval quantile.95

Sample Code

The following code is an sample algorithm that always returns 1 as the forecast results.

import numpy as np
from taosanalytics.service import AbstractForecastService


# Algorithm files must start with an underscore ("_") and end with "Service".
class _MyForecastService(AbstractForecastService):
""" Define a class inheriting from AbstractAnomalyDetectionService and implementing the `execute` method. """

# Name the algorithm using only lowercase ASCII characters.
name = 'myfc'

# Include a description of the algorithm (recommended)
desc = """return the forecast time series data"""

def __init__(self):
"""Method to initialize the class"""
super().__init__()

def execute(self):
""" Implementation of algorithm logic"""
res = []

"""This algorithm always returns 1 as the forecast result. The number of results returned is determined by the self.fc_rows value input by the user."""
ts_list = [self.start_ts + i * self.time_step for i in range(self.fc_rows)]
res.append(ts_list) # set timestamp column for forecast results

"""Generate forecast results whose value is 1. """
res_list = [1] * self.fc_rows
res.append(res_list)

"""Check whether user has requested the upper and lower boundaries of the confidence interval."""
if self.return_conf:
"""If the algorithm does not calculate these values, return the forecast results."""
bound_list = [1] * self.fc_rows
res.append(bound_list) # lower confidence limit
res.append(bound_list) # upper confidence limit

"""Return results"""
return {"res": res, "mse": 0}

def set_params(self, params):
"""This algorithm does not take any parameters, only calling a parent function, so this logic is not included."""
return super().set_params(params)

Save this file to the ./lib/taosanalytics/algo/fc/ directory and restart the taosanode service. In the TDengine CLI, run SHOW ANODES FULL to see your new algorithm. Your applications can now use this algorithm via SQL.

--- Detect anomalies in the `col` column using the newly added `myfc` algorithm
SELECT _flow, _fhigh, _frowts, FORECAST(col_name, "algo=myfc")
FROM foo;

If you have never started the anode, see Operations & Maintenance to add the anode to your TDengine cluster.

Unit Testing

You can add unit test cases to the forecase_test.py file in the taosanalytics/test directory or create a file for unit tests. Unit tests have a dependency on the Python unittest module.

def test_myfc(self):
""" Test the myfc class """
s = loader.get_service("myfc")

# Configure data for forecasting
s.set_input_list(self.get_input_list(), None)
# Check whether all results are 1
r = s.set_params(
{"fc_rows": 10, "start_ts": 171000000, "time_step": 86400 * 30, "start_p": 0}
)
r = s.execute()

expected_list = [1] * 10
self.assertEqlist(r["res"][0], expected_list)