In [1]:
# remove the notebook root logger.\n",
import logging
logger = logging.getLogger()
logger.handlers = []

In [2]:
import pandas as pd

Hierarchical Forecasting with PyAF

In this document , we give a use case of hierarchcial forecasting wioth PyAF.

We study the problem of forecasting France wine exportation by wine type (Champagne , Bordeaux, etc), variant (red , white, sparkling etc) and destination country.

A dataset has been built based on French government opendata gratefully provided by the foreign trade ministry. This dataset is available here : https://github.com/antoinecarme/TimeSeriesData/tree/master/Stat_FR_CommExt.

Please note that the original dataset is generic and contains export data for all foreign trade products to all possible countries with a significant level of detail (cars, crops, living animals , legal weapons , ...).

Data Overview

The dataset is a collection of 2872 monthly time series overserved on a period ranging from 2012-01-01 to 2016-09-01.

Each time series has 50 rows (some data are missing in 2015 , under investigation) and represents the export of a given type of wine, a given variant to a unique contry.

The time series column name is built by concatenating the three above informations.

To simplify, we will reduce the number of countries to the 10 most signficant (wine-friendly) ones. This reduces the number of columns to 176 ;)


In [3]:
import datetime

filename = "https://raw.githubusercontent.com/antoinecarme/TimeSeriesData/master/Stat_FR_CommExt/merged/French_Wine_Export_in_Euros_Some_Countries.csv"

French_Wine_Export_in_Euros_DF = pd.read_csv(filename);

lDateColumn = 'Month';
French_Wine_Export_in_Euros_DF[lDateColumn] = French_Wine_Export_in_Euros_DF[lDateColumn].apply(lambda x : datetime.datetime.strptime(str(x), "%Y-%m-%d"))

French_Wine_Export_in_Euros_DF.head(5)


Out[3]:
Month ALSACE_BLANC_BE ALSACE_BLANC_CA ALSACE_BLANC_CH ALSACE_BLANC_CN ALSACE_BLANC_DE ALSACE_BLANC_GB ALSACE_BLANC_HK ALSACE_BLANC_JP ALSACE_BLANC_NL ... RHÔNE_ROUGE_CA RHÔNE_ROUGE_CH RHÔNE_ROUGE_CN RHÔNE_ROUGE_DE RHÔNE_ROUGE_GB RHÔNE_ROUGE_HK RHÔNE_ROUGE_JP RHÔNE_ROUGE_NL RHÔNE_ROUGE_OTHER RHÔNE_ROUGE_US
0 2012-01-01 1131852 571940 257116 140013 357516 344274 51043 329883 624695 ... 800628 650236 1127393 783952 1513332 335710 916965 314654 35418 1260510
1 2012-02-01 857289 585556 187917 89805 505896 424953 80220 239242 899144 ... 795356 680567 188827 868576 1277664 197072 318522 516140 36604 2136484
2 2012-03-01 1438501 834142 679281 103577 583887 352675 102980 394945 1093638 ... 873858 1318538 856382 627236 2343448 132200 605914 410308 43197 3264810
3 2012-04-01 986602 866221 523202 203456 515903 403517 52773 260953 874217 ... 1004028 919493 460815 829432 1861188 128164 472522 290407 45396 2631466
4 2012-05-01 991668 1061702 611369 80327 767522 627232 78115 680323 994697 ... 2098300 632778 239200 934532 2215922 202210 337894 284868 41469 2945175

5 rows × 177 columns


In [4]:
French_Wine_Export_in_Euros_DF.describe()


Out[4]:
ALSACE_BLANC_BE ALSACE_BLANC_CA ALSACE_BLANC_CH ALSACE_BLANC_CN ALSACE_BLANC_DE ALSACE_BLANC_GB ALSACE_BLANC_HK ALSACE_BLANC_JP ALSACE_BLANC_NL ALSACE_BLANC_OTHER ... RHÔNE_ROUGE_CA RHÔNE_ROUGE_CH RHÔNE_ROUGE_CN RHÔNE_ROUGE_DE RHÔNE_ROUGE_GB RHÔNE_ROUGE_HK RHÔNE_ROUGE_JP RHÔNE_ROUGE_NL RHÔNE_ROUGE_OTHER RHÔNE_ROUGE_US
count 5.000000e+01 5.000000e+01 50.000000 50.000000 5.000000e+01 50.000000 50.000000 50.000000 5.000000e+01 50.000000 ... 5.000000e+01 5.000000e+01 5.000000e+01 5.000000e+01 5.000000e+01 50.000000 5.000000e+01 5.000000e+01 50.000000 5.000000e+01
mean 1.189956e+06 8.037735e+05 428923.380000 119348.360000 6.173951e+05 414037.100000 88636.820000 361437.900000 8.035454e+05 38337.801569 ... 1.607702e+06 8.523710e+05 7.498312e+05 1.072562e+06 2.876061e+06 235678.640000 5.760031e+05 4.986103e+05 52907.080000 2.912355e+06
std 2.780384e+05 1.691507e+05 158179.648178 65116.609016 2.765474e+05 116398.158498 68347.582681 110140.042643 2.732401e+05 6088.988573 ... 7.064099e+05 2.458533e+05 3.592653e+05 4.307817e+05 1.366642e+06 140071.773582 2.398091e+05 1.720202e+05 9667.885799 6.675896e+05
min 5.477480e+05 3.514620e+05 88329.000000 19546.000000 3.131500e+05 168388.000000 31864.000000 192553.000000 3.085880e+05 18550.156250 ... 7.935600e+05 3.992940e+05 1.888270e+05 5.558550e+05 1.277664e+06 77550.000000 2.053840e+05 2.311020e+05 35238.000000 1.260510e+06
25% 1.004816e+06 6.791068e+05 316753.500000 82278.500000 4.801042e+05 333264.500000 52845.750000 293690.250000 6.061862e+05 35457.417067 ... 1.047350e+06 6.819278e+05 5.089532e+05 7.219495e+05 2.025437e+06 152307.750000 3.751060e+05 3.725818e+05 46721.000000 2.500847e+06
50% 1.161726e+06 8.070940e+05 445554.500000 98656.000000 5.449660e+05 401774.500000 76561.500000 335180.000000 7.884350e+05 38715.394123 ... 1.506712e+06 8.120535e+05 7.065070e+05 9.246160e+05 2.519672e+06 203395.000000 5.414685e+05 4.674045e+05 52305.000000 2.896628e+06
75% 1.323582e+06 8.880218e+05 542924.000000 161694.000000 6.549058e+05 515408.000000 102011.750000 417475.000000 8.980862e+05 41900.001008 ... 1.936743e+06 1.023269e+06 9.285735e+05 1.207832e+06 3.018630e+06 257873.500000 7.998980e+05 6.143272e+05 59756.250000 3.380802e+06
max 2.166585e+06 1.216720e+06 857207.000000 317661.000000 1.871515e+06 635447.000000 510151.000000 680323.000000 1.458234e+06 52823.280702 ... 3.946934e+06 1.334550e+06 1.755449e+06 2.312776e+06 8.652432e+06 879037.000000 1.076535e+06 1.063568e+06 71487.000000 4.664273e+06

8 rows × 176 columns

To give an example, the following plot compares the export of Champagne to Germany, Japan and UK:


In [5]:
%matplotlib inline

In [6]:
French_Wine_Export_in_Euros_DF.plot('Month' , 
                                    ['CHAMPAGNE_MOUSSEUX_DE', 'CHAMPAGNE_MOUSSEUX_GB' , 'CHAMPAGNE_MOUSSEUX_JP'],
                                   figsize=(32 , 12)).legend(loc='best', fontsize=24)


Out[6]:
<matplotlib.legend.Legend at 0x7feb3960b730>

While the next one compares US consumption (in Euros) of red and white Bordeaux ;)


In [7]:
French_Wine_Export_in_Euros_DF.plot('Month' , 
                                    ['BORDEAUX_BLANC_US', 'BORDEAUX_ROUGE_US'],
                                    fontsize = 24,
                                    figsize=(32 , 12)).legend(loc='best', fontsize=24)


Out[7]:
<matplotlib.legend.Legend at 0x7feb395590d0>

In [8]:
CN_columns = [col for col in French_Wine_Export_in_Euros_DF.columns if col.endswith('_CN') ]
French_Wine_Export_in_Euros_DF[CN_columns].describe()


Out[8]:
ALSACE_BLANC_CN BEAUJOLAIS_ROUGE_CN BORDEAUX_BLANC_CN BORDEAUX_ROUGE_CN BOURGOGNE_BLANC_CN BOURGOGNE_ROUGE_CN CHAMPAGNE_MOUSSEUX_CN EUROPE_ROUGE_CN FRANCE_BLANC_CN FRANCE_MOUSSEUX_CN FRANCE_ROUGE_CN LANGUEDOC_ROUGE_CN LOIRE_BLANC_CN LOIRE_ROUGE_CN OTHER_ROUGE_CN RHÔNE_ROUGE_CN
count 50.000000 50.00000 5.000000e+01 5.000000e+01 50.000000 5.000000e+01 5.000000e+01 5.000000e+01 50.000000 50.000000 50.000000 5.000000e+01 50.000000 50.000000 50.000000 5.000000e+01
mean 119348.360000 130292.47000 4.993186e+05 1.138432e+07 242575.340000 7.436432e+05 6.225160e+05 8.313372e+05 12978.062000 93298.256667 11185.281403 1.304245e+06 48771.330000 92016.740000 52969.948000 7.498312e+05
std 65116.609016 102214.45714 2.936971e+05 3.081051e+06 99492.736867 4.176045e+05 3.812781e+05 2.337996e+05 24705.479992 63521.773261 13888.069451 6.352887e+05 27922.200988 54704.609614 36129.014739 3.592653e+05
min 19546.000000 5833.00000 1.678740e+05 5.377235e+06 75396.000000 2.725460e+05 1.976760e+05 3.270090e+05 0.000000 20488.500000 260.500000 4.916860e+05 16643.500000 15325.000000 6337.750000 1.888270e+05
25% 82278.500000 66206.50000 3.117738e+05 9.737536e+06 171633.250000 4.214805e+05 3.897600e+05 6.529608e+05 1607.250000 46355.750000 4759.017857 9.207640e+05 31191.250000 54588.250000 28779.650000 5.089532e+05
50% 98656.000000 98427.50000 4.148980e+05 1.039686e+07 237099.500000 6.060540e+05 5.299100e+05 8.078685e+05 6237.750000 82644.583333 8837.333333 1.211934e+06 37845.750000 77491.500000 44118.875000 7.065070e+05
75% 161694.000000 158673.75000 5.623658e+05 1.316721e+07 308119.750000 9.648268e+05 7.029695e+05 9.859902e+05 14842.000000 118693.250000 12869.584821 1.416010e+06 62140.375000 119915.500000 62176.000000 9.285735e+05
max 317661.000000 453985.00000 1.890312e+06 1.905088e+07 535157.000000 2.021852e+06 2.103130e+06 1.367882e+06 163701.000000 366064.500000 96564.222222 3.607517e+06 151128.000000 272948.000000 179114.750000 1.755449e+06

In [9]:
French_Wine_Export_in_Euros_DF.plot('Month' , 
                                    CN_columns,
                                   figsize=(32 , 12)).legend(fontsize=18)


Out[9]:
<matplotlib.legend.Legend at 0x7feb33b75a00>

In [10]:
Wines = "ALSACE BEAUJOLAIS BORDEAUX BOURGOGNE CHAMPAGNE EUROPE FRANCE LANGUEDOC LOIRE OTHER RHÔNE".split();
Variants = ['BLANC' , 'MOUSSEUX' , 'ROUGE'];
Countries = ['GB', 'US', 'DE', 'BE', 'CN', 'JP', 'CH', 'HK', 'NL', 'CA' , 'OTHER']

