M5 Competition¶
Introduction¶
The M5 Competition, held in 2020, was part of the prestigious Makridakis Forecasting Competitions. The goal of this competition was to accurately forecast the sales of 3,000 individual items across 10 Walmart stores for the next 28 days. The winning strategy involved transforming and augmenting the raw multivariate time series data into a tabular dataset, which was then used to train a collection of Gradient Boosted Trees models.
See https://www.kaggle.com/competitions/m5-forecasting-accuracy/overview.
In this notebook, we show how Temporian can replicate such data preprocessing and feature engineering with low effort. More specifically, we will replicate, with much less code, the preprocessing demonstrated at the Khipu 2023: A Hands-On Forecasting Guide, which was done with Pandas.
The notebook is divided into three parts:
- Loading the dataset and initial cleaning using Pandas.
- Temporal feature engineering using Temporian.
- Training and evaluation of a model using TensorFlow Decision Forests.
The following preprocessing operations will be applied using Temporian:
- label: Compute forecasting labels i.e. future leak of sales data.
- lagged sales: Give access to previous sales data.
- moving statistics: Moving average, sum and standard deviation of the sales over the last 7, 14, 28 and 64 days.
- calendar features: Extract discriminative calendar features such as day of the week, day of the month, etc.
- aggregated sales: Aggregate sales per department. Each item has access to the sales of its corresponding department.
- special events: Holidays, sales, and other special events.
- train / test split: Split the data between a training and testing dataset.
Install and import dependencies¶
%pip install temporian -q
# The Bokeh package is used by Temporian to create interactive plots.
# If if Bokeh is not installed, Temporian plots are static.
%pip install bokeh -q
[notice] A new release of pip is available: 23.1.2 -> 23.2.1 [notice] To update, run: pip install --upgrade pip Note: you may need to restart the kernel to use updated packages. [notice] A new release of pip is available: 23.1.2 -> 23.2.1 [notice] To update, run: pip install --upgrade pip Note: you may need to restart the kernel to use updated packages.
import os
import urllib.request
import zipfile
from collections import defaultdict
from datetime import datetime, timedelta, timezone
from typing import List
import pandas as pd
import temporian as tp
Download the raw data¶
The M5 dataset is a collection of csv files.
# Directory to download the raw M5 dataset and to export the result.
work_directory = "tmp/temporian_m5"
os.makedirs(work_directory, exist_ok=True)
# Download the M5 dataset
raw_data_zip = os.path.join(work_directory, "raw.zip")
if not os.path.exists(raw_data_zip):
url = "https://docs.google.com/uc?export=download&id=1NYHXmgrcXg50zR4CVWPPntHx9vvU5jbM&confirm=t"
urllib.request.urlretrieve(url, raw_data_zip)
# Extract the M5 dataset
raw_data_dir = os.path.join(work_directory, "raw")
if not os.path.exists(raw_data_dir):
with zipfile.ZipFile(raw_data_zip, "r") as zip_ref:
zip_ref.extractall(raw_data_dir)
!ls -lh tmp/temporian_m5/raw
total 430M -rw-r----- 1 gbm primarygroup 102K Aug 18 21:48 calendar.csv -rw-r----- 1 gbm primarygroup 117M Aug 18 21:48 sales_train_evaluation.csv -rw-r----- 1 gbm primarygroup 115M Aug 18 21:48 sales_train_validation.csv -rw-r----- 1 gbm primarygroup 5.0M Aug 18 21:48 sample_submission.csv -rw-r----- 1 gbm primarygroup 194M Aug 18 21:48 sell_prices.csv
Load raw dataset¶
The dataset is a set of csv files. We are using Pandas to load it and do some initial non-temporal preparations.
raw_path = lambda x: os.path.join(raw_data_dir, x)
raw_sales = pd.read_csv(raw_path("sales_train_evaluation.csv"))
raw_sell_prices = pd.read_csv(raw_path("sell_prices.csv"))
raw_calendar = pd.read_csv(raw_path("calendar.csv"))
# Print the name, type and memory usage of the raw data columns.
print("==========\nraw_sales\n")
raw_sales.info()
print("==========\nraw_sell_prices\n")
raw_sell_prices.info()
print("==========\nraw_calendar_raw\n")
raw_calendar.info()
========== raw_sales <class 'pandas.core.frame.DataFrame'> RangeIndex: 30490 entries, 0 to 30489 Columns: 1947 entries, id to d_1941 dtypes: int64(1941), object(6) memory usage: 452.9+ MB ========== raw_sell_prices <class 'pandas.core.frame.DataFrame'> RangeIndex: 6841121 entries, 0 to 6841120 Data columns (total 4 columns): # Column Dtype --- ------ ----- 0 store_id object 1 item_id object 2 wm_yr_wk int64 3 sell_price float64 dtypes: float64(1), int64(1), object(2) memory usage: 208.8+ MB ========== raw_calendar_raw <class 'pandas.core.frame.DataFrame'> RangeIndex: 1969 entries, 0 to 1968 Data columns (total 14 columns): # Column Non-Null Count Dtype --- ------ -------------- ----- 0 date 1969 non-null object 1 wm_yr_wk 1969 non-null int64 2 weekday 1969 non-null object 3 wday 1969 non-null int64 4 month 1969 non-null int64 5 year 1969 non-null int64 6 d 1969 non-null object 7 event_name_1 162 non-null object 8 event_type_1 162 non-null object 9 event_name_2 5 non-null object 10 event_type_2 5 non-null object 11 snap_CA 1969 non-null int64 12 snap_TX 1969 non-null int64 13 snap_WI 1969 non-null int64 dtypes: int64(7), object(7) memory usage: 215.5+ KB
Downsample the dataset¶
During development, we restrict the dataset to a subset of items for fast iteration.
Once you are happy with the result, we can use the full dataset with downsample_dataset=False
.
Each product will result in ~1900 examples in the final tabular dataset. For example, using a sample of 100 products will train a model on 190.000 examples which is more than enough for a quick demonstration.
downsample_dataset = True
if downsample_dataset:
# The items with the most sales.
selected_items_names = ['FOODS_3_090', 'FOODS_3_586', 'FOODS_3_252', 'FOODS_3_555',
'FOODS_3_587', 'FOODS_3_714', 'FOODS_3_694', 'FOODS_3_226',
#'FOODS_3_202', 'FOODS_3_120', 'FOODS_3_723', 'FOODS_3_635',
#'FOODS_3_808', 'FOODS_3_377', 'FOODS_3_541', 'FOODS_3_080',
#'FOODS_3_318', 'FOODS_2_360', 'FOODS_3_681', 'FOODS_3_234',
]
sampled_raw_sales = raw_sales[raw_sales["item_id"].isin(selected_items_names)]
print("Number of selected items:", len(sampled_raw_sales))
raw_sales = sampled_raw_sales
Number of selected items: 80
Normalize dataset¶
Each of the three tables sales_raw
, sell_prices_raw
and calendar_raw
contains different information: sales_raw
contains the daily sales of each product in each store, sell_prices_raw
contains selling prices, and calendar_raw
contains calendar events such as holidays.
Each table represents temporal data in a different way. For example, timestamps are stored by columns in sales_raw
and by rows in sell_prices_raw
and calendar_raw
. The three tables also use a different system to represent dates.
In Temporian, the data is always expressed as an EventSet. Let's normalize and convert the raw tables to EventSets. EventSets can be built manually with tp.event_set()
or they can be imported from Pandas DataFrames with tp.from_pandas()
. In this case, timestamps need to be organized by rows.
Normalize raw_sales
¶
Before:
raw_sales.head()
id | item_id | dept_id | cat_id | store_id | state_id | d_1 | d_2 | d_3 | d_4 | ... | d_1932 | d_1933 | d_1934 | d_1935 | d_1936 | d_1937 | d_1938 | d_1939 | d_1940 | d_1941 | |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
2314 | FOODS_3_090_CA_1_evaluation | FOODS_3_090 | FOODS_3 | FOODS | CA_1 | CA | 107 | 182 | 47 | 47 | ... | 77 | 47 | 74 | 38 | 42 | 39 | 51 | 69 | 67 | 64 |
2450 | FOODS_3_226_CA_1_evaluation | FOODS_3_226 | FOODS_3 | FOODS | CA_1 | CA | 13 | 9 | 2 | 10 | ... | 5 | 11 | 9 | 1 | 5 | 4 | 3 | 3 | 5 | 5 |
2476 | FOODS_3_252_CA_1_evaluation | FOODS_3_252 | FOODS_3 | FOODS | CA_1 | CA | 19 | 14 | 10 | 8 | ... | 38 | 61 | 61 | 36 | 34 | 39 | 30 | 32 | 50 | 50 |
2779 | FOODS_3_555_CA_1_evaluation | FOODS_3_555 | FOODS_3 | FOODS | CA_1 | CA | 23 | 16 | 14 | 10 | ... | 20 | 26 | 25 | 19 | 19 | 26 | 16 | 15 | 32 | 26 |
2810 | FOODS_3_586_CA_1_evaluation | FOODS_3_586 | FOODS_3 | FOODS | CA_1 | CA | 42 | 36 | 30 | 23 | ... | 42 | 45 | 71 | 34 | 46 | 33 | 18 | 33 | 48 | 43 |
5 rows × 1947 columns
Each daily sales value is stored in a different column. Instead, we want for each value (which in Temporian we refer to as an event) to be in a different row.
For example, the record:
id,item_id,dept_id,d_1,d_2,d_3,...,d_n
will be converted to the following records:
id,item_id,dept_id,day,d_1
id,item_id,dept_id,day,d_2
...
id,item_id,dept_id,day,d_n
cleaned_sales = pd.melt(
raw_sales,
var_name="day",
value_name="sales",
id_vars=["id", "item_id", "dept_id", "cat_id", "store_id", "state_id"],
)
cleaned_sales["day"] = cleaned_sales["day"].apply(lambda x: int(x[2:]))
The timestamps are expressed in number of days since 29/1/2011
.
Let's convert them into python datetimes.
origin_date = datetime(2011, 1, 29, tzinfo=timezone.utc)
cleaned_sales["timestamp"] = cleaned_sales["day"].apply(
lambda x: (origin_date + timedelta(days=x - 1))
)
Finally, we can remove the fields we won't use.
del cleaned_sales["id"]
After:
cleaned_sales.head()
item_id | dept_id | cat_id | store_id | state_id | day | sales | timestamp | |
---|---|---|---|---|---|---|---|---|
0 | FOODS_3_090 | FOODS_3 | FOODS | CA_1 | CA | 1 | 107 | 2011-01-29 00:00:00+00:00 |
1 | FOODS_3_226 | FOODS_3 | FOODS | CA_1 | CA | 1 | 13 | 2011-01-29 00:00:00+00:00 |
2 | FOODS_3_252 | FOODS_3 | FOODS | CA_1 | CA | 1 | 19 | 2011-01-29 00:00:00+00:00 |
3 | FOODS_3_555 | FOODS_3 | FOODS | CA_1 | CA | 1 | 23 | 2011-01-29 00:00:00+00:00 |
4 | FOODS_3_586 | FOODS_3 | FOODS | CA_1 | CA | 1 | 42 | 2011-01-29 00:00:00+00:00 |
Let's now convert cleaned_sales
to a Temporian EventSet.
sales_evset = tp.from_pandas(
cleaned_sales,
indexes=["item_id", "dept_id", "cat_id", "store_id", "state_id"],
)
sales_evset
WARNING:root:Feature "item_id" is an array of numpy.object_ and was casted to numpy.string_ (Note: numpy.string_ is equivalent to numpy.bytes_). WARNING:root:Feature "dept_id" is an array of numpy.object_ and was casted to numpy.string_ (Note: numpy.string_ is equivalent to numpy.bytes_). WARNING:root:Feature "cat_id" is an array of numpy.object_ and was casted to numpy.string_ (Note: numpy.string_ is equivalent to numpy.bytes_). WARNING:root:Feature "store_id" is an array of numpy.object_ and was casted to numpy.string_ (Note: numpy.string_ is equivalent to numpy.bytes_). WARNING:root:Feature "state_id" is an array of numpy.object_ and was casted to numpy.string_ (Note: numpy.string_ is equivalent to numpy.bytes_).
Index: (item_id=FOODS_3_090, dept_id=FOODS_3, cat_id=FOODS, store_id=CA_1, state_id=CA)
1941 eventstimestamp | day | sales |
---|---|---|
2011-01-29 00:00:00+00:00 | 1 | 107 |
2011-01-30 00:00:00+00:00 | 2 | 182 |
2011-01-31 00:00:00+00:00 | 3 | 47 |
2011-02-01 00:00:00+00:00 | 4 | 47 |
2011-02-02 00:00:00+00:00 | 5 | 62 |
2011-02-03 00:00:00+00:00 | 6 | 90 |
2011-02-04 00:00:00+00:00 | 7 | 81 |
2011-02-05 00:00:00+00:00 | 8 | 124 |
2011-02-06 00:00:00+00:00 | 9 | 134 |
2011-02-07 00:00:00+00:00 | 10 | 65 |
2011-02-08 00:00:00+00:00 | 11 | 0 |
2011-02-09 00:00:00+00:00 | 12 | 0 |
2011-02-10 00:00:00+00:00 | 13 | 0 |
2011-02-11 00:00:00+00:00 | 14 | 0 |
2011-02-12 00:00:00+00:00 | 15 | 0 |
2011-02-13 00:00:00+00:00 | 16 | 0 |
2011-02-14 00:00:00+00:00 | 17 | 0 |
2011-02-15 00:00:00+00:00 | 18 | 0 |
2011-02-16 00:00:00+00:00 | 19 | 0 |
2011-02-17 00:00:00+00:00 | 20 | 0 |
… | … | … |
Index: (item_id=FOODS_3_090, dept_id=FOODS_3, cat_id=FOODS, store_id=CA_2, state_id=CA)
1941 eventstimestamp | day | sales |
---|---|---|
2011-01-29 00:00:00+00:00 | 1 | 116 |
2011-01-30 00:00:00+00:00 | 2 | 90 |
2011-01-31 00:00:00+00:00 | 3 | 35 |
2011-02-01 00:00:00+00:00 | 4 | 33 |
2011-02-02 00:00:00+00:00 | 5 | 26 |
2011-02-03 00:00:00+00:00 | 6 | 38 |
2011-02-04 00:00:00+00:00 | 7 | 100 |
2011-02-05 00:00:00+00:00 | 8 | 89 |
2011-02-06 00:00:00+00:00 | 9 | 71 |
2011-02-07 00:00:00+00:00 | 10 | 0 |
2011-02-08 00:00:00+00:00 | 11 | 0 |
2011-02-09 00:00:00+00:00 | 12 | 0 |
2011-02-10 00:00:00+00:00 | 13 | 0 |
2011-02-11 00:00:00+00:00 | 14 | 0 |
2011-02-12 00:00:00+00:00 | 15 | 0 |
2011-02-13 00:00:00+00:00 | 16 | 0 |
2011-02-14 00:00:00+00:00 | 17 | 0 |
2011-02-15 00:00:00+00:00 | 18 | 0 |
2011-02-16 00:00:00+00:00 | 19 | 0 |
2011-02-17 00:00:00+00:00 | 20 | 0 |
… | … | … |
Index: (item_id=FOODS_3_090, dept_id=FOODS_3, cat_id=FOODS, store_id=CA_3, state_id=CA)
1941 eventstimestamp | day | sales |
---|---|---|
2011-01-29 00:00:00+00:00 | 1 | 108 |
2011-01-30 00:00:00+00:00 | 2 | 132 |
2011-01-31 00:00:00+00:00 | 3 | 102 |
2011-02-01 00:00:00+00:00 | 4 | 120 |
2011-02-02 00:00:00+00:00 | 5 | 106 |
2011-02-03 00:00:00+00:00 | 6 | 123 |
2011-02-04 00:00:00+00:00 | 7 | 279 |
2011-02-05 00:00:00+00:00 | 8 | 175 |
2011-02-06 00:00:00+00:00 | 9 | 186 |
2011-02-07 00:00:00+00:00 | 10 | 120 |
2011-02-08 00:00:00+00:00 | 11 | 0 |
2011-02-09 00:00:00+00:00 | 12 | 0 |
2011-02-10 00:00:00+00:00 | 13 | 0 |
2011-02-11 00:00:00+00:00 | 14 | 0 |
2011-02-12 00:00:00+00:00 | 15 | 0 |
2011-02-13 00:00:00+00:00 | 16 | 0 |
2011-02-14 00:00:00+00:00 | 17 | 0 |
2011-02-15 00:00:00+00:00 | 18 | 0 |
2011-02-16 00:00:00+00:00 | 19 | 0 |
2011-02-17 00:00:00+00:00 | 20 | 0 |
… | … | … |
Index: (item_id=FOODS_3_090, dept_id=FOODS_3, cat_id=FOODS, store_id=CA_4, state_id=CA)
1941 eventstimestamp | day | sales |
---|---|---|
2011-01-29 00:00:00+00:00 | 1 | 69 |
2011-01-30 00:00:00+00:00 | 2 | 49 |
2011-01-31 00:00:00+00:00 | 3 | 37 |
2011-02-01 00:00:00+00:00 | 4 | 40 |
2011-02-02 00:00:00+00:00 | 5 | 38 |
2011-02-03 00:00:00+00:00 | 6 | 39 |
2011-02-04 00:00:00+00:00 | 7 | 61 |
2011-02-05 00:00:00+00:00 | 8 | 79 |
2011-02-06 00:00:00+00:00 | 9 | 102 |
2011-02-07 00:00:00+00:00 | 10 | 86 |
2011-02-08 00:00:00+00:00 | 11 | 0 |
2011-02-09 00:00:00+00:00 | 12 | 0 |
2011-02-10 00:00:00+00:00 | 13 | 0 |
2011-02-11 00:00:00+00:00 | 14 | 0 |
2011-02-12 00:00:00+00:00 | 15 | 0 |
2011-02-13 00:00:00+00:00 | 16 | 0 |
2011-02-14 00:00:00+00:00 | 17 | 0 |
2011-02-15 00:00:00+00:00 | 18 | 0 |
2011-02-16 00:00:00+00:00 | 19 | 0 |
2011-02-17 00:00:00+00:00 | 20 | 0 |
… | … | … |
Index: (item_id=FOODS_3_090, dept_id=FOODS_3, cat_id=FOODS, store_id=TX_1, state_id=TX)
1941 eventstimestamp | day | sales |
---|---|---|
2011-01-29 00:00:00+00:00 | 1 | 75 |
2011-01-30 00:00:00+00:00 | 2 | 54 |
2011-01-31 00:00:00+00:00 | 3 | 74 |
2011-02-01 00:00:00+00:00 | 4 | 62 |
2011-02-02 00:00:00+00:00 | 5 | 60 |
2011-02-03 00:00:00+00:00 | 6 | 106 |
2011-02-04 00:00:00+00:00 | 7 | 96 |
2011-02-05 00:00:00+00:00 | 8 | 118 |
2011-02-06 00:00:00+00:00 | 9 | 177 |
2011-02-07 00:00:00+00:00 | 10 | 51 |
2011-02-08 00:00:00+00:00 | 11 | 0 |
2011-02-09 00:00:00+00:00 | 12 | 0 |
2011-02-10 00:00:00+00:00 | 13 | 0 |
2011-02-11 00:00:00+00:00 | 14 | 0 |
2011-02-12 00:00:00+00:00 | 15 | 0 |
2011-02-13 00:00:00+00:00 | 16 | 0 |
2011-02-14 00:00:00+00:00 | 17 | 0 |
2011-02-15 00:00:00+00:00 | 18 | 0 |
2011-02-16 00:00:00+00:00 | 19 | 0 |
2011-02-17 00:00:00+00:00 | 20 | 0 |
… | … | … |
Let's plot the sales of the first two products.
sales_evset.plot(max_num_plots=4, interactive=True, width_px=600)
The number of plots (160) is larger than "options.max_num_plots=4". Only the first plots will be printed.
Normalize raw_calendar
¶
In raw_calendar
, timestamps are expressed as ISO 8601 string e.g., 2011-01-29
. Let's convert them into python datetimes.
Before:
raw_calendar.head()
date | wm_yr_wk | weekday | wday | month | year | d | event_name_1 | event_type_1 | event_name_2 | event_type_2 | snap_CA | snap_TX | snap_WI | |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
0 | 2011-01-29 | 11101 | Saturday | 1 | 1 | 2011 | d_1 | NaN | NaN | NaN | NaN | 0 | 0 | 0 |
1 | 2011-01-30 | 11101 | Sunday | 2 | 1 | 2011 | d_2 | NaN | NaN | NaN | NaN | 0 | 0 | 0 |
2 | 2011-01-31 | 11101 | Monday | 3 | 1 | 2011 | d_3 | NaN | NaN | NaN | NaN | 0 | 0 | 0 |
3 | 2011-02-01 | 11101 | Tuesday | 4 | 2 | 2011 | d_4 | NaN | NaN | NaN | NaN | 1 | 1 | 0 |
4 | 2011-02-02 | 11101 | Wednesday | 5 | 2 | 2011 | d_5 | NaN | NaN | NaN | NaN | 1 | 0 | 1 |
cleaned_calendar = raw_calendar.copy()
# Temporian and TensorFlow Decision Forests (after) treat NaN values as "missing".
# In this dataset, a NaN means that there is not calendar event on this day.
cleaned_calendar.fillna("no_event", inplace=True)
cleaned_calendar["timestamp"] = cleaned_calendar["date"].apply(
lambda x: datetime.strptime(x, "%Y-%m-%d")
)
# We keep the mapping wm_yr_wk -> timestamp to clean "raw_sell_prices" in the next section.
wm_yr_wk_map = cleaned_calendar[["weekday", "timestamp", "wm_yr_wk"]]
del cleaned_calendar["date"]
del cleaned_calendar["wm_yr_wk"]
del cleaned_calendar["d"]
del cleaned_calendar["weekday"]
del cleaned_calendar["wday"]
del cleaned_calendar["month"]
del cleaned_calendar["year"]
After:
cleaned_calendar.head()
event_name_1 | event_type_1 | event_name_2 | event_type_2 | snap_CA | snap_TX | snap_WI | timestamp | |
---|---|---|---|---|---|---|---|---|
0 | no_event | no_event | no_event | no_event | 0 | 0 | 0 | 2011-01-29 |
1 | no_event | no_event | no_event | no_event | 0 | 0 | 0 | 2011-01-30 |
2 | no_event | no_event | no_event | no_event | 0 | 0 | 0 | 2011-01-31 |
3 | no_event | no_event | no_event | no_event | 1 | 1 | 0 | 2011-02-01 |
4 | no_event | no_event | no_event | no_event | 1 | 0 | 1 | 2011-02-02 |
Same as before, we can convert the calendar data into a Temporian EventSet.
calendar_evset = tp.from_pandas(cleaned_calendar)
calendar_evset
WARNING:root:Feature "event_name_1" is an array of numpy.object_ and was casted to numpy.string_ (Note: numpy.string_ is equivalent to numpy.bytes_). WARNING:root:Feature "event_type_1" is an array of numpy.object_ and was casted to numpy.string_ (Note: numpy.string_ is equivalent to numpy.bytes_). WARNING:root:Feature "event_name_2" is an array of numpy.object_ and was casted to numpy.string_ (Note: numpy.string_ is equivalent to numpy.bytes_). WARNING:root:Feature "event_type_2" is an array of numpy.object_ and was casted to numpy.string_ (Note: numpy.string_ is equivalent to numpy.bytes_).
Index: ()
1969 eventstimestamp | event_name_1 | event_type_1 | event_name_2 | event_type_2 | snap_CA | snap_TX | snap_WI |
---|---|---|---|---|---|---|---|
2011-01-29 00:00:00+00:00 | no_event | no_event | no_event | no_event | 0 | 0 | 0 |
2011-01-30 00:00:00+00:00 | no_event | no_event | no_event | no_event | 0 | 0 | 0 |
2011-01-31 00:00:00+00:00 | no_event | no_event | no_event | no_event | 0 | 0 | 0 |
2011-02-01 00:00:00+00:00 | no_event | no_event | no_event | no_event | 1 | 1 | 0 |
2011-02-02 00:00:00+00:00 | no_event | no_event | no_event | no_event | 1 | 0 | 1 |
2011-02-03 00:00:00+00:00 | no_event | no_event | no_event | no_event | 1 | 1 | 1 |
2011-02-04 00:00:00+00:00 | no_event | no_event | no_event | no_event | 1 | 0 | 0 |
2011-02-05 00:00:00+00:00 | no_event | no_event | no_event | no_event | 1 | 1 | 1 |
2011-02-06 00:00:00+00:00 | SuperBowl | Sporting | no_event | no_event | 1 | 1 | 1 |
2011-02-07 00:00:00+00:00 | no_event | no_event | no_event | no_event | 1 | 1 | 0 |
2011-02-08 00:00:00+00:00 | no_event | no_event | no_event | no_event | 1 | 0 | 1 |
2011-02-09 00:00:00+00:00 | no_event | no_event | no_event | no_event | 1 | 1 | 1 |
2011-02-10 00:00:00+00:00 | no_event | no_event | no_event | no_event | 1 | 0 | 0 |
2011-02-11 00:00:00+00:00 | no_event | no_event | no_event | no_event | 0 | 1 | 1 |
2011-02-12 00:00:00+00:00 | no_event | no_event | no_event | no_event | 0 | 1 | 1 |
2011-02-13 00:00:00+00:00 | no_event | no_event | no_event | no_event | 0 | 1 | 0 |
2011-02-14 00:00:00+00:00 | ValentinesDay | Cultural | no_event | no_event | 0 | 0 | 1 |
2011-02-15 00:00:00+00:00 | no_event | no_event | no_event | no_event | 0 | 1 | 1 |
2011-02-16 00:00:00+00:00 | no_event | no_event | no_event | no_event | 0 | 0 | 0 |
2011-02-17 00:00:00+00:00 | no_event | no_event | no_event | no_event | 0 | 0 | 0 |
… | … | … | … | … | … | … | … |
Normalize raw_sell_prices
¶
Before:
raw_sell_prices.head()
store_id | item_id | wm_yr_wk | sell_price | |
---|---|---|---|---|
0 | CA_1 | HOBBIES_1_001 | 11325 | 9.58 |
1 | CA_1 | HOBBIES_1_001 | 11326 | 9.58 |
2 | CA_1 | HOBBIES_1_001 | 11327 | 8.26 |
3 | CA_1 | HOBBIES_1_001 | 11328 | 8.26 |
4 | CA_1 | HOBBIES_1_001 | 11329 | 8.26 |
In sell_prices
, timestamps as expressed with a special date format called wm_yr_wk
.
We use the calendar
data to find the mapping between wm_yr_wk
and classical python datetimes.
wm_yr_wk_to_date = wm_yr_wk_map[wm_yr_wk_map["weekday"] == "Saturday"][
["timestamp", "wm_yr_wk"]
]
map_wm_yr_wk_to_date = {}
for _, row in wm_yr_wk_to_date.iterrows():
map_wm_yr_wk_to_date[row["wm_yr_wk"]] = row["timestamp"]
cleaned_sell_prices = raw_sell_prices.copy()
cleaned_sell_prices["timestamp"] = cleaned_sell_prices["wm_yr_wk"].apply(
lambda x: map_wm_yr_wk_to_date[x]
)
del cleaned_sell_prices["wm_yr_wk"]
After:
cleaned_sell_prices.head()
store_id | item_id | sell_price | timestamp | |
---|---|---|---|---|
0 | CA_1 | HOBBIES_1_001 | 9.58 | 2013-07-13 |
1 | CA_1 | HOBBIES_1_001 | 9.58 | 2013-07-20 |
2 | CA_1 | HOBBIES_1_001 | 8.26 | 2013-07-27 |
3 | CA_1 | HOBBIES_1_001 | 8.26 | 2013-08-03 |
4 | CA_1 | HOBBIES_1_001 | 8.26 | 2013-08-10 |
Same as before, we can convert the calendar data into a Temporian EventSet.
sell_prices_evset = tp.from_pandas(
cleaned_sell_prices, indexes=["store_id", "item_id"]
)
sell_prices_evset
WARNING:root:Feature "store_id" is an array of numpy.object_ and was casted to numpy.string_ (Note: numpy.string_ is equivalent to numpy.bytes_). WARNING:root:Feature "item_id" is an array of numpy.object_ and was casted to numpy.string_ (Note: numpy.string_ is equivalent to numpy.bytes_).
Index: (store_id=CA_1, item_id=FOODS_1_001)
282 eventstimestamp | sell_price |
---|---|
2011-01-29 00:00:00+00:00 | 2 |
2011-02-05 00:00:00+00:00 | 2 |
2011-02-12 00:00:00+00:00 | 2 |
2011-02-19 00:00:00+00:00 | 2 |
2011-02-26 00:00:00+00:00 | 2 |
2011-03-05 00:00:00+00:00 | 2 |
2011-03-12 00:00:00+00:00 | 2 |
2011-03-19 00:00:00+00:00 | 2 |
2011-03-26 00:00:00+00:00 | 2 |
2011-04-02 00:00:00+00:00 | 2 |
2011-04-09 00:00:00+00:00 | 2 |
2011-04-16 00:00:00+00:00 | 2 |
2011-04-23 00:00:00+00:00 | 2 |
2011-04-30 00:00:00+00:00 | 2 |
2011-05-07 00:00:00+00:00 | 2 |
2011-05-14 00:00:00+00:00 | 2 |
2011-05-21 00:00:00+00:00 | 2 |
2011-05-28 00:00:00+00:00 | 2 |
2011-06-04 00:00:00+00:00 | 2 |
2011-06-11 00:00:00+00:00 | 2 |
… | … |
Index: (store_id=CA_1, item_id=FOODS_1_002)
282 eventstimestamp | sell_price |
---|---|
2011-01-29 00:00:00+00:00 | 7.88 |
2011-02-05 00:00:00+00:00 | 7.88 |
2011-02-12 00:00:00+00:00 | 7.88 |
2011-02-19 00:00:00+00:00 | 7.88 |
2011-02-26 00:00:00+00:00 | 7.88 |
2011-03-05 00:00:00+00:00 | 7.88 |
2011-03-12 00:00:00+00:00 | 7.88 |
2011-03-19 00:00:00+00:00 | 7.88 |
2011-03-26 00:00:00+00:00 | 7.88 |
2011-04-02 00:00:00+00:00 | 7.88 |
2011-04-09 00:00:00+00:00 | 7.88 |
2011-04-16 00:00:00+00:00 | 7.88 |
2011-04-23 00:00:00+00:00 | 7.88 |
2011-04-30 00:00:00+00:00 | 7.88 |
2011-05-07 00:00:00+00:00 | 7.88 |
2011-05-14 00:00:00+00:00 | 7.88 |
2011-05-21 00:00:00+00:00 | 7.88 |
2011-05-28 00:00:00+00:00 | 7.88 |
2011-06-04 00:00:00+00:00 | 7.88 |
2011-06-11 00:00:00+00:00 | 7.88 |
… | … |
Index: (store_id=CA_1, item_id=FOODS_1_003)
282 eventstimestamp | sell_price |
---|---|
2011-01-29 00:00:00+00:00 | 2.88 |
2011-02-05 00:00:00+00:00 | 2.88 |
2011-02-12 00:00:00+00:00 | 2.88 |
2011-02-19 00:00:00+00:00 | 2.88 |
2011-02-26 00:00:00+00:00 | 2.88 |
2011-03-05 00:00:00+00:00 | 2.88 |
2011-03-12 00:00:00+00:00 | 2.88 |
2011-03-19 00:00:00+00:00 | 2.88 |
2011-03-26 00:00:00+00:00 | 2.88 |
2011-04-02 00:00:00+00:00 | 2.88 |
2011-04-09 00:00:00+00:00 | 2.88 |
2011-04-16 00:00:00+00:00 | 2.88 |
2011-04-23 00:00:00+00:00 | 2.88 |
2011-04-30 00:00:00+00:00 | 2.88 |
2011-05-07 00:00:00+00:00 | 2.88 |
2011-05-14 00:00:00+00:00 | 2.88 |
2011-05-21 00:00:00+00:00 | 2.88 |
2011-05-28 00:00:00+00:00 | 2.88 |
2011-06-04 00:00:00+00:00 | 2.88 |
2011-06-11 00:00:00+00:00 | 2.88 |
… | … |
Index: (store_id=CA_1, item_id=FOODS_1_004)
225 eventstimestamp | sell_price |
---|---|
2012-03-03 00:00:00+00:00 | 1.78 |
2012-03-10 00:00:00+00:00 | 1.78 |
2012-03-17 00:00:00+00:00 | 1.78 |
2012-03-24 00:00:00+00:00 | 1.78 |
2012-03-31 00:00:00+00:00 | 1.78 |
2012-04-07 00:00:00+00:00 | 1.78 |
2012-04-14 00:00:00+00:00 | 1.78 |
2012-04-21 00:00:00+00:00 | 1.78 |
2012-04-28 00:00:00+00:00 | 1.78 |
2012-05-05 00:00:00+00:00 | 1.78 |
2012-05-12 00:00:00+00:00 | 1.78 |
2012-05-19 00:00:00+00:00 | 1.78 |
2012-05-26 00:00:00+00:00 | 1.78 |
2012-06-02 00:00:00+00:00 | 1.78 |
2012-06-09 00:00:00+00:00 | 1.78 |
2012-06-16 00:00:00+00:00 | 1.78 |
2012-06-23 00:00:00+00:00 | 1.78 |
2012-06-30 00:00:00+00:00 | 1.78 |
2012-07-07 00:00:00+00:00 | 1.78 |
2012-07-14 00:00:00+00:00 | 1.78 |
… | … |
Index: (store_id=CA_1, item_id=FOODS_1_005)
282 eventstimestamp | sell_price |
---|---|
2011-01-29 00:00:00+00:00 | 2.94 |
2011-02-05 00:00:00+00:00 | 2.94 |
2011-02-12 00:00:00+00:00 | 2.94 |
2011-02-19 00:00:00+00:00 | 2.94 |
2011-02-26 00:00:00+00:00 | 2.94 |
2011-03-05 00:00:00+00:00 | 2.94 |
2011-03-12 00:00:00+00:00 | 2.94 |
2011-03-19 00:00:00+00:00 | 2.94 |
2011-03-26 00:00:00+00:00 | 2.94 |
2011-04-02 00:00:00+00:00 | 2.94 |
2011-04-09 00:00:00+00:00 | 2.94 |
2011-04-16 00:00:00+00:00 | 2.94 |
2011-04-23 00:00:00+00:00 | 2.94 |
2011-04-30 00:00:00+00:00 | 2.94 |
2011-05-07 00:00:00+00:00 | 2.94 |
2011-05-14 00:00:00+00:00 | 2.94 |
2011-05-21 00:00:00+00:00 | 2.94 |
2011-05-28 00:00:00+00:00 | 2.94 |
2011-06-04 00:00:00+00:00 | 2.94 |
2011-06-11 00:00:00+00:00 | 2.94 |
… | … |
Now that our data is in the Temporian format, we can delete the Pandas DataFrames to recover some memory.
del raw_sales
del raw_sell_prices
del raw_calendar
Feature engineering¶
The EventSets sales_evset
, calendar_evset
and sell_prices_evset
are indexed by product.
To illustrate each of the newly computed features, we will plot them on a single product.
# Select a product.
selected_index = sales_evset.get_arbitrary_index_key()
print("Selected product (selected_index):", selected_index)
Selected product (selected_index): (b'FOODS_3_694', b'FOODS_3', b'FOODS', b'WI_2', b'WI')
The following arguments will be used for tp.plot()
.
plot_options = {
# Only plot the selected product.
"indexes": selected_index,
# Make the plot interactive.
"interactive": True,
# Make sure the toolbar is visible
"width_px": 600,
# Only plot the data for the year 2015.
"min_time": datetime(2015, 1, 1),
"max_time": datetime(2015, 12, 31),
}
all_features
will contain all of the generated features, and we'll use the prefix f_
for all their names.
all_features = [
# The raw sales is the first feature.
sales_evset["sales"].prefix("f_"),
]
Label¶
The labels at time t
are the sales at time t+1..28
. This is computed with the EventSet.leak()
operator.
label_list: List[tp.EventSet] = []
# Prediction horizon. In the M5 competition, participants should forecast the next 28 days.
# You can predict less days to make the training section of this notebook run faster.
horizons = list(range(1, 28))
# For each of the horizons.
for horizon in horizons:
# Leak the sales in the past.
x = sales_evset["sales"].leak(tp.duration.days(horizon))
# Resample the label to the sales data.
x = x.resample(sales_evset)
# Give a name to the label for book-keeping.
x = x.rename(f"label_horizon_{horizon}_days")
label_list.append(x)
labels = tp.glue(*label_list)
Let's see what the labels look like. Can you see how they shift more and more to the left while the horizon increases?
labels.plot(**plot_options, max_num_plots=4)
The number of plots (27) is larger than "options.max_num_plots=4". Only the first plots will be printed.
Past observations i.e. lagged sales¶
The model will have access to the daily sales in the last 3 days, as well as in the same day of the last and second-to-last weeks.
This is similar to computing the labels, except that the "shift" is in the opposite direction.
lagged_sales_list: List[tp.EventSet] = []
for horizon in [1, 2, 3, 7, 14]:
x = sales_evset["sales"].lag(tp.duration.days(horizon))
x = x.resample(sales_evset)
x = x.rename(f"f_sales_lag_{horizon}_d")
lagged_sales_list.append(x)
feature_lagged_sales = tp.glue(*lagged_sales_list)
all_features.append(feature_lagged_sales)
feature_lagged_sales.plot(**plot_options, max_num_plots=4)
The number of plots (5) is larger than "options.max_num_plots=4". Only the first plots will be printed.
Moving statistics¶
Moving statistics can help the model identify global trends in the data (moving average) or periods of high or low volatility (moving standard deviation).
moving_stats_list: List[tp.EventSet] = []
float_sales = sales_evset["sales"].cast(tp.float32)
for win_day in [7, 14, 28, 84]:
win = tp.duration.days(win_day)
x = float_sales.simple_moving_average(win).prefix(
f"f_sma_{win_day}_"
)
moving_stats_list.append(x)
x = float_sales.moving_standard_deviation(win).prefix(
f"f_sd_{win_day}_"
)
moving_stats_list.append(x)
x = float_sales.moving_sum(win).prefix(f"f_sum_{win_day}_")
moving_stats_list.append(x)
feature_moving_stats = tp.glue(*moving_stats_list)
all_features.append(feature_moving_stats)
feature_moving_stats.plot(**plot_options, max_num_plots=5)
The number of plots (12) is larger than "options.max_num_plots=5". Only the first plots will be printed.
Calendar features¶
The model will not be able to use dates directly. Instead, we transform the date into numerical features that can be consumed by a model.
calendar_list: List[tp.EventSet] = []
calendar_list.append(sales_evset.calendar_day_of_month())
calendar_list.append(sales_evset.calendar_day_of_week())
calendar_list.append(sales_evset.calendar_month())
feature_calendar = tp.glue(*calendar_list).prefix("f_")
all_features.append(feature_calendar)
feature_calendar.plot(**plot_options, max_num_plots=5)
Sales aggregated per department¶
When predicting the sales of a product, the sales of the other products in the same department can help forecasting.
Let's first group all the sales per department in each store, by removing the item_id
feature from our EventSet's index.
# `sales_per_dept` contains all the sales indexed by department / category / store / state.
# Aggregating the sales at other levels (e.g., by store) could also be useful.
sales_per_dept = sales_evset.drop_index("item_id", keep=False)
sales_per_dept
still contains the sales of each item: each day, sales_per_dept
contains one record for each item.
We need to aggregate those sales together on each day.
We compute the 28 days moving sum of sales for this department. To improve the quality of the final model, we could additionally use other time windows e.g. 1, 3, 7, 28.
# Create a daily sampling.
sampling_once_a_day = sales_per_dept.unique_timestamps()
# Cumulative 28 days sum of sales, per department.
sum28_sales_per_dept = sales_per_dept["sales"].moving_sum(
window_length=tp.duration.days(28),
sampling=sampling_once_a_day
)
# Give it a name for book-keeping.
sum28_sales_per_dept = sum28_sales_per_dept.prefix("f_sum28_per_dep_")
sum28_sales_per_dept.plot(max_num_plots=3, width_px=600)
The number of plots (10) is larger than "options.max_num_plots=3". Only the first plots will be printed.
The sales of each department is then propagated back to each corresponding product.
Note that two products from the same department will receive the same features.
sum28_sales_per_dept = sum28_sales_per_dept.propagate(sales_evset, resample=True)
all_features.append(sum28_sales_per_dept)
sum28_sales_per_dept.plot(max_num_plots=3, width_px=600)
The number of plots (80) is larger than "options.max_num_plots=3". Only the first plots will be printed.
Special events¶
Special events such as holidays and sale periods can impact sales.
# Propagate the global special event to each product.
special_event_per_product = calendar_evset.propagate(sales_evset, resample=True)
# Since special events are known in advance, we can leak future special events in the past.
#
# For example, on 22/12/2016, the model can know that it will be christmas in 2 days.
special_events_list: List[tp.EventSet] = []
special_events_list.append(special_event_per_product.prefix("f_"))
for leak in [5]:
x = special_event_per_product.leak(tp.duration.days(leak))
x = x.resample(sales_evset)
x = x.prefix(f"f_leak{leak}_")
special_events_list.append(x)
# To make the model more powerful, we could also apply some moving statistics such
# as moving-maximum to create features such as: is it christmas in the following N days.
feature_special_events = tp.glue(*special_events_list)
all_features.append(feature_special_events)
feature_special_events.plot(**plot_options, max_num_plots=3)
The number of plots (14) is larger than "options.max_num_plots=3". Only the first plots will be printed.
Review all the features¶
all_features
contains all the features we want to feed to our model.
tabular
is the data that will be used to train the model.
tabular = tp.glue(*all_features, sales_evset["day"], labels)
tabular.schema
features: [('f_sales', int64), ('f_sales_lag_1_d', int64), ('f_sales_lag_2_d', int64), ('f_sales_lag_3_d', int64), ('f_sales_lag_7_d', int64), ('f_sales_lag_14_d', int64), ('f_sma_7_sales', float32), ('f_sd_7_sales', float32), ('f_sum_7_sales', float32), ('f_sma_14_sales', float32), ('f_sd_14_sales', float32), ('f_sum_14_sales', float32), ('f_sma_28_sales', float32), ('f_sd_28_sales', float32), ('f_sum_28_sales', float32), ('f_sma_84_sales', float32), ('f_sd_84_sales', float32), ('f_sum_84_sales', float32), ('f_calendar_day_of_month', int32), ('f_calendar_day_of_week', int32), ('f_calendar_month', int32), ('f_sum28_per_dep_sales', int64), ('f_event_name_1', str_), ('f_event_type_1', str_), ('f_event_name_2', str_), ('f_event_type_2', str_), ('f_snap_CA', int64), ('f_snap_TX', int64), ('f_snap_WI', int64), ('f_leak5_event_name_1', str_), ('f_leak5_event_type_1', str_), ('f_leak5_event_name_2', str_), ('f_leak5_event_type_2', str_), ('f_leak5_snap_CA', int64), ('f_leak5_snap_TX', int64), ('f_leak5_snap_WI', int64), ('day', int64), ('label_horizon_1_days', int64), ('label_horizon_2_days', int64), ('label_horizon_3_days', int64), ('label_horizon_4_days', int64), ('label_horizon_5_days', int64), ('label_horizon_6_days', int64), ('label_horizon_7_days', int64), ('label_horizon_8_days', int64), ('label_horizon_9_days', int64), ('label_horizon_10_days', int64), ('label_horizon_11_days', int64), ('label_horizon_12_days', int64), ('label_horizon_13_days', int64), ('label_horizon_14_days', int64), ('label_horizon_15_days', int64), ('label_horizon_16_days', int64), ('label_horizon_17_days', int64), ('label_horizon_18_days', int64), ('label_horizon_19_days', int64), ('label_horizon_20_days', int64), ('label_horizon_21_days', int64), ('label_horizon_22_days', int64), ('label_horizon_23_days', int64), ('label_horizon_24_days', int64), ('label_horizon_25_days', int64), ('label_horizon_26_days', int64), ('label_horizon_27_days', int64)] indexes: [('item_id', str_), ('dept_id', str_), ('cat_id', str_), ('store_id', str_), ('state_id', str_)] is_unix_timestamp: True
Generate training and testing datasets¶
Compute all the new features and labels on the dataset.
The test dataset is the single day 1914. In this day, the model makes 28 predictions, one for each horizon, for each of the products.
For training, we use the data prior to the test day. We also remove the first 30 days as those days don't have enough data to compute good statistics.
tabular_test = tabular.filter(tabular["day"].equal(1914))
tabular_train = tabular.filter(
(tabular["day"] >= 30) & (tabular["day"] < 1914)
)
Let's compute the test dataset.
test_dataset = tp.to_pandas(tabular_test, timestamp_to_datetime=False)
test_dataset.head()
item_id | dept_id | cat_id | store_id | state_id | f_sales | f_sales_lag_1_d | f_sales_lag_2_d | f_sales_lag_3_d | f_sales_lag_7_d | ... | label_horizon_19_days | label_horizon_20_days | label_horizon_21_days | label_horizon_22_days | label_horizon_23_days | label_horizon_24_days | label_horizon_25_days | label_horizon_26_days | label_horizon_27_days | timestamp | |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
0 | FOODS_3_694 | FOODS_3 | FOODS | WI_2 | WI | 24 | 29 | 33 | 31 | 38 | ... | 31 | 31 | 34 | 24 | 36 | 30 | 44 | 37 | 42 | 1.461542e+09 |
1 | FOODS_3_694 | FOODS_3 | FOODS | WI_1 | WI | 13 | 24 | 28 | 18 | 27 | ... | 10 | 27 | 20 | 20 | 16 | 22 | 31 | 30 | 32 | 1.461542e+09 |
2 | FOODS_3_694 | FOODS_3 | FOODS | TX_3 | TX | 21 | 17 | 31 | 20 | 16 | ... | 21 | 26 | 17 | 35 | 19 | 23 | 22 | 14 | 21 | 1.461542e+09 |
3 | FOODS_3_694 | FOODS_3 | FOODS | TX_2 | TX | 26 | 21 | 17 | 22 | 9 | ... | 26 | 33 | 12 | 19 | 13 | 11 | 18 | 38 | 25 | 1.461542e+09 |
4 | FOODS_3_694 | FOODS_3 | FOODS | WI_3 | WI | 42 | 48 | 46 | 46 | 54 | ... | 64 | 57 | 57 | 37 | 30 | 45 | 51 | 46 | 48 | 1.461542e+09 |
5 rows × 70 columns
Let's compute the train dataset.
train_dataset = tp.to_pandas(tabular_train, timestamp_to_datetime=False)
train_dataset.head()
item_id | dept_id | cat_id | store_id | state_id | f_sales | f_sales_lag_1_d | f_sales_lag_2_d | f_sales_lag_3_d | f_sales_lag_7_d | ... | label_horizon_19_days | label_horizon_20_days | label_horizon_21_days | label_horizon_22_days | label_horizon_23_days | label_horizon_24_days | label_horizon_25_days | label_horizon_26_days | label_horizon_27_days | timestamp | |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
0 | FOODS_3_694 | FOODS_3 | FOODS | WI_2 | WI | 48 | 47 | 31 | 46 | 38 | ... | 34 | 32 | 29 | 32 | 18 | 24 | 41 | 30 | 44 | 1.298765e+09 |
1 | FOODS_3_694 | FOODS_3 | FOODS | WI_2 | WI | 30 | 48 | 47 | 31 | 36 | ... | 32 | 29 | 32 | 18 | 24 | 41 | 30 | 44 | 36 | 1.298851e+09 |
2 | FOODS_3_694 | FOODS_3 | FOODS | WI_2 | WI | 42 | 30 | 48 | 47 | 29 | ... | 29 | 32 | 18 | 24 | 41 | 30 | 44 | 36 | 15 | 1.298938e+09 |
3 | FOODS_3_694 | FOODS_3 | FOODS | WI_2 | WI | 39 | 42 | 30 | 48 | 44 | ... | 32 | 18 | 24 | 41 | 30 | 44 | 36 | 15 | 26 | 1.299024e+09 |
4 | FOODS_3_694 | FOODS_3 | FOODS | WI_2 | WI | 25 | 39 | 42 | 30 | 46 | ... | 18 | 24 | 41 | 30 | 44 | 36 | 15 | 26 | 33 | 1.299110e+09 |
5 rows × 70 columns
We can convert those EventSets to Pandas DataFrames and save them to csv files for later use.
test_dataset.to_csv(os.path.join(work_directory, "test.csv"), index=False)
train_dataset.to_csv(os.path.join(work_directory, "train.csv"), index=False)
!head tmp/temporian_m5/train.csv -n 5
item_id,dept_id,cat_id,store_id,state_id,f_sales,f_sales_lag_1_d,f_sales_lag_2_d,f_sales_lag_3_d,f_sales_lag_7_d,f_sales_lag_14_d,f_sma_7_sales,f_sd_7_sales,f_sum_7_sales,f_sma_14_sales,f_sd_14_sales,f_sum_14_sales,f_sma_28_sales,f_sd_28_sales,f_sum_28_sales,f_sma_84_sales,f_sd_84_sales,f_sum_84_sales,f_calendar_day_of_month,f_calendar_day_of_week,f_calendar_month,f_sum28_per_dep_sales,f_event_name_1,f_event_type_1,f_event_name_2,f_event_type_2,f_snap_CA,f_snap_TX,f_snap_WI,f_leak5_event_name_1,f_leak5_event_type_1,f_leak5_event_name_2,f_leak5_event_type_2,f_leak5_snap_CA,f_leak5_snap_TX,f_leak5_snap_WI,day,label_horizon_1_days,label_horizon_2_days,label_horizon_3_days,label_horizon_4_days,label_horizon_5_days,label_horizon_6_days,label_horizon_7_days,label_horizon_8_days,label_horizon_9_days,label_horizon_10_days,label_horizon_11_days,label_horizon_12_days,label_horizon_13_days,label_horizon_14_days,label_horizon_15_days,label_horizon_16_days,label_horizon_17_days,label_horizon_18_days,label_horizon_19_days,label_horizon_20_days,label_horizon_21_days,label_horizon_22_days,label_horizon_23_days,label_horizon_24_days,label_horizon_25_days,label_horizon_26_days,label_horizon_27_days,timestamp FOODS_3_694,FOODS_3,FOODS,WI_2,WI,48,47,31,46,38,53,40.142857,7.3955307,281.0,42.357143,7.393116,593.0,42.82143,11.796045,1199.0,43.333332,12.070166,1300.0,27,6,2,5313,no_event,no_event,no_event,no_event,0,0,0,no_event,no_event,no_event,no_event,1,0,0,30,30,42,39,25,27,43,34,29,29,19,7,42,30,32,46,27,33,36,34,32,29,32,18,24,41,30,44,1298764800.0 FOODS_3_694,FOODS_3,FOODS,WI_2,WI,30,48,47,31,36,41,39.285713,8.136589,275.0,41.57143,8.0508585,582.0,42.607143,11.971213,1193.0,42.903225,12.10533,1330.0,28,0,2,5298,no_event,no_event,no_event,no_event,0,0,0,no_event,no_event,no_event,no_event,1,1,1,31,42,39,25,27,43,34,29,29,19,7,42,30,32,46,27,33,36,34,32,29,32,18,24,41,30,44,36,1298851200.0 FOODS_3_694,FOODS_3,FOODS,WI_2,WI,42,30,48,47,29,45,41.142857,6.9781,288.0,41.357143,7.9964914,579.0,42.392857,11.926379,1187.0,42.875,11.91572,1372.0,1,1,3,5254,no_event,no_event,no_event,no_event,1,1,0,no_event,no_event,no_event,no_event,1,1,1,32,39,25,27,43,34,29,29,19,7,42,30,32,46,27,33,36,34,32,29,32,18,24,41,30,44,36,15,1298937600.0 FOODS_3_694,FOODS_3,FOODS,WI_2,WI,39,42,30,48,44,34,40.42857,6.9045978,283.0,41.714287,7.768329,584.0,42.67857,11.744462,1195.0,42.757576,11.752576,1411.0,2,2,3,5319,no_event,no_event,no_event,no_event,1,0,1,no_event,no_event,no_event,no_event,1,1,0,33,25,27,43,34,29,29,19,7,42,30,32,46,27,33,36,34,32,29,32,18,24,41,30,44,36,15,26,1299024000.0
Training and evaluating a simple model¶
Now that we have pre-processed data, we can train a model. We will train a collection of Gradient Boosted Trees using TensorFlow Decision Forests.
%pip install tensorflow tensorflow_decision_forests -q
import tensorflow as tf
import tensorflow_decision_forests as tfdf
[notice] A new release of pip is available: 23.1.2 -> 23.2.1 [notice] To update, run: pip install --upgrade pip Note: you may need to restart the kernel to use updated packages.
2023-08-22 17:19:07.938517: I tensorflow/core/util/port.cc:110] oneDNN custom operations are on. You may see slightly different numerical results due to floating-point round-off errors from different computation orders. To turn them off, set the environment variable `TF_ENABLE_ONEDNN_OPTS=0`. 2023-08-22 17:19:07.941786: I tensorflow/tsl/cuda/cudart_stub.cc:28] Could not find cuda drivers on your machine, GPU will not be used. 2023-08-22 17:19:08.021257: I tensorflow/tsl/cuda/cudart_stub.cc:28] Could not find cuda drivers on your machine, GPU will not be used. 2023-08-22 17:19:08.022287: I tensorflow/core/platform/cpu_feature_guard.cc:182] This TensorFlow binary is optimized to use available CPU instructions in performance-critical operations. To enable the following instructions: AVX2 AVX512F AVX512_VNNI FMA, in other operations, rebuild TensorFlow with the appropriate compiler flags. 2023-08-22 17:19:09.593394: W tensorflow/compiler/tf2tensorrt/utils/py_utils.cc:38] TF-TRT Warning: Could not find TensorRT
# The name of the labels and features.
label_names = [x for x in test_dataset.columns if x.startswith("label_")]
feature_names = [x for x in test_dataset.columns if x.startswith("f_")] + [
# The model also has access to the meta-data.
"dept_id",
"cat_id",
"store_id",
"state_id",
]
print("label_names:", label_names)
print("feature_names:", feature_names)
label_names: ['label_horizon_1_days', 'label_horizon_2_days', 'label_horizon_3_days', 'label_horizon_4_days', 'label_horizon_5_days', 'label_horizon_6_days', 'label_horizon_7_days', 'label_horizon_8_days', 'label_horizon_9_days', 'label_horizon_10_days', 'label_horizon_11_days', 'label_horizon_12_days', 'label_horizon_13_days', 'label_horizon_14_days', 'label_horizon_15_days', 'label_horizon_16_days', 'label_horizon_17_days', 'label_horizon_18_days', 'label_horizon_19_days', 'label_horizon_20_days', 'label_horizon_21_days', 'label_horizon_22_days', 'label_horizon_23_days', 'label_horizon_24_days', 'label_horizon_25_days', 'label_horizon_26_days', 'label_horizon_27_days'] feature_names: ['f_sales', 'f_sales_lag_1_d', 'f_sales_lag_2_d', 'f_sales_lag_3_d', 'f_sales_lag_7_d', 'f_sales_lag_14_d', 'f_sma_7_sales', 'f_sd_7_sales', 'f_sum_7_sales', 'f_sma_14_sales', 'f_sd_14_sales', 'f_sum_14_sales', 'f_sma_28_sales', 'f_sd_28_sales', 'f_sum_28_sales', 'f_sma_84_sales', 'f_sd_84_sales', 'f_sum_84_sales', 'f_calendar_day_of_month', 'f_calendar_day_of_week', 'f_calendar_month', 'f_sum28_per_dep_sales', 'f_event_name_1', 'f_event_type_1', 'f_event_name_2', 'f_event_type_2', 'f_snap_CA', 'f_snap_TX', 'f_snap_WI', 'f_leak5_event_name_1', 'f_leak5_event_type_1', 'f_leak5_event_name_2', 'f_leak5_event_type_2', 'f_leak5_snap_CA', 'f_leak5_snap_TX', 'f_leak5_snap_WI', 'dept_id', 'cat_id', 'store_id', 'state_id']
The Pandas DataFrame can be converted into a TensorFlow dataset.
def dataset_pandas_to_tensorflow_dataset(df):
features = {k: df[k] for k in feature_names}
labels = {k: df[k] for k in label_names}
return tf.data.Dataset.from_tensor_slices((features, labels)).batch(100)
tf_test_dataset = dataset_pandas_to_tensorflow_dataset(test_dataset)
tf_train_dataset = dataset_pandas_to_tensorflow_dataset(train_dataset)
We can train our model.
model_path = os.path.join(work_directory, "cache_model")
if os.path.exists(model_path):
# Load the model if it was already trained.
# If you change the dataset or the model parameters, change the "model_path".
# Note that loading the model won't display the training logs.
model = tf.keras.models.load_model(model_path)
else:
model = tfdf.keras.GradientBoostedTreesModel(
multitask=[
tfdf.keras.MultiTaskItem(x, task=tfdf.keras.Task.REGRESSION)
for x in label_names
],
num_trees=40, # Increase the number of trees (e.g., 100) for a better model.
verbose=2, # Remove to make the training less verbose.
)
model.fit(tf_train_dataset)
Use /tmp/tmpfn9n19rs as temporary training directory Reading training dataset... Training tensor examples: Features: {'f_sales': <tf.Tensor 'data:0' shape=(None,) dtype=int64>, 'f_sales_lag_1_d': <tf.Tensor 'data_1:0' shape=(None,) dtype=int64>, 'f_sales_lag_2_d': <tf.Tensor 'data_2:0' shape=(None,) dtype=int64>, 'f_sales_lag_3_d': <tf.Tensor 'data_3:0' shape=(None,) dtype=int64>, 'f_sales_lag_7_d': <tf.Tensor 'data_4:0' shape=(None,) dtype=int64>, 'f_sales_lag_14_d': <tf.Tensor 'data_5:0' shape=(None,) dtype=int64>, 'f_sma_7_sales': <tf.Tensor 'data_6:0' shape=(None,) dtype=float32>, 'f_sd_7_sales': <tf.Tensor 'data_7:0' shape=(None,) dtype=float32>, 'f_sum_7_sales': <tf.Tensor 'data_8:0' shape=(None,) dtype=float32>, 'f_sma_14_sales': <tf.Tensor 'data_9:0' shape=(None,) dtype=float32>, 'f_sd_14_sales': <tf.Tensor 'data_10:0' shape=(None,) dtype=float32>, 'f_sum_14_sales': <tf.Tensor 'data_11:0' shape=(None,) dtype=float32>, 'f_sma_28_sales': <tf.Tensor 'data_12:0' shape=(None,) dtype=float32>, 'f_sd_28_sales': <tf.Tensor 'data_13:0' shape=(None,) dtype=float32>, 'f_sum_28_sales': <tf.Tensor 'data_14:0' shape=(None,) dtype=float32>, 'f_sma_84_sales': <tf.Tensor 'data_15:0' shape=(None,) dtype=float32>, 'f_sd_84_sales': <tf.Tensor 'data_16:0' shape=(None,) dtype=float32>, 'f_sum_84_sales': <tf.Tensor 'data_17:0' shape=(None,) dtype=float32>, 'f_calendar_day_of_month': <tf.Tensor 'data_18:0' shape=(None,) dtype=int32>, 'f_calendar_day_of_week': <tf.Tensor 'data_19:0' shape=(None,) dtype=int32>, 'f_calendar_month': <tf.Tensor 'data_20:0' shape=(None,) dtype=int32>, 'f_sum28_per_dep_sales': <tf.Tensor 'data_21:0' shape=(None,) dtype=int64>, 'f_event_name_1': <tf.Tensor 'data_22:0' shape=(None,) dtype=string>, 'f_event_type_1': <tf.Tensor 'data_23:0' shape=(None,) dtype=string>, 'f_event_name_2': <tf.Tensor 'data_24:0' shape=(None,) dtype=string>, 'f_event_type_2': <tf.Tensor 'data_25:0' shape=(None,) dtype=string>, 'f_snap_CA': <tf.Tensor 'data_26:0' shape=(None,) dtype=int64>, 'f_snap_TX': <tf.Tensor 'data_27:0' shape=(None,) dtype=int64>, 'f_snap_WI': <tf.Tensor 'data_28:0' shape=(None,) dtype=int64>, 'f_leak5_event_name_1': <tf.Tensor 'data_29:0' shape=(None,) dtype=string>, 'f_leak5_event_type_1': <tf.Tensor 'data_30:0' shape=(None,) dtype=string>, 'f_leak5_event_name_2': <tf.Tensor 'data_31:0' shape=(None,) dtype=string>, 'f_leak5_event_type_2': <tf.Tensor 'data_32:0' shape=(None,) dtype=string>, 'f_leak5_snap_CA': <tf.Tensor 'data_33:0' shape=(None,) dtype=int64>, 'f_leak5_snap_TX': <tf.Tensor 'data_34:0' shape=(None,) dtype=int64>, 'f_leak5_snap_WI': <tf.Tensor 'data_35:0' shape=(None,) dtype=int64>, 'dept_id': <tf.Tensor 'data_36:0' shape=(None,) dtype=string>, 'cat_id': <tf.Tensor 'data_37:0' shape=(None,) dtype=string>, 'store_id': <tf.Tensor 'data_38:0' shape=(None,) dtype=string>, 'state_id': <tf.Tensor 'data_39:0' shape=(None,) dtype=string>} Label: {'label_horizon_1_days': <tf.Tensor 'data_40:0' shape=(None,) dtype=int64>, 'label_horizon_2_days': <tf.Tensor 'data_41:0' shape=(None,) dtype=int64>, 'label_horizon_3_days': <tf.Tensor 'data_42:0' shape=(None,) dtype=int64>, 'label_horizon_4_days': <tf.Tensor 'data_43:0' shape=(None,) dtype=int64>, 'label_horizon_5_days': <tf.Tensor 'data_44:0' shape=(None,) dtype=int64>, 'label_horizon_6_days': <tf.Tensor 'data_45:0' shape=(None,) dtype=int64>, 'label_horizon_7_days': <tf.Tensor 'data_46:0' shape=(None,) dtype=int64>, 'label_horizon_8_days': <tf.Tensor 'data_47:0' shape=(None,) dtype=int64>, 'label_horizon_9_days': <tf.Tensor 'data_48:0' shape=(None,) dtype=int64>, 'label_horizon_10_days': <tf.Tensor 'data_49:0' shape=(None,) dtype=int64>, 'label_horizon_11_days': <tf.Tensor 'data_50:0' shape=(None,) dtype=int64>, 'label_horizon_12_days': <tf.Tensor 'data_51:0' shape=(None,) dtype=int64>, 'label_horizon_13_days': <tf.Tensor 'data_52:0' shape=(None,) dtype=int64>, 'label_horizon_14_days': <tf.Tensor 'data_53:0' shape=(None,) dtype=int64>, 'label_horizon_15_days': <tf.Tensor 'data_54:0' shape=(None,) dtype=int64>, 'label_horizon_16_days': <tf.Tensor 'data_55:0' shape=(None,) dtype=int64>, 'label_horizon_17_days': <tf.Tensor 'data_56:0' shape=(None,) dtype=int64>, 'label_horizon_18_days': <tf.Tensor 'data_57:0' shape=(None,) dtype=int64>, 'label_horizon_19_days': <tf.Tensor 'data_58:0' shape=(None,) dtype=int64>, 'label_horizon_20_days': <tf.Tensor 'data_59:0' shape=(None,) dtype=int64>, 'label_horizon_21_days': <tf.Tensor 'data_60:0' shape=(None,) dtype=int64>, 'label_horizon_22_days': <tf.Tensor 'data_61:0' shape=(None,) dtype=int64>, 'label_horizon_23_days': <tf.Tensor 'data_62:0' shape=(None,) dtype=int64>, 'label_horizon_24_days': <tf.Tensor 'data_63:0' shape=(None,) dtype=int64>, 'label_horizon_25_days': <tf.Tensor 'data_64:0' shape=(None,) dtype=int64>, 'label_horizon_26_days': <tf.Tensor 'data_65:0' shape=(None,) dtype=int64>, 'label_horizon_27_days': <tf.Tensor 'data_66:0' shape=(None,) dtype=int64>} Weights: None Normalized tensor features: {'f_sales': SemanticTensor(semantic=<Semantic.NUMERICAL: 1>, tensor=<tf.Tensor 'Cast:0' shape=(None,) dtype=float32>), 'f_sales_lag_1_d': SemanticTensor(semantic=<Semantic.NUMERICAL: 1>, tensor=<tf.Tensor 'Cast_1:0' shape=(None,) dtype=float32>), 'f_sales_lag_2_d': SemanticTensor(semantic=<Semantic.NUMERICAL: 1>, tensor=<tf.Tensor 'Cast_2:0' shape=(None,) dtype=float32>), 'f_sales_lag_3_d': SemanticTensor(semantic=<Semantic.NUMERICAL: 1>, tensor=<tf.Tensor 'Cast_3:0' shape=(None,) dtype=float32>), 'f_sales_lag_7_d': SemanticTensor(semantic=<Semantic.NUMERICAL: 1>, tensor=<tf.Tensor 'Cast_4:0' shape=(None,) dtype=float32>), 'f_sales_lag_14_d': SemanticTensor(semantic=<Semantic.NUMERICAL: 1>, tensor=<tf.Tensor 'Cast_5:0' shape=(None,) dtype=float32>), 'f_sma_7_sales': SemanticTensor(semantic=<Semantic.NUMERICAL: 1>, tensor=<tf.Tensor 'data_6:0' shape=(None,) dtype=float32>), 'f_sd_7_sales': SemanticTensor(semantic=<Semantic.NUMERICAL: 1>, tensor=<tf.Tensor 'data_7:0' shape=(None,) dtype=float32>), 'f_sum_7_sales': SemanticTensor(semantic=<Semantic.NUMERICAL: 1>, tensor=<tf.Tensor 'data_8:0' shape=(None,) dtype=float32>), 'f_sma_14_sales': SemanticTensor(semantic=<Semantic.NUMERICAL: 1>, tensor=<tf.Tensor 'data_9:0' shape=(None,) dtype=float32>), 'f_sd_14_sales': SemanticTensor(semantic=<Semantic.NUMERICAL: 1>, tensor=<tf.Tensor 'data_10:0' shape=(None,) dtype=float32>), 'f_sum_14_sales': SemanticTensor(semantic=<Semantic.NUMERICAL: 1>, tensor=<tf.Tensor 'data_11:0' shape=(None,) dtype=float32>), 'f_sma_28_sales': SemanticTensor(semantic=<Semantic.NUMERICAL: 1>, tensor=<tf.Tensor 'data_12:0' shape=(None,) dtype=float32>), 'f_sd_28_sales': SemanticTensor(semantic=<Semantic.NUMERICAL: 1>, tensor=<tf.Tensor 'data_13:0' shape=(None,) dtype=float32>), 'f_sum_28_sales': SemanticTensor(semantic=<Semantic.NUMERICAL: 1>, tensor=<tf.Tensor 'data_14:0' shape=(None,) dtype=float32>), 'f_sma_84_sales': SemanticTensor(semantic=<Semantic.NUMERICAL: 1>, tensor=<tf.Tensor 'data_15:0' shape=(None,) dtype=float32>), 'f_sd_84_sales': SemanticTensor(semantic=<Semantic.NUMERICAL: 1>, tensor=<tf.Tensor 'data_16:0' shape=(None,) dtype=float32>), 'f_sum_84_sales': SemanticTensor(semantic=<Semantic.NUMERICAL: 1>, tensor=<tf.Tensor 'data_17:0' shape=(None,) dtype=float32>), 'f_calendar_day_of_month': SemanticTensor(semantic=<Semantic.NUMERICAL: 1>, tensor=<tf.Tensor 'Cast_6:0' shape=(None,) dtype=float32>), 'f_calendar_day_of_week': SemanticTensor(semantic=<Semantic.NUMERICAL: 1>, tensor=<tf.Tensor 'Cast_7:0' shape=(None,) dtype=float32>), 'f_calendar_month': SemanticTensor(semantic=<Semantic.NUMERICAL: 1>, tensor=<tf.Tensor 'Cast_8:0' shape=(None,) dtype=float32>), 'f_sum28_per_dep_sales': SemanticTensor(semantic=<Semantic.NUMERICAL: 1>, tensor=<tf.Tensor 'Cast_9:0' shape=(None,) dtype=float32>), 'f_event_name_1': SemanticTensor(semantic=<Semantic.CATEGORICAL: 2>, tensor=<tf.Tensor 'data_22:0' shape=(None,) dtype=string>), 'f_event_type_1': SemanticTensor(semantic=<Semantic.CATEGORICAL: 2>, tensor=<tf.Tensor 'data_23:0' shape=(None,) dtype=string>), 'f_event_name_2': SemanticTensor(semantic=<Semantic.CATEGORICAL: 2>, tensor=<tf.Tensor 'data_24:0' shape=(None,) dtype=string>), 'f_event_type_2': SemanticTensor(semantic=<Semantic.CATEGORICAL: 2>, tensor=<tf.Tensor 'data_25:0' shape=(None,) dtype=string>), 'f_snap_CA': SemanticTensor(semantic=<Semantic.NUMERICAL: 1>, tensor=<tf.Tensor 'Cast_10:0' shape=(None,) dtype=float32>), 'f_snap_TX': SemanticTensor(semantic=<Semantic.NUMERICAL: 1>, tensor=<tf.Tensor 'Cast_11:0' shape=(None,) dtype=float32>), 'f_snap_WI': SemanticTensor(semantic=<Semantic.NUMERICAL: 1>, tensor=<tf.Tensor 'Cast_12:0' shape=(None,) dtype=float32>), 'f_leak5_event_name_1': SemanticTensor(semantic=<Semantic.CATEGORICAL: 2>, tensor=<tf.Tensor 'data_29:0' shape=(None,) dtype=string>), 'f_leak5_event_type_1': SemanticTensor(semantic=<Semantic.CATEGORICAL: 2>, tensor=<tf.Tensor 'data_30:0' shape=(None,) dtype=string>), 'f_leak5_event_name_2': SemanticTensor(semantic=<Semantic.CATEGORICAL: 2>, tensor=<tf.Tensor 'data_31:0' shape=(None,) dtype=string>), 'f_leak5_event_type_2': SemanticTensor(semantic=<Semantic.CATEGORICAL: 2>, tensor=<tf.Tensor 'data_32:0' shape=(None,) dtype=string>), 'f_leak5_snap_CA': SemanticTensor(semantic=<Semantic.NUMERICAL: 1>, tensor=<tf.Tensor 'Cast_13:0' shape=(None,) dtype=float32>), 'f_leak5_snap_TX': SemanticTensor(semantic=<Semantic.NUMERICAL: 1>, tensor=<tf.Tensor 'Cast_14:0' shape=(None,) dtype=float32>), 'f_leak5_snap_WI': SemanticTensor(semantic=<Semantic.NUMERICAL: 1>, tensor=<tf.Tensor 'Cast_15:0' shape=(None,) dtype=float32>), 'dept_id': SemanticTensor(semantic=<Semantic.CATEGORICAL: 2>, tensor=<tf.Tensor 'data_36:0' shape=(None,) dtype=string>), 'cat_id': SemanticTensor(semantic=<Semantic.CATEGORICAL: 2>, tensor=<tf.Tensor 'data_37:0' shape=(None,) dtype=string>), 'store_id': SemanticTensor(semantic=<Semantic.CATEGORICAL: 2>, tensor=<tf.Tensor 'data_38:0' shape=(None,) dtype=string>), 'state_id': SemanticTensor(semantic=<Semantic.CATEGORICAL: 2>, tensor=<tf.Tensor 'data_39:0' shape=(None,) dtype=string>)} Training dataset read in 0:00:15.636382. Found 150720 examples. Training model... Standard output detected as not visible to the user e.g. running in a notebook. Creating a training log redirection. If training gets stuck, try calling tfdf.keras.set_training_logs_redirection(False).
[INFO 23-08-22 17:19:27.7980 CEST kernel.cc:773] Start Yggdrasil model training [INFO 23-08-22 17:19:27.7980 CEST kernel.cc:774] Collect training examples [INFO 23-08-22 17:19:27.7981 CEST kernel.cc:787] Dataspec guide: column_guides { column_name_pattern: "^label_horizon_1_days$" type: NUMERICAL } column_guides { column_name_pattern: "^label_horizon_2_days$" type: NUMERICAL } column_guides { column_name_pattern: "^label_horizon_3_days$" type: NUMERICAL } column_guides { column_name_pattern: "^label_horizon_4_days$" type: NUMERICAL } column_guides { column_name_pattern: "^label_horizon_5_days$" type: NUMERICAL } column_guides { column_name_pattern: "^label_horizon_6_days$" type: NUMERICAL } column_guides { column_name_pattern: "^label_horizon_7_days$" type: NUMERICAL } column_guides { column_name_pattern: "^label_horizon_8_days$" type: NUMERICAL } column_guides { column_name_pattern: "^label_horizon_9_days$" type: NUMERICAL } column_guides { column_name_pattern: "^label_horizon_10_days$" type: NUMERICAL } column_guides { column_name_pattern: "^label_horizon_11_days$" type: NUMERICAL } column_guides { column_name_pattern: "^label_horizon_12_days$" type: NUMERICAL } column_guides { column_name_pattern: "^label_horizon_13_days$" type: NUMERICAL } column_guides { column_name_pattern: "^label_horizon_14_days$" type: NUMERICAL } column_guides { column_name_pattern: "^label_horizon_15_days$" type: NUMERICAL } column_guides { column_name_pattern: "^label_horizon_16_days$" type: NUMERICAL } column_guides { column_name_pattern: "^label_horizon_17_days$" type: NUMERICAL } column_guides { column_name_pattern: "^label_horizon_18_days$" type: NUMERICAL } column_guides { column_name_pattern: "^label_horizon_19_days$" type: NUMERICAL } column_guides { column_name_pattern: "^label_horizon_20_days$" type: NUMERICAL } column_guides { column_name_pattern: "^label_horizon_21_days$" type: NUMERICAL } column_guides { column_name_pattern: "^label_horizon_22_days$" type: NUMERICAL } column_guides { column_name_pattern: "^label_horizon_23_days$" type: NUMERICAL } column_guides { column_name_pattern: "^label_horizon_24_days$" type: NUMERICAL } column_guides { column_name_pattern: "^label_horizon_25_days$" type: NUMERICAL } column_guides { column_name_pattern: "^label_horizon_26_days$" type: NUMERICAL } column_guides { column_name_pattern: "^label_horizon_27_days$" type: NUMERICAL } default_column_guide { categorial { max_vocab_count: 2000 } discretized_numerical { maximum_num_bins: 255 } } ignore_columns_without_guides: false detect_numerical_as_discretized_numerical: false [INFO 23-08-22 17:19:27.8163 CEST kernel.cc:393] Number of batches: 1508 [INFO 23-08-22 17:19:27.8163 CEST kernel.cc:394] Number of examples: 150720 [INFO 23-08-22 17:19:28.0986 CEST kernel.cc:794] Training dataset: Number of records: 150720 Number of columns: 67 Number of columns by type: NUMERICAL: 55 (82.0896%) CATEGORICAL: 12 (17.9104%) Columns: NUMERICAL: 55 (82.0896%) 2: "f_calendar_day_of_month" NUMERICAL mean:15.7107 min:1 max:31 sd:8.79464 3: "f_calendar_day_of_week" NUMERICAL mean:3.00159 min:0 max:6 sd:2.00066 4: "f_calendar_month" NUMERICAL mean:6.42622 min:1 max:12 sd:3.44017 13: "f_leak5_snap_CA" NUMERICAL mean:0.327495 min:0 max:1 sd:0.469299 14: "f_leak5_snap_TX" NUMERICAL mean:0.328025 min:0 max:1 sd:0.469494 15: "f_leak5_snap_WI" NUMERICAL mean:0.328025 min:0 max:1 sd:0.469494 16: "f_sales" NUMERICAL mean:29.5872 min:0 max:763 sd:31.5277 17: "f_sales_lag_14_d" NUMERICAL mean:29.5573 min:0 max:763 sd:31.5369 18: "f_sales_lag_1_d" NUMERICAL mean:29.5861 min:0 max:763 sd:31.5303 19: "f_sales_lag_2_d" NUMERICAL mean:29.5797 min:0 max:763 sd:31.5265 20: "f_sales_lag_3_d" NUMERICAL mean:29.5746 min:0 max:763 sd:31.5255 21: "f_sales_lag_7_d" NUMERICAL mean:29.5707 min:0 max:763 sd:31.5324 22: "f_sd_14_sales" NUMERICAL mean:10.0323 min:0 max:203.329 sd:10.8368 23: "f_sd_28_sales" NUMERICAL mean:10.8908 min:0 max:192.891 sd:11.4905 24: "f_sd_7_sales" NUMERICAL mean:9.12405 min:0 max:235.264 sd:10.209 25: "f_sd_84_sales" NUMERICAL mean:12.2336 min:0 max:173.639 sd:12.8959 26: "f_sma_14_sales" NUMERICAL mean:29.5678 min:0 max:468.643 sd:27.8563 27: "f_sma_28_sales" NUMERICAL mean:29.5606 min:0 max:442.75 sd:27.2844 28: "f_sma_7_sales" NUMERICAL mean:29.5773 min:0 max:602.857 sd:28.3994 29: "f_sma_84_sales" NUMERICAL mean:29.5427 min:0 max:279.786 sd:26.147 30: "f_snap_CA" NUMERICAL mean:0.329087 min:0 max:1 sd:0.469882 31: "f_snap_TX" NUMERICAL mean:0.329087 min:0 max:1 sd:0.469882 32: "f_snap_WI" NUMERICAL mean:0.329087 min:0 max:1 sd:0.469882 33: "f_sum28_per_dep_sales" NUMERICAL mean:6621.58 min:1333 max:19255 sd:2895.7 34: "f_sum_14_sales" NUMERICAL mean:413.949 min:0 max:6561 sd:389.988 35: "f_sum_28_sales" NUMERICAL mean:827.698 min:0 max:12397 sd:763.964 36: "f_sum_7_sales" NUMERICAL mean:207.041 min:0 max:4220 sd:198.796 37: "f_sum_84_sales" NUMERICAL mean:2460.49 min:0 max:23502 sd:2194.56 38: "label_horizon_10_days" NUMERICAL mean:29.6007 min:0 max:763 sd:31.5209 39: "label_horizon_11_days" NUMERICAL mean:29.6038 min:0 max:763 sd:31.5202 40: "label_horizon_12_days" NUMERICAL mean:29.6097 min:0 max:763 sd:31.5218 41: "label_horizon_13_days" NUMERICAL mean:29.6176 min:0 max:763 sd:31.5275 42: "label_horizon_14_days" NUMERICAL mean:29.6194 min:0 max:763 sd:31.5271 43: "label_horizon_15_days" NUMERICAL mean:29.6189 min:0 max:763 sd:31.5249 44: "label_horizon_16_days" NUMERICAL mean:29.6204 min:0 max:763 sd:31.5241 45: "label_horizon_17_days" NUMERICAL mean:29.6229 min:0 max:763 sd:31.5229 46: "label_horizon_18_days" NUMERICAL mean:29.6257 min:0 max:763 sd:31.5219 47: "label_horizon_19_days" NUMERICAL mean:29.6304 min:0 max:763 sd:31.523 48: "label_horizon_1_days" NUMERICAL mean:29.5853 min:0 max:763 sd:31.5245 49: "label_horizon_20_days" NUMERICAL mean:29.6377 min:0 max:763 sd:31.5259 50: "label_horizon_21_days" NUMERICAL mean:29.6423 min:0 max:763 sd:31.5277 51: "label_horizon_22_days" NUMERICAL mean:29.6404 min:0 max:763 sd:31.5232 52: "label_horizon_23_days" NUMERICAL mean:29.6433 min:0 max:763 sd:31.5218 53: "label_horizon_24_days" NUMERICAL mean:29.6473 min:0 max:763 sd:31.5202 54: "label_horizon_25_days" NUMERICAL mean:29.6505 min:0 max:763 sd:31.518 55: "label_horizon_26_days" NUMERICAL mean:29.6582 min:0 max:763 sd:31.5185 56: "label_horizon_27_days" NUMERICAL mean:29.6661 min:0 max:763 sd:31.5204 57: "label_horizon_2_days" NUMERICAL mean:29.5869 min:0 max:763 sd:31.5242 58: "label_horizon_3_days" NUMERICAL mean:29.5863 min:0 max:763 sd:31.5234 59: "label_horizon_4_days" NUMERICAL mean:29.5873 min:0 max:763 sd:31.5224 60: "label_horizon_5_days" NUMERICAL mean:29.5916 min:0 max:763 sd:31.525 61: "label_horizon_6_days" NUMERICAL mean:29.5976 min:0 max:763 sd:31.5282 62: "label_horizon_7_days" NUMERICAL mean:29.5993 min:0 max:763 sd:31.5276 63: "label_horizon_8_days" NUMERICAL mean:29.5965 min:0 max:763 sd:31.5239 64: "label_horizon_9_days" NUMERICAL mean:29.5992 min:0 max:763 sd:31.5224 CATEGORICAL: 12 (17.9104%) 0: "cat_id" CATEGORICAL has-dict vocab-size:2 zero-ood-items most-frequent:"FOODS" 150720 (100%) 1: "dept_id" CATEGORICAL has-dict vocab-size:2 zero-ood-items most-frequent:"FOODS_3" 150720 (100%) 5: "f_event_name_1" CATEGORICAL has-dict vocab-size:32 zero-ood-items most-frequent:"no_event" 138640 (91.9851%) 6: "f_event_name_2" CATEGORICAL has-dict vocab-size:6 zero-ood-items most-frequent:"no_event" 150400 (99.7877%) 7: "f_event_type_1" CATEGORICAL has-dict vocab-size:6 zero-ood-items most-frequent:"no_event" 138640 (91.9851%) 8: "f_event_type_2" CATEGORICAL has-dict vocab-size:4 zero-ood-items most-frequent:"no_event" 150400 (99.7877%) 9: "f_leak5_event_name_1" CATEGORICAL has-dict vocab-size:32 zero-ood-items most-frequent:"no_event" 138640 (91.9851%) 10: "f_leak5_event_name_2" CATEGORICAL has-dict vocab-size:6 zero-ood-items most-frequent:"no_event" 150400 (99.7877%) 11: "f_leak5_event_type_1" CATEGORICAL has-dict vocab-size:6 zero-ood-items most-frequent:"no_event" 138640 (91.9851%) 12: "f_leak5_event_type_2" CATEGORICAL has-dict vocab-size:4 zero-ood-items most-frequent:"no_event" 150400 (99.7877%) 65: "state_id" CATEGORICAL has-dict vocab-size:4 zero-ood-items most-frequent:"CA" 60288 (40%) 66: "store_id" CATEGORICAL has-dict vocab-size:11 zero-ood-items most-frequent:"CA_1" 15072 (10%) Terminology: nas: Number of non-available (i.e. missing) values. ood: Out of dictionary. manually-defined: Attribute which type is manually defined by the user i.e. the type was not automatically inferred. tokenized: The attribute value is obtained through tokenization. has-dict: The attribute is attached to a string dictionary e.g. a categorical attribute stored as a string. vocab-size: Number of unique values. [INFO 23-08-22 17:19:28.1055 CEST kernel.cc:810] Configure learner [INFO 23-08-22 17:19:28.1057 CEST kernel.cc:824] Training config: learner: "MULTITASKER" features: "^cat_id$" features: "^dept_id$" features: "^f_calendar_day_of_month$" features: "^f_calendar_day_of_week$" features: "^f_calendar_month$" features: "^f_event_name_1$" features: "^f_event_name_2$" features: "^f_event_type_1$" features: "^f_event_type_2$" features: "^f_leak5_event_name_1$" features: "^f_leak5_event_name_2$" features: "^f_leak5_event_type_1$" features: "^f_leak5_event_type_2$" features: "^f_leak5_snap_CA$" features: "^f_leak5_snap_TX$" features: "^f_leak5_snap_WI$" features: "^f_sales$" features: "^f_sales_lag_14_d$" features: "^f_sales_lag_1_d$" features: "^f_sales_lag_2_d$" features: "^f_sales_lag_3_d$" features: "^f_sales_lag_7_d$" features: "^f_sd_14_sales$" features: "^f_sd_28_sales$" features: "^f_sd_7_sales$" features: "^f_sd_84_sales$" features: "^f_sma_14_sales$" features: "^f_sma_28_sales$" features: "^f_sma_7_sales$" features: "^f_sma_84_sales$" features: "^f_snap_CA$" features: "^f_snap_TX$" features: "^f_snap_WI$" features: "^f_sum28_per_dep_sales$" features: "^f_sum_14_sales$" features: "^f_sum_28_sales$" features: "^f_sum_7_sales$" features: "^f_sum_84_sales$" features: "^state_id$" features: "^store_id$" label: "^label_horizon_1_days$" task: REGRESSION metadata { framework: "TF Keras" } [yggdrasil_decision_forests.model.multitasker.proto.multitasker_config] { base_learner { learner: "GRADIENT_BOOSTED_TREES" } subtasks { primary: true train_config { label: "^label_horizon_1_days$" task: REGRESSION } } subtasks { primary: true train_config { label: "^label_horizon_2_days$" task: REGRESSION } } subtasks { primary: true train_config { label: "^label_horizon_3_days$" task: REGRESSION } } subtasks { primary: true train_config { label: "^label_horizon_4_days$" task: REGRESSION } } subtasks { primary: true train_config { label: "^label_horizon_5_days$" task: REGRESSION } } subtasks { primary: true train_config { label: "^label_horizon_6_days$" task: REGRESSION } } subtasks { primary: true train_config { label: "^label_horizon_7_days$" task: REGRESSION } } subtasks { primary: true train_config { label: "^label_horizon_8_days$" task: REGRESSION } } subtasks { primary: true train_config { label: "^label_horizon_9_days$" task: REGRESSION } } subtasks { primary: true train_config { label: "^label_horizon_10_days$" task: REGRESSION } } subtasks { primary: true train_config { label: "^label_horizon_11_days$" task: REGRESSION } } subtasks { primary: true train_config { label: "^label_horizon_12_days$" task: REGRESSION } } subtasks { primary: true train_config { label: "^label_horizon_13_days$" task: REGRESSION } } subtasks { primary: true train_config { label: "^label_horizon_14_days$" task: REGRESSION } } subtasks { primary: true train_config { label: "^label_horizon_15_days$" task: REGRESSION } } subtasks { primary: true train_config { label: "^label_horizon_16_days$" task: REGRESSION } } subtasks { primary: true train_config { label: "^label_horizon_17_days$" task: REGRESSION } } subtasks { primary: true train_config { label: "^label_horizon_18_days$" task: REGRESSION } } subtasks { primary: true train_config { label: "^label_horizon_19_days$" task: REGRESSION } } subtasks { primary: true train_config { label: "^label_horizon_20_days$" task: REGRESSION } } subtasks { primary: true train_config { label: "^label_horizon_21_days$" task: REGRESSION } } subtasks { primary: true train_config { label: "^label_horizon_22_days$" task: REGRESSION } } subtasks { primary: true train_config { label: "^label_horizon_23_days$" task: REGRESSION } } subtasks { primary: true train_config { label: "^label_horizon_24_days$" task: REGRESSION } } subtasks { primary: true train_config { label: "^label_horizon_25_days$" task: REGRESSION } } subtasks { primary: true train_config { label: "^label_horizon_26_days$" task: REGRESSION } } subtasks { primary: true train_config { label: "^label_horizon_27_days$" task: REGRESSION } } } [INFO 23-08-22 17:19:28.1066 CEST kernel.cc:827] Deployment config: cache_path: "/tmp/tmpfn9n19rs/working_cache" num_threads: 8 try_resume_training: true [INFO 23-08-22 17:19:28.1118 CEST kernel.cc:889] Train model [INFO 23-08-22 17:19:28.1495 CEST multitasker.cc:286] Train multitasker primary tasks with 27 model(s) [WARNING[ 23-08-22 17:19:28.1574 CEST gradient_boosted_trees.cc:1818] "goss_alpha" set but "sampling_method" not equal to "GOSS". [WARNING[[WARNING[WARNINGWARNINGWARNING 23-08-22 17:19:28.1575 CEST gradient_boosted_trees.cc: 23-08-22 17:19:28.1575 CEST gradient_boosted_trees.cc:1818 23-08-22 17:19:28.1575 CEST gradient_boosted_trees.cc] 1818"goss_alpha" set but "sampling_method" not equal to "GOSS". ] 23-08-22 17:19:28.1575 CEST gradient_boosted_trees.cc:[WARNING 23-08-22 17:19:28.1576 CEST gradient_boosted_trees.cc:1829] "goss_beta" set but "sampling_method" not equal to "GOSS". [WARNING 23-08-22 17:19:28.1576 CEST gradient_boosted_trees.cc:1843] "selective_gradient_boosting_ratio" set but "sampling_method" not equal to "SELGB". 23-08-22 17:19:28.1574 CEST gradient_boosted_trees.cc:1829] "goss_beta" set but "sampling_method" not equal to "GOSS". [WARNING 23-08-22 17:19:28.1577 CEST gradient_boosted_trees.cc:1843] "selective_gradient_boosting_ratio" set but "sampling_method" not equal to "SELGB". [WARNING 23-08-22 17:19:28.1580 CEST gradient_boosted_trees.cc:1818] "goss_alpha" set but "sampling_method" not equal to "GOSS". [WARNING 23-08-22 17:19:28.1581 CEST gradient_boosted_trees.cc:1829] "goss_beta" set but "sampling_method" not equal to "GOSS". [WARNING 23-08-22 17:19:28.1581 CEST gradient_boosted_trees.cc:1843] "selective_gradient_boosting_ratio" set but "sampling_method" not equal to "SELGB". "goss_alpha" set but "sampling_method" not equal to "GOSS". [WARNING 23-08-22 17:19:28.1581 CEST gradient_boosted_trees.cc:1829] [WARNING 23-08-22 17:19:28.1582 CEST gradient_boosted_trees.cc:1818] "goss_alpha" set but "sampling_method" not equal to "GOSS". [WARNING 23-08-22 17:19:28.1582 CEST gradient_boosted_trees.cc:1829] "goss_beta" set but "sampling_method" not equal to "GOSS". [WARNING 23-08-22 17:19:28.1582 CEST gradient_boosted_trees.cc:1843] "selective_gradient_boosting_ratio" set but "sampling_method" not equal to "SELGB". [WARNING 23-08-22 17:19:28.1584 CEST gradient_boosted_trees.cc:1818] "goss_alpha" set but "sampling_method" not equal to "GOSS". [WARNING 23-08-22 17:19:28.1584 CEST gradient_boosted_trees.cc:1829] "goss_beta" set but "sampling_method" not equal to "GOSS". [WARNING 23-08-22 17:19:28.1584 CEST gradient_boosted_trees.cc:1843] "selective_gradient_boosting_ratio" set but "sampling_method" not equal to "SELGB". "goss_beta" set but "sampling_method" not equal to "GOSS". [WARNING 23-08-22 17:19:28.1598 CEST gradient_boosted_trees.cc:1843] "selective_gradient_boosting_ratio" set but "sampling_method" not equal to "SELGB". 1818] "goss_alpha" set but "sampling_method" not equal to "GOSS". [WARNING 23-08-22 17:19:28.1600 CEST gradient_boosted_trees.cc:1829] "goss_beta" set but "sampling_method" not equal to "GOSS". [WARNING 23-08-22 17:19:28.1600 CEST gradient_boosted_trees.cc:1843] "selective_gradient_boosting_ratio" set but "sampling_method" not equal to "SELGB". :1818] "goss_alpha" set but "sampling_method" not equal to "GOSS". [WARNING 23-08-22 17:19:28.1602 CEST gradient_boosted_trees.cc:1829] "goss_beta" set but "sampling_method" not equal to "GOSS". [WARNING 23-08-22 17:19:28.1602 CEST gradient_boosted_trees.cc:1843] "selective_gradient_boosting_ratio" set but "sampling_method" not equal to "SELGB". [INFO 23-08-22 17:19:32.0507 CEST gradient_boosted_trees.cc:459] Default loss set to SQUARED_ERROR [INFO 23-08-22 17:19:32.0614 CEST gradient_boosted_trees.cc:1085] Training gradient boosted tree on 150720 example(s) and 40 feature(s). [INFO 23-08-22 17:19:32.1276 CEST gradient_boosted_trees.cc:459] Default loss set to SQUARED_ERROR [INFO 23-08-22 17:19:32.1455 CEST gradient_boosted_trees.cc:1085] Training gradient boosted tree on 150720 example(s) and 40 feature(s). [INFO 23-08-22 17:19:32.4159 CEST gradient_boosted_trees.cc:459] Default loss set to SQUARED_ERROR [INFO 23-08-22 17:19:32.4160 CEST gradient_boosted_trees.cc:1085] Training gradient boosted tree on 150720 example(s) and 40 feature(s). [INFO 23-08-22 17:19:32.5365 CEST gradient_boosted_trees.cc:459] Default loss set to SQUARED_ERROR [INFO 23-08-22 17:19:32.5365 CEST gradient_boosted_trees.cc:1085] Training gradient boosted tree on 150720 example(s) and 40 feature(s). [INFO 23-08-22 17:19:32.6083 CEST gradient_boosted_trees.cc:459] Default loss set to SQUARED_ERROR [INFO 23-08-22 17:19:32.6084 CEST gradient_boosted_trees.cc:1085] Training gradient boosted tree on 150720 example(s) and 40 feature(s). [INFO 23-08-22 17:19:32.8171 CEST gradient_boosted_trees.cc:1128] 135737 examples used for training and 14983 examples used for validation [INFO 23-08-22 17:19:32.8182 CEST gradient_boosted_trees.cc:459] Default loss set to SQUARED_ERROR [INFO 23-08-22 17:19:32.8183 CEST gradient_boosted_trees.cc:1085] Training gradient boosted tree on 150720 example(s) and 40 feature(s). [INFO 23-08-22 17:19:32.9276 CEST gradient_boosted_trees.cc:459] Default loss set to SQUARED_ERROR [INFO 23-08-22 17:19:32.9277 CEST gradient_boosted_trees.cc:1085] Training gradient boosted tree on 150720 example(s) and 40 feature(s). [INFO 23-08-22 17:19:33.1349 CEST gradient_boosted_trees.cc:459] Default loss set to SQUARED_ERROR [INFO 23-08-22 17:19:33.1350 CEST gradient_boosted_trees.cc:1085] Training gradient boosted tree on 150720 example(s) and 40 feature(s). [INFO 23-08-22 17:19:33.1581 CEST gradient_boosted_trees.cc:1128] 135737 examples used for training and 14983 examples used for validation [INFO 23-08-22 17:19:34.0283 CEST gradient_boosted_trees.cc:1128] 135737 examples used for training and 14983 examples used for validation [INFO 23-08-22 17:19:34.1116 CEST gradient_boosted_trees.cc:1128] 135737 examples used for training and 14983 examples used for validation [INFO 23-08-22 17:19:34.3145 CEST gradient_boosted_trees.cc:1128] 135737 examples used for training and 14983 examples used for validation [INFO 23-08-22 17:19:34.8990 CEST gradient_boosted_trees.cc:1128] 135737 examples used for training and 14983 examples used for validation [INFO 23-08-22 17:19:35.1325 CEST gradient_boosted_trees.cc:1542] num-trees:1 train-loss:29.267696 train-rmse:29.267696 valid-loss:29.130789 valid-rmse:29.130789 [INFO 23-08-22 17:19:35.1814 CEST gradient_boosted_trees.cc:1128] 135737 examples used for training and 14983 examples used for validation [INFO 23-08-22 17:19:35.3696 CEST gradient_boosted_trees.cc:1128] 135737 examples used for training and 14983 examples used for validation [INFO 23-08-22 17:19:35.9690 CEST gradient_boosted_trees.cc:1542] num-trees:1 train-loss:29.335985 train-rmse:29.335985 valid-loss:29.099661 valid-rmse:29.099661 [INFO 23-08-22 17:19:37.9991 CEST gradient_boosted_trees.cc:1542] num-trees:1 train-loss:29.214186 train-rmse:29.214186 valid-loss:29.899080 valid-rmse:29.899080 [INFO 23-08-22 17:19:38.5385 CEST gradient_boosted_trees.cc:1542] num-trees:1 train-loss:29.303213 train-rmse:29.303213 valid-loss:29.393198 valid-rmse:29.393198 [INFO 23-08-22 17:19:38.5435 CEST gradient_boosted_trees.cc:1542] num-trees:1 train-loss:29.399338 train-rmse:29.399338 valid-loss:29.028122 valid-rmse:29.028122 [INFO 23-08-22 17:19:38.6758 CEST gradient_boosted_trees.cc:1544] num-trees:2 train-loss:27.390989 train-rmse:27.390989 valid-loss:27.127483 valid-rmse:27.127483 [INFO 23-08-22 17:19:38.9145 CEST gradient_boosted_trees.cc:1542] num-trees:1 train-loss:29.124109 train-rmse:29.124109 valid-loss:29.133936 valid-rmse:29.133936 [INFO 23-08-22 17:19:39.5908 CEST gradient_boosted_trees.cc:1542] num-trees:1 train-loss:29.295769 train-rmse:29.295769 valid-loss:28.769020 valid-rmse:28.769020 [INFO 23-08-22 17:19:39.7044 CEST gradient_boosted_trees.cc:1542] num-trees:1 train-loss:29.323404 train-rmse:29.323404 valid-loss:28.357626 valid-rmse:28.357626 [INFO 23-08-22 17:20:09.1838 CEST gradient_boosted_trees.cc:1544] num-trees:15 train-loss:16.286356 train-rmse:16.286356 valid-loss:17.388578 valid-rmse:17.388578 [INFO 23-08-22 17:20:39.5899 CEST gradient_boosted_trees.cc:1544] num-trees:26 train-loss:15.550566 train-rmse:15.550566 valid-loss:15.613172 valid-rmse:15.613172 [INFO 23-08-22 17:21:09.7584 CEST gradient_boosted_trees.cc:1544] num-trees:36 train-loss:12.604913 train-rmse:12.604913 valid-loss:12.728271 valid-rmse:12.728271 [INFO 23-08-22 17:21:29.1166 CEST gradient_boosted_trees.cc:1542] num-trees:50 train-loss:13.866138 train-rmse:13.866138 valid-loss:15.359539 valid-rmse:15.359539 [INFO 23-08-22 17:21:29.1166 CEST gradient_boosted_trees.cc:247] Truncates the model to 48 tree(s) i.e. 48 iteration(s). [INFO 23-08-22 17:21:29.1167 CEST gradient_boosted_trees.cc:310] Final model num-trees:48 valid-loss:15.355445 valid-rmse:15.355445 [WARNING 23-08-22 17:21:29.1246 CEST gradient_boosted_trees.cc:1818] "goss_alpha" set but "sampling_method" not equal to "GOSS". [WARNING 23-08-22 17:21:29.1246 CEST gradient_boosted_trees.cc:1829] "goss_beta" set but "sampling_method" not equal to "GOSS". [WARNING 23-08-22 17:21:29.1246 CEST gradient_boosted_trees.cc:1843] "selective_gradient_boosting_ratio" set but "sampling_method" not equal to "SELGB". [INFO 23-08-22 17:21:30.4713 CEST gradient_boosted_trees.cc:459] Default loss set to SQUARED_ERROR [INFO 23-08-22 17:21:30.4714 CEST gradient_boosted_trees.cc:1085] Training gradient boosted tree on 150720 example(s) and 40 feature(s). [INFO 23-08-22 17:21:30.6207 CEST gradient_boosted_trees.cc:1128] 135737 examples used for training and 14983 examples used for validation [INFO 23-08-22 17:21:30.8606 CEST gradient_boosted_trees.cc:1542] num-trees:50 train-loss:13.575471 train-rmse:13.575471 valid-loss:15.029240 valid-rmse:15.029240 [INFO 23-08-22 17:21:30.8838 CEST gradient_boosted_trees.cc:247] Truncates the model to 50 tree(s) i.e. 50 iteration(s). [INFO 23-08-22 17:21:30.8877 CEST gradient_boosted_trees.cc:310] Final model num-trees:50 valid-loss:15.029240 valid-rmse:15.029240 [WARNING 23-08-22 17:21:30.9208 CEST gradient_boosted_trees.cc:1818] "goss_alpha" set but "sampling_method" not equal to "GOSS". [WARNING 23-08-22 17:21:30.9309 CEST gradient_boosted_trees.cc:1829] "goss_beta" set but "sampling_method" not equal to "GOSS". [WARNING 23-08-22 17:21:30.9312 CEST gradient_boosted_trees.cc:1843] "selective_gradient_boosting_ratio" set but "sampling_method" not equal to "SELGB". [INFO 23-08-22 17:21:31.0555 CEST gradient_boosted_trees.cc:1542] num-trees:50 train-loss:13.423209 train-rmse:13.423209 valid-loss:13.453820 valid-rmse:13.453820 [INFO 23-08-22 17:21:31.0684 CEST gradient_boosted_trees.cc:247] Truncates the model to 50 tree(s) i.e. 50 iteration(s). [INFO 23-08-22 17:21:31.0688 CEST gradient_boosted_trees.cc:310] Final model num-trees:50 valid-loss:13.453820 valid-rmse:13.453820 [WARNING 23-08-22 17:21:31.0988 CEST gradient_boosted_trees.cc:1818] "goss_alpha" set but "sampling_method" not equal to "GOSS". [WARNING 23-08-22 17:21:31.0991 CEST gradient_boosted_trees.cc:1829] "goss_beta" set but "sampling_method" not equal to "GOSS". [WARNING 23-08-22 17:21:31.0993 CEST gradient_boosted_trees.cc:1843] "selective_gradient_boosting_ratio" set but "sampling_method" not equal to "SELGB". [INFO 23-08-22 17:21:31.5115 CEST gradient_boosted_trees.cc:1542] num-trees:50 train-loss:14.071945 train-rmse:14.071945 valid-loss:14.601532 valid-rmse:14.601532 [INFO 23-08-22 17:21:31.5116 CEST gradient_boosted_trees.cc:247] Truncates the model to 47 tree(s) i.e. 47 iteration(s). [INFO 23-08-22 17:21:31.5116 CEST gradient_boosted_trees.cc:310] Final model num-trees:47 valid-loss:14.593384 valid-rmse:14.593384 [WARNING 23-08-22 17:21:31.5663 CEST gradient_boosted_trees.cc:1818] "goss_alpha" set but "sampling_method" not equal to "GOSS". [WARNING 23-08-22 17:21:31.5663 CEST gradient_boosted_trees.cc:1829] "goss_beta" set but "sampling_method" not equal to "GOSS". [WARNING 23-08-22 17:21:31.5663 CEST gradient_boosted_trees.cc:1843] "selective_gradient_boosting_ratio" set but "sampling_method" not equal to "SELGB". [INFO 23-08-22 17:21:31.7412 CEST gradient_boosted_trees.cc:1542] num-trees:50 train-loss:13.070064 train-rmse:13.070064 valid-loss:13.403740 valid-rmse:13.403740 [INFO 23-08-22 17:21:31.7490 CEST gradient_boosted_trees.cc:247] Truncates the model to 50 tree(s) i.e. 50 iteration(s). [INFO 23-08-22 17:21:31.7490 CEST gradient_boosted_trees.cc:310] Final model num-trees:50 valid-loss:13.403740 valid-rmse:13.403740 [WARNING 23-08-22 17:21:31.8163 CEST gradient_boosted_trees.cc:1818] "goss_alpha" set but "sampling_method" not equal to "GOSS". [WARNING 23-08-22 17:21:31.8618 CEST gradient_boosted_trees.cc:1829] "goss_beta" set but "sampling_method" not equal to "GOSS". [WARNING 23-08-22 17:21:31.8654 CEST gradient_boosted_trees.cc:1843] "selective_gradient_boosting_ratio" set but "sampling_method" not equal to "SELGB". [INFO 23-08-22 17:21:32.1903 CEST gradient_boosted_trees.cc:1542] num-trees:1 train-loss:29.487211 train-rmse:29.487211 valid-loss:28.607134 valid-rmse:28.607134 [INFO 23-08-22 17:21:33.1783 CEST gradient_boosted_trees.cc:459] Default loss set to SQUARED_ERROR [INFO 23-08-22 17:21:33.1786 CEST gradient_boosted_trees.cc:1085] Training gradient boosted tree on 150720 example(s) and 40 feature(s). [INFO 23-08-22 17:21:33.3258 CEST gradient_boosted_trees.cc:1128] 135737 examples used for training and 14983 examples used for validation [INFO 23-08-22 17:21:33.4076 CEST gradient_boosted_trees.cc:1542] num-trees:50 train-loss:12.181689 train-rmse:12.181689 valid-loss:12.686768 valid-rmse:12.686768 [INFO 23-08-22 17:21:33.4866 CEST gradient_boosted_trees.cc:247] Truncates the model to 41 tree(s) i.e. 41 iteration(s). [INFO 23-08-22 17:21:33.4872 CEST gradient_boosted_trees.cc:310] Final model num-trees:41 valid-loss:12.684937 valid-rmse:12.684937 [WARNING 23-08-22 17:21:33.5223 CEST gradient_boosted_trees.cc:1818] "goss_alpha" set but "sampling_method" not equal to "GOSS". [WARNING 23-08-22 17:21:33.5226 CEST gradient_boosted_trees.cc:1829] "goss_beta" set but "sampling_method" not equal to "GOSS". [WARNING 23-08-22 17:21:33.5228 CEST gradient_boosted_trees.cc:1843] "selective_gradient_boosting_ratio" set but "sampling_method" not equal to "SELGB". [INFO 23-08-22 17:21:34.5676 CEST gradient_boosted_trees.cc:459] Default loss set to SQUARED_ERROR [INFO 23-08-22 17:21:34.5677 CEST gradient_boosted_trees.cc:1085] Training gradient boosted tree on 150720 example(s) and 40 feature(s). [INFO 23-08-22 17:21:34.7348 CEST gradient_boosted_trees.cc:1128] 135737 examples used for training and 14983 examples used for validation [INFO 23-08-22 17:21:34.8318 CEST gradient_boosted_trees.cc:1542] num-trees:1 train-loss:29.497025 train-rmse:29.497025 valid-loss:28.542063 valid-rmse:28.542063 [INFO 23-08-22 17:21:35.1272 CEST gradient_boosted_trees.cc:459] Default loss set to SQUARED_ERROR [INFO 23-08-22 17:21:35.1273 CEST gradient_boosted_trees.cc:1085] Training gradient boosted tree on 150720 example(s) and 40 feature(s). [INFO 23-08-22 17:21:35.2377 CEST gradient_boosted_trees.cc:1128] 135737 examples used for training and 14983 examples used for validation [INFO 23-08-22 17:21:35.8849 CEST gradient_boosted_trees.cc:459] Default loss set to SQUARED_ERROR [INFO 23-08-22 17:21:35.9068 CEST gradient_boosted_trees.cc:1085] Training gradient boosted tree on 150720 example(s) and 40 feature(s). [INFO 23-08-22 17:21:36.0690 CEST gradient_boosted_trees.cc:459] Default loss set to SQUARED_ERROR [INFO 23-08-22 17:21:36.0691 CEST gradient_boosted_trees.cc:1085] Training gradient boosted tree on 150720 example(s) and 40 feature(s). [INFO 23-08-22 17:21:36.1502 CEST gradient_boosted_trees.cc:1128] 135737 examples used for training and 14983 examples used for validation [INFO 23-08-22 17:21:36.6343 CEST gradient_boosted_trees.cc:1128] 135737 examples used for training and 14983 examples used for validation [INFO 23-08-22 17:21:36.8570 CEST gradient_boosted_trees.cc:1542] num-trees:1 train-loss:29.453743 train-rmse:29.453743 valid-loss:29.037130 valid-rmse:29.037130 [INFO 23-08-22 17:21:37.0224 CEST gradient_boosted_trees.cc:1542] num-trees:50 train-loss:13.252879 train-rmse:13.252879 valid-loss:13.566219 valid-rmse:13.566219 [INFO 23-08-22 17:21:37.0225 CEST gradient_boosted_trees.cc:247] Truncates the model to 50 tree(s) i.e. 50 iteration(s). [INFO 23-08-22 17:21:37.0225 CEST gradient_boosted_trees.cc:310] Final model num-trees:50 valid-loss:13.566219 valid-rmse:13.566219 [WARNING 23-08-22 17:21:37.0245 CEST gradient_boosted_trees.cc:1818] "goss_alpha" set but "sampling_method" not equal to "GOSS". [WARNING 23-08-22 17:21:37.0245 CEST gradient_boosted_trees.cc:1829] "goss_beta" set but "sampling_method" not equal to "GOSS". [WARNING 23-08-22 17:21:37.0245 CEST gradient_boosted_trees.cc:1843] "selective_gradient_boosting_ratio" set but "sampling_method" not equal to "SELGB". [INFO 23-08-22 17:21:37.1079 CEST gradient_boosted_trees.cc:1542] num-trees:1 train-loss:29.470354 train-rmse:29.470354 valid-loss:28.912182 valid-rmse:28.912182 [INFO 23-08-22 17:21:37.2099 CEST gradient_boosted_trees.cc:1542] num-trees:50 train-loss:14.514459 train-rmse:14.514459 valid-loss:14.994228 valid-rmse:14.994228 [INFO 23-08-22 17:21:37.2436 CEST gradient_boosted_trees.cc:247] Truncates the model to 50 tree(s) i.e. 50 iteration(s). [INFO 23-08-22 17:21:37.2473 CEST gradient_boosted_trees.cc:310] Final model num-trees:50 valid-loss:14.994228 valid-rmse:14.994228 [WARNING 23-08-22 17:21:37.3063 CEST gradient_boosted_trees.cc:1818] "goss_alpha" set but "sampling_method" not equal to "GOSS". [WARNING 23-08-22 17:21:37.3167 CEST gradient_boosted_trees.cc:1829] "goss_beta" set but "sampling_method" not equal to "GOSS". [WARNING 23-08-22 17:21:37.3167 CEST gradient_boosted_trees.cc:1843] "selective_gradient_boosting_ratio" set but "sampling_method" not equal to "SELGB". [INFO 23-08-22 17:21:37.8581 CEST gradient_boosted_trees.cc:1542] num-trees:1 train-loss:29.474899 train-rmse:29.474899 valid-loss:28.634254 valid-rmse:28.634254 [INFO 23-08-22 17:21:38.7341 CEST gradient_boosted_trees.cc:1542] num-trees:1 train-loss:29.421598 train-rmse:29.421598 valid-loss:29.626032 valid-rmse:29.626032 [INFO 23-08-22 17:21:39.3875 CEST gradient_boosted_trees.cc:459] Default loss set to SQUARED_ERROR [INFO 23-08-22 17:21:39.3893 CEST gradient_boosted_trees.cc:1085] Training gradient boosted tree on 150720 example(s) and 40 feature(s). [INFO 23-08-22 17:21:39.5529 CEST gradient_boosted_trees.cc:1128] 135737 examples used for training and 14983 examples used for validation [INFO 23-08-22 17:21:39.8978 CEST gradient_boosted_trees.cc:459] Default loss set to SQUARED_ERROR [INFO 23-08-22 17:21:39.8978 CEST gradient_boosted_trees.cc:1085] Training gradient boosted tree on 150720 example(s) and 40 feature(s). [INFO 23-08-22 17:21:40.0404 CEST gradient_boosted_trees.cc:1544] num-trees:6 train-loss:22.339996 train-rmse:22.339996 valid-loss:21.602955 valid-rmse:21.602955 [INFO 23-08-22 17:21:40.3224 CEST gradient_boosted_trees.cc:1128] 135737 examples used for training and 14983 examples used for validation [INFO 23-08-22 17:21:41.1769 CEST gradient_boosted_trees.cc:1542] num-trees:1 train-loss:29.545298 train-rmse:29.545298 valid-loss:29.298836 valid-rmse:29.298836 [INFO 23-08-22 17:21:43.4812 CEST gradient_boosted_trees.cc:1542] num-trees:1 train-loss:29.541935 train-rmse:29.541935 valid-loss:28.897583 valid-rmse:28.897583 [INFO 23-08-22 17:22:10.7016 CEST gradient_boosted_trees.cc:1544] num-trees:13 train-loss:18.213362 train-rmse:18.213362 valid-loss:18.072496 valid-rmse:18.072496 [INFO 23-08-22 17:22:41.1286 CEST gradient_boosted_trees.cc:1544] num-trees:23 train-loss:16.149427 train-rmse:16.149427 valid-loss:16.552889 valid-rmse:16.552889 [INFO 23-08-22 17:23:11.2261 CEST gradient_boosted_trees.cc:1544] num-trees:41 train-loss:15.091777 train-rmse:15.091777 valid-loss:15.722352 valid-rmse:15.722352 [INFO 23-08-22 17:23:37.3905 CEST gradient_boosted_trees.cc:1542] num-trees:50 train-loss:14.713874 train-rmse:14.713874 valid-loss:15.431265 valid-rmse:15.431265 [INFO 23-08-22 17:23:37.4181 CEST gradient_boosted_trees.cc:247] Truncates the model to 50 tree(s) i.e. 50 iteration(s). [INFO 23-08-22 17:23:37.4187 CEST gradient_boosted_trees.cc:310] Final model num-trees:50 valid-loss:15.431265 valid-rmse:15.431265 [WARNING 23-08-22 17:23:37.5522 CEST gradient_boosted_trees.cc:1818] "goss_alpha" set but "sampling_method" not equal to "GOSS". [WARNING 23-08-22 17:23:37.5523 CEST gradient_boosted_trees.cc:1829] "goss_beta" set but "sampling_method" not equal to "GOSS". [WARNING 23-08-22 17:23:37.5524 CEST gradient_boosted_trees.cc:1843] "selective_gradient_boosting_ratio" set but "sampling_method" not equal to "SELGB". [INFO 23-08-22 17:23:41.2318 CEST gradient_boosted_trees.cc:1542] num-trees:50 train-loss:14.750937 train-rmse:14.750937 valid-loss:15.528153 valid-rmse:15.528153 [INFO 23-08-22 17:23:41.2319 CEST gradient_boosted_trees.cc:247] Truncates the model to 50 tree(s) i.e. 50 iteration(s). [INFO 23-08-22 17:23:41.2319 CEST gradient_boosted_trees.cc:310] Final model num-trees:50 valid-loss:15.528153 valid-rmse:15.528153 [WARNING 23-08-22 17:23:41.2358 CEST gradient_boosted_trees.cc:1818] "goss_alpha" set but "sampling_method" not equal to "GOSS". [WARNING 23-08-22 17:23:41.2358 CEST gradient_boosted_trees.cc:1829] "goss_beta" set but "sampling_method" not equal to "GOSS". [WARNING 23-08-22 17:23:41.2358 CEST gradient_boosted_trees.cc:1843] "selective_gradient_boosting_ratio" set but "sampling_method" not equal to "SELGB". [INFO 23-08-22 17:23:41.6881 CEST gradient_boosted_trees.cc:1544] num-trees:46 train-loss:15.416377 train-rmse:15.416377 valid-loss:15.507325 valid-rmse:15.507325 [INFO 23-08-22 17:23:41.9143 CEST gradient_boosted_trees.cc:1542] num-trees:50 train-loss:15.019258 train-rmse:15.019258 valid-loss:15.995070 valid-rmse:15.995070 [INFO 23-08-22 17:23:41.9144 CEST gradient_boosted_trees.cc:247] Truncates the model to 50 tree(s) i.e. 50 iteration(s). [INFO 23-08-22 17:23:41.9144 CEST gradient_boosted_trees.cc:310] Final model num-trees:50 valid-loss:15.995070 valid-rmse:15.995070 [WARNING 23-08-22 17:23:41.9572 CEST gradient_boosted_trees.cc:1818] "goss_alpha" set but "sampling_method" not equal to "GOSS". [WARNING 23-08-22 17:23:41.9962 CEST gradient_boosted_trees.cc:1829] "goss_beta" set but "sampling_method" not equal to "GOSS". [WARNING 23-08-22 17:23:41.9966 CEST gradient_boosted_trees.cc:1843] "selective_gradient_boosting_ratio" set but "sampling_method" not equal to "SELGB". [INFO 23-08-22 17:23:42.3678 CEST gradient_boosted_trees.cc:1542] num-trees:50 train-loss:14.769040 train-rmse:14.769040 valid-loss:15.246088 valid-rmse:15.246088 [INFO 23-08-22 17:23:42.3678 CEST gradient_boosted_trees.cc:247] Truncates the model to 50 tree(s) i.e. 50 iteration(s). [INFO 23-08-22 17:23:42.3679 CEST gradient_boosted_trees.cc:310] Final model num-trees:50 valid-loss:15.246088 valid-rmse:15.246088 [WARNING 23-08-22 17:23:42.4095 CEST gradient_boosted_trees.cc:1818] "goss_alpha" set but "sampling_method" not equal to "GOSS". [WARNING 23-08-22 17:23:42.4095 CEST gradient_boosted_trees.cc:1829] "goss_beta" set but "sampling_method" not equal to "GOSS". [WARNING 23-08-22 17:23:42.4095 CEST gradient_boosted_trees.cc:1843] "selective_gradient_boosting_ratio" set but "sampling_method" not equal to "SELGB". [INFO 23-08-22 17:23:44.4584 CEST gradient_boosted_trees.cc:459] Default loss set to SQUARED_ERROR [INFO 23-08-22 17:23:44.4585 CEST gradient_boosted_trees.cc:1085] Training gradient boosted tree on 150720 example(s) and 40 feature(s). [INFO 23-08-22 17:23:45.0821 CEST gradient_boosted_trees.cc:1128] 135737 examples used for training and 14983 examples used for validation [INFO 23-08-22 17:23:45.3081 CEST gradient_boosted_trees.cc:459] Default loss set to SQUARED_ERROR [INFO 23-08-22 17:23:45.3082 CEST gradient_boosted_trees.cc:1085] Training gradient boosted tree on 150720 example(s) and 40 feature(s). [INFO 23-08-22 17:23:45.5279 CEST gradient_boosted_trees.cc:1128] 135737 examples used for training and 14983 examples used for validation [INFO 23-08-22 17:23:45.7003 CEST gradient_boosted_trees.cc:1542] num-trees:50 train-loss:15.393883 train-rmse:15.393883 valid-loss:15.816501 valid-rmse:15.816501 [INFO 23-08-22 17:23:45.7003 CEST gradient_boosted_trees.cc:247] Truncates the model to 50 tree(s) i.e. 50 iteration(s). [INFO 23-08-22 17:23:45.7004 CEST gradient_boosted_trees.cc:310] Final model num-trees:50 valid-loss:15.816501 valid-rmse:15.816501 [WARNING 23-08-22 17:23:45.7447 CEST gradient_boosted_trees.cc:1818] "goss_alpha" set but "sampling_method" not equal to "GOSS". [WARNING 23-08-22 17:23:45.7448 CEST gradient_boosted_trees.cc:1829] "goss_beta" set but "sampling_method" not equal to "GOSS". [WARNING 23-08-22 17:23:45.7448 CEST gradient_boosted_trees.cc:1843] "selective_gradient_boosting_ratio" set but "sampling_method" not equal to "SELGB". [INFO 23-08-22 17:23:47.3018 CEST gradient_boosted_trees.cc:1542] num-trees:50 train-loss:14.870501 train-rmse:14.870501 valid-loss:15.861364 valid-rmse:15.861364 [INFO 23-08-22 17:23:47.3018 CEST gradient_boosted_trees.cc:247] Truncates the model to 50 tree(s) i.e. 50 iteration(s). [INFO 23-08-22 17:23:47.3019 CEST gradient_boosted_trees.cc:310] Final model num-trees:50 valid-loss:15.861364 valid-rmse:15.861364 [WARNING 23-08-22 17:23:47.4206 CEST gradient_boosted_trees.cc:1818] "goss_alpha" set but "sampling_method" not equal to "GOSS". [WARNING 23-08-22 17:23:47.4727 CEST gradient_boosted_trees.cc:1829] "goss_beta" set but "sampling_method" not equal to "GOSS". [WARNING 23-08-22 17:23:47.4728 CEST gradient_boosted_trees.cc:1843] "selective_gradient_boosting_ratio" set but "sampling_method" not equal to "SELGB". [INFO 23-08-22 17:23:47.6738 CEST gradient_boosted_trees.cc:459] Default loss set to SQUARED_ERROR [INFO 23-08-22 17:23:47.6739 CEST gradient_boosted_trees.cc:1085] Training gradient boosted tree on 150720 example(s) and 40 feature(s). [INFO 23-08-22 17:23:47.9977 CEST gradient_boosted_trees.cc:1128] 135737 examples used for training and 14983 examples used for validation [INFO 23-08-22 17:23:48.3165 CEST gradient_boosted_trees.cc:1542] num-trees:1 train-loss:29.561636 train-rmse:29.561636 valid-loss:28.802879 valid-rmse:28.802879 [INFO 23-08-22 17:23:48.4621 CEST gradient_boosted_trees.cc:1542] num-trees:1 train-loss:29.545330 train-rmse:29.545330 valid-loss:28.827353 valid-rmse:28.827353 [INFO 23-08-22 17:23:50.4980 CEST gradient_boosted_trees.cc:459] Default loss set to SQUARED_ERROR [INFO 23-08-22 17:23:50.5432 CEST gradient_boosted_trees.cc:1085] Training gradient boosted tree on 150720 example(s) and 40 feature(s). [INFO 23-08-22 17:23:50.5479 CEST gradient_boosted_trees.cc:459] Default loss set to SQUARED_ERROR [INFO 23-08-22 17:23:50.5480 CEST gradient_boosted_trees.cc:1085] Training gradient boosted tree on 150720 example(s) and 40 feature(s). [INFO 23-08-22 17:23:50.6301 CEST gradient_boosted_trees.cc:1542] num-trees:50 train-loss:14.620991 train-rmse:14.620991 valid-loss:15.723470 valid-rmse:15.723470 [INFO 23-08-22 17:23:50.6547 CEST gradient_boosted_trees.cc:247] Truncates the model to 50 tree(s) i.e. 50 iteration(s). [INFO 23-08-22 17:23:50.6548 CEST gradient_boosted_trees.cc:310] Final model num-trees:50 valid-loss:15.723470 valid-rmse:15.723470 [WARNING 23-08-22 17:23:50.6926 CEST gradient_boosted_trees.cc:1818] "goss_alpha" set but "sampling_method" not equal to "GOSS". [WARNING 23-08-22 17:23:50.6927 CEST gradient_boosted_trees.cc:1829] "goss_beta" set but "sampling_method" not equal to "GOSS". [WARNING 23-08-22 17:23:50.6927 CEST gradient_boosted_trees.cc:1843] "selective_gradient_boosting_ratio" set but "sampling_method" not equal to "SELGB". [INFO 23-08-22 17:23:51.0291 CEST gradient_boosted_trees.cc:1128] 135737 examples used for training and 14983 examples used for validation [INFO 23-08-22 17:23:51.1478 CEST gradient_boosted_trees.cc:1542] num-trees:50 train-loss:15.277184 train-rmse:15.277184 valid-loss:15.470344 valid-rmse:15.470344 [INFO 23-08-22 17:23:51.1479 CEST gradient_boosted_trees.cc:247] Truncates the model to 50 tree(s) i.e. 50 iteration(s). [INFO 23-08-22 17:23:51.1479 CEST gradient_boosted_trees.cc:310] Final model num-trees:50 valid-loss:15.470344 valid-rmse:15.470344 [WARNING 23-08-22 17:23:51.1515 CEST gradient_boosted_trees.cc:1818] "goss_alpha" set but "sampling_method" not equal to "GOSS". [WARNING 23-08-22 17:23:51.1515 CEST gradient_boosted_trees.cc:1829] "goss_beta" set but "sampling_method" not equal to "GOSS". [WARNING 23-08-22 17:23:51.1516 CEST gradient_boosted_trees.cc:1843] "selective_gradient_boosting_ratio" set but "sampling_method" not equal to "SELGB". [INFO 23-08-22 17:23:51.4062 CEST gradient_boosted_trees.cc:1128] 135737 examples used for training and 14983 examples used for validation [INFO 23-08-22 17:23:51.4393 CEST gradient_boosted_trees.cc:1542] num-trees:1 train-loss:29.519100 train-rmse:29.519100 valid-loss:28.915615 valid-rmse:28.915615 [INFO 23-08-22 17:23:51.4788 CEST gradient_boosted_trees.cc:459] Default loss set to SQUARED_ERROR [INFO 23-08-22 17:23:51.4788 CEST gradient_boosted_trees.cc:1085] Training gradient boosted tree on 150720 example(s) and 40 feature(s). [INFO 23-08-22 17:23:51.6864 CEST gradient_boosted_trees.cc:1128] 135737 examples used for training and 14983 examples used for validation [INFO 23-08-22 17:23:53.6416 CEST [INFO 23-08-22 17:23:53.6617 CEST gradient_boosted_trees.cc:gradient_boosted_trees.cc:1542] num-trees:1 train-loss:29.555222 train-rmse:29.555222 valid-loss:29.081779 valid-rmse:29.081779 1542] num-trees:1 train-loss:29.580265 train-rmse:29.580265 valid-loss:28.985928 valid-rmse:28.985928 [INFO 23-08-22 17:23:53.8442 CEST gradient_boosted_trees.cc:459] Default loss set to SQUARED_ERROR [INFO 23-08-22 17:23:53.8442 CEST gradient_boosted_trees.cc:1085] Training gradient boosted tree on 150720 example(s) and 40 feature(s). [INFO 23-08-22 17:23:53.9488 CEST gradient_boosted_trees.cc:1128] 135737 examples used for training and 14983 examples used for validation [INFO 23-08-22 17:23:53.9779 CEST gradient_boosted_trees.cc:1542] num-trees:1 train-loss:29.485874 train-rmse:29.485874 valid-loss:29.859213 valid-rmse:29.859213 [INFO 23-08-22 17:23:54.5426 CEST gradient_boosted_trees.cc:459] Default loss set to SQUARED_ERROR [INFO 23-08-22 17:23:54.5427 CEST gradient_boosted_trees.cc:1085] Training gradient boosted tree on 150720 example(s) and 40 feature(s). [INFO 23-08-22 17:23:54.6690 CEST gradient_boosted_trees.cc:1128] 135737 examples used for training and 14983 examples used for validation [INFO 23-08-22 17:23:55.6092 CEST gradient_boosted_trees.cc:1542] num-trees:1 train-loss:29.552290 train-rmse:29.552290 valid-loss:29.436209 valid-rmse:29.436209 [INFO 23-08-22 17:23:57.1400 CEST gradient_boosted_trees.cc:1542] num-trees:1 train-loss:29.592987 train-rmse:29.592987 valid-loss:29.220953 valid-rmse:29.220953 [INFO 23-08-22 17:24:11.9398 CEST gradient_boosted_trees.cc:1544] num-trees:12 train-loss:19.211472 train-rmse:19.211472 valid-loss:19.920101 valid-rmse:19.920101 [INFO 23-08-22 17:24:42.3389 CEST gradient_boosted_trees.cc:1544] num-trees:22 train-loss:16.972153 train-rmse:16.972153 valid-loss:17.439720 valid-rmse:17.439720 [INFO 23-08-22 17:25:12.4270 CEST gradient_boosted_trees.cc:1544] num-trees:32 train-loss:16.314236 train-rmse:16.314236 valid-loss:16.762869 valid-rmse:16.762869 [INFO 23-08-22 17:25:42.6012 CEST gradient_boosted_trees.cc:1544] num-trees:48 train-loss:15.584856 train-rmse:15.584856 valid-loss:16.379702 valid-rmse:16.379702 [INFO 23-08-22 17:25:43.3731 CEST gradient_boosted_trees.cc:1542] num-trees:50 train-loss:15.488959 train-rmse:15.488959 valid-loss:16.052216 valid-rmse:16.052216 [INFO 23-08-22 17:25:43.3966 CEST gradient_boosted_trees.cc:247] Truncates the model to 50 tree(s) i.e. 50 iteration(s). [INFO 23-08-22 17:25:43.3967 CEST gradient_boosted_trees.cc:310] Final model num-trees:50 valid-loss:16.052216 valid-rmse:16.052216 [WARNING 23-08-22 17:25:43.4003 CEST gradient_boosted_trees.cc:1818] "goss_alpha" set but "sampling_method" not equal to "GOSS". [WARNING 23-08-22 17:25:43.4004 CEST gradient_boosted_trees.cc:1829] "goss_beta" set but "sampling_method" not equal to "GOSS". [WARNING 23-08-22 17:25:43.4004 CEST gradient_boosted_trees.cc:1843] "selective_gradient_boosting_ratio" set but "sampling_method" not equal to "SELGB". [INFO 23-08-22 17:25:47.8493 CEST gradient_boosted_trees.cc:1542] num-trees:50 train-loss:15.795024 train-rmse:15.795024 valid-loss:17.031176 valid-rmse:17.031176 [INFO 23-08-22 17:25:47.8494 CEST gradient_boosted_trees.cc:247] Truncates the model to 50 tree(s) i.e. 50 iteration(s). [INFO 23-08-22 17:25:47.8495 CEST gradient_boosted_trees.cc:310] Final model num-trees:50 valid-loss:17.031176 valid-rmse:17.031176 [WARNING 23-08-22 17:25:47.9558 CEST gradient_boosted_trees.cc:1818] "goss_alpha" set but "sampling_method" not equal to "GOSS". [WARNING 23-08-22 17:25:47.9558 CEST gradient_boosted_trees.cc:1829] "goss_beta" set but "sampling_method" not equal to "GOSS". [WARNING 23-08-22 17:25:47.9559 CEST gradient_boosted_trees.cc:1843] "selective_gradient_boosting_ratio" set but "sampling_method" not equal to "SELGB". [INFO 23-08-22 17:25:48.0492 CEST gradient_boosted_trees.cc:1542] num-trees:50 train-loss:15.498506 train-rmse:15.498506 valid-loss:16.925005 valid-rmse:16.925005 [INFO 23-08-22 17:25:48.0493 CEST gradient_boosted_trees.cc:247] Truncates the model to 50 tree(s) i.e. 50 iteration(s). [INFO 23-08-22 17:25:48.0493 CEST gradient_boosted_trees.cc:310] Final model num-trees:50 valid-loss:16.925005 valid-rmse:16.925005 [WARNING 23-08-22 17:25:48.1019 CEST gradient_boosted_trees.cc:1818] "goss_alpha" set but "sampling_method" not equal to "GOSS". [WARNING 23-08-22 17:25:48.1020 CEST gradient_boosted_trees.cc:1829] "goss_beta" set but "sampling_method" not equal to "GOSS". [WARNING 23-08-22 17:25:48.1020 CEST gradient_boosted_trees.cc:1843] "selective_gradient_boosting_ratio" set but "sampling_method" not equal to "SELGB". [INFO 23-08-22 17:25:49.0721 CEST gradient_boosted_trees.cc:1542] num-trees:50 train-loss:15.436479 train-rmse:15.436479 valid-loss:16.489502 valid-rmse:16.489502 [INFO 23-08-22 17:25:49.0858 CEST gradient_boosted_trees.cc:247] Truncates the model to 50 tree(s) i.e. 50 iteration(s). [INFO 23-08-22 17:25:49.0859 CEST gradient_boosted_trees.cc:310] Final model num-trees:50 valid-loss:16.489502 valid-rmse:16.489502 [INFO 23-08-22 17:25:49.3451 CEST gradient_boosted_trees.cc:1542] num-trees:50 train-loss:15.940226 train-rmse:15.940226 valid-loss:16.628620 valid-rmse:16.628620 [INFO 23-08-22 17:25:49.3730 CEST gradient_boosted_trees.cc:247] Truncates the model to 50 tree(s) i.e. 50 iteration(s). [INFO 23-08-22 17:25:49.3731 CEST gradient_boosted_trees.cc:310] Final model num-trees:50 valid-loss:16.628620 valid-rmse:16.628620 [INFO 23-08-22 17:25:49.5604 CEST gradient_boosted_trees.cc:1542] num-trees:50 train-loss:15.528732 train-rmse:15.528732 valid-loss:16.360813 valid-rmse:16.360813 [INFO 23-08-22 17:25:49.5826 CEST gradient_boosted_trees.cc:247] Truncates the model to 50 tree(s) i.e. 50 iteration(s). [INFO 23-08-22 17:25:49.5827 CEST gradient_boosted_trees.cc:310] Final model num-trees:50 valid-loss:16.360813 valid-rmse:16.360813 [INFO 23-08-22 17:25:49.7487 CEST gradient_boosted_trees.cc:459] Default loss set to SQUARED_ERROR [INFO 23-08-22 17:25:49.7488 CEST gradient_boosted_trees.cc:1085] Training gradient boosted tree on 150720 example(s) and 40 feature(s). [INFO 23-08-22 17:25:49.8992 CEST gradient_boosted_trees.cc:1542] num-trees:50 train-loss:15.585465 train-rmse:15.585465 valid-loss:16.446827 valid-rmse:16.446827 [INFO 23-08-22 17:25:49.9236 CEST gradient_boosted_trees.cc:247] Truncates the model to 50 tree(s) i.e. 50 iteration(s). [INFO 23-08-22 17:25:49.9237 CEST gradient_boosted_trees.cc:310] Final model num-trees:50 valid-loss:16.446827 valid-rmse:16.446827 [INFO 23-08-22 17:25:50.0453 CEST gradient_boosted_trees.cc:1128] 135737 examples used for training and 14983 examples used for validation [INFO 23-08-22 17:25:51.9348 CEST gradient_boosted_trees.cc:459] Default loss set to SQUARED_ERROR [INFO 23-08-22 17:25:51.9349 CEST gradient_boosted_trees.cc:1085] Training gradient boosted tree on 150720 example(s) and 40 feature(s). [INFO 23-08-22 17:25:52.1247 CEST gradient_boosted_trees.cc[INFO 23-08-22 17:25:52.1449 CEST gradient_boosted_trees.cc:459] Default loss set to SQUARED_ERROR [INFO 23-08-22 17:25:52.1450 CEST gradient_boosted_trees.cc:1085] Training gradient boosted tree on 150720 example(s) and 40 feature(s). :1542] num-trees:1 train-loss:29.473177 train-rmse:29.473177 valid-loss:30.028440 valid-rmse:30.028440 [INFO 23-08-22 17:25:52.1676 CEST gradient_boosted_trees.cc:1128] 135737 examples used for training and 14983 examples used for validation [INFO 23-08-22 17:25:52.8560 CEST gradient_boosted_trees.cc:1128] 135737 examples used for training and 14983 examples used for validation [INFO 23-08-22 17:25:53.4240 CEST gradient_boosted_trees.cc:1542] num-trees:50 train-loss:15.958979 train-rmse:15.958979 valid-loss:17.016514 valid-rmse:17.016514 [INFO 23-08-22 17:25:53.4504 CEST gradient_boosted_trees.cc:247] Truncates the model to 50 tree(s) i.e. 50 iteration(s). [INFO 23-08-22 17:25:53.4529 CEST gradient_boosted_trees.cc:310] Final model num-trees:50 valid-loss:17.016514 valid-rmse:17.016514 [INFO 23-08-22 17:25:54.2969 CEST gradient_boosted_trees.cc:1542] num-trees:1 train-loss:29.512590 train-rmse:29.512590 valid-loss:29.749025 valid-rmse:29.749025 [INFO 23-08-22 17:25:55.0639 CEST gradient_boosted_trees.cc:1542] num-trees:1 train-loss:29.433599 train-rmse:29.433599 valid-loss:30.823900 valid-rmse:30.823900 [INFO 23-08-22 17:26:12.6080 CEST gradient_boosted_trees.cc:1544] num-trees:14 train-loss:18.923498 train-rmse:18.923498 valid-loss:19.393936 valid-rmse:19.393936 [INFO 23-08-22 17:26:42.7529 CEST gradient_boosted_trees.cc:1544] num-trees:46 train-loss:16.113173 train-rmse:16.113173 valid-loss:17.555851 valid-rmse:17.555851 [INFO 23-08-22 17:26:45.2334 CEST gradient_boosted_trees.cc:1542] num-trees:50 train-loss:15.972644 train-rmse:15.972644 valid-loss:17.476349 valid-rmse:17.476349 [INFO 23-08-22 17:26:45.2351 CEST gradient_boosted_trees.cc:247] Truncates the model to 50 tree(s) i.e. 50 iteration(s). [INFO 23-08-22 17:26:45.2352 CEST gradient_boosted_trees.cc:310] Final model num-trees:50 valid-loss:17.476349 valid-rmse:17.476349 [INFO 23-08-22 17:26:46.1924 CEST gradient_boosted_trees.cc:1542] num-trees:50 train-loss:15.949216 train-rmse:15.949216 valid-loss:16.998175 valid-rmse:16.998175 [INFO 23-08-22 17:26:46.1925 CEST gradient_boosted_trees.cc:247] Truncates the model to 50 tree(s) i.e. 50 iteration(s). [INFO 23-08-22 17:26:46.1925 CEST gradient_boosted_trees.cc:310] Final model num-trees:50 valid-loss:16.998175 valid-rmse:16.998175 [INFO 23-08-22 17:26:46.2895 CEST gradient_boosted_trees.cc:1542] num-trees:50 train-loss:15.933821 train-rmse:15.933821 valid-loss:18.116308 valid-rmse:18.116308 [INFO 23-08-22 17:26:46.2895 CEST gradient_boosted_trees.cc:247] Truncates the model to 50 tree(s) i.e. 50 iteration(s). [INFO 23-08-22 17:26:46.2895 CEST gradient_boosted_trees.cc:310] Final model num-trees:50 valid-loss:18.116308 valid-rmse:18.116308 [INFO 23-08-22 17:26:46.2920 CEST kernel.cc:926] Export model in log directory: /tmp/tmpfn9n19rs with prefix 5b2c1467920142a0 [INFO 23-08-22 17:26:46.3781 CEST kernel.cc:944] Save model in resources [WARNING 23-08-22 17:26:46.3801 CEST abstract_model.cc:1058] Validation evaluation not supported for MULTITASKER [INFO 23-08-22 17:26:46.3803 CEST abstract_model.cc:849] Model self evaluation: Number of predictions (with weights): 1 Task: REGRESSION Loss (SQUARED_ERROR): 12.6849 RMSE: 3.56159 Default RMSE: : 0 [INFO 23-08-22 17:26:46.3808 CEST abstract_model.cc:849] Model self evaluation: Number of predictions (with weights): 1 Task: REGRESSION Loss (SQUARED_ERROR): 13.4037 RMSE: 3.66111 Default RMSE: : 0 [INFO 23-08-22 17:26:46.3813 CEST abstract_model.cc:849] Model self evaluation: Number of predictions (with weights): 1 Task: REGRESSION Loss (SQUARED_ERROR): 13.4538 RMSE: 3.66794 Default RMSE: : 0 [INFO 23-08-22 17:26:46.3818 CEST abstract_model.cc:849] Model self evaluation: Number of predictions (with weights): 1 Task: REGRESSION Loss (SQUARED_ERROR): 13.5662 RMSE: 3.68323 Default RMSE: : 0 [INFO 23-08-22 17:26:46.3823 CEST abstract_model.cc:849] Model self evaluation: Number of predictions (with weights): 1 Task: REGRESSION Loss (SQUARED_ERROR): 15.0292 RMSE: 3.87676 Default RMSE: : 0 [INFO 23-08-22 17:26:46.3828 CEST abstract_model.cc:849] Model self evaluation: Number of predictions (with weights): 1 Task: REGRESSION Loss (SQUARED_ERROR): 15.3554 RMSE: 3.9186 Default RMSE: : 0 [INFO 23-08-22 17:26:46.3833 CEST abstract_model.cc:849] Model self evaluation: Number of predictions (with weights): 1 Task: REGRESSION Loss (SQUARED_ERROR): 14.5934 RMSE: 3.82013 Default RMSE: : 0 [INFO 23-08-22 17:26:46.3836 CEST abstract_model.cc:849] Model self evaluation: Number of predictions (with weights): 1 Task: REGRESSION Loss (SQUARED_ERROR): 14.9942 RMSE: 3.87224 Default RMSE: : 0 [INFO 23-08-22 17:26:46.3841 CEST abstract_model.cc:849] Model self evaluation: Number of predictions (with weights): 1 Task: REGRESSION Loss (SQUARED_ERROR): 15.4313 RMSE: 3.92826 Default RMSE: : 0 [INFO 23-08-22 17:26:46.3846 CEST abstract_model.cc:849] Model self evaluation: Number of predictions (with weights): 1 Task: REGRESSION Loss (SQUARED_ERROR): 15.5282 RMSE: 3.94058 Default RMSE: : 0 [INFO 23-08-22 17:26:46.3850 CEST abstract_model.cc:849] Model self evaluation: Number of predictions (with weights): 1 Task: REGRESSION Loss (SQUARED_ERROR): 15.7235 RMSE: 3.96528 Default RMSE: : 0 [INFO 23-08-22 17:26:46.3854 CEST abstract_model.cc:849] Model self evaluation: Number of predictions (with weights): 1 Task: REGRESSION Loss (SQUARED_ERROR): 15.2461 RMSE: 3.90462 Default RMSE: : 0 [INFO 23-08-22 17:26:46.3858 CEST abstract_model.cc:849] Model self evaluation: Number of predictions (with weights): 1 Task: REGRESSION Loss (SQUARED_ERROR): 15.8614 RMSE: 3.98263 Default RMSE: : 0 [INFO 23-08-22 17:26:46.3862 CEST abstract_model.cc:849] Model self evaluation: Number of predictions (with weights): 1 Task: REGRESSION Loss (SQUARED_ERROR): 15.9951 RMSE: 3.99938 Default RMSE: : 0 [INFO 23-08-22 17:26:46.3865 CEST abstract_model.cc:849] Model self evaluation: Number of predictions (with weights): 1 Task: REGRESSION Loss (SQUARED_ERROR): 15.4703 RMSE: 3.93324 Default RMSE: : 0 [INFO 23-08-22 17:26:46.3869 CEST abstract_model.cc:849] Model self evaluation: Number of predictions (with weights): 1 Task: REGRESSION Loss (SQUARED_ERROR): 15.8165 RMSE: 3.977 Default RMSE: : 0 [INFO 23-08-22 17:26:46.3872 CEST abstract_model.cc:849] Model self evaluation: Number of predictions (with weights): 1 Task: REGRESSION Loss (SQUARED_ERROR): 16.0522 RMSE: 4.00652 Default RMSE: : 0 [INFO 23-08-22 17:26:46.3876 CEST abstract_model.cc:849] Model self evaluation: Number of predictions (with weights): 1 Task: REGRESSION Loss (SQUARED_ERROR): 16.4895 RMSE: 4.06073 Default RMSE: : 0 [INFO 23-08-22 17:26:46.3881 CEST abstract_model.cc:849] Model self evaluation: Number of predictions (with weights): 1 Task: REGRESSION Loss (SQUARED_ERROR): 16.3608 RMSE: 4.04485 Default RMSE: : 0 [INFO 23-08-22 17:26:46.3885 CEST abstract_model.cc:849] Model self evaluation: Number of predictions (with weights): 1 Task: REGRESSION Loss (SQUARED_ERROR): 16.925 RMSE: 4.114 Default RMSE: : 0 [INFO 23-08-22 17:26:46.3888 CEST abstract_model.cc:849] Model self evaluation: Number of predictions (with weights): 1 Task: REGRESSION Loss (SQUARED_ERROR): 16.4468 RMSE: 4.05547 Default RMSE: : 0 [INFO 23-08-22 17:26:46.3892 CEST abstract_model.cc:849] Model self evaluation: Number of predictions (with weights): 1 Task: REGRESSION Loss (SQUARED_ERROR): 17.0312 RMSE: 4.12688 Default RMSE: : 0 [INFO 23-08-22 17:26:46.3896 CEST abstract_model.cc:849] Model self evaluation: Number of predictions (with weights): 1 Task: REGRESSION Loss (SQUARED_ERROR): 16.6286 RMSE: 4.07782 Default RMSE: : 0 [INFO 23-08-22 17:26:46.3900 CEST abstract_model.cc:849] Model self evaluation: Number of predictions (with weights): 1 Task: REGRESSION Loss (SQUARED_ERROR): 17.0165 RMSE: 4.12511 Default RMSE: : 0 [INFO 23-08-22 17:26:46.3905 CEST abstract_model.cc:849] Model self evaluation: Number of predictions (with weights): 1 Task: REGRESSION Loss (SQUARED_ERROR): 17.4763 RMSE: 4.18047 Default RMSE: : 0 [INFO 23-08-22 17:26:46.3909 CEST abstract_model.cc:849] Model self evaluation: Number of predictions (with weights): 1 Task: REGRESSION Loss (SQUARED_ERROR): 16.9982 RMSE: 4.12288 Default RMSE: : 0 [INFO 23-08-22 17:26:46.3912 CEST abstract_model.cc:849] Model self evaluation: Number of predictions (with weights): 1 Task: REGRESSION Loss (SQUARED_ERROR): 18.1163 RMSE: 4.25633 Default RMSE: : 0 [INFO 23-08-22 17:26:46.4543 CEST kernel.cc:1243] Loading model from path /tmp/tmpfn9n19rs/model/ with prefix 5b2c1467920142a0_0 [INFO 23-08-22 17:26:46.4598 CEST abstract_model.cc:1311] Engine "GradientBoostedTreesQuickScorerExtended" built [INFO 23-08-22 17:26:46.4599 CEST kernel.cc:1075] Use fast generic engine [INFO 23-08-22 17:26:46.6703 CEST kernel.cc:1243] Loading model from path /tmp/tmpfn9n19rs/model/ with prefix 5b2c1467920142a0_1 [INFO 23-08-22 17:26:46.6773 CEST kernel.cc:1075] Use fast generic engine [INFO 23-08-22 17:26:46.7141 CEST kernel.cc:1243] Loading model from path /tmp/tmpfn9n19rs/model/ with prefix 5b2c1467920142a0_2 [INFO 23-08-22 17:26:46.7188 CEST kernel.cc:1075] Use fast generic engine [INFO 23-08-22 17:26:46.7456 CEST kernel.cc:1243] Loading model from path /tmp/tmpfn9n19rs/model/ with prefix 5b2c1467920142a0_3 [INFO 23-08-22 17:26:46.7522 CEST kernel.cc:1075] Use fast generic engine [INFO 23-08-22 17:26:46.7786 CEST kernel.cc:1243] Loading model from path /tmp/tmpfn9n19rs/model/ with prefix 5b2c1467920142a0_4 [INFO 23-08-22 17:26:46.7844 CEST kernel.cc:1075] Use fast generic engine [INFO 23-08-22 17:26:46.8141 CEST kernel.cc:1243] Loading model from path /tmp/tmpfn9n19rs/model/ with prefix 5b2c1467920142a0_5 [INFO 23-08-22 17:26:46.8192 CEST kernel.cc:1075] Use fast generic engine [INFO 23-08-22 17:26:46.8565 CEST kernel.cc:1243] Loading model from path /tmp/tmpfn9n19rs/model/ with prefix 5b2c1467920142a0_6 [INFO 23-08-22 17:26:46.8639 CEST kernel.cc:1075] Use fast generic engine [INFO 23-08-22 17:26:46.8908 CEST kernel.cc:1243] Loading model from path /tmp/tmpfn9n19rs/model/ with prefix 5b2c1467920142a0_7 [INFO 23-08-22 17:26:46.8960 CEST kernel.cc:1075] Use fast generic engine [INFO 23-08-22 17:26:46.9250 CEST kernel.cc:1243] Loading model from path /tmp/tmpfn9n19rs/model/ with prefix 5b2c1467920142a0_8 [INFO 23-08-22 17:26:46.9325 CEST kernel.cc:1075] Use fast generic engine [INFO 23-08-22 17:26:46.9626 CEST kernel.cc:1243] Loading model from path /tmp/tmpfn9n19rs/model/ with prefix 5b2c1467920142a0_9 [INFO 23-08-22 17:26:46.9694 CEST kernel.cc:1075] Use fast generic engine [INFO 23-08-22 17:26:47.0174 CEST kernel.cc:1243] Loading model from path /tmp/tmpfn9n19rs/model/ with prefix 5b2c1467920142a0_10 [INFO 23-08-22 17:26:47.0231 CEST kernel.cc:1075] Use fast generic engine [INFO 23-08-22 17:26:47.0515 CEST kernel.cc:1243] Loading model from path /tmp/tmpfn9n19rs/model/ with prefix 5b2c1467920142a0_11 [INFO 23-08-22 17:26:47.0572 CEST kernel.cc:1075] Use fast generic engine [INFO 23-08-22 17:26:47.0883 CEST kernel.cc:1243] Loading model from path /tmp/tmpfn9n19rs/model/ with prefix 5b2c1467920142a0_12 [INFO 23-08-22 17:26:47.0935 CEST kernel.cc:1075] Use fast generic engine [INFO 23-08-22 17:26:47.1232 CEST kernel.cc:1243] Loading model from path /tmp/tmpfn9n19rs/model/ with prefix 5b2c1467920142a0_13 [INFO 23-08-22 17:26:47.1283 CEST kernel.cc:1075] Use fast generic engine [INFO 23-08-22 17:26:47.1589 CEST kernel.cc:1243] Loading model from path /tmp/tmpfn9n19rs/model/ with prefix 5b2c1467920142a0_14 [INFO 23-08-22 17:26:47.1640 CEST kernel.cc:1075] Use fast generic engine [INFO 23-08-22 17:26:47.1923 CEST kernel.cc:1243] Loading model from path /tmp/tmpfn9n19rs/model/ with prefix 5b2c1467920142a0_15 [INFO 23-08-22 17:26:47.1974 CEST kernel.cc:1075] Use fast generic engine [INFO 23-08-22 17:26:47.2254 CEST kernel.cc:1243] Loading model from path /tmp/tmpfn9n19rs/model/ with prefix 5b2c1467920142a0_16 [INFO 23-08-22 17:26:47.2307 CEST kernel.cc:1075] Use fast generic engine [INFO 23-08-22 17:26:47.2588 CEST kernel.cc:1243] Loading model from path /tmp/tmpfn9n19rs/model/ with prefix 5b2c1467920142a0_17 [INFO 23-08-22 17:26:47.2641 CEST kernel.cc:1075] Use fast generic engine [INFO 23-08-22 17:26:47.2919 CEST kernel.cc:1243] Loading model from path /tmp/tmpfn9n19rs/model/ with prefix 5b2c1467920142a0_18 [INFO 23-08-22 17:26:47.2972 CEST kernel.cc:1075] Use fast generic engine [INFO 23-08-22 17:26:47.3378 CEST kernel.cc:1243] Loading model from path /tmp/tmpfn9n19rs/model/ with prefix 5b2c1467920142a0_19 [INFO 23-08-22 17:26:47.3459 CEST kernel.cc:1075] Use fast generic engine [INFO 23-08-22 17:26:47.3834 CEST kernel.cc:1243] Loading model from path /tmp/tmpfn9n19rs/model/ with prefix 5b2c1467920142a0_20 [INFO 23-08-22 17:26:47.3918 CEST kernel.cc:1075] Use fast generic engine [INFO 23-08-22 17:26:47.4245 CEST kernel.cc:1243] Loading model from path /tmp/tmpfn9n19rs/model/ with prefix 5b2c1467920142a0_21 [INFO 23-08-22 17:26:47.4294 CEST kernel.cc:1075] Use fast generic engine [INFO 23-08-22 17:26:47.4576 CEST kernel.cc:1243] Loading model from path /tmp/tmpfn9n19rs/model/ with prefix 5b2c1467920142a0_22 [INFO 23-08-22 17:26:47.4631 CEST kernel.cc:1075] Use fast generic engine [INFO 23-08-22 17:26:47.4906 CEST kernel.cc:1243] Loading model from path /tmp/tmpfn9n19rs/model/ with prefix 5b2c1467920142a0_23 [INFO 23-08-22 17:26:47.4953 CEST kernel.cc:1075] Use fast generic engine [INFO 23-08-22 17:26:47.5222 CEST kernel.cc:1243] Loading model from path /tmp/tmpfn9n19rs/model/ with prefix 5b2c1467920142a0_24 [INFO 23-08-22 17:26:47.5276 CEST kernel.cc:1075] Use fast generic engine [INFO 23-08-22 17:26:47.5570 CEST kernel.cc:1243] Loading model from path /tmp/tmpfn9n19rs/model/ with prefix 5b2c1467920142a0_25 [INFO 23-08-22 17:26:47.5627 CEST kernel.cc:1075] Use fast generic engine [INFO 23-08-22 17:26:47.5937 CEST kernel.cc:1243] Loading model from path /tmp/tmpfn9n19rs/model/ with prefix 5b2c1467920142a0_26 [INFO 23-08-22 17:26:47.6032 CEST kernel.cc:1075] Use fast generic engine
Model trained in 0:07:19.827763 Compiling model...
WARNING:tensorflow:AutoGraph could not transform <function simple_ml_inference_op_with_handle at 0x7f1d92732050> and will run it as-is. Please report this to the TensorFlow team. When filing the bug, set the verbosity to 10 (on Linux, `export AUTOGRAPH_VERBOSITY=10`) and attach the full output. Cause: could not get source code To silence this warning, decorate the function with @tf.autograph.experimental.do_not_convert
WARNING: AutoGraph could not transform <function simple_ml_inference_op_with_handle at 0x7f1d92732050> and will run it as-is. Please report this to the TensorFlow team. When filing the bug, set the verbosity to 10 (on Linux, `export AUTOGRAPH_VERBOSITY=10`) and attach the full output. Cause: could not get source code To silence this warning, decorate the function with @tf.autograph.experimental.do_not_convert Model compiled.
<keras.src.callbacks.History at 0x7f1d91badc00>
Let's generate the predictions on the test dataset.
tf_predictions = model.predict(tf_test_dataset, verbose=0)
Let's convert those TensorFlow predictions into a Temporian EventSet. This way we will be able to plot the predictions alongside the real sales.
index_names = tabular_test.schema.index_names()
raw_predicted_sales = defaultdict(list)
timestamps = []
# For each product
for row_idx in range(len(test_dataset)):
original_timestamp = datetime.fromtimestamp(
test_dataset["timestamp"][row_idx], tz=timezone.utc
)
# For each prediction horizon
for horizon, predictions in zip(horizons, tf_predictions.values()):
timestamps.append(original_timestamp + timedelta(days=horizon))
for k in index_names:
raw_predicted_sales[k].append(test_dataset[k][row_idx])
raw_predicted_sales["prediction_sales"].append(predictions[row_idx, 0])
# Convert the dictionary of values into an event set.
prediction_evset = tp.event_set(
timestamps, raw_predicted_sales, indexes=index_names
)
Finally, we can plot the real sales and predicted sales.
Remember: Update the variable horizons
to change the number of days the model is predicting (14 by default).
Plot predictions¶
Let's now show some predictions and compare them against the real sales. The sales before the test day 1914 are considered past sales, and then we compare the predictions against real sales after the test day.
In this cell we'll just use the standard plots, and then we'll customize them to better compare predictions against ground-truth.
real_sales_evset = sales_evset["sales"].filter(sales_evset["day"] > 1914)
past_sales_evset = sales_evset["sales"].filter((sales_evset["day"] <= 1914) & (sales_evset["day"] >= 1914 - 40))
# Rename and plot together
real_sales_evset = real_sales_evset.rename("real_sales")
past_sales_evset = past_sales_evset.rename("past_sales")
prediction_evset = prediction_evset.rename("predicted_sales")
tp.plot(
[real_sales_evset, prediction_evset, past_sales_evset],
max_num_plots=3*2,
width_px=600,
merge=True,
)
The number of plots (80) is larger than "options.max_num_plots=6". Only the first plots will be printed.
How does that model work? We can look at the variable importance to get an idea of what feature matters the most with model.summary()
.
Note that this model contains in fact one individual model for each horizon. In other words, this model contains 28 sub models!