<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/timeseries-forecasting-using-extreme-gradient-boosting/"></div></div><div><a data-url="https://www.r-bloggers.com/timeseries-forecasting-using-extreme-gradient-boosting/" data-counturl="https://www.r-bloggers.com/timeseries-forecasting-using-extreme-gradient-boosting/" data-count="horizontal" data-text="Timeseries forecasting using extreme gradient boosting" 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/11/06/forecastxgb"> Peter's stats stuff - R</a></strong>, and kindly contributed to <a rel="nofollow" href="https://www.r-bloggers.com/">R-bloggers)</a> </div>
<p>In the last few years there have been more attempts at a fresh approach to statistical timeseries forecasting using the increasingly accessible tools of machine learning. This means methods like <a target="_blank" rel="nofollow" href="http://www.neural-forecasting-competition.com/index.htm">neural networks</a> and extreme <a target="_blank" rel="nofollow" href="https://en.wikipedia.org/wiki/Gradient_boosting">gradient boosting</a>, as supplements or even replacements of the more traditional tools like auto-regressive integrated moving average (ARIMA) models.</p>
<p>As an example aiming to get these methods into accessible production, Rob Hyndman’s <code>forecast</code> R package now includes the <code>nnetar</code> function. This takes lagged versions of the target variable as inputs and uses a neural network with a single hidden layer to model the results. Forecasting is then done one period at a time, with each new period then becoming part of the matrix of explanatory variables for the subsequent periods. All this is put into play (from the user’s perspective) with one or two lines of easily understood code.</p>
<p>I’ve started on an <a target="_blank" rel="nofollow" href="https://github.com/ellisp/forecastxgb-r-package/">R package <code>forecastxgb</code></a> which will adapt this approach to extreme gradient boosting, popularly implemented by the astonishingly fast and effective <a target="_blank" rel="nofollow" href="https://cran.r-project.org/package=xgboost"><code>xgboost</code></a> algorithm. <code>xgboost</code> has become dominant in parts of the predictive analytics field, particularly through competitions such as those hosted by Kaggle. From the <a target="_blank" rel="nofollow" href="https://github.com/ellisp/forecastxgb-r-package/blob/master/pkg/vignettes/xgbts.Rmd"><code>forecastxgb</code> vignette</a>:</p>
<blockquote>
<p>The <code>forecastxgb</code> package aims to provide time series modelling and forecasting functions that combine the machine learning approach of Chen, He and Benesty’s <a target="_blank" rel="nofollow" href="https://cran.r-project.org/package=xgboost"><code>xgboost</code></a> with the convenient handling of time series and familiar API of Rob Hyndman’s <a target="_blank" rel="nofollow" href="http://github.com/robjhyndman/forecast"><code>forecast</code></a>. It applies to time series the Extreme Gradient Boosting proposed in <a target="_blank" rel="nofollow" href="http://www.jstor.org/stable/2699986"><em>Greedy Function Approximation: A Gradient Boosting Machine</em>, by Jerome Friedman in 2001</a>. xgboost has become an important machine learning algorithm; nicely explained in <a target="_blank" rel="nofollow" href="http://xgboost.readthedocs.io/en/latest/model.html">this accessible documentation</a>.</p>
</blockquote>
<p>My aim is to make the data handling – creating all those lagged variables, and lagged versions of the xreg variables, and dummies for seasons – easy, and to make the API familiar to timeseries analysts familiar with the <code>forecast</code> package. Usage is straightforward, as shown here modelling Australia’s quarterly gas production using the <code>gas</code> time series included with <code>forecast</code>:</p>
<figure>
<pre><code data-lang="r"><span>devtools</span><span>::</span><span>install_github</span><span>(</span><span>&quot;ellisp/forecastxgb-r-package/pkg&quot;</span><span>)</span><span> </span><span># CRAN release still to come
</span><span>library</span><span>(</span><span>forecastxgb</span><span>)</span><span>
</span><span>model</span><span> </span><span>&lt;-</span><span> </span><span>xgbts</span><span>(</span><span>gas</span><span>)</span><span>
</span><span>fc</span><span> </span><span>&lt;-</span><span> </span><span>forecast</span><span>(</span><span>model</span><span>,</span><span> </span><span>h</span><span> </span><span>=</span><span> </span><span>12</span><span>)</span><span>
</span><span>plot</span><span>(</span><span>fc</span><span>)</span></code></pre>
</figure>
<p><em>[results not shown but will look familiar to anyone using the <code>forecast</code> toolkit]</em></p>
<p>I’m hoping that at least a few people will try it out and give me feedback before I feel comfortable publishing it on CRAN.</p>
<p>The <a target="_blank" rel="nofollow" href="https://github.com/ellisp/forecastxgb-r-package/blob/master/pkg/vignettes/xgbts.Rmd">vignette</a> has more examples, including with external regressors via the <code>xreg=</code> argument. This is where I think the approach might have something to offer that is competitive with traditional techniques, but I’m still on the lookout for a ready-to-go mass collection of data with x regressors, set up like a forecasting competition (ie with the actual results for assessment), to test it against.</p>
<p>Here is an extended univariate test of my new <code>xgbts</code> function against <code>nnetar</code> and two more traditional time series methods – ARIMA and the Theta method. Because it is well known that forecasting is more successful when averages of several forecasts are used, I also look at all the combinations of the four models, meaning there are 15 different sets of forecasts in the end for each data series. I test the approach on the 1,311 data series from the <a target="_blank" rel="nofollow" href="http://ellisp.github.io/blog/2016/10/19/Tcomp">2010 Tourism forecasting competition</a> conveniently available in the <code>Tcomp</code> R package which I released and blogged about a few weeks ago. The chart below shows mean absolute scaled error (MASE) of the various models’ forecasts when confronted with the actual results.</p>
<p><img alt="tcomp-results" src="https://i1.wp.com/ellisp.github.io/img/0066-tcomp.png?w=456" data-recalc-dims="1"></p>
<p>We see the overall best performing ensemble is the average of the Theta and ARIMA models – the two from the more traditional timeseries forecasting approach. The two machine learning methods (neural network and extreme gradient boosting) are not as effective, at least in these implementations. As individual methods, they are the two weakest, although the extreme gradient boosting method provided in <code>forecastxgb</code> performs noticeably better than <code>forecast::nnetar</code> (with this particular set of data – as I write, my computer finishes churning through all 3,000+ M3 competition datasets, which goes the other way in terms of <code>xgbts</code> versus <code>nnetar</code>).</p>
<p>Theta by itself is the best performing with the annual data – simple methods work well when the dataset is small and highly aggregate. The best that can be said of the <code>xgbts</code> approach in this context is that it doesn’t damage the Theta method much when included in a combination – several of the better performing ensembles have <code>xgbts</code> as one of their members. In contrast, the neural network models do badly with this particular collection of annual data.</p>
<p>Adding <code>auto.arima</code> and <code>xgbts</code> to an ensemble of quarterly or monthly data definitely improves on Theta by itself. The best performing single model for quarterly or monthly data is <code>auto.arima</code> followed by <code>thetaf</code>. Again, neural networks are the poorest of the four individual models.</p>
<p>Overall, I conclude that with this sort of univariate data, <code>xgbts</code> with its current default settings has little to add to an ensemble that already contains <code>auto.arima</code> and <code>thetaf</code> (or – not shown – the closely related <code>ets</code>). It’s likely that more investigation will show differing results with differing defaults, particuarly of the maximum number of lags to use. It’s also possible that inclusion of <code>xreg</code> external regressors might shift the balance in favour of <code>xgbts</code> and maybe even <code>nnetar</code> – the more complex and larger the dataset, the better the chance that these methods will have something to offer. Watch this space. Any ideas welcomed. Specific bugs, suggestions or enhancement requests are particularly welcome on the <a target="_blank" rel="nofollow" href="https://github.com/ellisp/forecastxgb-r-package/issues"><code>forecastxgb</code> page on GitHub</a>.</p>
<p>Here’s the code that did that test against the tourism competition data:</p>
<figure>
<pre><code data-lang="r"><span>#=============prep======================
</span><span>library</span><span>(</span><span>Tcomp</span><span>)</span><span>
</span><span>library</span><span>(</span><span>foreach</span><span>)</span><span>
</span><span>library</span><span>(</span><span>doParallel</span><span>)</span><span>
</span><span>library</span><span>(</span><span>forecastxgb</span><span>)</span><span>
</span><span>library</span><span>(</span><span>dplyr</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>Mcomp</span><span>)</span><span>
</span><span>#============set up cluster for parallel computing===========
</span><span>cluster</span><span> </span><span>&lt;-</span><span> </span><span>makeCluster</span><span>(</span><span>7</span><span>)</span><span> </span><span># only any good if you have at least 7 processors :)
</span><span>registerDoParallel</span><span>(</span><span>cluster</span><span>)</span><span>
</span><span>clusterEvalQ</span><span>(</span><span>cluster</span><span>,</span><span> </span><span>{</span><span>
</span><span>library</span><span>(</span><span>Tcomp</span><span>)</span><span>
</span><span>library</span><span>(</span><span>forecastxgb</span><span>)</span><span>
</span><span>library</span><span>(</span><span>Mcomp</span><span>)</span><span>
</span><span>})</span><span>
</span><span>#===============the actual analytical function==============
</span><span>competition</span><span> </span><span>&lt;-</span><span> </span><span>function</span><span>(</span><span>collection</span><span>,</span><span> </span><span>maxfors</span><span> </span><span>=</span><span> </span><span>length</span><span>(</span><span>collection</span><span>)){</span><span>
</span><span>if</span><span>(</span><span>class</span><span>(</span><span>collection</span><span>)</span><span> </span><span>!=</span><span> </span><span>&quot;Mcomp&quot;</span><span>){</span><span>
</span><span>stop</span><span>(</span><span>&quot;This function only works on objects of class Mcomp, eg from the Mcomp or Tcomp packages.&quot;</span><span>)</span><span>
</span><span>}</span><span>
</span><span>nseries</span><span> </span><span>&lt;-</span><span> </span><span>length</span><span>(</span><span>collection</span><span>)</span><span>
</span><span>mases</span><span> </span><span>&lt;-</span><span> </span><span>foreach</span><span>(</span><span>i</span><span> </span><span>=</span><span> </span><span>1</span><span>:</span><span>maxfors</span><span>,</span><span> </span><span>.combine</span><span> </span><span>=</span><span> </span><span>&quot;rbind&quot;</span><span>)</span><span> </span><span>%dopar%</span><span> </span><span>{</span><span>
</span><span>thedata</span><span> </span><span>&lt;-</span><span> </span><span>collection</span><span>[[</span><span>i</span><span>]]</span><span> </span><span>mod1</span><span> </span><span>&lt;-</span><span> </span><span>xgbts</span><span>(</span><span>thedata</span><span>$</span><span>x</span><span>)</span><span>
</span><span>fc1</span><span> </span><span>&lt;-</span><span> </span><span>forecast</span><span>(</span><span>mod1</span><span>,</span><span> </span><span>h</span><span> </span><span>=</span><span> </span><span>thedata</span><span>$</span><span>h</span><span>)</span><span>
</span><span>fc2</span><span> </span><span>&lt;-</span><span> </span><span>thetaf</span><span>(</span><span>thedata</span><span>$</span><span>x</span><span>,</span><span> </span><span>h</span><span> </span><span>=</span><span> </span><span>thedata</span><span>$</span><span>h</span><span>)</span><span>
</span><span>fc3</span><span> </span><span>&lt;-</span><span> </span><span>forecast</span><span>(</span><span>auto.arima</span><span>(</span><span>thedata</span><span>$</span><span>x</span><span>),</span><span> </span><span>h</span><span> </span><span>=</span><span> </span><span>thedata</span><span>$</span><span>h</span><span>)</span><span>
</span><span>fc4</span><span> </span><span>&lt;-</span><span> </span><span>forecast</span><span>(</span><span>nnetar</span><span>(</span><span>thedata</span><span>$</span><span>x</span><span>),</span><span> </span><span>h</span><span> </span><span>=</span><span> </span><span>thedata</span><span>$</span><span>h</span><span>)</span><span>
</span><span># copy the skeleton of fc1 over for ensembles:
</span><span> </span><span>fc12</span><span> </span><span>&lt;-</span><span> </span><span>fc13</span><span> </span><span>&lt;-</span><span> </span><span>fc14</span><span> </span><span>&lt;-</span><span> </span><span>fc23</span><span> </span><span>&lt;-</span><span> </span><span>fc24</span><span> </span><span>&lt;-</span><span> </span><span>fc34</span><span> </span><span>&lt;-</span><span> </span><span>fc123</span><span> </span><span>&lt;-</span><span> </span><span>fc124</span><span> </span><span>&lt;-</span><span> </span><span>fc134</span><span> </span><span>&lt;-</span><span> </span><span>fc234</span><span> </span><span>&lt;-</span><span> </span><span>fc1234</span><span> </span><span>&lt;-</span><span> </span><span>fc1</span><span>
</span><span># replace the point forecasts with averages of member forecasts:
</span><span> </span><span>fc12</span><span>$</span><span>mean</span><span> </span><span>&lt;-</span><span> </span><span>(</span><span>fc1</span><span>$</span><span>mean</span><span> </span><span>+</span><span> </span><span>fc2</span><span>$</span><span>mean</span><span>)</span><span> </span><span>/</span><span> </span><span>2</span><span>
</span><span>fc13</span><span>$</span><span>mean</span><span> </span><span>&lt;-</span><span> </span><span>(</span><span>fc1</span><span>$</span><span>mean</span><span> </span><span>+</span><span> </span><span>fc3</span><span>$</span><span>mean</span><span>)</span><span> </span><span>/</span><span> </span><span>2</span><span>
</span><span>fc14</span><span>$</span><span>mean</span><span> </span><span>&lt;-</span><span> </span><span>(</span><span>fc1</span><span>$</span><span>mean</span><span> </span><span>+</span><span> </span><span>fc4</span><span>$</span><span>mean</span><span>)</span><span> </span><span>/</span><span> </span><span>2</span><span>
</span><span>fc23</span><span>$</span><span>mean</span><span> </span><span>&lt;-</span><span> </span><span>(</span><span>fc2</span><span>$</span><span>mean</span><span> </span><span>+</span><span> </span><span>fc3</span><span>$</span><span>mean</span><span>)</span><span> </span><span>/</span><span> </span><span>2</span><span>
</span><span>fc24</span><span>$</span><span>mean</span><span> </span><span>&lt;-</span><span> </span><span>(</span><span>fc2</span><span>$</span><span>mean</span><span> </span><span>+</span><span> </span><span>fc4</span><span>$</span><span>mean</span><span>)</span><span> </span><span>/</span><span> </span><span>2</span><span>
</span><span>fc34</span><span>$</span><span>mean</span><span> </span><span>&lt;-</span><span> </span><span>(</span><span>fc3</span><span>$</span><span>mean</span><span> </span><span>+</span><span> </span><span>fc4</span><span>$</span><span>mean</span><span>)</span><span> </span><span>/</span><span> </span><span>2</span><span>
</span><span>fc123</span><span>$</span><span>mean</span><span> </span><span>&lt;-</span><span> </span><span>(</span><span>fc1</span><span>$</span><span>mean</span><span> </span><span>+</span><span> </span><span>fc2</span><span>$</span><span>mean</span><span> </span><span>+</span><span> </span><span>fc3</span><span>$</span><span>mean</span><span>)</span><span> </span><span>/</span><span> </span><span>3</span><span>
</span><span>fc124</span><span>$</span><span>mean</span><span> </span><span>&lt;-</span><span> </span><span>(</span><span>fc1</span><span>$</span><span>mean</span><span> </span><span>+</span><span> </span><span>fc2</span><span>$</span><span>mean</span><span> </span><span>+</span><span> </span><span>fc4</span><span>$</span><span>mean</span><span>)</span><span> </span><span>/</span><span> </span><span>3</span><span>
</span><span>fc134</span><span>$</span><span>mean</span><span> </span><span>&lt;-</span><span> </span><span>(</span><span>fc1</span><span>$</span><span>mean</span><span> </span><span>+</span><span> </span><span>fc3</span><span>$</span><span>mean</span><span> </span><span>+</span><span> </span><span>fc4</span><span>$</span><span>mean</span><span>)</span><span> </span><span>/</span><span> </span><span>3</span><span>
</span><span>fc234</span><span>$</span><span>mean</span><span> </span><span>&lt;-</span><span> </span><span>(</span><span>fc2</span><span>$</span><span>mean</span><span> </span><span>+</span><span> </span><span>fc3</span><span>$</span><span>mean</span><span> </span><span>+</span><span> </span><span>fc4</span><span>$</span><span>mean</span><span>)</span><span> </span><span>/</span><span> </span><span>3</span><span>
</span><span>fc1234</span><span>$</span><span>mean</span><span> </span><span>&lt;-</span><span> </span><span>(</span><span>fc1</span><span>$</span><span>mean</span><span> </span><span>+</span><span> </span><span>fc2</span><span>$</span><span>mean</span><span> </span><span>+</span><span> </span><span>fc3</span><span>$</span><span>mean</span><span> </span><span>+</span><span> </span><span>fc4</span><span>$</span><span>mean</span><span>)</span><span> </span><span>/</span><span> </span><span>4</span><span>
</span><span>mase</span><span> </span><span>&lt;-</span><span> </span><span>c</span><span>(</span><span>accuracy</span><span>(</span><span>fc1</span><span>,</span><span> </span><span>thedata</span><span>$</span><span>xx</span><span>)[</span><span>2</span><span>,</span><span> </span><span>6</span><span>],</span><span>
</span><span>accuracy</span><span>(</span><span>fc2</span><span>,</span><span> </span><span>thedata</span><span>$</span><span>xx</span><span>)[</span><span>2</span><span>,</span><span> </span><span>6</span><span>],</span><span>
</span><span>accuracy</span><span>(</span><span>fc3</span><span>,</span><span> </span><span>thedata</span><span>$</span><span>xx</span><span>)[</span><span>2</span><span>,</span><span> </span><span>6</span><span>],</span><span>
</span><span>accuracy</span><span>(</span><span>fc4</span><span>,</span><span> </span><span>thedata</span><span>$</span><span>xx</span><span>)[</span><span>2</span><span>,</span><span> </span><span>6</span><span>],</span><span>
</span><span>accuracy</span><span>(</span><span>fc12</span><span>,</span><span> </span><span>thedata</span><span>$</span><span>xx</span><span>)[</span><span>2</span><span>,</span><span> </span><span>6</span><span>],</span><span>
</span><span>accuracy</span><span>(</span><span>fc13</span><span>,</span><span> </span><span>thedata</span><span>$</span><span>xx</span><span>)[</span><span>2</span><span>,</span><span> </span><span>6</span><span>],</span><span>
</span><span>accuracy</span><span>(</span><span>fc14</span><span>,</span><span> </span><span>thedata</span><span>$</span><span>xx</span><span>)[</span><span>2</span><span>,</span><span> </span><span>6</span><span>],</span><span>
</span><span>accuracy</span><span>(</span><span>fc23</span><span>,</span><span> </span><span>thedata</span><span>$</span><span>xx</span><span>)[</span><span>2</span><span>,</span><span> </span><span>6</span><span>],</span><span>
</span><span>accuracy</span><span>(</span><span>fc24</span><span>,</span><span> </span><span>thedata</span><span>$</span><span>xx</span><span>)[</span><span>2</span><span>,</span><span> </span><span>6</span><span>],</span><span>
</span><span>accuracy</span><span>(</span><span>fc34</span><span>,</span><span> </span><span>thedata</span><span>$</span><span>xx</span><span>)[</span><span>2</span><span>,</span><span> </span><span>6</span><span>],</span><span>
</span><span>accuracy</span><span>(</span><span>fc123</span><span>,</span><span> </span><span>thedata</span><span>$</span><span>xx</span><span>)[</span><span>2</span><span>,</span><span> </span><span>6</span><span>],</span><span>
</span><span>accuracy</span><span>(</span><span>fc124</span><span>,</span><span> </span><span>thedata</span><span>$</span><span>xx</span><span>)[</span><span>2</span><span>,</span><span> </span><span>6</span><span>],</span><span>
</span><span>accuracy</span><span>(</span><span>fc134</span><span>,</span><span> </span><span>thedata</span><span>$</span><span>xx</span><span>)[</span><span>2</span><span>,</span><span> </span><span>6</span><span>],</span><span>
</span><span>accuracy</span><span>(</span><span>fc234</span><span>,</span><span> </span><span>thedata</span><span>$</span><span>xx</span><span>)[</span><span>2</span><span>,</span><span> </span><span>6</span><span>],</span><span>
</span><span>accuracy</span><span>(</span><span>fc1234</span><span>,</span><span> </span><span>thedata</span><span>$</span><span>xx</span><span>)[</span><span>2</span><span>,</span><span> </span><span>6</span><span>])</span><span>
</span><span>mase</span><span>
</span><span>}</span><span>
</span><span>message</span><span>(</span><span>&quot;Finished fitting models&quot;</span><span>)</span><span>
</span><span>colnames</span><span>(</span><span>mases</span><span>)</span><span> </span><span>&lt;-</span><span> </span><span>c</span><span>(</span><span>&quot;x&quot;</span><span>,</span><span> </span><span>&quot;f&quot;</span><span>,</span><span> </span><span>&quot;a&quot;</span><span>,</span><span> </span><span>&quot;n&quot;</span><span>,</span><span> </span><span>&quot;xf&quot;</span><span>,</span><span> </span><span>&quot;xa&quot;</span><span>,</span><span> </span><span>&quot;xn&quot;</span><span>,</span><span> </span><span>&quot;fa&quot;</span><span>,</span><span> </span><span>&quot;fn&quot;</span><span>,</span><span> </span><span>&quot;an&quot;</span><span>,</span><span>
</span><span>&quot;xfa&quot;</span><span>,</span><span> </span><span>&quot;xfn&quot;</span><span>,</span><span> </span><span>&quot;xan&quot;</span><span>,</span><span> </span><span>&quot;fan&quot;</span><span>,</span><span> </span><span>&quot;xfan&quot;</span><span>)</span><span>
</span><span>return</span><span>(</span><span>mases</span><span>)</span><span>
</span><span>}</span><span>
</span><span>## Test on a small set of data, useful during dev
</span><span>small_collection</span><span> </span><span>&lt;-</span><span> </span><span>list</span><span>(</span><span>tourism</span><span>[[</span><span>1</span><span>]],</span><span> </span><span>tourism</span><span>[[</span><span>2</span><span>]],</span><span> </span><span>tourism</span><span>[[</span><span>3</span><span>]],</span><span> </span><span>tourism</span><span>[[</span><span>4</span><span>]],</span><span> </span><span>tourism</span><span>[[</span><span>5</span><span>]],</span><span> </span><span>tourism</span><span>[[</span><span>6</span><span>]])</span><span>
</span><span>class</span><span>(</span><span>small_collection</span><span>)</span><span> </span><span>&lt;-</span><span> </span><span>&quot;Mcomp&quot;</span><span>
</span><span>test1</span><span> </span><span>&lt;-</span><span> </span><span>competition</span><span>(</span><span>small_collection</span><span>)</span><span>
</span><span>#========Fit models==============
</span><span>system.time</span><span>(</span><span>t</span><span>1</span><span> </span><span>&lt;-</span><span> </span><span>competition</span><span>(</span><span>subset</span><span>(</span><span>tourism</span><span>,</span><span> </span><span>&quot;yearly&quot;</span><span>)))</span><span>
</span><span>system.time</span><span>(</span><span>t</span><span>4</span><span> </span><span>&lt;-</span><span> </span><span>competition</span><span>(</span><span>subset</span><span>(</span><span>tourism</span><span>,</span><span> </span><span>&quot;quarterly&quot;</span><span>)))</span><span>
</span><span>system.time</span><span>(</span><span>t</span><span>12</span><span> </span><span>&lt;-</span><span> </span><span>competition</span><span>(</span><span>subset</span><span>(</span><span>tourism</span><span>,</span><span> </span><span>&quot;monthly&quot;</span><span>)))</span><span>
</span><span># shut down cluster to avoid any mess:
</span><span>stopCluster</span><span>(</span><span>cluster</span><span>)</span><span>
</span><span>#==============present tourism results================
</span><span>results</span><span> </span><span>&lt;-</span><span> </span><span>c</span><span>(</span><span>apply</span><span>(</span><span>t</span><span>1</span><span>,</span><span> </span><span>2</span><span>,</span><span> </span><span>mean</span><span>),</span><span>
</span><span>apply</span><span>(</span><span>t</span><span>4</span><span>,</span><span> </span><span>2</span><span>,</span><span> </span><span>mean</span><span>),</span><span>
</span><span>apply</span><span>(</span><span>t</span><span>12</span><span>,</span><span> </span><span>2</span><span>,</span><span> </span><span>mean</span><span>))</span><span>
</span><span>results_df</span><span> </span><span>&lt;-</span><span> </span><span>data.frame</span><span>(</span><span>MASE</span><span> </span><span>=</span><span> </span><span>results</span><span>)</span><span>
</span><span>results_df</span><span>$</span><span>model</span><span> </span><span>&lt;-</span><span> </span><span>as.character</span><span>(</span><span>names</span><span>(</span><span>results</span><span>))</span><span>
</span><span>periods</span><span> </span><span>&lt;-</span><span> </span><span>c</span><span>(</span><span>&quot;Annual&quot;</span><span>,</span><span> </span><span>&quot;Quarterly&quot;</span><span>,</span><span> </span><span>&quot;Monthly&quot;</span><span>)</span><span>
</span><span>results_df</span><span>$</span><span>Frequency</span><span> </span><span>&lt;-</span><span> </span><span>rep.int</span><span>(</span><span>periods</span><span>,</span><span> </span><span>times</span><span> </span><span>=</span><span> </span><span>c</span><span>(</span><span>15</span><span>,</span><span> </span><span>15</span><span>,</span><span> </span><span>15</span><span>))</span><span>
</span><span>best</span><span> </span><span>&lt;-</span><span> </span><span>results_df</span><span> </span><span>%>%</span><span>
</span><span>group_by</span><span>(</span><span>model</span><span>)</span><span> </span><span>%>%</span><span>
</span><span>summarise</span><span>(</span><span>MASE</span><span> </span><span>=</span><span> </span><span>mean</span><span>(</span><span>MASE</span><span>))</span><span> </span><span>%>%</span><span>
</span><span>arrange</span><span>(</span><span>MASE</span><span>)</span><span> </span><span>%>%</span><span>
</span><span>mutate</span><span>(</span><span>Frequency</span><span> </span><span>=</span><span> </span><span>&quot;Average&quot;</span><span>)</span><span>
</span><span>Tcomp_results</span><span> </span><span>&lt;-</span><span> </span><span>results_df</span><span> </span><span>%>%</span><span>
</span><span>rbind</span><span>(</span><span>best</span><span>)</span><span> </span><span>%>%</span><span>
</span><span>mutate</span><span>(</span><span>model</span><span> </span><span>=</span><span> </span><span>factor</span><span>(</span><span>model</span><span>,</span><span> </span><span>levels</span><span> </span><span>=</span><span> </span><span>best</span><span>$</span><span>model</span><span>))</span><span> </span><span>%>%</span><span>
</span><span>mutate</span><span>(</span><span>Frequency</span><span> </span><span>=</span><span> </span><span>factor</span><span>(</span><span>Frequency</span><span>,</span><span> </span><span>levels</span><span> </span><span>=</span><span> </span><span>c</span><span>(</span><span>&quot;Annual&quot;</span><span>,</span><span> </span><span>&quot;Average&quot;</span><span>,</span><span> </span><span>&quot;Quarterly&quot;</span><span>,</span><span> </span><span>&quot;Monthly&quot;</span><span>)))</span><span>
</span><span>leg</span><span> </span><span>&lt;-</span><span> </span><span>&quot;f: Theta; forecast::thetaf\na: ARIMA; forecast::auto.arima
n: Neural network; forecast::nnetar\nx: Extreme gradient boosting; forecastxgb::xgbts&quot;</span><span>
</span><span>Tcomp_results</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>model</span><span>,</span><span> </span><span>y</span><span> </span><span>=</span><span> </span><span>MASE</span><span>,</span><span> </span><span>colour</span><span> </span><span>=</span><span> </span><span>Frequency</span><span>,</span><span> </span><span>label</span><span> </span><span>=</span><span> </span><span>model</span><span>))</span><span> </span><span>+</span><span>
</span><span>geom_text</span><span>(</span><span>size</span><span> </span><span>=</span><span> </span><span>6</span><span>)</span><span> </span><span>+</span><span>
</span><span>geom_line</span><span>(</span><span>aes</span><span>(</span><span>x</span><span> </span><span>=</span><span> </span><span>as.numeric</span><span>(</span><span>model</span><span>)),</span><span> </span><span>alpha</span><span> </span><span>=</span><span> </span><span>0.25</span><span>)</span><span> </span><span>+</span><span>
</span><span>scale_y_continuous</span><span>(</span><span>&quot;Mean scaled absolute error\n(smaller numbers are better)&quot;</span><span>)</span><span> </span><span>+</span><span>
</span><span>annotate</span><span>(</span><span>&quot;text&quot;</span><span>,</span><span> </span><span>x</span><span> </span><span>=</span><span> </span><span>2</span><span>,</span><span> </span><span>y</span><span> </span><span>=</span><span> </span><span>3.5</span><span>,</span><span> </span><span>label</span><span> </span><span>=</span><span> </span><span>leg</span><span>,</span><span> </span><span>hjust</span><span> </span><span>=</span><span> </span><span>0</span><span>)</span><span> </span><span>+</span><span>
</span><span>ggtitle</span><span>(</span><span>&quot;Average error of four different timeseries forecasting methods\n2010 Tourism Forecasting Competition data&quot;</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;Model, or ensemble of models\n(further to the left means better overall performance)&quot;</span><span>)</span></code></pre>
</figure>
<p><div><div><div><div data-width="55" data-show-faces="false" data-send="true" data-layout="box_count" data-height="62" data-href="https://www.r-bloggers.com/timeseries-forecasting-using-extreme-gradient-boosting/"></div></div><div><a data-url="https://www.r-bloggers.com/timeseries-forecasting-using-extreme-gradient-boosting/" data-counturl="https://www.r-bloggers.com/timeseries-forecasting-using-extreme-gradient-boosting/" data-count="vertical" data-text="Timeseries forecasting using extreme gradient boosting" 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/11/06/forecastxgb"> 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/?s=tutorial">tutorials</a> on topics such as: <a title="Data science" rel="nofollow" href="https://www.r-bloggers.com/?s=data%20science">Data science</a>, <a title="Big Data" rel="nofollow" href="https://www.r-bloggers.com/?s=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/?s=ggplot2">ggplot2</a>, <a title="Boxplots using lattice and ggplot2 tutorials" rel="nofollow" href="https://www.r-bloggers.com/?s=boxplot">Boxplots</a>, <a title="Maps and gis" rel="nofollow" href="https://www.r-bloggers.com/?s=map">maps</a>, <a title="Animation in R" rel="nofollow" href="https://www.r-bloggers.com/?s=animation">animation</a>), programming (<a title="RStudio IDE for R" rel="nofollow" href="https://www.r-bloggers.com/?s=RStudio">RStudio</a>, <a title="Sweave and literate programming" rel="nofollow" href="https://www.r-bloggers.com/?s=sweave">Sweave</a>, <a title="LaTeX in R" rel="nofollow" href="https://www.r-bloggers.com/?s=LaTeX">LaTeX</a>, <a title="SQL and databases" rel="nofollow" href="https://www.r-bloggers.com/?s=SQL">SQL</a>, <a title="Eclipse IDE for R" rel="nofollow" href="https://www.r-bloggers.com/?s=eclipse">Eclipse</a>, <a title="git and github, Version Control System" rel="nofollow" href="https://www.r-bloggers.com/?s=git">git</a>, <a title="Large data in R using Hadoop" rel="nofollow" href="https://www.r-bloggers.com/?s=hadoop">hadoop</a>, <a title="Web Scraping of google, facebook, yahoo, twitter and more using R" rel="nofollow" href="https://www.r-bloggers.com/?s=Web+Scraping">Web Scraping</a>) statistics (<a title="Regressions and ANOVA analysis tutorials" rel="nofollow" href="https://www.r-bloggers.com/?s=regression">regression</a>, <a title="principal component analysis tutorial" rel="nofollow" href="https://www.r-bloggers.com/?s=PCA">PCA</a>, <a title="Time series" rel="nofollow" href="https://www.r-bloggers.com/?s=time+series">time series</a>, <a title="finance trading" rel="nofollow" href="https://www.r-bloggers.com/?s=trading">trading</a>) and more...
<img height="1" alt="" width="1" src="http://feeds.feedburner.com/~r/RBloggers/~4/ZDmcpWn6Dek"></a></div>