In [11]:
# A lot of possibilities , but only 176 are available ;)
len(Wines) * len(Variants) * len(Countries)


Out[11]:
363

In [12]:
from IPython.display import display

In [13]:
rows = [];
cols = []
for cntry in Countries:
    cntry_columns = [col for col in French_Wine_Export_in_Euros_DF.columns if col.endswith('_' + cntry) ]
    cols = []
    row = [cntry];
    for col in cntry_columns:
        col1 = col.replace('_' + cntry , "")
        sum1 = French_Wine_Export_in_Euros_DF[col].sum()
        row.append(sum1);
        cols.append(col1);
    rows.append(row);

plot_df = pd.DataFrame(rows , columns=['Country'] + cols);

    
plot_df.set_index('Country').plot.barh(stacked=True, figsize=(20,10), fontsize = 16, colormap='Paired').legend(loc='best', fontsize=12)


Out[13]:
<matplotlib.legend.Legend at 0x7feb33b316d0>

In [ ]:

Hierarchy Definition

Here, we start by defining as hierarchical to forecast wolrdwide wine export by forecasting country and continent exports.

A country export is computed by afgregating all wine types and variants exported to that country.

In this section, we describe the definition of the hierarchy. Again, for clarity, we restrict our work to some countries and some wine types and variants.


In [14]:
Regions = ['EUROPE', 'AMERICA', 'EUROPE' , 'EUROPE' , 'ASIA' , 'ASIA' , 'EUROPE',  'ASIA', 'EUROPE' , 'AMERICA' , 'OTHER_REGION']
lDict = dict(zip(Countries , Regions));

# simplify !!!!
Variants = ['BLANC' , 'ROUGE'];
Wines = Wines[0:3];
Countries = Countries[0:5]



In [15]:
# Hierarchy defintion
rows_list = [];
for v in Variants:
    for w in Wines:
        for c in Countries:
            col = w + "_" + v + "_" + c;
            region = lDict[c]
            if(col in French_Wine_Export_in_Euros_DF.columns):
                rows_list.append([col , c , region , 'WORLD']);
            
lLevels = ['Wine' , 'Country' , 'Region' , 'WORLD'];
lHierarchy = {};
lHierarchy['Levels'] = lLevels;
lHierarchy['Data'] = pd.DataFrame(rows_list, columns =  lLevels);
lHierarchy['Type'] = "Hierarchical";

The hierarchy has been specified this way :


In [16]:
lHierarchy


Out[16]:
{'Levels': ['Wine', 'Country', 'Region', 'WORLD'],
 'Data':                    Wine Country   Region  WORLD
 0       ALSACE_BLANC_GB      GB   EUROPE  WORLD
 1       ALSACE_BLANC_US      US  AMERICA  WORLD
 2       ALSACE_BLANC_DE      DE   EUROPE  WORLD
 3       ALSACE_BLANC_BE      BE   EUROPE  WORLD
 4       ALSACE_BLANC_CN      CN     ASIA  WORLD
 5     BORDEAUX_BLANC_GB      GB   EUROPE  WORLD
 6     BORDEAUX_BLANC_US      US  AMERICA  WORLD
 7     BORDEAUX_BLANC_DE      DE   EUROPE  WORLD
 8     BORDEAUX_BLANC_BE      BE   EUROPE  WORLD
 9     BORDEAUX_BLANC_CN      CN     ASIA  WORLD
 10  BEAUJOLAIS_ROUGE_GB      GB   EUROPE  WORLD
 11  BEAUJOLAIS_ROUGE_US      US  AMERICA  WORLD
 12  BEAUJOLAIS_ROUGE_DE      DE   EUROPE  WORLD
 13  BEAUJOLAIS_ROUGE_BE      BE   EUROPE  WORLD
 14  BEAUJOLAIS_ROUGE_CN      CN     ASIA  WORLD
 15    BORDEAUX_ROUGE_GB      GB   EUROPE  WORLD
 16    BORDEAUX_ROUGE_US      US  AMERICA  WORLD
 17    BORDEAUX_ROUGE_DE      DE   EUROPE  WORLD
 18    BORDEAUX_ROUGE_BE      BE   EUROPE  WORLD
 19    BORDEAUX_ROUGE_CN      CN     ASIA  WORLD,
 'Type': 'Hierarchical'}

We plot the hierarchy ...


In [ ]:


In [17]:
# create a model to plot the hierarchy.
import pyaf.HierarchicalForecastEngine as hautof
lEngine = hautof.cHierarchicalForecastEngine()


lSignalHierarchy = lEngine.plot_Hierarchy(French_Wine_Export_in_Euros_DF , "Month", "Signal", 1, 
                                          lHierarchy, None);


INFO:pyaf.std:START_HIERARCHICAL_PLOTTING
INFO:pyaf.std:END_HIERARCHICAL_PLOTTING_TIME_IN_SECONDS 0.18779993057250977

The strcuture levels have been built :


In [18]:
lSignalHierarchy.mStructure


Out[18]:
{0: {'ALSACE_BLANC_GB': set(),
  'ALSACE_BLANC_US': set(),
  'ALSACE_BLANC_DE': set(),
  'ALSACE_BLANC_BE': set(),
  'ALSACE_BLANC_CN': set(),
  'BORDEAUX_BLANC_GB': set(),
  'BORDEAUX_BLANC_US': set(),
  'BORDEAUX_BLANC_DE': set(),
  'BORDEAUX_BLANC_BE': set(),
  'BORDEAUX_BLANC_CN': set(),
  'BEAUJOLAIS_ROUGE_GB': set(),
  'BEAUJOLAIS_ROUGE_US': set(),
  'BEAUJOLAIS_ROUGE_DE': set(),
  'BEAUJOLAIS_ROUGE_BE': set(),
  'BEAUJOLAIS_ROUGE_CN': set(),
  'BORDEAUX_ROUGE_GB': set(),
  'BORDEAUX_ROUGE_US': set(),
  'BORDEAUX_ROUGE_DE': set(),
  'BORDEAUX_ROUGE_BE': set(),
  'BORDEAUX_ROUGE_CN': set()},
 1: {'GB': {'ALSACE_BLANC_GB',
   'BEAUJOLAIS_ROUGE_GB',
   'BORDEAUX_BLANC_GB',
   'BORDEAUX_ROUGE_GB'},
  'US': {'ALSACE_BLANC_US',
   'BEAUJOLAIS_ROUGE_US',
   'BORDEAUX_BLANC_US',
   'BORDEAUX_ROUGE_US'},
  'DE': {'ALSACE_BLANC_DE',
   'BEAUJOLAIS_ROUGE_DE',
   'BORDEAUX_BLANC_DE',
   'BORDEAUX_ROUGE_DE'},
  'BE': {'ALSACE_BLANC_BE',
   'BEAUJOLAIS_ROUGE_BE',
   'BORDEAUX_BLANC_BE',
   'BORDEAUX_ROUGE_BE'},
  'CN': {'ALSACE_BLANC_CN',
   'BEAUJOLAIS_ROUGE_CN',
   'BORDEAUX_BLANC_CN',
   'BORDEAUX_ROUGE_CN'}},
 2: {'EUROPE': {'BE', 'DE', 'GB'}, 'AMERICA': {'US'}, 'ASIA': {'CN'}},
 3: {'WORLD': {'AMERICA', 'ASIA', 'EUROPE'}}}

In [ ]:


In [ ]:


In [ ]:

Hierarchical Modelling

Here, we build a first model on the previous hierarchy. Thsi will build an internal model for each node of the previous graph.

Note that the lower (most detailed) level data are coming from the datset and higher levels are obtained by aggregating previous levels.

We discard the last 4 months of the dataset and try to forecast their values.


In [19]:
# create a hierarchical model and train it
import pyaf.HierarchicalForecastEngine as hautof

lEngine = hautof.cHierarchicalForecastEngine()

lSignalVar = "Sales";

#
N = French_Wine_Export_in_Euros_DF.shape[0];
H = 4;
train_df = French_Wine_Export_in_Euros_DF.head(N-H);


lSignalHierarchy = lEngine.train(train_df , lDateColumn, lSignalVar, 1, lHierarchy, None);


