class: inverse .title[fasster] .sticker-float[![fasster](resources/fasster.png)] ## Forecasting multiple seasonality with state switching .bottom[ ### Mitchell O'Hara-Wild (<svg style="height:0.8em;top:.04em;position:relative;fill:#1da1f2;" viewBox="0 0 512 512"><path d="M459.37 151.716c.325 4.548.325 9.097.325 13.645 0 138.72-105.583 298.558-298.558 298.558-59.452 0-114.68-17.219-161.137-47.106 8.447.974 16.568 1.299 25.34 1.299 49.055 0 94.213-16.568 130.274-44.832-46.132-.975-84.792-31.188-98.112-72.772 6.498.974 12.995 1.624 19.818 1.624 9.421 0 18.843-1.3 27.614-3.573-48.081-9.747-84.143-51.98-84.143-102.985v-1.299c13.969 7.797 30.214 12.67 47.431 13.319-28.264-18.843-46.781-51.005-46.781-87.391 0-19.492 5.197-37.36 14.294-52.954 51.655 63.675 129.3 105.258 216.365 109.807-1.624-7.797-2.599-15.918-2.599-24.04 0-57.828 46.782-104.934 104.934-104.934 30.213 0 57.502 12.67 76.67 33.137 23.715-4.548 46.456-13.32 66.599-25.34-7.798 24.366-24.366 44.833-46.132 57.827 21.117-2.273 41.584-8.122 60.426-16.243-14.292 20.791-32.161 39.308-52.628 54.253z"/></svg>[@mitchoharawild](https://twitter.com/mitchoharawild)) <br> ### 13 July 2018 ### Slides @ [slides.mitchelloharawild.com/useR18/](https://slides.mitchelloharawild.com/useR18/) ] --- class: center .animated.fadeIn[ ## Time-series data is changing ### More data, more often. <hr> ] --- class: center ## Time-series data is changing ### More data, more often. <hr> .animated.fadeIn[ ## Complicated patterns emerge .pull-left[ ### Multiple seasonality ### Lots of data ] .pull-right[ ### Missing values ### Additional noise ] <hr> ] --- class: center ## Time-series data is changing ### More data, more often. <hr> ## Complicated patterns emerge .pull-left[ ### Multiple seasonality ### Lots of data ] .pull-right[ ### Missing values ### Additional noise ] <hr> .animated.fadeIn[ ## New tools are needed .sticker[![tsibble](resources/tsibble.svg)] .sticker[![fable](resources/fable.svg)] .sticker[![fasster](resources/fasster.png)] ] --- class: inverse, center, top background-image: url(resources/electricity.jpg) background-size: cover .animated.fadeIn.shadowText[ # Electricity demand ] --- # Electricity demand (Monthly)
--- # Electricity demand (Daily)
--- # Electricity demand (Half-hourly)
--- # Electricity demand (Half-hourly)
--- # Models for multiple seasonality
+
-
<table class="table"> <thead> <tr> <th>Model</th> <th>Flexible</th> <th>Speed</th> <th>Exogenous Regressors</th> <th>Accuracy</th> <th>Decompose Components</th> <th>Evolving Terms</th> </tr> </thead> <tbody> <tr> <td>State Space</td> <td class="danger">No</td> <td class="danger">Slow</td> <td class="warning">Depends</td> <td class="warning">Okay</td> <td class="success">Yes</td> <td class="success">Yes</td> </tr> <tr> <td>Regression</td> <td class="success">Yes</td> <td class="success">Fast</td> <td class="success">Yes</td> <td class="warning">Okay</td> <td class="warning">Depends</td> <td class="danger">No</td> </tr> </tbody> </table> .center[(this table is a *massive* generalisation)] --- class: inverse .sticker-float[![fasster](resources/fasster.png)] # What is fasster? ### * **F**orecasting with **A**dditive **S**witching of **S**easonality, **T**rend & **E**xogenous **R**egressors* <br> -- ### A state space model that is: .pull-left[ * ### Flexible ] .pull-right[ * ### Fast ] <br> -- ### With support for: .pull-left[ * ### Missing values ] .pull-right[ * ### Exogenous regressors ] --- .sticker-float[![fable](resources/fable.svg)] # Extending fable **fasster** is the first extension of fable. <br> This allows fasster models to work with other features from the fable package. * Consistent output and graphics * Usable in combination forecasts <br> Uses formula based model specification: .panel.panel-default[.panel-body.largecode[ t(y) ~ *\{specials\}* ]] --- # Supported specials for fasster <table class="table" style="font-size: 26px; margin-left: auto; margin-right: auto;"> <thead> <tr> <th style="text-align:left;"> Function </th> <th style="text-align:left;"> Description </th> </tr> </thead> <tbody> <tr> <td style="text-align:left;"> poly(n) </td> <td style="text-align:left;"> Polynomials </td> </tr> <tr> <td style="text-align:left;"> seas(s) </td> <td style="text-align:left;"> Seasonal factors </td> </tr> <tr> <td style="text-align:left;"> trig(s, q) </td> <td style="text-align:left;"> Seasonal fourier terms </td> </tr> <tr> <td style="text-align:left;"> ARMA(ar, ma) </td> <td style="text-align:left;"> ARMA processes </td> </tr> <tr> <td style="text-align:left;"> xreg </td> <td style="text-align:left;"> Exogenous regressors </td> </tr> <tr> <td style="text-align:left;"> custom() </td> <td style="text-align:left;"> Custom dlm matrices </td> </tr> <tr> <td style="text-align:left;"> %S% </td> <td style="text-align:left;"> State switching </td> </tr> </tbody> </table> --- # Modelling with fasster <img src="figure/elecPlot2-1.svg" style="display: block; margin: auto;" /> --- # Modelling with fasster ```r elec_tr <- tsibbledata::elecdemand %>% filter(index < ymd("2014-03-01")) ``` ``` #> # A tsibble: 2,832 x 4 [30MINUTE] #> index Demand WorkDay Temperature #> <dttm> <dbl> <dbl> <dbl> #> 1 2014-01-01 00:00:00 3.91 0 18.2 #> 2 2014-01-01 00:30:00 3.67 0 17.9 #> 3 2014-01-01 01:00:00 3.50 0 17.6 #> 4 2014-01-01 01:30:00 3.34 0 16.8 #> 5 2014-01-01 02:00:00 3.20 0 16.3 #> 6 2014-01-01 02:30:00 3.10 0 16.6 #> 7 2014-01-01 03:00:00 3.04 0 16.6 #> 8 2014-01-01 03:30:00 3.01 0 16.7 #> 9 2014-01-01 04:00:00 3.02 0 16.2 #> 10 2014-01-01 04:30:00 3.03 0 16.6 #> # ... with 2,822 more rows ``` --- # Capturing seasonality ```r Demand ~ poly(1) + trig(48, 16) ``` <img src="figure/noswitching-1.svg" style="display: block; margin: auto;" /> --- # Capturing seasonality ```r Demand ~ DayType %S% (poly(1) + trig(48, 16)) ``` <img src="figure/switching-1.svg" style="display: block; margin: auto;" /> --- # Using temperature information ```r Demand ~ Temperature + I(Temperature^2) # (huge simplification of the non-linear relationship) ``` <img src="figure/unnamed-chunk-6-1.svg" style="display: block; margin: auto;" /> * Strongly related non-linear relationship. * Takes care of most annual seasonality. --- # Estimating the model ```r elec_fit <- elec_tr %>% fasster( log(Demand) ~ WorkDay %S% (trig(48, 16) + poly(1)) + Temperature + I(Temperature^2) ) ``` ``` #> # A mable: 1 model [30MINUTE] #> data model #> <list> <model> #> 1 <tsibble [2,832 × 4]> FASSTER ``` <br> * A log transformation is taken to stabalise the variance. * Specials are combined additively. --- # Components ```r components(elec_fit) ``` ``` #> # A tsibble: 2,832 x 7 [30MINUTE] #> index `I(Temperature^2… Temperature `WorkDay_0/poly… `WorkDay_0/trig… #> <dttm> <dbl> <dbl> <dbl> <dbl> #> 1 2014-01-01 00:00:00 0.000512 -0.0189 1.55 -0.00826 #> 2 2014-01-01 00:30:00 0.000512 -0.0189 1.55 -0.0826 #> 3 2014-01-01 01:00:00 0.000512 -0.0189 1.55 -0.118 #> 4 2014-01-01 01:30:00 0.000512 -0.0189 1.55 -0.167 #> 5 2014-01-01 02:00:00 0.000510 -0.0188 1.55 -0.198 #> 6 2014-01-01 02:30:00 0.000509 -0.0186 1.54 -0.227 #> 7 2014-01-01 03:00:00 0.000510 -0.0187 1.54 -0.244 #> 8 2014-01-01 03:30:00 0.000509 -0.0187 1.53 -0.249 #> 9 2014-01-01 04:00:00 0.000521 -0.0195 1.54 -0.250 #> 10 2014-01-01 04:30:00 0.000505 -0.0184 1.52 -0.232 #> # ... with 2,822 more rows, and 2 more variables: `WorkDay_1/poly(1)` <dbl>, #> # `WorkDay_1/trig(48, 16)` <dbl> ``` --- # Components (Seasonality) <img src="figure/comp-plot1-1.svg" style="display: block; margin: auto;" /> --- # Forecasts ```r elec_fc <- elec_fit %>% forecast(newdata = elec_ts) ``` ``` #> # A fable: 1 forecast [30MINUTE] #> data model forecast #> <list> <model> <fc> #> 1 <tsibble [2,832 × 4]> FASSTER ~t(N) [h=672] ``` -- ```r elec_ts ``` ``` #> # A tsibble: 672 x 3 [30MINUTE] #> index WorkDay Temperature #> <dttm> <dbl> <dbl> #> 1 2014-03-01 00:00:00 0 16.9 #> 2 2014-03-01 00:30:00 0 16.5 #> 3 2014-03-01 01:00:00 0 16.3 #> 4 2014-03-01 01:30:00 0 16.4 #> 5 2014-03-01 02:00:00 0 16.3 #> 6 2014-03-01 02:30:00 0 16.3 #> # ... with 666 more rows ``` --- # Forecasts <img src="figure/elecfcplot-1.svg" style="display: block; margin: auto;" /> --- # Forecasts <img src="figure/elecfcplotint-1.svg" style="display: block; margin: auto;" /> --- # Forecasts <img src="figure/elecfcplotintactual-1.svg" style="display: block; margin: auto;" /> --- # Interpolation <img src="figure/elecmissing-1.svg" style="display: block; margin: auto;" /> ```r elec_misfit <- elecdemand_missing %>% fasster(log(Demand) ~ WorkDay %S% (trig(48, 16) + poly(1)) + Temperature + Temperature^2) ``` --- # Interpolation <img src="figure/interpolated-1.svg" style="display: block; margin: auto;" /> ```r elec_misfit %>% interpolate ``` --- # Streaming data <img src="figure/stream_data_blank-1.svg" style="display: block; margin: auto;" /> --- # Streaming data <img src="figure/stream_data_new-1.svg" style="display: block; margin: auto;" /> ```r elec_stream ``` --- # Streaming data <img src="figure/stream_fc-1.svg" style="display: block; margin: auto;" /> ```r elec_fit %>% stream(elec_stream) %>% forecast(newdata = elec_stream_future) ``` --- class: inverse, top .sticker-float[![fasster](resources/fasster.png)] .title[Summary] .larger[ Features: .pull-left[ * Component extraction * Forecasting ] .pull-right[ * Interpolation * Streaming ] ] <br> -- <table class="table"> <thead> <tr> <th>Model</th> <th>Flexible</th> <th>Speed</th> <th>Exogenous Regressors</th> <th>Accuracy</th> <th>Decompose Components</th> <th>Evolving Terms</th> </tr> </thead> <tbody> <tr> <td>TBATS</td> <td class="danger">No</td> <td class="danger">Slow</td> <td class="danger">No</td> <td class="warning">Okay</td> <td class="success">Yes</td> <td class="success">Yes</td> </tr> <tr> <td>Prophet</td> <td class="warning">Okay</td> <td class="warning">Okay</td> <td class="success">Yes</td> <td class="success">Good</td> <td class="success">Yes</td> <td class="danger">No</td> </tr> <tr> <td>fasster</td> <td class="success">Yes</td> <td class="warning">Okay</td> <td class="success">Yes</td> <td class="success">Good</td> <td class="success">Yes</td> <td class="success">Yes</td> </tr> </tbody> </table> --- class: inverse, top .sticker-float[![fasster](resources/fasster.png)] .title[Thanks! <svg style="height:0.8em;top:.04em;position:relative;fill:white;" viewBox="0 0 576 512"><path d="M416 192c0-88.4-93.1-160-208-160S0 103.6 0 192c0 34.3 14.1 65.9 38 92-13.4 30.2-35.5 54.2-35.8 54.5-2.2 2.3-2.8 5.7-1.5 8.7S4.8 352 8 352c36.6 0 66.9-12.3 88.7-25 32.2 15.7 70.3 25 111.3 25 114.9 0 208-71.6 208-160zm122 220c23.9-26 38-57.7 38-92 0-66.9-53.5-124.2-129.3-148.1.9 6.6 1.3 13.3 1.3 20.1 0 105.9-107.7 192-240 192-10.8 0-21.3-.8-31.7-1.9C207.8 439.6 281.8 480 368 480c41 0 79.1-9.2 111.3-25 21.8 12.7 52.1 25 88.7 25 3.2 0 6.1-1.9 7.3-4.8 1.3-2.9.7-6.3-1.5-8.7-.3-.3-22.4-24.2-35.8-54.5z"/></svg>] <br> .larger[ <svg style="height:0.8em;top:.04em;position:relative;fill:white;" viewBox="0 0 496 512"><path d="M165.9 397.4c0 2-2.3 3.6-5.2 3.6-3.3.3-5.6-1.3-5.6-3.6 0-2 2.3-3.6 5.2-3.6 3-.3 5.6 1.3 5.6 3.6zm-31.1-4.5c-.7 2 1.3 4.3 4.3 4.9 2.6 1 5.6 0 6.2-2s-1.3-4.3-4.3-5.2c-2.6-.7-5.5.3-6.2 2.3zm44.2-1.7c-2.9.7-4.9 2.6-4.6 4.9.3 2 2.9 3.3 5.9 2.6 2.9-.7 4.9-2.6 4.6-4.6-.3-1.9-3-3.2-5.9-2.9zM244.8 8C106.1 8 0 113.3 0 252c0 110.9 69.8 205.8 169.5 239.2 12.8 2.3 17.3-5.6 17.3-12.1 0-6.2-.3-40.4-.3-61.4 0 0-70 15-84.7-29.8 0 0-11.4-29.1-27.8-36.6 0 0-22.9-15.7 1.6-15.4 0 0 24.9 2 38.6 25.8 21.9 38.6 58.6 27.5 72.9 20.9 2.3-16 8.8-27.1 16-33.7-55.9-6.2-112.3-14.3-112.3-110.5 0-27.5 7.6-41.3 23.6-58.9-2.6-6.5-11.1-33.3 2.6-67.9 20.9-6.5 69 27 69 27 20-5.6 41.5-8.5 62.8-8.5s42.8 2.9 62.8 8.5c0 0 48.1-33.6 69-27 13.7 34.7 5.2 61.4 2.6 67.9 16 17.7 25.8 31.5 25.8 58.9 0 96.5-58.9 104.2-114.8 110.5 9.2 7.9 17 22.9 17 46.4 0 33.7-.3 75.4-.3 83.6 0 6.5 4.6 14.4 17.3 12.1C428.2 457.8 496 362.9 496 252 496 113.3 383.5 8 244.8 8zM97.2 352.9c-1.3 1-1 3.3.7 5.2 1.6 1.6 3.9 2.3 5.2 1 1.3-1 1-3.3-.7-5.2-1.6-1.6-3.9-2.3-5.2-1zm-10.8-8.1c-.7 1.3.3 2.9 2.3 3.9 1.6 1 3.6.7 4.3-.7.7-1.3-.3-2.9-2.3-3.9-2-.6-3.6-.3-4.3.7zm32.4 35.6c-1.6 1.3-1 4.3 1.3 6.2 2.3 2.3 5.2 2.6 6.5 1 1.3-1.3.7-4.3-1.3-6.2-2.2-2.3-5.2-2.6-6.5-1zm-11.4-14.7c-1.6 1-1.6 3.6 0 5.9 1.6 2.3 4.3 3.3 5.6 2.3 1.6-1.3 1.6-3.9 0-6.2-1.4-2.3-4-3.3-5.6-2z"/></svg> Learn more on GitHub: [tidyverts/fasster](https://github.com/tidyverts/fasster) <svg style="height:0.8em;top:.04em;position:relative;fill:white;" viewBox="0 0 512 512"><path d="M500 384c6.6 0 12 5.4 12 12v40c0 6.6-5.4 12-12 12H12c-6.6 0-12-5.4-12-12V76c0-6.6 5.4-12 12-12h40c6.6 0 12 5.4 12 12v308h436zM456 96H344c-21.4 0-32.1 25.9-17 41l32.9 32.9-72 72.9-55.6-55.6c-4.7-4.7-12.2-4.7-16.9 0L96.4 305c-4.7 4.6-4.8 12.2-.2 16.9l28.5 29.4c4.7 4.8 12.4 4.9 17.1.1l82.1-82.1 55.5 55.5c4.7 4.7 12.3 4.7 17 0l109.2-109.2L439 249c15.1 15.1 41 4.4 41-17V120c0-13.3-10.7-24-24-24z"/></svg> Keep updated: [tidyverts.org](http://www.tidyverts.org) <svg style="height:0.8em;top:.04em;position:relative;fill:white;" viewBox="0 0 576 512"><path d="M528 0H48C21.5 0 0 21.5 0 48v320c0 26.5 21.5 48 48 48h192l-16 48h-72c-13.3 0-24 10.7-24 24s10.7 24 24 24h272c13.3 0 24-10.7 24-24s-10.7-24-24-24h-72l-16-48h192c26.5 0 48-21.5 48-48V48c0-26.5-21.5-48-48-48zm-16 352H64V64h448v288z"/></svg> Review slides: [slides.mitchelloharawild.com/useR18/](https://slides.mitchelloharawild.com/useR18/) <br> This work is licensed as <svg style="height:0.8em;top:.04em;position:relative;fill:white;" viewBox="0 0 496 512"><path d="M254.8 214.8l-33.2 17.3c-9.4-19.6-25.2-19.9-27.5-19.9-22.1 0-33.2 14.6-33.2 43.8 0 23.6 9.2 43.8 33.2 43.8 14.5 0 24.7-7.1 30.6-21.3l30.6 15.5c-6.2 11.5-25.7 39-65.1 39-22.6 0-74-10.3-74-77.1 0-58.7 43-77.1 72.6-77.1 30.8.2 52.7 12.1 66 36zm143.1 0l-32.8 17.3c-9.5-19.8-25.7-19.9-27.9-19.9-22.1 0-33.2 14.6-33.2 43.8 0 23.6 9.2 43.8 33.2 43.8 14.5 0 24.6-7.1 30.5-21.3l31 15.5c-2.1 3.7-21.4 39-65.1 39-22.7 0-74-9.9-74-77.1 0-58.7 43-77.1 72.6-77.1 30.8.2 52.7 12.1 65.7 36zM247.6 8C389.4 8 496 118.1 496 256c0 147.1-118.5 248-248.4 248C113.6 504 0 394.5 0 256 0 123.1 104.7 8 247.6 8zm.8 44.7C130.2 52.7 44.7 150.6 44.7 256c0 109.8 91.2 202.8 203.7 202.8 103.2 0 202.8-81.1 202.8-202.8.1-113.8-90.2-203.3-202.8-203.3z"/></svg> BY-NC 4.0. ] --- class: center ## Corticosteroid drug sales .thesisplot[ ![](resources/thesisp1.png) ] ![](resources/thesist1.png) --- class: center ## Pedestrian counts .thesisplot[ ![](resources/thesisp2.png) ] ![](resources/thesist2.png) --- class: center ## Electricity demand .thesisplot[ ![](resources/thesisp3.png) ] ![](resources/thesist3.png)