<p><div><div><div><div data-width="100" data-show-faces="false" data-send="true" data-layout="button_count" data-height="21" data-href="http://www.r-bloggers.com/announcing-new-forecasthybrid-package/"></div></div><div><a data-url="http://www.r-bloggers.com/announcing-new-forecasthybrid-package/" data-counturl="http://www.r-bloggers.com/announcing-new-forecasthybrid-package/" data-count="horizontal" data-text="Announcing new forecastHybrid package" class="twitter-share-button" data-via="rbloggers" href="https://twitter.com/share"></a></div><div></div></div><div></div></div>
<div>
(This article was first published on <strong><a href="http://ellisp.github.io/blog/2016/05/07/forecastHybrid"> Peter's stats stuff - R</a></strong>, and kindly contributed to <a rel="nofollow" href="http://www.r-bloggers.com/">R-bloggers)</a> </div>
<h2>Background and motivation</h2>
<p>In an <a target="_blank" href="http://ellisp.github.io/blog/2016/01/30/hybrid-forecasts/">earlier post</a> I explored ways that might improve on standard methods for prediction intervals from univariate time series forecasting. One of the tools I used was a convenience function to combine forecasts from Rob Hyndman’s <code>ets</code> and <code>auto.arima</code> functions. David Shaub (with a small contribution from myself) has now built and published an R package <code>forecastHybrid</code> that expands on this idea to create ensembles from other forecasting methods from Hyndman’s <code>forecast</code> package.</p>
<p>The motivation is to make it easy to improve forecasts, both their point estimates and their prediction intervals. It has been well known for many years that taking the average of rival forecast methods improves the performance of forecasts. This new R package aims to make it as easy for people to do this as to fit the individual models in the first place.</p>
<h2>Installation</h2>
<p>The stable version of the <code>forecastHybrid</code> package is on CRAN, and is installed the usual way:</p>
<div>
<pre><code data-lang="r"><a name="True-1"></a>install.packages<span>(</span><span>&quot;forecastHybrid&quot;</span><span>)</span>
<a name="True-2"></a><span>library</span><span>(</span>forecastHybrid<span>)</span></code></pre>
</div>
<p>It requires at least version 7.1 of Rob Hyndman’s <code>forecast</code> package, which is a recent upgrade.</p>
<h2>Usage</h2>
<h3>Basic</h3>
<p>Usage is a two step process:</p>
<ul>
<li>fitting the required time series models</li>
<li>forecasting them and taking a weighted average</li>
</ul>
<div>
<pre><code data-lang="r"><a name="True-1"></a>mod1 <span>&lt;-</span> hybridModel<span>(</span>AirPassengers<span>)</span>
<a name="True-2"></a>fc1 <span>&lt;-</span> forecast<span>(</span>mod1<span>)</span>
<a name="True-3"></a>fc1
<a name="True-4"></a>
<a name="True-5"></a>         Point Forecast    Lo <span>80</span>    Hi <span>80</span>    Lo <span>95</span>    Hi <span>95</span>
<a name="True-6"></a>Jan <span>1961</span>       <span>449.0761</span> <span>420.9284</span> <span>474.4528</span> <span>409.9071</span> <span>486.2105</span>
<a name="True-7"></a>Feb <span>1961</span>       <span>430.5014</span> <span>402.5180</span> <span>463.4376</span> <span>392.8622</span> <span>477.7219</span>
<a name="True-8"></a>Mar <span>1961</span>       <span>476.6044</span> <span>427.8241</span> <span>541.2952</span> <span>416.7423</span> <span>560.7848</span>
<a name="True-9"></a>Apr <span>1961</span>       <span>489.6462</span> <span>445.6985</span> <span>533.1953</span> <span>425.6737</span> <span>554.8180</span>
<a name="True-10"></a>May <span>1961</span>       <span>499.3256</span> <span>443.0128</span> <span>546.2434</span> <span>420.7317</span> <span>570.5889</span>
<a name="True-11"></a>Jun <span>1961</span>       <span>565.3663</span> <span>498.8558</span> <span>624.6220</span> <span>471.1949</span> <span>654.7751</span>
<a name="True-12"></a>Jul <span>1961</span>       <span>642.3351</span> <span>550.5136</span> <span>710.4620</span> <span>517.2336</span> <span>747.2133</span>
<a name="True-13"></a><span>&lt;</span>truncated<span>></span></code></pre>
</div>
<p>Prediction intervals are based on the conservative (and accurate, at least for the auto.arima / ets combination and the M3 competition data) method I set out in my <a target="_blank" href="http://ellisp.github.io/blog/2016/01/30/hybrid-forecasts/">earlier post</a> on hybrid methods. That is, at each time period of the forecast, the points of the prediction intervals of all the component models in the ensemble that are highest in absolute magnitude are used for the boundaries of the ensemble prediction interval. This method seems to give truer prediction intervals than any individual model’s prediction intervals, which are usually too narrow (ie give a false sense of precision) because they don’t take model uncertainty into account. This is an active area of investigation; <a target="_blank" href="https://github.com/ellisp/forecastHybrid/issues/19">we’re not sure we’re going to keep them calculated this way</a>.</p>
<p>The object created by the above procedure is of class <code>forecast</code> and the base graphics plotting method from Hyndman’s <code>forecast</code> package applies:</p>
<div>
<pre><code data-lang="r"><a name="True-1"></a>par<span>(</span>mar <span>=</span> <span>c</span><span>(</span><span>5</span><span>,</span> <span>4</span><span>,</span> <span>8</span><span>,</span> <span>2</span><span>))</span>
<a name="True-2"></a>plot<span>(</span>fc1<span>,</span> ylab <span>=</span> <span>&quot;International airline passengers&quot;</span><span>)</span></code></pre>
</div>
<p><img alt="basic" src="http://ellisp.github.io/img/0039-airpassengers1.svg"></p>
<h3>Custom combinations and weights</h3>
<p>Controlling which of the five types of available models are used in the ensemble is done via the <code>models</code> argument of <code>hybridModel</code>. <code>models</code> is a character string of any combination of <code>a</code>, <code>e</code>, <code>n</code>, <code>s</code>, and <code>t</code> for <code>auto.arima</code>, <code>ets</code>, <code>nnetar</code>, <code>stlm</code> and <code>tbats</code> respectively. In the code below I combine just <code>auto.arima</code> and <code>ets</code> (exponential state space smoothing) models, two component models that make up a high-performing (on average) forecasting method.</p>
<p>I also use this example to show how, instead of weighting the models equally, we can specify greater weight to be given to the model that fits the historical data better. This procedure isn’t recommended – it seems better just to give the models a priori weights, usually equal, rather than let the data dictate them. Why this is the case is out of my scope just here. Here’s the example:</p>
<div>
<pre><code data-lang="r"><a name="True-1"></a>mod2 <span>&lt;-</span> hybridModel<span>(</span>AirPassengers<span>,</span> models <span>=</span> <span>&quot;ae&quot;</span><span>,</span>
<a name="True-2"></a>                    weights <span>=</span> <span>&quot;insample.errors&quot;</span><span>)</span>
<a name="True-3"></a>fc2 <span>&lt;-</span> forecast<span>(</span>mod2<span>)</span>
<a name="True-4"></a>par<span>(</span>mar <span>=</span> <span>c</span><span>(</span><span>5</span><span>,</span> <span>4</span><span>,</span> <span>8</span><span>,</span> <span>2</span><span>))</span>
<a name="True-5"></a>plot<span>(</span>fc2<span>,</span> ylab <span>=</span> <span>&quot;International airline passengers&quot;</span><span>)</span></code></pre>
</div>
<p><img alt="ae" src="http://ellisp.github.io/img/0039-airpassengers2.svg"></p>
<h3>External regressors</h3>
<p>While most of the candidate models for an ensemble are univariate methods, <code>auto.arima</code> and <code>nnetar</code> models can incorporate an <code>xreg</code> argument. If you have actual values for the forecast period of external regressors, it’s often useful to use them in the forecasting process. The forecastHybrid approach lets you do this with the component models that support <code>xreg</code>, while ignoring it and fitting univariate time series models with other component models (eg <code>ets</code>).</p>
<p>To pass <code>xreg</code> or other parameters through to the model-fitting functions, the user passes up to five lists of parameters (<code>a.arg</code>, <code>e.arg</code>, <code>n.arg</code>, <code>s.arg</code> and <code>t.arg</code>). Here’s an example showing how to pass through xreg parameters to <code>auto.arima</code> for automated ARIMA modelling and <code>nnetar</code> for the feed-forward neural network model. This example tries to forecast 12 months of unemployment in Wisconsin, given known values of unemployment in surrounding states and for the USA as a whole (this isn’t a particularly realistic example in itself, but is of a type of forecast that does occur in reality, for example when one economic time series is only available after a much longer delay than other more timely measures).</p>
<p>The data management and forecast question below has been pinched from <a target="_blank" href="http://biba.etsii.upm.es/web/tiki-view_blog_post.php?postId=26">an example on the BIBA blog by joaquin</a></p>
<div>
<pre><code data-lang="r"><a name="True-1"></a><span># adapted from http://biba.etsii.upm.es/web/tiki-view_blog_post.php?postId=26 </span>
<a name="True-2"></a><span># donwload individual datasets from QUANDL</span>
<a name="True-3"></a>wi<span>&lt;-</span>read.csv<span>(</span><span>'http://www.quandl.com/api/v1/datasets/FRED/WIUR.csv?&amp;auth_token=gigXwpxd6Ex91cjgz1B7&amp;trim_start=1976-01-01&amp;trim_end=2013-04-01&amp;sort_order=desc'</span><span>,</span> colClasses<span>=</span><span>c</span><span>(</span><span>'Date'</span><span>=</span><span>'Date'</span><span>))</span>
<a name="True-4"></a>us<span>&lt;-</span>read.csv<span>(</span><span>'http://www.quandl.com/api/v1/datasets/FRED/UNRATE.csv?&amp;auth_token=gigXwpxd6Ex91cjgz1B7&amp;trim_start=1976-01-01&amp;trim_end=2013-04-01&amp;sort_order=desc'</span><span>,</span> colClasses<span>=</span><span>c</span><span>(</span><span>'Date'</span><span>=</span><span>'Date'</span><span>))</span>
<a name="True-5"></a>il<span>&lt;-</span>read.csv<span>(</span><span>'http://www.quandl.com/api/v1/datasets/FRED/ILUR.csv?&amp;auth_token=gigXwpxd6Ex91cjgz1B7&amp;trim_start=1976-01-01&amp;trim_end=2013-04-01&amp;sort_order=desc'</span><span>,</span> colClasses<span>=</span><span>c</span><span>(</span><span>'Date'</span><span>=</span><span>'Date'</span><span>))</span>
<a name="True-6"></a>mi<span>&lt;-</span>read.csv<span>(</span><span>'http://www.quandl.com/api/v1/datasets/FRED/MIUR.csv?&amp;auth_token=gigXwpxd6Ex91cjgz1B7&amp;trim_start=1976-01-01&amp;trim_end=2013-04-01&amp;sort_order=desc'</span><span>,</span> colClasses<span>=</span><span>c</span><span>(</span><span>'Date'</span><span>=</span><span>'Date'</span><span>))</span>
<a name="True-7"></a>mn<span>&lt;-</span>read.csv<span>(</span><span>'http://www.quandl.com/api/v1/datasets/FRED/MNUR.csv?&amp;auth_token=gigXwpxd6Ex91cjgz1B7&amp;trim_start=1976-01-01&amp;trim_end=2013-04-01&amp;sort_order=desc'</span><span>,</span> colClasses<span>=</span><span>c</span><span>(</span><span>'Date'</span><span>=</span><span>'Date'</span><span>))</span>
<a name="True-8"></a>io<span>&lt;-</span>read.csv<span>(</span><span>'http://www.quandl.com/api/v1/datasets/FRED/IAUR.csv?&amp;auth_token=gigXwpxd6Ex91cjgz1B7&amp;trim_start=1976-01-01&amp;trim_end=2013-04-01&amp;sort_order=desc'</span><span>,</span> colClasses<span>=</span><span>c</span><span>(</span><span>'Date'</span><span>=</span><span>'Date'</span><span>))</span>
<a name="True-9"></a>
<a name="True-10"></a><span>#merging the data into one dataframe</span>
<a name="True-11"></a>unemp <span>&lt;-</span> <span>merge</span><span>(</span>wi<span>,</span> io<span>,</span> by <span>=</span> <span>'DATE'</span><span>);</span> <span>colnames</span><span>(</span>unemp<span>)</span> <span>&lt;-</span> <span>c</span><span>(</span><span>'DATE'</span><span>,</span> <span>'wi'</span><span>,</span> <span>'io'</span><span>)</span>
<a name="True-12"></a>unemp <span>&lt;-</span> <span>merge</span><span>(</span>unemp<span>,</span> mi<span>,</span> by <span>=</span> <span>'DATE'</span><span>);</span> <span>colnames</span><span>(</span>unemp<span>)</span> <span>&lt;-</span> <span>c</span><span>(</span><span>'DATE'</span><span>,</span> <span>'wi'</span><span>,</span> <span>'io'</span><span>,</span> <span>'mi'</span><span>)</span>
<a name="True-13"></a>unemp <span>&lt;-</span> <span>merge</span><span>(</span>unemp<span>,</span> mn<span>,</span> by <span>=</span> <span>'DATE'</span><span>);</span> <span>colnames</span><span>(</span>unemp<span>)</span> <span>&lt;-</span> <span>c</span><span>(</span><span>'DATE'</span><span>,</span> <span>'wi'</span><span>,</span> <span>'io'</span><span>,</span> <span>'mi'</span><span>,</span> <span>'mn'</span><span>)</span>
<a name="True-14"></a>unemp <span>&lt;-</span> <span>merge</span><span>(</span>unemp<span>,</span> us<span>,</span> by <span>=</span> <span>'DATE'</span><span>);</span> <span>colnames</span><span>(</span>unemp<span>)</span> <span>&lt;-</span> <span>c</span><span>(</span><span>'DATE'</span><span>,</span> <span>'wi'</span><span>,</span> <span>'io'</span><span>,</span> <span>'mi'</span><span>,</span> <span>'mn'</span><span>,</span> <span>'us'</span><span>)</span>
<a name="True-15"></a>unemp <span>&lt;-</span> <span>merge</span><span>(</span>unemp<span>,</span> il<span>,</span> by <span>=</span> <span>'DATE'</span><span>);</span> <span>colnames</span><span>(</span>unemp<span>)</span> <span>&lt;-</span> <span>c</span><span>(</span><span>'DATE'</span><span>,</span> <span>'wi'</span><span>,</span> <span>'io'</span><span>,</span> <span>'mi'</span><span>,</span> <span>'mn'</span><span>,</span> <span>'us'</span><span>,</span> <span>'il'</span><span>)</span>
<a name="True-16"></a>
<a name="True-17"></a><span># break into historical and forecast periods</span>
<a name="True-18"></a>n <span>&lt;-</span> <span>nrow</span><span>(</span>unemp<span>)</span>
<a name="True-19"></a>unemp_hist <span>&lt;-</span> unemp<span>[</span><span>1</span><span>:</span><span>(</span>n <span>-</span> <span>12</span><span>),</span> <span>]</span>
<a name="True-20"></a>unemp_fc <span>&lt;-</span> unemp<span>[(</span>n <span>-</span> <span>11</span><span>)</span><span>:</span><span>448</span><span>,]</span>
<a name="True-21"></a>unemp_hist_ts <span>&lt;-</span> ts<span>(</span>unemp_hist<span>$</span>wi<span>,</span> start <span>=</span> <span>c</span><span>(</span><span>1976</span><span>,</span> <span>1</span><span>),</span> frequency <span>=</span> <span>12</span><span>)</span>
<a name="True-22"></a>
<a name="True-23"></a><span># fit hybrid model, passing arguments to auto.arima with a.args and to</span>
<a name="True-24"></a><span># nnetar with n.args</span>
<a name="True-25"></a>mod4 <span>&lt;-</span> hybridModel<span>(</span>unemp_hist_ts<span>,</span> models <span>=</span> <span>&quot;aen&quot;</span><span>,</span> 
<a name="True-26"></a>                    a.args <span>=</span> <span>list</span><span>(</span>xreg <span>=</span> unemp_hist<span>[</span> <span>,</span> <span>3</span><span>:</span><span>7</span><span>]),</span>
<a name="True-27"></a>                    n.args <span>=</span> <span>list</span><span>(</span>xreg <span>=</span> unemp_hist<span>[</span> <span>,</span> <span>3</span><span>:</span><span>7</span><span>]))</span>
<a name="True-28"></a>
<a name="True-29"></a><span># fit the forecast - note that you have to supply the future xreg values,</span>
<a name="True-30"></a><span># but you only need to do it once (both nnetar and auto.arima use the same </span>
<a name="True-31"></a><span># ones): </span>
<a name="True-32"></a>par<span>(</span>mar <span>=</span> <span>c</span><span>(</span><span>5</span><span>,</span> <span>4</span><span>,</span> <span>6</span><span>,</span> <span>2</span><span>))</span>
<a name="True-33"></a>plot<span>(</span>fc4<span>,</span> ylab <span>=</span> <span>&quot;Unemployment in Wisonsin&quot;</span><span>,</span> 
<a name="True-34"></a>     sub <span>=</span> <span>&quot;Forecasts based on unemployment innUSA, Iowa, Michigan, Minnesota, and Illinois&quot;</span><span>)</span></code></pre>
</div>
<p><img alt="unemp" src="http://ellisp.github.io/img/0039-unemployment.svg"></p>
<p>There’s a lot more functionality in this package, mostly just inherited from Hyndman’s <code>forecast</code> package. So <a target="_blank" href="https://cran.rstudio.com/web/packages/forecastHybrid/">check it out on CRAN</a>.</p>
<h2>Future work</h2>
<p>Future work on the package, if / when we get around to it, is likely to include:</p>
<ul>
<li>Allowing the weights between the models to be set based on cross-validation performance of the component models</li>
<li>Allowing weights between the models to change over different forecast horizons (eg some models are known to be generally better at predicting long term than short term, so could be given extra weight as the forecast horizon increase)</li>
<li><code>ggplot2</code> graphics integration</li>
<li>More models</li>
<li>Improved parallelization (it already works with parallel processing, but this could be improved between models)</li>
<li>Automating model selection</li>
<li>Various under the hood things</li>
</ul>
<p>I also hope to do some more work <em>with</em> the package, eg more systematic tests of the performance of these hybrid model forecasts both as point forecasters and prediction intervals.</p>
<p>Bugs, issues and enhancement requests can be <a target="_blank" href="https://github.com/ellisp/forecastHybrid/issues">filed at GitHub</a>.</p>
<p>Nearly all the credit for this package goes to David Shaub; although it’s hosted on my GitHub account, my contribution has been small. So thanks David for a great convenient set of functionality for forecasters using R.</p>
<div>
<pre><code data-lang="r"><a name="True-1"></a><span>@</span>Manual<span>{,</span>
<a name="True-2"></a>    title <span>=</span> <span>{</span>forecastHybrid<span>:</span> Convenient Functions <span>for</span> Ensemble Time Series Forecasts<span>},</span>
<a name="True-3"></a>    author <span>=</span> <span>{</span>David Shaub<span>},</span>
<a name="True-4"></a>    year <span>=</span> <span>{</span><span>2016</span><span>},</span>
<a name="True-5"></a>    note <span>=</span> <span>{</span>R package version <span>0.1.5</span><span>},</span>
<a name="True-6"></a>    url <span>=</span> <span>{</span>https<span>://</span>CRAN.R<span>-</span>project.org<span>/</span>package<span>=</span>forecastHybrid<span>},</span>
<a name="True-7"></a>  <span>}</span></code></pre>
</div>
<p><div><div><div><div data-width="55" data-show-faces="false" data-send="true" data-layout="box_count" data-height="62" data-href="http://www.r-bloggers.com/announcing-new-forecasthybrid-package/"></div></div><div><a data-url="http://www.r-bloggers.com/announcing-new-forecasthybrid-package/" data-counturl="http://www.r-bloggers.com/announcing-new-forecasthybrid-package/" data-count="vertical" data-text="Announcing new forecastHybrid package" class="twitter-share-button" data-via="rbloggers" href="https://twitter.com/share"></a></div><div></div></div><div></div></div>
<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/05/07/forecastHybrid"> Peter's stats stuff - R</a></strong>.</div>
<hr>
<a rel="nofollow" href="http://www.r-bloggers.com/">R-bloggers.com</a> offers <strong><a rel="nofollow" href="http://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="http://www.r-project.org/">R</a> news and <a title="R tutorials" rel="nofollow" href="http://www.r-bloggers.com/?s=tutorial">tutorials</a> on topics such as: <a title="Data science" rel="nofollow" href="http://www.r-bloggers.com/?s=data%20science">Data science</a>, <a title="Big Data" rel="nofollow" href="http://www.r-bloggers.com/?s=Big%20Data">Big Data, <a title="R jobs" rel="nofollow" href="http://www.r-users.com/">R jobs</a>, visualization (<a title="ggplot and ggplot2 tutorials" rel="nofollow" href="http://www.r-bloggers.com/?s=ggplot2">ggplot2</a>, <a title="Boxplots using lattice and ggplot2 tutorials" rel="nofollow" href="http://www.r-bloggers.com/?s=boxplot">Boxplots</a>, <a title="Maps and gis" rel="nofollow" href="http://www.r-bloggers.com/?s=map">maps</a>, <a title="Animation in R" rel="nofollow" href="http://www.r-bloggers.com/?s=animation">animation</a>), programming (<a title="RStudio IDE for R" rel="nofollow" href="http://www.r-bloggers.com/?s=RStudio">RStudio</a>, <a title="Sweave and literate programming" rel="nofollow" href="http://www.r-bloggers.com/?s=sweave">Sweave</a>, <a title="LaTeX in R" rel="nofollow" href="http://www.r-bloggers.com/?s=LaTeX">LaTeX</a>, <a title="SQL and databases" rel="nofollow" href="http://www.r-bloggers.com/?s=SQL">SQL</a>, <a title="Eclipse IDE for R" rel="nofollow" href="http://www.r-bloggers.com/?s=eclipse">Eclipse</a>, <a title="git and github, Version Control System" rel="nofollow" href="http://www.r-bloggers.com/?s=git">git</a>, <a title="Large data in R using Hadoop" rel="nofollow" href="http://www.r-bloggers.com/?s=hadoop">hadoop</a>, <a title="Web Scraping of google, facebook, yahoo, twitter and more using R" rel="nofollow" href="http://www.r-bloggers.com/?s=Web+Scraping">Web Scraping</a>) statistics (<a title="Regressions and ANOVA analysis tutorials" rel="nofollow" href="http://www.r-bloggers.com/?s=regression">regression</a>, <a title="principal component analysis tutorial" rel="nofollow" href="http://www.r-bloggers.com/?s=PCA">PCA</a>, <a title="Time series" rel="nofollow" href="http://www.r-bloggers.com/?s=time+series">time series</a>, <a title="finance trading" rel="nofollow" href="http://www.r-bloggers.com/?s=trading">trading</a>) and more...
<img height="1" alt="" width="1" src="http://feeds.feedburner.com/~r/RBloggers/~4/0tOh6CVt9Lg"></a></div>