INFO:pyaf.std:START_HIERARCHICAL_TRAINING
INFO:pyaf.hierarchical:TRAINING_HIERARCHICAL_MODELS_LEVEL_SIGNAL [(0, 'ALSACE_BLANC_BE'), (0, 'ALSACE_BLANC_CN'), (0, 'ALSACE_BLANC_DE'), (0, 'ALSACE_BLANC_GB'), (0, 'ALSACE_BLANC_US'), (0, 'BEAUJOLAIS_ROUGE_BE'), (0, 'BEAUJOLAIS_ROUGE_CN'), (0, 'BEAUJOLAIS_ROUGE_DE'), (0, 'BEAUJOLAIS_ROUGE_GB'), (0, 'BEAUJOLAIS_ROUGE_US'), (0, 'BORDEAUX_BLANC_BE'), (0, 'BORDEAUX_BLANC_CN'), (0, 'BORDEAUX_BLANC_DE'), (0, 'BORDEAUX_BLANC_GB'), (0, 'BORDEAUX_BLANC_US'), (0, 'BORDEAUX_ROUGE_BE'), (0, 'BORDEAUX_ROUGE_CN'), (0, 'BORDEAUX_ROUGE_DE'), (0, 'BORDEAUX_ROUGE_GB'), (0, 'BORDEAUX_ROUGE_US'), (1, 'BE'), (1, 'CN'), (1, 'DE'), (1, 'GB'), (1, 'US'), (2, 'AMERICA'), (2, 'ASIA'), (2, 'EUROPE'), (3, 'WORLD')]
INFO:pyaf.std:START_TRAINING 'ALSACE_BLANC_CN'
INFO:pyaf.std:START_TRAINING 'ALSACE_BLANC_BE'
INFO:pyaf.std:START_TRAINING 'ALSACE_BLANC_DE'
INFO:pyaf.std:START_TRAINING 'ALSACE_BLANC_GB'
INFO:pyaf.std:START_TRAINING 'ALSACE_BLANC_US'
INFO:pyaf.std:START_TRAINING 'BEAUJOLAIS_ROUGE_CN'
INFO:pyaf.std:START_TRAINING 'BEAUJOLAIS_ROUGE_BE'
INFO:pyaf.std:START_TRAINING 'BEAUJOLAIS_ROUGE_DE'
INFO:pyaf.std:END_TRAINING_TIME_IN_SECONDS 'BEAUJOLAIS_ROUGE_DE' 3.116830348968506
INFO:pyaf.std:START_TRAINING 'BEAUJOLAIS_ROUGE_GB'
INFO:pyaf.std:END_TRAINING_TIME_IN_SECONDS 'BEAUJOLAIS_ROUGE_CN' 3.2174572944641113
INFO:pyaf.std:END_TRAINING_TIME_IN_SECONDS 'BEAUJOLAIS_ROUGE_BE' 3.218780755996704
INFO:pyaf.std:START_TRAINING 'BEAUJOLAIS_ROUGE_US'
INFO:pyaf.std:START_TRAINING 'BORDEAUX_BLANC_BE'
INFO:pyaf.std:END_TRAINING_TIME_IN_SECONDS 'ALSACE_BLANC_CN' 3.2586417198181152
INFO:pyaf.std:START_TRAINING 'BORDEAUX_BLANC_CN'
INFO:pyaf.std:END_TRAINING_TIME_IN_SECONDS 'ALSACE_BLANC_DE' 3.2711479663848877
INFO:pyaf.std:END_TRAINING_TIME_IN_SECONDS 'ALSACE_BLANC_GB' 3.280301809310913
INFO:pyaf.std:START_TRAINING 'BORDEAUX_BLANC_DE'
INFO:pyaf.std:END_TRAINING_TIME_IN_SECONDS 'ALSACE_BLANC_BE' 3.299868106842041
INFO:pyaf.std:START_TRAINING 'BORDEAUX_BLANC_GB'
INFO:pyaf.std:END_TRAINING_TIME_IN_SECONDS 'ALSACE_BLANC_US' 3.316903591156006
INFO:pyaf.std:START_TRAINING 'BORDEAUX_BLANC_US'
INFO:pyaf.std:START_TRAINING 'BORDEAUX_ROUGE_BE'
INFO:pyaf.std:END_TRAINING_TIME_IN_SECONDS 'BEAUJOLAIS_ROUGE_GB' 2.790262460708618
INFO:pyaf.std:START_TRAINING 'BORDEAUX_ROUGE_CN'
INFO:pyaf.std:END_TRAINING_TIME_IN_SECONDS 'BORDEAUX_BLANC_DE' 2.77897310256958
INFO:pyaf.std:START_TRAINING 'BORDEAUX_ROUGE_DE'
INFO:pyaf.std:END_TRAINING_TIME_IN_SECONDS 'BEAUJOLAIS_ROUGE_US' 2.8733577728271484
INFO:pyaf.std:END_TRAINING_TIME_IN_SECONDS 'BORDEAUX_BLANC_CN' 2.856806993484497
INFO:pyaf.std:START_TRAINING 'BORDEAUX_ROUGE_GB'
INFO:pyaf.std:START_TRAINING 'BORDEAUX_ROUGE_US'
INFO:pyaf.std:END_TRAINING_TIME_IN_SECONDS 'BORDEAUX_BLANC_GB' 2.8904035091400146
INFO:pyaf.std:START_TRAINING 'BE'
INFO:pyaf.std:START_TRAINING 'GB'
INFO:pyaf.std:END_TRAINING_TIME_IN_SECONDS 'BORDEAUX_BLANC_BE' 2.9640254974365234
INFO:pyaf.std:END_TRAINING_TIME_IN_SECONDS 'BORDEAUX_BLANC_US' 2.930906295776367
INFO:pyaf.std:END_TRAINING_TIME_IN_SECONDS 'BORDEAUX_ROUGE_BE' 2.941695213317871
INFO:pyaf.std:START_TRAINING 'CN'
INFO:pyaf.std:START_TRAINING 'DE'
INFO:pyaf.std:END_TRAINING_TIME_IN_SECONDS 'BORDEAUX_ROUGE_CN' 2.878282308578491
INFO:pyaf.std:START_TRAINING 'US'
INFO:pyaf.std:END_TRAINING_TIME_IN_SECONDS 'BORDEAUX_ROUGE_DE' 2.7534682750701904
INFO:pyaf.std:START_TRAINING 'AMERICA'
INFO:pyaf.std:END_TRAINING_TIME_IN_SECONDS 'BORDEAUX_ROUGE_GB' 2.8161003589630127
INFO:pyaf.std:START_TRAINING 'ASIA'
INFO:pyaf.std:END_TRAINING_TIME_IN_SECONDS 'BORDEAUX_ROUGE_US' 2.8470776081085205
INFO:pyaf.std:END_TRAINING_TIME_IN_SECONDS 'BE' 2.799729108810425
INFO:pyaf.std:START_TRAINING 'EUROPE'
INFO:pyaf.std:START_TRAINING 'WORLD'
INFO:pyaf.std:END_TRAINING_TIME_IN_SECONDS 'DE' 2.83880877494812
INFO:pyaf.std:END_TRAINING_TIME_IN_SECONDS 'CN' 2.852757692337036
INFO:pyaf.std:END_TRAINING_TIME_IN_SECONDS 'GB' 2.96859073638916
INFO:pyaf.std:END_TRAINING_TIME_IN_SECONDS 'US' 2.7348833084106445
INFO:pyaf.std:END_TRAINING_TIME_IN_SECONDS 'ASIA' 2.6849465370178223
INFO:pyaf.std:END_TRAINING_TIME_IN_SECONDS 'EUROPE' 2.679492712020874
INFO:pyaf.std:END_TRAINING_TIME_IN_SECONDS 'AMERICA' 2.8715567588806152
INFO:pyaf.std:END_TRAINING_TIME_IN_SECONDS 'WORLD' 2.790771961212158
INFO:pyaf.hierarchical:TRAINING_HIERARCHICAL_MODEL_COMPUTE_TOP_DOWN_HISTORICAL_PROPORTIONS
INFO:pyaf.hierarchical:FORECASTING_HIERARCHICAL_MODELS_LEVEL_SIGNAL [(0, 'ALSACE_BLANC_BE'), (0, 'ALSACE_BLANC_CN'), (0, 'ALSACE_BLANC_DE'), (0, 'ALSACE_BLANC_GB'), (0, 'ALSACE_BLANC_US'), (0, 'BEAUJOLAIS_ROUGE_BE'), (0, 'BEAUJOLAIS_ROUGE_CN'), (0, 'BEAUJOLAIS_ROUGE_DE'), (0, 'BEAUJOLAIS_ROUGE_GB'), (0, 'BEAUJOLAIS_ROUGE_US'), (0, 'BORDEAUX_BLANC_BE'), (0, 'BORDEAUX_BLANC_CN'), (0, 'BORDEAUX_BLANC_DE'), (0, 'BORDEAUX_BLANC_GB'), (0, 'BORDEAUX_BLANC_US'), (0, 'BORDEAUX_ROUGE_BE'), (0, 'BORDEAUX_ROUGE_CN'), (0, 'BORDEAUX_ROUGE_DE'), (0, 'BORDEAUX_ROUGE_GB'), (0, 'BORDEAUX_ROUGE_US'), (1, 'BE'), (1, 'CN'), (1, 'DE'), (1, 'GB'), (1, 'US'), (2, 'AMERICA'), (2, 'ASIA'), (2, 'EUROPE'), (3, 'WORLD')]
INFO:pyaf.std:START_FORECASTING 'ALSACE_BLANC_BE'
INFO:pyaf.std:END_FORECAST_TIME_IN_SECONDS  'ALSACE_BLANC_BE' 0.03546404838562012
INFO:pyaf.std:START_FORECASTING 'ALSACE_BLANC_CN'
INFO:pyaf.std:END_FORECAST_TIME_IN_SECONDS  'ALSACE_BLANC_CN' 0.046620845794677734
INFO:pyaf.std:START_FORECASTING 'ALSACE_BLANC_DE'
INFO:pyaf.std:END_FORECAST_TIME_IN_SECONDS  'ALSACE_BLANC_DE' 0.03574967384338379
INFO:pyaf.std:START_FORECASTING 'ALSACE_BLANC_GB'
INFO:pyaf.std:END_FORECAST_TIME_IN_SECONDS  'ALSACE_BLANC_GB' 0.03654885292053223
INFO:pyaf.std:START_FORECASTING 'ALSACE_BLANC_US'
INFO:pyaf.std:END_FORECAST_TIME_IN_SECONDS  'ALSACE_BLANC_US' 0.042937517166137695
INFO:pyaf.std:START_FORECASTING 'BEAUJOLAIS_ROUGE_BE'
INFO:pyaf.std:END_FORECAST_TIME_IN_SECONDS  'BEAUJOLAIS_ROUGE_BE' 0.04005265235900879
INFO:pyaf.std:START_FORECASTING 'BEAUJOLAIS_ROUGE_CN'
INFO:pyaf.std:END_FORECAST_TIME_IN_SECONDS  'BEAUJOLAIS_ROUGE_CN' 0.03484606742858887
INFO:pyaf.std:START_FORECASTING 'BEAUJOLAIS_ROUGE_DE'
INFO:pyaf.std:END_FORECAST_TIME_IN_SECONDS  'BEAUJOLAIS_ROUGE_DE' 0.04229998588562012
INFO:pyaf.std:START_FORECASTING 'BEAUJOLAIS_ROUGE_GB'
INFO:pyaf.std:END_FORECAST_TIME_IN_SECONDS  'BEAUJOLAIS_ROUGE_GB' 0.031418800354003906
INFO:pyaf.std:START_FORECASTING 'BEAUJOLAIS_ROUGE_US'
INFO:pyaf.std:END_FORECAST_TIME_IN_SECONDS  'BEAUJOLAIS_ROUGE_US' 0.033751487731933594
INFO:pyaf.std:START_FORECASTING 'BORDEAUX_BLANC_BE'
INFO:pyaf.std:END_FORECAST_TIME_IN_SECONDS  'BORDEAUX_BLANC_BE' 0.04135394096374512
INFO:pyaf.std:START_FORECASTING 'BORDEAUX_BLANC_CN'
INFO:pyaf.std:END_FORECAST_TIME_IN_SECONDS  'BORDEAUX_BLANC_CN' 0.02912306785583496
INFO:pyaf.std:START_FORECASTING 'BORDEAUX_BLANC_DE'
INFO:pyaf.std:END_FORECAST_TIME_IN_SECONDS  'BORDEAUX_BLANC_DE' 0.03085160255432129
INFO:pyaf.std:START_FORECASTING 'BORDEAUX_BLANC_GB'
INFO:pyaf.std:END_FORECAST_TIME_IN_SECONDS  'BORDEAUX_BLANC_GB' 0.03562617301940918
INFO:pyaf.std:START_FORECASTING 'BORDEAUX_BLANC_US'
INFO:pyaf.std:END_FORECAST_TIME_IN_SECONDS  'BORDEAUX_BLANC_US' 0.029346466064453125
INFO:pyaf.std:START_FORECASTING 'BORDEAUX_ROUGE_BE'
INFO:pyaf.std:END_FORECAST_TIME_IN_SECONDS  'BORDEAUX_ROUGE_BE' 0.03003406524658203
INFO:pyaf.std:START_FORECASTING 'BORDEAUX_ROUGE_CN'
INFO:pyaf.std:END_FORECAST_TIME_IN_SECONDS  'BORDEAUX_ROUGE_CN' 0.032271623611450195
INFO:pyaf.std:START_FORECASTING 'BORDEAUX_ROUGE_DE'
INFO:pyaf.std:END_FORECAST_TIME_IN_SECONDS  'BORDEAUX_ROUGE_DE' 0.029767751693725586
INFO:pyaf.std:START_FORECASTING 'BORDEAUX_ROUGE_GB'
INFO:pyaf.std:END_FORECAST_TIME_IN_SECONDS  'BORDEAUX_ROUGE_GB' 0.02918076515197754
INFO:pyaf.std:START_FORECASTING 'BORDEAUX_ROUGE_US'
INFO:pyaf.std:END_FORECAST_TIME_IN_SECONDS  'BORDEAUX_ROUGE_US' 0.0391845703125
INFO:pyaf.std:START_FORECASTING 'BE'
INFO:pyaf.std:END_FORECAST_TIME_IN_SECONDS  'BE' 0.03859758377075195
INFO:pyaf.std:START_FORECASTING 'CN'
INFO:pyaf.std:END_FORECAST_TIME_IN_SECONDS  'CN' 0.03562211990356445
INFO:pyaf.std:START_FORECASTING 'DE'
INFO:pyaf.std:END_FORECAST_TIME_IN_SECONDS  'DE' 0.028944969177246094
INFO:pyaf.std:START_FORECASTING 'GB'
INFO:pyaf.std:END_FORECAST_TIME_IN_SECONDS  'GB' 0.029288053512573242
INFO:pyaf.std:START_FORECASTING 'US'
INFO:pyaf.std:END_FORECAST_TIME_IN_SECONDS  'US' 0.030891895294189453
INFO:pyaf.std:START_FORECASTING 'AMERICA'
INFO:pyaf.std:END_FORECAST_TIME_IN_SECONDS  'AMERICA' 0.030309677124023438
INFO:pyaf.std:START_FORECASTING 'ASIA'
INFO:pyaf.std:END_FORECAST_TIME_IN_SECONDS  'ASIA' 0.03577613830566406
INFO:pyaf.std:START_FORECASTING 'EUROPE'
INFO:pyaf.std:END_FORECAST_TIME_IN_SECONDS  'EUROPE' 0.027979612350463867
INFO:pyaf.std:START_FORECASTING 'WORLD'
INFO:pyaf.std:END_FORECAST_TIME_IN_SECONDS  'WORLD' 0.03704357147216797
INFO:pyaf.hierarchical:FORECASTING_HIERARCHICAL_MODEL_COMBINATION_METHODS ['BU']
INFO:pyaf.hierarchical:FORECASTING_HIERARCHICAL_MODEL_BOTTOM_UP_METHOD BU
INFO:pyaf.hierarchical:FORECASTING_HIERARCHICAL_MODEL_OPTIMAL_COMBINATION_METHOD
INFO:pyaf.hierarchical:STRUCTURE [0, 1, 2, 3]
INFO:pyaf.hierarchical:DATASET_COLUMNS Index(['Month', 'ALSACE_BLANC_BE', 'ALSACE_BLANC_BE_Forecast',
       'ALSACE_BLANC_BE_Forecast_Lower_Bound',
       'ALSACE_BLANC_BE_Forecast_Upper_Bound', 'ALSACE_BLANC_CN',
       'ALSACE_BLANC_CN_Forecast', 'ALSACE_BLANC_CN_Forecast_Lower_Bound',
       'ALSACE_BLANC_CN_Forecast_Upper_Bound', 'ALSACE_BLANC_DE',
       ...
       'BORDEAUX_ROUGE_US_BU_Forecast', 'BE_BU_Forecast', 'CN_BU_Forecast',
       'DE_BU_Forecast', 'GB_BU_Forecast', 'US_BU_Forecast',
       'AMERICA_BU_Forecast', 'ASIA_BU_Forecast', 'EUROPE_BU_Forecast',
       'WORLD_BU_Forecast'],
      dtype='object', length=146)
