A web application for forecasting in Python, R, Ruby, C#, JavaScript, PHP, Go, Rust, Java, MATLAB, etc.

This article was first published on T. Moudiki's Webpage - Python , and kindly contributed to python-bloggers. (You can report issue about the content on this page here)
Want to share your content on python-bloggers? click here.

Content

  • 0 – Intro
  • 1 – Create an account
  • 2 – Get a token for authentication
  • 3 – Requests for forecasts
  • 4 – On model calibration and cross-validation

0 – Intro

In this post, I’ll describe an (work-in-progress) Application Programming Interface (API) for time series forecasting. An API is a system that can receive requests from your computer, to carry out given tasks on given resources, and return a response. This type of system is programming-language-agnostic. That means: it can be used with Python, JavaScript, PHP, R, Go, C#, Ruby, Rust, Java, MATLAB, Julia, and any other programming language speaking http. And therefore, it could be relatively easily integrated into existing workflows for uncertainty forecasting. I’ve used the following tools for building it:

The application is here:

https://techtonique2.herokuapp.com/

app's homepage

In the homepage (“/”), you can plot a time series by uploading a csv file, and pushing the button “Plot!”. Some examples of input files are stored on GitHub, at https://github.com/Techtonique/datasets/tree/main/time_series/univariate. Hover your cursor over the graph to see the options available, like downloading as png, zooming in and out, etc. Let’s describe the API now.

1 – Create an account:

In order to sign up, you can use your username or an email address. A valid email address is preferable, because usernames duplicates aren’t authorized in the database. You don’t want to spend your precious time trying to figure out which username hasn’t been registered yet! In addition, without a valid email address, you won’t be notified for changes and improvements in the API (e.g new forecasting models added, bugs fixes…).

Using curl

curl -X POST -H "Content-Type: application/json" -d '{"username":"[email protected]","password":"pwd"}' https://techtonique2.herokuapp.com/api/users

