Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add support for reconciling disjoint hierarchies #106

Open
robjhyndman opened this issue Aug 9, 2019 · 2 comments
Open

Add support for reconciling disjoint hierarchies #106

robjhyndman opened this issue Aug 9, 2019 · 2 comments
Labels
reconciliation Related to hierarchical reconciliation

Comments

@robjhyndman
Copy link
Member

This seems to be unstable for some reason (non-positive-definite covariance), perhaps the .id is being used in reconciliation in some way.

library(fpp3)
tourism_stretch <- tourism %>%
  stretch_tsibble(.init = 16)
fits <- tourism_stretch %>%
  model(ets = ETS(Trips)) %>%
  reconcile(ets_adj = min_trace(ets, method='wls'))
fc <- fits %>% forecast(h = 1)
fc %>% accuracy(tourism) %>%
  group_by(.model) %>%
  summarise(MASE = mean(MASE))
@mitchelloharawild mitchelloharawild transferred this issue from tidyverts/fable Aug 9, 2019
@mitchelloharawild
Copy link
Member

From an email I sent related to this issue:

A simple test for reconciliation on a stretched tsibble would be as follows:

  • stretch the tsibble (2 folds should be sufficient), then make reconciled forecasts
  • Filter the tsibble to obtain a tsibble for each fold above, then separately produce reconciled forecasts using the same method above.

The resulting forecasts should be identical, if not the fold ID is probably messing with the reconciliation (actually, after thinking about it in the paragraph below, I know that there is a problem with this now!).

Thinking about this has actually led me to an interesting thought about reconciliation of disjoint graph structures.
What we actually have is separate network structures for each fold, and so the reconciliation should probably happen independently for each network.
This has neat conceptual implications with reconciling a set of models without any specified aggregation structure - all bottom level time series are separate networks and so there is nothing to reconcile.
I'll have to think about this some more, but if we can detect disjoint graph structures within the key variable (should be possible) and then reconcile each tree separately (with their own S matrix, etc.), we should be able to keep the same interface.

@mitchelloharawild mitchelloharawild changed the title Stability of reconciliation Add support for reconciling disjoint hierarchies Aug 12, 2019
@mitchelloharawild
Copy link
Member

An update. It is now possible to create these disjoint sets using aggregate_key.
As suggested by Rob, this uses the same hierarchical interface as lm(). Below I've nested key by .id, and removed the top level by excluding the intercept.
I've also made the reconciliation fail when it detects disjoint sets, until the reconciliation of multiple hierarchies is implemented.

library(fable)
#> Loading required package: fabletools
library(tsibble)
lung_deaths_long <- as_tsibble(cbind(mdeaths, fdeaths))

lung_deaths_long %>% 
  aggregate_key(key, value = sum(value)) %>% 
  stretch_tsibble(.init = 71)
#> # A tsibble: 429 x 4 [1M]
#> # Key:       .id, key [6]
#>    key        index value   .id
#>    <chr>      <mth> <dbl> <int>
#>  1 fdeaths 1974 Jan   901     1
#>  2 fdeaths 1974 Feb   689     1
#>  3 fdeaths 1974 Mar   827     1
#>  4 fdeaths 1974 Apr   677     1
#>  5 fdeaths 1974 May   522     1
#>  6 fdeaths 1974 Jun   406     1
#>  7 fdeaths 1974 Jul   441     1
#>  8 fdeaths 1974 Aug   393     1
#>  9 fdeaths 1974 Sep   387     1
#> 10 fdeaths 1974 Oct   582     1
#> # … with 419 more rows

lung_deaths_long %>% 
  stretch_tsibble(.init = 71) %>% 
  aggregate_key(0 + .id/key, value = sum(value))
#> # A tsibble: 429 x 4 [1M]
#> # Key:       .id, key [6]
#>    .id   key             index value
#>    <int> <chr>           <mth> <dbl>
#>  1 1     <aggregated> 1974 Jan  3035
#>  2 2     <aggregated> 1974 Jan  3035
#>  3 1     <aggregated> 1974 Feb  2552
#>  4 2     <aggregated> 1974 Feb  2552
#>  5 1     <aggregated> 1974 Mar  2704
#>  6 2     <aggregated> 1974 Mar  2704
#>  7 1     <aggregated> 1974 Apr  2554
#>  8 2     <aggregated> 1974 Apr  2554
#>  9 1     <aggregated> 1974 May  2014
#> 10 2     <aggregated> 1974 May  2014
#> # … with 419 more rows

lung_deaths_long %>% 
  aggregate_key(key, value = sum(value)) %>% 
  stretch_tsibble(.init = 71) %>% 
  model(mdl = ETS(value)) %>% 
  reconcile(mdl = min_trace(mdl)) %>% 
  forecast()
#> Warning: Reconciliation in fable is highly experimental. The interface will
#> likely be refined in the near future.
#> Loading required namespace: SparseM
#> Reconciliation of disjoint hierarchical structures is not yet supported.

Created on 2019-08-13 by the reprex package (v0.3.0)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
reconciliation Related to hierarchical reconciliation
Projects
None yet
Development

No branches or pull requests

2 participants