INFO:pyaf.hierarchical:STRUCTURE_LEVEL (0, ['ALSACE_BLANC_BE', 'ALSACE_BLANC_CN', 'ALSACE_BLANC_DE', 'ALSACE_BLANC_GB', 'ALSACE_BLANC_US', 'BEAUJOLAIS_ROUGE_BE', 'BEAUJOLAIS_ROUGE_CN', 'BEAUJOLAIS_ROUGE_DE', 'BEAUJOLAIS_ROUGE_GB', 'BEAUJOLAIS_ROUGE_US', 'BORDEAUX_BLANC_BE', 'BORDEAUX_BLANC_CN', 'BORDEAUX_BLANC_DE', 'BORDEAUX_BLANC_GB', 'BORDEAUX_BLANC_US', 'BORDEAUX_ROUGE_BE', 'BORDEAUX_ROUGE_CN', 'BORDEAUX_ROUGE_DE', 'BORDEAUX_ROUGE_GB', 'BORDEAUX_ROUGE_US'])
INFO:pyaf.hierarchical:MODEL_LEVEL (0, ['ALSACE_BLANC_BE', 'ALSACE_BLANC_CN', 'ALSACE_BLANC_DE', 'ALSACE_BLANC_GB', 'ALSACE_BLANC_US', 'BEAUJOLAIS_ROUGE_BE', 'BEAUJOLAIS_ROUGE_CN', 'BEAUJOLAIS_ROUGE_DE', 'BEAUJOLAIS_ROUGE_GB', 'BEAUJOLAIS_ROUGE_US', 'BORDEAUX_BLANC_BE', 'BORDEAUX_BLANC_CN', 'BORDEAUX_BLANC_DE', 'BORDEAUX_BLANC_GB', 'BORDEAUX_BLANC_US', 'BORDEAUX_ROUGE_BE', 'BORDEAUX_ROUGE_CN', 'BORDEAUX_ROUGE_DE', 'BORDEAUX_ROUGE_GB', 'BORDEAUX_ROUGE_US'])
INFO:pyaf.hierarchical:STRUCTURE_LEVEL (1, ['BE', 'CN', 'DE', 'GB', 'US'])
INFO:pyaf.hierarchical:MODEL_LEVEL (1, ['BE', 'CN', 'DE', 'GB', 'US'])
INFO:pyaf.hierarchical:STRUCTURE_LEVEL (2, ['AMERICA', 'ASIA', 'EUROPE'])
INFO:pyaf.hierarchical:MODEL_LEVEL (2, ['AMERICA', 'ASIA', 'EUROPE'])
INFO:pyaf.hierarchical:STRUCTURE_LEVEL (3, ['WORLD'])
INFO:pyaf.hierarchical:MODEL_LEVEL (3, ['WORLD'])
INFO:pyaf.hierarchical:REPORT_COMBINED_FORECASTS_FIT_PERF {'Signal': 'ALSACE_BLANC_BE_BU_Forecast', 'Length': 36, 'MAPE': 0.1418, 'RMSE': 199577.56080021942, 'MAE': 165591.68055555556, 'SMAPE': 0.1379, 'ErrorMean': 0.0, 'ErrorStdDev': 199577.56080021942, 'R2': 0.0, 'Pearson': 0.0}
INFO:pyaf.hierarchical:REPORT_COMBINED_FORECASTS_VALID_PERF {'Signal': 'ALSACE_BLANC_BE_BU_Forecast', 'Length': 9, 'MAPE': 0.2979, 'RMSE': 444837.29072987556, 'MAE': 326942.97222222225, 'SMAPE': 0.2631, 'ErrorMean': -79348.75, 'ErrorStdDev': 437703.08554696455, 'R2': -0.032864040938387795, 'Pearson': 0.0}
INFO:pyaf.hierarchical:REPORT_COMBINED_FORECASTS_FIT_PERF {'Signal': 'ALSACE_BLANC_CN_BU_Forecast', 'Length': 36, 'MAPE': 0.4769, 'RMSE': 54489.48176893604, 'MAE': 43502.069322031304, 'SMAPE': 0.3645, 'ErrorMean': -6.063298011819521e-13, 'ErrorStdDev': 54489.48176893604, 'R2': 0.20977709881983608, 'Pearson': 0.4592342911941588}
INFO:pyaf.hierarchical:REPORT_COMBINED_FORECASTS_VALID_PERF {'Signal': 'ALSACE_BLANC_CN_BU_Forecast', 'Length': 9, 'MAPE': 0.3401, 'RMSE': 86153.69023954055, 'MAE': 54624.102041553844, 'SMAPE': 0.4141, 'ErrorMean': -40494.168775788356, 'ErrorStdDev': 76043.938858062, 'R2': -0.08384682031687452, 'Pearson': 0.0}
INFO:pyaf.hierarchical:REPORT_COMBINED_FORECASTS_FIT_PERF {'Signal': 'ALSACE_BLANC_DE_BU_Forecast', 'Length': 36, 'MAPE': 0.3037, 'RMSE': 381643.9708516124, 'MAE': 239057.80555555556, 'SMAPE': 0.3884, 'ErrorMean': -235745.16666666666, 'ErrorStdDev': 300127.2011675914, 'R2': -0.5439845652964985, 'Pearson': 0.4222538037199401}
INFO:pyaf.hierarchical:REPORT_COMBINED_FORECASTS_VALID_PERF {'Signal': 'ALSACE_BLANC_DE_BU_Forecast', 'Length': 9, 'MAPE': 0.1906, 'RMSE': 144769.4922736975, 'MAE': 112843.61111111117, 'SMAPE': 0.2201, 'ErrorMean': -112843.61111111117, 'ErrorStdDev': 90689.16872807068, 'R2': -1.6785920899742903, 'Pearson': 0.0}
INFO:pyaf.hierarchical:REPORT_COMBINED_FORECASTS_FIT_PERF {'Signal': 'ALSACE_BLANC_GB_BU_Forecast', 'Length': 36, 'MAPE': 0.2964, 'RMSE': 127746.35430699537, 'MAE': 106249.85185185184, 'SMAPE': 0.264, 'ErrorMean': -2.5870071517096624e-11, 'ErrorStdDev': 127746.35430699537, 'R2': 0.0, 'Pearson': 0.0}
INFO:pyaf.hierarchical:REPORT_COMBINED_FORECASTS_VALID_PERF {'Signal': 'ALSACE_BLANC_GB_BU_Forecast', 'Length': 9, 'MAPE': 0.1402, 'RMSE': 66480.16663925201, 'MAE': 55017.46913580247, 'SMAPE': 0.1358, 'ErrorMean': -731.2222222222481, 'ErrorStdDev': 66476.1451232278, 'R2': -0.00012099491204886625, 'Pearson': 0.0}
INFO:pyaf.hierarchical:REPORT_COMBINED_FORECASTS_FIT_PERF {'Signal': 'ALSACE_BLANC_US_BU_Forecast', 'Length': 36, 'MAPE': 0.2222, 'RMSE': 165735.85694123103, 'MAE': 131398.81721645, 'SMAPE': 0.1986, 'ErrorMean': -6.467517879274156e-12, 'ErrorStdDev': 165735.85694123103, 'R2': 0.25091278856867993, 'Pearson': 0.5009119569032863}
INFO:pyaf.hierarchical:REPORT_COMBINED_FORECASTS_VALID_PERF {'Signal': 'ALSACE_BLANC_US_BU_Forecast', 'Length': 9, 'MAPE': 0.238, 'RMSE': 178019.5721837483, 'MAE': 142116.45550728482, 'SMAPE': 0.21, 'ErrorMean': 27404.560804801127, 'ErrorStdDev': 175897.57851539835, 'R2': -0.10452085387212473, 'Pearson': 0.0}
INFO:pyaf.hierarchical:REPORT_COMBINED_FORECASTS_FIT_PERF {'Signal': 'AMERICA_BU_Forecast', 'Length': 36, 'MAPE': 0.1917, 'RMSE': 2510501.287288395, 'MAE': 1922713.7690322092, 'SMAPE': 0.1847, 'ErrorMean': -8.27842288547092e-10, 'ErrorStdDev': 2510501.287288395, 'R2': 0.037907811620797593, 'Pearson': 0.20054881525310836}
INFO:pyaf.hierarchical:REPORT_COMBINED_FORECASTS_VALID_PERF {'Signal': 'AMERICA_BU_Forecast', 'Length': 9, 'MAPE': 0.2209, 'RMSE': 2096609.4319779796, 'MAE': 1789928.428711845, 'SMAPE': 0.2023, 'ErrorMean': 47699.14401481321, 'ErrorStdDev': 2096066.7694325198, 'R2': -0.04914130046529963, 'Pearson': 0.0}
INFO:pyaf.hierarchical:REPORT_COMBINED_FORECASTS_FIT_PERF {'Signal': 'ASIA_BU_Forecast', 'Length': 36, 'MAPE': 0.3787, 'RMSE': 5843680.673765567, 'MAE': 4760283.971866047, 'SMAPE': 0.4745, 'ErrorMean': -3220956.760186489, 'ErrorStdDev': 4875863.140609071, 'R2': -2.1808950571472274, 'Pearson': -0.18079022667756428}
INFO:pyaf.hierarchical:REPORT_COMBINED_FORECASTS_VALID_PERF {'Signal': 'ASIA_BU_Forecast', 'Length': 9, 'MAPE': 0.2353, 'RMSE': 2852608.7810445037, 'MAE': 2276336.9642346404, 'SMAPE': 0.1973, 'ErrorMean': -122512.68660265993, 'ErrorStdDev': 2849976.7541707437, 'R2': 0.19246072545988602, 'Pearson': 0.0}
INFO:pyaf.hierarchical:REPORT_COMBINED_FORECASTS_FIT_PERF {'Signal': 'BEAUJOLAIS_ROUGE_BE_BU_Forecast', 'Length': 36, 'MAPE': 0.5435, 'RMSE': 106802.3837449867, 'MAE': 80457.65319272065, 'SMAPE': 0.4144, 'ErrorMean': 15233.682772240725, 'ErrorStdDev': 105710.37831171608, 'R2': -0.024414222050409773, 'Pearson': -0.004087940353046451}
INFO:pyaf.hierarchical:REPORT_COMBINED_FORECASTS_VALID_PERF {'Signal': 'BEAUJOLAIS_ROUGE_BE_BU_Forecast', 'Length': 9, 'MAPE': 0.4458, 'RMSE': 126806.9861784883, 'MAE': 82815.0405050574, 'SMAPE': 0.6497, 'ErrorMean': -67684.41089172459, 'ErrorStdDev': 107232.60822115405, 'R2': -0.3166836761041538, 'Pearson': 0.0}
INFO:pyaf.hierarchical:REPORT_COMBINED_FORECASTS_FIT_PERF {'Signal': 'BEAUJOLAIS_ROUGE_CN_BU_Forecast', 'Length': 36, 'MAPE': 1.5835, 'RMSE': 386578.75642473, 'MAE': 186893.800154321, 'SMAPE': 1.9954, 'ErrorMean': -70248.17206790124, 'ErrorStdDev': 380142.51175053976, 'R2': -13.912792387418225, 'Pearson': -0.060453437527646335}
INFO:pyaf.hierarchical:REPORT_COMBINED_FORECASTS_VALID_PERF {'Signal': 'BEAUJOLAIS_ROUGE_CN_BU_Forecast', 'Length': 9, 'MAPE': 1.0, 'RMSE': 190554.48176906724, 'MAE': 147575.0, 'SMAPE': 2.0, 'ErrorMean': -147575.0, 'ErrorStdDev': 120551.3579238234, 'R2': -1.498584962180829, 'Pearson': 0.0}
INFO:pyaf.hierarchical:REPORT_COMBINED_FORECASTS_FIT_PERF {'Signal': 'BEAUJOLAIS_ROUGE_DE_BU_Forecast', 'Length': 36, 'MAPE': 0.6182, 'RMSE': 268908.8411572105, 'MAE': 121252.86111111111, 'SMAPE': 0.5239, 'ErrorMean': -90871.33333333333, 'ErrorStdDev': 253089.63951678487, 'R2': -0.1235609513710596, 'Pearson': 0.17563597266024822}
INFO:pyaf.hierarchical:REPORT_COMBINED_FORECASTS_VALID_PERF {'Signal': 'BEAUJOLAIS_ROUGE_DE_BU_Forecast', 'Length': 9, 'MAPE': 0.6144, 'RMSE': 155871.73582628762, 'MAE': 101230.22222222222, 'SMAPE': 0.6012, 'ErrorMean': -55130.88888888889, 'ErrorStdDev': 145796.375537326, 'R2': -0.1492885450742618, 'Pearson': 0.0}
INFO:pyaf.hierarchical:REPORT_COMBINED_FORECASTS_FIT_PERF {'Signal': 'BEAUJOLAIS_ROUGE_GB_BU_Forecast', 'Length': 36, 'MAPE': 0.7216, 'RMSE': 574972.8645601943, 'MAE': 422320.22222222225, 'SMAPE': 0.5076, 'ErrorMean': 1963.388888888889, 'ErrorStdDev': 574969.5123088063, 'R2': -0.6540904308136148, 'Pearson': 0.16869668407790478}
INFO:pyaf.hierarchical:REPORT_COMBINED_FORECASTS_VALID_PERF {'Signal': 'BEAUJOLAIS_ROUGE_GB_BU_Forecast', 'Length': 9, 'MAPE': 0.3584, 'RMSE': 485564.32192152576, 'MAE': 335481.1111111111, 'SMAPE': 0.3897, 'ErrorMean': -82966.66666666667, 'ErrorStdDev': 478423.7065043217, 'R2': -0.1714086691299752, 'Pearson': 0.0}
INFO:pyaf.hierarchical:REPORT_COMBINED_FORECASTS_FIT_PERF {'Signal': 'BEAUJOLAIS_ROUGE_US_BU_Forecast', 'Length': 36, 'MAPE': 0.5762, 'RMSE': 867034.3960889542, 'MAE': 582255.0717515774, 'SMAPE': 0.4781, 'ErrorMean': 1.8109050061967638e-10, 'ErrorStdDev': 867034.3960889542, 'R2': 0.0028471423817205688, 'Pearson': 0.05534550225360017}
INFO:pyaf.hierarchical:REPORT_COMBINED_FORECASTS_VALID_PERF {'Signal': 'BEAUJOLAIS_ROUGE_US_BU_Forecast', 'Length': 9, 'MAPE': 0.2867, 'RMSE': 774435.6013471647, 'MAE': 387408.1202543912, 'SMAPE': 0.2956, 'ErrorMean': -153564.98378074175, 'ErrorStdDev': 759057.5053251005, 'R2': -0.02749876936315787, 'Pearson': 0.0}
INFO:pyaf.hierarchical:REPORT_COMBINED_FORECASTS_FIT_PERF {'Signal': 'BE_BU_Forecast', 'Length': 36, 'MAPE': 0.1263, 'RMSE': 1158430.1818586537, 'MAE': 870585.8539859032, 'SMAPE': 0.1235, 'ErrorMean': 15233.682772240834, 'ErrorStdDev': 1158330.013921019, 'R2': 0.08023471545578531, 'Pearson': 0.2838047668764661}
INFO:pyaf.hierarchical:REPORT_COMBINED_FORECASTS_VALID_PERF {'Signal': 'BE_BU_Forecast', 'Length': 9, 'MAPE': 0.1993, 'RMSE': 1355866.3595957132, 'MAE': 1199399.0626261914, 'SMAPE': 0.2043, 'ErrorMean': -389555.3695622764, 'ErrorStdDev': 1298699.4260137833, 'R2': 0.10495568930123467, 'Pearson': 0.0}
INFO:pyaf.hierarchical:REPORT_COMBINED_FORECASTS_FIT_PERF {'Signal': 'BORDEAUX_BLANC_BE_BU_Forecast', 'Length': 36, 'MAPE': 0.1248, 'RMSE': 71511.23866079607, 'MAE': 57284.517524619594, 'SMAPE': 0.1211, 'ErrorMean': -1.616879469818539e-12, 'ErrorStdDev': 71511.23866079607, 'R2': 0.29465347365490646, 'Pearson': 0.5433689983428429}
INFO:pyaf.hierarchical:REPORT_COMBINED_FORECASTS_VALID_PERF {'Signal': 'BORDEAUX_BLANC_BE_BU_Forecast', 'Length': 9, 'MAPE': 0.3373, 'RMSE': 133791.73715896055, 'MAE': 125843.55513525108, 'SMAPE': 0.3039, 'ErrorMean': 28407.455518913033, 'ErrorStdDev': 130741.13890797098, 'R2': 0.24879767521606466, 'Pearson': 0.0}
INFO:pyaf.hierarchical:REPORT_COMBINED_FORECASTS_FIT_PERF {'Signal': 'BORDEAUX_BLANC_CN_BU_Forecast', 'Length': 36, 'MAPE': 0.4861, 'RMSE': 236751.57395505198, 'MAE': 196901.17592592593, 'SMAPE': 0.4008, 'ErrorMean': -2.5870071517096624e-11, 'ErrorStdDev': 236751.57395505198, 'R2': 0.0, 'Pearson': 0.0}
INFO:pyaf.hierarchical:REPORT_COMBINED_FORECASTS_VALID_PERF {'Signal': 'BORDEAUX_BLANC_CN_BU_Forecast', 'Length': 9, 'MAPE': 0.306, 'RMSE': 477151.95433478977, 'MAE': 234114.8703703704, 'SMAPE': 0.3129, 'ErrorMean': -116613.27777777782, 'ErrorStdDev': 462682.7541322803, 'R2': -0.06352276318980388, 'Pearson': 0.0}
INFO:pyaf.hierarchical:REPORT_COMBINED_FORECASTS_FIT_PERF {'Signal': 'BORDEAUX_BLANC_DE_BU_Forecast', 'Length': 36, 'MAPE': 0.3966, 'RMSE': 270676.3073877788, 'MAE': 178217.47222222222, 'SMAPE': 0.3632, 'ErrorMean': -18718.194444444445, 'ErrorStdDev': 270028.31810353394, 'R2': -0.18936319314386085, 'Pearson': 0.3559880158188731}
INFO:pyaf.hierarchical:REPORT_COMBINED_FORECASTS_VALID_PERF {'Signal': 'BORDEAUX_BLANC_DE_BU_Forecast', 'Length': 9, 'MAPE': 0.2533, 'RMSE': 201387.2590557804, 'MAE': 97102.88888888889, 'SMAPE': 0.1866, 'ErrorMean': 76439.11111111111, 'ErrorStdDev': 186316.64016545383, 'R2': -13.060718941617052, 'Pearson': 0.0}
INFO:pyaf.hierarchical:REPORT_COMBINED_FORECASTS_FIT_PERF {'Signal': 'BORDEAUX_BLANC_GB_BU_Forecast', 'Length': 36, 'MAPE': 0.259, 'RMSE': 282372.93395753554, 'MAE': 228564.85401399242, 'SMAPE': 0.2421, 'ErrorMean': 3.233758939637078e-12, 'ErrorStdDev': 282372.93395753554, 'R2': 0.14947145177295817, 'Pearson': 0.5128583610185686}
INFO:pyaf.hierarchical:REPORT_COMBINED_FORECASTS_VALID_PERF {'Signal': 'BORDEAUX_BLANC_GB_BU_Forecast', 'Length': 9, 'MAPE': 0.133, 'RMSE': 99936.68789248545, 'MAE': 84699.5553837494, 'SMAPE': 0.1238, 'ErrorMean': 44758.01780843718, 'ErrorStdDev': 89353.57535532457, 'R2': -0.19706891807788685, 'Pearson': 0.0}
INFO:pyaf.hierarchical:REPORT_COMBINED_FORECASTS_FIT_PERF {'Signal': 'BORDEAUX_BLANC_US_BU_Forecast', 'Length': 36, 'MAPE': 0.383, 'RMSE': 403395.3115675406, 'MAE': 307343.7377127167, 'SMAPE': 0.3217, 'ErrorMean': -1.358178754647573e-10, 'ErrorStdDev': 403395.3115675405, 'R2': 0.041980024342557765, 'Pearson': 0.21104598132953822}
INFO:pyaf.hierarchical:REPORT_COMBINED_FORECASTS_VALID_PERF {'Signal': 'BORDEAUX_BLANC_US_BU_Forecast', 'Length': 9, 'MAPE': 0.2096, 'RMSE': 252977.83561553687, 'MAE': 167581.60529117833, 'SMAPE': 0.2035, 'ErrorMean': -54277.80173525347, 'ErrorStdDev': 247086.43336191104, 'R2': -0.21729575877784302, 'Pearson': 0.0}
INFO:pyaf.hierarchical:REPORT_COMBINED_FORECASTS_FIT_PERF {'Signal': 'BORDEAUX_ROUGE_BE_BU_Forecast', 'Length': 36, 'MAPE': 0.1511, 'RMSE': 1034134.42595624, 'MAE': 745887.7208675914, 'SMAPE': 0.1449, 'ErrorMean': 1.2935035758548313e-10, 'ErrorStdDev': 1034134.42595624, 'R2': 0.1148498112118489, 'Pearson': 0.34110079343525745}
INFO:pyaf.hierarchical:REPORT_COMBINED_FORECASTS_VALID_PERF {'Signal': 'BORDEAUX_ROUGE_BE_BU_Forecast', 'Length': 9, 'MAPE': 0.1915, 'RMSE': 921082.2727095841, 'MAE': 803425.001323376, 'SMAPE': 0.1977, 'ErrorMean': -270929.66418946494, 'ErrorStdDev': 880334.9761096833, 'R2': 0.053418461566188125, 'Pearson': 0.0}
INFO:pyaf.hierarchical:REPORT_COMBINED_FORECASTS_FIT_PERF {'Signal': 'BORDEAUX_ROUGE_CN_BU_Forecast', 'Length': 36, 'MAPE': 0.3932, 'RMSE': 5899859.7343801735, 'MAE': 4710841.45749947, 'SMAPE': 0.521, 'ErrorMean': -3569399.141589253, 'ErrorStdDev': 4697630.748939554, 'R2': -2.539579776876861, 'Pearson': -0.19228543926286962}
INFO:pyaf.hierarchical:REPORT_COMBINED_FORECASTS_VALID_PERF {'Signal': 'BORDEAUX_ROUGE_CN_BU_Forecast', 'Length': 9, 'MAPE': 0.2216, 'RMSE': 2646130.4232281283, 'MAE': 2110502.4689600933, 'SMAPE': 0.1932, 'ErrorMean': -382238.5782750007, 'ErrorStdDev': 2618377.338355146, 'R2': 0.2772267547872993, 'Pearson': 0.0}
INFO:pyaf.hierarchical:REPORT_COMBINED_FORECASTS_FIT_PERF {'Signal': 'BORDEAUX_ROUGE_DE_BU_Forecast', 'Length': 36, 'MAPE': 0.337, 'RMSE': 2172921.2151209507, 'MAE': 1699796.3050877494, 'SMAPE': 0.2917, 'ErrorMean': -91240.87311386141, 'ErrorStdDev': 2171004.7697313167, 'R2': -0.046690116723479, 'Pearson': -0.29888213817842174}
INFO:pyaf.hierarchical:REPORT_COMBINED_FORECASTS_VALID_PERF {'Signal': 'BORDEAUX_ROUGE_DE_BU_Forecast', 'Length': 9, 'MAPE': 0.272, 'RMSE': 1186136.6973808932, 'MAE': 910725.4387466401, 'SMAPE': 0.2118, 'ErrorMean': 677534.4440548599, 'ErrorStdDev': 973584.7893187959, 'R2': -0.2559907176181191, 'Pearson': 0.0}
INFO:pyaf.hierarchical:REPORT_COMBINED_FORECASTS_FIT_PERF {'Signal': 'BORDEAUX_ROUGE_GB_BU_Forecast', 'Length': 36, 'MAPE': 0.3547, 'RMSE': 4522958.716730319, 'MAE': 3622128.5, 'SMAPE': 0.3104, 'ErrorMean': 275448.1111111111, 'ErrorStdDev': 4514563.532760625, 'R2': 0.6230681985385662, 'Pearson': 0.8098760167727042}
INFO:pyaf.hierarchical:REPORT_COMBINED_FORECASTS_VALID_PERF {'Signal': 'BORDEAUX_ROUGE_GB_BU_Forecast', 'Length': 9, 'MAPE': 0.1592, 'RMSE': 1259434.9100598427, 'MAE': 951526.7777777778, 'SMAPE': 0.1541, 'ErrorMean': -18088.777777777777, 'ErrorStdDev': 1259305.0022913236, 'R2': -0.6548872013161662, 'Pearson': 0.0}
INFO:pyaf.hierarchical:REPORT_COMBINED_FORECASTS_FIT_PERF {'Signal': 'BORDEAUX_ROUGE_US_BU_Forecast', 'Length': 36, 'MAPE': 0.3846, 'RMSE': 3670201.8525633416, 'MAE': 3004362.8880813215, 'SMAPE': 0.4796, 'ErrorMean': -1559385.3195952456, 'ErrorStdDev': 3322453.7714752657, 'R2': -3.6041850530076776, 'Pearson': -0.2210489590109037}
INFO:pyaf.hierarchical:REPORT_COMBINED_FORECASTS_VALID_PERF {'Signal': 'BORDEAUX_ROUGE_US_BU_Forecast', 'Length': 9, 'MAPE': 0.1988, 'RMSE': 1279973.40760195, 'MAE': 1187013.801149747, 'SMAPE': 0.1863, 'ErrorMean': 88484.9492303933, 'ErrorStdDev': 1276911.249041155, 'R2': 0.1688012406765682, 'Pearson': 0.0}
INFO:pyaf.hierarchical:REPORT_COMBINED_FORECASTS_FIT_PERF {'Signal': 'CN_BU_Forecast', 'Length': 36, 'MAPE': 0.3828, 'RMSE': 6060931.46109166, 'MAE': 4880893.700146054, 'SMAPE': 0.4977, 'ErrorMean': -3639647.3136571553, 'ErrorStdDev': 4846427.303513274, 'R2': -2.4218040424796645, 'Pearson': -0.19318225959972254}
INFO:pyaf.hierarchical:REPORT_COMBINED_FORECASTS_VALID_PERF {'Signal': 'CN_BU_Forecast', 'Length': 9, 'MAPE': 0.2306, 'RMSE': 2851654.6793566504, 'MAE': 2420007.4080430586, 'SMAPE': 0.2083, 'ErrorMean': -686921.024828567, 'ErrorStdDev': 2767683.8540456803, 'R2': 0.1930008245727045, 'Pearson': 0.0}
INFO:pyaf.hierarchical:REPORT_COMBINED_FORECASTS_FIT_PERF {'Signal': 'DE_BU_Forecast', 'Length': 36, 'MAPE': 0.2925, 'RMSE': 2544167.6664504567, 'MAE': 1934557.116816145, 'SMAPE': 0.2714, 'ErrorMean': -436575.5675583059, 'ErrorStdDev': 2506429.909018623, 'R2': -0.000994242046815419, 'Pearson': 0.21952310702899056}
INFO:pyaf.hierarchical:REPORT_COMBINED_FORECASTS_VALID_PERF {'Signal': 'DE_BU_Forecast', 'Length': 9, 'MAPE': 0.2071, 'RMSE': 1175225.5046689187, 'MAE': 933131.1733145413, 'SMAPE': 0.1745, 'ErrorMean': 585999.0551659709, 'ErrorStdDev': 1018705.1065783974, 'R2': -0.11602593999046817, 'Pearson': 0.0}
INFO:pyaf.hierarchical:REPORT_COMBINED_FORECASTS_FIT_PERF {'Signal': 'EUROPE_BU_Forecast', 'Length': 36, 'MAPE': 0.212, 'RMSE': 6747586.225448739, 'MAE': 5705896.63604811, 'SMAPE': 0.2008, 'ErrorMean': -159164.06755830607, 'ErrorStdDev': 6745708.759608871, 'R2': 0.3741000559540115, 'Pearson': 0.6477186996501847}
INFO:pyaf.hierarchical:REPORT_COMBINED_FORECASTS_VALID_PERF {'Signal': 'EUROPE_BU_Forecast', 'Length': 9, 'MAPE': 0.1116, 'RMSE': 2443759.540347075, 'MAE': 2059543.2845683566, 'SMAPE': 0.1077, 'ErrorMean': 278069.3076139353, 'ErrorStdDev': 2427887.590313945, 'R2': 0.4954231535971201, 'Pearson': 0.0}
INFO:pyaf.hierarchical:REPORT_COMBINED_FORECASTS_FIT_PERF {'Signal': 'GB_BU_Forecast', 'Length': 36, 'MAPE': 0.3427, 'RMSE': 4910323.308976409, 'MAE': 4088050.915260217, 'SMAPE': 0.2992, 'ErrorMean': 277411.5000000002, 'ErrorStdDev': 4902480.786127038, 'R2': 0.5807302960568244, 'Pearson': 0.7856609595821422}
INFO:pyaf.hierarchical:REPORT_COMBINED_FORECASTS_VALID_PERF {'Signal': 'GB_BU_Forecast', 'Length': 9, 'MAPE': 0.1514, 'RMSE': 1555255.9635870806, 'MAE': 1179264.328081761, 'SMAPE': 0.1455, 'ErrorMean': -57028.64885822953, 'ErrorStdDev': 1554210.0390496075, 'R2': -0.32675474980832786, 'Pearson': 0.0}
INFO:pyaf.hierarchical:REPORT_COMBINED_FORECASTS_FIT_PERF {'Signal': 'US_BU_Forecast', 'Length': 36, 'MAPE': 0.3174, 'RMSE': 4139444.8981735716, 'MAE': 3423881.523455315, 'SMAPE': 0.363, 'ErrorMean': -1559385.3195952454, 'ErrorStdDev': 3834491.034028643, 'R2': -1.615652245446988, 'Pearson': -0.1851354794911439}
INFO:pyaf.hierarchical:REPORT_COMBINED_FORECASTS_VALID_PERF {'Signal': 'US_BU_Forecast', 'Length': 9, 'MAPE': 0.2064, 'RMSE': 1961288.3969814766, 'MAE': 1729787.2463276673, 'SMAPE': 0.1953, 'ErrorMean': -91953.27548080104, 'ErrorStdDev': 1959131.6370429327, 'R2': 0.08191724153051494, 'Pearson': 0.0}
INFO:pyaf.hierarchical:REPORT_COMBINED_FORECASTS_FIT_PERF {'Signal': 'WORLD_BU_Forecast', 'Length': 36, 'MAPE': 0.147, 'RMSE': 9271518.686280593, 'MAE': 7579789.866852175, 'SMAPE': 0.1531, 'ErrorMean': -3380120.8277447955, 'ErrorStdDev': 8633414.268983973, 'R2': 0.31923877147646307, 'Pearson': 0.6412775585974727}
INFO:pyaf.hierarchical:REPORT_COMBINED_FORECASTS_VALID_PERF {'Signal': 'WORLD_BU_Forecast', 'Length': 9, 'MAPE': 0.1213, 'RMSE': 5720232.5387728, 'MAE': 4423326.626083633, 'SMAPE': 0.1129, 'ErrorMean': 203255.76502609006, 'ErrorStdDev': 5716620.2770184735, 'R2': 0.3573359608539569, 'Pearson': 0.0}
INFO:pyaf.std:END_HIERARCHICAL_TRAINING_TIME_IN_SECONDS 16.736175298690796

