Want to share your content on R-bloggers? click here if you have a blog, or here if you don't.
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:
- Python’s Flask for backend development
- Bootswatch for the HTML/CSS theme
- Plotly for interactive graphs
- SQLAlchemy| PostgreSQL for database management
- Swagger for API documentation
- Salesforce’s Heroku (Cloud Application Platform) for deploying the application
The application is here:
https://techtonique2.herokuapp.com/
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":"tester_curl@example.com","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': 'tester_py@example.com', '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":"tester_r@example.com","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 tester_curl@example.com: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=('tester_py@example.com', '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('tester_r@example.com', '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)
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-validationn_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, andn_training
remains constant.-
n_training
is incremented of 1 at each iteration, andstart_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.
R-bloggers.com offers daily e-mail updates about R news and tutorials about learning R and many other topics. Click here if you're looking to post or find an R/data-science job.
Want to share your content on R-bloggers? click here if you have a blog, or here if you don't.