The finnts package, commonly referred to as “Finn”, is a standardized times series forecast framework developed by Microsoft Finance. It’s a result of years of effort trying to perfect a centralized forecasting practice that everyone in finance could leverage. Even though it was built for finance like forecasts, it can easily be extended to any type of time series forecast.
Finn takes years of hard work and thousands of lines of code, and simplifies the forecasting process down to a an AI agent that can optimize a forecast for you or a few function calls that give you total control over the forecast Finn creates. In order to leverage the best components of Finn, please check out all of the other vignettes within the package.
library(finnts)
browseVignettes("finnts")
The easiest way to use Finn is through the built in AI agent. The agent learns about your data and runs experiements to create the most accurate forecast possible. Here’s how to get started with the agent.
Data used in Finn needs to follow a few requirements, called out below.
A good example to use when producing your first Finn forecast is to leverage existing data examples from the timetk package. Let’s take a monthly example and trim it down to speed up the run time of your first Finn forecast.
library(finnts)
hist_data <- timetk::m4_monthly %>%
dplyr::filter(date >= "2013-01-01") %>%
dplyr::rename(Date = date) %>%
dplyr::mutate(id = as.character(id))
print(hist_data)
#> # A tibble: 120 × 3
#> id Date value
#> <chr> <date> <dbl>
#> 1 M1 2013-01-01 9120
#> 2 M1 2013-02-01 8280
#> 3 M1 2013-03-01 7860
#> 4 M1 2013-04-01 7150
#> 5 M1 2013-05-01 8110
#> 6 M1 2013-06-01 10860
#> 7 M1 2013-07-01 10730
#> 8 M1 2013-08-01 9610
#> 9 M1 2013-09-01 8270
#> 10 M1 2013-10-01 9200
#> # ℹ 110 more rows
print(unique(hist_data$id))
#> [1] "M1" "M2" "M750" "M1000"
The above data set contains 4 individual time series, identified using the “id” column.
Before any forecasts are created, we need to set up the agent. This
is done by setting up a new project with
set_project_info()
, then initialize the agent with
set_agent_info()
.
In order to use the agent, we must first connect it to a LLM using the ellmer package.
# connect to LLM via Azure AI
driver_llm <- ellmer::chat_azure_openai(model = "gpt-4o-mini")
Now we can use that LLM inside of our agent when setting it up.
# set up new forecast project and agent run
project <- set_project_info(
project_name = "Demo_Project",
combo_variables = c("id"),
target_variable = "value",
date_type = "month"
)
agent <- set_agent_info(
project_info = project,
driver_llm = driver_llm,
input_data = hist_data,
forecast_horizon = 12,
hist_end_date = as.Date("2014-12-01")
)
Once the agent is set up and fed data, we can now have it automatically optimize for the most accurate forecast. The agent will try various combinations of feature engineering techniques, ML algorithms, etc. to create the best forecast. We can give the agent constraints around how many iterations it can try and what accuracy goal it should strive to beat. Let’s have it run at most 3 different forecast iterations with an accuracy goal of a 3% weighted MAPE.
iterate_forecast(
agent_info = agent,
max_iter = 3,
weighted_mape_goal = 0.03
)
After the agent completes the forecast iteration, we can take a look at the final results.
forecast_output <- get_agent_forecast(agent_info = agent)
Here’s a breakdown of the major columns in the Finn forecast output.
set_project_info()
.set_project_info()
.To see which inputs were used by the agent to create the optimal
forecast, you can call get_best_agent_run()
. This allows us
to see what kind of feature engineering was applied, as well as what
models were chosen to run. More information about the inputs used by the
agent in each Finn run iteration can be found in the other
vignettes.
agent_run_results <- get_best_agent_run(agent_info = agent, full_run_info = TRUE)
After the agent runs iterate_forecast()
, we can use the
previously trained models to get updated forecasts with new data. This
makes it easy to get updated forecasts fast.
# set up agent with updated data
# overwrite creates a new version of the agent, which is required when running update_forecast()
agent <- set_agent_info(
project_info = project,
driver_llm = driver_llm,
input_data = hist_data,
forecast_horizon = 6,
hist_end_date = as.Date("2015-06-01"),
overwrite = TRUE
)
# update forecast
update_forecast(
agent_info = agent,
weighted_mape_goal = 0.03
)
# get updated forecast output
updated_forecast_output <- get_agent_forecast(agent_info = agent)