In [20]:
French_Wine_Export_in_Euros_DF.info()


<class 'pandas.core.frame.DataFrame'>
RangeIndex: 50 entries, 0 to 49
Columns: 177 entries, Month to RHÔNE_ROUGE_US
dtypes: datetime64[ns](1), float64(56), int64(120)
memory usage: 69.3 KB

In [21]:
lInfo = lEngine.to_json()
lInfo.keys()


Out[21]:
dict_keys(['Structure', 'Models'])

In [22]:
lInfo['Structure']


Out[22]:
{0: {'ALSACE_BLANC_GB': set(),
  'ALSACE_BLANC_US': set(),
  'ALSACE_BLANC_DE': set(),
  'ALSACE_BLANC_BE': set(),
  'ALSACE_BLANC_CN': set(),
  'BORDEAUX_BLANC_GB': set(),
  'BORDEAUX_BLANC_US': set(),
  'BORDEAUX_BLANC_DE': set(),
  'BORDEAUX_BLANC_BE': set(),
  'BORDEAUX_BLANC_CN': set(),
  'BEAUJOLAIS_ROUGE_GB': set(),
  'BEAUJOLAIS_ROUGE_US': set(),
  'BEAUJOLAIS_ROUGE_DE': set(),
  'BEAUJOLAIS_ROUGE_BE': set(),
  'BEAUJOLAIS_ROUGE_CN': set(),
  'BORDEAUX_ROUGE_GB': set(),
  'BORDEAUX_ROUGE_US': set(),
  'BORDEAUX_ROUGE_DE': set(),
  'BORDEAUX_ROUGE_BE': set(),
  'BORDEAUX_ROUGE_CN': set()},
 1: {'GB': {'ALSACE_BLANC_GB',
   'BEAUJOLAIS_ROUGE_GB',
   'BORDEAUX_BLANC_GB',
   'BORDEAUX_ROUGE_GB'},
  'US': {'ALSACE_BLANC_US',
   'BEAUJOLAIS_ROUGE_US',
   'BORDEAUX_BLANC_US',
   'BORDEAUX_ROUGE_US'},
  'DE': {'ALSACE_BLANC_DE',
   'BEAUJOLAIS_ROUGE_DE',
   'BORDEAUX_BLANC_DE',
   'BORDEAUX_ROUGE_DE'},
  'BE': {'ALSACE_BLANC_BE',
   'BEAUJOLAIS_ROUGE_BE',
   'BORDEAUX_BLANC_BE',
   'BORDEAUX_ROUGE_BE'},
  'CN': {'ALSACE_BLANC_CN',
   'BEAUJOLAIS_ROUGE_CN',
   'BORDEAUX_BLANC_CN',
   'BORDEAUX_ROUGE_CN'}},
 2: {'EUROPE': {'BE', 'DE', 'GB'}, 'AMERICA': {'US'}, 'ASIA': {'CN'}},
 3: {'WORLD': {'AMERICA', 'ASIA', 'EUROPE'}}}

