<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Archives ARIMA - Open Forecasting</title>
	<atom:link href="https://openforecast.org/tag/arima-en/feed/" rel="self" type="application/rss+xml" />
	<link>https://openforecast.org/tag/arima-en/</link>
	<description>How to look into the future</description>
	<lastBuildDate>Wed, 11 Feb 2026 19:59:54 +0000</lastBuildDate>
	<language>en-GB</language>
	<sy:updatePeriod>
	hourly	</sy:updatePeriod>
	<sy:updateFrequency>
	1	</sy:updateFrequency>
	<generator>https://wordpress.org/?v=6.9.4</generator>

<image>
	<url>https://openforecast.org/wp-content/webpc-passthru.php?src=https://openforecast.org/wp-content/uploads/2015/08/cropped-usd-05-32x32.png&amp;nocache=1</url>
	<title>Archives ARIMA - Open Forecasting</title>
	<link>https://openforecast.org/tag/arima-en/</link>
	<width>32</width>
	<height>32</height>
</image> 
	<item>
		<title>smooth v4.4.0</title>
		<link>https://openforecast.org/2026/02/09/smooth-v4-4-0/</link>
					<comments>https://openforecast.org/2026/02/09/smooth-v4-4-0/#respond</comments>
		
		<dc:creator><![CDATA[Ivan Svetunkov]]></dc:creator>
		<pubDate>Mon, 09 Feb 2026 09:02:21 +0000</pubDate>
				<category><![CDATA[Package smooth for R]]></category>
		<category><![CDATA[R]]></category>
		<category><![CDATA[ADAM]]></category>
		<category><![CDATA[ARIMA]]></category>
		<category><![CDATA[CES]]></category>
		<category><![CDATA[ETS]]></category>
		<category><![CDATA[GUM]]></category>
		<category><![CDATA[smooth]]></category>
		<guid isPermaLink="false">https://openforecast.org/?p=3959</guid>

					<description><![CDATA[<p>Great news, everyone! smooth package for R version 4.4.0 is now on CRAN. Why is this a great news? Let me explain! On this page: What&#8217;s new? Evaluation Setup Results What&#8217;s next? Here is what&#8217;s new since 4.3.0: First, I have worked on tuning the initialisation in adam() in case of backcasting, and improved the [&#8230;]</p>
<p>Message <a href="https://openforecast.org/2026/02/09/smooth-v4-4-0/">smooth v4.4.0</a> first appeared on <a href="https://openforecast.org">Open Forecasting</a>.</p>
]]></description>
										<content:encoded><![CDATA[<p>Great news, everyone! smooth package for R version 4.4.0 is now on CRAN. Why is this a great news? Let me explain!</p>
<p>On this page:</p>
<ul>
<li><a href="#whatsNew">What&#8217;s new?</a></li>
<li><a href="#evaluation">Evaluation</a></li>
<ul>
<li><a href="#evaluationSetup">Setup</a></li>
<li><a href="#evaluationResults">Results</a></li>
</ul>
<li><a href="#whatsNext">What&#8217;s next?</a></li>
</ul>
<h3 id="whatsNew">Here is what&#8217;s new since 4.3.0:</h3>
<p>First, I have worked on tuning the initialisation in <code>adam()</code> in case of backcasting, and improved the <code>msdecompose()</code> function a bit to get more robust results. This was necessary to make sure that when the smoothing parameters are close to zero, initial values would still make sense. This is already in <code>adam</code> (use <code>smoother="global"</code> to test), but will become the default behaviour in the next version of the package, when we iron everything out. This is all a part of a larger work with Kandrika Pritularga on a paper about the initialisation of dynamic models.</p>
<p>Second, I have fixed a long standing issue of the eigenvalues calculation inside the dynamic models, which is applicable only in case of <code>bounds="admissible"</code> and might impact ARIMA, CES and GUM. The parameter restriction are now done consistently across all functions, guaranteeing that they will not fail and will produce stable/invertible estimates of parameters.</p>
<p>Third, I have added the Sparse ARMA function, which constructs ARMA(p,q) of the specific orders, dropping all the elements from 1 to those. e.g. SpARMA(2,3) would have the following form:<br />
\begin{equation*}<br />
y_t = \phi_2 y_{t-2} + \theta_3 \epsilon_{t-3} + \epsilon_{t}<br />
\end{equation*}<br />
This weird model is needed for a project I am working on together with Devon Barrow, Nikos Kourentzes and Yves Sagaert. I&#8217;ll explain more when we get the final draft of the paper.</p>
<p>And something very important, which you will not notice: I refactored the C++ code in the package so that it is available not only for R, but also for Python&#8230; Why? I&#8217;ll explain in the next post :). But this also means that the old functions that relied on the previous generation of the C++ code are now discontinued, and all the smooth functions use the new core. This applies to <code>es()</code>, <code>ssarima()</code>, <code>msarima()</code>, <code>ces()</code>, <code>gum()</code> and <code>sma()</code>. You will not notice any change, except that some of them should become a bit faster and probably more robust. And this also means that all of them will now be able to use methods for the <code>adam()</code> function. For example, the <code>summary()</code> will produce the proper output with standard errors and confidence intervals for all estimated parameters.</p>
<h2 id="evaluation">Evaluation</h2>
<p><strong>DISCLAIMER</strong>: The previous evaluation was for smooth v4.3.0, you can find it <a href="/2025/07/04/smooth-v4-3-0-in-r-what-s-new-and-what-s-next/">here</a>. I have changed one of error measures (sCE to SAME), but the rest is the same, so the results are widely comparable between the versions.</p>
<h3 id="evaluationSetup">The setup</h3>
<p>As usual, in situations like this, I have run the evaluation on the M1, M3 and Tourism competition data. This time, I have added more flavours of the ETS model selection so that you can see how the models pool impacts the forecasting accuracy. Short description:</p>
<ol>
<li>XXX &#8211; select between pure additive ETS models only;</li>
<li>ZZZ &#8211; select from the pool of all 30 models, but use branch-and-bound to kick out the less suitable models;</li>
<li>ZXZ &#8211; same as (2), but without the multiplicative trend models. This is used in the <code>smooth</code> functions <strong>by default</strong>;</li>
<li>FFF &#8211; select from the pool of all 30 models (exhaustive search);</li>
<li>SXS &#8211; the pool of models that is used by default in <code>ets()</code> from the <code>forecast</code> package in R.</li>
</ol>
<p>I also tested three types of the ETS initialisation:</p>
<ol>
<li>Back &#8211; <code>initial="backcasting"</code></li>
<li>Opt &#8211; <code>initial="optimal"</code></li>
<li>Two &#8211; <code>initial="two-stage"</code></li>
</ol>
<p>Backcasting is now the default method of initialisation, and does well in many cases, but I found that optimal initials (if done correctly) help in some difficult situations, as long a you have enough of computational time.</p>
<p>I used two error measures and computational time to check how functions work. The first error measure is called RMSSE (Root Mean Squared Scaled Error) from <a href="http://dx.doi.org/10.1016/j.ijforecast.2021.11.013">M5 competition</a>, motivated by <a href="http://dx.doi.org/10.1016/j.ijforecast.2022.08.003">Athanasopoulos &#038; Kourentzes (2023)</a>:</p>
<p>\begin{equation*}<br />
\mathrm{RMSSE} = \frac{1}{\sqrt{\frac{1}{T-1} \sum_{t=1}^{T-1} \Delta_t^2}} \mathrm{RMSE},<br />
\end{equation*}<br />
where \(\mathrm{RMSE} = \sqrt{\frac{1}{h} \sum_{j=1}^h e^2_{t+j}}\) is the Root Mean Squared Error of the point forecasts, and \(\Delta_t\) is the first differences of the in-sample actual values.</p>
<p>The second measure does not have a standard name in the literature, but the idea of it is to the measure the bias of forecasts and to get rid of the sign to make sure that positively biased forecasts on some time series are not cancelled out by the negative ones on the other ones. I call this measure &#8220;Scaled Absolute Mean Error&#8221; (SAME):</p>
<p>\begin{equation*}<br />
\mathrm{SAME} = \frac{1}{\frac{1}{T-1} \sum_{t=1}^{T-1} |\Delta_t|} \mathrm{AME},<br />
\end{equation*}<br />
where \(\mathrm{AME}= \left| \frac{1}{h} \sum_{j=1}^h e_{t+j} \right|\).</p>
<p>For both of these measures, the lower value is better than the higher one. As for the computational time, I have measured it for each model and each series, and this time I provided distribution of times to better see how methods perform.</p>
<div class="su-spoiler su-spoiler-style-fancy su-spoiler-icon-plus su-spoiler-closed" data-scroll-offset="0" data-anchor-in-url="no"><div class="su-spoiler-title" tabindex="0" role="button"><span class="su-spoiler-icon"></span>Boring code in R</div><div class="su-spoiler-content su-u-clearfix su-u-trim">
<pre class="decode">library(Mcomp)
library(Tcomp)
library(forecast)
library(smooth)

library(doMC)
registerDoMC(detectCores())

# Create a small but neat function that will return a vector of error measures
errorMeasuresFunction <- function(object, holdout, insample){
        holdout <- as.vector(holdout);
        insample <- as.vector(insample);
	# RMSSE and SAME are defined in greybox v2.0.7
        return(c(RMSSE(holdout, object$mean, mean(diff(insample^2)),
                 SAME(holdout, object$mean, mean(abs(diff(insample)))),
                 object$timeElapsed))
}

datasets <- c(M1,M3,tourism)
datasetLength <- length(datasets)

# Method configuration list
# Each method specifies: fn (function name), pkg (package), model, initial,
methodsConfig <- list(
	# ETS and Auto ARIMA from the forecast package in R
	"ETS" = list(fn = "ets", pkg = "forecast", use_x_only = TRUE),
	"Auto ARIMA" = list(fn = "auto.arima", pkg = "forecast", use_x_only = TRUE),
	# ADAM with different initialisation schemes
	"ADAM ETS Back" = list(fn = "adam", pkg = "smooth", model = "ZXZ", initial = "back"),
	"ADAM ETS Opt" = list(fn = "adam", pkg = "smooth", model = "ZXZ", initial = "opt"),
	"ADAM ETS Two" = list(fn = "adam", pkg = "smooth", model = "ZXZ", initial = "two"),
	# ES, which is a wrapper of ADAM. Should give very similar results to ADAM on regular data
	"ES Back" = list(fn = "es", pkg = "smooth", model = "ZXZ", initial = "back"),
	"ES Opt" = list(fn = "es", pkg = "smooth", model = "ZXZ", initial = "opt"),
	"ES Two" = list(fn = "es", pkg = "smooth", model = "ZXZ", initial = "two"),
	# Several flavours for model selection in ES
	"ES XXX" = list(fn = "es", pkg = "smooth", model = "XXX", initial = "back"),
	"ES ZZZ" = list(fn = "es", pkg = "smooth", model = "ZZZ", initial = "back"),
	"ES FFF" = list(fn = "es", pkg = "smooth", model = "FFF", initial = "back"),
	"ES SXS" = list(fn = "es", pkg = "smooth", model = "SXS", initial = "back"),
	# ARIMA implementations in smooth
	"MSARIMA" = list(fn = "auto.msarima", pkg = "smooth", initial = "back"),
	"SSARIMA" = list(fn = "auto.ssarima", pkg = "smooth", initial = "back"),
	# Complex Exponential Smoothing
	"CES" = list(fn = "auto.ces", pkg = "smooth", initial = "back"),
	# Generalised Univeriate Model (experimental)
	"GUM" = list(fn = "auto.gum", pkg = "smooth", initial = "back")
)

methodsNames <- names(methodsConfig)
methodsNumber <- length(methodsNames)

measuresNames <- c("RMSSE","SAME","Time")
measuresNumber <- length(measuresNames)

testResults <- array(NA, c(methodsNumber, datasetLength, measuresNumber),
                     dimnames = list(methodsNames, NULL, measuresNames))

# Unified loop over all methods
for(j in seq_along(methodsConfig)){
	cfg <- methodsConfig[[j]]
	cat("Running method:", methodsNames[j], "\n")

	result <- foreach(i = 1:datasetLength, .combine = "cbind",
	                  .packages = c("smooth", "forecast")) %dopar% {
		startTime <- Sys.time()

		# Build model call based on method type
		if(isTRUE(cfg$use_x_only)){
			# forecast package methods: ets, auto.arima
			test <- do.call(cfg$fn, list(datasets[[i]]$x))
		}else if(cfg$fn %in% c("adam", "es")) {
			# adam and es take dataset and model
			test <- do.call(cfg$fn, list(datasets[[i]], model=cfg$model, initial = cfg$initial))
		}else{
			# auto.msarima, auto.ssarima, auto.ces, auto.gum
			test <- do.call(cfg$fn, list(datasets[[i]], initial = cfg$initial))
		}

		# Build forecast call
		forecast_args <- list(test, h = datasets[[i]]$h)
		testForecast <- do.call(forecast, forecast_args)
		testForecast$timeElapsed <- Sys.time() - startTime

		return(errorMeasuresFunction(testForecast, datasets[[i]]$xx, datasets[[i]]$x))
	}
	testResults[j,,] <- t(result)
}

</pre>
</div></div>
<h3 id="evaluationResults">Results</h3>
<p>And here are the results for the smooth functions in v4.4.0 for R. First, we summarise the RMSSEs. I produce quartiles of distribution of RMSSE together with the mean.</p>
<pre class="decode">cbind(t(apply(testResults[,,"RMSSE"],1,quantile, na.rm=T)),
      mean=apply(testResults[,,"RMSSE"],1,mean)) |> round(4)</pre>
<pre>                  0%    25%    50%    75%      100%   mean
ETS           0.0245 0.6772 1.1806 2.3765   51.6160 1.9697
Auto ARIMA    0.0246 0.6802 1.1790 2.3583   51.6160 1.9864
ADAM ETS Back 0.0183 <strong>0.6647</strong> <strong>1.1620</strong> <strong>2.3023</strong>   <strong>50.2585</strong> <strong>1.9283</strong>
ADAM ETS Opt  0.0242 0.6714 1.1868 2.3623   51.6160 1.9432
ADAM ETS Two  0.0246 0.6690 1.1875 2.3374   51.6160 1.9480
ES Back       0.0183 0.6674 1.1647 2.3164   <strong>50.2585</strong> 1.9292
ES Opt        0.0242 0.6740 1.1858 2.3644   51.6160 1.9469
ES Two        0.0245 0.6717 1.1874 2.3463   51.6160 1.9538
ES XXX        0.0183 0.6777 1.1708 2.3062   <strong>50.2585</strong> 1.9613
ES ZZZ        <strong>0.0108</strong> 0.6682 1.1816 2.3611  201.4959 2.0841
ES FFF        0.0145 0.6795 1.2170 2.4575 5946.1858 3.3033
ES SXS        0.0183 0.6754 1.1709 2.3539   <strong>50.2585</strong> 1.9448
MSARIMA       0.0278 0.6988 1.1898 2.4208   51.6160 2.0750
SSARIMA       0.0277 0.7371 1.2544 2.4425   51.6160 2.0625
CES Back      0.0450 0.6761 1.1741 2.3205   51.0571 1.9650
GUM Back      0.0333 0.7077 1.2073 2.4533   51.6184 2.0461
</pre>
<p>The worst performing models are the ETS with the multiplicative trend (ES ZZZ and ES FFF). This is because there are outliers in some time series, and the multiplicative trend reacts to them by amending the trend value to something large (e.g. 2, i.e. twice increase in level for each step), and then can never return to a reasonable level (see explanation of this phenomenon in <a href="https://openforecast.org/adam/ADAMETSMultiplicativeAlternative.html">Section 6.6 of ADAM book</a>). As expected, ADAM ETS does very similar to the ES, and we can see that the default initialisation (backcasting) is pretty good in terms of RMSSE values. To be fair, if the models are tested on a different dataset, it might be the case that the optimal initialisation would do better.</p>
<p>Here is a table with the SAME results:</p>
<pre class="decode">cbind(t(apply(testResults[,,"SAME"],1,quantile, na.rm=T)),
      mean=apply(testResults[,,"SAME"],1,mean)) |> round(4)</pre>
<pre>                 0%    25%    50%    75%      100%   mean
ETS           8e-04 0.3757 1.0203 2.5097   54.6872 1.9983
Auto ARIMA    <strong>0e+00</strong> 0.3992 1.0429 2.4565   53.2710 2.0446
ADAM ETS Back 1e-04 0.3752 0.9965 <strong>2.4047</strong>   <strong>52.3418</strong> 1.9518
ADAM ETS Opt  5e-04 0.3733 1.0212 2.4848   55.1018 1.9618
ADAM ETS Two  8e-04 0.3780 1.0316 2.4511   55.1019 1.9712
ES Back       <strong>0e+00</strong> 0.3733 <strong>0.9945</strong> 2.4122   53.4504 <strong>1.9485</strong>
ES Opt        2e-04 <strong>0.3727</strong> 1.0255 2.4756   54.6860 1.9673
ES Two        1e-04 0.3855 1.0323 2.4535   54.6856 1.9799
ES XXX        1e-04 0.3733 1.0050 2.4257   53.1697 1.9927
ES ZZZ        3e-04 0.3824 1.0135 2.4885  229.7626 2.1376
ES FFF        3e-04 0.3972 1.0489 2.6042 3748.4268 2.9501
ES SXS        6e-04 0.3750 1.0125 2.4627   53.4504 1.9725
MSARIMA       1e-04 0.3960 1.0094 2.5409   54.7916 2.1227
SSARIMA       1e-04 0.4401 1.1222 2.5673   52.5023 2.1248
CES Back      6e-04 0.3767 1.0079 2.4085   54.9026 2.0052
GUM Back      0e+00 0.3803 1.0575 2.6259   63.0637 2.0858
</pre>
<p>In terms of bias, smooth implementations of ETS are doing well again, and we can see the same issue with the multiplicative trend here as before. Another thing to note is that MSARIMA and SSARIMA are not as good as the Auto ARIMA from the forecast package on these datasets in terms of RMSSE and SAME (at least, in terms of mean error measures). And actually, GUM and CES are now better than those in terms of both error measures.</p>
<p>Finally, here is a table with the computational time:</p>
<pre class="decode">cbind(t(apply(testResults[,,"Time"],1,quantile, na.rm=T)),
      mean=apply(testResults[,,"Time"],1,mean)) |> round(4)</pre>
<pre>                  0%    25%    50%     75%    100%   mean
ETS           <strong>0.0032</strong> <strong>0.0117</strong> 0.1660  0.6728  1.6400 0.3631
Auto ARIMA    0.0100 0.1184 0.3618  1.0548 54.3652 1.4760
ADAM ETS Back 0.0162 0.1062 0.1854  0.4022  2.5109 0.2950
ADAM ETS Opt  0.0319 0.1920 0.3103  0.6792  3.8933 0.5368
ADAM ETS Two  0.0427 0.2548 0.4035  0.8567  3.7178 0.6331
ES Back       0.0153 0.0896 <strong>0.1521</strong>  0.3335  2.1128 0.2476
ES Opt        0.0303 0.1667 0.2565  0.5910  3.5887 0.4522
ES Two        0.0483 0.2561 0.4016  0.8626  3.5892 0.6309
MSARIMA Back  0.0614 0.3418 0.6947  0.9868  3.9677 0.7534
SSARIMA Back  0.0292 0.2963 0.8988  2.1729 13.7635 1.6581
CES Back      0.0146 0.0400 0.1834  <strong>0.2298</strong>  <strong>1.2099</strong> <strong>0.1713</strong>
GUM Back      0.0165 0.2101 1.5221  3.0543  9.5380 1.9506

# Separate table for special pools of ETS.
# The time is proportional to the number of models here
=========================================================
                  0%    25%    50%     75%    100%   mean
ES XXX        0.0114 0.0539 0.0782  0.1110  0.8163 0.0859
ES ZZZ        0.0147 0.1371 0.2690  0.4947  2.2049 0.3780
ES FFF        0.0529 0.2775 1.1539  1.5926  3.8552 1.1231
ES SXS        0.0323 0.1303 0.4491  0.6013  2.2170 0.4581
</pre>
<p><em><br />
I have manually moved the specific ES model pools flavours below because there is no point in comparing their computational time with the time of the others (they have different pools of models and thus are not really comparable with the rest).</em></p>
<p>What we can see from this, is that the ES with backcasting is faster in comparison with the other models in this setting (in terms of mean and median computational time). CES is very fast in terms of mean computational time, which is probably because of the very short pool of models to choose from (only four). SSARIMA is pretty slow, which is due to the nature of its order selection algorithm (I don't plan to update it any time soon, but if someone wants to contribute - let me know). But the interesting thing is that Auto ARIMA, while being relatively fine in terms of median time, has the highest maximum one, meaning that for some time series, it failed for some unknown reason. The series that caused the biggest issue for Auto ARIMA is N389 from the M1 competition. I'm not sure what the issue was, and I don't have time to investigate this.</p>
<div id="attachment_4002" style="width: 310px" class="wp-caption aligncenter"><a href="https://openforecast.org/wp-content/webpc-passthru.php?src=https://openforecast.org/wp-content/uploads/2026/02/smoot-4-4-0-time-vs-RMSSE.png&amp;nocache=1"><img fetchpriority="high" decoding="async" aria-describedby="caption-attachment-4002" src="https://openforecast.org/wp-content/webpc-passthru.php?src=https://openforecast.org/wp-content/uploads/2026/02/smoot-4-4-0-time-vs-RMSSE-300x180.png&amp;nocache=1" alt="Mean computational time vs mean RMSSE" width="300" height="180" class="size-medium wp-image-4002" srcset="https://openforecast.org/wp-content/webpc-passthru.php?src=https://openforecast.org/wp-content/uploads/2026/02/smoot-4-4-0-time-vs-RMSSE-300x180.png&amp;nocache=1 300w, https://openforecast.org/wp-content/webpc-passthru.php?src=https://openforecast.org/wp-content/uploads/2026/02/smoot-4-4-0-time-vs-RMSSE-768x461.png&amp;nocache=1 768w, https://openforecast.org/wp-content/webpc-passthru.php?src=https://openforecast.org/wp-content/uploads/2026/02/smoot-4-4-0-time-vs-RMSSE.png&amp;nocache=1 1000w" sizes="(max-width: 300px) 100vw, 300px" /></a><p id="caption-attachment-4002" class="wp-caption-text">Mean computational time vs mean RMSSE</p></div>
<p>Comparing the mean computational time with mean RMSSE value (image above), it looks like the overall tendency in the <code>smooth</code> + <code>forecast</code> functions for the M1, M3 and Tourism datasets is that additional computational time does not improve the accuracy. But it also looks like a simpler pool of pure additive models (ETS(X,X,X)) harms the accuracy in comparison with the branch-and-bound based one of the default <code>model="ZXZ"</code>. There seems to be a sweet spot in terms of the pool of models to choose from (no multiplicative trend, allow mixed models). This aligns well with the papers of <a href="https://doi.org/10.1080/01605682.2024.2421339">Petropoulos et al. (2025)</a>, who investigated the accuracy of arbitrary short pools of models and <a href="https://doi.org/10.1016/j.ijpe.2018.05.019">Kourentzes et al. (2019)</a>, who showed how pooling (if done correctly) can improve the accuracy on average.</p>
<h3 id="whatsNext">What's next?</h3>
<p>For R, the main task now is to rewrite the <code>oes()</code> function and substitute it with the <code>om()</code> one - "Occurrence Model". This should be equivalent to <code>adam()</code> in functionality, allowing to introduce ETS, ARIMA and explanatory variables for the occurrence part of the model. This is a huge work, which I hope to progress slowly throughout the 2026 and finish by the end of the year. Doing that will also allow me removing the last bits of the old C++ code and switch to the ADAM core completely, introducing more functionality for capturing patterns on intermittent demand. The minor task, is to test the <code>smoother="global"</code> more for the ETS initialisation and roll it out as the default in the next release for both R and Python.</p>
<p>For Python,... What Python? Ah! You'll see soon :)</p>
<p>Message <a href="https://openforecast.org/2026/02/09/smooth-v4-4-0/">smooth v4.4.0</a> first appeared on <a href="https://openforecast.org">Open Forecasting</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://openforecast.org/2026/02/09/smooth-v4-4-0/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>smooth v4.3.0 in R: what&#8217;s new and what&#8217;s next?</title>
		<link>https://openforecast.org/2025/07/04/smooth-v4-3-0-in-r-what-s-new-and-what-s-next/</link>
					<comments>https://openforecast.org/2025/07/04/smooth-v4-3-0-in-r-what-s-new-and-what-s-next/#respond</comments>
		
		<dc:creator><![CDATA[Ivan Svetunkov]]></dc:creator>
		<pubDate>Fri, 04 Jul 2025 10:02:17 +0000</pubDate>
				<category><![CDATA[Package smooth for R]]></category>
		<category><![CDATA[R]]></category>
		<category><![CDATA[ADAM]]></category>
		<category><![CDATA[ARIMA]]></category>
		<category><![CDATA[CES]]></category>
		<category><![CDATA[ETS]]></category>
		<category><![CDATA[GUM]]></category>
		<category><![CDATA[smooth]]></category>
		<guid isPermaLink="false">https://openforecast.org/?p=3898</guid>

					<description><![CDATA[<p>Good news! The smooth package v4.3.0 is now on CRAN. And there are several things worth mentioning, so I have written this post. New default initialisation mechanism Since the beginning of the package, the smooth functions supported three ways for initialising the state vector (the vector that includes level, trend, seasonal indices): optimisation, backcasting and [&#8230;]</p>
<p>Message <a href="https://openforecast.org/2025/07/04/smooth-v4-3-0-in-r-what-s-new-and-what-s-next/">smooth v4.3.0 in R: what&#8217;s new and what&#8217;s next?</a> first appeared on <a href="https://openforecast.org">Open Forecasting</a>.</p>
]]></description>
										<content:encoded><![CDATA[<p>Good news! The smooth package v4.3.0 is now on CRAN. And there are several things worth mentioning, so I have written this post.</p>
<h3>New default initialisation mechanism</h3>
<p>Since the beginning of the package, the <code>smooth</code> functions supported three ways for initialising the state vector (the vector that includes level, trend, seasonal indices): optimisation, backcasting and values provided by user. The former has been considered the standard way of estimating ETS, while the backcasting was originally proposed by Box &#038; Jenkins (1970) and was only implemented in the <code>smooth</code> (at least, I haven&#8217;t seen it anywhere else). The main advantage of the latter is in computational time, because you do not need to estimate every single value of the state vector. The new ADAM core that I developed during COVID lockdown, had some improvements for the backcasting, and I noticed that <code>adam()</code> produced more accurate forecasts with it than with the optimisation. But I needed more testing, so I have not changed anything back then.</p>
<p>However, my recent work with Kandrika Pritularga on capturing uncertainty in ETS, have demonstrated that backcasting solves some fundamental problems with the variance of states &#8211; the optimisation cannot handle so many parameters, and asymptotic properties of ETS do not make sense in that case (we&#8217;ll release the paper as soon as we finish the experiments). So, with this evidence on hands and additional tests, I have made a decision to switch from the optimisation to backcasting as the default initialisation mechanism for all the <strong>smooth</strong> functions.</p>
<p>The final users should not feel much difference, but it should work faster now and (hopefully) more accurately. If this is not the case, please get in touch or <a href="https://github.com/config-i1/smooth/issues">file an issue on github</a>.</p>
<p>Also, rest assured the <code>initial="optimal"</code> is available and will stay available as an option in all the <code>smooth</code> functions, so, you can always switch back to it if you don&#8217;t like backcasting.</p>
<p>Finally, I have introduce a new initialisation mechanism called &#8220;two-stage&#8221;, the idea of which is to apply backcasting first and then to optimise the obtained state values. It is slower, but is supposed to be better than the standard optimisation.</p>
<h3>ADAM core</h3>
<p>Every single function in the <code>smooth</code> package now uses ADAM C++ core, and the old core will be discontinued starting from v4.5.0 of the package. This applies to the functions: <code>es()</code>, <code>ssarima()</code>, <code>msarima()</code>, <code>ces()</code>, <code>gum()</code>, <code>sma()</code>. There are now the legacy versions of these functions in the package with the prefix &#8220;_old&#8221; (e.g. <code>es_old()</code>), which will be removed in the smooth v4.5.0. The new engine also helped <code>ssarima()</code>, which now became slightly more accurate than before. Unfortunately, there are still some issues with the initialisation of the seasonal <code>ssarima()</code>, which I have failed to solve completely. But I hope that over time this will be resolved as well.</p>
<h3>smooth performance update</h3>
<p>I have applied all the smooth functions together with the <code>ets()</code> and <code>auto.arima()</code> from the <code>forecast</code> package to the M1, M3 and Tourism competition data and have measured their performances in terms of RMSSE, scaled Cumulative Error (sCE) and computational time. I used the following R code for that:</p>
<div class="su-spoiler su-spoiler-style-fancy su-spoiler-icon-plus su-spoiler-closed" data-scroll-offset="0" data-anchor-in-url="no"><div class="su-spoiler-title" tabindex="0" role="button"><span class="su-spoiler-icon"></span>Long and boring code in R</div><div class="su-spoiler-content su-u-clearfix su-u-trim">
<pre class="decode">library(Mcomp)
library(Tcomp)

library(forecast)
library(smooth)

# I work on Linux and use doMC. Substitute this with doParallel if you use Windows
library(doMC)
registerDoMC(detectCores())

# Create a small but neat function that will return a vector of error measures
errorMeasuresFunction <- function(object, holdout, insample){
	holdout <- as.vector(holdout);
	insample <- as.vector(insample);
	return(c(measures(holdout, object$mean, insample),
			 mean(holdout < object$upper &#038; holdout > object$lower),
			 mean(object$upper-object$lower)/mean(insample),
			 pinball(holdout, object$upper, 0.975)/mean(insample),
			 pinball(holdout, object$lower, 0.025)/mean(insample),
			 sMIS(holdout, object$lower, object$upper, mean(insample),0.95),
			 object$timeElapsed))
}

# Datasets to use
datasets <- c(M1,M3,tourism)
datasetLength <- length(datasets)
# Types of models to try
methodsNames <- c("ETS", "Auto ARIMA",
				  "ADAM ETS Back", "ADAM ETS Opt", "ADAM ETS Two",
				  "ES Back", "ES Opt", "ES Two",
				  "ADAM ARIMA Back", "ADAM ARIMA Opt", "ADAM ARIMA Two",
				  "MSARIMA Back", "MSARIMA Opt", "MSARIMA Two",
				  "SSARIMA Back", "SSARIMA Opt", "SSARIMA Two",
				  "CES Back", "CES Opt", "CES Two",
				  "GUM Back", "GUM Opt", "GUM Two");
methodsNumber <- length(methodsNames);
test <- adam(datasets[[125]]);

testResults20250603 <- array(NA,c(methodsNumber,datasetLength,length(test$accuracy)+6),
                             dimnames=list(methodsNames, NULL,
                                           c(names(test$accuracy),
                                             "Coverage","Range",
                                             "pinballUpper","pinballLower","sMIS",
                                             "Time")));

#### ETS from forecast package ####
j <- 1;
result <- foreach(i=1:datasetLength, .combine="cbind", .packages="forecast") %dopar% {
  startTime <- Sys.time()
  test <- ets(datasets[[i]]$x);
  testForecast <- forecast(test, h=datasets[[i]]$h, level=95);
  testForecast$timeElapsed <- Sys.time() - startTime;
  return(errorMeasuresFunction(testForecast, datasets[[i]]$xx, datasets[[i]]$x));
}
testResults20250603[j,,] <- t(result);

#### AUTOARIMA ####
j <- 2;
result <- foreach(i=1:datasetLength, .combine="cbind", .packages="forecast") %dopar% {
    startTime <- Sys.time()
    test <- auto.arima(datasets[[i]]$x);
    testForecast <- forecast(test, h=datasets[[i]]$h, level=95);
    testForecast$timeElapsed <- Sys.time() - startTime;
    return(errorMeasuresFunction(testForecast, datasets[[i]]$xx, datasets[[i]]$x));
}
testResults20250603[j,,] <- t(result);

#### ADAM ETS Backcasting ####
j <- 3;
result <- foreach(i=1:datasetLength, .combine="cbind", .packages="smooth") %dopar% {
  startTime <- Sys.time()
  test <- adam(datasets[[i]],"ZXZ", initial="back");
  testForecast <- forecast(test, h=datasets[[i]]$h, interval="pred");
  testForecast$timeElapsed <- Sys.time() - startTime;
  return(errorMeasuresFunction(testForecast, datasets[[i]]$xx, datasets[[i]]$x));
}
testResults20250603[j,,] <- t(result);

#### ADAM ETS Optimal ####
j <- 4;
result <- foreach(i=1:datasetLength, .combine="cbind", .packages="smooth") %dopar% {
  startTime <- Sys.time()
  test <- adam(datasets[[i]],"ZXZ", initial="opt");
  testForecast <- forecast(test, h=datasets[[i]]$h, interval="pred");
  testForecast$timeElapsed <- Sys.time() - startTime;
  return(errorMeasuresFunction(testForecast, datasets[[i]]$xx, datasets[[i]]$x));
}
testResults20250603[j,,] <- t(result);

#### ADAM ETS Two-stage ####
j <- 5;
result <- foreach(i=1:datasetLength, .combine="cbind", .packages="smooth") %dopar% {
  startTime <- Sys.time()
  test <- adam(datasets[[i]],"ZXZ", initial="two");
  testForecast <- forecast(test, h=datasets[[i]]$h, interval="pred");
  testForecast$timeElapsed <- Sys.time() - startTime;
  return(errorMeasuresFunction(testForecast, datasets[[i]]$xx, datasets[[i]]$x));
}
testResults20250603[j,,] <- t(result);

#### ES Backcasting ####
j <- 6;
result <- foreach(i=1:datasetLength, .combine="cbind", .packages="smooth") %dopar% {
  startTime <- Sys.time()
  test <- es(datasets[[i]],"ZXZ", initial="back");
  testForecast <- forecast(test, h=datasets[[i]]$h, interval="parametric");
  testForecast$timeElapsed <- Sys.time() - startTime;
  return(errorMeasuresFunction(testForecast, datasets[[i]]$xx, datasets[[i]]$x));
}
testResults20250603[j,,] <- t(result);

#### ES Optimal ####
j <- 7;
result <- foreach(i=1:datasetLength, .combine="cbind", .packages="smooth") %dopar% {
  startTime <- Sys.time()
  test <- es(datasets[[i]],"ZXZ", initial="opt");
  testForecast <- forecast(test, h=datasets[[i]]$h, interval="parametric");
  testForecast$timeElapsed <- Sys.time() - startTime;
  return(errorMeasuresFunction(testForecast, datasets[[i]]$xx, datasets[[i]]$x));
}
testResults20250603[j,,] <- t(result);

#### ES Two-stage ####
j <- 8;
result <- foreach(i=1:datasetLength, .combine="cbind", .packages="smooth") %dopar% {
  startTime <- Sys.time()
  test <- es(datasets[[i]],"ZXZ", initial="two");
  testForecast <- forecast(test, h=datasets[[i]]$h, interval="parametric");
  testForecast$timeElapsed <- Sys.time() - startTime;
  return(errorMeasuresFunction(testForecast, datasets[[i]]$xx, datasets[[i]]$x));
}
testResults20250603[j,,] <- t(result);

#### ADAM ARIMA Backcasting ####
j <- 9;
result <- foreach(i=1:datasetLength, .combine="cbind", .packages="smooth") %dopar% {
  startTime <- Sys.time()
  test <- auto.adam(datasets[[i]], "NNN", initial="back", distribution=c("dnorm"));
  testForecast <- forecast(test, h=datasets[[i]]$h, interval="pred");
  testForecast$timeElapsed <- Sys.time() - startTime;
  return(errorMeasuresFunction(testForecast, datasets[[i]]$xx, datasets[[i]]$x));
}
testResults20250603[j,,] <- t(result);

#### ADAM ARIMA Optimal ####
j <- 10;
result <- foreach(i=1:datasetLength, .combine="cbind", .packages="smooth") %dopar% {
  startTime <- Sys.time()
  test <- auto.adam(datasets[[i]], "NNN", initial="opt", distribution=c("dnorm"));
  testForecast <- forecast(test, h=datasets[[i]]$h, interval="pred");
  testForecast$timeElapsed <- Sys.time() - startTime;
  return(errorMeasuresFunction(testForecast, datasets[[i]]$xx, datasets[[i]]$x));
}
testResults20250603[j,,] <- t(result);

#### ADAM ARIMA Two-stage ####
j <- 11;
result <- foreach(i=1:datasetLength, .combine="cbind", .packages="smooth") %dopar% {
  startTime <- Sys.time()
  test <- auto.adam(datasets[[i]], "NNN", initial="two", distribution=c("dnorm"));
  testForecast <- forecast(test, h=datasets[[i]]$h, interval="pred");
  testForecast$timeElapsed <- Sys.time() - startTime;
  return(errorMeasuresFunction(testForecast, datasets[[i]]$xx, datasets[[i]]$x));
}
testResults20250603[j,,] <- t(result);

#### MSARIMA Backcasting ####
j <- 12;
result <- foreach(i=1:datasetLength, .combine="cbind", .packages="smooth") %dopar% {
  startTime <- Sys.time()
  test <- auto.msarima(datasets[[i]], initial="back");
  testForecast <- forecast(test, h=datasets[[i]]$h, interval="parametric");
  testForecast$timeElapsed <- Sys.time() - startTime;
  return(errorMeasuresFunction(testForecast, datasets[[i]]$xx, datasets[[i]]$x));
}
testResults20250603[j,,] <- t(result);

#### MSARIMA Optimal ####
j <- 13;
result <- foreach(i=1:datasetLength, .combine="cbind", .packages="smooth") %dopar% {
  startTime <- Sys.time()
  test <- auto.msarima(datasets[[i]], initial="opt");
  testForecast <- forecast(test, h=datasets[[i]]$h, interval="parametric");
  testForecast$timeElapsed <- Sys.time() - startTime;
  return(errorMeasuresFunction(testForecast, datasets[[i]]$xx, datasets[[i]]$x));
}
testResults20250603[j,,] <- t(result);

#### MSARIMA Two-stage ####
j <- 14;
result <- foreach(i=1:datasetLength, .combine="cbind", .packages="smooth") %dopar% {
  startTime <- Sys.time()
  test <- auto.msarima(datasets[[i]], initial="two");
  testForecast <- forecast(test, h=datasets[[i]]$h, interval="parametric");
  testForecast$timeElapsed <- Sys.time() - startTime;
  return(errorMeasuresFunction(testForecast, datasets[[i]]$xx, datasets[[i]]$x));
}
testResults20250603[j,,] <- t(result);

#### SSARIMA Backcasting ####
j <- 15;
result <- foreach(i=1:datasetLength, .combine="cbind", .packages="smooth") %dopar% {
  startTime <- Sys.time()
  test <- auto.ssarima(datasets[[i]], initial="back");
  testForecast <- forecast(test, h=datasets[[i]]$h, interval="parametric");
  testForecast$timeElapsed <- Sys.time() - startTime;
  return(errorMeasuresFunction(testForecast, datasets[[i]]$xx, datasets[[i]]$x));
}
testResults20250603[j,,] <- t(result);

#### SSARIMA Optimal ####
j <- 16;
result <- foreach(i=1:datasetLength, .combine="cbind", .packages="forecast") %dopar% {
    startTime <- Sys.time()
    test <- auto.ssarima(datasets[[i]], initial="opt");
    testForecast <- forecast(test, h=datasets[[i]]$h, interval="parametric");
    testForecast$timeElapsed <- Sys.time() - startTime;
    return(errorMeasuresFunction(testForecast, datasets[[i]]$xx, datasets[[i]]$x));
}
testResults20250603[j,,] <- t(result);

#### SSARIMA Two-stage ####
j <- 17;
result <- foreach(i=1:datasetLength, .combine="cbind", .packages="forecast") %dopar% {
    startTime <- Sys.time()
    test <- auto.ssarima(datasets[[i]], initial="two");
    testForecast <- forecast(test, h=datasets[[i]]$h, interval="parametric");
    testForecast$timeElapsed <- Sys.time() - startTime;
    return(errorMeasuresFunction(testForecast, datasets[[i]]$xx, datasets[[i]]$x));
}
testResults20250603[j,,] <- t(result);

#### CES Backcasting ####
j <- 18;
result <- foreach(i=1:datasetLength, .combine="cbind", .packages="smooth") %dopar% {
  startTime <- Sys.time()
  test <- auto.ces(datasets[[i]], initial="back");
  testForecast <- forecast(test, h=datasets[[i]]$h, interval="parametric");
  testForecast$timeElapsed <- Sys.time() - startTime;
  return(errorMeasuresFunction(testForecast, datasets[[i]]$xx, datasets[[i]]$x));
}
testResults20250603[j,,] <- t(result);

#### CES Optimal ####
j <- 19;
result <- foreach(i=1:datasetLength, .combine="cbind", .packages="smooth") %dopar% {
  startTime <- Sys.time()
  test <- auto.ces(datasets[[i]], initial="opt");
  testForecast <- forecast(test, h=datasets[[i]]$h, interval="parametric");
  testForecast$timeElapsed <- Sys.time() - startTime;
  return(errorMeasuresFunction(testForecast, datasets[[i]]$xx, datasets[[i]]$x));
}
testResults20250603[j,,] <- t(result);

#### CES Two-stage ####
j <- 20;
result <- foreach(i=1:datasetLength, .combine="cbind", .packages="smooth") %dopar% {
  startTime <- Sys.time()
  test <- auto.ces(datasets[[i]], initial="two");
  testForecast <- forecast(test, h=datasets[[i]]$h, interval="parametric");
  testForecast$timeElapsed <- Sys.time() - startTime;
  return(errorMeasuresFunction(testForecast, datasets[[i]]$xx, datasets[[i]]$x));
}
testResults20250603[j,,] <- t(result);

#### GUM Backcasting ####
j <- 21;
result <- foreach(i=1:datasetLength, .combine="cbind", .packages="smooth") %dopar% {
  startTime <- Sys.time()
  test <- auto.gum(datasets[[i]], initial="back");
  testForecast <- forecast(test, h=datasets[[i]]$h, interval="parametric");
  testForecast$timeElapsed <- Sys.time() - startTime;
  return(errorMeasuresFunction(testForecast, datasets[[i]]$xx, datasets[[i]]$x));
}
testResults20250603[j,,] <- t(result);

#### GUM Optimal ####
j <- 22;
result <- foreach(i=1:datasetLength, .combine="cbind", .packages="smooth") %dopar% {
  startTime <- Sys.time()
  test <- auto.gum(datasets[[i]], initial="opt");
  testForecast <- forecast(test, h=datasets[[i]]$h, interval="parametric");
  testForecast$timeElapsed <- Sys.time() - startTime;
  return(errorMeasuresFunction(testForecast, datasets[[i]]$xx, datasets[[i]]$x));
}
testResults20250603[j,,] <- t(result);

#### GUM Two-stage ####
j <- 23;
result <- foreach(i=1:datasetLength, .combine="cbind", .packages="smooth") %dopar% {
  startTime <- Sys.time()
  test <- auto.gum(datasets[[i]], initial="two");
  testForecast <- forecast(test, h=datasets[[i]]$h, interval="parametric");
  testForecast$timeElapsed <- Sys.time() - startTime;
  return(errorMeasuresFunction(testForecast, datasets[[i]]$xx, datasets[[i]]$x));
}
testResults20250603[j,,] <- t(result);</pre>
<p># Summary of results<br />
cbind(t(apply(testResults20250603[c(1:8,12:23),,"RMSSE"],1,quantile)),<br />
	  mean=apply(testResults20250603[c(1:8,12:23),,"RMSSE"],1,mean),<br />
	  sCE=apply(testResults20250603[c(1:8,12:23),,"sCE"],1,mean),<br />
	  Time=apply(testResults20250603[c(1:8,12:23),,"Time"],1,mean)) |> round(3)<br />
</div></div>
<p>The table below shows the distribution of RMSSE, the mean sCE and mean Time. The boldface shows the best performing model.</p>
<pre>                    min   Q1  median   Q3     max  mean    sCE  Time
ETS                0.024 0.677 1.181 2.376  51.616 1.970  0.299 0.385
Auto ARIMA         0.025 0.680 1.179 2.358  51.616 1.986  0.124 1.467

ADAM ETS Back      <strong>0.015</strong> <strong>0.666</strong> 1.175 <strong>2.276</strong>  51.616 <strong>1.921</strong>  0.470 0.218
ADAM ETS Opt       0.020 <strong>0.666</strong> 1.190 2.311  51.616 1.937  0.299 0.432
ADAM ETS Two       0.025 <strong>0.666</strong> 1.179 2.330  51.616 1.951  0.330 0.579

ES Back            <strong>0.015</strong> 0.672 <strong>1.174</strong> 2.284  51.616 <strong>1.921</strong>  0.464 0.219
ES Opt             0.020 0.672 1.186 2.316  51.616 1.943  0.302 0.497
ES Two             0.024 0.668 1.181 2.346  51.616 1.952  0.346 0.562

MSARIMA Back       0.025 0.710 1.188 2.383  51.616 2.028  <strong>0.067</strong> 0.780
MSARIMA Opt        0.025 0.724 1.242 2.489  51.616 2.083  0.088 1.905
MSARIMA Two        0.025 0.718 1.250 2.485  51.906 2.075  0.083 2.431

SSARIMA Back       0.045 0.738 1.248 2.383  51.616 2.063  0.167 1.747
SSARIMA Opt        0.025 0.774 1.292 2.413  51.616 2.040  0.178 7.324
SSARIMA Two        0.025 0.742 1.241 2.414  51.616 2.027  0.183 8.096

CES Back           0.046 0.695 1.189 2.355  51.342 1.981  0.125 <strong>0.185</strong>
CES Opt            0.030 0.698 1.218 2.327  <strong>49.480</strong> 2.001 -0.135 0.834
CES Two            0.025 0.696 1.207 2.343  51.242 1.993 -0.078 1.006

GUM Back           0.046 0.707 1.215 2.399  51.134 2.049 -0.285 3.575
GUM Opt            0.026 0.795 1.381 2.717 240.143 2.932 -0.549 4.668
GUM Two            0.026 0.803 1.406 2.826 240.143 3.041 -0.593 4.703</pre>
<p>Several notes:</p>
<ul>
<li>ES is a wrapper of ADAM ETS. The main difference between them is that the latter uses the Gamma distribution for the multiplicative error models, while the former relies on the Normal one.</li>
<li>MSARIMA is a wrapper for ADAM ARIMA, which is why I don't report the latter in the results.</li>
</ul>
<p>One thing you can notice from the output above, is that the models with backcasting consistently produce more accurate forecasts across all measures. I explain this with the idea that they tend not to overfit the data as much as the optimal initialisation does.</p>
<p>To see the stochastic dominance of the forecasting models, I conducted the modification of the MCB/Nemenyi test, explained in <a href="/2020/08/17/accuracy-of-forecasting-methods-can-you-tell-the-difference/">this post</a>:</p>
<pre class="decode">par(mar=c(10,3,4,1))
greybox::rmcb(t(testResults20250603[c(1:8,12:23),,"RMSSE"]), outplot="mcb")</pre>
<div id="attachment_3908" style="width: 310px" class="wp-caption aligncenter"><a href="https://openforecast.org/wp-content/webpc-passthru.php?src=https://openforecast.org/wp-content/uploads/2025/07/2025-07-04-smooth-v4-3-0.png&amp;nocache=1"><img decoding="async" aria-describedby="caption-attachment-3908" src="https://openforecast.org/wp-content/webpc-passthru.php?src=https://openforecast.org/wp-content/uploads/2025/07/2025-07-04-smooth-v4-3-0-300x175.png&amp;nocache=1" alt="Nemenyi test for the smooth functions" width="300" height="175" class="size-medium wp-image-3908" srcset="https://openforecast.org/wp-content/webpc-passthru.php?src=https://openforecast.org/wp-content/uploads/2025/07/2025-07-04-smooth-v4-3-0-300x175.png&amp;nocache=1 300w, https://openforecast.org/wp-content/webpc-passthru.php?src=https://openforecast.org/wp-content/uploads/2025/07/2025-07-04-smooth-v4-3-0-1024x597.png&amp;nocache=1 1024w, https://openforecast.org/wp-content/webpc-passthru.php?src=https://openforecast.org/wp-content/uploads/2025/07/2025-07-04-smooth-v4-3-0-768x448.png&amp;nocache=1 768w, https://openforecast.org/wp-content/webpc-passthru.php?src=https://openforecast.org/wp-content/uploads/2025/07/2025-07-04-smooth-v4-3-0.png&amp;nocache=1 1200w" sizes="(max-width: 300px) 100vw, 300px" /></a><p id="caption-attachment-3908" class="wp-caption-text">Nemenyi test for the smooth functions</p></div>
<p>The image shows mean ranks for each of the models and whether the performance of those is significant on the 5% level or not. It is apparent that ADAM ETS has the lowest rank, no matter what the initialisation is used, but its performance does not differ significantly from the <code>es()</code>, <code>ets()</code> and <code>auto.arima()</code>. Also, <code>auto.arima()</code> significantly outperforms <code>msarima()</code> and <code>ssarima()</code> on this data, which could be due to their initialisation. Still, backcasting seems to help all the functions in terms of accuracy in comparison with the "optimal" and "two-stage" initials.</p>
<h3>What's next?</h3>
<p>I am now working on a modified formulation for ETS, which should fix some issues with the multiplicative trend and make the ETS safer. This is based on <a href="https://openforecast.org/adam/ADAMETSMultiplicativeAlternative.html">Section 6.6</a> of the online version of the ADAM monograph (it is not in the printed version). I am not sure whether this will improve the accuracy further, but I hope that it will make some of the ETS models more resilient than they are right now. I specifically need the multiplicative trend model, which sometimes behave like crazy due to its formulation.</p>
<p>I also plan to translate all the simulation functions to the ADAM core. This applies to <code>sim.es()</code>, <code>sim.ssarima()</code>, <code>sim.gum()</code> and <code>sim.ces()</code>. Currently they rely on the older one, and I want to get rid of it. Having said that, the method <code>simulate()</code> applied to the new <code>smooth</code> functions already uses the new core. It just lacks the flexibility that the other functions have.</p>
<p>Furthermore, I want to rewrite the <code>oes()</code> function and substitute it with <code>oadam()</code>, which would use a better engine, supporting more features, such as multiple frequencies and ARIMA for the occurrence. This is a lot of work, and I probably will need help with that.</p>
<p>Finally, Filotas Theodosiou, Leonidas Tsaprounis, and I are working on the translation of the R code of the <code>smooth</code> to Python. You can read a bit more about this project <a href="/2025/06/30/iif-open-source-forecasting-software-workshop-and-smooth/">here</a>. There are several other people who decided to help us, but the progress so far has been a bit slow, because of the code translation. If you want to help, please get in touch.</p>
<p>Message <a href="https://openforecast.org/2025/07/04/smooth-v4-3-0-in-r-what-s-new-and-what-s-next/">smooth v4.3.0 in R: what&#8217;s new and what&#8217;s next?</a> first appeared on <a href="https://openforecast.org">Open Forecasting</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://openforecast.org/2025/07/04/smooth-v4-3-0-in-r-what-s-new-and-what-s-next/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Fundamental Flaw of the Box-Jenkins Methodology</title>
		<link>https://openforecast.org/2025/05/13/fundamental-flaw-of-the-box-jenkins-methodology/</link>
					<comments>https://openforecast.org/2025/05/13/fundamental-flaw-of-the-box-jenkins-methodology/#respond</comments>
		
		<dc:creator><![CDATA[Ivan Svetunkov]]></dc:creator>
		<pubDate>Tue, 13 May 2025 11:57:07 +0000</pubDate>
				<category><![CDATA[ARIMA]]></category>
		<category><![CDATA[Social media]]></category>
		<category><![CDATA[Univariate models]]></category>
		<category><![CDATA[extrapolation methods]]></category>
		<category><![CDATA[Information criteria]]></category>
		<guid isPermaLink="false">https://openforecast.org/?p=3838</guid>

					<description><![CDATA[<p>If you have taken a course on forecasting or time series analysis, you’ve probably heard of ARIMA and the Box–Jenkins methodology. In my opinion, this methodology has a fundamental flaw and should not be used in practice. Here&#8217;s why. When Box and Jenkins wrote their book back in the 1960s, it was a very different [&#8230;]</p>
<p>Message <a href="https://openforecast.org/2025/05/13/fundamental-flaw-of-the-box-jenkins-methodology/">Fundamental Flaw of the Box-Jenkins Methodology</a> first appeared on <a href="https://openforecast.org">Open Forecasting</a>.</p>
]]></description>
										<content:encoded><![CDATA[<p>If you have taken a course on forecasting or time series analysis, you’ve probably heard of ARIMA and the Box–Jenkins methodology. In my opinion, <strong>this methodology has a fundamental flaw</strong> and should not be used in practice. Here&#8217;s why.</p>
<p>When Box and Jenkins wrote their book back in the 1960s, it was a very different era: computers were massive, and people worked with punch cards. To make their approach viable, Box and Jenkins developed a methodology for selecting the appropriate orders of AR and MA based on the values of the autocorrelation and partial autocorrelation functions (ACF and PACF, respectively). Their idea was that if an ARMA process generates a specific ACF/PACF pattern, then it could be identified by analysing those functions in the data. At the time, it wasn’t feasible to do cross-validation or rolling origin evaluation, and even using information criteria for model selection was a challenge. So, the Box–Jenkins approach was a sensible option, producing adequate results with limited computational resources, and was considered state of the art.</p>
<p>Unfortunately, as the M1 competition later showed (see my <a href="/2024/03/14/the-role-of-m-competitions-in-forecasting/">earlier post</a>), the methodology didn’t work well in practice. Simpler methods that didn’t rely on rigorous model selection actually performed better. But in fact, the winning model in the competition was ARARMA by Emanuel Parzen (https://doi.org/10.1002/for.3980010108). His idea was to make the series stationary by applying a low-order, non-stationary AR to the data, then extract residuals and select appropriate ARMA orders using AIC. Parzen ignored the Box–Jenkins methodology entirely &#8211; he didn’t analyse ACF or PACF and instead relied fully on automated selection. And it worked!</p>
<p>So why didn’t the Box–Jenkins methodology perform as expected? In my monograph <a href="/adam">Forecasting and Analytics with ADAM</a>, I use the following example to explain the main issue: “All birds have wings. Sarah has wings. Thus, Sarah is a bird.” But Sarah, as shown in the image attached to this post, is a butterfly.</p>
<p>The fundamental issue with the Box–Jenkins methodology lies in its logic: if a process generates a specific ACF/PACF, that doesn’t mean that an observed ACF/PACF must come from that process. Many ARMA and even non-ARMA processes can generate exactly the same autocorrelation structure.</p>
<p>Further developments in ARIMA modelling have shown that ACF and PACF can only be used as general guidelines for order selection. To assess model performance properly, we need other tools. All modern approaches rely on information criteria for ARIMA order selection, and they consistently perform well in forecasting competitions. For example, <a href="https://doi.org/10.18637/jss.v027.i03">Hyndman &#038; Khandakar (2008)</a> use AIC for ARMA order selection, while <a href="https://doi.org/10.1080/00207543.2019.1600764">Svetunkov &#038; Boylan (2020)</a> apply AIC after reformulating ARIMA in a state space form. The former is implemented in the forecast package in R and the StatsForecast library in Python (thanks to Nixtla and Azul Garza); the latter is available in the smooth package in R. I also discuss another ARIMA order selection approach in <a href="/adam/ARIMASelection.html">Section 15.2 of my book</a>.</p>
<p>Long story short: don’t use the Box–Jenkins methodology for order selection. Use more modern tools, such as information criteria.</p>
<p>P.S. <a href="/2024/03/21/what-s-wrong-with-arima/">See also my early post on ARIMA</a>, discussing what is wrong with it.</p>
<p>Message <a href="https://openforecast.org/2025/05/13/fundamental-flaw-of-the-box-jenkins-methodology/">Fundamental Flaw of the Box-Jenkins Methodology</a> first appeared on <a href="https://openforecast.org">Open Forecasting</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://openforecast.org/2025/05/13/fundamental-flaw-of-the-box-jenkins-methodology/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Multistep loss functions: Geometric Trace MSE</title>
		<link>https://openforecast.org/2024/06/04/multistep-loss-functions-geometric-trace-mse/</link>
					<comments>https://openforecast.org/2024/06/04/multistep-loss-functions-geometric-trace-mse/#respond</comments>
		
		<dc:creator><![CDATA[Ivan Svetunkov]]></dc:creator>
		<pubDate>Tue, 04 Jun 2024 09:05:56 +0000</pubDate>
				<category><![CDATA[Social media]]></category>
		<category><![CDATA[Theory of forecasting]]></category>
		<category><![CDATA[Univariate models]]></category>
		<category><![CDATA[ARIMA]]></category>
		<category><![CDATA[estimators]]></category>
		<category><![CDATA[ETS]]></category>
		<category><![CDATA[extrapolation methods]]></category>
		<category><![CDATA[statistics]]></category>
		<guid isPermaLink="false">https://openforecast.org/?p=3594</guid>

					<description><![CDATA[<p>While there is a lot to say about multistep losses, I&#8217;ve decided to write the final post on one of them and leave the topic alone for a while. Here it goes. Last time, we discussed MSEh and TMSE, and I mentioned that both of them impose shrinkage and have some advantages and disadvantages. One [&#8230;]</p>
<p>Message <a href="https://openforecast.org/2024/06/04/multistep-loss-functions-geometric-trace-mse/">Multistep loss functions: Geometric Trace MSE</a> first appeared on <a href="https://openforecast.org">Open Forecasting</a>.</p>
]]></description>
										<content:encoded><![CDATA[<p>While there is a lot to say about multistep losses, I&#8217;ve decided to write the final post on one of them and leave the topic alone for a while. Here it goes.</p>
<p>Last time, we discussed <a href="/2024/05/25/recursive-vs-direct-forecasting-strategy/">MSEh</a> and <a href="/2024/06/01/multistep-loss-functions-trace-mse/">TMSE</a>, and I mentioned that both of them impose shrinkage and have some advantages and disadvantages. One of the main advantages of TMSE was in reducing computational time in comparison with MSEh: you just fit one model with it instead of doing it h times. However, the downside of TMSE is that it averages things out, and we end up with model parameters that minimize the h-steps-ahead forecast error to a much larger extent than those that are close to the one-step-ahead. For example, if the one-step-ahead MSE was 500, while the six-steps-ahead MSE was 3000, the impact of the latter in TMSE would be six times higher than that of the former, and the estimator would prioritize the minimization of the longer horizon one.</p>
<p>A more balanced version of this was introduced in <a href="/2023/08/09/multi-step-estimators-and-shrinkage-effect-in-time-series-models/">our paper</a> and was called &#8220;Geometric Trace MSE&#8221; (GTMSE). The main idea of GTMSE is to take the geometric mean or, equivalently, the sum of logarithms of MSEh instead of taking the arithmetic mean. Because of that, the impact of MSEh on the loss becomes comparable with the effect of MSE1, and the model performs well throughout the whole horizon from 1 to h. For the same example of MSEs as above, the logarithm of 500 is approximately 2.7, while the logarithm of 3000 is 3.5. The difference between the two is much smaller, reducing the impact of the long-term forecast uncertainty. As a result, GTMSE has the following features:</p>
<ul>
<li>It imposes shrinkage on models parameters.</li>
<li>The strength of shrinkage is proportional to the forecast horizon.</li>
<li>But it is much milder than in case of MSEh or TMSE.</li>
<li>It leads to more balanced forecasts, performing well on average across the whole horizon.</li>
</ul>
<p>In that paper, we did extensive simulations to see how different estimators behave, and we found that:</p>
<ol>
<li>If an analyst is interested in parameters of models, they should stick with the conventional loss functions (based on one-step-ahead forecast error) because the multistep ones tend to produce biased estimates of parameters.</li>
<li>On the other hand, multistep losses kick off the redundant parameters faster than the conventional one, so there might be a benefit in the case of overparameterized models.</li>
<li>At the same time, if forecasting is of the main interest, then multistep losses might bring benefits, especially on larger samples.</li>
</ol>
<div id="attachment_3595" style="width: 310px" class="wp-caption aligncenter"><a href="https://openforecast.org/wp-content/webpc-passthru.php?src=https://openforecast.org/wp-content/uploads/2024/06/2024-06-04-Multistep-Example.png&amp;nocache=1"><img decoding="async" aria-describedby="caption-attachment-3595" src="https://openforecast.org/wp-content/webpc-passthru.php?src=https://openforecast.org/wp-content/uploads/2024/06/2024-06-04-Multistep-Example-300x200.png&amp;nocache=1" alt="ETS(A,A,A) estimated using different loss functions applied to the data with multiplicative seasonality" width="300" height="200" class="size-medium wp-image-3595" srcset="https://openforecast.org/wp-content/webpc-passthru.php?src=https://openforecast.org/wp-content/uploads/2024/06/2024-06-04-Multistep-Example-300x200.png&amp;nocache=1 300w, https://openforecast.org/wp-content/webpc-passthru.php?src=https://openforecast.org/wp-content/uploads/2024/06/2024-06-04-Multistep-Example-1024x681.png&amp;nocache=1 1024w, https://openforecast.org/wp-content/webpc-passthru.php?src=https://openforecast.org/wp-content/uploads/2024/06/2024-06-04-Multistep-Example-768x511.png&amp;nocache=1 768w, https://openforecast.org/wp-content/webpc-passthru.php?src=https://openforecast.org/wp-content/uploads/2024/06/2024-06-04-Multistep-Example.png&amp;nocache=1 1049w" sizes="(max-width: 300px) 100vw, 300px" /></a><p id="caption-attachment-3595" class="wp-caption-text">ETS(A,A,A) estimated using different loss functions applied to the data with multiplicative seasonality</p></div>
<p>The image above shows an example from our paper, where we applied the additive model to the data, which exhibits apparent multiplicative seasonality. Despite that, we can see that multistep losses did a much better job than the conventional MSE, compensating for the misspecification.</p>
<p>Message <a href="https://openforecast.org/2024/06/04/multistep-loss-functions-geometric-trace-mse/">Multistep loss functions: Geometric Trace MSE</a> first appeared on <a href="https://openforecast.org">Open Forecasting</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://openforecast.org/2024/06/04/multistep-loss-functions-geometric-trace-mse/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Detecting patterns in white noise</title>
		<link>https://openforecast.org/2024/04/10/detecting-patterns-in-white-noise/</link>
					<comments>https://openforecast.org/2024/04/10/detecting-patterns-in-white-noise/#respond</comments>
		
		<dc:creator><![CDATA[Ivan Svetunkov]]></dc:creator>
		<pubDate>Wed, 10 Apr 2024 08:16:58 +0000</pubDate>
				<category><![CDATA[ARIMA]]></category>
		<category><![CDATA[ETS]]></category>
		<category><![CDATA[R]]></category>
		<category><![CDATA[Social media]]></category>
		<category><![CDATA[ADAM]]></category>
		<category><![CDATA[smooth]]></category>
		<guid isPermaLink="false">https://openforecast.org/?p=3413</guid>

					<description><![CDATA[<p>Back in 2015, when I was working on my paper on Complex Exponential Smoothing, I conducted a simple simulation experiment to check how ARIMA and ETS select components/orders in time series. And I found something interesting&#8230; One of the important steps in forecasting with statistical models is identifying the existing structure. In the case of [&#8230;]</p>
<p>Message <a href="https://openforecast.org/2024/04/10/detecting-patterns-in-white-noise/">Detecting patterns in white noise</a> first appeared on <a href="https://openforecast.org">Open Forecasting</a>.</p>
]]></description>
										<content:encoded><![CDATA[<p>Back in 2015, when I was working on my paper on <a href="/2022/08/02/complex-exponential-smoothing/">Complex Exponential Smoothing</a>, I conducted a simple simulation experiment to check how ARIMA and ETS select components/orders in time series. And I found something interesting&#8230;</p>
<p>One of the important steps in forecasting with statistical models is identifying the existing structure. In the case of ETS, it comes to selecting trend/seasonal components, while for ARIMA, it&#8217;s about order selection. In R, several functions automatically handle this based on information criteria (<a href="https://doi.org/10.18637/jss.v027.i03">Hyndman &#038; Khandakar, 2006</a>; <a href="https://doi.org/10.1080/00207543.2019.1600764">Svetunkov &#038; Boylan (2017)</a>; <a href="https://openforecast.org/adam/ADAMSelection.html">Chapter 15 of ADAM</a>). I decided to investigate how this mechanism works.</p>
<p>I generated data from the Normal distribution with a fixed mean of 5000 and a standard deviation of 50. Then, I asked ETS and ARIMA (from the forecast package in R) to automatically select the appropriate model for each of 1000 time series. Here is the R code for this simple experiment:</p>
<div class="su-accordion su-u-trim"><div class="su-spoiler su-spoiler-style-default su-spoiler-icon-plus su-spoiler-closed" data-scroll-offset="0" data-anchor-in-url="no"><div class="su-spoiler-title" tabindex="0" role="button"><span class="su-spoiler-icon"></span>Some R code</div><div class="su-spoiler-content su-u-clearfix su-u-trim">
<pre class="decode"># Set random seed for reproducibility
set.seed(41, kind="L'Ecuyer-CMRG")
# Number of iterations
nsim <- 1000
# Number of observations
obsAll <- 120
# Generate data from N(5000, 50)
rnorm(nsim*obsAll, 5000, 50) |>
  matrix(obsAll, nsim) |>
  ts(frequency=12) -> x

# Load forecast package
library(forecast)
# Load doMC for parallel calculations
# doMC is only available on Linux and Max
# Use library(doParallel) on Windows
library(doMC)
registerDoMC(detectCores())

# A loop for ARIMA, recording the orders
matArima <- foreach(i=1:nsim, .combine=cbind, .packages=c("forecast")) %dopar% {
    testModel <- auto.arima(x&#091;,i&#093;)
    # The element number 5 is just m, period of seasonality
    return(c(testModel$arma&#091;-5&#093;,(!is.na(testModel$coef&#091;"drift"&#093;))*1))
}
rownames(matArima) <- c("AR","MA","SAR","SMA","I","SI","Drift")

# A loop for ETS, recording the model types
matEts <- foreach(i=1:nsim, .combine=cbind, .packages=c("forecast")) %dopar% {
    testModel <- ets(x&#091;,i&#093;, allow.multiplicative.trend=TRUE)
    return(testModel&#091;13&#093;$method)
}
</pre>
</div></div></div>
<p>The findings of this experiment are summarised using the following chunk of the R code:</p>
<div class="su-accordion su-u-trim"><div class="su-spoiler su-spoiler-style-default su-spoiler-icon-plus su-spoiler-closed" data-scroll-offset="0" data-anchor-in-url="no"><div class="su-spoiler-title" tabindex="0" role="button"><span class="su-spoiler-icon"></span>R code for the analysis of the results</div><div class="su-spoiler-content su-u-clearfix su-u-trim">
<pre class="decode">
#### Auto ARIMA ####
# Non-seasonal ARIMA elements
mean(apply(matArima[c("AR","MA","I","Drift"),]!=0, 2, any))
# Seasonal ARIMA elements
mean(apply(matArima[c("SAR","SMA","SI"),]!=0, 2, any))

#### ETS ####
# Trend in ETS
mean(substr(matEts,7,7)!="N")
# Seasonality in ETS
mean(substr(matEts,nchar(matEts)-1,nchar(matEts)-1)!="N")</pre>
</div></div></div>
<p>I summarised them in the following table:</p>
<table>
<thead>
<tr>
<td></td>
<td><strong>ARIMA</strong></td>
<td><strong>ETS</strong></td>
</tr>
</thead>
<tr>
<td>Non-seasonal elements</td>
<td>24.8%</td>
<td>2.3%</td>
</tr>
<tr>
<td>Seasonal elements</td>
<td>18.0%</td>
<td>0.2%</td>
</tr>
<tr>
<td>Any type of structure</td>
<td>37.9%</td>
<td>2.4%</td>
</tr>
</table>
<p>So, ARIMA detected some structure (had non-zero orders) in almost 40% of all time series, even though the data was designed to have no structure (just white noise). It also captured non-seasonal orders in a quarter of the series and identified seasonality in 18% of them. ETS performed better (only 0.2% of seasonal models identified on the white noise), but still captured trends in 2.3% of cases.</p>
<p>Does this simple experiment suggest that ARIMA is a bad model and ETS is a good one? No, it does not. It simply demonstrates that ARIMA tends to overfit the data if allowed to select whatever it wants. How can we fix that?</p>
<p>My solution: restrict the pool of ARIMA models to check, preventing it from going crazy. My personal pool includes ARIMA(0,1,1), (1,1,2), (0,2,2), along with the seasonal orders of (0,1,1), (1,1,2), and (0,2,2), and combinations between them. This approach is motivated by the connection between <a href="https://openforecast.org/adam/ARIMAandETS.html">ARIMA and ETS</a>. Additionally, we can check whether the addition of AR/MA orders detected by ACF/PACF analysis of the best model reduces the AICc. If not, they shouldn't be included.</p>
<p>This algorithm can be written in the following simple function that uses <code>msarima()</code> function from the smooth package in R (note that the reason why this function is used is because all ARIMA models implemented in the function are directly comparable via information criteria):</p>
<div class="su-accordion su-u-trim"><div class="su-spoiler su-spoiler-style-default su-spoiler-icon-plus su-spoiler-closed" data-scroll-offset="0" data-anchor-in-url="no"><div class="su-spoiler-title" tabindex="0" role="button"><span class="su-spoiler-icon"></span>R code for the compact ARIMA function</div><div class="su-spoiler-content su-u-clearfix su-u-trim">
<pre class="decode">arimaCompact <- function(y, lags=c(1,frequency(y)), ic=c("AICc","AIC","BIC","BICc"), ...){

    # Start measuring the time of calculations
    startTime <- Sys.time();

    # If there are no lags for the basic components, correct this.
    if(sum(lags==1)==0){
        lags <- c(1,lags);
    }

    orderLength <- length(lags);
    ic <- match.arg(ic);
    IC <- switch(ic,
                 "AIC"=AIC,
                 "AICc"=AICc,
                 "BIC"=BIC,
                 "BICc"=BICc);

    # We consider the following list of models:
    # ARIMA(0,1,1), (1,1,2), (0,2,2),
    # ARIMA(0,0,0)+c, ARIMA(0,1,1)+c,
    # seasonal orders (0,1,1), (1,1,2), (0,2,2)
    # And all combinations between seasonal and non-seasonal parts
    # 
    # Encode all non-seasonal parts
    nNonSeasonal <- 5
    arimaNonSeasonal <- matrix(c(0,1,1,0, 1,1,2,0, 0,2,2,0, 0,0,0,1, 0,1,1,1), nNonSeasonal,4,
                               dimnames=list(NULL, c("ar","i","ma","const")), byrow=TRUE)
    # Encode all seasonal parts ()
    nSeasonal <- 4
    arimaSeasonal <- matrix(c(0,0,0, 0,1,1, 1,1,2, 0,2,2), nSeasonal,3,
                               dimnames=list(NULL, c("sar","si","sma")), byrow=TRUE)

    # Check all the models in the pool
    testModels <- vector("list", nSeasonal*nNonSeasonal);
    m <- 1;
    for(i in 1:nSeasonal){
        for(j in 1:nNonSeasonal){
            testModels&#091;&#091;m&#093;&#093; <- msarima(y, orders=list(ar=c(arimaNonSeasonal&#091;j,1&#093;,arimaSeasonal&#091;i,1&#093;),
                                                      i=c(arimaNonSeasonal&#091;j,2&#093;,arimaSeasonal&#091;i,2&#093;),
                                                      ma=c(arimaNonSeasonal&#091;j,3&#093;,arimaSeasonal&#091;i,3&#093;)),
                                       constant=arimaNonSeasonal&#091;j,4&#093;==1, lags=lags, ...);
            m&#091;&#093; <- m+1;
        }
    }

    # Find the best one
    m <- which.min(sapply(testModels, IC));
    # Amend computational time
    testModels&#091;&#091;m&#093;&#093;$timeElapsed <- Sys.time()-startTime;

    return(testModels&#091;&#091;m&#093;&#093;);
}</pre>
</div></div></div>
<p>Additionally, we can check whether the addition of AR/MA orders detected by ACF/PACF analysis of the best model reduces the AICc. If not, they shouldn't be included. I have not added that part in the code above. Still, this algorithm brings some improvements:</p>
<div class="su-accordion su-u-trim"><div class="su-spoiler su-spoiler-style-default su-spoiler-icon-plus su-spoiler-closed" data-scroll-offset="0" data-anchor-in-url="no"><div class="su-spoiler-title" tabindex="0" role="button"><span class="su-spoiler-icon"></span>R code for the application of compact ARIMA to the data</div><div class="su-spoiler-content su-u-clearfix su-u-trim">
<pre class="decode">#### Load the smooth package
library(smooth)

# A loop for the compact ARIMA, recording the orders
matArimaCompact <- foreach(i=1:nsim, .packages=c("smooth")) %dopar% {
    testModel <- arimaCompact(x&#091;,i&#093;)
    return(orders(testModel))
}

#### Auto MSARIMA from smooth ####
# Non-seasonal ARIMA elements
mean(sapply(sapply(matArimaCompact, "&#091;&#091;", "ar"), function(x){x&#091;1&#093;!=0}) |
  sapply(sapply(matArimaCompact, "&#091;&#091;", "i"), function(x){x&#091;1&#093;!=0}) |
  sapply(sapply(matArimaCompact, "&#091;&#091;", "ma"), function(x){x&#091;1&#093;!=0}))

# Seasonal ARIMA elements
mean(sapply(sapply(matArimaSmooth, "&#091;&#091;", "ar"), function(x){length(x)==2 &#038;&#038; (x&#091;2&#093;!=0)}) |
  sapply(sapply(matArimaSmooth, "&#091;&#091;", "i"), function(x){length(x)==2 &#038;&#038; (x&#091;2&#093;!=0)}) |
  sapply(sapply(matArimaSmooth, "&#091;&#091;", "ma"), function(x){length(x)==2 &#038;&#038; (x&#091;2&#093;!=0)}))
</pre>
</div></div></div>
<p>In my case, it resulted in the following:</p>
<table>
<thead>
<tr>
<td></td>
<td><strong>ARIMA</strong></td>
<td><strong>ETS</strong></td>
<td style="text-align: center"><strong>Compact ARIMA</strong></td>
</tr>
</thead>
<tr>
<td>Non-seasonal elements</td>
<td>24.8%</td>
<td>2.3%</td>
<td style="text-align: center">2.4%</td>
</tr>
<tr>
<td>Seasonal elements</td>
<td>18.0%</td>
<td>0.2%</td>
<td style="text-align: center">0.0%</td>
</tr>
<tr>
<td>Any type of structure</td>
<td>37.9%</td>
<td>2.4%</td>
<td style="text-align: center">2.4%</td>
</tr>
</table>
<p>As we see, when we impose restrictions on order selection in ARIMA, it avoids fitting seasonal models to non-seasonal data. While it still makes minor mistakes in terms of non-seasonal structure, it's nothing compared to the conventional approach. What about accuracy? I don't know. I'll have to write another post on this :).</p>
<p>Note that the models were applied to samples of 120 observations, which is considered "small" in statistics, while in real life is sometimes a luxury to have...</p>
<p>Message <a href="https://openforecast.org/2024/04/10/detecting-patterns-in-white-noise/">Detecting patterns in white noise</a> first appeared on <a href="https://openforecast.org">Open Forecasting</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://openforecast.org/2024/04/10/detecting-patterns-in-white-noise/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>What does &#8220;lower error measure&#8221; really mean?</title>
		<link>https://openforecast.org/2024/03/27/what-does-lower-error-measure-really-mean/</link>
					<comments>https://openforecast.org/2024/03/27/what-does-lower-error-measure-really-mean/#respond</comments>
		
		<dc:creator><![CDATA[Ivan Svetunkov]]></dc:creator>
		<pubDate>Wed, 27 Mar 2024 18:29:03 +0000</pubDate>
				<category><![CDATA[Forecast evaluation]]></category>
		<category><![CDATA[Social media]]></category>
		<category><![CDATA[ADAM]]></category>
		<category><![CDATA[ARIMA]]></category>
		<category><![CDATA[CES]]></category>
		<category><![CDATA[error measures]]></category>
		<category><![CDATA[ETS]]></category>
		<guid isPermaLink="false">https://openforecast.org/?p=3380</guid>

					<description><![CDATA[<p>&#8220;My amazing forecasting method has a lower MASE than any other method!&#8221; You&#8217;ve probably seen claims like this on social media or in papers. But have you ever thought about what it really means? Many forecasting experiments come to applying several approaches to a dataset, calculating error measures for each method per time series and [&#8230;]</p>
<p>Message <a href="https://openforecast.org/2024/03/27/what-does-lower-error-measure-really-mean/">What does &#8220;lower error measure&#8221; really mean?</a> first appeared on <a href="https://openforecast.org">Open Forecasting</a>.</p>
]]></description>
										<content:encoded><![CDATA[<p>&#8220;My amazing forecasting method has a lower MASE than any other method!&#8221; You&#8217;ve probably seen claims like this on social media or in papers. But have you ever thought about what it really means?</p>
<p>Many forecasting experiments come to applying several approaches to a dataset, calculating error measures for each method per time series and aggregating them to get a neat table like this one (based on the M and tourism competitions, with R code similar to the one from <a href="/2021/01/13/the-creation-of-adam-next-step-in-statistical-forecasting/">this post</a>):</p>
<pre>           RMSSE    sCE
ADAM ETS   <strong>1.947</strong>  0.319
ETS        1.970  0.299
ARIMA      1.986  0.125
CES        1.960 <strong>-0.011</strong></pre>
<p>Typically, the conclusion drawn from such tables is that the approach with the measure closest to zero performs the best, on average. I&#8217;ve done this myself many times because it&#8217;s a simple way to present results. So, what&#8217;s the issue?</p>
<p>Well, almost any error measure has a skewed distribution because it cannot be lower than zero, and its highest value is infinity (this doesn&#8217;t apply to bias). Let me show you:</p>
<div id="attachment_3381" style="width: 310px" class="wp-caption aligncenter"><a href="https://openforecast.org/wp-content/webpc-passthru.php?src=https://openforecast.org/wp-content/uploads/2024/03/2024-03-03-vioplot.png&amp;nocache=1"><img loading="lazy" decoding="async" aria-describedby="caption-attachment-3381" src="https://openforecast.org/wp-content/webpc-passthru.php?src=https://openforecast.org/wp-content/uploads/2024/03/2024-03-03-vioplot-300x150.png&amp;nocache=1" alt="Distribution of RMSSE for ADAM ETS on M and tourism competitions data" width="300" height="150" class="size-medium wp-image-3381" srcset="https://openforecast.org/wp-content/webpc-passthru.php?src=https://openforecast.org/wp-content/uploads/2024/03/2024-03-03-vioplot-300x150.png&amp;nocache=1 300w, https://openforecast.org/wp-content/webpc-passthru.php?src=https://openforecast.org/wp-content/uploads/2024/03/2024-03-03-vioplot-768x384.png&amp;nocache=1 768w, https://openforecast.org/wp-content/webpc-passthru.php?src=https://openforecast.org/wp-content/uploads/2024/03/2024-03-03-vioplot.png&amp;nocache=1 800w" sizes="auto, (max-width: 300px) 100vw, 300px" /></a><p id="caption-attachment-3381" class="wp-caption-text">Distribution of RMSSE for ADAM ETS on M and tourism competitions data</p></div>
<p>This figure shows the distribution of 5,315 RMSSE values for ADAM ETS. As seen from the violin plot, the distribution has a peak close to zero and a very long tail. This suggests that the model performed well on many series but generated inaccurate forecasts for just a few, or perhaps only one of them. The mean RMSSE is 1.947 (vertical red line on the plot). However, this single value alone does not provide full information about the model&#8217;s performance. Firstly, it tries to represent the entire distribution with just one number. Secondly, as we know from statistics, the mean is influenced by outliers: if your method performed exceptionally well on 99% of cases but poorly on just 1%, the mean will be higher than in the case of a poorly performing method that did not do that badly on 1%.</p>
<p>So, what should we do?</p>
<p>At the very least, provide both mean and median error measures: the distance between them shows how skewed the distribution is. But an even better approach would be to report mean and several quantiles of error measures (not just median). For instance, we could present the 1st, 2nd (median), and 3rd quartiles together with mean, min and max to offer a clearer understanding of the spread and variability of the error measure:</p>
<pre>             min    1Q  median    3Q     max  mean
ADAM ETS   <strong>0.024</strong> <strong>0.670</strong>   1.180 2.340  51.616 <strong>1.947</strong>
ETS        <strong>0.024</strong> 0.677   1.181 2.376  51.616 1.970
ARIMA      0.025 0.681   1.179 2.358  51.616 1.986
CES        0.045 0.675   <strong>1.171</strong> <strong>2.330</strong>  <strong>51.201</strong> 1.960</pre>
<p>This table provides better insights: ETS models consistently perform well in terms of mean, min, and first quartile RMSSE, while ARIMA outperformed them in terms of median. CES did better than the others in terms of median, third quartile, and the maximum. This means that there were some time series, where ETS struggled a bit more than CES, but in the majority of cases it performed well.</p>
<p>So, next time you see a table with error measures, keep in mind that the best method on average might not be the best consistently. Having more details helps in understanding the situation better.</p>
<p>You can read more about error measures for forecasting in the &#8220;<a href="/category/forecasting-theory/forecast-evaluation/">forecast evaluation</a>&#8221; category.</p>
<p>Message <a href="https://openforecast.org/2024/03/27/what-does-lower-error-measure-really-mean/">What does &#8220;lower error measure&#8221; really mean?</a> first appeared on <a href="https://openforecast.org">Open Forecasting</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://openforecast.org/2024/03/27/what-does-lower-error-measure-really-mean/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>What&#8217;s wrong with ARIMA?</title>
		<link>https://openforecast.org/2024/03/21/what-s-wrong-with-arima/</link>
					<comments>https://openforecast.org/2024/03/21/what-s-wrong-with-arima/#respond</comments>
		
		<dc:creator><![CDATA[Ivan Svetunkov]]></dc:creator>
		<pubDate>Thu, 21 Mar 2024 10:10:52 +0000</pubDate>
				<category><![CDATA[ARIMA]]></category>
		<category><![CDATA[Social media]]></category>
		<category><![CDATA[Univariate models]]></category>
		<category><![CDATA[extrapolation methods]]></category>
		<guid isPermaLink="false">https://openforecast.org/?p=3366</guid>

					<description><![CDATA[<p>Have you heard of ARIMA? It is one of the benchmark forecasting models used in different academic experiments, although it is not always popular among practitioners. But why? What&#8217;s wrong with ARIMA? ARIMA has been a standard forecasting model in statistics for ages. It gained popularity with the famous Box &#038; Jenkins (1970) book and [&#8230;]</p>
<p>Message <a href="https://openforecast.org/2024/03/21/what-s-wrong-with-arima/">What&#8217;s wrong with ARIMA?</a> first appeared on <a href="https://openforecast.org">Open Forecasting</a>.</p>
]]></description>
										<content:encoded><![CDATA[<p>Have you heard of ARIMA? It is one of the benchmark forecasting models used in different academic experiments, although it is not always popular among practitioners. But why? What&#8217;s wrong with ARIMA?</p>
<p>ARIMA has been a standard forecasting model in statistics for ages. It gained popularity with the famous <a href="https://archive.org/details/timeseriesanalys0000boxg">Box &#038; Jenkins (1970) book</a> and was considered the best forecasting model by statisticians for a couple of decades without any strong evidence to support this.</p>
<p>It represents one of the two fundamental approaches to time series modeling (the second being the state space approach): <a href="https://openforecast.org/adam/ARIMA.html">it captures the relation between the variable and itself in the past</a>. This has a great rationale in technical areas. For example, the quantity of CO2 in a furnace at this moment in time will depend on the quantity of CO2 five minutes ago. Such processes can be efficiently modeled and then forecasted using ARIMA. In demand forecasting, making sense of ARIMA is more challenging: it is hard to argue that the demand for shoes on Monday can impact the demand on Tuesday. So, when we apply ARIMA to such data, we sort of rely on a spurious relation. Still, demand data often exhibits autocorrelations, and ARIMA has been used efficiently in that context.</p>
<p>Over the years, ARIMA did not perform well in different competitions (see <a href="/2024/03/14/the-role-of-m-competitions-in-forecasting/">my post</a> about that), but this was mainly due to the wrong assumptions in <a href="https://openforecast.org/adam/BJApproach.html#BJApproachSummary">Box-Jenkins methodology</a>, not because the model has been fundamentally bad. After <a href="https://doi.org/10.18637/jss.v027.i03">Hyndman &#038; Khandakar (2006)</a> implemented their version with automatic order selection based on information criteria, ARIMA has started producing much more accurate forecasts.</p>
<p>But if I were to summarize what the problem with the model is, I would outline these points:</p>
<ol>
<li>It is hard to explain ARIMA to people who are not comfortable with statistics. Here is an example of how seasonal ARIMA(1,0,1)(1,0,1)_4 is written mathematically:<br />
\begin{equation*}<br />
  y_t (1 -\phi_{4,1} B^4)(1 -\phi_{1} B) = \epsilon_t (1 + \theta_{4,1} B^4) (1 + \theta_{1} B).<br />
\end{equation*}<br />
Good luck explaining this to a demand planner who does not know mathematics.</li>
<li>It is hard to estimate, especially for models with seasonality. It is typically estimated using some numeric optimisation, and reaching the maximum likelihood (or a global minimum of a loss function) is not guaranteed.</li>
<li>It is hard to select the appropriate order of the model, as there can be thousands of potential models to choose from. Yes, there are heuristic approaches that allow simplifying the problem and selecting a reasonable model (e.g. <a href="https://doi.org/10.18637/jss.v027.i03">Hyndman &#038; Khandakar, 2006</a>; or <a href="https://doi.org/10.1080/00207543.2019.1600764">Svetunkov &#038; Boylan, 2017</a>), but they do not guarantee that you will get the best possible model.</li>
</ol>
<p>Nonetheless, ARIMA is a strong contender that can outperform other models if implemented well. Furthermore, it has become one of the standard forecasting benchmarks in forecasting-related experiments. So, if you are a data scientist comfortable with mathematics and want to see how your machine learning approach performs, you should consider including ARIMA as a benchmark.</p>
<p>P.S. Check out <a href="https://www.linkedin.com/posts/vandeputnicolas_i-am-not-aware-of-any-successful-use-at-activity-7148632910441377793-27s5">a post by Nicolas Vandeput on LinkedIn</a> &#8211; he had a discussion about ARIMA and raised good points as well.</p>
<p>Message <a href="https://openforecast.org/2024/03/21/what-s-wrong-with-arima/">What&#8217;s wrong with ARIMA?</a> first appeared on <a href="https://openforecast.org">Open Forecasting</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://openforecast.org/2024/03/21/what-s-wrong-with-arima/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>The role of M competitions in forecasting</title>
		<link>https://openforecast.org/2024/03/14/the-role-of-m-competitions-in-forecasting/</link>
					<comments>https://openforecast.org/2024/03/14/the-role-of-m-competitions-in-forecasting/#respond</comments>
		
		<dc:creator><![CDATA[Ivan Svetunkov]]></dc:creator>
		<pubDate>Thu, 14 Mar 2024 14:53:03 +0000</pubDate>
				<category><![CDATA[Applied forecasting]]></category>
		<category><![CDATA[Social media]]></category>
		<category><![CDATA[ARIMA]]></category>
		<category><![CDATA[ETS]]></category>
		<category><![CDATA[stories]]></category>
		<guid isPermaLink="false">https://openforecast.org/?p=3358</guid>

					<description><![CDATA[<p>If you are interested in forecasting, you might have heard of M-competitions. They played a pivotal role in developing forecasting principles, yet also sparked controversy. In this short post, I&#8217;ll briefly explain their historical significance and discuss their main findings. Before M-competitions, only few papers properly evaluated forecasting approaches. Statisticians assumed that if a model [&#8230;]</p>
<p>Message <a href="https://openforecast.org/2024/03/14/the-role-of-m-competitions-in-forecasting/">The role of M competitions in forecasting</a> first appeared on <a href="https://openforecast.org">Open Forecasting</a>.</p>
]]></description>
										<content:encoded><![CDATA[<p>If you are interested in forecasting, you might have heard of M-competitions. They played a pivotal role in developing forecasting principles, yet also sparked controversy. In this short post, I&#8217;ll briefly explain their historical significance and discuss their main findings.</p>
<p>Before M-competitions, only few papers properly evaluated forecasting approaches. Statisticians assumed that if a model had solid theoretical backing, it should perform well. One of the first papers to conduct a proper evaluation was <a href="https://doi.org/10.2307/2344546">Newbold &#038; Granger (1974)</a>, who compared exponential smoothing (ES), ARIMA, and stepwise AR on 106 economic time series. Their conclusions were:</p>
<p>1. ES performed well on short time series;<br />
2. Stepwise AR did well on the series with more than 30 observations;<br />
3. Box-Jenkins methodology was recommended for series longer than 50 observations.</p>
<p>Statistical community received the results favourably, as they aligned with their expectations.</p>
<p>In 1979, <a href="https://doi.org/10.2307/2345077">Makridakis &#038; Hibon</a> conducted a similar analysis on 111 time series, including various ES methods and ARIMA. However, they found that &#8220;simpler methods perform well in comparison to the more complex and statistically sophisticated ARMA models&#8221;. This is because ARIMA performed slightly worse than ES, which contradicted the findings of Newbold &#038; Granger. Furthermore, their paper faced heavy criticism, with some claiming that Makridakis did not correctly utilize Box-Jenkins methodology.</p>
<p>So, in 1982, <a href="https://doi.org/10.1002/for.3980010202">Makridakis et al.</a> organized a competition on 1001 time series, inviting external participants to submit their forecasts. It was won by&#8230; the <a href="https://doi.org/10.1002/for.3980010108">ARARMA model by Emmanuel Parzen</a>. This model used information criteria for ARMA order selection instead of Box-Jenkins methodology. The main conclusion drawn from this competition was that &#8220;<strong>Statistically sophisticated or complex methods do not necessarily provide more accurate forecasts than simpler ones</strong>.&#8221; Note that this does not mean that simple methods are always better, because that was not even the case in the first competition: it was won by a quite complicated statistical model based on ARMA. This only means that the complexity does not necessarily translate into accuracy.</p>
<p>The M2 competition focused on judgmental forecasting, and is not discussed here.</p>
<p>We then arrive to <a href="https://doi.org/10.1016/S0169-2070(00)00057-1">M3 competition</a> with 3003 time series and, once again, open submission for anyone. The results widely confirmed the previous findings, with <a href="https://doi.org/10.1016/S0169-2070(00)00066-2">Theta</a> by Vasilious Assimakopoulos and Kostas Nikolopoulos outperforming all the other methods. Note that ARIMA with order selection based on Box-Jenkins methodology performed fine, but could not beat its competitors.</p>
<p>Finally, we arrive to <a href="https://doi.org/10.1016/j.ijforecast.2019.04.014">M4 competition</a>, which had 100,000 time series and was open to even wider audience. While I have <a href="https://openforecast.org/2020/03/01/m-competitions-from-m4-to-m5-reservations-and-expectations/">my reservations about the competition itself</a>, there were several curious findings, including the fact that ARIMA implemented by <a href="https://doi.org/10.18637/jss.v027.i03">Hyndman &#038; Khandakar (2008)</a> performed on average better than ETS (Theta outperformed both of them), and that the more complex methods won the competition.</p>
<p>It was also the first paper to show that the accuracy tends to increase on average with the increase of the computational time spent for training. This means that if you want to have more accurate forecasts, you need to spend more resources. The only catch is that this happens with the decreasing return effect. So, the improvements become smaller and smaller the more time you spend on training.</p>
<p>The competition was followed by M5 and M6, and now they plan to have another one. I don&#8217;t want to discuss all of them &#8211; they are beyond the scope of this short post (see details on the <a href="https://mofc.unic.ac.cy/history-of-competitions/">website of the competitions</a>). But I personally find the first competitions very impactful and useful.</p>
<p>And here are my personal takeaways from these competitions:</p>
<p>1. Simple forecasting methods perform well and should be included as benchmarks in experiments;<br />
2. Complex methods can outperform simple ones, especially if used intelligently, but you might need to spend more resources to gain in accuracy;<br />
3. ARIMA is effective, but Box-Jenkins methodology may not be practical. Using information criteria for order selection is a better approach (as evidenced from ARARMA example and Hydnman &#038; Khandakar implementation).</p>
<p>Finally, I like the following <a href="https://robjhyndman.com/hyndsight/m4comp/">quote from Rob J. Hyndman about the competitions</a> that gives some additional perspective: &#8220;The &#8220;M&#8221; competitions organized by Spyros Makridakis have had an enormous influence on the field of forecasting. They focused attention on what models produced good forecasts, rather than on the mathematical properties of those models&#8221;.</p>
<div id="attachment_3360" style="width: 310px" class="wp-caption aligncenter"><a href="https://openforecast.org/wp-content/webpc-passthru.php?src=https://openforecast.org/wp-content/uploads/2024/03/2024-03-13-M3-competition.png&amp;nocache=1"><img loading="lazy" decoding="async" aria-describedby="caption-attachment-3360" src="https://openforecast.org/wp-content/webpc-passthru.php?src=https://openforecast.org/wp-content/uploads/2024/03/2024-03-13-M3-competition-300x182.png&amp;nocache=1" alt="Table with the results of the M3 competition" width="300" height="182" class="size-medium wp-image-3360" srcset="https://openforecast.org/wp-content/webpc-passthru.php?src=https://openforecast.org/wp-content/uploads/2024/03/2024-03-13-M3-competition-300x182.png&amp;nocache=1 300w, https://openforecast.org/wp-content/webpc-passthru.php?src=https://openforecast.org/wp-content/uploads/2024/03/2024-03-13-M3-competition-768x467.png&amp;nocache=1 768w, https://openforecast.org/wp-content/webpc-passthru.php?src=https://openforecast.org/wp-content/uploads/2024/03/2024-03-13-M3-competition.png&amp;nocache=1 923w" sizes="auto, (max-width: 300px) 100vw, 300px" /></a><p id="caption-attachment-3360" class="wp-caption-text">Table with the results of the M3 competition</p></div>
<p>Message <a href="https://openforecast.org/2024/03/14/the-role-of-m-competitions-in-forecasting/">The role of M competitions in forecasting</a> first appeared on <a href="https://openforecast.org">Open Forecasting</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://openforecast.org/2024/03/14/the-role-of-m-competitions-in-forecasting/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Multi-step Estimators and Shrinkage Effect in Time Series Models</title>
		<link>https://openforecast.org/2023/08/09/multi-step-estimators-and-shrinkage-effect-in-time-series-models/</link>
					<comments>https://openforecast.org/2023/08/09/multi-step-estimators-and-shrinkage-effect-in-time-series-models/#respond</comments>
		
		<dc:creator><![CDATA[Ivan Svetunkov]]></dc:creator>
		<pubDate>Wed, 09 Aug 2023 10:14:59 +0000</pubDate>
				<category><![CDATA[ARIMA]]></category>
		<category><![CDATA[ETS]]></category>
		<category><![CDATA[Package smooth for R]]></category>
		<category><![CDATA[Papers]]></category>
		<category><![CDATA[R]]></category>
		<category><![CDATA[Univariate models]]></category>
		<category><![CDATA[extrapolation methods]]></category>
		<category><![CDATA[papers]]></category>
		<category><![CDATA[theory]]></category>
		<guid isPermaLink="false">https://openforecast.org/?p=3142</guid>

					<description><![CDATA[<p>Authors: Ivan Svetunkov, Nikos Kourentzes, Rebecca Killick Journal: Computational Statistics Abstract: Many modern statistical models are used for both insight and prediction when applied to data. When models are used for prediction one should optimise parameters through a prediction error loss function. Estimation methods based on multiple steps ahead forecast errors have been shown to [&#8230;]</p>
<p>Message <a href="https://openforecast.org/2023/08/09/multi-step-estimators-and-shrinkage-effect-in-time-series-models/">Multi-step Estimators and Shrinkage Effect in Time Series Models</a> first appeared on <a href="https://openforecast.org">Open Forecasting</a>.</p>
]]></description>
										<content:encoded><![CDATA[<p><strong>Authors</strong>: Ivan Svetunkov, <a href="http://kourentzes.com/forecasting/">Nikos Kourentzes</a>, <a href="https://www.lancaster.ac.uk/maths/people/rebecca-killick">Rebecca Killick</a></p>
<p><strong>Journal</strong>: <a href="https://www.springer.com/journal/180">Computational Statistics</a></p>
<p><strong>Abstract</strong>: Many modern statistical models are used for both insight and prediction when applied to data. When models are used for prediction one should optimise parameters through a prediction error loss function. Estimation methods based on multiple steps ahead forecast errors have been shown to lead to more robust and less biased estimates of parameters. However, a plausible explanation of why this is the case is lacking. In this paper, we provide this explanation, showing that the main benefit of these estimators is in a shrinkage effect, happening in univariate models naturally. However, this can introduce a series of limitations, due to overly aggressive shrinkage. We discuss the predictive likelihoods related to the multistep estimators and demonstrate what their usage implies to time series models. To overcome the limitations of the existing multiple steps estimators, we propose the Geometric Trace Mean Squared Error, demonstrating its advantages. We conduct a simulation experiment showing how the estimators behave with different sample sizes and forecast horizons. Finally, we carry out an empirical evaluation on real data, demonstrating the performance and advantages of the estimators. Given that the underlying process to be modelled is often unknown, we conclude that the shrinkage achieved by the GTMSE is a competitive alternative to conventional ones.</p>
<p><strong>DOI</strong>: <a href="https://doi.org/10.1007/s00180-023-01377-x">10.1007/s00180-023-01377-x</a>.</p>
<p><a href="http://dx.doi.org/10.13140/RG.2.2.17854.31043">Working paper</a>.</p>
<h2>About the paper</h2>
<p><b>DISCLAIMER 1</b>: To better understand what I am talking about in this section, I would recommend you to have a look at the <a href="https://openforecast.org/adam/">ADAM monograph</a>, and specifically at <a href="https://openforecast.org/adam/ADAMETSEstimation.html">the Chapter 11</a>. In fact, <a href="https://openforecast.org/adam/multistepLosses.html">Section 11.3</a> is based on this paper.</p>
<p><b>DISCLAIMER 2</b>: All the discussions in the paper only apply to pure additive models. If you are interested in multiplicative or mixed ETS models, you&#8217;ll have to wait another seven years for another paper on this topic to get written and published.</p>
<h3>Introduction</h3>
<p>There are lots of ways how dynamic models can be estimated. Some analysts prefer likelihood, some would stick with Least Squares (i.e. minimising MSE), while others would use advanced estimators like Huber&#8217;s loss or M-estimators. And sometimes, statisticians or machine learning experts would use multiple steps ahead estimators. For example, they would use a so-called &#8220;direct forecast&#8221; by fitting a model to the data, producing h-steps ahead in-sample point forecasts from the very first to the very last observation, then calculating the respective h-steps ahead forecast errors and (based on them) Mean Squared Error. Mathematically, this can be written as:</p>
<p>\begin{equation} \label{eq:hstepsMSE}<br />
	\mathrm{MSE}_h = \frac{1}{T-h} \sum_{t=1}^{T-h} e_{t+h|t}^2 ,<br />
\end{equation}<br />
where \(e_{t+h|t}\) is the h-steps ahead error for the point forecast produced from the observation \(t\), and \(T\) is the sample size.</p>
<p>In my final year of PhD, I have decided to analyse how different multistep loss functions work, to understand what happens with dynamic models, when these losses are minimised, and how this can help in efficient model estimation. Doing the literature review, I noticed that the claims about the multistep estimators are sometimes contradictory: some authors say that they are more efficient (i.e. estimates of parameters have lower variances) than the conventional estimators, some say that they are less efficient; some claim that they improve accuracy, while the others do not find any substantial improvements. Finally, I could not find a proper explanation of what happens with the dynamic models when the estimators are used. So, I&#8217;ve started my own investigation, together with Nikos Kourentzes and Rebecca Killick (who was my internal examiner and joined our team after my graduation).</p>
<p>Our investigation started with the single source of error model, then led us to predictive likelihoods and, after that &#8211; to the development of a couple of non-conventional estimators. As a result, the paper grew and became less focused than initially intended. In the end, it became 42 pages long and discussed several aspects of models estimation (making it a bit of a hodgepodge):</p>
<ol>
<li>How multistep estimators regularise parameters of dynamic models;</li>
<li>That multistep forecast errors are always correlated when the models&#8217; parameters are not zero;</li>
<li>What predictive likelihoods align with the multistep estimators (this is useful for a discussion of their statistical properties);</li>
<li>How General Predictive Likelihood encompasses all popular multistep estimators;</li>
<li>And that there is another estimator (namely GTMSE &#8211; Geometric Trace Mean Squared Error), which has good properties and has not been discussed in the literature before.</li>
</ol>
<p>Because of the size of the paper and the spread of the topics throughout it, many reviewers ignored (1) &#8211; (4), focusing on (5) and thus rejecting the paper on the grounds that we propose a new estimator, but instead spend too much time discussing irrelevant topics. These types of comments were given to us by the editor of the Journal of the Royal Statistical Society: B and reviewers of Computational Statistics and Data Analysis. While we tried addressing this issue several times, given the size of the paper, we failed to fix it fully. The paper was rejected from both of these journals and ended up in Computational Statistics, where the editor gave us a chance to respond to the comments. We explained what the paper was really about and changed its focus to satisfy the reviewers, after which the paper was accepted.</p>
<p>So, what are the main findings of this paper?</p>
<h3>How multistep estimators regularise parameters of dynamic models</h3>
<p>Given that any dynamic model (such as ETS or ARIMA) can be represented in the Single Source of Error state space form, we showed that the application of multistep estimators leads to the inclusion of parameters of models in the loss function, leading to the regularisation. In ETS, this means that the smoothing parameters are shrunk to zero, with the shrinkage becoming stronger with the increase of the forecasting horizon relative to the sample size. This makes the models less stochastic and more conservative. Mathematically this becomes apparent if we express the conditional multistep variance in terms of smoothing parameters and one-step-ahead error variance. For example, for ETS(A,N,N) we have:</p>
<p>\begin{equation} \label{eq:hstepsMSEVariance}<br />
	\mathrm{MSE}_h \propto \hat{\sigma}_1^2 \left(1 +(h-1) \hat{\alpha} \right),<br />
\end{equation}<br />
where \( \hat{\alpha} \) is the smoothing parameter and \(\hat{\sigma}_1^2 \) is the one-step-ahead error variance. From the formula \eqref{eq:hstepsMSEVariance}, it becomes apparent that when we minimise MSE\(_h\), the estimated variance and the smoothing parameters will be minimised as well. This is how the shrinkage effect appears: we force \( \hat{\alpha} \) to become as close to zero as possible, and the strength of shrinkage is regulated by the forecasting horizon \( h \).</p>
<p>In the paper itself, we discuss this effect for several multistep estimators (the specific effect would be different between them) and several ETS and ARIMA models. While for ETS, it is easy to show how shrinkage works, for ARIMA, the situation is more complicated because the direction of shrinkage would change with the ARIMA orders. Still, what can be said clearly for any dynamic model is that the multistep estimators make them less stochastic and more conservative.</p>
<h3>Multistep forecast errors are always correlated</h3>
<p>This is a small finding, done in bypassing. It means that, for example, the forecast error two steps ahead is always correlated with the three steps ahead one. This does not depend on the autocorrelation of residuals or any violation of assumptions of the model but rather only on whether the parameters of the model are zero or not. This effect arises from the model rather than from the data. The only situation when the forecast errors will not be correlated is when the model is deterministic (e.g. linear trend). This has important practical implications because some forecasting techniques make explicit and unrealistic assumptions that these correlations are zero, which would impact the final forecasts.</p>
<h3>Predictive likelihoods aligning with the multistep estimators</h3>
<p>We showed that if a model assumes the Normal distribution, in the case of MSEh and MSCE (Mean Squared Cumulative Error), the distribution of the future values follows Normal as well. This means that there are predictive likelihood functions for these models, the maximum of which is achieved with the same set of parameters as the minimum of the multistep estimators. This has two implications:</p>
<ol>
<li>These multistep estimators should be consistent and efficient, especially when the smoothing parameters are close to zero;</li>
<li>The predictive likelihoods can be used in the model selection via information criteria.</li>
</ol>
<p>The first point also explains the contradiction in the literature: if the smoothing parameter in the population is close to zero, then the multistep estimators will give more efficient estimates than the conventional estimators; in the other case, it might be less efficient. We have not used the second point above, but it would be useful when the best model needs to be selected for the data, and an analyst wants to use information criteria. This is one of the potential ways for future research.</p>
<h3>How General Predictive Likelihood (GPL) encompasses all popular multistep estimators</h3>
<p>GPL arises when the joint distribution of 1 to h steps ahead forecast errors is considered. It will be Multivariate Normal if the model assumes normality. In the paper, we showed that the maximum of GPL coincides with the minimum of the so-called &#8220;Generalised Variance&#8221; &#8211; the determinant of the covariance matrix of forecast errors. This minimisation reduces variances for all the forecast errors (from 1 to h) and increases the covariances between them, making the multistep forecast errors look more similar. In the perfect case, when the model is correctly specified (no omitted or redundant variables, homoscedastic residuals etc), the maximum of GPL will coincide with the maximum of the conventional likelihood of the Normal distribution (see <a href="https://openforecast.org/adam/ADAMETSEstimationLikelihood.html">Section 11.1 of the ADAM monograph</a>).</p>
<p>Accidentally, it can be shown that the existing estimators are just special cases of the GPL, but with some restrictions on the covariance matrix. I do not intend to show it here, the reader is encouraged to either read the paper or see the brief discussion <a href="https://openforecast.org/adam/multistepLosses.html#multistepLossesGPL">in Subsection 11.3.5</a> of the ADAM monograph.</p>
<h3>GTMSE &#8211; Geometric Trace Mean Squared Error</h3>
<p>Finally, looking at the special cases of GPL, we have noticed that there is one which has not been discussed in the literature. We called it Geometric Trace Mean Squared Error (GTMSE) because of the logarithms in the formula:<br />
\begin{equation} \label{eq:GTMSE}<br />
	\mathrm{GTMSE} = \sum_{j=1}^h \log \frac{1}{T-j} \sum_{t=1}^{T-j} e_{t+j|t}^2 .<br />
\end{equation}<br />
GTMSE imposes shrinkage on parameters similar to other estimators but does it more mildly because of the logarithms in the formula. In fact, what the logarithms do is make variances of all forecast errors similar to each other. As a result, when used, GTMSE does not focus on the larger variances as other methods do but minimises all of them simultaneously similarly.</p>
<h2>Examples in R</h2>
<p>The estimators discussed in the paper are all implemented in the functions of the smooth package in R, including <code>adam()</code>, <code>es()</code>, <code>ssarima()</code>, <code>msarima()</code> and <code>ces()</code>. In the example below, we will see how the shrinkage works for the ETS on the example of Box-Jenkins sales data (this is the example taken from ADAM, <a href="https://openforecast.org/adam/multistepLosses.html#an-example-in-r-2">Subsection 11.3.7</a>):</p>
<pre class="decode">library(smooth)

adamETSAANBJ <- vector("list",6)
names(adamETSAANBJ) <- c("MSE","MSEh","TMSE","GTMSE","MSCE","GPL")
for(i in 1:length(adamETSAANBJ)){
    adamETSAANBJ[[i]] <- adam(BJsales, "AAN", h=10, holdout=TRUE,
                              loss=names(adamETSAANBJ)[i])
}</pre>
<p>The ETS(A,A,N) model, applied to this data, has different estimates of smoothing parameters:</p>
<pre class="decode">sapply(adamETSAANBJ,"[[","persistence") |>
	round(5)</pre>
<pre>          MSE MSEh TMSE   GTMSE MSCE GPL
alpha 1.00000    1    1 1.00000    1   1
beta  0.23915    0    0 0.14617    0   0</pre>
<p>We can see how shrinkage shows itself in the case of the smoothing parameter \(\beta\), which is shrunk to zero by MSEh, TMSE, MSCE and GPL but left intact by MSE and shrunk a little bit in the case of GTMSE. These different estimates of parameters lead to different forecasting trajectories and prediction intervals, as can be shown visually:</p>
<pre class="decode">par(mfcol=c(3,2), mar=c(2,2,4,1))
# Produce forecasts
lapply(adamETSAANBJ, forecast, h=10, interval="prediction") |>
# Plot forecasts
    lapply(function(x, ...) plot(x, ylim=c(200,280), main=x$model$loss))</pre>
<p>This should result in the following plots:</p>
<div id="attachment_3162" style="width: 1210px" class="wp-caption aligncenter"><a href="https://openforecast.org/wp-content/webpc-passthru.php?src=https://openforecast.org/wp-content/uploads/2023/07/ADAMBJSalesLosses.png&amp;nocache=1"><img loading="lazy" decoding="async" aria-describedby="caption-attachment-3162" src="https://openforecast.org/wp-content/webpc-passthru.php?src=https://openforecast.org/wp-content/uploads/2023/07/ADAMBJSalesLosses.png&amp;nocache=1" alt="ADAM ETS on Box-Jenkins data with several estimators" width="1200" height="700" class="size-full wp-image-3162" srcset="https://openforecast.org/wp-content/webpc-passthru.php?src=https://openforecast.org/wp-content/uploads/2023/07/ADAMBJSalesLosses.png&amp;nocache=1 1200w, https://openforecast.org/wp-content/webpc-passthru.php?src=https://openforecast.org/wp-content/uploads/2023/07/ADAMBJSalesLosses-300x175.png&amp;nocache=1 300w, https://openforecast.org/wp-content/webpc-passthru.php?src=https://openforecast.org/wp-content/uploads/2023/07/ADAMBJSalesLosses-1024x597.png&amp;nocache=1 1024w, https://openforecast.org/wp-content/webpc-passthru.php?src=https://openforecast.org/wp-content/uploads/2023/07/ADAMBJSalesLosses-768x448.png&amp;nocache=1 768w" sizes="auto, (max-width: 1200px) 100vw, 1200px" /></a><p id="caption-attachment-3162" class="wp-caption-text">ADAM ETS on Box-Jenkins data with several estimators</p></div>
<p>Analysing the figure, it looks like the shrinkage of the smoothing parameter \(\beta\) is useful for this time series: the forecasts from ETS(A,A,N) estimated using MSEh, TMSE, MSCE and GPL look closer to the actual values than the ones from MSE and GTMSE. To assess their performance more precisely, we can extract error measures from the models:</p>
<pre class="decode">sapply(adamETSAANBJ,"[[","accuracy") |>
	round(5)[c("ME","MSE"),]</pre>
<pre>         MSE    MSEh    TMSE    GTMSE    MSCE     GPL
ME   3.22900 1.06479 1.05233  3.44962 1.04604 0.95515
MSE 14.41862 2.89067 2.85880 16.26344 2.84288 2.62394</pre>
<p>Alternatively, we can calculate error measures based on the produced forecasts and the <code>measures()</code> function from the <code>greybox</code> package:</p>
<pre class="decode">lapply(adamETSAANBJ, forecast, h=10) |>
    sapply(function(x, ...) measures(holdout=x$model$holdout,
                                     forecast=x$mean,
                                     actual=actuals(x$model)))</pre>
<p>A thing to note about the multistep estimators is that they are slower than the conventional ones because they require producing 1 to \( h \) steps ahead forecasts from every observation in-sample. In the case of the <code>smooth</code> functions, the time elapsed can be extracted from the models in the following way:</p>
<pre class="decode">sapply(adamETSAANBJ, "[[", "timeElapsed")</pre>
<p>In summary, the multistep estimators are potentially useful in forecasting and can produce models with more accurate forecasts. This happens because they impose shrinkage on the estimates of parameters, making models less stochastic and more inert. But their performance depends on each specific situation and the available data, so I would not recommend using them universally.</p>
<p>Message <a href="https://openforecast.org/2023/08/09/multi-step-estimators-and-shrinkage-effect-in-time-series-models/">Multi-step Estimators and Shrinkage Effect in Time Series Models</a> first appeared on <a href="https://openforecast.org">Open Forecasting</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://openforecast.org/2023/08/09/multi-step-estimators-and-shrinkage-effect-in-time-series-models/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>smooth v3.2.0: what&#8217;s new?</title>
		<link>https://openforecast.org/2023/01/30/smooth-v3-2-0-what-s-new/</link>
					<comments>https://openforecast.org/2023/01/30/smooth-v3-2-0-what-s-new/#comments</comments>
		
		<dc:creator><![CDATA[Ivan Svetunkov]]></dc:creator>
		<pubDate>Mon, 30 Jan 2023 13:06:47 +0000</pubDate>
				<category><![CDATA[About es() function]]></category>
		<category><![CDATA[adam()]]></category>
		<category><![CDATA[ARIMA]]></category>
		<category><![CDATA[ETS]]></category>
		<category><![CDATA[Package smooth for R]]></category>
		<category><![CDATA[R]]></category>
		<category><![CDATA[Regression]]></category>
		<category><![CDATA[Univariate models]]></category>
		<category><![CDATA[ADAM]]></category>
		<category><![CDATA[smooth]]></category>
		<guid isPermaLink="false">https://openforecast.org/?p=3063</guid>

					<description><![CDATA[<p>smooth package has reached version 3.2.0 and is now on CRAN. While the version change from 3.1.7 to 3.2.0 looks small, this has introduced several substantial changes and represents a first step in moving to the new C++ code in the core of the functions. In this short post, I will outline the main new [&#8230;]</p>
<p>Message <a href="https://openforecast.org/2023/01/30/smooth-v3-2-0-what-s-new/">smooth v3.2.0: what&#8217;s new?</a> first appeared on <a href="https://openforecast.org">Open Forecasting</a>.</p>
]]></description>
										<content:encoded><![CDATA[<p>smooth package has reached version 3.2.0 and is now <a href="https://cran.r-project.org/package=smooth">on CRAN</a>. While the version change from 3.1.7 to 3.2.0 looks small, this has introduced several substantial changes and represents a first step in moving to the new C++ code in the core of the functions. In this short post, I will outline the main new features of smooth 3.2.0.</p>
<p><a href="https://openforecast.org/wp-content/webpc-passthru.php?src=https://openforecast.org/wp-content/uploads/2023/01/smooth2.png&amp;nocache=1"><img loading="lazy" decoding="async" src="https://openforecast.org/wp-content/webpc-passthru.php?src=https://openforecast.org/wp-content/uploads/2023/01/smooth2-300x218.png&amp;nocache=1" alt="" width="300" height="218" class="aligncenter size-medium wp-image-3065" srcset="https://openforecast.org/wp-content/webpc-passthru.php?src=https://openforecast.org/wp-content/uploads/2023/01/smooth2-300x218.png&amp;nocache=1 300w, https://openforecast.org/wp-content/webpc-passthru.php?src=https://openforecast.org/wp-content/uploads/2023/01/smooth2-1024x745.png&amp;nocache=1 1024w, https://openforecast.org/wp-content/webpc-passthru.php?src=https://openforecast.org/wp-content/uploads/2023/01/smooth2-768x559.png&amp;nocache=1 768w, https://openforecast.org/wp-content/webpc-passthru.php?src=https://openforecast.org/wp-content/uploads/2023/01/smooth2-1536x1117.png&amp;nocache=1 1536w, https://openforecast.org/wp-content/webpc-passthru.php?src=https://openforecast.org/wp-content/uploads/2023/01/smooth2.png&amp;nocache=1 1650w" sizes="auto, (max-width: 300px) 100vw, 300px" /></a></p>
<h3>New engines for ETS, MSARIMA and SMA</h3>
<p>The first and one of the most important changes is the new engine for the ETS (Error-Trend-Seasonal exponential smoothing model), MSARIMA (Multiple Seasonal ARIMA) and SMA (Simple Moving Average), implemented respectively in <code>es()</code>, <code>msarima()</code> and <code>sma()</code> functions. The new engine was developed for <code>adam()</code> and the three models above can be considered as special cases of it. You can read more about ETS in ADAM monograph, starting from<a href="https://openforecast.org/adam/ETSConventional.html"> Chapter 4</a>; MSARIMA is discussed in <a href="https://openforecast.org/adam/ADAMARIMA.html">Chapter 9</a>, while SMA is briefly discussed in <a href="https://openforecast.org/adam/simpleForecastingMethods.html#SMA">Subsection 3.3.3</a>.</p>
<p>The <code>es()</code> function now implements the ETS close to the conventional one, assuming that the error term follows normal distribution. It still supports explanatory variables (discussed in <a href="https://openforecast.org/adam/ADAMX.html">Chapter 10 of ADAM monograph</a>) and advanced estimators (<a href="https://openforecast.org/adam/ADAMETSEstimation.html">Chapter 11</a>), and it has the same syntax as the previous version of the function had, but now acts as a wrapper for <code>adam()</code>. This means that it is now faster, more accurate and requires less memory than it used to. <code>msarima()</code> being a wrapper of <code>adam()</code> as well, is now also faster and more accurate than it used to be. But in addition to that both functions now support the methods that were developed for <code>adam()</code>, including <code>vcov()</code>, <code>confint()</code>, <code>summary()</code>, <code>rmultistep()</code>, <code>reapply()</code>, <code>plot()</code> and others. So, now you can do more thorough analysis and improve the models using all these advanced instruments (see, for example, <a href="https://openforecast.org/adam/diagnostics.html">Chapter 14 of ADAM</a>).</p>
<p>The main reason why I moved the functions to the new engine was to clean up the code and remove the old chunks that were developed when I only started learning C++. A side effect, as you see, is that the functions have now been improved in a variety of ways.</p>
<p>And to be on the safe side, the old versions of the functions are still available in <code>smooth</code> under the names <code>es_old()</code>, <code>msarima_old()</code> and <code>sma_old()</code>. They will be removed from the package if it ever reaches the v.4.0.0.</p>
<h3>New methods for ADAM</h3>
<p>There are two new methods for <code>adam()</code> that can be used in a variety of cases. The first one is <code>simulate()</code>, which will generate data based on the estimated ADAM, whatever the original model is (e.g. mixture of ETS, ARIMA and regression on the data with multiple frequencies). Here is how it can be used:</p>
<pre class="decode">adam(BJsales, "AAdN") |>
     simulate() |>
     plot()</pre>
<p>which will produce a plot similar to the following:</p>
<div id="attachment_3077" style="width: 650px" class="wp-caption aligncenter"><a href="https://openforecast.org/wp-content/webpc-passthru.php?src=https://openforecast.org/wp-content/uploads/2023/01/adamSimulate.png&amp;nocache=1"><img loading="lazy" decoding="async" aria-describedby="caption-attachment-3077" src="https://openforecast.org/wp-content/webpc-passthru.php?src=https://openforecast.org/wp-content/uploads/2023/01/adamSimulate-1024x597.png&amp;nocache=1" alt="Simulated data based on adam() applied to Box-Jenkins sales data" width="640" height="373" class="size-large wp-image-3077" srcset="https://openforecast.org/wp-content/webpc-passthru.php?src=https://openforecast.org/wp-content/uploads/2023/01/adamSimulate-1024x597.png&amp;nocache=1 1024w, https://openforecast.org/wp-content/webpc-passthru.php?src=https://openforecast.org/wp-content/uploads/2023/01/adamSimulate-300x175.png&amp;nocache=1 300w, https://openforecast.org/wp-content/webpc-passthru.php?src=https://openforecast.org/wp-content/uploads/2023/01/adamSimulate-768x448.png&amp;nocache=1 768w, https://openforecast.org/wp-content/webpc-passthru.php?src=https://openforecast.org/wp-content/uploads/2023/01/adamSimulate.png&amp;nocache=1 1200w" sizes="auto, (max-width: 640px) 100vw, 640px" /></a><p id="caption-attachment-3077" class="wp-caption-text">Simulated data based on adam() applied to Box-Jenkins sales data</p></div>
<p>This can be used for research, when a more controlled environment is needed. If you want to fine tune the parameters of ADAM before simulating the data, you can save the output in an object and amend its parameters. For example:</p>
<pre class="decode">testModel <- adam(BJsales, "AAdN")
testModel$persistence <- c(0.5, 0.2)
simulate(testModel)</pre>
<p>The second new method is the <code>xtable()</code> from the respective <code>xtable</code> package. It produces LaTeX version of the table from the summary of ADAM. Here is an example of a summary from ADAM ETS:</p>
<pre class="decode">adam(BJsales, "AAdN") |>
     summary()</pre>
<pre>Model estimated using adam() function: ETS(AAdN)
Response variable: BJsales
Distribution used in the estimation: Normal
Loss function type: likelihood; Loss function value: 256.1516
Coefficients:
      Estimate Std. Error Lower 2.5% Upper 97.5%  
alpha   0.9514     0.1292     0.6960      1.0000 *
beta    0.3328     0.2040     0.0000      0.7358  
phi     0.8560     0.1671     0.5258      1.0000 *
level 203.2835     5.9968   191.4304    215.1289 *
trend  -2.6793     4.7705   -12.1084      6.7437  

Error standard deviation: 1.3623
Sample size: 150
Number of estimated parameters: 6
Number of degrees of freedom: 144
Information criteria:
     AIC     AICc      BIC     BICc 
524.3032 524.8907 542.3670 543.8387</pre>
<p>As you can see in the output above, the function generates the confidence intervals for the parameters of the model, including the smoothing parameters, dampening parameter and the initial states. This summary can then be used to generate the LaTeX code for the main part of the table:</p>
<pre class="decode">adam(BJsales, "AAdN") |>
     xtable()</pre>
<p>which will looks something like this:</p>
<div id="attachment_3073" style="width: 650px" class="wp-caption aligncenter"><a href="https://openforecast.org/wp-content/webpc-passthru.php?src=https://openforecast.org/wp-content/uploads/2023/01/adamXtable.png&amp;nocache=1"><img loading="lazy" decoding="async" aria-describedby="caption-attachment-3073" src="https://openforecast.org/wp-content/webpc-passthru.php?src=https://openforecast.org/wp-content/uploads/2023/01/adamXtable-1024x303.png&amp;nocache=1" alt="Summary of adam()" width="512" height="152" class="size-large wp-image-3073" srcset="https://openforecast.org/wp-content/webpc-passthru.php?src=https://openforecast.org/wp-content/uploads/2023/01/adamXtable-1024x303.png&amp;nocache=1 1024w, https://openforecast.org/wp-content/webpc-passthru.php?src=https://openforecast.org/wp-content/uploads/2023/01/adamXtable-300x89.png&amp;nocache=1 300w, https://openforecast.org/wp-content/webpc-passthru.php?src=https://openforecast.org/wp-content/uploads/2023/01/adamXtable-768x227.png&amp;nocache=1 768w, https://openforecast.org/wp-content/webpc-passthru.php?src=https://openforecast.org/wp-content/uploads/2023/01/adamXtable.png&amp;nocache=1 1207w" sizes="auto, (max-width: 512px) 100vw, 512px" /></a><p id="caption-attachment-3073" class="wp-caption-text">Summary of adam()</p></div>
<h3>Other improvements</h3>
<p>First, one of the major changes in <code>smooth</code> functions is the new backcasting mechanism for <code>adam()</code>, <code>es()</code> and <code>msarima()</code> (this is discussed in <a href="https://openforecast.org/adam/ADAMInitialisation.html">Section 11.4 of ADAM monograph</a>). The main difference with the old one is that now it does not backcast the parameters for the explanatory variables and estimates them separately via optimisation. This feature appeared to be important for some of users who wanted to try MSARIMAX/ETSX (a model with explanatory variables) but wanted to use backcasting as the initialisation. These users then wanted to get a summary, analysing the uncertainty around the estimates of parameters for exogenous variables, but could not because the previous implementation would not estimate them explicitly. This is now available. Here is an example:</p>
<pre class="decode">cbind(BJsales, BJsales.lead) |>
    adam(model="AAdN", initial="backcasting") |>
    summary()</pre>
<pre>Model estimated using adam() function: ETSX(AAdN)
Response variable: BJsales
Distribution used in the estimation: Normal
Loss function type: likelihood; Loss function value: 255.1935
Coefficients:
             Estimate Std. Error Lower 2.5% Upper 97.5%  
alpha          0.9724     0.1108     0.7534      1.0000 *
beta           0.2904     0.1368     0.0199      0.5607 *
phi            0.8798     0.0925     0.6970      1.0000 *
BJsales.lead   0.1662     0.2336    -0.2955      0.6276  

Error standard deviation: 1.3489
Sample size: 150
Number of estimated parameters: 5
Number of degrees of freedom: 145
Information criteria:
     AIC     AICc      BIC     BICc 
520.3870 520.8037 535.4402 536.4841</pre>
<p>As you can see in the output above, the initial level and trend of the model are not reported, because they were estimated via backcasting. However, we get the value of the parameter <code>BJsales.lead</code> and the uncertainty around it. The old backcasting approach is now called "complete", implying that all values of the state vector are produce via backcasting.</p>
<p>Second, <code>forecast.adam()</code> now has a parameter <code>scenarios</code>, which when TRUE will return the simulated paths from the model. This only works when <code>interval="simulated"</code> and can be used for the analysis of possible forecast trajectories.</p>
<p>Third, the <code>plot()</code> method now can also produce ACF/PACF for the squared residuals for all <code>smooth</code> functions. This becomes useful if you suspect that your data has ARCH elements and want to see if they need to be modelled separately. This can also be done using <code>adam()</code> and <code>sm()</code> and is discussed in <a href="https://openforecast.org/adam/ADAMscaleModel.html">Chapter 17 of the monograph</a>.</p>
<p>Finally, the <code>sma()</code> function now has the <code>fast</code> parameter, which when true will use a modified Ternary search for the best order based on information criteria. It might not give the global minimum, but it works much faster than the exhaustive search.</p>
<h3>Conclusions</h3>
<p>These are the main new features in the package. I feel that the main job in <code>smooth</code> is already done, and all I can do now is just tune the functions and improve the existing code. I want to move all the functions to the new engine and ditch the old one, but this requires much more time than I have. So, I don't expect to finish this any time soon, but I hope I'll get there someday. On the other hand, I'm not sure that spending much time on developing an R package is a wise idea, given that nowadays people tend to use Python. I would develop Python analogue of the <code>smooth</code> package, but currently I don't have the necessary expertise and time to do that. Besides, there already exist great libraries, such as <a href="https://github.com/Nixtla/nixtla/tree/main/tsforecast">tsforecast</a> from <a href="https://github.com/Nixtla/nixtla">nixtla</a> and <a href="https://www.sktime.org/">sktime</a>. I am not sure that another library, implementing ETS and ARIMA is needed in Python. What do you think?</p>
<p>Message <a href="https://openforecast.org/2023/01/30/smooth-v3-2-0-what-s-new/">smooth v3.2.0: what&#8217;s new?</a> first appeared on <a href="https://openforecast.org">Open Forecasting</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://openforecast.org/2023/01/30/smooth-v3-2-0-what-s-new/feed/</wfw:commentRss>
			<slash:comments>3</slash:comments>
		
		
			</item>
	</channel>
</rss>
