<?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 About es() function - Open Forecasting</title>
	<atom:link href="https://openforecast.org/category/r-en/smooth/es-function/feed/" rel="self" type="application/rss+xml" />
	<link>https://openforecast.org/category/r-en/smooth/es-function/</link>
	<description>How to look into the future</description>
	<lastBuildDate>Mon, 30 Jan 2023 13:06:47 +0000</lastBuildDate>
	<language>en-GB</language>
	<sy:updatePeriod>
	hourly	</sy:updatePeriod>
	<sy:updateFrequency>
	1	</sy:updateFrequency>
	<generator>https://wordpress.org/?v=7.0</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 About es() function - Open Forecasting</title>
	<link>https://openforecast.org/category/r-en/smooth/es-function/</link>
	<width>32</width>
	<height>32</height>
</image> 
	<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 fetchpriority="high" 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="(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 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="(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 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="(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>
		<item>
		<title>&#8220;smooth&#8221; package for R. Intermittent state-space model. Part I. Introducing the model</title>
		<link>https://openforecast.org/2018/09/18/smooth-package-for-r-intermittent-state-space-model-part-i-introducing-the-model/</link>
					<comments>https://openforecast.org/2018/09/18/smooth-package-for-r-intermittent-state-space-model-part-i-introducing-the-model/#comments</comments>
		
		<dc:creator><![CDATA[Ivan Svetunkov]]></dc:creator>
		<pubDate>Tue, 18 Sep 2018 20:52:14 +0000</pubDate>
				<category><![CDATA[About es() function]]></category>
		<category><![CDATA[Package smooth for R]]></category>
		<category><![CDATA[R]]></category>
		<category><![CDATA[Univariate models]]></category>
		<category><![CDATA[intermittent demand]]></category>
		<category><![CDATA[smooth]]></category>
		<guid isPermaLink="false">https://openforecast.org/?p=1832</guid>

					<description><![CDATA[<p>UPDATE: Starting from smooth v 3.0.0, the occurrence part of the model has been removed from es() and other functions. The only one that implements this now is adam(). This post has been updated on 01 January 2021. UPDATE: Starting from smooth v 2.5.0, the model and the respective functions have changed. Now instead of [&#8230;]</p>
<p>Message <a href="https://openforecast.org/2018/09/18/smooth-package-for-r-intermittent-state-space-model-part-i-introducing-the-model/">&#8220;smooth&#8221; package for R. Intermittent state-space model. Part I. Introducing the model</a> first appeared on <a href="https://openforecast.org">Open Forecasting</a>.</p>
]]></description>
										<content:encoded><![CDATA[<p><strong>UPDATE</strong>: Starting from smooth v 3.0.0, the occurrence part of the model has been removed from <code>es()</code> and other functions. The only one that implements this now is <a href="https://openforecast.org/adam/">adam()</a>. This post has been updated on 01 January 2021.</p>
<p><strong>UPDATE</strong>: Starting from smooth v 2.5.0, the model and the respective functions have changed. Now instead of calling the parameter <span class="lang:r decode:true crayon-inline">intermittent</span> and working with <code>iss()</code>, one needs to use <code>occurrence</code> and <code>oes()</code> respectively. This post has been updated on 25 April 2019.</p>
<hr />
<p>One of the features of functions of smooth package is the ability to work with intermittent data and the data with periodically occurring zeroes.</p>
<p>Intermittent time series is a series that has non-zero values occurring at irregular frequency (<a href="/en/2017/11/07/multiplicative-state-space-models-for-intermittent-time-series/">Svetuknov and Boylan, 2017</a>). Imagine retailer who sells green lipsticks. The demand on such a product will not be easy to predict, because green colour is not a popular colour in this case, and thus the data of sales will contain a lot of zeroes with seldom non-zero values. Such demand is called “intermittent”. In fact, many products exhibit intermittent patterns in sales, especially when we increase the frequency of measurement (how many tomatoes and how often does a store sell per day? What about per hour? Per minute?).</p>
<p>The other case is when watermelons are sold in high quantities over summer and are either not sold at all or sold very seldom in winter. In this case the demand might be intermittent or even absent in winter and have a nature of continuous demand during summer.</p>
<p>smooth functions can work with both of these types of data, building upon mixture distributions.</p>
<p>In this post we will discuss the basic intermittent demand statistical models implemented in the package.</p>
<h3>The model</h3>
<p>First, it is worth pointing out that the approach that is used in the statistical methods and models discussed in this post assumes that the final demand on the product can be split into two parts (<a href="https://doi.org/10.2307/3007885" rel="noopener noreferrer" target="_blank">Croston, 1972</a>):</p>
<ol>
<li>Demand occurrence part, which is represented by a binary variable, which is equal to one when there is a non-zero demand in period \(t\) and zero otherwise;</li>
<li>Demand sizes part, which reflects the amount of sold product when demand occurrence part is equal to one.</li>
</ol>
<p>This can be represented mathematically by the following equation:<br />
\begin{equation} \label{eq:iSS}<br />
	y_t = o_t z_t ,<br />
\end{equation}<br />
where \(o_t\) is the binary demand occurrence variable, \(z_t\) is the demand sizes variable and \(y_t\) is the final demand. This equation was originally proposed by <a href="https://doi.org/10.2307/3007885" rel="noopener noreferrer" target="_blank">Croston, (1972)</a>, although he has never considered the complete statistical model and only proposed a forecasting method.</p>
<p>There are several intermittent demand methods that are usually discussed in forecasting literature: Croston (<a href="https://doi.org/10.2307/3007885" rel="noopener noreferrer" target="_blank">Croston, 1972</a>), SBA (<a href="https://doi.org/10.1057/palgrave.jors.2601841" rel="noopener noreferrer" target="_blank">Syntetos &#038; Boylan, 2000</a>) and TSB (<a href="https://doi.org/10.1016/j.ejor.2011.05.018" rel="noopener noreferrer" target="_blank">Teunter et al., 2011</a>). These are good methods that work well in intermittent demand context (see, for example, <a href="http://10.1016/j.ijpe.2014.06.007" rel="noopener noreferrer" target="_blank">Kourentzes, 2014</a>). The only limitation is that they are the “methods” and not “models”. Having models becomes important when you want to include additional components and produce proper prediction intervals, need the ability to select the appropriate components and do proper statistical inference. So, John Boylan and I developed the model underlying these methods (<a href="/en/2017/11/07/multiplicative-state-space-models-for-intermittent-time-series/">Svetunkov &#038; Boylan, 2017</a>), based on \eqref{eq:iSS}. It is built upon ETS framework, so we call it “iETS”. Given that all the intermittent demand forecasting methods rely on simple exponential smoothing (SES), we suggested to use ETS(M,N,N) model for both demand sizes and demand occurrence parts, because it underlies SES (<a href="https://www.springer.com/gb/book/9783540719168" rel="noopener noreferrer" target="_blank">Hyndman et al., 2008</a>). One of the key assumptions in our model is that demand sizes and demand occurrences are independent of each other. Although, this is an obvious simplification, it is inherited from Croston and TSB, and seems to work well in many contexts.</p>
<p>The iETS(M,N,N) model, discussed in our paper is formulated the following way:<br />
\begin{equation}<br />
	\begin{matrix} \label{eq:iETS}<br />
		y_t = o_t z_t \\<br />
		z_t = l_{z,t-1} \left(1 + \epsilon_t \right) \\<br />
		l_{z,t} = l_{z,t-1}( 1  + \alpha_z \epsilon_t) \\<br />
		o_t \sim \text{Bernoulli}(p_t)<br />
	\end{matrix} ,<br />
\end{equation}<br />
where \(z_t\) is represented by the ETS(M,N,N) model, \(l_{z,t}\) is the level of demand sizes, \(\alpha_z\) is the smoothing parameter and \(\epsilon_t\) is the error term. The important assumption in our implementation of the model is that \(\left(1 + \epsilon_t \right) \sim \text{log}\mathcal{N}(0, \sigma_\epsilon^2) \) &#8211; something that we discussed in <a href="/en/2016/11/18/smooth-package-for-r-es-function-part-iii-multiplicative-models/">one of the previous posts</a>. This means that the demand will always be positive. However if you deal with some other type of data, where negative values are natural, then you might want to stick with <a href="/en/2016/11/02/smooth-package-for-r-es-function-part-ii-pure-additive-models/">pure additive model</a>.</p>
<p>Having this statistical model, makes it extendable, so that one can add trend, seasonal component, or exogenous variables. We don’t discuss these elements in our paper, but it is briefly mentioned in the conclusions. And we don&#8217;t discuss these features just yet, we will cover them in the next post.</p>
<p>Now the main question that stays unanswered is how to model the probability \(p_t\). And there are several approaches to that:</p>
<ol>
<li>iETS\(_F\) &#8211; assume that the demand occurs at random with a fixed probability (so \(p_t = p\)).</li>
<li>iETS\(_O\) &#8211; so called &#8220;Odds Ratio&#8221; model, which uses the logistic curve in order to update the probability. In this case the model is focused on the probability of occurrence of the demand.</li>
<li>iETS\(_I\) &#8211; the &#8220;Inverse Odds Ratio&#8221; model, which uses similar principles to iETS\(_O\), but focusing on the probability of non-occurrence. This model underlies <a href="https://doi.org/10.2307/3007885" rel="noopener noreferrer" target="_blank">Croston (1972)</a> method, but it uses different principles. Instead of updating the probability only when demand occurs, it does that on every observation.</li>
<li>iETS\(_D\) &#8211; the &#8220;Direct probability&#8221; model, which uses the principles, suggested by <a href="https://doi.org/10.1016/j.ejor.2011.05.018" rel="noopener noreferrer" target="_blank">Teunter et al., (2011)</a>. In this case the probability is updated directly based on the values of occurrence variable, using SES method.</li>
<li>iETS\(_G\) &#8211; the &#8220;General&#8221; model, encompassing all above. This model has two sub-models for the demand occurrence, capturing both the probability of occurrence and non-occurrence.</li>
</ol>
<p>In case (1) the model is very basic, and we can just estimate the value of probability and produce forecasts. In cases of (2) &#8211; (5), we suggest using another ETS(M,N,N) model as underlying each of these processes. So when it comes to producing forecasts, in both cases we assume that future level of probability will be the same as the last obtained one (level forecast from the local-level model). After that the final forecast is generated using:<br />
\begin{equation} \label{eq:iSSForecast}<br />
	\hat{y}_t = \hat{p}_t \hat{z}_t ,<br />
\end{equation}<br />
where \(\hat{p}_t\) is the forecast of the probability, \(\hat{z}_t\) is the forecast of demand sizes and \(\hat{y}_t\) is the final forecast of the intermittent demand.</p>
<p>In order to distinguish the whole model \eqref{eq:iETS}, the demand sizes and the demand occurrence parts of the model, different names are used. For example, iETS\(_G\)(M,N,N) would refer to the full model \eqref{eq:iETS}, (\(y_t\)), oETS\(_G\)(M,N,N) would refer to the occurrence part of the model (\(o_t\)) and ETS(M,N,N) refers to the demand sizes part (\(z_t\)). In all these three cases the &#8220;(M,N,N)&#8221; part indicates that the exponential smoothing with multiplicative error, no trend and no seasonality is used. The more advanced notations for the iETS models are available, but they will be discuss in the next post. For now we will stick with the level models and use the shorter names.</p>
<p>Summarising advantages of our framework:</p>
<ol>
<li>Our model is extendable: you can use any ETS model and even introduce exogenous variables. This is already available in <span class="lang:r decode:true crayon-inline">smooth</span> package. In fact, you can use any model you want for demand sizes and a wide variety of models for demand occurrence variable;</li>
<li>The model allows selecting between the aforementioned types of intermittent models (&#8220;fixed&#8221; / &#8220;odds ratio&#8221; / &#8220;inverse odds ratio&#8221; / &#8220;direct&#8221; and &#8220;general&#8221;) using information criteria. This mechanism works fine on large samples, but, unfortunately, does not always work well in cases of small samples;</li>
<li>The model allows producing prediction intervals for several steps ahead and cumulative (over a lead time) upper bound of the intervals. The latter arises naturally from the model and can be used for safety stock calculation;</li>
<li>The estimation of models is done using likelihood function and not some ad-hoc estimators. This means that the estimates of parameters become <a href="/en/2017/11/20/smooth-package-for-r-common-ground-part-ii-estimators/">efficient and consistent</a>;</li>
<li>Although the proposed model is continuous, we show in our paper that it is more accurate than several other integer-valued models. Still, if you want to have integer numbers as your final forecasts, you can round up or round down either the point or prediction intervals, ending up with meaningful values. This can be done due to a connection between the quantiles of rounded values and the rounding of quantiles of continuous variable (discussed in Appendix of <a href="/en/2017/11/07/multiplicative-state-space-models-for-intermittent-time-series/">our paper</a>).</li>
</ol>
<p>If you need more details, have a look at our <a href="/en/2017/11/07/multiplicative-state-space-models-for-intermittent-time-series/">working paper</a> (have I already advertise it enough in this post?).</p>
<h3>Implementation. Demand occurrence</h3>
<p>The aforementioned model with different occurrence types is available in <span class="lang:r decode:true crayon-inline">smooth</span> package. There is a special function for demand occurrence part, called <span class="lang:r decode:true crayon-inline">oes()</span> (Occurrence Exponential Smoothing) and there is a parameter in every smooth forecasting function called <span class="lang:r decode:true crayon-inline">occurrence</span>, which can be one of: &#8220;none&#8221;, &#8220;fixed&#8221;, &#8220;odds-ratio&#8221;, &#8220;inverse-odds-ratio&#8221;, &#8220;direct&#8221;, &#8220;general&#8221; or &#8220;auto&#8221;, corresponding to the sub types of oETS discussed above. The &#8220;auto&#8221; option selects the best occurrence model of the five. For now we will neglect this option and come back to it later.</p>
<p>So, let’s consider an example with artificial data. We create the following time series:</p>
<pre class="decode">x <- c(rpois(25,5),rpois(25,1),rpois(25,0.5),rpois(25,0.1))</pre>
<p>This way we have an artificial data, where both demand sizes and demand occurrence probability decrease over time in a step-wise manner, each 25 observations. The generated data resembles something called "demand obsolescence" or "dying out demand". Let’s start by fitting those five models for the demand occurrence part:</p>
<pre class="decode">oesFixed <- oes(x, occurrence="f", h=25)</pre>
<pre>Occurrence state space model estimated: Fixed probability
Underlying ETS model: oETS[F](MNN)
Smoothing parameters:
level 
    0 
Vector of initials:
level 
 0.55 
Information criteria: 
     AIC     AICc      BIC     BICc 
139.6278 139.6686 142.2329 142.3269</pre>
<pre class="decode">oesOdds <- oes(x, occurrence="o", h=25)</pre>
<pre>Occurrence state space model estimated: Odds ratio
Underlying ETS model: oETS[O](MNN)
Smoothing parameters:
level 
0.828 
Vector of initials:
 level 
14.442 
Information criteria: 
     AIC     AICc      BIC     BICc 
116.3124 116.4361 121.5227 121.8076 </pre>
<pre class="decode">oesInverse <- oes(x, occurrence="i", h=25)</pre>
<pre>Occurrence state space model estimated: Inverse odds ratio
Underlying ETS model: oETS[I](MNN)
Smoothing parameters:
level 
0.116 
Vector of initials:
level 
0.039 
Information criteria: 
     AIC     AICc      BIC     BICc 
 98.5508  98.6745 103.7611 104.0460</pre>
<pre class="decode">oesDirect <- oes(x, occurrence="d", h=25)</pre>
<pre>Occurrence state space model estimated: Direct probability
Underlying ETS model: oETS[D](MNN)
Smoothing parameters:
level 
0.115 
Vector of initials:
level 
0.884 
Information criteria: 
     AIC     AICc      BIC     BICc 
106.5982 106.7219 111.8086 112.0934</pre>
<pre class="decode">oesGeneral <- oes(x, occurrence="g", h=25)</pre>
<pre>Occurrence state space model estimated: General
Underlying ETS model: oETS[G](MNN)(MNN)
Information criteria: 
     AIC     AICc      BIC     BICc 
102.5508 102.9718 112.9715 113.9410</pre>
<p>By looking at the outputs, we can already say that oETS\(_I\) model performs better than the others in terms of information criteria - it has the lowest AIC, as well as the other criteria. This is because this model is more suitable for cases, when demand is dying out, as it focuses on demand non-occurrence. Note that the optimal smoothing parameter for the oETS\(_O\) is quite high. This is because the model is more focused on demand occurrences. If the demand was building out, not dying out in our example, the situation would be different: the oETS\(_O\) would have a lower parameter and oETS\(_I\) would have the higher one. Note that the initial level of oETS\(_I\) is equal to 0.116, which corresponds to \(\frac{1}{1+0.116} \approx 0.89\), which is the probability of occurrence at the beginning of time series.</p>
<p>Note also, that the oETS\(_G\) does not print out details, because it has two models (called modelA and modelB in R), each of which has their own parameters. Here are the outputs of both these models:</p>
<pre class="decode">oesGeneral$modelA
oesGeneral$modelB</pre>
<pre>Occurrence state space model estimated: General
Underlying ETS model: oETS(MNN)_A
Smoothing parameters:
level 
    0 
Vector of initials:
level 
   16 
Information criteria: 
     AIC     AICc      BIC     BICc 
 98.5508  98.6745 103.7611 104.0460

Occurrence state space model estimated: General
Underlying ETS model: oETS(MNN)_B
Smoothing parameters:
level 
0.116 
Vector of initials:
level 
0.628 
Information criteria: 
     AIC     AICc      BIC     BICc 
 98.5508  98.6745 103.7611 104.0460 </pre>
<p>Note that oETS\(_G\) and both models A and B have the same likelihood, because they are all parts of one and the same thing. However, the information criteria differ because they have different number of parameters to estimate: models A and B have 2 parameters each, which means that the whole model has 4 parameters. Also, note that the model A has the smoothing parameter equal to zero, which means that there is no updated of states in that part of model. We will come back to this observation in a moment.</p>
<p>We can also plot the actual occurrence variable, fitted and forecasted probabilities using plot function:</p>
<pre class="decode">plot(oesFixed)</pre>
<p><a href="https://openforecast.org/wp-content/webpc-passthru.php?src=https://openforecast.org/wp-content/uploads/2018/09/oesFixedExample.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/2018/09/oesFixedExample-300x175.png&amp;nocache=1" alt="" width="300" height="175" class="alignnone size-medium wp-image-1968" srcset="https://openforecast.org/wp-content/webpc-passthru.php?src=https://openforecast.org/wp-content/uploads/2018/09/oesFixedExample-300x175.png&amp;nocache=1 300w, https://openforecast.org/wp-content/webpc-passthru.php?src=https://openforecast.org/wp-content/uploads/2018/09/oesFixedExample-768x448.png&amp;nocache=1 768w, https://openforecast.org/wp-content/webpc-passthru.php?src=https://openforecast.org/wp-content/uploads/2018/09/oesFixedExample-1024x597.png&amp;nocache=1 1024w, https://openforecast.org/wp-content/webpc-passthru.php?src=https://openforecast.org/wp-content/uploads/2018/09/oesFixedExample.png&amp;nocache=1 1200w" sizes="auto, (max-width: 300px) 100vw, 300px" /></a></p>
<pre class="decode">plot(oesOdds)</pre>
<p><a href="https://openforecast.org/wp-content/webpc-passthru.php?src=https://openforecast.org/wp-content/uploads/2018/09/oesOddsExample.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/2018/09/oesOddsExample-300x175.png&amp;nocache=1" alt="" width="300" height="175" class="alignnone size-medium wp-image-1966" srcset="https://openforecast.org/wp-content/webpc-passthru.php?src=https://openforecast.org/wp-content/uploads/2018/09/oesOddsExample-300x175.png&amp;nocache=1 300w, https://openforecast.org/wp-content/webpc-passthru.php?src=https://openforecast.org/wp-content/uploads/2018/09/oesOddsExample-768x448.png&amp;nocache=1 768w, https://openforecast.org/wp-content/webpc-passthru.php?src=https://openforecast.org/wp-content/uploads/2018/09/oesOddsExample-1024x597.png&amp;nocache=1 1024w, https://openforecast.org/wp-content/webpc-passthru.php?src=https://openforecast.org/wp-content/uploads/2018/09/oesOddsExample.png&amp;nocache=1 1200w" sizes="auto, (max-width: 300px) 100vw, 300px" /></a></p>
<pre class="decode">plot(oesInverse)</pre>
<p><a href="https://openforecast.org/wp-content/webpc-passthru.php?src=https://openforecast.org/wp-content/uploads/2018/09/oesInverseExample.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/2018/09/oesInverseExample-300x175.png&amp;nocache=1" alt="" width="300" height="175" class="alignnone size-medium wp-image-1970" srcset="https://openforecast.org/wp-content/webpc-passthru.php?src=https://openforecast.org/wp-content/uploads/2018/09/oesInverseExample-300x175.png&amp;nocache=1 300w, https://openforecast.org/wp-content/webpc-passthru.php?src=https://openforecast.org/wp-content/uploads/2018/09/oesInverseExample-768x448.png&amp;nocache=1 768w, https://openforecast.org/wp-content/webpc-passthru.php?src=https://openforecast.org/wp-content/uploads/2018/09/oesInverseExample-1024x597.png&amp;nocache=1 1024w, https://openforecast.org/wp-content/webpc-passthru.php?src=https://openforecast.org/wp-content/uploads/2018/09/oesInverseExample.png&amp;nocache=1 1200w" sizes="auto, (max-width: 300px) 100vw, 300px" /></a></p>
<pre class="decode">plot(oesDirect)</pre>
<p><a href="https://openforecast.org/wp-content/webpc-passthru.php?src=https://openforecast.org/wp-content/uploads/2018/09/oesDirectExample.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/2018/09/oesDirectExample-300x175.png&amp;nocache=1" alt="" width="300" height="175" class="alignnone size-medium wp-image-1967" srcset="https://openforecast.org/wp-content/webpc-passthru.php?src=https://openforecast.org/wp-content/uploads/2018/09/oesDirectExample-300x175.png&amp;nocache=1 300w, https://openforecast.org/wp-content/webpc-passthru.php?src=https://openforecast.org/wp-content/uploads/2018/09/oesDirectExample-768x448.png&amp;nocache=1 768w, https://openforecast.org/wp-content/webpc-passthru.php?src=https://openforecast.org/wp-content/uploads/2018/09/oesDirectExample-1024x597.png&amp;nocache=1 1024w, https://openforecast.org/wp-content/webpc-passthru.php?src=https://openforecast.org/wp-content/uploads/2018/09/oesDirectExample.png&amp;nocache=1 1200w" sizes="auto, (max-width: 300px) 100vw, 300px" /></a></p>
<pre class="decode">plot(oesGeneral)</pre>
<p><a href="https://openforecast.org/wp-content/webpc-passthru.php?src=https://openforecast.org/wp-content/uploads/2018/09/oesGeneralExample.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/2018/09/oesGeneralExample-300x175.png&amp;nocache=1" alt="" width="300" height="175" class="alignnone size-medium wp-image-1969" srcset="https://openforecast.org/wp-content/webpc-passthru.php?src=https://openforecast.org/wp-content/uploads/2018/09/oesGeneralExample-300x175.png&amp;nocache=1 300w, https://openforecast.org/wp-content/webpc-passthru.php?src=https://openforecast.org/wp-content/uploads/2018/09/oesGeneralExample-768x448.png&amp;nocache=1 768w, https://openforecast.org/wp-content/webpc-passthru.php?src=https://openforecast.org/wp-content/uploads/2018/09/oesGeneralExample-1024x597.png&amp;nocache=1 1024w, https://openforecast.org/wp-content/webpc-passthru.php?src=https://openforecast.org/wp-content/uploads/2018/09/oesGeneralExample.png&amp;nocache=1 1200w" sizes="auto, (max-width: 300px) 100vw, 300px" /></a></p>
<p>Note that the different models capture the probability differently. While oETS\(_F\) averages out the probability, all the other models react to the changes in the data, but differently:<br />
odds ratio model is more reactive and seems not to do a good job, trying to keep up after the changes in the data; inverse odds ratio is much smoother; the direct probability model is more reactive, but not as reactive as the odds ratio one; finally the general model replicates the behaviour of the inverse odds ratio model. The latter happens because, as we have seen from the output above, model A in oETS\(_G\) is not updating the states, which means that the general and more complicated model reverts to the special case of oETS\(_I\). Still, it is worth mentioning that all the models predict that the probability will be quite low, which corresponds to the data that we have generated.</p>
<p>Although we could have tried out the more complicated ETS models for the demand occurrence, we will leave this to the next post.</p>
<h3>Implementation. The whole demand</h3>
<p>In order to deal with the intermittent data and produce the forecasts for the whole time series, we can use either <span class="lang:r decode:true crayon-inline">es()</span>, or <span class="lang:r decode:true crayon-inline">ssarima()</span>, or <span class="lang:r decode:true crayon-inline">ces()</span>, or <span class="lang:r decode:true crayon-inline">gum()</span> - all of them have the parameter <span class="lang:r decode:true crayon-inline">occurrence</span>, which is equal to "none" by default. We will use an example of ETS models. In order to simplify things we will use iETS\(_I\) model (because we have noticed that it is more appropriate for the data than the other models):</p>
<pre class="decode">es(x, "MNN", occurrence="i", silent=FALSE, h=25)</pre>
<p><a href="https://openforecast.org/wp-content/webpc-passthru.php?src=https://openforecast.org/wp-content/uploads/2018/09/iETSMNNIMNN.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/2018/09/iETSMNNIMNN-300x175.png&amp;nocache=1" alt="" width="300" height="175" class="alignnone size-medium wp-image-1971" srcset="https://openforecast.org/wp-content/webpc-passthru.php?src=https://openforecast.org/wp-content/uploads/2018/09/iETSMNNIMNN-300x175.png&amp;nocache=1 300w, https://openforecast.org/wp-content/webpc-passthru.php?src=https://openforecast.org/wp-content/uploads/2018/09/iETSMNNIMNN-768x448.png&amp;nocache=1 768w, https://openforecast.org/wp-content/webpc-passthru.php?src=https://openforecast.org/wp-content/uploads/2018/09/iETSMNNIMNN-1024x597.png&amp;nocache=1 1024w, https://openforecast.org/wp-content/webpc-passthru.php?src=https://openforecast.org/wp-content/uploads/2018/09/iETSMNNIMNN.png&amp;nocache=1 1200w" sizes="auto, (max-width: 300px) 100vw, 300px" /></a></p>
<p>The forecast of this model is a straight line, close to zero due to the decrease in both demand sizes and demand occurrence parts. However, knowing that the demand decreases, we can use trend model in this case. And the flexibility of the approach allows us doing that, so we fit ETS(M,M,N) to demand sizes:</p>
<pre class="decode">es(x, "MMN", occurrence="i", silent=FALSE, h=25)</pre>
<p><a href="https://openforecast.org/wp-content/webpc-passthru.php?src=https://openforecast.org/wp-content/uploads/2018/09/iETSMMNIMNN.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/2018/09/iETSMMNIMNN-300x175.png&amp;nocache=1" alt="" width="300" height="175" class="alignnone size-medium wp-image-1972" srcset="https://openforecast.org/wp-content/webpc-passthru.php?src=https://openforecast.org/wp-content/uploads/2018/09/iETSMMNIMNN-300x175.png&amp;nocache=1 300w, https://openforecast.org/wp-content/webpc-passthru.php?src=https://openforecast.org/wp-content/uploads/2018/09/iETSMMNIMNN-768x448.png&amp;nocache=1 768w, https://openforecast.org/wp-content/webpc-passthru.php?src=https://openforecast.org/wp-content/uploads/2018/09/iETSMMNIMNN-1024x597.png&amp;nocache=1 1024w, https://openforecast.org/wp-content/webpc-passthru.php?src=https://openforecast.org/wp-content/uploads/2018/09/iETSMMNIMNN.png&amp;nocache=1 1200w" sizes="auto, (max-width: 300px) 100vw, 300px" /></a></p>
<p>The forecast in this case is even closer to zero and reaches it asymptotically, which means that we foresee that the demand on our product will on average die out.</p>
<p>We can also produce prediction intervals and use model selection for demand sizes. If you know that the data cannot be negative (e.g. selling tomatoes in kilograms), then I would recommend using the pure multiplicative model:</p>
<pre class="decode">es(x, "YYN", occurrence="i", silent=FALSE, h=25, intervals=TRUE)</pre>
<pre>Forming the pool of models based on... MNN, MMN, Estimation progress: 100%... Done! 
Time elapsed: 1.02 seconds
Model estimated: iETS(MMN)
Occurrence model type: Inverse odds ratio
Persistence vector g:
alpha  beta 
0.268 0.000 
Initial values were optimised.
7 parameters were estimated in the process
Residuals standard deviation: 0.386
Cost function type: MSE; Cost function value: 0.149

Information criteria:
     AIC     AICc      BIC     BICc 
333.4377 334.0760 348.5648 339.9301 
95% parametric prediction intervals were constructed</pre>
<p><a href="https://openforecast.org/wp-content/webpc-passthru.php?src=https://openforecast.org/wp-content/uploads/2018/09/iETSYYNIMNN.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/2018/09/iETSYYNIMNN-300x175.png&amp;nocache=1" alt="" width="300" height="175" class="alignnone size-medium wp-image-1973" srcset="https://openforecast.org/wp-content/webpc-passthru.php?src=https://openforecast.org/wp-content/uploads/2018/09/iETSYYNIMNN-300x175.png&amp;nocache=1 300w, https://openforecast.org/wp-content/webpc-passthru.php?src=https://openforecast.org/wp-content/uploads/2018/09/iETSYYNIMNN-768x448.png&amp;nocache=1 768w, https://openforecast.org/wp-content/webpc-passthru.php?src=https://openforecast.org/wp-content/uploads/2018/09/iETSYYNIMNN-1024x597.png&amp;nocache=1 1024w, https://openforecast.org/wp-content/webpc-passthru.php?src=https://openforecast.org/wp-content/uploads/2018/09/iETSYYNIMNN.png&amp;nocache=1 1200w" sizes="auto, (max-width: 300px) 100vw, 300px" /></a></p>
<p>As we can see, the multiplicative trend model appears to be more suitable for our data. Note that the prediction intervals for the model are narrowing down, which is due to the decrease of level of demand. Compare this graph with the one when the pure additive model is selected:</p>
<pre class="decode">es(x, "XXN", occurrence="i", silent=FALSE, h=25, intervals=TRUE)</pre>
<pre>Forming the pool of models based on... ANN, AAN, Estimation progress:    ... Done! 
Time elapsed: 0.23 seconds
Model estimated: iETS(ANN)
Occurrence model type: Inverse odds ratio
Persistence vector g:
alpha 
0.251 
Initial values were optimised.
5 parameters were estimated in the process
Residuals standard deviation: 1.125
Cost function type: MSE; Cost function value: 1.265

Information criteria:
     AIC     AICc      BIC     BICc 
459.8706 460.1206 472.8964 464.2617 
95% parametric prediction intervals were constructed</pre>
<p><a href="https://openforecast.org/wp-content/webpc-passthru.php?src=https://openforecast.org/wp-content/uploads/2018/09/iETSXXNIMNN.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/2018/09/iETSXXNIMNN-300x175.png&amp;nocache=1" alt="" width="300" height="175" class="alignnone size-medium wp-image-1974" srcset="https://openforecast.org/wp-content/webpc-passthru.php?src=https://openforecast.org/wp-content/uploads/2018/09/iETSXXNIMNN-300x175.png&amp;nocache=1 300w, https://openforecast.org/wp-content/webpc-passthru.php?src=https://openforecast.org/wp-content/uploads/2018/09/iETSXXNIMNN-768x448.png&amp;nocache=1 768w, https://openforecast.org/wp-content/webpc-passthru.php?src=https://openforecast.org/wp-content/uploads/2018/09/iETSXXNIMNN-1024x597.png&amp;nocache=1 1024w, https://openforecast.org/wp-content/webpc-passthru.php?src=https://openforecast.org/wp-content/uploads/2018/09/iETSXXNIMNN.png&amp;nocache=1 1200w" sizes="auto, (max-width: 300px) 100vw, 300px" /></a></p>
<p>In the latter case the prediction intervals cover the negative part of the plane which does not make sense in our context. Note also that the information criteria are lower for the multiplicative model, which is due to the changing variance in sample for each 25 observations.</p>
<p>The important thing to note is that although multiplicative trend model sounds solid from the theoretical point of view (it cannot produce negative values), it might be dangerous in cases of small samples and positive trends. In this situation the model can produce exploding trajectory, because the forecast corresponds to the exponent. I don’t have any universal solution for this problem at the moment, but I would recommend using ETS(M,Md,N) (damped multiplicative trend) model instead of ETS(M,M,N). The reason why I don’t recommend ETS(M,A,N), is because in cases of negative trend, with the typically low level of intermittent demand, the updated level might become negative, thus making model inapplicable to the data.</p>
<p>As you see, there is now five new options for the models, which might complicate things in practice. Now we need to understand, how to select the most appropriate model for the demand occurrence between these five and how to make them more flexible, so that the trend and seasonal components are taken into account in demand occurrence, potentially together with some explanatory variables. If we can have a model that does all that, it would make it universal for a wide variety of data... One could only dream... right?</p>
<p>Message <a href="https://openforecast.org/2018/09/18/smooth-package-for-r-intermittent-state-space-model-part-i-introducing-the-model/">&#8220;smooth&#8221; package for R. Intermittent state-space model. Part I. Introducing the model</a> first appeared on <a href="https://openforecast.org">Open Forecasting</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://openforecast.org/2018/09/18/smooth-package-for-r-intermittent-state-space-model-part-i-introducing-the-model/feed/</wfw:commentRss>
			<slash:comments>6</slash:comments>
		
		
			</item>
		<item>
		<title>&#8220;smooth&#8221; package for R. es() function. Part VI. Parameters optimisation</title>
		<link>https://openforecast.org/2017/04/29/smooth-package-for-r-es-function-part-vi-parameters-optimisation/</link>
					<comments>https://openforecast.org/2017/04/29/smooth-package-for-r-es-function-part-vi-parameters-optimisation/#respond</comments>
		
		<dc:creator><![CDATA[Ivan Svetunkov]]></dc:creator>
		<pubDate>Sat, 29 Apr 2017 18:56:21 +0000</pubDate>
				<category><![CDATA[About es() function]]></category>
		<category><![CDATA[Applied forecasting]]></category>
		<category><![CDATA[ETS]]></category>
		<category><![CDATA[Package smooth for R]]></category>
		<category><![CDATA[R]]></category>
		<category><![CDATA[smooth]]></category>
		<guid isPermaLink="false">https://openforecast.org/?p=1212</guid>

					<description><![CDATA[<p>UPDATE: Starting from the v2.5.6 the C parameter has been renamed into B. This is now consistent across all the functions. Now that we looked into the basics of es() function, we can discuss how the optimisation mechanism works, how the parameters are restricted and what are the initials values for the parameters in the [&#8230;]</p>
<p>Message <a href="https://openforecast.org/2017/04/29/smooth-package-for-r-es-function-part-vi-parameters-optimisation/">&#8220;smooth&#8221; package for R. es() function. Part VI. Parameters optimisation</a> first appeared on <a href="https://openforecast.org">Open Forecasting</a>.</p>
]]></description>
										<content:encoded><![CDATA[<p><strong>UPDATE</strong>: Starting from the v2.5.6 the <code>C</code> parameter has been renamed into <code>B</code>. This is now consistent across all the functions.</p>
<p>Now that we looked into the basics of <code>es()</code> function, we can discuss how the optimisation mechanism works, how the parameters are restricted and what are the initials values for the parameters in the optimisation of the function. This will be fairly technical post for the researchers who are interested in the inner (darker) parts of <code>es()</code>.</p>
<p><strong>NOTE</strong>. In this post we will discuss initial values of parameters. Please, don’t confuse this with initial values of components. The former is a wider term, than the latter, because in general it includes the latter. Here I will explain how initialisation is done before the parameters are optimised.</p>
<p>Let’s get started.</p>
<p>Before the optimisation, we need to have some initial values of all the parameters we want to estimate. The number of parameters and initialisation principles depend on the selected model. Let’s go through all of them in details.</p>
<p>The smoothing parameters \(\alpha\), \(\beta\) and \(\gamma\) (for level, trend and seasonal components) for the model with additive error term are set to be equal to 0.3, 0.2 and 0.1, while for the multiplicative one they are equal to 0.1, 0.05 and 0.01 respectively. The motivation here is that we want to have parameters closer to zero in order to smooth the series (although we don’t always get these values), and in case with multiplicative models the parameters need to be very low, otherwise the model may become too sensitive to the noise.</p>
<p>The next important values is the initial of the damping parameter \(\phi\), which is set to be equal to 0.95. We don’t want to start from one, because the damped trend model in this case looses property of damping, but we want to be close to one in order not too enforce the excessive damping.</p>
<p>As for the vector of states, its initial values are set depending on the type of model. First, the following simple model is fit to the first 12 observations of data (if we don’t have 12 observations, than to the whole sample we have):<br />
\begin{equation} \label{eq:simpleregressionAdditive}<br />
	y_t = a_0 + a_1 t + e_t .<br />
\end{equation}<br />
In case with multiplicative trend we use a different model:<br />
\begin{equation} \label{eq:simpleregressionMulti}<br />
	\log(y_t) = a_0 + a_1 t + e_t .<br />
\end{equation}<br />
In both cases \(a_0\) is the intercept, which is used as the initial value of level component and \(a_1\) is the slope of the trend, which is used as the initial of trend component. In case of multiplicative model, exponents of \(a_0\) and \(a_1\) are used. For the case of no trend, a simple average (of the same sample) is used as initial of level component.</p>
<p>In case of seasonal model, the classical seasonal decomposition (&#8220;additive&#8221; or &#8220;multiplicative&#8221; &#8211; depending on the type specified by user) is done using <code>decompose()</code> function, and the seasonal indices are used as initials for the seasonal component.</p>
<p>All the values are then packed in the vector called <code>B</code> in the following order:</p>
<ol>
<li>Vector of smoothing parameters \(\mathbf{g}\) (<code>persistence</code>);</li>
<li>Damping parameter \(\phi\) (<code>phi</code>);</li>
<li>Initial values of non-seasonal part of vector of states \(\mathbf{v}_t\) (<code>initial</code>);</li>
<li>Initial values of seasonal part of vector of states \(\mathbf{v}_t\) (<code>initialSeason</code>);</li>
<p>After that parameters of exogenous variables are added to the vector. We will cover the topic of exogenous variable separately in one of the upcoming posts. The sequence is:</p>
<li>Vector of parameters of exogenous variables \(\mathbf{a}_t\) (<code>initialX</code>);</li>
<li>Transition matrix for exogenous variables (<code>transitionX</code>);</li>
<li>Persistence vector for exogenous variables (<code>persistenceX</code>).</li>
</ol>
<p>Obviously, if we use predefined values of some of those elements, then they are not optimised and skipped during the formation of the vector <code>B</code>. For example, if user specifies parameter initial, then the step (3) is skipped.</p>
<p>There are some restrictions on the estimated parameters values. They are defined in vectors <code>lb</code> and <code>ub</code> (names are taken from the respective parameters of <code>nloptr()</code> function), which have the same length as <code>B</code> and correspond to the same elements as in <code>B</code> (persistence vector, then damping parameter etc). They may vary depending on the value of the parameter bounds. These restrictions are needed in order to find faster the optimal value of the vector <code>B</code>. The majority of them are fairly technical, making sure that the resulting model has meaningful components (for example, multiplicative component should be greater than zero). The only parameter that is worth mentioning separately is the damping parameter \(\phi\). It is allowed to take values between zero and one (including boundary values). In this case the forecasting trajectories do not exhibit explosive behaviour.</p>
<p>Now the vectors <code>lb</code> and <code>ub</code> define general regions for all the parameters, but the bounds of smoothing parameters need finer regulations, because they are connected with each other. That is why they are regulated in the cost function itself. If user defines <code>"usual"</code> bounds, then they are restricted to make sure that:<br />
\begin{equation} \label{eq:boundsUsual}<br />
	\alpha \in [0, 1]; \beta \in [0, \alpha]; \gamma \in [0, 1-\alpha]
\end{equation}<br />
This way the exponential smoothing has property of averaging model, meaning that the weights are distributed over time in an exponential fashion, they are all positive and add up to one, plus the weights of the newer observations are higher than the weights of the older ones.</p>
<p>One of the features that has been introduced in smooth v2.5.3 is that if a parameter takes the boundary values (either zero or one), then it is substituted by that value and the number of parameters is decreased by one. All of that happens only in case of <code>bounds="usual"</code> and either model selection or estimation. Also, if the dampening parameter \(\phi=1\), then the model with damped trend is substituted by non-damped version (e.g. ETS(A,A,N) instead of ETS(A,Ad,N)).</p>
<p>If user defines <code>bounds="admissible"</code> then the eigenvalues of discount matrix are calculated on each iteration. The function makes sure that the selected smoothing parameters guarantee that the eigenvalues lie in the unit circle. This way the model has property of being stable, which means that the weights decrease over time and add up to one. However, on each separate observation they may become negative or greater than one, meaning that the model is no longer an &#8220;averaging&#8221; model.</p>
<p>In the extreme case of <code>bounds="none"</code> the bounds of smoothing parameters are not checked.</p>
<p>In case of violation of bounds for smoothing parameters, the cost function returns a very high number, so the optimiser &#8220;hits the wall&#8221; and goes to the next value.</p>
<p>In order to optimise the model we use function <code>nloptr()</code> from <code>nloptr</code> package. This function implements <a href="http://ab-initio.mit.edu/wiki/index.php/NLopt" target="_blank" rel="noopener noreferrer">non-linear optimisation algorithms</a> written in C. smooth functions use two algorithms: BOBYQA and Nelder-Mead. This is done in two stages: parameters are estimated using the former, after that the returned parameters are used as the initial values for the latter. In cases of mixed models we also check if the parameters returned from the first stage differ from the initial values. If they don’t, then it means that the optimisation failed and BOBYQA is repeated but with the different initial values of the vector of parameters <code>B</code> (smoothing parameters that failed during the optimisation are set equal to zero). If you find that the optimisation did not go well, you can pass two parameters to the functions via ellipsis: maximum number of iterations <code>maxeval</code> and the relative tolerance <code>xtol_rel</code>. The default values and general explanation are given in the documentation of smooth functions.</p>
<p>Overall this optimisation mechanism guarantees that the parameters are close to the optimal values, lie in the meaningful region and satisfy the predefined bounds.</p>
<p>As an example, we will apply <code>es()</code> to the time series N41 from M3.</p>
<p>First, here’s how ETS(A,A,N) with usual bounds looks like on that time series:</p>
<pre class="decode">es(M3$N0041$x,"AAN",bounds="u",h=6)</pre>
<pre>Time elapsed: 0.1 seconds
Model estimated: ETS(AAN)
Persistence vector g:
alpha  beta 
    0     0 
Initial values were optimised.
5 parameters were estimated in the process
Residuals standard deviation: 397.628
Cost function type: MSE; Cost function value: 101640.73

Information criteria:
     AIC     AICc      BIC 
211.1391 218.6391 214.3344</pre>
<p>As we see, in this case the optimal smoothing parameters are equal to zero. This means that we do not take any information into account and just produce the straight line (deterministic trend). See for yourselves:</p>
<div id="attachment_1206" style="width: 310px" class="wp-caption alignnone"><a href="/wp-content/uploads/2017/04/N0041-ETS-AAN-usual.png"><img loading="lazy" decoding="async" aria-describedby="caption-attachment-1206" src="/wp-content/uploads/2017/04/N0041-ETS-AAN-usual-300x175.png" alt="" width="300" height="175" class="size-medium wp-image-1206" srcset="https://openforecast.org/wp-content/webpc-passthru.php?src=https://openforecast.org/wp-content/uploads/2017/04/N0041-ETS-AAN-usual-300x175.png&amp;nocache=1 300w, https://openforecast.org/wp-content/webpc-passthru.php?src=https://openforecast.org/wp-content/uploads/2017/04/N0041-ETS-AAN-usual-768x448.png&amp;nocache=1 768w, https://openforecast.org/wp-content/webpc-passthru.php?src=https://openforecast.org/wp-content/uploads/2017/04/N0041-ETS-AAN-usual-1024x597.png&amp;nocache=1 1024w, https://openforecast.org/wp-content/webpc-passthru.php?src=https://openforecast.org/wp-content/uploads/2017/04/N0041-ETS-AAN-usual.png&amp;nocache=1 1200w" sizes="auto, (max-width: 300px) 100vw, 300px" /></a><p id="caption-attachment-1206" class="wp-caption-text">Series №41 and ETS(A,A,N) with traditional (aka &#8220;usual&#8221;) bounds</p></div>
<p>And here’s what happens with the admissible bounds:</p>
<pre class="decode">es(M3$N0041$x,"AAN",bounds="a",h=6)</pre>
<pre>Time elapsed: 0.11 seconds
Model estimated: ETS(AAN)
Persistence vector g:
alpha  beta 
1.990 0.018 
Initial values were optimised.
5 parameters were estimated in the process
Residuals standard deviation: 327.758
Cost function type: MSE; Cost function value: 69059.107

Information criteria:
     AIC     AICc      BIC 
205.7283 213.2283 208.9236</pre>
<p>The smoothing parameter of the level, \(\alpha\) is greater than one. It is almost two. This means that the exponential smoothing is no longer averaging model, but I can assure you that the model is still stable. Such a high value of smoothing parameter means that the level in time series changes drastically. This is not common and usually not a desired, but possible behaviour of the exponential smoothing. Here how it looks:</p>
<div id="attachment_1203" style="width: 310px" class="wp-caption alignnone"><a href="/wp-content/uploads/2017/04/N0041-ETS-AAN-admissible.png"><img loading="lazy" decoding="async" aria-describedby="caption-attachment-1203" src="/wp-content/uploads/2017/04/N0041-ETS-AAN-admissible-300x175.png" alt="" width="300" height="175" class="size-medium wp-image-1203" srcset="https://openforecast.org/wp-content/webpc-passthru.php?src=https://openforecast.org/wp-content/uploads/2017/04/N0041-ETS-AAN-admissible-300x175.png&amp;nocache=1 300w, https://openforecast.org/wp-content/webpc-passthru.php?src=https://openforecast.org/wp-content/uploads/2017/04/N0041-ETS-AAN-admissible-768x448.png&amp;nocache=1 768w, https://openforecast.org/wp-content/webpc-passthru.php?src=https://openforecast.org/wp-content/uploads/2017/04/N0041-ETS-AAN-admissible-1024x597.png&amp;nocache=1 1024w, https://openforecast.org/wp-content/webpc-passthru.php?src=https://openforecast.org/wp-content/uploads/2017/04/N0041-ETS-AAN-admissible.png&amp;nocache=1 1200w" sizes="auto, (max-width: 300px) 100vw, 300px" /></a><p id="caption-attachment-1203" class="wp-caption-text">Series №41 and ETS(A,A,N) with admissible bounds</p></div>
<p>Here I would like to note that model can be stable even with negative smoothing parameters. So don’t be scared. If the model is not stable, the function will warn you.</p>
<p>Last but not least, user can regulate values of <code>B</code>, <code>lb</code> and <code>ub</code> vectors for the first optimisation stage. Model selection does not work with the provided vectors of initial parameters, because the length of <code>B</code>, <code>lb</code> and <code>ub</code> vectors is fixed, while in the case of model selection it will vary from model to model. User also needs to make sure that the length of each of the vectors is correct and corresponds to the selected model. The values are passed via the ellipses, the following way:</p>
<pre class="decode">B <- c(0.2, 0.1, M3$N0041$x[1], diff(M3$N0041$x)[1])
es(M3$N0041$x,"AAN",B=B,h=6,bounds="u")</pre>
<pre>Time elapsed: 0.1 seconds
Model estimated: ETS(AAN)
Persistence vector g:
alpha  beta 
    1     0 
Initial values were optimised.
5 parameters were estimated in the process
Residuals standard deviation: 429.923
Cost function type: MSE; Cost function value: 118821.938

Information criteria:
     AIC     AICc      BIC 
213.3256 220.8256 216.5209</pre>
<p>In this case we reached boundary values for both level and trend smoothing parameters. The resulting model has constantly changing level (random walk level) and deterministic trend. This is a weird, but possible combination. The fit and forecast looks similar to the model with the admissible bounds, but not as reactive:</p>
<div id="attachment_1205" style="width: 310px" class="wp-caption alignnone"><a href="/wp-content/uploads/2017/04/N0041-ETS-AAN-tuned.png"><img loading="lazy" decoding="async" aria-describedby="caption-attachment-1205" src="/wp-content/uploads/2017/04/N0041-ETS-AAN-tuned-300x175.png" alt="" width="300" height="175" class="size-medium wp-image-1205" srcset="https://openforecast.org/wp-content/webpc-passthru.php?src=https://openforecast.org/wp-content/uploads/2017/04/N0041-ETS-AAN-tuned-300x175.png&amp;nocache=1 300w, https://openforecast.org/wp-content/webpc-passthru.php?src=https://openforecast.org/wp-content/uploads/2017/04/N0041-ETS-AAN-tuned-768x448.png&amp;nocache=1 768w, https://openforecast.org/wp-content/webpc-passthru.php?src=https://openforecast.org/wp-content/uploads/2017/04/N0041-ETS-AAN-tuned-1024x597.png&amp;nocache=1 1024w, https://openforecast.org/wp-content/webpc-passthru.php?src=https://openforecast.org/wp-content/uploads/2017/04/N0041-ETS-AAN-tuned.png&amp;nocache=1 1200w" sizes="auto, (max-width: 300px) 100vw, 300px" /></a><p id="caption-attachment-1205" class="wp-caption-text">Series №41 and ETS(A,A,N) with traditional bounds and non-standard initials</p></div>
<p>Using this functionality, you may end up with ridiculous and meaningless models, so be aware and be careful. For example, the following does not have any sense from forecasting perspective:</p>
<pre class="decode">B <- c(2.5, 1.1, M3$N0041$x[1], diff(M3$N0041$x)[1])
lb <- c(1,1, 0, -Inf)
ub <- c(3,3, Inf, Inf)
es(M3$N0041$x,"AAN",B=B, lb=lb, ub=ub, bounds="none",h=6)</pre>
<pre>Time elapsed: 0.12 seconds
Model estimated: ETS(AAN)
Persistence vector g:
alpha  beta 
2.483 1.093 
Initial values were optimised.
5 parameters were estimated in the process
Residuals standard deviation: 193.328
Cost function type: MSE; Cost function value: 24027.222

Information criteria:
     AIC     AICc      BIC 
190.9475 198.4475 194.1428 
Warning message:
Model ETS(AAN) is unstable! Use a different value of 'bounds' parameter to address this issue!</pre>
<p>Although the fit is very good and the model approximates data better than all the others (MSE value is 24027 versus 70000 – 120000 of other models), the model is unstable (the function warns us about that), meaning that the weights are distributed in an unreasonable way: the older observations become more important than the newer ones. The forecast of such a model is meaningless and most probably is biased and not accurate. Here how it looks:</p>
<div id="attachment_1204" style="width: 310px" class="wp-caption alignnone"><a href="/wp-content/uploads/2017/04/N0041-ETS-AAN-crazy.png"><img loading="lazy" decoding="async" aria-describedby="caption-attachment-1204" src="/wp-content/uploads/2017/04/N0041-ETS-AAN-crazy-300x175.png" alt="" width="300" height="175" class="size-medium wp-image-1204" srcset="https://openforecast.org/wp-content/webpc-passthru.php?src=https://openforecast.org/wp-content/uploads/2017/04/N0041-ETS-AAN-crazy-300x175.png&amp;nocache=1 300w, https://openforecast.org/wp-content/webpc-passthru.php?src=https://openforecast.org/wp-content/uploads/2017/04/N0041-ETS-AAN-crazy-768x448.png&amp;nocache=1 768w, https://openforecast.org/wp-content/webpc-passthru.php?src=https://openforecast.org/wp-content/uploads/2017/04/N0041-ETS-AAN-crazy-1024x597.png&amp;nocache=1 1024w, https://openforecast.org/wp-content/webpc-passthru.php?src=https://openforecast.org/wp-content/uploads/2017/04/N0041-ETS-AAN-crazy.png&amp;nocache=1 1200w" sizes="auto, (max-width: 300px) 100vw, 300px" /></a><p id="caption-attachment-1204" class="wp-caption-text">Series №41 and ETS(A,A,N) with crazy bounds</p></div>
<p>So be careful with manual tuning of the optimiser.</p>
<p>Have fun but be reasonable!</p>
<p>Message <a href="https://openforecast.org/2017/04/29/smooth-package-for-r-es-function-part-vi-parameters-optimisation/">&#8220;smooth&#8221; package for R. es() function. Part VI. Parameters optimisation</a> first appeared on <a href="https://openforecast.org">Open Forecasting</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://openforecast.org/2017/04/29/smooth-package-for-r-es-function-part-vi-parameters-optimisation/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>&#8220;smooth&#8221; package for R. es() function. Part V. Essential parameters</title>
		<link>https://openforecast.org/2017/03/05/smooth-package-for-r-es-function-part-v-essential-parameters/</link>
					<comments>https://openforecast.org/2017/03/05/smooth-package-for-r-es-function-part-v-essential-parameters/#respond</comments>
		
		<dc:creator><![CDATA[Ivan Svetunkov]]></dc:creator>
		<pubDate>Sun, 05 Mar 2017 00:00:58 +0000</pubDate>
				<category><![CDATA[About es() function]]></category>
		<category><![CDATA[Applied forecasting]]></category>
		<category><![CDATA[ETS]]></category>
		<category><![CDATA[Package smooth for R]]></category>
		<category><![CDATA[R]]></category>
		<category><![CDATA[smooth]]></category>
		<guid isPermaLink="false">https://openforecast.org/?p=1117</guid>

					<description><![CDATA[<p>While the previous posts on es() function contained two parts: theory of ETS and then the implementation &#8211; this post will cover only the latter. We won&#8217;t discuss anything new, we will mainly look into several parameters that the exponential smoothing function has and what they allow us to do. We start with initialisation of [&#8230;]</p>
<p>Message <a href="https://openforecast.org/2017/03/05/smooth-package-for-r-es-function-part-v-essential-parameters/">&#8220;smooth&#8221; package for R. es() function. Part V. Essential parameters</a> first appeared on <a href="https://openforecast.org">Open Forecasting</a>.</p>
]]></description>
										<content:encoded><![CDATA[<p>While the previous posts on <code>es()</code> function contained two parts: theory of ETS and then the implementation &#8211; this post will cover only the latter. We won&#8217;t discuss anything new, we will mainly look into several parameters that the exponential smoothing function has and what they allow us to do.</p>
<p>We start with initialisation of <code>es()</code>.</p>
<p>History of exponential smoothing counts dozens of methods of initialisation. Some of them are fine, some of them are very wrong. Some of those methods allow preserving data, the others unnecessarily consume parts of time series. I have implemented ETS in a way that allows initialising it before the sample starts. So the state vector \(v_t\) discussed in parts <a href="/en/2016/11/02/smooth-package-for-r-es-function-part-ii-pure-additive-models/">2</a> and <a href="/en/2016/11/18/smooth-package-for-r-es-function-part-iii-multiplicative-models/">3</a>, is defined before the very first observation \(y_1\). This is consistent with <a href="https://www.springer.com/gp/book/9783540719168">Hyndman et al. (2008)</a> approach. Still this initial value can be defined using different methods:</p>
<ol>
<li><strong>Optimisation</strong>. This means that the initial value is found along with the smoothing parameters. This can be triggered by <code>initial="optimal"</code> and is the default method in <code>es()</code>.</li>
<p>While the optimisation works perfectly fine on monthly data, there may be some problems with weekly and daily seasonal data. The reason for that is a high number of parameters that need to be estimated. For example, ETS(M,N,M) on weekly seasonal data will have 52 + 1 + 2 + 1 = 56 parameters to estimate (52 seasonal indices, 1 level component, 2 smoothing parameters and 1 variance of residuals). This is not an easy task which sometimes cannot be efficiently solved. That is why we may need other initialisation methods.</p>
<p>Let’s see what happens when we encounter this problem in an example. I will use time series <code>taylor</code> from <code>forecast</code> package. This is half-hourly electricity demand data. It has frequency of 336 (7 days * 48 half-hours) and is really hard to work with when the standard initialisation is used. Let’s see what happens when <code>es()</code> is applied with model selection and a holdout of one week of data:</p>
<pre class="decode">es(taylor,"ZZZ",h=336,holdout=TRUE)</pre>
<pre>
Forming the pool of models based on... ANN, ANA, ANM, AAA, Estimation progress: 100%... Done! 
Time elapsed: 18.47 seconds
Model estimated: ETS(ANA)
Persistence vector g:
alpha gamma 
0.850 0.001 
Initial values were optimised.
340 parameters were estimated in the process
Residuals standard deviation: 250.546
Cost function type: MSE; Cost function value: 56999

Information criteria:
     AIC     AICc      BIC 
51642.90 51712.02 53756.01 
Forecast errors:
MPE: 1%; Bias: 50%; MAPE: 1.8%; SMAPE: 1.8%
MASE: 0.798; sMAE: 1.8%; RelMAE: 0.078; sMSE: 0.1%</pre>
<p>We had to estimate 340 parameters and the model selection took 18 seconds (checking only 5 models in the pool). We ended up with the following graph:</p>
<div id="attachment_1120" style="width: 310px" class="wp-caption alignnone"><a href="/wp-content/uploads/2017/03/taylor-es-ANA-optimal.png"><img loading="lazy" decoding="async" aria-describedby="caption-attachment-1120" src="/wp-content/uploads/2017/03/taylor-es-ANA-optimal-300x175.png" alt="" width="300" height="175" class="size-medium wp-image-1120" srcset="https://openforecast.org/wp-content/webpc-passthru.php?src=https://openforecast.org/wp-content/uploads/2017/03/taylor-es-ANA-optimal-300x175.png&amp;nocache=1 300w, https://openforecast.org/wp-content/webpc-passthru.php?src=https://openforecast.org/wp-content/uploads/2017/03/taylor-es-ANA-optimal-768x448.png&amp;nocache=1 768w, https://openforecast.org/wp-content/webpc-passthru.php?src=https://openforecast.org/wp-content/uploads/2017/03/taylor-es-ANA-optimal-1024x597.png&amp;nocache=1 1024w, https://openforecast.org/wp-content/webpc-passthru.php?src=https://openforecast.org/wp-content/uploads/2017/03/taylor-es-ANA-optimal.png&amp;nocache=1 1200w" sizes="auto, (max-width: 300px) 100vw, 300px" /></a><p id="caption-attachment-1120" class="wp-caption-text">Electricity demand series with ETS(A,N,A) initialised using optimisation and its forecast</p></div>
<p>The first thing that can be noticed is the initial value of level, which results in a wrong one step ahead forecast for one of the first observations. This is because of the high number of parameters &#8211; the optimiser could not find the appropriate values. This could be not important, taking number of observations in the data, but still may influence the final forecast and, what is more important, the model selection. Some of models could have been initialised slightly better than the others, which could lead to a smaller value of information criterion for those models that should not have been selected.</p>
<p>This example motivates the other initialisation mechanisms.</p>
<li><strong>Backcasting</strong>. In order to define the initial value model is fitted to data several times going forward and backwards. For example, for ETS(A,N,N) the formula used for the forward is:</li>
<p>\begin{equation} \label{eq:ETSANN_Forward}<br />
\begin{matrix}<br />
	y_t = l_{t-1} + \epsilon_t \\<br />
	l_t = l_{t-1} + \alpha \epsilon_t<br />
\end{matrix}<br />
\end{equation}<br />
while for the backwards it should be changed to:<br />
\begin{equation} \label{eq:ETSANN_Backward}<br />
\begin{matrix}<br />
	y_t = l_{t+1} + \epsilon_t \\<br />
	l_t = l_{t+1} + \alpha \epsilon_t<br />
\end{matrix}<br />
\end{equation}</p>
<p>As you see, the only thing that changes is the lower index of level component. The formula \eqref{eq:ETSANN_Forward} is used for fitting of the model to the data starting from the first observation till the end of series. When we reach the end of series, we use formula \eqref{eq:ETSANN_Backward} and move from the last observation to the very first one. Then we produce forecast back in time before the initial \(y_1\) and obtain the initial values for the components. The model is then fit to the data using these initials. This procedure can be repeated several times in order to get more accurate estimates of the initial values. In <code>es()</code> it is done 3 times and can be triggered by <code>initial="backcasting"</code>. As mentioned above this method of initialisation is recommended for data with high seasonality frequencies (weekly, daily, hourly etc).</p>
<p>As an example, we will use the same time series from forecast package:</p>
<pre class="decode">es(taylor,"ZZZ",h=336,holdout=TRUE,initial="b")</pre>
<p>This time all the process takes around 7 seconds:</p>
<pre>
Forming the pool of models based on... ANN, ANA, ANM, AAA, Estimation progress: 100%... Done! 
Time elapsed: 6.81 seconds
Model estimated: ETS(MNA)
Persistence vector g:
alpha gamma 
    1     0 
Initial values were produced using backcasting.
3 parameters were estimated in the process
Residuals standard deviation: 0.007
Cost function type: MSE; Cost function value: 38238

Information criteria:
     AIC     AICc      BIC 
49493.46 49493.47 49512.11 
Forecast errors:
MPE: 0.8%; Bias: 40.6%; MAPE: 1.7%; SMAPE: 1.8%
MASE: 0.784; sMAE: 1.7%; RelMAE: 0.076; sMSE: 0.1%</pre>
<p>The function has checked the same pool of models and selected ETS(M,N,A) as the optimal model (estimating only 3 parameters). We ended up with a peculiar model, where smoothing parameter for the level is equal to one (meaning that we have random walk in the level) and the other parameter equal to zero (meaning that we have deterministic seasonality).</p>
<p>The graph of the model now looks reasonable:</p>
<div id="attachment_1123" style="width: 310px" class="wp-caption alignnone"><a href="/wp-content/uploads/2017/03/taylor-es-MNA-backcasting.png"><img loading="lazy" decoding="async" aria-describedby="caption-attachment-1123" src="/wp-content/uploads/2017/03/taylor-es-MNA-backcasting-300x175.png" alt="" width="300" height="175" class="size-medium wp-image-1123" srcset="https://openforecast.org/wp-content/webpc-passthru.php?src=https://openforecast.org/wp-content/uploads/2017/03/taylor-es-MNA-backcasting-300x175.png&amp;nocache=1 300w, https://openforecast.org/wp-content/webpc-passthru.php?src=https://openforecast.org/wp-content/uploads/2017/03/taylor-es-MNA-backcasting-768x448.png&amp;nocache=1 768w, https://openforecast.org/wp-content/webpc-passthru.php?src=https://openforecast.org/wp-content/uploads/2017/03/taylor-es-MNA-backcasting-1024x597.png&amp;nocache=1 1024w, https://openforecast.org/wp-content/webpc-passthru.php?src=https://openforecast.org/wp-content/uploads/2017/03/taylor-es-MNA-backcasting.png&amp;nocache=1 1200w" sizes="auto, (max-width: 300px) 100vw, 300px" /></a><p id="caption-attachment-1123" class="wp-caption-text">Electricity demand series with ETS(M,N,A) initialised using backcasting and its forecast</p></div>
<p>As it can be seen from the Figure, backcasting is not a bad technique and it can be useful in cases when we have a data with high frequencies. Furthermore, there is a proof that backcasting asymptotically gives the same estimates as least squares, meaning that both optimal and backcasted estimates of initial values should eventually converge to the same values.</p>
<li><strong>Arbitrary values</strong>. If for some reason we know initial values (either from a previous data or from similar data), then we can provide them to <code>es()</code>. In this case we may provide two parameters: <code>initial</code> and <code>initialSeason</code>. The function will then use the provided values and fit the model. We can provide both of them or just one of them, meaning that the other will be estimated during the optimisation. Obviously if we deal with non-seasonal model, we don’t need <code>initialSeason</code> at all. A thing to note is that we cannot use backcasting when we define parameters manually. The other important thing to note is that the model selection and combinations do not work with predefined initial values, so this method of initialisation is not available when we need to <a href="/en/2017/01/24/smooth-package-for-r-es-function-part-iv-model-selection-and-combination-of-forecasts/">select the best model or combine several forecasts</a> using <code>es()</code>.</li>
</ol>
<p>Continuing our example, we will use classical decomposition and construct ETS(M,N,M) model</p>
<pre class="decode">ourFigure <- decompose(taylor,type="m")$figure
es(taylor,"MNM",h=336,holdout=TRUE,initial=mean(taylor),initialSeason=ourFigure)</pre>
<pre>
Time elapsed: 3.97 seconds
Model estimated: ETS(MNM)
Persistence vector g:
alpha gamma 
    1     0 
Initial values were provided by user.
340 parameters were estimated in the process
Residuals standard deviation: 0.007
Cost function type: MSE; Cost function value: 37783

Information criteria:
     AIC     AICc      BIC 
50123.24 50192.36 52236.34 
Forecast errors:
MPE: 0.7%; Bias: 35%; MAPE: 1.6%; SMAPE: 1.7%
MASE: 0.738; sMAE: 1.6%; RelMAE: 0.072; sMSE: 0.1%</pre>
<p>We can even compare results of this call with other initialisation methods:</p>
<pre class="decode">es(taylor,"MNM",h=336,holdout=TRUE,initial="o")</pre>
<pre>
Time elapsed: 13.13 seconds
Model estimated: ETS(MNM)
Persistence vector g:
alpha gamma 
0.919 0.000 
Initial values were optimised.
340 parameters were estimated in the process
Residuals standard deviation: 0.009
Cost function type: MSE; Cost function value: 56381

Information criteria:
     AIC     AICc      BIC 
51602.59 51671.70 53715.69 
Forecast errors:
MPE: 0.9%; Bias: 40.6%; MAPE: 1.8%; SMAPE: 1.8%
MASE: 0.791; sMAE: 1.7%; RelMAE: 0.077; sMSE: 0.1%</pre>
<pre class="decode">es(taylor,"MNM",h=336,holdout=TRUE,initial="b")</pre>
<pre>
Time elapsed: 6.52 seconds
Model estimated: ETS(MNM)
Persistence vector g:
alpha gamma 
    1     0 
Initial values were produced using backcasting.
3 parameters were estimated in the process
Residuals standard deviation: 0.007
Cost function type: MSE; Cost function value: 37272

Information criteria:
     AIC     AICc      BIC 
49398.88 49398.89 49417.52 
Forecast errors:
MPE: 0.8%; Bias: 33.8%; MAPE: 1.7%; SMAPE: 1.8%
MASE: 0.786; sMAE: 1.7%; RelMAE: 0.076; sMSE: 0.1%</pre>
<p>Estimation in this case takes approximately four seconds (on my PC), while for <code>initial="o"</code> it takes around 13 seconds and for <code>initial="b"</code> - near seven seconds. The resulting models in these cases look very similar, with the first model producing slightly more accurate forecasts.</p>
<p>This method of initialisation may be used when the other two methods for some reason do not work as expected (for example, take too much computational time) and/ or when we know the values from some reliable sources (for example, from previously fitted model to the same or similar data). It can also be used for fun and experiments with ETS. In all the other cases I would not recommend using it.</p>
<p>There are other exciting parameters in <code>es()</code> that can be controlled. They allow to switch between optimised and predefined values. For example, parameter persistence accepts vector of smoothing parameters, the length of which should correspond to the number of components in the model, while parameter phi defines damping parameter. So, for example, ETS(A,Ad,N) fitted to a time series N1234 from M3 can be constructed using:</p>
<pre class="decode">es(M3$N1234$x,"AAdN",h=8,persistence=c(0.2,0.1),phi=0.95)</pre>
<p>Compare the resulting graph:</p>
<div id="attachment_1127" style="width: 310px" class="wp-caption alignnone"><a href="/wp-content/uploads/2017/03/N1234-AAdN-predefined-parameters.png"><img loading="lazy" decoding="async" aria-describedby="caption-attachment-1127" src="/wp-content/uploads/2017/03/N1234-AAdN-predefined-parameters-300x175.png" alt="" width="300" height="175" class="size-medium wp-image-1127" srcset="https://openforecast.org/wp-content/webpc-passthru.php?src=https://openforecast.org/wp-content/uploads/2017/03/N1234-AAdN-predefined-parameters-300x175.png&amp;nocache=1 300w, https://openforecast.org/wp-content/webpc-passthru.php?src=https://openforecast.org/wp-content/uploads/2017/03/N1234-AAdN-predefined-parameters-768x448.png&amp;nocache=1 768w, https://openforecast.org/wp-content/webpc-passthru.php?src=https://openforecast.org/wp-content/uploads/2017/03/N1234-AAdN-predefined-parameters-1024x597.png&amp;nocache=1 1024w, https://openforecast.org/wp-content/webpc-passthru.php?src=https://openforecast.org/wp-content/uploads/2017/03/N1234-AAdN-predefined-parameters.png&amp;nocache=1 1200w" sizes="auto, (max-width: 300px) 100vw, 300px" /></a><p id="caption-attachment-1127" class="wp-caption-text">Series N1234 and ETS(A,Ad,N) fit to it with predefined parameters</p></div>
<p>with the one from optimised model:</p>
<pre class="decode">es(M3$N1234$x,"AAdN",h=8)</pre>
<div id="attachment_1128" style="width: 310px" class="wp-caption alignnone"><a href="/wp-content/uploads/2017/03/N1234-AAdN-optimal.png"><img loading="lazy" decoding="async" aria-describedby="caption-attachment-1128" src="/wp-content/uploads/2017/03/N1234-AAdN-optimal-300x175.png" alt="" width="300" height="175" class="size-medium wp-image-1128" srcset="https://openforecast.org/wp-content/webpc-passthru.php?src=https://openforecast.org/wp-content/uploads/2017/03/N1234-AAdN-optimal-300x175.png&amp;nocache=1 300w, https://openforecast.org/wp-content/webpc-passthru.php?src=https://openforecast.org/wp-content/uploads/2017/03/N1234-AAdN-optimal-768x448.png&amp;nocache=1 768w, https://openforecast.org/wp-content/webpc-passthru.php?src=https://openforecast.org/wp-content/uploads/2017/03/N1234-AAdN-optimal-1024x597.png&amp;nocache=1 1024w, https://openforecast.org/wp-content/webpc-passthru.php?src=https://openforecast.org/wp-content/uploads/2017/03/N1234-AAdN-optimal.png&amp;nocache=1 1200w" sizes="auto, (max-width: 300px) 100vw, 300px" /></a><p id="caption-attachment-1128" class="wp-caption-text">Series N1234 and ETS(A,Ad,N) fit to it with optimised parameters</p></div>
<p>I cannot say which of them is better in means of accuracy, but if you really need to define those parameters manually (for example, when applying one and the same model to a large set of time series), then you can easily do it, and now you know how.</p>
<p>One other cool thing about <code>es()</code> is that it saves all the discussed above values and returns them as a list. So you can save a model and then reuse the parameters. For example, let’s select the best model and save it:</p>
<pre class="decode">ourModel <- es(M3$N1234$x,"ZZZ",h=8,holdout=TRUE)</pre>
<p>Which gives us:</p>
<div id="attachment_1130" style="width: 310px" class="wp-caption alignnone"><a href="/wp-content/uploads/2017/03/N1234-MAN-optimal.png"><img loading="lazy" decoding="async" aria-describedby="caption-attachment-1130" src="/wp-content/uploads/2017/03/N1234-MAN-optimal-300x175.png" alt="" width="300" height="175" class="size-medium wp-image-1130" srcset="https://openforecast.org/wp-content/webpc-passthru.php?src=https://openforecast.org/wp-content/uploads/2017/03/N1234-MAN-optimal-300x175.png&amp;nocache=1 300w, https://openforecast.org/wp-content/webpc-passthru.php?src=https://openforecast.org/wp-content/uploads/2017/03/N1234-MAN-optimal-768x448.png&amp;nocache=1 768w, https://openforecast.org/wp-content/webpc-passthru.php?src=https://openforecast.org/wp-content/uploads/2017/03/N1234-MAN-optimal-1024x597.png&amp;nocache=1 1024w, https://openforecast.org/wp-content/webpc-passthru.php?src=https://openforecast.org/wp-content/uploads/2017/03/N1234-MAN-optimal.png&amp;nocache=1 1200w" sizes="auto, (max-width: 300px) 100vw, 300px" /></a><p id="caption-attachment-1130" class="wp-caption-text">Series N1234 and ETS(M,A,N) fit to it with optimised parameters</p></div>
<p>Now we will use a small but neat function called <code>modelType()</code>, which extracts type of model, and use exactly the same model with exactly the same parameters but with a larger sample:</p>
<pre class="decode">es(M3$N1234$x,modelType(ourModel),h=8,holdout=FALSE,initial=ourModel$initial,persistence=ourModel$persistence,phi=ourModel$phi)</pre>
<p>This now results in the same model but with the updated states, taking into account the last ушпре observations:</p>
<div id="attachment_1131" style="width: 310px" class="wp-caption alignnone"><a href="/wp-content/uploads/2017/03/N1234-MAN-predefined.png"><img loading="lazy" decoding="async" aria-describedby="caption-attachment-1131" src="/wp-content/uploads/2017/03/N1234-MAN-predefined-300x175.png" alt="" width="300" height="175" class="size-medium wp-image-1131" srcset="https://openforecast.org/wp-content/webpc-passthru.php?src=https://openforecast.org/wp-content/uploads/2017/03/N1234-MAN-predefined-300x175.png&amp;nocache=1 300w, https://openforecast.org/wp-content/webpc-passthru.php?src=https://openforecast.org/wp-content/uploads/2017/03/N1234-MAN-predefined-768x448.png&amp;nocache=1 768w, https://openforecast.org/wp-content/webpc-passthru.php?src=https://openforecast.org/wp-content/uploads/2017/03/N1234-MAN-predefined-1024x597.png&amp;nocache=1 1024w, https://openforecast.org/wp-content/webpc-passthru.php?src=https://openforecast.org/wp-content/uploads/2017/03/N1234-MAN-predefined.png&amp;nocache=1 1200w" sizes="auto, (max-width: 300px) 100vw, 300px" /></a><p id="caption-attachment-1131" class="wp-caption-text">Series N1234 and the same ETS(M,A,N) fit to a larger sample</p></div>
<p>The other way to do exactly the same is just to pass <code>ourModel</code> to <code>es()</code> function this way:</p>
<pre class="decode">es(M3$N1234$x,model=ourModel,h=8,holdout=FALSE)</pre>
<p>This way we can, for example, do rolling origin with fixed parameters.</p>
<p>The function <code>modelType()</code> also works with models estimated using <code>ets()</code> function from <code>forecast</code> package, so you can easily use <code>ets()</code> and then construct the model of the same type using <code>es()</code>:</p>
<pre class="decode">etsModel <- ets(M3$N1234$x)
es(M3$N1234$x,model=modelType(etsModel),h=8,holdout=TRUE)</pre>
<p>Not sure why you would need it, but here it is. Enjoy!</p>
<p>That’s it for today. I hope that this post was helpful and now you know what you can do when you don’t have anything to do. See you next time!</p>
<p>Message <a href="https://openforecast.org/2017/03/05/smooth-package-for-r-es-function-part-v-essential-parameters/">&#8220;smooth&#8221; package for R. es() function. Part V. Essential parameters</a> first appeared on <a href="https://openforecast.org">Open Forecasting</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://openforecast.org/2017/03/05/smooth-package-for-r-es-function-part-v-essential-parameters/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>&#8220;smooth&#8221; package for R. es() function. Part IV. Model selection and combination of forecasts</title>
		<link>https://openforecast.org/2017/01/24/smooth-package-for-r-es-function-part-iv-model-selection-and-combination-of-forecasts/</link>
					<comments>https://openforecast.org/2017/01/24/smooth-package-for-r-es-function-part-iv-model-selection-and-combination-of-forecasts/#respond</comments>
		
		<dc:creator><![CDATA[Ivan Svetunkov]]></dc:creator>
		<pubDate>Tue, 24 Jan 2017 20:54:38 +0000</pubDate>
				<category><![CDATA[About es() function]]></category>
		<category><![CDATA[Applied forecasting]]></category>
		<category><![CDATA[ETS]]></category>
		<category><![CDATA[Package smooth for R]]></category>
		<category><![CDATA[R]]></category>
		<category><![CDATA[smooth]]></category>
		<category><![CDATA[statistics]]></category>
		<guid isPermaLink="false">https://openforecast.org/?p=1047</guid>

					<description><![CDATA[<p>Mixed models In the previous posts we have discussed pure additive and pure multiplicative exponential smoothing models. The next logical step would be to discuss mixed models, where some components have additive and the others have multiplicative nature. But we won&#8217;t spend much time on them because I personally think that they do not make [&#8230;]</p>
<p>Message <a href="https://openforecast.org/2017/01/24/smooth-package-for-r-es-function-part-iv-model-selection-and-combination-of-forecasts/">&#8220;smooth&#8221; package for R. es() function. Part IV. Model selection and combination of forecasts</a> first appeared on <a href="https://openforecast.org">Open Forecasting</a>.</p>
]]></description>
										<content:encoded><![CDATA[<h3>Mixed models</h3>
<p>In the previous posts we have discussed pure additive and pure multiplicative exponential smoothing models. The next logical step would be to discuss mixed models, where some components have additive and the others have multiplicative nature. But we won&#8217;t spend much time on them because I personally think that they do not make much sense. Why do I think so? Well, they simply contradict basic modelling logic. For example, the original Holt-Winters method, which has underlying ETS(A,A,M) model, assumes that data may be both positive and negative (from side of additive error and trend), but at the same time does not work when data is non-positive (because multiplicative seasonality cannot be calculated in this case). This causes severe problems in forecasting of data with low values. A simple example is dying out seasonal product, which implies negative trend, low values and some periodic pattern. In this case level and trend components may become negative, which screws the seasonality. Having said that, mixed models work fine when data has high level. But this disadvantage of mixed models should be taken into account when one of them is selected. And this is a reason why I don&#8217;t want to spend a separate post on them. This paragraph should suffice.</p>
<h3>Theory of model selection and combinations</h3>
<p>Now that we have discussed all the possible types of exponential smoothing models, it is time to select the most appropriate one for your data. <a href="http://kourentzes.com/forecasting/2015/07/24/diy-forecasting-judgment-models-and-judgmental-model-selection/" target="_blank" rel="noopener noreferrer">Fotios Petropoulos and Nikos Kourentzes</a> had a research on this topic and demonstrated that human beings are very good in selecting appropriate components for each time series. However when a forecaster faces thousands of products that he needs to work with, it is not possible to select components individually. That&#8217;s why automatic model selection is needed.</p>
<p>There are many model selection methods and a lot of literature on this topic. I have implemented only one of those methods in es() function. It is based on information criteria calculation and proved to work well (<a href="https://www.researchgate.net/publication/222552350_A_State_Space_Framework_for_Automatic_Forecasting_Using_Exponential_Smoothing_Methods" target="_blank" rel="noopener noreferrer">Hyndman et al. 2002</a>, <a href="https://www.researchgate.net/publication/223458328_Exponential_smoothing_model_selection_for_forecasting" target="_blank" rel="noopener noreferrer">Billah et al. 2006</a>). Any information criterion uses likelihood function, that is why I showed them in the previous posts. These likelihoods depend mainly on error term, so mixed models will have one of two likelihood functions.</p>
<p>es() allows selecting between AIC (Akaike Information Criterion), AICc (Akaike Information Criterion corrected) and BIC (Bayesian Information Criterion, also known as Schwarz IC). The very basic information criterion is AIC. It is calculated for a chosen model using formula:<br />
\begin{equation} \label{eq:AIC}<br />
	\text{AIC} = -2 \ell \left(\theta, \hat{\sigma}^2 | Y \right) + 2k,<br />
\end{equation}<br />
where \(k\) is number of parameters of the model. Not going too much into details, the model with the smallest AIC is considered to be the closest to the true model. Obviously IC cannot be calculated without model fitting, which implies that a human being needs to form a pool of models, then fit each of them to the data, calculate an information criterion for each of them and after that select the one model that has the lowest IC value. There are 30 ETS models, so this procedure may take some time. Or even too much time, if we deal with large samples. So what can be done in order to increase the speed?</p>
<p>I have decided to solve this problem using logic and decrease pool of models in several steps. Here&#8217;s what happens in es():</p>
<ol>
<li>Simple ETS(A,N,N) is fitted to the data.</li>
<li>ETS(A,N,A) is fitted to the data.</li>
<p>If IC of (2) is lower than IC of (1), then there is some type of seasonality in the data. This means that we can exclude non-seasonal models. This decreases pool of models from 30 to 20. After that we go to step (3).</p>
<p>Otherwise there is no seasonality in the data, which means that the pool of models decreases from 30 to 10. We go to step (4).</p>
<p>These two steps need some explanation. We do not discuss trend at this point because even if data is trended, then ETS(A,N,N) will be a fine approximator for it (but a very poor forecaster, which is irrelevant at this point). The smoothing parameter in this case will obviously be very high (can be very close to 1), but this is not really important when we want to see if there is seasonality in the data. ETS(A,N,A) will perform better than ETS(A,N,N) on series with trend and seasonality. Similar argument holds even when data has multiplicative seasonality. ETS(A,N,A) in this case will have lower IC than ETS(A,N,N), because it will always fit seasonal data better.</p>
<li>Fit ETS(A,N,M). Compare it with (2).</li>
<p>If IC of (3) is lower than (2), then seasonality has multiplicative type. This reduces pool of models from 20 to 10. Go to step (4).</p>
<p>Otherwise, multiplicative seasonality does not contribute in the model, we can stick with additive, decreasing pool of models to 10. Go to step (4).</p>
<p>The logic here is similar to the previous step. If there is trend with multiplicative seasonality in the data, then level part of the model will capture the increase of level, while the model with multiplicative seasonality will approximate data better than the one with additive.</p>
<li>Fit a model with additive trend and preselected type of seasonality. Depending on steps (2) and (3) this can either be ETS(A,A,N), ETS(A,A,A) or ETS(A,A,M).</li>
<p>If IC of this step model is lower than IC of model selected on previous step, then there is a trend in data. This decreases pool of models from 10 to 8.</p>
<p>Otherwise there is no trend, meaning that we deal either with model with additive or multiplicative error. The pool of models decreases from 10 to 1. For example, if we compared ETS(A,A,M) and (A,N,M), and found that the latter is better, then ther is only one model left to fit and compare with others – ETS(M,N,M).</p>
<p>Additive trend on the last step is a good approximation for all trend types. If we find that it contributes towards better fit, then we can investigate, what type of trend is needed. Also, because we have already identified seasonality type, it won&#8217;t make any distortions on this step.
</ol>
<p>Using this algorithm of model selection allows to fit from 5 to 12 models instead of 30. The experiments that I have conducted showed that this way we usually end up with a model with the lowest IC. Keep in mind that this does not necessarily mean that the chosen model will produce the most accurate forecasts. Here we only care for the fit and closeness to the &#8220;true model&#8221;. Which brings us to another idea. We know from forecasting theory that combinations of forecasts are on average more accurate than individual models. So why not use them for ETS?</p>
<p>One of the simplest and pretty efficient methods would be to produce forecasts from each model in the pool, then combine them and return the final combined forecast. The combination itself can be done with either equal weights or unequal ones. The former does not make much sense, when we deal with data with specific components (for example, why would ETS(A,N,N) have the same weight as ETS(A,N,A) on seasonal data?). So we need to use some weights. There is a lot of methods of weights distribution, but we will use the one discussed in <a href="https://books.google.co.uk/books/about/Model_Selection_and_Multimodel_Inference.html?id=BQYR6js0CC8C" target="_blank" rel="noopener noreferrer">Burnham and Anderson (2002)</a>, which is based on information criteria, so we do not create anything artificial and just use what ETS models implemented in es() already have. Weights for each produced forecast are calculated using the following formula:<br />
\begin{equation} \label{eq:statLikelihoodAICweights}<br />
	w_j = \frac{ \exp \left(-\frac{1}{2}  \left(\text{IC}_j -\min(\text{IC}) \right) \right)}{\sum_{i=1}^m \exp \left(-\frac{1}{2}  \left(\text{IC}_i -\min(\text{IC}) \right) \right)},<br />
\end{equation}<br />
where \(m\) is number of models in the pool, IC\(_j\) is information criterion value for \(j^{th}\) model and \(\min(\text{IC})\) is the value of the lowest IC in the pool. Models with lower IC will have higher weights than the ones with high ICs. These weights are then used for combination of forecasts, prediction intervals and fitted values. Any information criterion among discussed above can be used instead of IC.</p>
<p>By the way, <a href="https://www.researchgate.net/publication/223315940_Combining_exponential_smoothing_forecasts_using_Akaike_weights" target="_blank" rel="noopener noreferrer">Stephan Kolassa (2011)</a> showed that using this method of forecasts combination increases accuracy of ETS models. This method protects forecaster from a random error, where a wrong model would be chosen for some unknown reasons. The pool of models is determined by a forecaster and may either include all the 30 ETS models or a sub-sample of them.</p>
<h3>Practice of model selection and combinations</h3>
<p>Now that we have discussed basics of model selection and combinations, we can try it out in <span class="lang:r decode:true  crayon-inline">es()</span> function. There are several ways of making this selection. Let&#8217;s start from the very basic one.</p>
<p>If we are not sure what to do and whether we need to restrict our models, we may use default selection mechanism, which is triggered by setting all the components of the model parameter equal to &#8220;Z&#8221;. This is taken from Rob Hyndman <span class="lang:r decode:true  crayon-inline">ets()</span> function which uses the same notation. If we ask for <span class="lang:r decode:true  crayon-inline">model=&#8221;ZZZ&#8221;</span>, then <span class="lang:r decode:true  crayon-inline">es()</span> function will use the described in the previous section model selection algorithm.</p>
<p>For example, for a time series N2568 from M3 we will have:</p>
<pre class="decode">es(M3$N2568$x, "ZZZ", h=18)</pre>
<p>Which results in:</p>
<pre>Forming the pool of models based on... ANN, ANA, ANM, AAM, Estimation progress: 100%... Done! 
Time elapsed: 2.6 seconds
Model estimated: ETS(MMdM)
Persistence vector g:
alpha  beta gamma 
0.020 0.020 0.001 
Damping parameter: 0.965
Initial values were optimised.
19 parameters were estimated in the process
Residuals standard deviation: 0.065
Cost function type: MSE; Cost function value: 169626

Information criteria:
     AIC     AICc      BIC 
1763.990 1771.907 1816.309 </pre>
<div id="attachment_1072" style="width: 310px" class="wp-caption alignnone"><a href="/wp-content/uploads/2017/01/N2568-es-MMdM.png"><img loading="lazy" decoding="async" aria-describedby="caption-attachment-1072" src="/wp-content/uploads/2017/01/N2568-es-MMdM-300x175.png" alt="Move along! There&#039;s nothing to see here!" width="300" height="175" class="size-medium wp-image-1072" srcset="https://openforecast.org/wp-content/webpc-passthru.php?src=https://openforecast.org/wp-content/uploads/2017/01/N2568-es-MMdM-300x175.png&amp;nocache=1 300w, https://openforecast.org/wp-content/webpc-passthru.php?src=https://openforecast.org/wp-content/uploads/2017/01/N2568-es-MMdM-768x448.png&amp;nocache=1 768w, https://openforecast.org/wp-content/webpc-passthru.php?src=https://openforecast.org/wp-content/uploads/2017/01/N2568-es-MMdM-1024x597.png&amp;nocache=1 1024w, https://openforecast.org/wp-content/webpc-passthru.php?src=https://openforecast.org/wp-content/uploads/2017/01/N2568-es-MMdM.png&amp;nocache=1 1200w" sizes="auto, (max-width: 300px) 100vw, 300px" /></a><p id="caption-attachment-1072" class="wp-caption-text">ETS(MMdM) on N2568 series from M3</p></div>
<p>During the model selection the function will print out the progress and tell us what&#8217;s happening: first it tries <span class="lang:r decode:true crayon-inline">&#8220;ANN&#8221;</span>, then <span class="lang:r decode:true crayon-inline">&#8220;ANA&#8221;</span>, then <span class="lang:r decode:true crayon-inline">&#8220;ANM&#8221;</span> (which means that the data is seasonal and it tries to define type of seasonality) and finally <span class="lang:r decode:true crayon-inline">&#8220;AAM&#8221;</span> (checking the trend). If we do not need any output we can ask our function to shut up by specifying parameter <span class="lang:r decode:true  crayon-inline">silent=&#8221;all&#8221;</span>. As we see, the optimal model for this data is ETS(M,Md,M).</p>
<p>Note that the mentioned model selection algorithm is only used when we specify &#8220;Z&#8221; for at least one component and either &#8220;Z&#8221; or &#8220;A&#8221;, or &#8220;M&#8221;, or &#8220;N&#8221; for the others. Setting some components equal to either &#8220;A&#8221;, &#8220;M&#8221; or &#8220;N&#8221; will speed up the selection process, but the function will use the discussed above selection algorithm.</p>
<p>By default the selection is done using AICc, but AIC and BIC are also available and can be selected with ic parameter:</p>
<pre class="decode">es(M3$N2568$x, "ZZM", h=18, ic="BIC")</pre>
<p>Now let&#8217;s assume that for some reason we are only interested in pure additive models. What should we do in this case? How can we select the best model from such a pool of 6 models? <span class="lang:r decode:true  crayon-inline">es()</span> function allows us to do that via &#8220;X&#8221; component:</p>
<pre class="decode">es(M3$N2568$x, "XXX", h=18)</pre>
<p>This gives us:</p>
<pre>Estimation progress: 100%... Done! 
Time elapsed: 0.72 seconds
Model estimated: ETS(ANA)
Persistence vector g:
alpha gamma 
0.174 0.695 
Initial values were optimised.
16 parameters were estimated in the process
Residuals standard deviation: 609.711
Cost function type: MSE; Cost function value: 320472

Information criteria:
     AIC     AICc      BIC 
1831.789 1837.284 1875.847</pre>
<div id="attachment_1070" style="width: 310px" class="wp-caption alignnone"><a href="/wp-content/uploads/2017/01/N2568-es-ANA.png"><img loading="lazy" decoding="async" aria-describedby="caption-attachment-1070" src="/wp-content/uploads/2017/01/N2568-es-ANA-300x175.png" alt="" width="300" height="175" class="size-medium wp-image-1070" srcset="https://openforecast.org/wp-content/webpc-passthru.php?src=https://openforecast.org/wp-content/uploads/2017/01/N2568-es-ANA-300x175.png&amp;nocache=1 300w, https://openforecast.org/wp-content/webpc-passthru.php?src=https://openforecast.org/wp-content/uploads/2017/01/N2568-es-ANA-768x448.png&amp;nocache=1 768w, https://openforecast.org/wp-content/webpc-passthru.php?src=https://openforecast.org/wp-content/uploads/2017/01/N2568-es-ANA-1024x597.png&amp;nocache=1 1024w, https://openforecast.org/wp-content/webpc-passthru.php?src=https://openforecast.org/wp-content/uploads/2017/01/N2568-es-ANA.png&amp;nocache=1 1200w" sizes="auto, (max-width: 300px) 100vw, 300px" /></a><p id="caption-attachment-1070" class="wp-caption-text">ETS(ANA) on N2568 series from M3</p></div>
<p>In this case the model selection algorithm described in the previous section is not used. We just check 6 models and select the best of them. The pool of models in this case includes: <span class="lang:r decode:true crayon-inline">&#8220;ANN&#8221;</span>, <span class="lang:r decode:true crayon-inline">&#8220;AAN&#8221;</span>, <span class="lang:r decode:true crayon-inline">&#8220;AAdN&#8221;</span>, <span class="lang:r decode:true crayon-inline">&#8220;ANA&#8221;</span>, <span class="lang:r decode:true crayon-inline">&#8220;AAA&#8221;</span> and <span class="lang:r decode:true crayon-inline">&#8220;AAdA&#8221;</span>. For this data the best model in this pool is ETS(A,N,A).</p>
<p>In a similar manner we can ask the function to select between multiplicative models only. This is regulated with &#8220;Y&#8221; value for components:</p>
<pre class="decode">es(M3$N2568$x, "YYY", h=18)</pre>
<p>Similar to <span class="lang:r decode:true crayon-inline">&#8220;XXX&#8221;</span> we go through 6 models and select the best one. In this case we will end up with exactly the same model as in <span class="lang:r decode:true crayon-inline">&#8220;ZZZ&#8221;</span> case, because the optimal model for this time series is ETS(M,Md,M). <span class="lang:r decode:true crayon-inline">&#8220;YYY&#8221;</span> can be especially useful, when we deal with low level values.</p>
<p>Now that we know these features, we can combine different parameters and form pools that we want. For example, we can select the best model between <span class="lang:r decode:true crayon-inline">&#8220;MNN&#8221;</span>, <span class="lang:r decode:true crayon-inline">&#8220;MAN&#8221;</span>, <span class="lang:r decode:true crayon-inline">&#8220;MAdN&#8221;</span>, <span class="lang:r decode:true crayon-inline">&#8220;MNM&#8221;</span>, <span class="lang:r decode:true crayon-inline">&#8220;MAM&#8221;</span>, MAdM this way:</p>
<pre class="decode">es(M3$N2568$x, "YXY", h=18)</pre>
<p>Which results in:</p>
<pre>Estimation progress: 100%... Done! 
Time elapsed: 0.92 seconds
Model estimated: ETS(MAdM)
Persistence vector g:
alpha  beta gamma 
0.021 0.021 0.001 
Damping parameter: 0.976
Initial values were optimised.
19 parameters were estimated in the process
Residuals standard deviation: 0.065
Cost function type: MSE; Cost function value: 169730

Information criteria:
     AIC     AICc      BIC 
1764.062 1771.979 1816.380 </pre>
<p>Note that the information criteria for ETS(M,Ad,M) are very close to the optimal ETS(M,Md,M). This raises the question which of the models to prefer if the difference between them is negligible&#8230;</p>
<p>We can also pre-specify some components if we really want something special. For example, anything with multiplicative seasonality:</p>
<pre class="decode">es(M3$N2568$x, "ZZM", h=18)</pre>
<p>Finally, there is another way to select the best model from some pre-specified pool. Let&#8217;s say that we have a favourite set of ETS models that we want to check, which includes: <span class="lang:r decode:true crayon-inline">&#8220;ANN&#8221;</span>, <span class="lang:r decode:true crayon-inline">&#8220;MNN&#8221;</span>, <span class="lang:r decode:true crayon-inline">&#8220;AAdN&#8221;</span>, <span class="lang:r decode:true crayon-inline">&#8220;AAdM&#8221;</span> and <span class="lang:r decode:true crayon-inline">&#8220;MMdM&#8221;</span>. This cannot be specified via &#8220;X&#8221;, &#8220;Y&#8221; and &#8220;Z&#8221; parameters, but it can be provided to <span class="lang:r decode:true crayon-inline">es()</span> as a vector of model names:</p>
<pre class="decode">es(M3$N2568$x, c("ANN", "MNN", "AAdN", "AAdM", "MMdM"), h=18)</pre>
<p>In this case the function will go through all the provided models and select the one with the lowest IC (which is ETS(M,Md,M) in this case).</p>
<p>Now let’s have a look at combinations. This is specified with components equal to &#8220;C&#8221;. Once again we can set a pool of models via &#8220;Z&#8221;, &#8220;X&#8221;, &#8220;Y&#8221;, &#8220;N&#8221;, &#8220;A&#8221; and &#8220;M&#8221; and combine their forecasts. In order to produce combinations we need to specify at least one component as &#8220;C&#8221;. In a very simple case we have (let&#8217;s also ask for prediction intervals in order to see how this thing works):</p>
<pre class="decode">es(M3$N2568$x, "CCC", h=18, intervals=TRUE)</pre>
<p>With the following output:</p>
<pre>Estimation progress: 100%... Done!
Time elapsed: 10.04 seconds
Model estimated: ETS(CCC)
Initial values were optimised.
Residuals standard deviation: 438.242
Cost function type: MSE

Information criteria:
Combined AICc 
     1772.198 
95% parametric prediction intervals were constructed</pre>
<p>and graph:</p>
<div id="attachment_1071" style="width: 310px" class="wp-caption alignnone"><a href="/wp-content/uploads/2017/01/N2568-es-CCC.png"><img loading="lazy" decoding="async" aria-describedby="caption-attachment-1071" src="/wp-content/uploads/2017/01/N2568-es-CCC-300x175.png" alt="" width="300" height="175" class="size-medium wp-image-1071" srcset="https://openforecast.org/wp-content/webpc-passthru.php?src=https://openforecast.org/wp-content/uploads/2017/01/N2568-es-CCC-300x175.png&amp;nocache=1 300w, https://openforecast.org/wp-content/webpc-passthru.php?src=https://openforecast.org/wp-content/uploads/2017/01/N2568-es-CCC-768x448.png&amp;nocache=1 768w, https://openforecast.org/wp-content/webpc-passthru.php?src=https://openforecast.org/wp-content/uploads/2017/01/N2568-es-CCC-1024x597.png&amp;nocache=1 1024w, https://openforecast.org/wp-content/webpc-passthru.php?src=https://openforecast.org/wp-content/uploads/2017/01/N2568-es-CCC.png&amp;nocache=1 1200w" sizes="auto, (max-width: 300px) 100vw, 300px" /></a><p id="caption-attachment-1071" class="wp-caption-text">Combined ETS on N2568 series from M3</p></div>
<p>Because we have set &#8220;C&#8221; for all the components, we have combined point forecasts and prediction intervals for all the 30 models, which took almost 10 seconds. But we could have asked something stricter, if we knew that some of the components need to be of a specific type. For example, additive seasonality does not make much sense for our time series, so we can ask for:</p>
<pre class="decode">es(M3$N2568$x, "CCM", h=18)</pre>
<p>which will use only 10 models and as a result happen approximately 3 times faster with approximately the same result for our time series, which exhibits obvious multiplicative seasonality. This means that all the models with multiplicative seasonality will have higher weight than other models.</p>
<p>We can also use &#8220;X&#8221; and &#8220;Y&#8221;, which in this case will ask our function to use additive and multiplicative models in combinations respectively. For example, this thing:</p>
<pre class="decode">es(M3$N2568$x, "CXY", h=18)</pre>
<p>will combine forecasts from the following 12 models: <span class="lang:r decode:true crayon-inline">&#8220;ANN&#8221;</span>, <span class="lang:r decode:true crayon-inline">&#8220;AAN&#8221;</span>, <span class="lang:r decode:true crayon-inline">&#8220;AAdN&#8221;</span>, <span class="lang:r decode:true crayon-inline">&#8220;ANM&#8221;</span>, <span class="lang:r decode:true crayon-inline">&#8220;AAM&#8221;</span>, <span class="lang:r decode:true crayon-inline">&#8220;AAdM&#8221;</span>, <span class="lang:r decode:true crayon-inline">&#8220;MNN&#8221;</span>, <span class="lang:r decode:true crayon-inline">&#8220;MAN&#8221;</span>, <span class="lang:r decode:true crayon-inline">&#8220;MAdN&#8221;</span>, <span class="lang:r decode:true crayon-inline">&#8220;MNM&#8221;</span>, <span class="lang:r decode:true crayon-inline">&#8220;MAM&#8221;</span>, <span class="lang:r decode:true crayon-inline">&#8220;MAdM&#8221;</span>.</p>
<p>Finally forecasts can be combined from an arbitrary pool of models. In order to do that a user needs to add <span class="lang:r decode:true crayon-inline">&#8220;CCC&#8221;</span> model in the desired pool of models. Here how it works:</p>
<pre class="decode">es(M3$N2568$x, c("CCC","ANN", "MNN", "AAdN", "AAdM", "MMdM"), h=18)</pre>
<p>This will combine forecasts of <span class="lang:r decode:true crayon-inline">&#8220;ANN&#8221;</span>, <span class="lang:r decode:true crayon-inline">&#8220;MNN&#8221;</span>, <span class="lang:r decode:true crayon-inline">&#8220;AAdN&#8221;</span>, <span class="lang:r decode:true crayon-inline">&#8220;AAdM&#8221;</span> and <span class="lang:r decode:true crayon-inline">&#8220;MMdM&#8221;</span> ETS models.</p>
<p>As we see, the model selection and combinations mechanism implemented in <span class="lang:r decode:true crayon-inline">es()</span> is very flexible and allows to do a lot of cool things with exponential smoothing.</p>
<p>That&#8217;s it for today. I hope that this post was as exciting for you as previous ones about <span class="lang:r decode:true crayon-inline">es()</span> function :). We will continue with a more detailed explanation of <span class="lang:r decode:true crayon-inline">es()</span> function parameters.</p>
<h3>P.S. about the pools of models</h3>
<p>Although there are 30 types of ETS models out there, there have been some arguments that not all of them make sense. For example, it is weird to have a model with multiplicative seasonality and additive error &#8211; the more natural would be the model with the aligned errors and seasonality. In addition, a lot of mixed models are difficult to work with &#8211; they break easily if the fitted values get close to zero. So, taking all of this into account Rob Hyndman has restricted his <span class="lang:r decode:true crayon-inline">ets()</span> function from the <span class="lang:r decode:true crayon-inline">forecast</span> package with the following pool of 19 models (if the parameter <span class="lang:r decode:true crayon-inline">allow.multiplicative.trend=TRUE</span>): (A,N,N), (A,A,N), (A,Ad,N), (A,N,A), (A,A,A), (A,Ad,A), (M,N,N), (M,A,N), (M,Ad,N), (M,M,N), (M,Md,N), (M,N,M), (M,A,M), (M,Ad,M), (M,M,M), (M,Md,M), (M,N,A), (M,A,A), (M,Ad,A). In my opinion, the last three models should be removed from the pool for the consistency purposes, and all the mixed models can only be used when the level of series big enough, ensuring that we will not get to the negative plane. Still, if anyone wants to select between these of models, it can easily be done in <span class="lang:r decode:true crayon-inline">es()</span> as a pool of models:</p>
<pre class="decode">es(M3$N2568$x, c("ANN", "AAN", "AAdN", "ANA", "AAA", "AAdA", "MNN", "MAN", "MAdN", "MMN", "MMdN", "MNM", "MAM", "MAdM", "MMM", "MMdM", "MNA", "MAA", "MAdA"), h=18)</pre>
<p>Message <a href="https://openforecast.org/2017/01/24/smooth-package-for-r-es-function-part-iv-model-selection-and-combination-of-forecasts/">&#8220;smooth&#8221; package for R. es() function. Part IV. Model selection and combination of forecasts</a> first appeared on <a href="https://openforecast.org">Open Forecasting</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://openforecast.org/2017/01/24/smooth-package-for-r-es-function-part-iv-model-selection-and-combination-of-forecasts/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>&#8220;smooth&#8221; package for R. es() function. Part III. Multiplicative models</title>
		<link>https://openforecast.org/2016/11/18/smooth-package-for-r-es-function-part-iii-multiplicative-models/</link>
					<comments>https://openforecast.org/2016/11/18/smooth-package-for-r-es-function-part-iii-multiplicative-models/#respond</comments>
		
		<dc:creator><![CDATA[Ivan Svetunkov]]></dc:creator>
		<pubDate>Fri, 18 Nov 2016 13:17:19 +0000</pubDate>
				<category><![CDATA[About es() function]]></category>
		<category><![CDATA[Applied forecasting]]></category>
		<category><![CDATA[ETS]]></category>
		<category><![CDATA[Package smooth for R]]></category>
		<category><![CDATA[R]]></category>
		<category><![CDATA[smooth]]></category>
		<category><![CDATA[statistics]]></category>
		<guid isPermaLink="false">https://openforecast.org/?p=942</guid>

					<description><![CDATA[<p>Theoretical stuff Last time we talked about pure additive models, today I want to discuss multiplicative ones. There is a general scepticism about pure multiplicative exponential smoothing models in the forecasters society, because it is not clear why level, trend, seasonality and error term should be multiplied. Well, when it comes to seasonality, then there [&#8230;]</p>
<p>Message <a href="https://openforecast.org/2016/11/18/smooth-package-for-r-es-function-part-iii-multiplicative-models/">&#8220;smooth&#8221; package for R. es() function. Part III. Multiplicative models</a> first appeared on <a href="https://openforecast.org">Open Forecasting</a>.</p>
]]></description>
										<content:encoded><![CDATA[<h3>Theoretical stuff</h3>
<p>Last time we talked about pure additive models, today I want to discuss multiplicative ones.</p>
<p>There is a general scepticism about pure multiplicative exponential smoothing models in the forecasters society, because it is not clear why level, trend, seasonality and error term should be multiplied. Well, when it comes to seasonality, then there is no doubt &#8211; multiplicative one is more often met than additive and thus is more often used in practice. However, multiplicative trend and multiplicative error are not as straight forward, because it is not easy to understand why we need them in the first place. In addition, models with these multiplicative components are harder to implement, harder to work with and their forecast accuracy is not necessarily better than accuracy of other models.</p>
<p>So why bother at all? There is at least one reason. Pure multiplicative models are constructed with the assumption that the data we work with is positive only. And this is a plausible assumption when we work with demand on products, because selling -50 boots in March 2017 or something like that does not make much sense. However, when we work with high scale data (for example, hundreds or even thousands of units), then this advantage becomes negligible, so pure additive or mixed models can be used instead. This, in fact, is the reason why pure multiplicative models are neglected.</p>
<p>So, what&#8217;s the catch with these models? Let&#8217;s have a look.</p>
<p>The general pure multiplicative model can be written in the following compact form, if we use natural logarithms:<br />
\begin{equation} \label{eq:ssGeneralMultiplicative}<br />
	\begin{matrix}<br />
		y_t = \exp \left(w&#8217; \log(v_{t-l}) + \log(1+\epsilon_t) \right) \\<br />
		\log(v_t) = F \log(v_{t-l}) + \log (1 + g \epsilon_t)<br />
	\end{matrix} ,<br />
\end{equation}<br />
where all the notations have already been introduced in <a href="/en/2016/11/02/smooth-package-for-r-es-function-part-ii-pure-additive-models/">the previous post</a>. The only thing to note is that both \(\exp\) and \(\log\) are applied element wise to vectors. This means that \(\log(v_t)\) will result in vector consisting of components in logarithms. The important thing to note here is that all the components of this models must be positive, otherwise it won&#8217;t work.</p>
<p>An example of multiplicative model written in this form is ETS(M,M,N) &#8211; model with multiplicative error and multiplicative trend &#8211; can be written as:<br />
\begin{equation} \label{eq:ssETS(M,M,N)}<br />
	\begin{matrix}<br />
		y_t = \exp \left(\log(l_{t-l}) + \log(b_{t-l}) + \log(1 + \epsilon_t) \right) \\<br />
		\log(l_t) = \log(l_{t-l}) + \log(b_{t-l}) + \log (1 + \alpha \epsilon_t) \\<br />
		\log(b_t) = \log(b_{t-l}) + \log (1 + \beta \epsilon_t)<br />
	\end{matrix} .<br />
\end{equation}<br />
Taking exponent of second and third equations and simplifying the first one in \eqref{eq:ssETS(M,M,N)} leads to the conventional model, that underlies Pegel&#8217;s method:<br />
\begin{equation} \label{eq:ssETS(M,M,N)_Pegels}<br />
	\begin{matrix}<br />
		y_t = l_{t-l} b_{t-l} (1 + \epsilon_t) \\<br />
		l_t = l_{t-l} b_{t-l} (1 + \alpha \epsilon_t) \\<br />
		b_t = b_{t-l} (1 + \beta \epsilon_t)<br />
	\end{matrix} .<br />
\end{equation}<br />
Multiplication of level, trend and error term restricts actuals with positive values, but this will only be true if we impose correct assumptions on error term. While <a href="http://www.springer.com/gp/book/9783540719168" target="_blank" rel="noopener noreferrer">Hyndman et al. 2008</a> assume that it is distributed normally  (they have actually discussed other assumption in Chapter 15), we assume in <span class="lang:r decode:true  crayon-inline " >es()</span> that it is distributed log-normally:<br />
\begin{equation} \label{eq:ssErrorlogN}<br />
	(1 + \epsilon_t) \sim \text{log}\mathcal{N}(0,\sigma^2),<br />
\end{equation}<br />
where \(\sigma^2\) is variance of logarithm of \(1 + \epsilon_t\). Why log-normal distribution? Let me explain. When the variance \(\sigma^2\) is small, the differences between <span class="lang:r decode:true  crayon-inline " >es()</span> and <span class="lang:r decode:true  crayon-inline " >ets()</span> models with multiplicative error are almost non-existent, because in this case both normal and log-normal distributions look very similar. However with larger variance the differences become more substantial (and by larger I mean something greater than 0.1), because log-normal distribution becomes positive skewed with a longer tail. In addition, with a higher variance and normality assumption chances of having \(1 + \epsilon_t \leq 0\) increase, which contradicts the original model. So the assumption of normality is not always unrealistic and may lead to problems in model construction. That is why we need the assumption \eqref{eq:ssErrorlogN}.</p>
<p>Now \eqref{eq:ssErrorlogN} influences several aspects of how the model work: point forecasts, prediction intervals and estimation of the model \eqref{eq:ssGeneralMultiplicative} will be slightly different.</p>
<p>First of all, with low actual values point forecasts correspond to median rather than mean. This is because of relations between mean in normal and log-normal distributions and the fact that variance of error term in these cases may become sufficiently large for them to differ substantially. Arguably, median is what we need in cases of skewed distributions and that&#8217;s what <span class="lang:r decode:true  crayon-inline " >es()</span> produces. Knowing that is especially important in cases with intermittent demand models, which will be discussed in this blog at some distant point in future.</p>
<p>Secondly, due to asymmetry of log-normal distribution prediction intervals become asymmetric. This will especially be evident, when scale of data is low and variance is high. In the other situations the intervals will be very close to intervals produced by additive error models with normally distributed errors.</p>
<p>Finally, the estimation of models with multiplicative errors should be based on the following concentrated log-likelihood function (for log-normal distribution):<br />
\begin{equation} \label{eq:ssConcentratedLogLikelihoodLnorm}<br />
	\ell(\theta | Y) = -\frac{T}{2} \left( \log \left( 2 \pi e \right) +\log \left( \hat{\sigma}^2 \right) \right) -\sum_{t=1}^T \log y_t ,<br />
\end{equation}<br />
where \(\hat{\sigma}^2 = \frac{1}{T} \sum_{t=1}^T \log^2(1 + \epsilon_{t})\). The likelihood function \eqref{eq:ssConcentratedLogLikelihoodLnorm} looks very similar to <a href="/en/2016/11/02/smooth-package-for-r-es-function-part-ii-pure-additive-models/">the one used in additive models</a>, but leads to a slightly different cost function (that we need to minimise):<br />
\begin{equation} \label{eq:ssCostFunction}<br />
	\text{CF} = \log \left( \hat{\sigma}^2 \right) + \frac{2}{T} \sum_{t=1}^T \log y_t .<br />
\end{equation}<br />
Giving interpretation to the cost function \eqref{eq:ssCostFunction}, variance of error term here is weighed with actual values. So roughly saying higher actuals will be predicted with higher precision.</p>
<h3>R stuff</h3>
<p>A good example of data, where pure multiplicative model can be used is time series N2457 from M3. Although the scale of data is high (the average is around 5000), the variability of data is high as well, which indicates that multiplicative model could be efficiently used here. So, let&#8217;s construct the ETS(M,N,N) model with parametric prediction intervals:</p>
<pre class="decode" title="Examples of usage" >es(M3$N2457$x, "MNN", h=18, holdout=TRUE, intervals="p")</pre>
<p>This results in the following output:</p>
<pre title="N1234, ETS(AAdN), output of es()" >Time elapsed: 0.1 seconds
Model estimated: ETS(MNN)
Persistence vector g:
alpha 
0.145 
Initial values were optimised.
3 parameters were estimated in the process
Residuals standard deviation: 0.413
Cost function type: MSE; Cost function value: 1288657

Information criteria:
     AIC     AICc      BIC 
1645.978 1646.236 1653.702 
95% parametric prediction intervals were constructed
72% of values are in the prediction interval
Forecast errors:
MPE: 26.3%; Bias: 87%; MAPE: 39.8%; SMAPE: 49.4%
MASE: 2.944; sMAE: 120.1%; RelMAE: 1.258; sMSE: 242.7%</pre>
<p>We have already discussed what each of the lines of this output means in the <a href="/en/2016/11/02/smooth-package-for-r-es-function-part-ii-pure-additive-models/">previous post</a>, so we will not stop on that here. The thing to note, however, is the line with residuals standard deviation, which is equal to 0.413 (meaning that variance is approximately equal to 0.17). With this standard deviation the distribution will be noticeably skewed. This can be evidently seen on the produced graph:<br />
<div id="attachment_1014" style="width: 310px" class="wp-caption alignnone"><a href="/wp-content/uploads/2016/11/N2457-MNN-PI-parametric.png"><img loading="lazy" decoding="async" aria-describedby="caption-attachment-1014" src="/wp-content/uploads/2016/11/N2457-MNN-PI-parametric-300x175.png" alt="Series N2457 from M3 and es(&quot;MNN&quot;) forecast with prediction intervals" width="300" height="175" class="size-medium wp-image-1014" srcset="https://openforecast.org/wp-content/webpc-passthru.php?src=https://openforecast.org/wp-content/uploads/2016/11/N2457-MNN-PI-parametric-300x175.png&amp;nocache=1 300w, https://openforecast.org/wp-content/webpc-passthru.php?src=https://openforecast.org/wp-content/uploads/2016/11/N2457-MNN-PI-parametric-768x448.png&amp;nocache=1 768w, https://openforecast.org/wp-content/webpc-passthru.php?src=https://openforecast.org/wp-content/uploads/2016/11/N2457-MNN-PI-parametric-1024x597.png&amp;nocache=1 1024w, https://openforecast.org/wp-content/webpc-passthru.php?src=https://openforecast.org/wp-content/uploads/2016/11/N2457-MNN-PI-parametric.png&amp;nocache=1 1200w" sizes="auto, (max-width: 300px) 100vw, 300px" /></a><p id="caption-attachment-1014" class="wp-caption-text">Series N2457 from M3 and es(&quot;MNN&quot;) forecast with prediction intervals</p></div>
<p>For the same time series ETS(A,N,N) model will produce the following forecast:<br />
<div id="attachment_1016" style="width: 310px" class="wp-caption alignnone"><a href="/wp-content/uploads/2016/11/N2457-ANN-PI-parametric.png"><img loading="lazy" decoding="async" aria-describedby="caption-attachment-1016" src="/wp-content/uploads/2016/11/N2457-ANN-PI-parametric-300x175.png" alt="Series N2457 from M3 and es(&quot;ANN&quot;) forecast with prediction intervals" width="300" height="175" class="size-medium wp-image-1016" srcset="https://openforecast.org/wp-content/webpc-passthru.php?src=https://openforecast.org/wp-content/uploads/2016/11/N2457-ANN-PI-parametric-300x175.png&amp;nocache=1 300w, https://openforecast.org/wp-content/webpc-passthru.php?src=https://openforecast.org/wp-content/uploads/2016/11/N2457-ANN-PI-parametric-768x448.png&amp;nocache=1 768w, https://openforecast.org/wp-content/webpc-passthru.php?src=https://openforecast.org/wp-content/uploads/2016/11/N2457-ANN-PI-parametric-1024x597.png&amp;nocache=1 1024w, https://openforecast.org/wp-content/webpc-passthru.php?src=https://openforecast.org/wp-content/uploads/2016/11/N2457-ANN-PI-parametric.png&amp;nocache=1 1200w" sizes="auto, (max-width: 300px) 100vw, 300px" /></a><p id="caption-attachment-1016" class="wp-caption-text">Series N2457 from M3 and es(&#8220;ANN&#8221;) forecast with prediction intervals</p></div>
<p>Comparing the two graphs, we can notice that prediction intervals on the first one are more adequate for this data, because they take into account skewness in errors distribution. As a result they cover more observations in the holdout than the intervals of the second model.</p>
<p>A counter example is time series N2348 &#8211; it does not have as high variability as N2457, so ETS(M,N,N) and ETS(A,N,N) produce very similar point forecasts and prediction intervals. This is because variance in multiplicative model applied to this data is equal to 0.000625 and as a result the log-normal distribution becomes very close to the normal. See for yourselves:</p>
<div id="attachment_1018" style="width: 310px" class="wp-caption alignnone"><a href="/wp-content/uploads/2016/11/N2348-MNN-PI-parametric.png"><img loading="lazy" decoding="async" aria-describedby="caption-attachment-1018" src="/wp-content/uploads/2016/11/N2348-MNN-PI-parametric-300x175.png" alt="Series N2348 from M3 and es(&quot;MNN&quot;) forecast with prediction intervals" width="300" height="175" class="size-medium wp-image-1018" srcset="https://openforecast.org/wp-content/webpc-passthru.php?src=https://openforecast.org/wp-content/uploads/2016/11/N2348-MNN-PI-parametric-300x175.png&amp;nocache=1 300w, https://openforecast.org/wp-content/webpc-passthru.php?src=https://openforecast.org/wp-content/uploads/2016/11/N2348-MNN-PI-parametric-768x448.png&amp;nocache=1 768w, https://openforecast.org/wp-content/webpc-passthru.php?src=https://openforecast.org/wp-content/uploads/2016/11/N2348-MNN-PI-parametric-1024x597.png&amp;nocache=1 1024w, https://openforecast.org/wp-content/webpc-passthru.php?src=https://openforecast.org/wp-content/uploads/2016/11/N2348-MNN-PI-parametric.png&amp;nocache=1 1200w" sizes="auto, (max-width: 300px) 100vw, 300px" /></a><p id="caption-attachment-1018" class="wp-caption-text">Series N2348 from M3 and es(&#8220;MNN&#8221;) forecast with prediction intervals</p></div>
<div id="attachment_1019" style="width: 310px" class="wp-caption alignnone"><a href="/wp-content/uploads/2016/11/N2348-ANN-PI-parametric.png"><img loading="lazy" decoding="async" aria-describedby="caption-attachment-1019" src="/wp-content/uploads/2016/11/N2348-ANN-PI-parametric-300x175.png" alt="Series N2348 from M3 and es(&quot;ANN&quot;) forecast with prediction intervals" width="300" height="175" class="size-medium wp-image-1019" srcset="https://openforecast.org/wp-content/webpc-passthru.php?src=https://openforecast.org/wp-content/uploads/2016/11/N2348-ANN-PI-parametric-300x175.png&amp;nocache=1 300w, https://openforecast.org/wp-content/webpc-passthru.php?src=https://openforecast.org/wp-content/uploads/2016/11/N2348-ANN-PI-parametric-768x448.png&amp;nocache=1 768w, https://openforecast.org/wp-content/webpc-passthru.php?src=https://openforecast.org/wp-content/uploads/2016/11/N2348-ANN-PI-parametric-1024x597.png&amp;nocache=1 1024w, https://openforecast.org/wp-content/webpc-passthru.php?src=https://openforecast.org/wp-content/uploads/2016/11/N2348-ANN-PI-parametric.png&amp;nocache=1 1200w" sizes="auto, (max-width: 300px) 100vw, 300px" /></a><p id="caption-attachment-1019" class="wp-caption-text">Series N2348 from M3 and es(&#8220;ANN&#8221;) forecast with prediction intervals</p></div>
<p>So in cases of time series similar to N2348 both multiplicative and additive error models can be used equally efficiently. But in general pure multiplicative models should not be neglected as they have useful properties. In one of the next posts we will see that these properties become especially useful for intermittent demand.</p>
<p>That&#8217;s all, folks!</p>
<p>Message <a href="https://openforecast.org/2016/11/18/smooth-package-for-r-es-function-part-iii-multiplicative-models/">&#8220;smooth&#8221; package for R. es() function. Part III. Multiplicative models</a> first appeared on <a href="https://openforecast.org">Open Forecasting</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://openforecast.org/2016/11/18/smooth-package-for-r-es-function-part-iii-multiplicative-models/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>&#8220;smooth&#8221; package for R. es() function. Part II. Pure additive models</title>
		<link>https://openforecast.org/2016/11/02/smooth-package-for-r-es-function-part-ii-pure-additive-models/</link>
					<comments>https://openforecast.org/2016/11/02/smooth-package-for-r-es-function-part-ii-pure-additive-models/#respond</comments>
		
		<dc:creator><![CDATA[Ivan Svetunkov]]></dc:creator>
		<pubDate>Wed, 02 Nov 2016 09:27:21 +0000</pubDate>
				<category><![CDATA[About es() function]]></category>
		<category><![CDATA[Applied forecasting]]></category>
		<category><![CDATA[ETS]]></category>
		<category><![CDATA[Package smooth for R]]></category>
		<category><![CDATA[R]]></category>
		<category><![CDATA[smooth]]></category>
		<category><![CDATA[statistics]]></category>
		<guid isPermaLink="false">https://openforecast.org/?p=867</guid>

					<description><![CDATA[<p>A bit of statistics As mentioned in the previous post, all the details of models underlying functions of &#8220;smooth&#8221; package can be found in extensive documentation. Here I want to discuss several basic, important aspects of statistical model underlying es() and how it is implementated in R. Today we will have a look at basic [&#8230;]</p>
<p>Message <a href="https://openforecast.org/2016/11/02/smooth-package-for-r-es-function-part-ii-pure-additive-models/">&#8220;smooth&#8221; package for R. es() function. Part II. Pure additive models</a> first appeared on <a href="https://openforecast.org">Open Forecasting</a>.</p>
]]></description>
										<content:encoded><![CDATA[<h3>A bit of statistics</h3>
<p>As mentioned <a href="/en/2016/10/14/smooth-package-for-r-es-i/">in the previous post</a>, all the details of models underlying functions of &#8220;smooth&#8221; package can be found in extensive <a href="https://github.com/config-i1/smooth/blob/master/inst/doc/smooth-Documentation.pdf" target="_blank" rel="noopener noreferrer">documentation</a>. Here I want to discuss several basic, important aspects of statistical model underlying <span class="lang:r decode:true  crayon-inline " >es()</span> and how it is implementated in R. Today we will have a look at basic pure additive models. These models do not have multiplicative components in them in any form and are very easy to implement and understand.</p>
<p><span class="lang:r decode:true  crayon-inline " >es()</span> uses Single Source of Error State-Space model, described in <a href="http://www.springer.com/gp/book/9783540719168" target="_blank" rel="noopener noreferrer">Hyndman et al. (2008)</a>. The advantage of this is that it allows writing any type of exponential smoothing in a compact form and simplifies some statistical derivations. However the general model underlying <span class="lang:r decode:true  crayon-inline " >es()</span> differs slightly from the conventional one by <a href="http://www.springer.com/gp/book/9783540719168" target="_blank" rel="noopener noreferrer">Hyndman et al. (2008)</a> &#8211; seasonal component is modelled using lags rather than dummy variables. There are some other differences, but we will not go into much details right now.</p>
<p>In general state-space model underlying <span class="lang:r decode:true  crayon-inline " >es()</span> is written as (for pure additive models):<br />
\begin{equation} \label{eq:ssGeneralAdditive}<br />
	\begin{matrix}<br />
		y_t = w&#8217; v_{t-l} + \epsilon_t \\<br />
		v_t = F v_{t-l} + g \epsilon_t<br />
	\end{matrix} ,<br />
\end{equation}<br />
where \(y_{t}\) is value of series on observation \(t\), \(v_{t}\) is a state vector (containing components of time series, such as level, trend, seasonality), \(w\) and \(F\) are predefined measurement vector and transition matrix and \(g\) is persistence vector (vector, containing smoothing parameters). Finally \(\epsilon_t\) is error term, which for additive model is assumed to be normally distributed.</p>
<p>Using these notations, all the additive exponential smoothing models can be united in one compact form \eqref{eq:ssGeneralAdditive}. For example, Damped trend model, ETS(A,Ad,N), has the following matrices:<br />
\begin{equation} \label{eq:ssAAdNMatrices}<br />
w = 	\begin{pmatrix}<br />
		1 \\ \phi<br />
	\end{pmatrix},<br />
F = 	\begin{pmatrix}<br />
		1 &#038; \phi \\<br />
		0 &#038; \phi<br />
	\end{pmatrix},<br />
g = 	\begin{pmatrix}<br />
		\alpha \\<br />
		\beta<br />
	\end{pmatrix},<br />
v_t = 	\begin{pmatrix}<br />
		l_t \\<br />
		b_t<br />
	\end{pmatrix},<br />
v_{t-l} = 	\begin{pmatrix}<br />
		l_{t-1} \\<br />
		b_{t-1}<br />
	\end{pmatrix},<br />
\end{equation}<br />
and can be represented in the system of the following equations:<br />
\begin{equation} \label{eq:ssAAdN}<br />
	\begin{matrix}<br />
		y_t = l_{t-1} + \phi b_{t-1} + \epsilon_t \\<br />
		l_t = l_{t-1} + \phi b_{t-1} + \alpha \epsilon_t \\<br />
		b_t = \phi b_{t-1} + \beta \epsilon_t<br />
	\end{matrix} ,<br />
\end{equation}<br />
where \(l_t\) is level components, \(b_t\) is trend component, \(\phi\) is dampening parameter, \(\alpha\) and \(\beta\) are smoothing parameters.</p>
<p>Non-seasonal models in <span class="lang:r decode:true  crayon-inline " >es()</span> have exactly the same structure as in <span class="lang:r decode:true  crayon-inline " >ets()</span>. However the differences appear when we deal with seasonal components. The main element that is different in \eqref{eq:ssGeneralAdditive} in comparison with the conventional ETS is index \(l\), which indicates that some components of state vector have different lags. For example, seasonal component has a lag of \(m\) (for example, \(m=\)12 for monthly data) instead of 1, so some model ETS(A,A,A) has the following lagged state vector:<br />
\begin{equation} \label{eq:ssETS(A,A,A)StateVector}<br />
	v_{t-l} =<br />
	\begin{pmatrix}<br />
		l_{t-1} \\<br />
		b_{t-1} \\<br />
		s_{t-m}<br />
	\end{pmatrix} ,<br />
\end{equation}<br />
where \(l_{t-1}\) is lagged level component, \(b_{t-1}\) is lagged trend component, \(s_{t-m}\) is lagged seasonal component and \(m\) is lag of seasonality. Inserting \eqref{eq:ssETS(A,A,A)StateVector} in \eqref{eq:ssGeneralAdditive} and substituting all the other elements with the appropriate values, leads to the following well-known model, which underlies additive Holt-Winters method:<br />
\begin{equation} \label{eq:ssETS(A,A,A)}<br />
	\begin{matrix}<br />
		y_t = l_{t-1} + b_{t-1} + s_{t-m} + \epsilon_t \\<br />
		l_t = l_{t-1} + b_{t-1} + \alpha \epsilon_t \\<br />
		b_t = b_{t-1} + \beta \epsilon_t \\<br />
		s_t = s_{t-m} + \gamma \epsilon_t<br />
	\end{matrix} .<br />
\end{equation}</p>
<p>In case of <a href="http://www.springer.com/gp/book/9783540719168" target="_blank" rel="noopener noreferrer">Hyndman et al. (2008)</a> equation \eqref{eq:ssETS(A,A,A)} would contain \(m-\)1 more seasonal components, which would not be updated (claiming that their values are just moved to another observation). So the essence of the model would be the same, but it would be larger in size. By introducing the lagged structure of state vector, we decrease dimensions of \(v_t, w, F\) and \(g\). This simplifies some derivations and also means that normalisation of seasonal components needs to be done differently, than proposed by <a href="http://www.springer.com/gp/book/9783540719168" target="_blank" rel="noopener noreferrer">Hyndman et al. (2008)</a>. Point forecasts in this case should be similar to <span class="lang:r decode:true  crayon-inline " >ets()</span>, however prediction intervals and seasonal components could be potentially slightly different than in <span class="lang:r decode:true  crayon-inline " >ets()</span>. Although using lags instead of dummies can be considered as a substantial difference from modelling perspective, it does not change substantially the final forecasts, and all the statistical properties of the model are still there. For example, concentrated log-likelihood for models with additive errors is calculated in exactly the same manner as in the original ETS:<br />
\begin{equation} \label{eq:ssConcentratedLogLikelihoodNorm}<br />
	\ell(\theta | Y) = -\frac{T}{2} \left( \log \left( 2 \pi e \right) +\log \left( \hat{\sigma}^2 \right) \right),<br />
\end{equation}<br />
where \(\theta\) is a set of parameters used in model and \(T\) is number of observations. This likelihood can be used for the purpose of estimation of models and selection of the most appropriate one via information criteria. We will discuss these elements in details in the upcoming posts.</p>
<p><!-- By default in <span class="lang:r decode:true  crayon-inline " >es()</span> the optimisation of additive error ETS models is done using Mean Squared Error, which in case of normal distribution of the residuals is equivalent to maximisation of \eqref{eq:ssConcentratedLogLikelihoodNorm}. --></p>
<h3>A bit of examples in R</h3>
<p>Let&#8217;s see some examples of usage of <span class="lang:r decode:true  crayon-inline " >es()</span>. We will use library &#8220;Mcomp&#8221;, so don&#8217;t forget to install it (if you haven&#8217;t done so before) and load it using <span class="lang:r decode:true  crayon-inline " >library(Mcomp)</span>.</p>
<p>We start by estimating some model on a time series N1234. This time series has an obvious trend, and a safe option in forecasting of this sort of time series is using Damped trend method, which corresponds to ETS(A,Ad,N) model:</p>
<pre class="decode" title="Examples of usage" >es(M3$N1234$x, "AAdN", h=8, intervals=TRUE)</pre>
<p>This command produces two things: an output and the following graph:<br />
<div id="attachment_936" style="width: 310px" class="wp-caption alignnone"><a href="/wp-content/uploads/2016/10/N1234-AAdN.png"><img loading="lazy" decoding="async" aria-describedby="caption-attachment-936" src="/wp-content/uploads/2016/10/N1234-AAdN-300x175.png" alt="Series N1234 from M3 and es() forecast" width="300" height="175" class="size-medium wp-image-936" srcset="https://openforecast.org/wp-content/webpc-passthru.php?src=https://openforecast.org/wp-content/uploads/2016/10/N1234-AAdN-300x175.png&amp;nocache=1 300w, https://openforecast.org/wp-content/webpc-passthru.php?src=https://openforecast.org/wp-content/uploads/2016/10/N1234-AAdN-768x448.png&amp;nocache=1 768w, https://openforecast.org/wp-content/webpc-passthru.php?src=https://openforecast.org/wp-content/uploads/2016/10/N1234-AAdN-1024x597.png&amp;nocache=1 1024w, https://openforecast.org/wp-content/webpc-passthru.php?src=https://openforecast.org/wp-content/uploads/2016/10/N1234-AAdN.png&amp;nocache=1 1200w" sizes="auto, (max-width: 300px) 100vw, 300px" /></a><p id="caption-attachment-936" class="wp-caption-text">Series N1234 from M3 and es() forecast</p></div>
<p>If you don&#8217;t need a graph, ask function not to do it via <span class="lang:r decode:true  crayon-inline " >silent=&#8221;graph&#8221;</span>. If you don&#8217;t need an output, then write &#8220;smooth&#8221; object into some variable:</p>
<pre class="decode" title="Examples of usage" >ourModel <- es(M3$N1234$x, "AAdN", h=8, intervals=TRUE, silent="graph")</pre>
<p>In cases of model selection and combinations (which will be discussed later), you may want for the function to work really silently. You then need to specify <span class="lang:r decode:true  crayon-inline " >silent="all"</span> or <span class="lang:r decode:true  crayon-inline " >silent=TRUE</span>.</p>
<p>So, what do we have in that output? Let's see:</p>
<pre title="N1234, ETS(AAdN), output of es()" >Time elapsed: 0.15 seconds
Model estimated: ETS(AAdN)
Persistence vector g:
alpha  beta
0.623 0.26
Damping parameter: 0.964
Initial values were optimised.
6 parameters were estimated in the process
Residuals standard deviation: 75.206
Cost function type: MSE; Cost function value: 4902

Information criteria:
     AIC     AICc      BIC 
522.0857 524.2962 532.9256 

95% parametric prediction intervals were constructed</pre>
<p>The first two lines are self explanatory - all the process took 0.15 seconds and we have constructed damped-trend model.</p>
<p>"Persistence vector g" refers to the vector of smoothing parameters \(g\) in \eqref{eq:ssGeneralAdditive}. It consists of two smoothing parameters: \(\alpha\), for level of series, and \(\beta\), for the trend component. As we see, alpha is pretty high, which indicates that the level component evolves fast in time. Beta is higher than usual, which corresponds to changes of trend in time.</p>
<p>"Damping parameter" shows what is the value of parameter that damps trend. It is close to one, which means that the trend is damped slightly.</p>
<p>The next line tells us how the initial values of state vector \(v_0\) were estimated. This time they were optimised. However we could ask our function to do it differently. We may discuss this some other day, some other time.</p>
<p>After that we see the number of parameters estimated in the process. We get 6 because we have: 2 smoothing parameters, 2 initial values of state vector \(v_0\), 1 damping parameter and 1 estimated variance of residuals. The latter is needed in order to take the correct number of degree of freedom into account. And actually it is not fare to calculate the variance but not to take it into account.</p>
<p>Then we see the value of standard deviation of residuals. This is an unbiased estimate, corrected by the number of degrees of freedom. This means that it is calculated using:<br />
\begin{equation} \label{eq:sd_Value}<br />
	s = \sqrt{\frac{1}{T-k} \sum_{t=1}^T e_t },<br />
\end{equation}<br />
where \(k\) is number of estimated parameters (in our example \(k=\)6). This value is reported just for the general information. It does not tell us much about the estimated model, although we could potentially compare models with additive error using this value... But not today.</p>
<p>The line about cost functions follows. We see that Mean Squared Error was used in the estimation and the final value is equal to 4902. Not really helpful for anything, just a general information.</p>
<p>"Information criteria" line and a table with values below it tell what they say - these are Akaike Information Criterion, it's correct version and Bayesian Information Criterion. These can be compared across different models applied to one and the same sample of data.</p>
<p>Finally, the function tells us that it has produced 95% parametric prediction intervals.</p>
<p>All of this in a way points out at what to expect in <span class="lang:r decode:true  crayon-inline " >ourModel</span>, when we decide to extract some values. Note that <span class="lang:r decode:true  crayon-inline " >ourModel</span> is a list of variables, so the values can be extracted as usual. For example, model name is saved in <span class="lang:r decode:true  crayon-inline " >ourModel$model</span>, while forecasts are stored in <span class="lang:r decode:true  crayon-inline " >ourModel$forecast</span>. The detailed description of returned values is given in the help for function in R.</p>
<p>Now let's make things more interesting and see how the same model performs in the holdout. We will use parameter <span class="lang:r decode:true  crayon-inline " >holdout</span> for this purpose:</p>
<pre class="decode" title="Examples of usage" >y <- ts(c(M3$N1234$x,M3$N1234$xx),start=start(M3$N1234$x),frequency=frequency(M3$N1234$x))
es(y, "AAdN", h=8, holdout=TRUE, intervals=TRUE)</pre>
<p>The resulting graph looks similar to the previous one with a small difference - we now have actual values in the holdout:<br />
<div id="attachment_954" style="width: 310px" class="wp-caption alignnone"><a href="/wp-content/uploads/2016/10/N1234-AAdN-holdout.png"><img loading="lazy" decoding="async" aria-describedby="caption-attachment-954" src="/wp-content/uploads/2016/10/N1234-AAdN-holdout-300x175.png" alt="Series N1234 from M3, es() forecast and holdout" width="300" height="175" class="size-medium wp-image-954" srcset="https://openforecast.org/wp-content/webpc-passthru.php?src=https://openforecast.org/wp-content/uploads/2016/10/N1234-AAdN-holdout-300x175.png&amp;nocache=1 300w, https://openforecast.org/wp-content/webpc-passthru.php?src=https://openforecast.org/wp-content/uploads/2016/10/N1234-AAdN-holdout-768x448.png&amp;nocache=1 768w, https://openforecast.org/wp-content/webpc-passthru.php?src=https://openforecast.org/wp-content/uploads/2016/10/N1234-AAdN-holdout-1024x597.png&amp;nocache=1 1024w, https://openforecast.org/wp-content/webpc-passthru.php?src=https://openforecast.org/wp-content/uploads/2016/10/N1234-AAdN-holdout.png&amp;nocache=1 1200w" sizes="auto, (max-width: 300px) 100vw, 300px" /></a><p id="caption-attachment-954" class="wp-caption-text">Series N1234 from M3, es() forecast and holdout</p></div>
<p>As it can be seen from the graph we didn't manage to produce forecasts close to the actual values, but at least prediction intervals cover them. The output gives us more information about that:</p>
<pre title="N1234, ETS(AAN), holdout, output of es()" >Time elapsed: 0.18 seconds
Model estimated: ETS(AAdN)
Persistence vector g:
alpha  beta 
0.623 0.260 
Damping parameter: 0.964
Initial values were optimised.
6 parameters were estimated in the process
Residuals standard deviation: 75.206
Cost function type: MSE; Cost function value: 4902

Information criteria:
     AIC     AICc      BIC 
522.0857 524.2962 532.9256 

95% parametric prediction intervals were constructed
88% of values are in the prediction interval
Forecast errors:
MPE: -3.2%; Bias: -100%; MAPE: 3.2%; SMAPE: 3.2%
MASE: 4.183; sMAE: 3.7%; RelMAE: 3.436; sMSE: 0.2%</pre>
<p>The main difference between this output and the previous one is in last several lines. Now the function also informs us, in how many cases the prediction intervals covered actual values (88%) and what were the prediction errors for the holdout. The errors are:</p>
<ul>
<li>MPE - Mean Percentage Error;</li>
<li>Bias - Coefficient based on Mean Root Error, measuring symmetry / bias in residuals. If it is 0, then there's no bias, otherwise there is either positive or negative bias. This coefficient lies in region from -100% to 100%;</li>
<li>MAPE - Mean Absolute Percentage Error;</li>
<li>SMAPE - Symmetric Mean Absolute Percentage Error;</li>
<li>MASE - Mean Absolute Scaled Error;</li>
<li>sMAE - Scaled Mean Absolute Error (MAE divided  by mean absolute actual value);</li>
<li>RelMAE - Relative Mean Absolute Error (comparison is done with Naive);</li>
<li>sMSE - Scaled Mean Squared Error. This is scaled by dividing MSE by square of mean absolute actual value.</li>
</ul>
<p>These error measures allow us assessing accuracy of the produced model. They do not mean much on their own, but can be compared across several models. For example, ETS(A,A,N) applied to the same data has:</p>
<pre title="N1234, ETS(AAN), holdout, output of es()" >MPE: -3.7%; Bias: -100%; MAPE: 3.7%; SMAPE: 3.6%
MASE: 4.82; sMAE: 4.3%; RelMAE: 3.958; sMSE: 0.2%</pre>
<p>Comparing these errors with the errors of ETS(A,Ad,N), we can say that damped trend model performs slightly better than ETS(A,A,N).</p>
<p>The only meaningful metric in the list, that can be analysed on its own, is RelMAE, which shows us that our forecast is 3.436 times worse than Naive. Not really soothing...</p>
<p>All these errors are stored in <span class="lang:r decode:true  crayon-inline " >ourModel$accuracy</span> as a vector. Additionally, because we used <span class="lang:r decode:true  crayon-inline " >holdout=TRUE</span> in the estimation, now we have this part of data in a special variable - <span class="lang:r decode:true  crayon-inline " >ourModel$holdout</span>. This is handy, because allows calculating any other error measures you can think of.</p>
<p>We have mentioned seasonal models in this post, so let's see how <span class="lang:r decode:true  crayon-inline " >es()</span> works with seasonal data on an example of ETS(A,N,A) model and time series N1956:</p>
<pre class="decode" title="N1956, ETS(ANA)" >ourModel <- es(M3$N1956$x, "ANA", h=18)</pre>
<p>The resulting graph should look like the following one:<br />
<div id="attachment_976" style="width: 310px" class="wp-caption alignnone"><a href="/wp-content/uploads/2016/11/N1956-ANA.png"><img loading="lazy" decoding="async" aria-describedby="caption-attachment-976" src="/wp-content/uploads/2016/11/N1956-ANA-300x175.png" alt="Series N1956 from M3 and es() forecast" width="300" height="175" class="size-medium wp-image-976" srcset="https://openforecast.org/wp-content/webpc-passthru.php?src=https://openforecast.org/wp-content/uploads/2016/11/N1956-ANA-300x175.png&amp;nocache=1 300w, https://openforecast.org/wp-content/webpc-passthru.php?src=https://openforecast.org/wp-content/uploads/2016/11/N1956-ANA-768x448.png&amp;nocache=1 768w, https://openforecast.org/wp-content/webpc-passthru.php?src=https://openforecast.org/wp-content/uploads/2016/11/N1956-ANA-1024x597.png&amp;nocache=1 1024w, https://openforecast.org/wp-content/webpc-passthru.php?src=https://openforecast.org/wp-content/uploads/2016/11/N1956-ANA.png&amp;nocache=1 1200w" sizes="auto, (max-width: 300px) 100vw, 300px" /></a><p id="caption-attachment-976" class="wp-caption-text">Series N1956 from M3 and es() forecast</p></div>
<p>There is not much to say about this graph, except that the model is fitted well and more or less adequate forecasts have been produced (at least nothing ridiculous). Obviously if we compare this model with the one estimated using <span class="lang:r decode:true  crayon-inline " >ets()</span>, we will see that there are some small differences. For example, smoothing parameters values and initial values will differ, which will lead to slightly different forecasts. Here's an example of forecasts for 6 months ahead produced by both functions:</p>
<table>
<thead>
<tr>
<td>h</td>
<td><span class="lang:r decode:true  crayon-inline " >es()</span></td>
<td><span class="lang:r decode:true  crayon-inline " >ets()</span></td>
</tr>
</thead>
<tr>
<td>1</td>
<td>3106.583</td>
<td>3105.761</td>
</tr>
<tr>
<td>2</td>
<td>3592.868</td>
<td>3580.976</td>
</tr>
<tr>
<td>3</td>
<td>4395.580</td>
<td>4389.775</td>
</tr>
<tr>
<td>4</td>
<td>5044.109</td>
<td>5052.459</td>
</tr>
<tr>
<td>5</td>
<td>4305.332</td>
<td>4364.522</td>
</tr>
<tr>
<td>6</td>
<td>3650.615</td>
<td>3733.528</td>
</tr>
</table>
<p>As we see, for some values the difference is almost non-existent (0.822 for \(h=\)1), but for the others it becomes larger (-82.913 for \(h=\)6). Still the overall difference between these two forecasts is around 0.43% (averaged out for the horizon of 1 to 6, scaled to the mean of the data), so it is not clear, which of the two forecasts is more adequate. This difference is not only caused by the structure of state vector, but also by the optimisers used in functions: the one used in <span class="lang:r decode:true  crayon-inline " >es()</span> is more precise, which however not necessarily transfers to increase in forecasting accuracy.</p>
<p>That's it for today. Next time we will look into models with multiplicative errors. They have some important differences in comparison with <span class="lang:r decode:true  crayon-inline " >ets()</span>, that we should discuss.</p>
<p>Message <a href="https://openforecast.org/2016/11/02/smooth-package-for-r-es-function-part-ii-pure-additive-models/">&#8220;smooth&#8221; package for R. es() function. Part II. Pure additive models</a> first appeared on <a href="https://openforecast.org">Open Forecasting</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://openforecast.org/2016/11/02/smooth-package-for-r-es-function-part-ii-pure-additive-models/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>&#8220;smooth&#8221; package for R. es() function. Part I</title>
		<link>https://openforecast.org/2016/10/14/smooth-package-for-r-es-i/</link>
					<comments>https://openforecast.org/2016/10/14/smooth-package-for-r-es-i/#respond</comments>
		
		<dc:creator><![CDATA[Ivan Svetunkov]]></dc:creator>
		<pubDate>Fri, 14 Oct 2016 15:29:45 +0000</pubDate>
				<category><![CDATA[About es() function]]></category>
		<category><![CDATA[Applied forecasting]]></category>
		<category><![CDATA[ETS]]></category>
		<category><![CDATA[Package smooth for R]]></category>
		<category><![CDATA[R]]></category>
		<category><![CDATA[Univariate models]]></category>
		<category><![CDATA[programming]]></category>
		<category><![CDATA[smooth]]></category>
		<guid isPermaLink="false">https://openforecast.org/?p=804</guid>

					<description><![CDATA[<p>Good news, everyone! &#8220;smooth&#8221; package is now available on CRAN. And it is time to look into what this package can do and why it is needed at all. The package itself contains some documentation that you can use as a starting point. For example, there are vignettes, which show included functions and what they [&#8230;]</p>
<p>Message <a href="https://openforecast.org/2016/10/14/smooth-package-for-r-es-i/">&#8220;smooth&#8221; package for R. es() function. Part I</a> first appeared on <a href="https://openforecast.org">Open Forecasting</a>.</p>
]]></description>
										<content:encoded><![CDATA[<p>Good news, everyone! &#8220;smooth&#8221; package is now <a href="https://cran.r-project.org/package=smooth" target="_blank" rel="noopener noreferrer">available on CRAN</a>. And it is time to look into what this package can do and why it is needed at all. The package itself contains some documentation that you can use as a starting point. For example, there are <a href="https://cran.r-project.org/package=smooth/vignettes/smooth.html" target="_blank" rel="noopener noreferrer">vignettes</a>, which show included functions and what they allow to do, but do not go into details of what is happening inside those functions. If you don&#8217;t have a personal life and are ready to spend some time reading semi-scientific materials with formulae, then I have a thing especially for you &#8211; <a href="https://github.com/config-i1/smooth/blob/master/inst/doc/smooth-Documentation.pdf" target="_blank" rel="noopener noreferrer">smooth documentation</a>, which describes in details why models used in the package make sense, how they are optimised and what it leads to. Here we will try to look into some functions and their application to real life forecasting problems.</p>
<p>This is the first post in a series of posts on &#8220;smooth&#8221; functions. We start with <span class="lang:r decode:true  crayon-inline " >es()</span> &#8211; Exponential Smoothing.</p>
<h3>What is es() and why do we need it?</h3>
<p>&#8220;ES&#8221; stands for &#8220;Exponential Smoothing&#8221;. This function is an implementation of ETS model, alternative to Rob Hyndman&#8217;s <span class="lang:r decode:true  crayon-inline " >ets()</span> function from &#8220;<a href="https://github.com/robjhyndman/forecast" target="_blank" rel="noopener noreferrer">forecast</a>&#8221; package. The natural question would be: &#8220;Why bother if there already exists exponential smoothing function&#8221;? There are several reasons for that:</p>
<ol>
<li><span class="lang:r decode:true  crayon-inline " >ets()</span> does not allow constructing some mixed models. For example, classical Holt-Winters model, which corresponds to ETS(A,A,M) is unavailable. This is not a big loss, but these models may be of interest to researchers. So <span class="lang:r decode:true  crayon-inline " >es()</span> function has all 30 of them;</li>
<li><span class="lang:r decode:true  crayon-inline " >ets()</span> does not have exogenous variables. <span class="lang:r decode:true  crayon-inline " >es()</span> allows providing either vector or matrix of exogenous variables. Note, however, that currently only additive ETS models are guaranteed to work well with exogenous variables. It will most probably work fine for other models, but I cannot guarantee stable performance;</li>
<li>There are quite few papers in forecasting field that show that using combinations of forecasts of different models leads to increase in forecasting accuracy. Stephan Kolassa <a href="http://econpapers.repec.org/article/eeeintfor/v_3a27_3ay_3a_3ai_3a2_3ap_3a238-251.htm" target="_blank" rel="noopener noreferrer">applied one neat method</a> of combinations described in <a href="http://www.springer.com/la/book/9780387953649" target="_blank" rel="noopener noreferrer">Burnham and Anderson book</a> to exponential smoothing, showing that it leads to increase of forecast accuracy. So I took that method and implemented it in <span class="lang:r decode:true  crayon-inline " >es()</span> function;</li>
<li><span class="lang:r decode:true  crayon-inline " >ets()</span> function restricts number of seasonal coefficients by 24. The motivation here is that with higher number of coefficients, optimisers will do lousy job in finding optimal values of parameters. <span class="lang:r decode:true  crayon-inline " >es()</span> doesn&#8217;t have this restriction, claiming that users should be responsible for their own actions. Every action has consequences, you know? So, be smart and responsible!</li>
<li><span class="lang:r decode:true  crayon-inline " >ets()</span> function does not allow defining initial values for state vector. In general, who could care less, right? But they may become important in some cases, when optimisation of initial states is not an option. So I have implemented two methods of initialisation (optimisation and backcasting) + allowed users providing initial values if they really need to. This also allows addressing problem with large number of parameters because of number of seasonal coefficients. For example, if you deal with weekly data, then you can switch to backcasting or provide your own values for seasonal indices;</li>
<li>MSE as cost function looked too boring, so I have introduced MAE, cost functions based on multiple steps ahead forecasting errors and exotic &#8220;Half Absolute Moment&#8221;. Why? Well, just in order to make life more exiting! (although there is a rationale for that, which is discussed in the documentation)</li>
<li>There are several ways of constructing prediction intervals. <span class="lang:r decode:true  crayon-inline " >es()</span> allows selecting between parametric, semi-parametric and non-parametric ones. This additional flexibility allows dealing with cases, when for some reason basic assumptions of ETS do not hold;</li>
<li>The derived underlying statistical model in <span class="lang:r decode:true  crayon-inline " >es()</span> differs slightly from <span class="lang:r decode:true  crayon-inline " >ets()</span>. This becomes especially evident, when models with multiplicative errors are used. There we assume that error term is distributed log-normally on the contrast to assumption of normality in <span class="lang:r decode:true  crayon-inline " >ets()</span>;</li>
<li>All the functions of &#8220;smooth&#8221; package allow dealing with intermittent data. This is based on a <a href="/2016/07/01/19th-iif-workshop/">very recent research</a> done in collaboration with John Boylan. So <span class="lang:r decode:true  crayon-inline " >es()</span> function allows producing forecasts using Croston&#8217;s model (not method, this is not a typo!) and some other intermittent data models. We can even select between intermittent and normal models using this approach. This is still an on-going research, so more models will follow with more advanced mechanisms;</li>
<li>Last but not least, we have a fancy <span class="lang:r decode:true  crayon-inline " >holdout</span> parameter, which allows dividing provided time series into two parts, fitting model on the first one and assessing forecasts accuracy on the second.</li>
</ol>
<p>Having said that, I am not claiming that <span class="lang:r decode:true  crayon-inline " >es()</span> function always produces more accurate forecasts than <span class="lang:r decode:true  crayon-inline " >ets()</span>. From what I have experienced so far the function is sometimes more accurate and sometimes less accurate than <span class="lang:r decode:true  crayon-inline " >ets()</span>. However the main point of the function is not in precision, but in flexibility. You can do much more with it, than with <span class="lang:r decode:true  crayon-inline " >ets()</span>, the only restriction for you is your imagination! If you don&#8217;t have imagination and / or just need an efficient exponential smoothing function, don&#8217;t waste your time with <span class="lang:r decode:true  crayon-inline " >es()</span> and use Rob&#8217;s <span class="lang:r decode:true  crayon-inline " >ets()</span>.</p>
<p>Message <a href="https://openforecast.org/2016/10/14/smooth-package-for-r-es-i/">&#8220;smooth&#8221; package for R. es() function. Part I</a> first appeared on <a href="https://openforecast.org">Open Forecasting</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://openforecast.org/2016/10/14/smooth-package-for-r-es-i/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
	</channel>
</rss>