In [23]:
lInfo['Models'].keys()


Out[23]:
dict_keys(['ALSACE_BLANC_BE', 'ALSACE_BLANC_CN', 'ALSACE_BLANC_DE', 'ALSACE_BLANC_GB', 'ALSACE_BLANC_US', 'BEAUJOLAIS_ROUGE_BE', 'BEAUJOLAIS_ROUGE_CN', 'BEAUJOLAIS_ROUGE_DE', 'BEAUJOLAIS_ROUGE_GB', 'BEAUJOLAIS_ROUGE_US', 'BORDEAUX_BLANC_BE', 'BORDEAUX_BLANC_CN', 'BORDEAUX_BLANC_DE', 'BORDEAUX_BLANC_GB', 'BORDEAUX_BLANC_US', 'BORDEAUX_ROUGE_BE', 'BORDEAUX_ROUGE_CN', 'BORDEAUX_ROUGE_DE', 'BORDEAUX_ROUGE_GB', 'BORDEAUX_ROUGE_US', 'BE', 'CN', 'DE', 'GB', 'US', 'AMERICA', 'ASIA', 'EUROPE', 'WORLD'])

In [24]:
lInfo['Models']['BORDEAUX_ROUGE_CN']


Out[24]:
{'Dataset': {'Time': {'TimeVariable': 'Month',
   'TimeMinMax': ['2012-01-01 00:00:00', '2016-05-01 00:00:00'],
   'Horizon': 1},
  'Signal': 'BORDEAUX_ROUGE_CN',
  'Training_Signal_Length': 46},
 'Model': {'Best_Decomposition': 'Diff_BORDEAUX_ROUGE_CN_ConstantTrend_residue_zeroCycle_residue_AR(11)',
  'Signal_Transoformation': 'Difference',
  'Trend': 'ConstantTrend',
  'Cycle': 'NoCycle',
  'AR_Model': 'AR'},
 'Model_Performance': {'MAPE': '0.2216',
  'MASE': '0.7022',
  'MAE': '2110502.4689600933',
  'RMSE': '2646130.4232281283',
  'COMPLEXITY': '41'}}

