<p><div><div><div><div data-width="100" data-show-faces="false" data-send="true" data-layout="button_count" data-height="21" data-href="https://www.r-bloggers.com/forecasthybrid-0-3-0-on-cran/"></div></div><div></div></div><div></div></div>
<div>
(This article was first published on <strong><a href="http://ellisp.github.io/blog/2016/12/24/forecastHybrid-0.3"> Peter's stats stuff - R</a></strong>, and kindly contributed to <a rel="nofollow" href="https://www.r-bloggers.com/">R-bloggers)</a> </div>
<h2>Make it easy to make ensemble time series forecast</h2>
<p><code>forecastHybrid</code> is an R package to make it easier to use the average predictions of ‘ensembles’ (or ‘combinations’) of time series models from Rob Hyndman’s <code>forecast</code> package. It looks after the averaging, and also calculates prediction intervals by a <a target="_blank" rel="nofollow" href="http://ellisp.github.io/presentations/ellis-prediction-intervals-for-ensemble-forecasts.pptx">conservative method</a> that aims to redress the general over-optimism in forecasting prediction intervals.</p>
<p>New in version 0.3.0 is:</p>
<ul>
<li>Following developments in the <code>forecast</code> package, prediction intervals are now created for <code>nnetar</code> objects in the ensemble. This should address one aspect of incorrect prediction intervals (e.g. <a target="_blank" rel="nofollow" href="https://github.com/ellisp/forecastHybrid/issues/37">issue #37</a>).</li>
<li>theta models can be added (by including “<code>f</code>” in the <code>models =</code> argument for <code>hybridModel()</code>) and are indeed part of the default – so unless set otherwise, <code>hybridModel()</code> will now fit six models.</li>
<li><code>accuracy.cvts()</code> is now exported. It returns ra ange of summary measures of the cross-validated forecast accuracy for objects created by <code>cvts</code>. Note that development on <code>cvts</code> for <code>forecastHybrid</code> has been independent of Hyndman’s work on a <a target="_blank" rel="nofollow" href="http://robjhyndman.com/hyndsight/tscv/">similarly purposed <code>tscv</code> function in <code>forecast</code></a> – be careful not to get the two confused.</li>
<li><code>plot.hybridModel()</code> now supports <code>ggplot2</code> graphics when the argument <code>ggplot = TRUE</code> is passed.</li>
<li>Time series must be at least four observations long.</li>
<li>Fixed an error where <code>e.args</code> was passed to <code>tbats</code> instead of <code>t.args</code>.</li>
</ul>
<p>In some respects, version 0.2.0 was a more important upgrade because it introduced <code>cvts</code> and the use of a weighted average forecast with weights for the component models chosen by cross-validation. I didn’t get around to writing a blog post when that happened.</p>
<h2>Installation</h2>
<figure>
<pre><code data-lang="r"><span># Install from CRAN the usual way:
</span><span>install.packages</span><span>(</span><span>&quot;forecastHybrid&quot;</span><span>)</span><span>
</span><span>library</span><span>(</span><span>forecastHybrid</span><span>)</span><span>
</span><span>library</span><span>(</span><span>ggplot2</span><span>)</span><span>
</span><span>library</span><span>(</span><span>scales</span><span>)</span><span>
</span><span>library</span><span>(</span><span>tidyverse</span><span>)</span><span>
</span><span>citation</span><span>(</span><span>&quot;forecastHybrid&quot;</span><span>)</span><span>
</span><span># To cite package ‘forecastHybrid’ in publications use:
# # David Shaub and Peter Ellis (2016). forecastHybrid: Convenient Functions for
# Ensemble Time Series Forecasts. R package version 0.3.0.
# https://CRAN.R-project.org/package=forecastHybrid
# # A BibTeX entry for LaTeX users is
# # @Manual{,
# title = {forecastHybrid: Convenient Functions for Ensemble Time Series Forecasts},
# author = {David Shaub and Peter Ellis},
# year = {2016},
# note = {R package version 0.3.0},
# url = {https://CRAN.R-project.org/package=forecastHybrid},
</span><span>#</span><span> </span><span>}</span></code></pre>
</figure>
<h2>Basic use</h2>
<p>The <code>hybridModel</code> function fits between two and six time series models to a time series, with or without <code>xreg</code> external regressor explanatory variables. The default, if the <code>models=</code> argument is left blank, is to fit all six available models. The modelling process also determines a set of weights to be used in subsequent forecasts. The two options are:</p>
<ul>
<li>equal weights ie a simple average</li>
<li>cross validation weights ie a weighted average, with models that performed better in cross-validation given more weight.</li>
</ul>
<p>Generally, we expect cross-validation weights to perform better, but they are quite computationally intensive and we haven’t got round to implementing parallel processing yet.</p>
<p>Here’s a demo with the median duration of unemployment in weeks from the <code>economics</code> dataset in the <code>ggplot2</code> package. This snippet demonstrates both ways of using weights and the default base plot method. This plot method is the one provided by <code>forecast</code> for all objects of class <code>forecast</code>, including those created by forecastHybrid.</p>
<figure>
<pre><code data-lang="r"><span># median duration of unemployment, in weeks
</span><span>uempmed</span><span> </span><span>&lt;-</span><span> </span><span>ts</span><span>(</span><span>economics</span><span>$</span><span>uempmed</span><span>,</span><span> </span><span>start</span><span> </span><span>=</span><span> </span><span>c</span><span>(</span><span>1967</span><span>,</span><span> </span><span>7</span><span>),</span><span> </span><span>frequency</span><span> </span><span>=</span><span> </span><span>12</span><span>)</span><span>
</span><span>BoxCox.lambda</span><span>(</span><span>uempmed</span><span>)</span><span> </span><span># very close to zero, so use logarithm tansform
</span><span>
</span><span>m</span><span>1</span><span> </span><span>&lt;-</span><span> </span><span>hybridModel</span><span>(</span><span>uempmed</span><span>,</span><span> </span><span>lambda</span><span> </span><span>=</span><span> </span><span>0</span><span>,</span><span> </span><span>weights</span><span> </span><span>=</span><span> </span><span>&quot;equal&quot;</span><span>)</span><span>
</span><span>m</span><span>2</span><span> </span><span>&lt;-</span><span> </span><span>hybridModel</span><span>(</span><span>uempmed</span><span>,</span><span> </span><span>lambda</span><span> </span><span>=</span><span> </span><span>0</span><span>,</span><span> </span><span>weights</span><span> </span><span>=</span><span> </span><span>&quot;cv.errors&quot;</span><span>)</span><span>
</span><span>f</span><span>1</span><span> </span><span>&lt;-</span><span> </span><span>forecast</span><span>(</span><span>m</span><span>1</span><span>,</span><span> </span><span>24</span><span>)</span><span>
</span><span>f</span><span>2</span><span> </span><span>&lt;-</span><span> </span><span>forecast</span><span>(</span><span>m</span><span>2</span><span>,</span><span> </span><span>24</span><span>)</span><span>
</span><span>par</span><span>(</span><span>mfrow</span><span> </span><span>=</span><span> </span><span>c</span><span>(</span><span>2</span><span>,</span><span> </span><span>1</span><span>),</span><span> </span><span>font.main</span><span> </span><span>=</span><span> </span><span>1</span><span>,</span><span> </span><span>bty</span><span> </span><span>=</span><span> </span><span>&quot;l&quot;</span><span>,</span><span> </span><span>mar</span><span> </span><span>=</span><span> </span><span>c</span><span>(</span><span>4</span><span>,</span><span>3</span><span>,</span><span>6</span><span>,</span><span>2</span><span>)</span><span> </span><span>+</span><span> </span><span>0.1</span><span>,</span><span> </span><span>cex.main</span><span> </span><span>=</span><span> </span><span>0.6</span><span>)</span><span>
</span><span>plot</span><span>(</span><span>f</span><span>1</span><span>)</span><span>
</span><span>plot</span><span>(</span><span>f</span><span>2</span><span>)</span></code></pre>
</figure>
<p><img alt="base" src="http://ellisp.github.io/img/0074-base-forecast.svg"></p>
<p>The cross-validation errors should be better because they give less weight to poor performing forecasts. The forecasts from <code>nnetar</code> for example are often not good, and in a set of experiments for a <a target="_blank" rel="nofollow" href="http://ellisp.github.io/presentations/ellis-prediction-intervals-for-ensemble-forecasts.pptx">recent talk at the Australian Statistical Conference</a> I showed that they are sufficiently poor that they often worsen ensemble forecasts when added to the mix. Setting weights by cross-validation should mitigate this.</p>
<p>All of the component models can be accessed individually if desired:</p>
<figure>
<pre><code data-lang="r"><span>par</span><span>(</span><span>mfrow</span><span> </span><span>=</span><span> </span><span>c</span><span>(</span><span>3</span><span>,</span><span> </span><span>2</span><span>),</span><span> </span><span>bty</span><span> </span><span>=</span><span> </span><span>&quot;l&quot;</span><span>,</span><span> </span><span>cex</span><span> </span><span>=</span><span> </span><span>0.8</span><span>)</span><span>
</span><span>plot</span><span>(</span><span>f</span><span>2</span><span>$</span><span>thetam</span><span>)</span><span>
</span><span>plot</span><span>(</span><span>f</span><span>2</span><span>$</span><span>ets</span><span>)</span><span>
</span><span>plot</span><span>(</span><span>f</span><span>2</span><span>$</span><span>stlm</span><span>)</span><span>
</span><span>plot</span><span>(</span><span>f</span><span>2</span><span>$</span><span>auto.arima</span><span>)</span><span>
</span><span>plot</span><span>(</span><span>f</span><span>2</span><span>$</span><span>nnetar</span><span>)</span><span>
</span><span>plot</span><span>(</span><span>f</span><span>2</span><span>$</span><span>tbats</span><span>)</span></code></pre>
</figure>
<p><img alt="six" src="http://ellisp.github.io/img/0074-six-forecasts.svg"></p>
<p>The <code>ggplot2::autoplot()</code> method provided by the <code>forecast</code> package also works:</p>
<figure>
<pre><code data-lang="r"><span>autoplot</span><span>(</span><span>f</span><span>2</span><span>)</span><span> </span><span>+</span><span>
</span><span>ggtitle</span><span>(</span><span>&quot;Forecast median length of unemployment&quot;</span><span>,</span><span>
</span><span>subtitle</span><span> </span><span>=</span><span> </span><span>&quot;Six component models, weights chosen by cross-validation&quot;</span><span>)</span><span> </span><span>+</span><span>
</span><span>labs</span><span>(</span><span>y</span><span> </span><span>=</span><span> </span><span>&quot;Weeks&quot;</span><span>,</span><span> </span><span>x</span><span> </span><span>=</span><span> </span><span>&quot;&quot;</span><span>,</span><span>
</span><span>caption</span><span> </span><span>=</span><span> </span><span>&quot;Source: 'economics' in ggplot2 R package,\nultimately from http://research.stlouisfed.org/fred2&quot;</span><span>)</span></code></pre>
</figure>
<p><img alt="gg" src="http://ellisp.github.io/img/0074-gg-forecast.svg"></p>
<h2>Theta models</h2>
<p>We implemented the Theta forecast method based on <code>thetaf()</code> in Hyndman’s <code>forecast</code> (although there are alternatives). We had to split the process into a modelling function <code>thetam()</code>, and an accompanying <code>forecast.thetam</code> method. The results are identical to <code>forecast::thetaf()</code>, as demonstrated below:</p>
<figure>
<pre><code data-lang="r"><span>f</span><span>3</span><span> </span><span>&lt;-</span><span> </span><span>thetaf</span><span>(</span><span>uempmed</span><span>,</span><span> </span><span>h</span><span> </span><span>=</span><span> </span><span>24</span><span>)</span><span>
</span><span>f</span><span>4</span><span> </span><span>&lt;-</span><span> </span><span>forecast</span><span>(</span><span>thetam</span><span>(</span><span>uempmed</span><span>),</span><span> </span><span>h</span><span> </span><span>=</span><span> </span><span>24</span><span>)</span><span>
</span><span>data.frame</span><span>(</span><span>thetaf</span><span> </span><span>=</span><span> </span><span>f</span><span>3</span><span>$</span><span>mean</span><span>,</span><span> </span><span>thetam</span><span> </span><span>=</span><span> </span><span>f</span><span>3</span><span>$</span><span>mean</span><span>)</span><span> </span><span>%>%</span><span>
</span><span>mutate_each</span><span>(</span><span>&quot;as.numeric&quot;</span><span>)</span><span> </span><span>%>%</span><span>
</span><span>ggplot</span><span>(</span><span>aes</span><span>(</span><span>x</span><span> </span><span>=</span><span> </span><span>thetaf</span><span>,</span><span> </span><span>y</span><span> </span><span>=</span><span> </span><span>thetam</span><span>))</span><span> </span><span>+</span><span>
</span><span>geom_abline</span><span>(</span><span>intercept</span><span> </span><span>=</span><span> </span><span>0</span><span>,</span><span> </span><span>slope</span><span> </span><span>=</span><span> </span><span>1</span><span>)</span><span> </span><span>+</span><span>
</span><span>geom_point</span><span>()</span><span> </span><span>+</span><span>
</span><span>labs</span><span>(</span><span>x</span><span> </span><span>=</span><span> </span><span>&quot;thetaf()&quot;</span><span>,</span><span> </span><span>y</span><span> </span><span>=</span><span> </span><span>&quot;forecast(thetam())&quot;</span><span>,</span><span>
</span><span>caption</span><span> </span><span>=</span><span> </span><span>&quot;Forecasts are of median length of unemployment in the USA&quot;</span><span>)</span><span> </span><span>+</span><span>
</span><span>ggtitle</span><span>(</span><span>&quot;Separating thetaf into a modelling function with a forecast method&quot;</span><span>,</span><span>
</span><span>subtitle</span><span> </span><span>=</span><span> </span><span>&quot;The two methods give identical results&quot;</span><span>)</span></code></pre>
</figure>
<p><img alt="theta" src="http://ellisp.github.io/img/0074-theta.svg"></p>
<h2>Conservative prediction intervals?</h2>
<p>The <code>forecastHybrid</code> method of setting prediction intervals is conservative. It takes the widest range of values covered by any of the component models. In a <a target="_blank" rel="nofollow" href="http://robjhyndman.com/hyndsight/forecast-combinations/">blog post on different ways of setting forecast combinations</a>, Rob Hyndman points out that, using the monthly <code>co2</code> dataset of Mauna Loa Atmospheric CO2 Concentration distributed with R, the prediction intervals for the <code>forecastHybrid</code> method with six component models look too conservative ie sufficiently wide that they look very likely to contain the correct values much more than aimed for. In this particular case I agree – the method should be used with a bit of caution.</p>
<p>In practice, I often use only the <code>auto.arima</code> and <code>ets</code> forecasts in combination rather than all six possibilities. Even then, the method is sometimes too conservative with data that of monthly or higher frequency, particularly at the 80% level. Here’s the conclusions from <a target="_blank" rel="nofollow" href="http://ellisp.github.io/blog/2016/12/24/(/presentations/ellis-prediction-intervals-for-ensemble-forecasts.pptx)">my recent presentation on this topic</a> (apologies for the screenshot from PowerPoint):</p>
<p><img src="https://i0.wp.com/ellisp.github.io/img/0074-table.png?w=456" data-recalc-dims="1"></p>
<p>So for annual and quarterly real world data, the method is not too conservative at all; and if you want your prediction intervals to contain the true value 95% of the time, the method checks out ok even for monthly data.</p>
<h2>Feedback and suggestions</h2>
<p>Our preferred approach for you to provide suggestions and bug reports is to file an <a target="_blank" rel="nofollow" href="https://github.com/ellisp/forecastHybrid/issues">issue on GitHub</a>. Other comments and feedback could be provided as a comment on this blog post or on <a target="_blank" rel="nofollow" href="https://twitter.com/ellis2013nz">Twitter</a>.</p>
<p>
<div>
<div>To <strong>leave a comment</strong> for the author, please follow the link and comment on their blog: <strong><a href="http://ellisp.github.io/blog/2016/12/24/forecastHybrid-0.3"> Peter's stats stuff - R</a></strong>.</div>
<hr>
<a rel="nofollow" href="https://www.r-bloggers.com/">R-bloggers.com</a> offers <strong><a rel="nofollow" href="https://feedburner.google.com/fb/a/mailverify?uri=RBloggers">daily e-mail updates</a></strong> about <a title="The R Project for Statistical Computing" rel="nofollow" href="https://www.r-project.org/">R</a> news and <a title="R tutorials" rel="nofollow" href="https://www.r-bloggers.com/search/tutorial">tutorials</a> on topics such as: <a title="Data science" rel="nofollow" href="https://www.r-bloggers.com/search/data%20science">Data science</a>, <a title="Big Data" rel="nofollow" href="https://www.r-bloggers.com/search/Big%20Data">Big Data, <a title="R jobs" rel="nofollow" href="https://www.r-users.com/">R jobs</a>, visualization (<a title="ggplot and ggplot2 tutorials" rel="nofollow" href="https://www.r-bloggers.com/search/ggplot2">ggplot2</a>, <a title="Boxplots using lattice and ggplot2 tutorials" rel="nofollow" href="https://www.r-bloggers.com/search/boxplot">Boxplots</a>, <a title="Maps and gis" rel="nofollow" href="https://www.r-bloggers.com/search/map">maps</a>, <a title="Animation in R" rel="nofollow" href="https://www.r-bloggers.com/search/animation">animation</a>), programming (<a title="RStudio IDE for R" rel="nofollow" href="https://www.r-bloggers.com/search/RStudio">RStudio</a>, <a title="Sweave and literate programming" rel="nofollow" href="https://www.r-bloggers.com/search/sweave">Sweave</a>, <a title="LaTeX in R" rel="nofollow" href="https://www.r-bloggers.com/search/LaTeX">LaTeX</a>, <a title="SQL and databases" rel="nofollow" href="https://www.r-bloggers.com/search/SQL">SQL</a>, <a title="Eclipse IDE for R" rel="nofollow" href="https://www.r-bloggers.com/search/eclipse">Eclipse</a>, <a title="git and github, Version Control System" rel="nofollow" href="https://www.r-bloggers.com/search/git">git</a>, <a title="Large data in R using Hadoop" rel="nofollow" href="https://www.r-bloggers.com/search/hadoop">hadoop</a>, <a title="Web Scraping of google, facebook, yahoo, twitter and more using R" rel="nofollow" href="https://www.r-bloggers.com/search/Web+Scraping">Web Scraping</a>) statistics (<a title="Regressions and ANOVA analysis tutorials" rel="nofollow" href="https://www.r-bloggers.com/search/regression">regression</a>, <a title="principal component analysis tutorial" rel="nofollow" href="https://www.r-bloggers.com/search/PCA">PCA</a>, <a title="Time series" rel="nofollow" href="https://www.r-bloggers.com/search/time+series">time series</a>, <a title="finance trading" rel="nofollow" href="https://www.r-bloggers.com/search/trading">trading</a>) and more...
<img height="1" alt="" width="1" src="http://feeds.feedburner.com/~r/RBloggers/~4/mcp_KMYEd5A"></a></div>