If you want to translate these commands from curl to your favorite programming language (Python, JavaScript, PHP, R, Go, C#, Ruby, Rust, Elixir, Java, MATLAB, Dart, CFML, Ansible URI, Strest), you can simply use the following website: https://curlconverter.com/. Of course, it’s important to choose a better password!

Using Python

In the near future, there will be a user-friendly Python package encapsulating these steps.

import requests

headers = {
    # Already added when you pass json=
    # 'Content-Type': 'application/json',
}

json_data = {
    'username': '[email protected]',
    'password': 'pwd',
}

response = requests.post('https://techtonique2.herokuapp.com/api/users', headers=headers, json=json_data)

Using R

In the near future, there will be a user-friendly R package encapsulating these steps.

require(httr)

headers = c(
  `Content-Type` = 'application/json'
)

data = '{"username":"[email protected]","password":"pwd"}'

res <- httr::POST(url = 'https://techtonique2.herokuapp.com/api/users', 
                  httr::add_headers(.headers=headers), body = data)

print(res)

Now that you have an account, you’ll need a token to obtain time series forecasts.
The username and password could be used for that purpose, but it’s better to avoid
sending them in every request. In any case, make sure that you’re always sending
requests to https:// and not http://.

2 – Get a token for authentication

Using curl

curl -u [email protected]:pwd -X GET https://techtonique2.herokuapp.com/api/token 

If you want to translate these commands from curl to your favorite programming language (Python, JavaScript, PHP, R, Go, C#, Ruby, Rust, Elixir, Java, MATLAB, Dart, CFML, Ansible URI, Strest), you can simply use the following website: https://curlconverter.com/.

Using Python

In the near future, there will be a user-friendly Python package encapsulating these steps.

response_token = requests.get('https://techtonique2.herokuapp.com/api/token', 
auth=('[email protected]', 'pwd'))

token = response_token.json()['token']

print("\n")
print(f"token: {token}")

Using R

In the near future, there will be a user-friendly R package encapsulating these steps.

res_token <- httr::GET(url = 'https://techtonique2.herokuapp.com/api/token', 
                 httr::authenticate('[email protected]', 'python22orpython33'))

print(res_token)

(token <- httr::content(res_token)$token)

3 – Requests for forecasts

We want to obtain 10 months-ahead forecasts
for the number of accidental Deaths in the US from 1973 to 1978
, and
a confidence level of 95% for prediction intervals. The forecasting method is
Theta from [1] and [2], winner of the M3 competition.

The token from section 2 (valid for 5 minutes)
will be used here for authentication. You should read the API’s documentation to understand each forecasting model’s parameters.

Using curl

curl -u eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpOCsOC8-I:x -F 'file=@/Users/t/Documents/datasets/time_series/univariate/USAccDeaths.csv' "https://techtonique2.herokuapp.com/api/theta?h=10&level=95"

If you want to translate these commands from curl to your favorite programming language (Python, JavaScript, PHP, R, Go, C#, Ruby, Rust, Elixir, Java, MATLAB, Dart, CFML, Ansible URI, Strest), you can simply use the following website: https://curlconverter.com/.

eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpOCsOC8-I is a simplified example of the type of token which can be obtained in step 2. The csv file sent in the request must be stored on your computer. Examples of such files can be found here.

Using Python

In the near future, there will be a user-friendly Python package encapsulating these steps.

params = {
    'h': '10',
    'level': '95',
}


files = {
    'file': open('./USAccDeaths.csv', 'rb') # File available at https://github.com/Techtonique/datasets/tree/main/time_series/univariate
}

response_forecast = requests.post('https://techtonique2.herokuapp.com/api/theta', 
files=files, params=params, auth=(token, 'x'))

print(response_forecast.json())

Using R

In the near future, there will be a user-friendly R package encapsulating these steps.

params = list(
  `h` = '10', # horizon
  `level` = '95' # level of confidence for prediction intervals
)

files = list(
  `file` = upload_file('./USAccDeaths.csv') # File available at https://github.com/Techtonique/datasets/tree/main/time_series/univariate
)

ptm <- proc.time()[3]
res_forecast <- httr::POST(url = 'https://techtonique2.herokuapp.com/api/theta', 
                           query = params, body = files, encode = 'multipart', 
                           httr::authenticate(token, 'x'))
proc.time()[3] - ptm

list_res <- httr::content(res_forecast)

# Plot results

# 1 - Results From R package forecast -----

require(forecast)

(forecast_object_R <- forecast::thetaf(USAccDeaths, h=10, level = 95))


# 2 - Results From a Python implementation (in the API) -----

h <- length(list_res$ranges)

forecast_object_api <- list()
forecast_object_api$mean <- forecast_object_api$upper <- forecast_object_api$lower <- ts(rep(0, h), 
                                                                             start = start(forecast_object_R$mean),
                                                                             frequency = frequency(forecast_object_R$x))

for (i in 1:h)
{
  forecast_object_api$mean[i] <- list_res$averages[[i]][[2]]
  forecast_object_api$lower[i] <- list_res$ranges[[i]][[2]]
  forecast_object_api$upper[i] <- list_res$ranges[[i]][[3]]
}

forecast_object_api$x <- forecast_object_R$x
forecast_object_api$method <- paste0(forecast_object_R$method, " (API)")
forecast_object_api$level <- forecast_object_R$level
forecast_object_api <- structure(forecast_object_api, class = "forecast")

print(forecast_object_api)
print(forecast_object_R)

# graphs

par(mfrow=c(1, 2))
plot(forecast_object_R)
plot(forecast_object_api)

api responses

4 – On model calibration and cross-validation

Each model in the API has 2 additional parameters that we haven’t discussed yet:

  • start_training: Start training index for cross-validation
  • n_training: Size of training set window for cross-validation

Both of these parameters are to be used in a loop, in your favorite programming language,
when you want to compare models’ performance, or tune their hyperparameters (model calibration).
You’d code a loop (with 3-seconds delays between each API call in the loop, because you’re nice!) in which:

  • start_training is incremented of 1 at each iteration, and n_training
    remains constant.
  • n_training is incremented of 1 at each iteration, and start_training
    remains constant.

More on this (cross-validation and model calibration) in a future post. Stay tuned.


[1] Assimakopoulos, V., & Nikolopoulos, K. (2000). The theta model: a decomposition approach to forecasting. International journal of forecasting, 16(4), 521-530.

[2] Hyndman, R. J., & Billah, B. (2003). Unmasking the Theta method. International Journal of Forecasting, 19(2), 287-290.

To leave a comment for the author, please follow the link and comment on their blog: T. Moudiki's Webpage - Python .

Want to share your content on python-bloggers? click here.