In [25]:
perfs = [];
for model in sorted(lInfo['Models'].keys()):
    lPerf = lInfo['Models'][model]['Model_Performance']
    perfs.append([model , lPerf['RMSE'] , lPerf['MAPE']])
df_perf = pd.DataFrame(perfs , columns=['Model' , 'RMSE' , 'MAPE']);
df_perf = df_perf.sort_values(by = ['MAPE'])
print(df_perf)


                  Model                RMSE    MAPE
16    BORDEAUX_BLANC_GB   99936.68789248545   0.133
28                WORLD   6516614.471320467  0.1367
3       ALSACE_BLANC_GB   66480.16663925201  0.1402
25               EUROPE   3085512.630860862  0.1468
26                   GB  1567222.4394758958  0.1579
21    BORDEAUX_ROUGE_GB  1259434.9100598427  0.1592
7                    BE  1150941.4629769188  0.1693
2       ALSACE_BLANC_DE   144769.4922736975  0.1906
18    BORDEAUX_ROUGE_BE   921082.2727095841  0.1915
22    BORDEAUX_ROUGE_US    1279973.40760195  0.1988
17    BORDEAUX_BLANC_US  252977.83561553687  0.2096
5               AMERICA  2096609.4319779796  0.2209
27                   US  2096609.4319779796  0.2209
19    BORDEAUX_ROUGE_CN  2646130.4232281283  0.2216
23                   CN  2852608.7810445037  0.2353
6                  ASIA  2852608.7810445037  0.2353
24                   DE  1311702.0584794695  0.2377
4       ALSACE_BLANC_US   178019.5721837483   0.238
15    BORDEAUX_BLANC_DE   201387.2590557804  0.2533
20    BORDEAUX_ROUGE_DE  1186136.6973808932   0.272
12  BEAUJOLAIS_ROUGE_US   774435.6013471647  0.2867
0       ALSACE_BLANC_BE  444837.29072987556  0.2979
14    BORDEAUX_BLANC_CN  477151.95433478977   0.306
13    BORDEAUX_BLANC_BE  133791.73715896055  0.3373
1       ALSACE_BLANC_CN   86153.69023954055  0.3401
11  BEAUJOLAIS_ROUGE_GB  485564.32192152576  0.3584
8   BEAUJOLAIS_ROUGE_BE   126806.9861784883  0.4458
10  BEAUJOLAIS_ROUGE_DE  155871.73582628762  0.6144
9   BEAUJOLAIS_ROUGE_CN  190554.48176906724     1.0

In [26]:
lEngine.mSignalHierarchy.plot()


INFO:pyaf.std:START_HIERARCHICAL_PLOTTING
INFO:pyaf.std:END_HIERARCHICAL_PLOTTING_TIME_IN_SECONDS 0.25464677810668945

In [27]:
BORDEAUX_ROUGE_CN_Engine = lEngine.mSignalHierarchy.mModels[0]['BORDEAUX_ROUGE_CN']

In [28]:
BORDEAUX_ROUGE_CN_Engine.getModelInfo()


INFO:pyaf.std:TIME_DETAIL TimeVariable='Month' TimeMin=2012-01-01T00:00:00.000000 TimeMax=2014-12-01T00:00:00.000000 TimeDelta=<DateOffset: months=1> Horizon=1
INFO:pyaf.std:SIGNAL_DETAIL_ORIG SignalVariable='BORDEAUX_ROUGE_CN' Length=46  Min=5377235 Max=19050876  Mean=11306225.717391305 StdDev=3097054.2409197744
INFO:pyaf.std:SIGNAL_DETAIL_TRANSFORMED TransformedSignalVariable='Diff_BORDEAUX_ROUGE_CN' Min=-7118004.0 Max=8508070.0  Mean=58285.34782608696 StdDev=2959960.353380101
INFO:pyaf.std:BEST_TRANSOFORMATION_TYPE 'Diff_'
INFO:pyaf.std:BEST_DECOMPOSITION  'Diff_BORDEAUX_ROUGE_CN_ConstantTrend_residue_zeroCycle_residue_AR(11)' [ConstantTrend + NoCycle + AR]
INFO:pyaf.std:TREND_DETAIL 'Diff_BORDEAUX_ROUGE_CN_ConstantTrend' [ConstantTrend]
INFO:pyaf.std:CYCLE_DETAIL 'Diff_BORDEAUX_ROUGE_CN_ConstantTrend_residue_zeroCycle' [NoCycle]
INFO:pyaf.std:AUTOREG_DETAIL 'Diff_BORDEAUX_ROUGE_CN_ConstantTrend_residue_zeroCycle_residue_AR(11)' [AR]
INFO:pyaf.std:MODEL_MAPE MAPE_Fit=0.3932 MAPE_Forecast=0.2216 MAPE_Test=0.0703
INFO:pyaf.std:MODEL_SMAPE SMAPE_Fit=0.521 SMAPE_Forecast=0.1932 SMAPE_Test=0.0679
INFO:pyaf.std:MODEL_MASE MASE_Fit=2.2581 MASE_Forecast=0.7022 MASE_Test=None
INFO:pyaf.std:MODEL_L1 L1_Fit=4710841.45749947 L1_Forecast=2110502.4689600933 L1_Test=793876.8093173634
INFO:pyaf.std:MODEL_L2 L2_Fit=5899859.7343801735 L2_Forecast=2646130.4232281283 L2_Test=793876.8093173634
INFO:pyaf.std:MODEL_COMPLEXITY 41
INFO:pyaf.std:SIGNAL_TRANSFORMATION_DETAIL_START
INFO:pyaf.std:DIFFERENCING_TRANSFORMATION Difference 8616750
INFO:pyaf.std:SIGNAL_TRANSFORMATION_DETAIL_END
INFO:pyaf.std:TREND_DETAIL_START
INFO:pyaf.std:CONSTANT_TREND ConstantTrend 102348.25
INFO:pyaf.std:TREND_DETAIL_END
INFO:pyaf.std:CYCLE_MODEL_DETAIL_START
INFO:pyaf.std:ZERO_CYCLE_MODEL_VALUES Diff_BORDEAUX_ROUGE_CN_ConstantTrend_residue_zeroCycle 0.0 {}
INFO:pyaf.std:CYCLE_MODEL_DETAIL_END
INFO:pyaf.std:AR_MODEL_DETAIL_START
INFO:pyaf.std:AR_MODEL_COEFF 1 Diff_BORDEAUX_ROUGE_CN_ConstantTrend_residue_zeroCycle_residue_Lag3 -0.3867966153192115
INFO:pyaf.std:AR_MODEL_COEFF 2 Diff_BORDEAUX_ROUGE_CN_ConstantTrend_residue_zeroCycle_residue_Lag9 -0.29935738107599374
INFO:pyaf.std:AR_MODEL_COEFF 3 Diff_BORDEAUX_ROUGE_CN_ConstantTrend_residue_zeroCycle_residue_Lag2 -0.2945132457675459
INFO:pyaf.std:AR_MODEL_COEFF 4 Diff_BORDEAUX_ROUGE_CN_ConstantTrend_residue_zeroCycle_residue_Lag6 -0.13283631227578233
INFO:pyaf.std:AR_MODEL_COEFF 5 Diff_BORDEAUX_ROUGE_CN_ConstantTrend_residue_zeroCycle_residue_Lag7 0.10596403673387618
INFO:pyaf.std:AR_MODEL_COEFF 6 Diff_BORDEAUX_ROUGE_CN_ConstantTrend_residue_zeroCycle_residue_Lag10 -0.06307985742933694
INFO:pyaf.std:AR_MODEL_COEFF 7 Diff_BORDEAUX_ROUGE_CN_ConstantTrend_residue_zeroCycle_residue_Lag1 -0.05288492538443518
INFO:pyaf.std:AR_MODEL_COEFF 8 Diff_BORDEAUX_ROUGE_CN_ConstantTrend_residue_zeroCycle_residue_Lag11 -0.03488010234067359
INFO:pyaf.std:AR_MODEL_COEFF 9 Diff_BORDEAUX_ROUGE_CN_ConstantTrend_residue_zeroCycle_residue_Lag5 0.030428207374232505
INFO:pyaf.std:AR_MODEL_DETAIL_END

In [29]:
BORDEAUX_ROUGE_CN_Engine.standardPlots()


INFO:pyaf.std:START_PLOTTING
INFO:pyaf.std:END_PLOTTING_TIME_IN_SECONDS 0.4307279586791992

Hierarchical Forecast Combinations

Bottom-Up / Top-Down and Middle-Out Forecasts


In [30]:
lEngine.mOptions.mHierarchicalCombinationMethod = ["BU" , 'TD' , 'MO' , 'OC'];
dfapp_out = lEngine.forecast(train_df, H);


INFO:pyaf.std:START_HIERARCHICAL_FORECASTING
INFO:pyaf.hierarchical:FORECASTING_HIERARCHICAL_MODELS_LEVEL_SIGNAL [(0, 'ALSACE_BLANC_BE'), (0, 'ALSACE_BLANC_CN'), (0, 'ALSACE_BLANC_DE'), (0, 'ALSACE_BLANC_GB'), (0, 'ALSACE_BLANC_US'), (0, 'BEAUJOLAIS_ROUGE_BE'), (0, 'BEAUJOLAIS_ROUGE_CN'), (0, 'BEAUJOLAIS_ROUGE_DE'), (0, 'BEAUJOLAIS_ROUGE_GB'), (0, 'BEAUJOLAIS_ROUGE_US'), (0, 'BORDEAUX_BLANC_BE'), (0, 'BORDEAUX_BLANC_CN'), (0, 'BORDEAUX_BLANC_DE'), (0, 'BORDEAUX_BLANC_GB'), (0, 'BORDEAUX_BLANC_US'), (0, 'BORDEAUX_ROUGE_BE'), (0, 'BORDEAUX_ROUGE_CN'), (0, 'BORDEAUX_ROUGE_DE'), (0, 'BORDEAUX_ROUGE_GB'), (0, 'BORDEAUX_ROUGE_US'), (1, 'BE'), (1, 'CN'), (1, 'DE'), (1, 'GB'), (1, 'US'), (2, 'AMERICA'), (2, 'ASIA'), (2, 'EUROPE'), (3, 'WORLD')]
INFO:pyaf.std:START_FORECASTING 'ALSACE_BLANC_BE'
INFO:pyaf.std:END_FORECAST_TIME_IN_SECONDS  'ALSACE_BLANC_BE' 0.10614252090454102
INFO:pyaf.std:START_FORECASTING 'ALSACE_BLANC_CN'
INFO:pyaf.std:START_FORECASTING 'ALSACE_BLANC_DE'
INFO:pyaf.std:END_FORECAST_TIME_IN_SECONDS  'ALSACE_BLANC_CN' 0.1340646743774414
INFO:pyaf.std:END_FORECAST_TIME_IN_SECONDS  'ALSACE_BLANC_DE' 0.09419608116149902
INFO:pyaf.std:START_FORECASTING 'ALSACE_BLANC_GB'
INFO:pyaf.std:END_FORECAST_TIME_IN_SECONDS  'ALSACE_BLANC_GB' 0.09335899353027344
INFO:pyaf.std:START_FORECASTING 'ALSACE_BLANC_US'
INFO:pyaf.std:START_FORECASTING 'BEAUJOLAIS_ROUGE_BE'
INFO:pyaf.std:END_FORECAST_TIME_IN_SECONDS  'ALSACE_BLANC_US' 0.1188194751739502
INFO:pyaf.std:END_FORECAST_TIME_IN_SECONDS  'BEAUJOLAIS_ROUGE_BE' 0.10483503341674805
INFO:pyaf.std:START_FORECASTING 'BEAUJOLAIS_ROUGE_CN'
INFO:pyaf.std:START_FORECASTING 'BEAUJOLAIS_ROUGE_DE'
INFO:pyaf.std:END_FORECAST_TIME_IN_SECONDS  'BEAUJOLAIS_ROUGE_CN' 0.09068918228149414
INFO:pyaf.std:END_FORECAST_TIME_IN_SECONDS  'BEAUJOLAIS_ROUGE_DE' 0.08982563018798828
INFO:pyaf.std:START_FORECASTING 'BEAUJOLAIS_ROUGE_GB'
INFO:pyaf.std:END_FORECAST_TIME_IN_SECONDS  'BEAUJOLAIS_ROUGE_GB' 0.08919095993041992
INFO:pyaf.std:START_FORECASTING 'BEAUJOLAIS_ROUGE_US'
INFO:pyaf.std:END_FORECAST_TIME_IN_SECONDS  'BEAUJOLAIS_ROUGE_US' 0.09915328025817871
INFO:pyaf.std:START_FORECASTING 'BORDEAUX_BLANC_BE'
INFO:pyaf.std:END_FORECAST_TIME_IN_SECONDS  'BORDEAUX_BLANC_BE' 0.12746596336364746
INFO:pyaf.std:START_FORECASTING 'BORDEAUX_BLANC_CN'
INFO:pyaf.std:END_FORECAST_TIME_IN_SECONDS  'BORDEAUX_BLANC_CN' 0.08881258964538574
INFO:pyaf.std:START_FORECASTING 'BORDEAUX_BLANC_DE'
INFO:pyaf.std:END_FORECAST_TIME_IN_SECONDS  'BORDEAUX_BLANC_DE' 0.1094510555267334
INFO:pyaf.std:START_FORECASTING 'BORDEAUX_BLANC_GB'
INFO:pyaf.std:START_FORECASTING 'BORDEAUX_BLANC_US'
INFO:pyaf.std:END_FORECAST_TIME_IN_SECONDS  'BORDEAUX_BLANC_GB' 0.12147212028503418
INFO:pyaf.std:END_FORECAST_TIME_IN_SECONDS  'BORDEAUX_BLANC_US' 0.08834195137023926
INFO:pyaf.std:START_FORECASTING 'BORDEAUX_ROUGE_BE'
INFO:pyaf.std:END_FORECAST_TIME_IN_SECONDS  'BORDEAUX_ROUGE_BE' 0.09271359443664551
INFO:pyaf.std:START_FORECASTING 'BORDEAUX_ROUGE_CN'
INFO:pyaf.std:START_FORECASTING 'BORDEAUX_ROUGE_DE'
INFO:pyaf.std:END_FORECAST_TIME_IN_SECONDS  'BORDEAUX_ROUGE_CN' 0.1137382984161377
INFO:pyaf.std:END_FORECAST_TIME_IN_SECONDS  'BORDEAUX_ROUGE_DE' 0.09014034271240234
INFO:pyaf.std:START_FORECASTING 'BORDEAUX_ROUGE_GB'
INFO:pyaf.std:START_FORECASTING 'BORDEAUX_ROUGE_US'
INFO:pyaf.std:END_FORECAST_TIME_IN_SECONDS  'BORDEAUX_ROUGE_GB' 0.0887598991394043
INFO:pyaf.std:END_FORECAST_TIME_IN_SECONDS  'BORDEAUX_ROUGE_US' 0.1569528579711914
INFO:pyaf.std:START_FORECASTING 'BE'
INFO:pyaf.std:START_FORECASTING 'CN'
INFO:pyaf.std:END_FORECAST_TIME_IN_SECONDS  'BE' 0.126878023147583
INFO:pyaf.std:END_FORECAST_TIME_IN_SECONDS  'CN' 0.11184477806091309
INFO:pyaf.std:START_FORECASTING 'DE'
INFO:pyaf.std:START_FORECASTING 'GB'
INFO:pyaf.std:END_FORECAST_TIME_IN_SECONDS  'DE' 0.07956194877624512
INFO:pyaf.std:START_FORECASTING 'US'
INFO:pyaf.std:END_FORECAST_TIME_IN_SECONDS  'GB' 0.0834503173828125
INFO:pyaf.std:END_FORECAST_TIME_IN_SECONDS  'US' 0.08534836769104004
INFO:pyaf.std:START_FORECASTING 'AMERICA'
INFO:pyaf.std:END_FORECAST_TIME_IN_SECONDS  'AMERICA' 0.08472228050231934
INFO:pyaf.std:START_FORECASTING 'ASIA'
INFO:pyaf.std:START_FORECASTING 'EUROPE'
INFO:pyaf.std:END_FORECAST_TIME_IN_SECONDS  'ASIA' 0.10328197479248047
INFO:pyaf.std:END_FORECAST_TIME_IN_SECONDS  'EUROPE' 0.08194112777709961
INFO:pyaf.std:START_FORECASTING 'WORLD'
INFO:pyaf.std:END_FORECAST_TIME_IN_SECONDS  'WORLD' 0.12117910385131836
INFO:pyaf.hierarchical:FORECASTING_HIERARCHICAL_MODEL_COMBINATION_METHODS ['BU', 'TD', 'MO', 'OC']
INFO:pyaf.hierarchical:FORECASTING_HIERARCHICAL_MODEL_BOTTOM_UP_METHOD BU
INFO:pyaf.hierarchical:FORECASTING_HIERARCHICAL_MODEL_TOP_DOWN_METHOD AHP_TD
INFO:pyaf.hierarchical:FORECASTING_HIERARCHICAL_MODEL_TOP_DOWN_METHOD PHA_TD
INFO:pyaf.hierarchical:FORECASTING_HIERARCHICAL_MODEL_MIDDLE_OUT_METHOD MO
INFO:pyaf.hierarchical:FORECASTING_HIERARCHICAL_MODEL_OPTIMAL_COMBINATION_METHOD OC
INFO:pyaf.std:END_HIERARCHICAL_FORECAST_TIME_IN_SECONDS 4.700767517089844

In [31]:
for country in Countries:
    dfapp_out.plot('Month' , 
                    [country , country + '_Forecast' , 
                     country + '_BU_Forecast',  
                     country + '_PHA_TD_Forecast',  
                     country + '_AHP_TD_Forecast'  ,  
                     country + '_MO_Forecast' ,
                     country + '_OC_Forecast'  ],
                figsize=(32 , 12)).legend(fontsize=18)



In [32]:
for region in ['AMERICA', 'ASIA', 'EUROPE']:
    dfapp_out.plot('Month' , 
                    [region , region + '_Forecast' , 
                     region + '_BU_Forecast',  
                     region + '_PHA_TD_Forecast',  
                     region + '_AHP_TD_Forecast'  ,  
                     region + '_MO_Forecast' ,
                     region + '_OC_Forecast'  ],
                    figsize=(32 , 12)).legend(fontsize=18)



In [33]:
world = 'WORLD'
dfapp_out.plot('Month' , 
                [world , world + '_Forecast' , 
                 world + '_BU_Forecast',  
                 world + '_PHA_TD_Forecast',  
                 world + '_AHP_TD_Forecast'  ,  
                 world + '_MO_Forecast' ,
                 world + '_OC_Forecast'  ],
                figsize=(32 , 12)).legend(fontsize=18)


Out[33]:
<matplotlib.legend.Legend at 0x7feb2a516dc0>

In [ ]: