<?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 Regression - Open Forecasting</title>
	<atom:link href="https://openforecast.org/category/univariate-en/regression/feed/" rel="self" type="application/rss+xml" />
	<link>https://openforecast.org/category/univariate-en/regression/</link>
	<description>How to look into the future</description>
	<lastBuildDate>Mon, 28 Jul 2025 15:51:00 +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 Regression - Open Forecasting</title>
	<link>https://openforecast.org/category/univariate-en/regression/</link>
	<width>32</width>
	<height>32</height>
</image> 
	<item>
		<title>Story of &#8220;Probabilistic forecasting of hourly emergency department arrivals&#8221;</title>
		<link>https://openforecast.org/2023/05/10/story-of-probabilistic-forecasting-of-hourly-emergency-department-arrivals/</link>
					<comments>https://openforecast.org/2023/05/10/story-of-probabilistic-forecasting-of-hourly-emergency-department-arrivals/#respond</comments>
		
		<dc:creator><![CDATA[Ivan Svetunkov]]></dc:creator>
		<pubDate>Wed, 10 May 2023 20:47:27 +0000</pubDate>
				<category><![CDATA[adam()]]></category>
		<category><![CDATA[Applied forecasting]]></category>
		<category><![CDATA[ETS]]></category>
		<category><![CDATA[R]]></category>
		<category><![CDATA[Regression]]></category>
		<category><![CDATA[Stories]]></category>
		<category><![CDATA[Univariate models]]></category>
		<category><![CDATA[ADAM]]></category>
		<category><![CDATA[papers]]></category>
		<guid isPermaLink="false">https://openforecast.org/?p=3092</guid>

					<description><![CDATA[<p>The paper Back in 2020, when we were all siting in the COVID lockdown, I had a call with Bahman Rostami-Tabar to discuss one of our projects. He told me that he had an hourly data of an Emergency Department from a hospital in Wales, and suggested writing a paper for a healthcare audience to [&#8230;]</p>
<p>Message <a href="https://openforecast.org/2023/05/10/story-of-probabilistic-forecasting-of-hourly-emergency-department-arrivals/">Story of &#8220;Probabilistic forecasting of hourly emergency department arrivals&#8221;</a> first appeared on <a href="https://openforecast.org">Open Forecasting</a>.</p>
]]></description>
										<content:encoded><![CDATA[<p><a href="/en/2023/05/09/probabilistic-forecasting-of-hourly-emergency-department-arrivals/">The paper</a></p>
<p>Back in 2020, when we were all siting in the COVID lockdown, I had a call with <a href="https://www.bahmanrt.com/">Bahman Rostami-Tabar</a> to discuss one of our projects. He told me that he had an hourly data of an Emergency Department from a hospital in Wales, and suggested writing a paper for a healthcare audience to show them how forecasting can be done properly in this setting. I noted that we did not have experience in working with high frequency data, and it would be good to have someone with relevant expertise. I knew a guy who worked in energy forecasting, <a href="http://www.jethrobrowell.com/">Jethro Browell</a> (we are mates in the <a href="https://forecasters.org/programs/communities/united-kingdom-chapter/">IIF UK Chapter</a>), so we had a chat between the three of us and formed a team to figure out better ways for ED arrival demand forecasting.</p>
<p>We agreed that each one of us will try their own models. Bahman wanted to try TBATS, Prophet and models from the <a href="https://github.com/tidyverts/fasster">fasster</a> package in R (spoiler: the latter ones produced very poor forecasts on our data, so we removed them from the paper). Jethro had a pool of <a href="https://www.gamlss.com/" rel="noopener" target="_blank">GAMLSS</a> models with different distributions, including Poisson and truncated Normal. He also tried a Gradient Boosting Machine (GBM). I decided to test ETS, Poisson Regression and <a href="https://openforecast.org/adam/" rel="noopener" target="_blank">ADAM</a>. We agreed that we will measure performance of models not only in terms of point forecasts (using RMSE), but also in terms of quantiles (pinball and quantile bias) and computational time. It took us a year to do all the experiments and another one to find a journal that would not desk-reject our paper because the editor thought that it was not relevant (even though they have published similar papers in the past). It was rejected from Annals of Emergency Medicine, Emergency Medicine Journal, American Journal of Emergency Medicine and Journal of Medical Systems. In the end, we submitted to Health Systems, and after a short revision the paper got accepted. So, there is a happy end in this story.</p>
<p>In the paper itself, we found that overall, in terms of quantile bias (calibration of models), GAMLSS with truncated Normal distribution and ADAM performed better than the other approaches, with the former also doing well in terms of pinball loss and the latter doing well in terms of point forecasts (RMSE). Note that the count data models did worse than the continuous ones, although one would expect Poisson distribution to be appropriate for the ED arrivals.</p>
<p>I don&#8217;t want to explain the paper and its findings in detail in this post, but given my relation to ADAM, I have decided to briefly explain what I included in the model and how it was used. After all, this is the first paper that uses almost all the main features of ADAM and shows how powerful it can be if used correctly.</p>
<h3>Using ADAM in Emergency Department arrivals forecasting</h3>
<p><strong>Disclaimer</strong>: The explanation provided here relies on the content of my monograph &#8220;<a href="https://openforecast.org/adam/">Forecasting and Analytics with ADAM</a>&#8220;. In the paper, I ended up creating a quite complicated model that allowed capturing complex demand dynamics. In order to fully understand what I am discussing in this post, you might need to refer to the monograph.</p>
<div id="attachment_3117" style="width: 1210px" class="wp-caption aligncenter"><a href="https://openforecast.org/wp-content/webpc-passthru.php?src=https://openforecast.org/wp-content/uploads/2023/05/EDArrivals-data.png&amp;nocache=1"><img fetchpriority="high" decoding="async" aria-describedby="caption-attachment-3117" src="https://openforecast.org/wp-content/webpc-passthru.php?src=https://openforecast.org/wp-content/uploads/2023/05/EDArrivals-data.png&amp;nocache=1" alt="Emergency Department Arrivals" width="1200" height="800" class="size-full wp-image-3117" srcset="https://openforecast.org/wp-content/webpc-passthru.php?src=https://openforecast.org/wp-content/uploads/2023/05/EDArrivals-data.png&amp;nocache=1 1200w, https://openforecast.org/wp-content/webpc-passthru.php?src=https://openforecast.org/wp-content/uploads/2023/05/EDArrivals-data-300x200.png&amp;nocache=1 300w, https://openforecast.org/wp-content/webpc-passthru.php?src=https://openforecast.org/wp-content/uploads/2023/05/EDArrivals-data-1024x683.png&amp;nocache=1 1024w, https://openforecast.org/wp-content/webpc-passthru.php?src=https://openforecast.org/wp-content/uploads/2023/05/EDArrivals-data-768x512.png&amp;nocache=1 768w" sizes="(max-width: 1200px) 100vw, 1200px" /></a><p id="caption-attachment-3117" class="wp-caption-text">Emergency Department Arrivals. The plots were generated using <code>seasplot()</code> function from the <code>tsutils</code> package.</p></div>
<p>The figure above shows the data that we were dealing with together with several seasonal plots (generated using <code>seasplot()</code> function from the <code>tsutils</code> package). As we see, the data exhibits hour of day, day of week and week of year seasonalities, although some of them are not very well pronounced. The data does not seem to have a strong trend, although there is a slow increase of the level. Based on this, I decided to use ETS(M,N,M) as the basis for modelling. However, if we want to capture all three seasonal patterns then we need to fit a triple seasonal model, which requires too much computational time, because of the estimation of all the seasonal indices. So, I have decided to use a <a href="https://openforecast.org/adam/ADAMMultipleFrequencies.html">double-seasonal ETS(M,N,M)</a> instead with hour of day and hour of week seasonalities and to include <a href="https://openforecast.org/adam/ETSXMultipleSeasonality.html">dummy variables for week of year seasonality</a>. The alternative to week of year dummies would be hour of year seasonal component, which would then require estimating 8760 seasonal indices, potentially overfitting the data. I argue that the week of year dummy provides the sufficient flexibility and there is no need in capturing the detailed intra-yearly profile on a more granular level.</p>
<p>To make things more exciting, given that we deal with hourly data of a UK hospital, we had to deal with issues of <a href="https://openforecast.org/adam/MultipleFrequenciesDSTandLeap.html">daylight saving and leap year</a>. I know that many of us hate the idea of daylight saving, because we have to change our lifestyles 2 times each year just because of an old 18th century tradition. But in addition to being <a href="https://publichealth.jhu.edu/2023/7-things-to-know-about-daylight-saving-time#:~:text=Making%20the%20shift%20can%20increase,a%20professor%20in%20Mental%20Health.">bad for your health</a>, this nasty thing messes things up for my models, because once a year we have 23 hours and in another time we have 25 hours in a day. Luckily, it is taken care of by <code>adam()</code> that shifts seasonal indices, when the time change happens. All you need to do for this mechanism to work is to provide an object with timestamps to the function (for example, zoo). As for the leap year, it becomes less important when we model week of year seasonality instead of the day of year or hour of year one.</p>
<div id="attachment_3123" style="width: 1210px" class="wp-caption aligncenter"><a href="https://openforecast.org/wp-content/webpc-passthru.php?src=https://openforecast.org/wp-content/uploads/2023/05/EDArrivals-data-daily.png&amp;nocache=1"><img decoding="async" aria-describedby="caption-attachment-3123" src="https://openforecast.org/wp-content/webpc-passthru.php?src=https://openforecast.org/wp-content/uploads/2023/05/EDArrivals-data-daily.png&amp;nocache=1" alt="Emergency Department Daily Arrivals" width="1200" height="700" class="size-full wp-image-3123" srcset="https://openforecast.org/wp-content/webpc-passthru.php?src=https://openforecast.org/wp-content/uploads/2023/05/EDArrivals-data-daily.png&amp;nocache=1 1200w, https://openforecast.org/wp-content/webpc-passthru.php?src=https://openforecast.org/wp-content/uploads/2023/05/EDArrivals-data-daily-300x175.png&amp;nocache=1 300w, https://openforecast.org/wp-content/webpc-passthru.php?src=https://openforecast.org/wp-content/uploads/2023/05/EDArrivals-data-daily-1024x597.png&amp;nocache=1 1024w, https://openforecast.org/wp-content/webpc-passthru.php?src=https://openforecast.org/wp-content/uploads/2023/05/EDArrivals-data-daily-768x448.png&amp;nocache=1 768w" sizes="(max-width: 1200px) 100vw, 1200px" /></a><p id="caption-attachment-3123" class="wp-caption-text">Emergency Department Daily Arrivals</p></div>
<p>Furthermore, as it can be seen from the figure above, it is apparent that <a href="https://openforecast.org/adam/ADAMX.html">calendar events</a> play a crucial role in ED arrivals. For example, the Emergency Department demand over Christmas is typically lower than average (the drops in Figure above), but right after the Christmas it tends to go up (with all the people who injured themselves during the festivities showing up in the hospital). So these events need to be taken into account in a form of additional dummy variables by a model together with their lags (the 24 hour lags of the original variables).</p>
<p>But that&#8217;s not all. If we want to fit a multiplicative seasonal model (which makes more sense than the additive one due to changing seasonal amplitude for different times of year), we need to do something with zeroes, which happen naturally in ED arrivals over night (see the first figure in this post with seasonal plots). They do not necessarily happen at the same time of day, but the probability of having no demand tends to increase at night. This meant that I needed to introduce the <a href="https://openforecast.org/adam/ADAMIntermittent.html">occurrence part of the model</a> to take care of zeroes. I used a very basic occurrence model called &#8220;<a href="https://openforecast.org/adam/ADAMOccurrence.html#oETSD">direct probability</a>&#8220;, because it is more sensitive to changes in demand occurrence, making the model more responsive. I did not use a seasonal demand occurrence model (and I don&#8217;t remember why), which is one of the limitations of ADAM used in this study.</p>
<p>Finally, given that we are dealing with low volume data, a positive distribution needed to be used instead of the Normal one. I used <a href="https://openforecast.org/adam/ADAMETSMultiplicativeDistributions.html">Gamma distribution</a> because it is better behaved than the Log Normal or the Inverse Gaussian, which tend to have much heavier tails. In the exploration of the data, I found that Gamma does better than the other two, probably because the ED arrivals have relatively slim tails.</p>
<p>So, the final ADAM included the following features:</p>
<ul>
<li>ETS(M,N,M) as the basis;</li>
<li>Double seasonality;</li>
<li>Week of year dummy variables;</li>
<li>Dummy variables for calendar events with their lags;</li>
<li>&#8220;Direct probability&#8221; occurrence model;</li>
<li>Gamma distribution for the residuals of the model.</li>
</ul>
<p>This model is summarised in equation (3) of <a href="/en/2023/05/09/probabilistic-forecasting-of-hourly-emergency-department-arrivals/">the paper</a>.</p>
<p>The model was <a href="https://openforecast.org/adam/ADAMInitialisation.html">initialised using backcasting</a>, because otherwise we would need to estimate too many initial values for the state vector. The estimation itself was done using <a href="https://openforecast.org/adam/ADAMETSEstimationLikelihood.html">likelihood</a>. In R, this corresponded to roughly the following lines of code:</p>
<pre class="decode">library(smooth)
oesModel <- oes(y, "MNN", occurrence="direct", h=48)
adamModelFirst <- adam(ourData, "MNM", lags=c(24,24*7), formula=y~x+xLag24+weekOfYear,
                       h=48, initial="backcasting",
                       occurrence=oesModel, distribution="dgamma")</pre>
<p>Where <code>x</code> was the categorical variable (factor in R) with all the main calendar events. However, even with backcasting, the estimation of such a big model took an hour and 25 minutes. Given that Bahman, Jethro and I have agreed to do rolling origin evaluation, I've decided to help the function in the estimation inside the loop, providing <a href="https://openforecast.org/adam/ADAMInitialisation.html#starting-optimisation-of-parameters">the initials to the optimiser</a> based on the very first estimated model. As a result, each estimation of ADAM in the rolling origin took 1.5 minutes. The code in the loop was modified to:</p>
<pre class="decode">adamParameters <- coef(adamModelFirst)
oesModel <- oes(y, "MNN", occurrence="direct", h=48)
adamModel <- adam(ourData, "MNM", lags=c(24,24*7), formula=y~x+xLag24+weekOfYear,
                  h=48, initial="backcasting",
                  occurrence=oesModel, distribution="dgamma",
                  B=adamParameters)</pre>
<p>Finally, we generated mean and quantile forecasts for 48 hours ahead. I used <a href="https://openforecast.org/adam/ADAMForecastingPI.html#semiparametric-intervals">semiparametric quantiles</a>, because I expected violation of some of assumptions in the model (e.g. autocorrelated residuals). The respective R code is:</p>
<pre class="decode">testForecast <- forecast(adamModel, newdata=newdata, h=48,
                         interval="semiparametric", level=c(1:19/20), side="upper")</pre>
<p>Furthermore, given that the data is integer-valued (how many people visit the hospital each hour) and ADAM produces fractional quantiles (because of the Gamma distribution), I decided to see how it would perform if the quantiles were rounded up. This strategy is simple and might be sensible when a continuous model is used for forecasting on a count data (see discussion in the paper). However, after running the experiment, the ADAM with rounded up quantiles performed very similar to the conventional one, so we have decided not to include it in the paper.</p>
<p>In the end, as stated earlier in this post, we concluded that in our experiment, there were two well performing approaches: GAMLSS with Truncated Normal distribution (called "NOtr-2" in the paper) and ADAM in the form explained above. The popular TBATS, Prophet and Gradient Boosting Machine performed poorly compared to these two approaches. For the first two, this is because of the lack of explanatory variables and inappropriate distributional assumptions (normality). As for the GBM, this is probably due to the lack of dynamic element in it (e.g. changing level and seasonal components).</p>
<p>Concluding this post, as you can see, I managed to fit a decent model based on ADAM, which captured the main characteristics of the data. However, it took a bit of time to understand what features should be included, together with some experiments on the data. This case study shows that if you want to get a better model for your problem, you might need to dive in the problem and spend some time analysing what you have on hands, experimenting with different parameters of a model. ADAM provides the flexibility necessary for such experiments.</p>
<p>Message <a href="https://openforecast.org/2023/05/10/story-of-probabilistic-forecasting-of-hourly-emergency-department-arrivals/">Story of &#8220;Probabilistic forecasting of hourly emergency department arrivals&#8221;</a> first appeared on <a href="https://openforecast.org">Open Forecasting</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://openforecast.org/2023/05/10/story-of-probabilistic-forecasting-of-hourly-emergency-department-arrivals/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>smooth v3.2.0: what&#8217;s new?</title>
		<link>https://openforecast.org/2023/01/30/smooth-v3-2-0-what-s-new/</link>
					<comments>https://openforecast.org/2023/01/30/smooth-v3-2-0-what-s-new/#comments</comments>
		
		<dc:creator><![CDATA[Ivan Svetunkov]]></dc:creator>
		<pubDate>Mon, 30 Jan 2023 13:06:47 +0000</pubDate>
				<category><![CDATA[About es() function]]></category>
		<category><![CDATA[adam()]]></category>
		<category><![CDATA[ARIMA]]></category>
		<category><![CDATA[ETS]]></category>
		<category><![CDATA[Package smooth for R]]></category>
		<category><![CDATA[R]]></category>
		<category><![CDATA[Regression]]></category>
		<category><![CDATA[Univariate models]]></category>
		<category><![CDATA[ADAM]]></category>
		<category><![CDATA[smooth]]></category>
		<guid isPermaLink="false">https://openforecast.org/?p=3063</guid>

					<description><![CDATA[<p>smooth package has reached version 3.2.0 and is now on CRAN. While the version change from 3.1.7 to 3.2.0 looks small, this has introduced several substantial changes and represents a first step in moving to the new C++ code in the core of the functions. In this short post, I will outline the main new [&#8230;]</p>
<p>Message <a href="https://openforecast.org/2023/01/30/smooth-v3-2-0-what-s-new/">smooth v3.2.0: what&#8217;s new?</a> first appeared on <a href="https://openforecast.org">Open Forecasting</a>.</p>
]]></description>
										<content:encoded><![CDATA[<p>smooth package has reached version 3.2.0 and is now <a href="https://cran.r-project.org/package=smooth">on CRAN</a>. While the version change from 3.1.7 to 3.2.0 looks small, this has introduced several substantial changes and represents a first step in moving to the new C++ code in the core of the functions. In this short post, I will outline the main new features of smooth 3.2.0.</p>
<p><a href="https://openforecast.org/wp-content/webpc-passthru.php?src=https://openforecast.org/wp-content/uploads/2023/01/smooth2.png&amp;nocache=1"><img 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 loading="lazy" decoding="async" aria-describedby="caption-attachment-3077" src="https://openforecast.org/wp-content/webpc-passthru.php?src=https://openforecast.org/wp-content/uploads/2023/01/adamSimulate-1024x597.png&amp;nocache=1" alt="Simulated data based on adam() applied to Box-Jenkins sales data" width="640" height="373" class="size-large wp-image-3077" srcset="https://openforecast.org/wp-content/webpc-passthru.php?src=https://openforecast.org/wp-content/uploads/2023/01/adamSimulate-1024x597.png&amp;nocache=1 1024w, https://openforecast.org/wp-content/webpc-passthru.php?src=https://openforecast.org/wp-content/uploads/2023/01/adamSimulate-300x175.png&amp;nocache=1 300w, https://openforecast.org/wp-content/webpc-passthru.php?src=https://openforecast.org/wp-content/uploads/2023/01/adamSimulate-768x448.png&amp;nocache=1 768w, https://openforecast.org/wp-content/webpc-passthru.php?src=https://openforecast.org/wp-content/uploads/2023/01/adamSimulate.png&amp;nocache=1 1200w" sizes="auto, (max-width: 640px) 100vw, 640px" /></a><p id="caption-attachment-3077" class="wp-caption-text">Simulated data based on adam() applied to Box-Jenkins sales data</p></div>
<p>This can be used for research, when a more controlled environment is needed. If you want to fine tune the parameters of ADAM before simulating the data, you can save the output in an object and amend its parameters. For example:</p>
<pre class="decode">testModel <- adam(BJsales, "AAdN")
testModel$persistence <- c(0.5, 0.2)
simulate(testModel)</pre>
<p>The second new method is the <code>xtable()</code> from the respective <code>xtable</code> package. It produces LaTeX version of the table from the summary of ADAM. Here is an example of a summary from ADAM ETS:</p>
<pre class="decode">adam(BJsales, "AAdN") |>
     summary()</pre>
<pre>Model estimated using adam() function: ETS(AAdN)
Response variable: BJsales
Distribution used in the estimation: Normal
Loss function type: likelihood; Loss function value: 256.1516
Coefficients:
      Estimate Std. Error Lower 2.5% Upper 97.5%  
alpha   0.9514     0.1292     0.6960      1.0000 *
beta    0.3328     0.2040     0.0000      0.7358  
phi     0.8560     0.1671     0.5258      1.0000 *
level 203.2835     5.9968   191.4304    215.1289 *
trend  -2.6793     4.7705   -12.1084      6.7437  

Error standard deviation: 1.3623
Sample size: 150
Number of estimated parameters: 6
Number of degrees of freedom: 144
Information criteria:
     AIC     AICc      BIC     BICc 
524.3032 524.8907 542.3670 543.8387</pre>
<p>As you can see in the output above, the function generates the confidence intervals for the parameters of the model, including the smoothing parameters, dampening parameter and the initial states. This summary can then be used to generate the LaTeX code for the main part of the table:</p>
<pre class="decode">adam(BJsales, "AAdN") |>
     xtable()</pre>
<p>which will looks something like this:</p>
<div id="attachment_3073" style="width: 650px" class="wp-caption aligncenter"><a href="https://openforecast.org/wp-content/webpc-passthru.php?src=https://openforecast.org/wp-content/uploads/2023/01/adamXtable.png&amp;nocache=1"><img loading="lazy" decoding="async" aria-describedby="caption-attachment-3073" src="https://openforecast.org/wp-content/webpc-passthru.php?src=https://openforecast.org/wp-content/uploads/2023/01/adamXtable-1024x303.png&amp;nocache=1" alt="Summary of adam()" width="512" height="152" class="size-large wp-image-3073" srcset="https://openforecast.org/wp-content/webpc-passthru.php?src=https://openforecast.org/wp-content/uploads/2023/01/adamXtable-1024x303.png&amp;nocache=1 1024w, https://openforecast.org/wp-content/webpc-passthru.php?src=https://openforecast.org/wp-content/uploads/2023/01/adamXtable-300x89.png&amp;nocache=1 300w, https://openforecast.org/wp-content/webpc-passthru.php?src=https://openforecast.org/wp-content/uploads/2023/01/adamXtable-768x227.png&amp;nocache=1 768w, https://openforecast.org/wp-content/webpc-passthru.php?src=https://openforecast.org/wp-content/uploads/2023/01/adamXtable.png&amp;nocache=1 1207w" sizes="auto, (max-width: 512px) 100vw, 512px" /></a><p id="caption-attachment-3073" class="wp-caption-text">Summary of adam()</p></div>
<h3>Other improvements</h3>
<p>First, one of the major changes in <code>smooth</code> functions is the new backcasting mechanism for <code>adam()</code>, <code>es()</code> and <code>msarima()</code> (this is discussed in <a href="https://openforecast.org/adam/ADAMInitialisation.html">Section 11.4 of ADAM monograph</a>). The main difference with the old one is that now it does not backcast the parameters for the explanatory variables and estimates them separately via optimisation. This feature appeared to be important for some of users who wanted to try MSARIMAX/ETSX (a model with explanatory variables) but wanted to use backcasting as the initialisation. These users then wanted to get a summary, analysing the uncertainty around the estimates of parameters for exogenous variables, but could not because the previous implementation would not estimate them explicitly. This is now available. Here is an example:</p>
<pre class="decode">cbind(BJsales, BJsales.lead) |>
    adam(model="AAdN", initial="backcasting") |>
    summary()</pre>
<pre>Model estimated using adam() function: ETSX(AAdN)
Response variable: BJsales
Distribution used in the estimation: Normal
Loss function type: likelihood; Loss function value: 255.1935
Coefficients:
             Estimate Std. Error Lower 2.5% Upper 97.5%  
alpha          0.9724     0.1108     0.7534      1.0000 *
beta           0.2904     0.1368     0.0199      0.5607 *
phi            0.8798     0.0925     0.6970      1.0000 *
BJsales.lead   0.1662     0.2336    -0.2955      0.6276  

Error standard deviation: 1.3489
Sample size: 150
Number of estimated parameters: 5
Number of degrees of freedom: 145
Information criteria:
     AIC     AICc      BIC     BICc 
520.3870 520.8037 535.4402 536.4841</pre>
<p>As you can see in the output above, the initial level and trend of the model are not reported, because they were estimated via backcasting. However, we get the value of the parameter <code>BJsales.lead</code> and the uncertainty around it. The old backcasting approach is now called "complete", implying that all values of the state vector are produce via backcasting.</p>
<p>Second, <code>forecast.adam()</code> now has a parameter <code>scenarios</code>, which when TRUE will return the simulated paths from the model. This only works when <code>interval="simulated"</code> and can be used for the analysis of possible forecast trajectories.</p>
<p>Third, the <code>plot()</code> method now can also produce ACF/PACF for the squared residuals for all <code>smooth</code> functions. This becomes useful if you suspect that your data has ARCH elements and want to see if they need to be modelled separately. This can also be done using <code>adam()</code> and <code>sm()</code> and is discussed in <a href="https://openforecast.org/adam/ADAMscaleModel.html">Chapter 17 of the monograph</a>.</p>
<p>Finally, the <code>sma()</code> function now has the <code>fast</code> parameter, which when true will use a modified Ternary search for the best order based on information criteria. It might not give the global minimum, but it works much faster than the exhaustive search.</p>
<h3>Conclusions</h3>
<p>These are the main new features in the package. I feel that the main job in <code>smooth</code> is already done, and all I can do now is just tune the functions and improve the existing code. I want to move all the functions to the new engine and ditch the old one, but this requires much more time than I have. So, I don't expect to finish this any time soon, but I hope I'll get there someday. On the other hand, I'm not sure that spending much time on developing an R package is a wise idea, given that nowadays people tend to use Python. I would develop Python analogue of the <code>smooth</code> package, but currently I don't have the necessary expertise and time to do that. Besides, there already exist great libraries, such as <a href="https://github.com/Nixtla/nixtla/tree/main/tsforecast">tsforecast</a> from <a href="https://github.com/Nixtla/nixtla">nixtla</a> and <a href="https://www.sktime.org/">sktime</a>. I am not sure that another library, implementing ETS and ARIMA is needed in Python. What do you think?</p>
<p>Message <a href="https://openforecast.org/2023/01/30/smooth-v3-2-0-what-s-new/">smooth v3.2.0: what&#8217;s new?</a> first appeared on <a href="https://openforecast.org">Open Forecasting</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://openforecast.org/2023/01/30/smooth-v3-2-0-what-s-new/feed/</wfw:commentRss>
			<slash:comments>3</slash:comments>
		
		
			</item>
		<item>
		<title>The first draft of &#8220;Forecasting and Analytics with ADAM&#8221;</title>
		<link>https://openforecast.org/2022/04/11/the-first-draft-of-forecasting-and-analytics-with-adam/</link>
					<comments>https://openforecast.org/2022/04/11/the-first-draft-of-forecasting-and-analytics-with-adam/#respond</comments>
		
		<dc:creator><![CDATA[Ivan Svetunkov]]></dc:creator>
		<pubDate>Mon, 11 Apr 2022 15:30:26 +0000</pubDate>
				<category><![CDATA[adam()]]></category>
		<category><![CDATA[ARIMA]]></category>
		<category><![CDATA[ETS]]></category>
		<category><![CDATA[R]]></category>
		<category><![CDATA[Regression]]></category>
		<category><![CDATA[Theory of forecasting]]></category>
		<category><![CDATA[ADAM]]></category>
		<category><![CDATA[regression]]></category>
		<category><![CDATA[smooth]]></category>
		<guid isPermaLink="false">https://openforecast.org/?p=2817</guid>

					<description><![CDATA[<p>After working on this for more than a year, I have finally prepared the first draft of my online monograph &#8220;Forecasting and Analytics with ADAM&#8220;. This is a monograph on the model that unites ETS, ARIMA and regression and introduces advanced features in univariate modelling, including: ETS in a new State Space form; ARIMA in [&#8230;]</p>
<p>Message <a href="https://openforecast.org/2022/04/11/the-first-draft-of-forecasting-and-analytics-with-adam/">The first draft of &#8220;Forecasting and Analytics with ADAM&#8221;</a> first appeared on <a href="https://openforecast.org">Open Forecasting</a>.</p>
]]></description>
										<content:encoded><![CDATA[<div id="attachment_2819" style="width: 222px" class="wp-caption aligncenter"><a href="/wp-content/uploads/2022/03/Adam-Title-web.jpg"><img loading="lazy" decoding="async" aria-describedby="caption-attachment-2819" src="/wp-content/uploads/2022/03/Adam-Title-web-212x300.jpg" alt="Forecasting and Analytics with ADAM" width="212" height="300" class="size-medium wp-image-2819" srcset="https://openforecast.org/wp-content/webpc-passthru.php?src=https://openforecast.org/wp-content/uploads/2022/03/Adam-Title-web-212x300.jpg&amp;nocache=1 212w, https://openforecast.org/wp-content/webpc-passthru.php?src=https://openforecast.org/wp-content/uploads/2022/03/Adam-Title-web-724x1024.jpg&amp;nocache=1 724w, https://openforecast.org/wp-content/webpc-passthru.php?src=https://openforecast.org/wp-content/uploads/2022/03/Adam-Title-web-768x1087.jpg&amp;nocache=1 768w, https://openforecast.org/wp-content/webpc-passthru.php?src=https://openforecast.org/wp-content/uploads/2022/03/Adam-Title-web.jpg&amp;nocache=1 1000w" sizes="auto, (max-width: 212px) 100vw, 212px" /></a><p id="caption-attachment-2819" class="wp-caption-text">Forecasting and Analytics with ADAM</p></div>
<p>After working on this for <a href="/en/2021/01/13/the-creation-of-adam-next-step-in-statistical-forecasting/" rel="noopener">more than</a> <a href="/en/2021/02/28/after-the-creation-of-adam-smooth-v3-1-0/">a year</a>, I have finally prepared the first draft of my online monograph &#8220;<a href="https://openforecast.org/adam/" rel="noopener" target="_blank">Forecasting and Analytics with ADAM</a>&#8220;. This is a monograph on the model that unites ETS, ARIMA and regression and introduces advanced features in univariate modelling, including:</p>
<ol>
<li>ETS in a new State Space form;</li>
<li>ARIMA in a new State Space form;</li>
<li>Regression;</li>
<li>TVP regression;</li>
<li>Combinations of (1), (2) and either (3), or (4);</li>
<li>Automatic selection/combination for ETS;</li>
<li>Automatic orders selection for ARIMA;</li>
<li>Variables selection for regression part;</li>
<li>Normal and non-normal distributions;</li>
<li>Automatic selection of most suitable distribution;</li>
<li>Multiple seasonality;</li>
<li>Occurrence part of the model to handle zeroes in data (intermittent demand);</li>
<li>Modelling scale of distribution (GARCH and beyond);</li>
<li>Handling uncertainty of estimates of parameters.</li>
</ol>
<p>The model and all its features are already implemented in <code>adam()</code> function from <code>smooth</code> package for R (you need v3.1.6 from CRAN for all the features listed above). The function supports many options that allow one experimenting with univariate forecasting, allowing to build complex models, combining elements from the list above. The monograph explaining how models underlying ADAM and how to work with them is <a href="https://openforecast.org/adam/" rel="noopener" target="_blank">available online</a>, and I plan to produce several physical copies of it after refining the text. Furthermore, I have already asked two well-known academics to act as reviewers of the monograph to collect the feedback and improve the monograph, and if you want to act as a reviewer as well, please let me know.</p>
<h3>Examples in R</h3>
<p>Just to give you a flavour of ADAM, I decided to provide a couple of examples on time series <code>AirPassengers</code> (included in <code>datasets</code> package in R). The first one is the ADAM ETS.</p>
<p>Building and selecting the most appropriate ADAM ETS comes to running the following line of code:</p>
<pre class="decode">adamETSAir <- adam(AirPassengers, h=12, holdout=TRUE)</pre>
<p>In this case, ADAM will select the most appropriate ETS model for the data, creating a holdout of the last 12 observations. We can see the details of the model by printing the output:</p>
<pre class="decode">adamETSAir</pre>
<pre>Time elapsed: 0.75 seconds
Model estimated using adam() function: ETS(MAM)
Distribution assumed in the model: Gamma
Loss function type: likelihood; Loss function value: 467.2981
Persistence vector g:
 alpha   beta  gamma 
0.7691 0.0053 0.0000 

Sample size: 132
Number of estimated parameters: 17
Number of degrees of freedom: 115
Information criteria:
      AIC      AICc       BIC      BICc 
 968.5961  973.9646 1017.6038 1030.7102 

Forecast errors:
ME: 9.537; MAE: 20.784; RMSE: 26.106
sCE: 43.598%; Asymmetry: 64.8%; sMAE: 7.918%; sMSE: 0.989%
MASE: 0.863; RMSSE: 0.833; rMAE: 0.273; rRMSE: 0.254</pre>
<p>The output above provides plenty of detail on what was estimated and how. Some of these elements have been discussed in <a href="/en/2016/11/02/smooth-package-for-r-es-function-part-ii-pure-additive-models/">one of my previous posts</a> on <code>es()</code> function. The new thing is the information about the assumed distribution for the response variable. By default, ADAM works with Gamma distribution in case of multiplicative error model. This is done to make model more robust in cases of low volume data, where the Normal distribution might produce negative numbers (see <a href="/en/2021/06/30/isf2021-how-to-make-multiplicative-ets-work-for-you/">my presentation</a> on this issues). In case of high volume data, the Gamma distribution will perform similar to the Normal one. The pure multiplicative ADAM ETS is discussed in <a href="https://openforecast.org/adam/ADAMETSPureMultiplicativeChapter.html" rel="noopener" target="_blank">Chapter 6 of ADAM monograph</a>. If Gamma is not suitable, then the other distribution can be selected via the <code>distribution</code> parameter. There is also an automated distribution selection approach in the function <code>auto.adam()</code>:</p>
<pre class="decode">adamETSAutoAir <- auto.adam(AirPassengers, h=12, holdout=TRUE)
adamETSAutoAir</pre>
<pre>Time elapsed: 3.86 seconds
Model estimated using auto.adam() function: ETS(MAM)
Distribution assumed in the model: Normal
Loss function type: likelihood; Loss function value: 466.0744
Persistence vector g:
 alpha   beta  gamma 
0.8054 0.0000 0.0000 

Sample size: 132
Number of estimated parameters: 17
Number of degrees of freedom: 115
Information criteria:
      AIC      AICc       BIC      BICc 
 966.1487  971.5172 1015.1564 1028.2628 

Forecast errors:
ME: 9.922; MAE: 21.128; RMSE: 26.246
sCE: 45.36%; Asymmetry: 65.4%; sMAE: 8.049%; sMSE: 1%
MASE: 0.877; RMSSE: 0.838; rMAE: 0.278; rRMSE: 0.255</pre>
<p>As we see from the output above, the Normal distribution is more appropriate for the data in terms of AICc than the other ones tried out by the function (by default the list includes Normal, Laplace, S, Generalised Normal, Gamma, Inverse Gaussian and Log Normal distributions, but this can be amended by providing a vector of names via <code>distribution</code> parameter). The selection of ADAM ETS and distributions is discussed in <a href="https://openforecast.org/adam/ADAMSelection.html" rel="noopener" target="_blank">Chapter 15 of the monograph</a>.</p>
<p>Having obtained the model, we can diagnose it using <code>plot.adam()</code> function:</p>
<pre class="decode">par(mfcol=c(3,3))
plot(adamETSAutoAir,which=c(1,4,2,6,7,8,10,11,13))</pre>
<p>The <code>which</code> parameter specifies what type of plots to produce, you can find the list of plots in the documentation for <code>plot.adam()</code>. The code above will result in:<br />
<div id="attachment_2824" style="width: 310px" class="wp-caption aligncenter"><a href="/wp-content/uploads/2022/03/adamETSAirDiagnostics.png"><img loading="lazy" decoding="async" aria-describedby="caption-attachment-2824" src="/wp-content/uploads/2022/03/adamETSAirDiagnostics-300x175.png" alt="Diagnostics plots for ADAM ETS on AirPassengers data" width="300" height="175" class="size-medium wp-image-2824" /></a><p id="caption-attachment-2824" class="wp-caption-text">Diagnostics plots for ADAM ETS on AirPassengers data</p></div>
The diagnostic plots are discussed in the <a href="https://openforecast.org/adam/diagnostics.html" rel="noopener" target="_blank">Chapter 14 of ADAM monograph</a>. The plot above does not show any serious issues with the model.</p>
<p>Just for the comparison, we could also try fitting the most appropriate ADAM ARIMA to the data (this model is discussed in <a href="https://openforecast.org/adam/ADAMARIMA.html" rel="noopener" target="_blank">Chapter 9</a>). The code in this case is slightly more complicated, because we need to switch off ETS part of the model and define the maximum orders of ARIMA to try:</p>
<pre class="decode">adamARIMAAir <- adam(AirPassengers, model="NNN", h=12, holdout=TRUE,
                     orders=list(ar=c(3,2),i=c(2,1),ma=c(3,2),select=TRUE))</pre>
<p>This results in the following <a href="https://openforecast.org/adam/ARIMASelection.html" rel="noopener" target="_blank">automatically selected</a> ARIMA model:</p>
<pre>Time elapsed: 3.54 seconds
Model estimated using auto.adam() function: SARIMA(0,1,1)[1](0,1,1)[12]
Distribution assumed in the model: Normal
Loss function type: likelihood; Loss function value: 491.7117
ARMA parameters of the model:
MA:
 theta1[1] theta1[12] 
   -0.1952    -0.0720 

Sample size: 132
Number of estimated parameters: 16
Number of degrees of freedom: 116
Information criteria:
     AIC     AICc      BIC     BICc 
1015.423 1020.154 1061.548 1073.097 

Forecast errors:
ME: -13.795; MAE: 16.65; RMSE: 21.644
sCE: -63.064%; Asymmetry: -79.4%; sMAE: 6.343%; sMSE: 0.68%
MASE: 0.691; RMSSE: 0.691; rMAE: 0.219; rRMSE: 0.21</pre>
<p>Given that ADAM ETS and ADAM ARIMA are formulated in the same framework, they are directly comparable using information critirea. Comparing AICc of the models <code>adamETSAutoAir</code> and <code>adamARIMAAir</code>, we can conclude that the former is more appropriate to the data than the latter. However, the default ARIMA works with the Normal distribution, which might not be appropriate for the data, so we can revert to the <code>auto.adam()</code> to select the better one:</p>
<pre class="decode">adamAutoARIMAAir <- auto.adam(AirPassengers, model="NNN", h=12, holdout=TRUE,
                              orders=list(ar=c(3,2),i=c(2,1),ma=c(3,2),select=TRUE))</pre>
<p>This will take more computational time, but will result in a different model with a lower AICc (which is still higher than the one in ADAM ETS):</p>
<pre>Time elapsed: 25.46 seconds
Model estimated using auto.adam() function: SARIMA(0,1,1)[1](0,1,1)[12]
Distribution assumed in the model: Log-Normal
Loss function type: likelihood; Loss function value: 472.923
ARMA parameters of the model:
MA:
 theta1[1] theta1[12] 
   -0.2785    -0.5530 

Sample size: 132
Number of estimated parameters: 16
Number of degrees of freedom: 116
Information criteria:
      AIC      AICc       BIC      BICc 
 977.8460  982.5764 1023.9708 1035.5197 

Forecast errors:
ME: -12.968; MAE: 13.971; RMSE: 19.143
sCE: -59.285%; Asymmetry: -91.7%; sMAE: 5.322%; sMSE: 0.532%
MASE: 0.58; RMSSE: 0.611; rMAE: 0.184; rRMSE: 0.186</pre>
<p>Note that although the AICc is higher for ARIMA than for ETS, the former has lower error measures than the latter. So, the higher AICc does not necessarily mean that the model is not good. But if we rely on the information criteria, then we should stick with ADAM ETS and we can then produce the forecasts for the next 12 observations (see <a href="https://openforecast.org/adam/ADAMForecasting.html" rel="noopener" target="_blank">Chapter 18</a>):</p>
<pre class="decode">adamETSAutoAirForecast <- forecast(adamETSAutoAir, h=12, interval="prediction",
                                   level=c(0.9,0.95,0.99))
par(mfcol=c(1,1))
plot(adamETSAutoAirForecast)</pre>
<div id="attachment_2839" style="width: 310px" class="wp-caption aligncenter"><a href="https://openforecast.org/wp-content/webpc-passthru.php?src=https://openforecast.org/wp-content/uploads/2022/03/adamETSAirForecast.png&amp;nocache=1"><img loading="lazy" decoding="async" aria-describedby="caption-attachment-2839" src="https://openforecast.org/wp-content/webpc-passthru.php?src=https://openforecast.org/wp-content/uploads/2022/03/adamETSAirForecast-300x175.png&amp;nocache=1" alt="Forecast from ADAM ETS" width="300" height="175" class="size-medium wp-image-2839" srcset="https://openforecast.org/wp-content/webpc-passthru.php?src=https://openforecast.org/wp-content/uploads/2022/03/adamETSAirForecast-300x175.png&amp;nocache=1 300w, https://openforecast.org/wp-content/webpc-passthru.php?src=https://openforecast.org/wp-content/uploads/2022/03/adamETSAirForecast-1024x597.png&amp;nocache=1 1024w, https://openforecast.org/wp-content/webpc-passthru.php?src=https://openforecast.org/wp-content/uploads/2022/03/adamETSAirForecast-768x448.png&amp;nocache=1 768w, https://openforecast.org/wp-content/webpc-passthru.php?src=https://openforecast.org/wp-content/uploads/2022/03/adamETSAirForecast.png&amp;nocache=1 1200w" sizes="auto, (max-width: 300px) 100vw, 300px" /></a><p id="caption-attachment-2839" class="wp-caption-text">Forecast from ADAM ETS</p></div>
Finally, if we want to do a more in-depth analysis of parameters of ADAM, we can also produce the summary, which will create the confidence intervals for the parameters of the model:</p>
<pre class="decode">summary(adamETSAutoAir)</pre>
<pre>Model estimated using auto.adam() function: ETS(MAM)
Response variable: data
Distribution used in the estimation: Normal
Loss function type: likelihood; Loss function value: 466.0744
Coefficients:
            Estimate Std. Error Lower 2.5% Upper 97.5%  
alpha         0.8054     0.0864     0.6343      0.9761 *
beta          0.0000     0.0203     0.0000      0.0401  
gamma         0.0000     0.0382     0.0000      0.0755  
level        96.2372     6.8596    82.6496    109.7919 *
trend         2.0901     0.3955     1.3068      2.8716 *
seasonal_1    0.9145     0.0077     0.9003      0.9372 *
seasonal_2    0.8999     0.0081     0.8857      0.9227 *
seasonal_3    1.0308     0.0094     1.0165      1.0535 *
seasonal_4    0.9885     0.0077     0.9743      1.0112 *
seasonal_5    0.9856     0.0072     0.9713      1.0083 *
seasonal_6    1.1165     0.0093     1.1023      1.1392 *
seasonal_7    1.2340     0.0115     1.2198      1.2568 *
seasonal_8    1.2254     0.0105     1.2112      1.2481 *
seasonal_9    1.0668     0.0094     1.0526      1.0896 *
seasonal_10   0.9256     0.0087     0.9113      0.9483 *
seasonal_11   0.8040     0.0075     0.7898      0.8268 *

Error standard deviation: 0.0367
Sample size: 132
Number of estimated parameters: 17
Number of degrees of freedom: 115
Information criteria:
      AIC      AICc       BIC      BICc 
 966.1487  971.5172 1015.1564 1028.2628 </pre>
<p>Note that the <code>summary()</code> function might complain about the Observed Fisher Information. This is because the covariance matrix of parameters is calculated numerically and sometimes the likelihood is not maximised properly. I have not been able to fully resolve this issue yet, but hopefully will do at some point. The summary above shows, for example, that the smoothing parameters \(\beta\) and \(\gamma\) are not significantly different from zero (on 5% level), while \(\alpha\) is expected to vary between 0.6343 and 0.9761 in 95% of the cases. You can read more about the uncertainty of parameters in ADAM in <a href="https://openforecast.org/adam/ADAMUncertainty.html" rel="noopener" target="_blank">Chapter 16</a> of the monograph.</p>
<p>As for the other features of ADAM, here is a brief guide:</p>
<ul>
<li>If you work with multiple seasonal data, then you might need to specify the seasonality via the <code>lags</code> parameter, for example as <code>lags=c(24,7*24)</code> in case of hourly data. This is discussed in <a href="https://openforecast.org/adam/multiple-frequencies-in-adam.html" rel="noopener" target="_blank">Chapter 12</a>;</li>
<li>If you have intermittent data, then you should read <a href="https://openforecast.org/adam/ADAMIntermittent.html" rel="noopener" target="_blank">Chapter 13</a>, which explains how to work with the <code>occurrence</code> parameter of the function;</li>
<li>Explanatory variables are discussed in <a href="https://openforecast.org/adam/ADAMX.html" rel="noopener" target="_blank">Chapter 10</a> and are handled in the <code>adam()</code> function via the <code>formula</code> parameter;</li>
<li>In the cases of heteroscedasticity (time varying or induced by some explanatory variables), there a scale model (which is discussed in <a href="https://openforecast.org/adam/ADAMscaleModel.html" rel="noopener" target="_blank">Chapter 17</a> and implemented as <code>sm()</code> method for the <code>adam</code> class).</li>
</ul>
<p>You can also experiment with advanced estimators (<a href="https://openforecast.org/adam/ADAMETSEstimation.html" rel="noopener" target="_blank">Chapter 11</a>, including custom loss functions) via the <code>loss</code> parameter and forecast combinations (<a href="https://openforecast.org/adam/ADAMCombinations.html" rel="noopener" target="_blank">Section 15.4</a>).</p>
<p>Long story short, if you are interested in univariate forecasting, then do give ADAM a try - it might have the flexibility you needed for your experiments. If you are worried about its accuracy, check out <a href="/en/2021/02/28/after-the-creation-of-adam-smooth-v3-1-0/">this post</a>, where I compared ADAM with other models.</p>
<p>And, as a friend of mine says, "Happy forecasting!"</p>
<p>Message <a href="https://openforecast.org/2022/04/11/the-first-draft-of-forecasting-and-analytics-with-adam/">The first draft of &#8220;Forecasting and Analytics with ADAM&#8221;</a> first appeared on <a href="https://openforecast.org">Open Forecasting</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://openforecast.org/2022/04/11/the-first-draft-of-forecasting-and-analytics-with-adam/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Introducing scale model in greybox</title>
		<link>https://openforecast.org/2022/01/23/introducing-scale-model-in-greybox/</link>
					<comments>https://openforecast.org/2022/01/23/introducing-scale-model-in-greybox/#respond</comments>
		
		<dc:creator><![CDATA[Ivan Svetunkov]]></dc:creator>
		<pubDate>Sun, 23 Jan 2022 18:04:33 +0000</pubDate>
				<category><![CDATA[Package greybox for R]]></category>
		<category><![CDATA[R]]></category>
		<category><![CDATA[Regression]]></category>
		<category><![CDATA[Univariate models]]></category>
		<category><![CDATA[greybox]]></category>
		<category><![CDATA[regression]]></category>
		<guid isPermaLink="false">https://openforecast.org/?p=2670</guid>

					<description><![CDATA[<p>At the end of June 2021, I released the greybox package version 1.0.0. This was a major release, introducing new functionality, but I did not have time to write a separate post about it because of the teaching and lack of free time. Finally, Christmas has arrived, and I could spend several hours preparing the [&#8230;]</p>
<p>Message <a href="https://openforecast.org/2022/01/23/introducing-scale-model-in-greybox/">Introducing scale model in greybox</a> first appeared on <a href="https://openforecast.org">Open Forecasting</a>.</p>
]]></description>
										<content:encoded><![CDATA[<p>At the end of June 2021, I released the <code>greybox</code> package version 1.0.0. This was a major release, introducing new functionality, but I did not have time to write a separate post about it because of the teaching and lack of free time. Finally, Christmas has arrived, and I could spend several hours preparing the post about it. In this post, I want to tell you about the new major feature in the <code>greybox</code> package.</p>
<h3>Scale Model</h3>
<p>The Scale Model is the regression-like model focusing on capturing the relation between the scale of distribution (for example, variance in Normal distribution) and a set of explanatory variables. It is implemented in <code>sm()</code> method in the <code>greybox</code> package. The motivation for this comes from <a href="https://www.gamlss.com/">GAMLSS</a>, the Generalised Additive Model for Location, Scale and Shape. While I have decided not to bother with the &#8220;GAM&#8221; part of this (there are <code>gam</code> and <code>gamlss</code> packages in R that do that), I liked the idea of being able to predict the scale (for example, variance) of a distribution. This becomes especially useful when one suspects heteroscedasticity in the model but does not think that variable transformations are appropriate.</p>
<p>To understand what the function does, it is necessary first to discuss the underlying model. We will start the discussion with an example of a linear regression model with two explanatory variables, assuming Normally distributed residuals \(\xi_t\) with zero mean and a fixed variance \(\sigma^2\), \(\xi_t \sim \mathcal{N}(0,\sigma^2)\), which can be formulated as:<br />
\begin{equation} \label{eq:model1}<br />
    y_t = \beta_0 + \beta_1 x_{1,t} + \beta_2 x_{2,t} + \xi_t ,<br />
\end{equation}<br />
where \(y_t\) is the response variable, \(x_{1,t}\) and \(x_{2,t}\) are the explanatory variables on observation \(t\), \(\beta_0\), \(\beta_1\) and \(\beta_2\) are the parameters of the model and \(\xi_t \sim \mathcal{N}\left(0, \sigma^2 \right)\). Recalling the basic properties of Normal distribution, we can rewrite the same model as a model with standard normal residuals \(\epsilon_t \sim \mathcal{N}\left(0, 1 \right)\) by inserting \(\xi_t = \sigma \epsilon_t\) in \eqref{eq:model1}:<br />
\begin{equation} \label{eq:model2}<br />
    y_t = \beta_0 + \beta_1 x_{1,t} + \beta_2 x_{2,t} + \sigma \epsilon_t .<br />
\end{equation}<br />
Now if we suspect that the variance of the model might not be constant, we can substitute the standard deviation \(\sigma\) with some function, transforming the model into:<br />
\begin{equation} \label{eq:model3}<br />
    y_t = \beta_0 + \beta_1 x_{1,t} + \beta_2 x_{2,t} + f\left(\gamma_0 + \gamma_2 x_{2,t} + \gamma_3 x_{3,t}\right) \epsilon_t ,<br />
\end{equation}<br />
where \(x_{2,t}\) and \(x_{3,t}\) are the explanatory variables (as you see, not necessarily the same as in the first part of the model) and \(\gamma_0\), \(\gamma_1\) and \(\gamma_2\) are the parameters of the scale part of the model. The idea here is that there is a regression model for the conditional mean of the distribution \(\beta_0 + \beta_1 x_{1,t} + \beta_2 x_{2,t}\), and that there is another one that will regulate the standard deviation via \(f\left(\gamma_0 + \gamma_2 x_{2,t} + \gamma_3 x_{3,t}\right)\). The main thing to keep in mind about the latter is that the function \(f(\cdot)\) needs to be strictly positive because the standard deviation cannot be zero or negative. The simplest way to guarantee this is to use exponent instead of \(f(\cdot)\). Furthermore, in our example with Normal distribution, the scale corresponds to the variance, so we should be introducing the model for variance: \(\sigma^2_t = \exp\left(\gamma_0 + \gamma_2 x_{2,t} + \gamma_3 x_{3,t}\right)\). This leads to the following model:<br />
\begin{equation} \label{eq:model4}<br />
    y_t = \beta_0 + \beta_1 x_{1,t} + \beta_2 x_{2,t} + \sqrt{\exp\left(\gamma_0 + \gamma_2 x_{2,t} + \gamma_3 x_{3,t}\right)} \epsilon_t ,<br />
\end{equation}<br />
The model above would not only have the conditional mean depending on the values of explanatory variables (the conventional regression) but also the conditional variance, which would change depending on the values of variables. Note that this model assumes the linearity in the conditional mean: increase of \(x_{1,t}\) by one leads to the increase of \(y_t\) by \(\beta_1\) on average. At the same time, it assumes non-linearity in the variance: increase of \(x_{2,t}\) by one leads to the increase of variance by \(\exp(\gamma_2-1)\times 100\)%. If we want a non-linear change in the conditional mean, we can use a model in logarithms. Alternatively, we could assume a different distribution for the response variable \(y_t\). To understand how the latter would work, we need to represent the same model \eqref{eq:model4} in a more general form. For the Normal distribution, the same model \eqref{eq:model4} can be rewritten as:<br />
\begin{equation} \label{eq:model5}<br />
    y_t \sim \mathcal{N}\left(\beta_0 + \beta_1 x_{1,t} + \beta_2 x_{2,t}, \exp\left(\gamma_0 + \gamma_2 x_{2,t} + \gamma_3 x_{3,t}\right)\right).<br />
\end{equation}<br />
This representation allows introducing scale model for many other distributions, such as Laplace, Generalised Normal, Gamma, Inverse Gaussian etc. All that we need to do in those cases is to substitute the distribution \(\mathcal{N}(\cdot)\) with a distribution of interest. The <code>sm()</code> function supports the same list of distributions as <code>alm()</code> (see <a href="https://cran.r-project.org/web/packages/greybox/vignettes/alm.html" rel="noopener" target="_blank">the vignette </a>for the function on CRAN or in R using the command <code>vignette()</code>). Each specific formula for scale would differ from one distribution to another, but the principles will be the same.</p>
<h3>Demonstration in R</h3>
<p>For demonstration purposes, we will use an example with artificial data, generated according to the model \eqref{eq:model4}:</p>
<pre class="decode">xreg <- matrix(rnorm(300,10,3),100,3)
xreg <- cbind(1000-0.75*xreg[,1]+1.75*xreg[,2]+
              sqrt(exp(0.3+0.5*xreg[,2]-0.4*xreg[,3]))*rnorm(100,0,1),xreg)
colnames(xreg) <- c("y",paste0("x",c(1:3)))</pre>
<p>The scatterplot of the generated data will look like this:</p>
<pre class="decode">spread(xreg)</pre>
<div id="attachment_2789" style="width: 310px" class="wp-caption aligncenter"><a href="https://openforecast.org/wp-content/webpc-passthru.php?src=https://openforecast.org/wp-content/uploads/2022/01/smExampleSpread.png&amp;nocache=1"><img loading="lazy" decoding="async" aria-describedby="caption-attachment-2789" src="https://openforecast.org/wp-content/webpc-passthru.php?src=https://openforecast.org/wp-content/uploads/2022/01/smExampleSpread-300x263.png&amp;nocache=1" alt="Scatterplot matrix for the generated data" width="300" height="263" class="size-medium wp-image-2789" srcset="https://openforecast.org/wp-content/webpc-passthru.php?src=https://openforecast.org/wp-content/uploads/2022/01/smExampleSpread-300x263.png&amp;nocache=1 300w, https://openforecast.org/wp-content/webpc-passthru.php?src=https://openforecast.org/wp-content/uploads/2022/01/smExampleSpread-768x672.png&amp;nocache=1 768w, https://openforecast.org/wp-content/webpc-passthru.php?src=https://openforecast.org/wp-content/uploads/2022/01/smExampleSpread.png&amp;nocache=1 800w" sizes="auto, (max-width: 300px) 100vw, 300px" /></a><p id="caption-attachment-2789" class="wp-caption-text">Scatterplot matrix for the generated data</p></div>
<p>We can then fit a model, specifying the location and scale parts of it in <code>alm()</code>. In this case, the <code>alm()</code> will call for <code>sm()</code> and will estimate both parts via likelihood maximisation. To make things closer to forecasting task, we will withhold the last 10 observations for the test set:</p>
<pre class="decode">ourModel <- alm(y~x1+x2+x3, scale=~x2+x3, xreg, subset=c(1:90), distribution="dnorm")</pre>
<p>The returned model contains both parts. The scale part of the model can be accessed via <code>ourModel$scale</code>. It is an object of class "scale", supporting several methods, such as<br />
<code>actuals()</code>, <code>residuals()</code>, <code>fitted()</code>, <code>summary()</code> and <code>plot()</code> (and several other). Here how the summary of the model looks in my case:</p>
<pre class="decode">summary(ourModel)</pre>
<pre>Response variable: y
Distribution used in the estimation: Normal
Loss function used in estimation: likelihood
Coefficients:
             Estimate Std. Error Lower 2.5% Upper 97.5%  
(Intercept) 1000.2850     2.9698   994.3782   1006.1917 *
x1            -0.8350     0.1435    -1.1204     -0.5497 *
x2             1.8656     0.1714     1.5246      2.2065 *
x3            -0.0228     0.1776    -0.3761      0.3305  

Coefficients for scale:
            Estimate Std. Error Lower 2.5% Upper 97.5%  
(Intercept)   0.0436     0.7012    -1.3510      1.4382  
x2            0.4705     0.0413     0.3883      0.5527 *
x3           -0.3355     0.0487    -0.4324     -0.2385 *

Error standard deviation: 4.52
Sample size: 90
Number of estimated parameters: 7
Number of degrees of freedom: 83
Information criteria:
     AIC     AICc      BIC     BICc 
391.0191 392.3849 408.5177 411.5908</pre>
<p>The summary above shows parameters for both parts of the model. They are not far from the ones used in the generation of the model, which indicates that the implemented model works as intended. The only issue here is that the standard errors in the location part of the model (first four coefficients) <strong>do not take the heteroscedasticity into account and thus are biased</strong>. The <a href="https://www.econometrics-with-r.org/15.4-hac-standard-errors.html" rel="noopener" target="_blank">HAC standard errors</a> are not yet implemented in <code>alm()</code></p>
<p>As we see, the returned model contains both parts. The scale part of the model can be accessed via <code>ourModel$scale</code>. It is an object of class "scale", supporting several methods, such as<br />
<code>actuals()</code>, <code>residuals()</code>, <code>fitted()</code>, <code>summary()</code> and <code>plot()</code> (and several other). Just to see the effect of scale model, here are the diagnostics plots for the original model (which returns the \(\xi_t\) residuals) and for the scale model (\(\epsilon_t\) residuals):</p>
<pre class="decode">par(mfcol=c(1,2))
plot(ourModel, 5)
plot(ourModel, 5)</pre>
<div id="attachment_2794" style="width: 310px" class="wp-caption aligncenter"><a href="https://openforecast.org/wp-content/webpc-passthru.php?src=https://openforecast.org/wp-content/uploads/2022/01/smDiagnostics.png&amp;nocache=1"><img loading="lazy" decoding="async" aria-describedby="caption-attachment-2794" src="https://openforecast.org/wp-content/webpc-passthru.php?src=https://openforecast.org/wp-content/uploads/2022/01/smDiagnostics-300x175.png&amp;nocache=1" alt="Diagnostics plots for sm" width="300" height="175" class="size-medium wp-image-2794" srcset="https://openforecast.org/wp-content/webpc-passthru.php?src=https://openforecast.org/wp-content/uploads/2022/01/smDiagnostics-300x175.png&amp;nocache=1 300w, https://openforecast.org/wp-content/webpc-passthru.php?src=https://openforecast.org/wp-content/uploads/2022/01/smDiagnostics-1024x597.png&amp;nocache=1 1024w, https://openforecast.org/wp-content/webpc-passthru.php?src=https://openforecast.org/wp-content/uploads/2022/01/smDiagnostics-768x448.png&amp;nocache=1 768w, https://openforecast.org/wp-content/webpc-passthru.php?src=https://openforecast.org/wp-content/uploads/2022/01/smDiagnostics.png&amp;nocache=1 1200w" sizes="auto, (max-width: 300px) 100vw, 300px" /></a><p id="caption-attachment-2794" class="wp-caption-text">Diagnostics plots for sm</p></div>
<p>The Figure above shows squared residuals vs fitted values for the location (the plot on the left) and the scale (the plot on the right) models. The former is agnostic of the scale model and demonstrates that there is heteroscedasticity of residuals (the variance increases with the increase of the fitted values). The latter shows that the scale model managed to resolve the issue. While the LOWESS line demonstrates some non-linearity, the distribution of residuals conditional on fitted values looks random.</p>
<p>Finally, we can produce forecasts from such model, similarly to how it is done for any other model, estimated with <code>alm()</code>:</p>
<pre class="decode">ourForecast <- predict(ourModel,xreg[-c(1:90),],interval="pred")
plot(ourForecast)</pre>
<div id="attachment_2800" style="width: 310px" class="wp-caption aligncenter"><a href="https://openforecast.org/wp-content/webpc-passthru.php?src=https://openforecast.org/wp-content/uploads/2022/01/smForecast.png&amp;nocache=1"><img loading="lazy" decoding="async" aria-describedby="caption-attachment-2800" src="https://openforecast.org/wp-content/webpc-passthru.php?src=https://openforecast.org/wp-content/uploads/2022/01/smForecast-300x175.png&amp;nocache=1" alt="Forecast from the model" width="300" height="175" class="size-medium wp-image-2800" srcset="https://openforecast.org/wp-content/webpc-passthru.php?src=https://openforecast.org/wp-content/uploads/2022/01/smForecast-300x175.png&amp;nocache=1 300w, https://openforecast.org/wp-content/webpc-passthru.php?src=https://openforecast.org/wp-content/uploads/2022/01/smForecast-1024x597.png&amp;nocache=1 1024w, https://openforecast.org/wp-content/webpc-passthru.php?src=https://openforecast.org/wp-content/uploads/2022/01/smForecast-768x448.png&amp;nocache=1 768w, https://openforecast.org/wp-content/webpc-passthru.php?src=https://openforecast.org/wp-content/uploads/2022/01/smForecast.png&amp;nocache=1 1200w" sizes="auto, (max-width: 300px) 100vw, 300px" /></a><p id="caption-attachment-2800" class="wp-caption-text">Forecast from the model</p></div>
<p>In this case, the function will first predict the scale part of the model, then it will use the predicted variance and the covariance matrix of parameters to calculate the prediction intervals, shown in Figure above. Given the independence of location and scale parts of the model, the conditional expectation (point forecast) will not change if we drop the scale model. It is all about variance.</p>
<p>Finally, if you do not want to use <code>alm()</code> function, you can use <code>lm()</code> instead and then apply the <code>sm()</code>:</p>
<pre class="decode">lmModel <- lm(y~x1+x2+x3, as.data.frame(xreg), subset=c(1:90))
smModel <- sm(lmModel, formula=~x2+x3, xreg)</pre>
<p>In this case, the <code>sm()</code> will assume that the error term follows Normal distribution, and we will end up with two models that are not connected with each other (e.g., the <code>predict()</code> method applied to <code>lmModel</code> will not use predictions from the <code>smModel</code>). Nonetheless, we could still use all the R methods discussed above for the analysis of the <code>smModel</code>.</p>
<p>As a final word, the scale model is a new feature. While it already works, there might be bugs in it. If you find any, please let me know by submitting <a href="https://github.com/config-i1/greybox/issues" rel="noopener" target="_blank">an issue on Github</a>.</p>
<h3>P.S.</h3>
<p>There is a danger that <code>greybox</code> <strong>package will be soon removed from CRAN</strong> together with other 88 packages (including my <code>smooth</code> and <code>legion</code>) because the <code>nloptr</code> package that it relies on has not passed some of new checks recently introduced by CRAN. This is beyond my control, and I do not have time or power to influence this, but if this happens, you might need to switch to <a href="https://github.com/config-i1/greybox/" rel="noopener" target="_blank">the installation from GitHub</a> via <code>remotes</code> package, using the command:</p>
<pre class="decode">remotes::install_github("config-i1/greybox")</pre>
<p>My apologies for the inconvenience. I might be able to remove the dependence on <code>nloptr</code> at some point, but it will not happen before March 2022.</p>
<p>Message <a href="https://openforecast.org/2022/01/23/introducing-scale-model-in-greybox/">Introducing scale model in greybox</a> first appeared on <a href="https://openforecast.org">Open Forecasting</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://openforecast.org/2022/01/23/introducing-scale-model-in-greybox/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>An Integrated Method for Estimation and Optimisation</title>
		<link>https://openforecast.org/2021/09/03/an-integrated-method-for-estimation-and-optimisation/</link>
					<comments>https://openforecast.org/2021/09/03/an-integrated-method-for-estimation-and-optimisation/#respond</comments>
		
		<dc:creator><![CDATA[Ivan Svetunkov]]></dc:creator>
		<pubDate>Fri, 03 Sep 2021 15:47:15 +0000</pubDate>
				<category><![CDATA[Package greybox for R]]></category>
		<category><![CDATA[Papers]]></category>
		<category><![CDATA[R]]></category>
		<category><![CDATA[Regression]]></category>
		<category><![CDATA[Univariate models]]></category>
		<category><![CDATA[extrapolation methods]]></category>
		<category><![CDATA[greybox]]></category>
		<category><![CDATA[regression]]></category>
		<category><![CDATA[statistics]]></category>
		<guid isPermaLink="false">https://openforecast.org/?p=2703</guid>

					<description><![CDATA[<p>My PhD student, Congzheng Liu (co-supervised with Adam Letchford) has written a paper, entitled &#8220;Newsvendor Problems: An Integrated Method for Estimation and Optimisation&#8220;. This paper has recently been published in EJOR. In this paper we build upon the existing Ban &#038; Rudin (2019) approach for newsvendor problem, showing that in case of the linear model, [&#8230;]</p>
<p>Message <a href="https://openforecast.org/2021/09/03/an-integrated-method-for-estimation-and-optimisation/">An Integrated Method for Estimation and Optimisation</a> first appeared on <a href="https://openforecast.org">Open Forecasting</a>.</p>
]]></description>
										<content:encoded><![CDATA[<p>My PhD student, <a href="https://www.linkedin.com/in/congzheng-liu/" rel="noopener" target="_blank">Congzheng Liu</a> (co-supervised with <a href="https://www.lancaster.ac.uk/staff/letchfoa/default.htm" rel="noopener" target="_blank">Adam Letchford</a>) has written a paper, entitled &#8220;<a href="https://doi.org/10.1016/j.ejor.2021.08.013" rel="noopener" target="_blank">Newsvendor Problems: An Integrated Method for Estimation and Optimisation</a>&#8220;. This paper has recently been published in <a href="https://www.sciencedirect.com/journal/european-journal-of-operational-research" rel="noopener" target="_blank">EJOR</a>. In this paper we build upon the existing <a href="https://doi.org/10.1287/opre.2018.1757" rel="noopener" target="_blank">Ban &#038; Rudin (2019)</a> approach for newsvendor problem, showing that in case of the linear model, it becomes equivalent to quantile regression. We then extend it for the non-linear newsvendor problems, testing it on simulated and real life data. In order to understand what specifically we propose, we need to discuss the typical process in case of newsvendor problem.</p>
<p>Newsvendor is a class of problems, where the product can only be sold one day, after which it goes to waste. So this is appropriate, for example, for perishable products in retail. Typically, in this situation we would have historical demand of sales of our product \(y_t\) and we would try forecasting it using regression / ETS / ARIMA or any other model. After doing that and obtaining the estimates of parameters, we would produce a quantile of assumed distribution, which then tells us how much to order (\(q_t\)). If we order more than needed, we will have holding costs. In the opposite case, we will have shortage costs. Based on these costs and the price of product, we can find the optimal order, that will give the maximum profit.</p>
<p>As you can already spot, the forecasting stage is detached from the optimisation one in this situation. The idea of the proposed integrated approach (IMEO) is simple: instead of optimising the model via MSE or any other conventional loss and then solving the optimisation problem, we could <strong>estimate the model via maximisation of the specific profit function</strong>, thus obtaining the required orders directly. This is not a new idea on its own, but using profit function rather than the cost (as <a href="https://doi.org/10.1287/opre.2018.1757" rel="noopener" target="_blank">Ban &#038; Rudin, 2019</a> did) allows applying IMEO to wider set of problems.</p>
<p>For example, if we know the price of the product \(p\), the costs for production \(v\), holding \(c_h\) and shortage costs \(c_s\), we can then calculate profit as (for a linear newsvendor problem):<br />
\begin{equation}<br />
    \pi(q_t,y_t)=<br />
    \begin{cases}<br />
        p y_t -v q_t -c_h (q_t -y_t),&#038; \text{for } q_t \geq y_t\\<br />
        p q_t -v q_t -c_s (y_t -q_t),&#038; \text{for } q_t< y_t,
    \end{cases}
\end{equation}
where \(q_t\) ​is the order quantity and \(y_t\) is the actual sales. This profit function can be used for the estimation of a model of your choosing. Congzheng has written a separate R code for the experiments for the paper. Inspired by his example, I have implemented custom losses in <code>alm()</code> and <code>adam()</code> functions from respective <code>greybox</code> and <code>smooth</code> packages for R. At the moment, only the regression model works properly with custom losses &#8211; ETS / ARIMA need additional modifications, which we will hopefully resolve in the next paper. So, here is an example with linear newsvendor problem and <code>alm()</code>:</p>
<pre class="decode"># Generate artificial data
x1 <- rnorm(100,100,10)
x2 <- rbinom(100,2,0.05)
y <- 10 + 1.5*x1 + 5*x2 + rnorm(100,0,10)
ourData <- cbind(y=y,x1=x1,x2=x2)

# Define price and costs
price <- 50
costBasic <- 5
costShort <- 15
costHold <- 1

# Define profit function for the linear case
lossProfit <- function(actual, fitted, B, xreg){
    # Minus sign is needed here, because we need to minimise the loss
    profit <- -ifelse(actual >= fitted,
                     (price - costBasic) * fitted - costShort * (actual - fitted),
                     price * actual - costBasic * fitted - costHold * (fitted - actual));
    return(sum(profit));
}

# Estimate the model
model1 <- alm(y~x1+x2, ourData, loss=lossProfit)

# Print summary of the model
summary(model1, bootstrap=TRUE) </pre>
<pre>Response variable: y
Distribution used in the estimation: Normal
Loss function used in estimation: custom
Bootstrap was used for the estimation of uncertainty of parameters
Coefficients:
            Estimate Std. Error Lower 2.5% Upper 97.5%  
(Intercept)  36.5177    14.2840     2.7783     51.4844 *
x1            1.3622     0.1622     1.1909      1.7528 *
x2            3.3423     2.7810    -6.5997      5.9101  

Error standard deviation: 17.2266
Sample size: 100
Number of estimated parameters: 3
Number of degrees of freedom: 97</pre>
<p>The resulting model is easy to work with: it provides meaningful parameters, showing how on average the order should change if a variable changes by one. For example, we see that with the increase of the variable x1, the orders should change on average by 1.36.</p>
<p>Note that in this specific case, as shown <a href="https://doi.org/10.1016/j.ejor.2021.08.013" rel="noopener" target="_blank">in our paper</a>, the model would be equivalent to the quantile regression, estimated for the quantile \(\left( \frac{c_u}{c_o+c_u} \right)\), where \(c_u= p-v+c_s\) is the "underage" cost and \(c_o = v+c_h\) is the "overage" cost. In our example it corresponds to approximately 0.9091 quantile. We can compare the output of this model with the one from the quantile regression in <code>alm</code> (which is estimated as an Asymmetric Laplace model):</p>
<pre class="decode">model2 <- alm(y~x1+x2, ourData, distribution="dalaplace", alpha=0.9091)
summary(model2, bootstrap=TRUE)</pre>
<pre>Response variable: y
Distribution used in the estimation: Asymmetric Laplace with alpha=0.9091
Loss function used in estimation: likelihood
Bootstrap was used for the estimation of uncertainty of parameters
Coefficients:
            Estimate Std. Error Lower 2.5% Upper 97.5%  
(Intercept)  36.6688    11.6686     3.8674     51.1987 *
x1            1.3611     0.1338     1.1920      1.7454 *
x2            3.1259     2.5424    -6.2518      5.4703  

Error standard deviation: 17.3379
Sample size: 100
Number of estimated parameters: 4
Number of degrees of freedom: 96
Information criteria:
     AIC     AICc      BIC     BICc 
826.4622 826.8833 836.8829 837.8524</pre>
<p>The differences between the estimates of parameters of the two models are due to the optimisation procedure, which would converge to slightly different points in these two cases. Still, the values of parameters are close to each other and would converge asymptotically, which supports our finding.</p>
<p>And here how the orders over time look in case of our custom loss:</p>
<pre class="decode">plot(model1, 7)</pre>
<div id="attachment_2716" style="width: 310px" class="wp-caption aligncenter"><a href="https://openforecast.org/wp-content/webpc-passthru.php?src=https://openforecast.org/wp-content/uploads/2021/09/ordersDynamics.png&amp;nocache=1"><img loading="lazy" decoding="async" aria-describedby="caption-attachment-2716" src="https://openforecast.org/wp-content/webpc-passthru.php?src=https://openforecast.org/wp-content/uploads/2021/09/ordersDynamics-300x175.png&amp;nocache=1" alt="Dynamics of orders from alm model" width="300" height="175" class="size-medium wp-image-2716" srcset="https://openforecast.org/wp-content/webpc-passthru.php?src=https://openforecast.org/wp-content/uploads/2021/09/ordersDynamics-300x175.png&amp;nocache=1 300w, https://openforecast.org/wp-content/webpc-passthru.php?src=https://openforecast.org/wp-content/uploads/2021/09/ordersDynamics-1024x597.png&amp;nocache=1 1024w, https://openforecast.org/wp-content/webpc-passthru.php?src=https://openforecast.org/wp-content/uploads/2021/09/ordersDynamics-768x448.png&amp;nocache=1 768w, https://openforecast.org/wp-content/webpc-passthru.php?src=https://openforecast.org/wp-content/uploads/2021/09/ordersDynamics.png&amp;nocache=1 1200w" sizes="auto, (max-width: 300px) 100vw, 300px" /></a><p id="caption-attachment-2716" class="wp-caption-text">Dynamics of orders from alm model</p></div>
<p>The purple line in the Figure above corresponds to the orders and would cover roughly 90.91% of cases, so that we would run out of product in approximately 10% of cases, which would still be more profitable than any other option.</p>
<p>Finally, the approach works also well in case of non-linear newsvendor problem (see <a href="https://doi.org/10.1016/j.ejor.2021.08.013" rel="noopener" target="_blank">the paper</a> for details), where quantile regression is not suitable and the conventional approach fails. The only thing that would change is the loss function, where the prices and costs would depend non-linearly on the order quantity and sales.</p>
<p>You can read <a href="https://doi.org/10.1016/j.ejor.2021.08.013" rel="noopener" target="_blank">the published paper on EJOR website</a> or the working paper on <a href="http://dx.doi.org/10.13140/RG.2.2.27057.81763" rel="noopener" target="_blank">ResearchGate</a>.</p>
<p>Message <a href="https://openforecast.org/2021/09/03/an-integrated-method-for-estimation-and-optimisation/">An Integrated Method for Estimation and Optimisation</a> first appeared on <a href="https://openforecast.org">Open Forecasting</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://openforecast.org/2021/09/03/an-integrated-method-for-estimation-and-optimisation/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>The creation of ADAM &#8211; next step in statistical forecasting</title>
		<link>https://openforecast.org/2021/01/13/the-creation-of-adam-next-step-in-statistical-forecasting/</link>
					<comments>https://openforecast.org/2021/01/13/the-creation-of-adam-next-step-in-statistical-forecasting/#respond</comments>
		
		<dc:creator><![CDATA[Ivan Svetunkov]]></dc:creator>
		<pubDate>Wed, 13 Jan 2021 11:24:18 +0000</pubDate>
				<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[regression]]></category>
		<category><![CDATA[smooth]]></category>
		<guid isPermaLink="false">https://openforecast.org/?p=2552</guid>

					<description><![CDATA[<p>Good news everyone! The future of statistical forecasting is finally here :). Have you ever struggled with ETS and needed explanatory variables? Have you ever needed to unite ARIMA and ETS? Have you ever needed to deal with all those zeroes in the data? What about the data with multiple seasonalities? All of this and [&#8230;]</p>
<p>Message <a href="https://openforecast.org/2021/01/13/the-creation-of-adam-next-step-in-statistical-forecasting/">The creation of ADAM &#8211; next step in statistical forecasting</a> first appeared on <a href="https://openforecast.org">Open Forecasting</a>.</p>
]]></description>
										<content:encoded><![CDATA[<p>Good news everyone! The future of statistical forecasting is finally here :). Have you ever struggled with ETS and needed explanatory variables? Have you ever needed to unite ARIMA and ETS? Have you ever needed to deal with all those zeroes in the data? What about the data with multiple seasonalities? All of this and more can now be solved by <code>adam()</code> function from smooth v3.0.1 package for R (<a href="https://cran.r-project.org/package=smooth">on its way to CRAN now</a>). ADAM stands for &#8220;Augmented Dynamic Adaptive Model&#8221; (I will talk about it in the next <a href="https://cmaf-fft.lp151.com/" rel="noopener" target="_blank">CMAF Friday Forecasting Talk</a> on 15th January). Now, what is ADAM? Well, something like this:</p>
<div id="attachment_2557" style="width: 310px" class="wp-caption aligncenter"><a href="https://openforecast.org/wp-content/webpc-passthru.php?src=https://openforecast.org/wp-content/uploads/2020/12/Touched_by_His_Noodly_Appendage_HD-smooth.jpg&amp;nocache=1"><img loading="lazy" decoding="async" aria-describedby="caption-attachment-2557" src="https://openforecast.org/wp-content/webpc-passthru.php?src=https://openforecast.org/wp-content/uploads/2020/12/Touched_by_His_Noodly_Appendage_HD-smooth-300x142.jpg&amp;nocache=1" alt="ADAM, smooth and His Noodly Appendage Flying Spaghetti Monster" width="300" height="142" class="size-medium wp-image-2557" srcset="https://openforecast.org/wp-content/webpc-passthru.php?src=https://openforecast.org/wp-content/uploads/2020/12/Touched_by_His_Noodly_Appendage_HD-smooth-300x142.jpg&amp;nocache=1 300w, https://openforecast.org/wp-content/webpc-passthru.php?src=https://openforecast.org/wp-content/uploads/2020/12/Touched_by_His_Noodly_Appendage_HD-smooth-768x364.jpg&amp;nocache=1 768w, https://openforecast.org/wp-content/webpc-passthru.php?src=https://openforecast.org/wp-content/uploads/2020/12/Touched_by_His_Noodly_Appendage_HD-smooth.jpg&amp;nocache=1 1000w" sizes="auto, (max-width: 300px) 100vw, 300px" /></a><p id="caption-attachment-2557" class="wp-caption-text">The Creation of ADAM by <a href="http://www.androidarts.com/">Arne Niklas Jansson</a> with my adaptation</p></div>
<p>ADAM is the next step in time series analysis and forecasting. Remember <a href="/en/2016/10/14/smooth-package-for-r-es-i/">exponential smoothing</a> and functions like <code>es()</code> and <code>ets()</code>? Remember ARIMA and functions like <code>arima()</code>, <code>ssarima()</code>, <code>msarima()</code> etc? Remember your favourite <a href="/en/2019/01/07/marketing-analytics-with-greybox/">linear regression function</a>, e.g. <code>lm()</code>, <code>glm()</code> or <code>alm()</code>? Well, now these three models are implemented in a unified framework. Now you can have exponential smoothing with ARIMA elements and explanatory variables in one box: <code>adam()</code>. You can do ETS components and ARIMA orders selection, together with explanatory variables selection in one go. You can estimate ETS / ARIMA / regression using either likelihood of a selected distribution or using conventional losses like MSE, or even using your own custom loss. You can tune parameters of optimiser and experiment with initialisation and estimation of the model. The function can deal with multiple seasonalities and with intermittent data in one place. In fact, there are so many features that it is just easier to list the major of them:</p>
<ol>
<li>ETS;</li>
<li>ARIMA;</li>
<li>Regression;</li>
<li>TVP regression;</li>
<li>Combination of (1), (2) and either (3), or (4);</li>
<li>Automatic selection / combination of states for ETS;</li>
<li>Automatic orders selection for ARIMA;</li>
<li>Variables selection for regression part;</li>
<li>Normal and non-normal distributions;</li>
<li>Automatic selection of most suitable distributions;</li>
<li>Advanced and custom loss functions;</li>
<li>Multiple seasonality;</li>
<li>Occurrence part of the model to handle zeroes in data (intermittent demand);</li>
<li>Model diagnostics using plot() and other methods;</li>
<li>Confidence intervals for parameters of models;</li>
<li>Automatic outliers detection;</li>
<li>Handling missing data;</li>
<li>Fine tuning of persistence vector (smoothing parameters);</li>
<li>Fine tuning of initial values of the state vector (e.g. level / trend / seasonality / ARIMA components / regression parameters);</li>
<li>Two initialisation options (optimal / backcasting);</li>
<li>Provided ARMA parameters;</li>
<li>Fine tuning of optimiser (select algorithm and convergence criteria);</li>
<li>&#8230;</li>
</ol>
<p>All of this is based on the Single Source of Error state space model, which makes ETS, ARIMA and regression directly comparable via information criteria and opens a variety of modelling and forecasting possibilities. In addition, the code is much more efficient than the code of already existing smooth functions, so hopefully this will be a convenient function to use. I do not promise that everything will work 100% efficiently from scratch, because this is a new function, which implies that inevitably there are bugs and there is a room for improvement. But I intent to continue working on it, improving it further, based on the provided feedback (you can submit <a href="https://github.com/config-i1/smooth/issues">an issue on github</a> if you have ideas).</p>
<p>Keep in mind that starting from smooth v3.0.0 I will not be introducing new features in <code>es()</code>, <code>ssarima()</code> and other conventional functions for univariate variables in <code>smooth</code> &#8211; I will only fix bugs in them and possibly optimise some parts of the code, but there will be no innovations in them, given that the main focus from now on will be on <code>adam()</code>. To that extent, I have removed some experimental and not fully developed parameters from those functions (e.g. occurrence, oesmodel, updateX, persistenceX and transitionX).</p>
<p>Now, I realise that ADAM is something completely new and contains just too much information to cover in one post. As a result, I have started the work on an <a href="https://openforecast.org/adam/" rel="noopener" target="_blank">online textbook</a>. This is work in progress, missing some chapters, but it already covers many important elements of ADAM. If you find any mistakes in the text or formulae, please, use the &#8220;Open Review&#8221; functionality in the textbook to give me feedback or send me a message. This will be highly appreciated, because, working on this alone, I am sure that I have made plenty of mistakes and typos.</p>
<h3>Example in R</h3>
<p>Finally, it would be boring just to announce things and leave it like that. So, I&#8217;ve decided to come up with an R experiments on M, M3 and tourism competitions data, similar to how I&#8217;ve <a href="/en/2018/01/01/smooth-functions-in-2017/" rel="noopener" target="_blank">done it in 2017</a>, just to show how the function compares with the other conventional ones, measuring their accuracy and computational time:</p>
<div class="su-spoiler su-spoiler-style-fancy su-spoiler-icon-plus su-spoiler-closed" data-scroll-offset="0" data-anchor-in-url="no"><div class="su-spoiler-title" tabindex="0" role="button"><span class="su-spoiler-icon"></span>Huge chunk of code in R</div><div class="su-spoiler-content su-u-clearfix su-u-trim">
<pre class="decode"># Load the packages. If the packages are not available, install them from CRAN
library(Mcomp)
library(Tcomp)
library(smooth)
library(forecast)

# Load the packages for parallel calculation
# This package is available for Linux and MacOS only
# Comment out this line if you work on Windows
library(doMC)

# Set up the cluster on all cores / threads.
## Note that the code that follows might take around 500Mb per thread,
## so the issue is not in the number of threads, but rather in the RAM availability
## If you do not have enough RAM,
## you might need to reduce the number of threads manually.
## But this should not be greater than the number of threads your processor can do.
registerDoMC(detectCores())

##### Alternatively, if you work on Windows (why?), uncomment and run the following lines
# library(doParallel)
# cl <- detectCores()
# registerDoParallel(cl)
#####

# Create a small but neat function that will return a vector of error measures
errorMeasuresFunction <- function(object, holdout, insample){
    return(c(measures(holdout, object$mean, insample),
             mean(holdout < object$upper &#038; holdout > object$lower),
             mean(object$upper-object$lower)/mean(insample),
             pinball(holdout, object$upper, 0.975)/mean(insample),
             pinball(holdout, object$lower, 0.025)/mean(insample),
             sMIS(holdout, object$lower, object$upper, mean(insample),0.95),
             object$timeElapsed))
}

# Create the list of datasets
datasets <- c(M1,M3,tourism)
datasetLength <- length(datasets)
# Give names to competing forecasting methods
methodsNames <- c("ADAM-ETS(ZZZ)","ADAM-ETS(ZXZ)","ADAM-ARIMA",
                  "ETS(ZXZ)","ETSHyndman","AutoSSARIMA","AutoARIMA");
methodsNumber <- length(methodsNames);
# Run adam on one of time series from the competitions to get names of error measures
test <- adam(datasets[[125]]);
# The array with error measures for each method on each series.
## Here we calculate a lot of error measures, but we will use only few of them
testResults <- array(NA,c(methodsNumber,datasetLength,length(test$accuracy)+6),
                             dimnames=list(methodsNames, NULL,
                                           c(names(test$accuracy),
                                             "Coverage","Range",
                                             "pinballUpper","pinballLower","sMIS",
                                             "Time")));

#### ADAM(ZZZ) ####
j <- 1;
result <- foreach(i=1:datasetLength, .combine="cbind", .packages="smooth") %dopar% {
    startTime <- Sys.time()
    test <- adam(datasets[[i]],"ZZZ");
    testForecast <- forecast(test, h=datasets[[i]]$h, interval="pred");
    testForecast$timeElapsed <- Sys.time() - startTime;
    return(errorMeasuresFunction(testForecast, datasets[[i]]$xx, datasets[[i]]$x));
}
testResults[j,,] <- t(result);

#### ADAM(ZXZ) ####
j <- 2;
result <- foreach(i=1:datasetLength, .combine="cbind", .packages="smooth") %dopar% {
    startTime <- Sys.time()
    test <- adam(datasets[[i]],"ZXZ");
    testForecast <- forecast(test, h=datasets[[i]]$h, interval="pred");
    testForecast$timeElapsed <- Sys.time() - startTime;
    return(errorMeasuresFunction(testForecast, datasets[[i]]$xx, datasets[[i]]$x));
}
testResults[j,,] <- t(result);

#### ADAMARIMA ####
j <- 3;
result <- foreach(i=1:datasetLength, .combine="cbind", .packages="smooth") %dopar% {
    startTime <- Sys.time()
    test <- adam(datasets[[i]], "NNN",
                 order=list(ar=c(3,2),i=c(2,1),ma=c(3,2),select=TRUE));
    testForecast <- forecast(test, h=datasets[[i]]$h, interval="pred");
    testForecast$timeElapsed <- Sys.time() - startTime;
    return(errorMeasuresFunction(testForecast, datasets[[i]]$xx, datasets[[i]]$x));
}
testResults[j,,] <- t(result);

#### ES(ZXZ) ####
j <- 4;
result <- foreach(i=1:datasetLength, .combine="cbind", .packages="smooth") %dopar% {
    startTime <- Sys.time()
    test <- es(datasets[[i]],"ZXZ");
    testForecast <- forecast(test, h=datasets[[i]]$h, interval="parametric");
    testForecast$timeElapsed <- Sys.time() - startTime;
    return(errorMeasuresFunction(testForecast, datasets[[i]]$xx, datasets[[i]]$x));
}
testResults[j,,] <- t(result);

#### ETS from forecast package ####
j <- 5;
result <- foreach(i=1:datasetLength, .combine="cbind", .packages="forecast") %dopar% {
    startTime <- Sys.time()
    test <- ets(datasets[[i]]$x);
    testForecast <- forecast(test, h=datasets[[i]]$h, level=95);
    testForecast$timeElapsed <- Sys.time() - startTime;
    return(errorMeasuresFunction(testForecast, datasets[[i]]$xx, datasets[[i]]$x));
}
testResults[j,,] <- t(result);

#### AUTO SSARIMA ####
j <- 6;
result <- foreach(i=1:datasetLength, .combine="cbind", .packages="smooth") %dopar% {
    startTime <- Sys.time()
    test <- auto.ssarima(datasets[[i]]);
    testForecast <- forecast(test, h=datasets[[i]]$h, interval=TRUE);
    testForecast$timeElapsed <- Sys.time() - startTime;
    return(errorMeasuresFunction(testForecast, datasets[[i]]$xx, datasets[[i]]$x));
}
testResults[j,,] <- t(result);

#### AUTOARIMA ####
j <- 7;
result <- foreach(i=1:datasetLength, .combine="cbind", .packages="forecast") %dopar% {
    startTime <- Sys.time()
    test <- auto.arima(datasets[[i]]$x);
    testForecast <- forecast(test, h=datasets[[i]]$h, level=95);
    testForecast$timeElapsed <- Sys.time() - startTime;
    return(errorMeasuresFunction(testForecast, datasets[[i]]$xx, datasets[[i]]$x));
}
testResults[j,,] <- t(result);

# If you work on Windows, don't forget to shutdown the cluster via the following command:
# stopCluster(cl)</pre>
</div></div>
<p>After running this code, we will get the big array (7x5315x21), which would contain many different error measures for <a href="/en/2019/08/25/are-you-sure-youre-precise-measuring-accuracy-of-point-forecasts/">point forecasts</a> and <a href="/en/2019/10/18/how-confident-are-you-assessing-the-uncertainty-in-forecasting/">prediction intervals</a>. We will not use all of them, but instead will extract MASE and RMSSE for point forecasts and Coverage, Range and sMIS for prediction intervals, together with computational time. Although it might be more informative to look at distributions of those variables, we will calculate mean and median values overall, just to get a feeling about the performance:<br />
<div class="su-spoiler su-spoiler-style-fancy su-spoiler-icon-plus su-spoiler-closed" data-scroll-offset="0" data-anchor-in-url="no"><div class="su-spoiler-title" tabindex="0" role="button"><span class="su-spoiler-icon"></span>A much smaller chunk of code in R</div><div class="su-spoiler-content su-u-clearfix su-u-trim">
<pre class="decode">round(apply(testResults[,,c("MASE","RMSSE","Coverage","Range","sMIS","Time")],
            c(1,3),mean),3)
round(apply(testResults[,,c("MASE","RMSSE","Range","MIS","Time")],
            c(1,3),median),3)</pre>
</div></div>
This will result in the following two tables (boldface shows the best performing functions):</p>
<pre><strong>Means</strong>:
               MASE RMSSE Coverage Range  sMIS  Time
ADAM-ETS(ZZZ) 2.415 2.098    0.888 1.398 2.437 0.654
ADAM-ETS(ZXZ) <strong>2.250 1.961    0.895</strong> 1.225 <strong>2.092</strong> 0.497
ADAM-ARIMA    2.551 2.203    0.862 0.968 3.098 5.990
ETS(ZXZ)      2.279 1.977    0.862 1.372 2.490 1.128
ETSHyndman    2.263 1.970    0.882 1.200 2.258 <strong>0.404</strong>
AutoSSARIMA   2.482 2.134    0.801 <strong>0.780</strong> 3.335 1.700
AutoARIMA     2.303 1.989    0.834 0.805 3.013 1.385

<strong>Medians</strong>:
               MASE RMSSE Range  sMIS  Time
ADAM-ETS(ZZZ) 1.362 1.215 0.671 0.917 0.396
ADAM-ETS(ZXZ) 1.327 1.184 0.675 0.909 0.310
ADAM-ARIMA    1.476 1.300 0.769 1.006 3.525
ETS(ZXZ)      1.335 1.198 0.616 0.931 0.551
ETSHyndman    1.323 <strong>1.181</strong> 0.653 0.925 <strong>0.164</strong>
AutoSSARIMA   1.419 1.271 <strong>0.577</strong> 0.988 0.909
AutoARIMA     <strong>1.310</strong> 1.182 0.609 <strong>0.881</strong> 0.322</pre>
<p>Some things to note from this:</p>
<ul>
<li>ADAM ETS(ZXZ) is the most accurate model in terms of mean MASE and RMSSE, it has the coverage closest to 95% (although none of the models achieved the nominal value because of the fundamental underestimation of uncertainty) and has the lowest sMIS, implying that it did better than the other functions in terms of prediction intervals;</li>
<li>The ETS(ZZZ) did worse than ETS(ZXZ) because the latter considers the multiplicative trend, which sometimes becomes unstable, producing exploding trajectories;</li>
<li>ADAM ARIMA is not performing well yet, because of the implemented order selection algorithm and it was the slowest function of all. I plan to improve it in future releases of the function;</li>
<li>While ADAM ETS(ZXZ) did not beat ETS from forecast package in terms of computational time, it was faster than the other functions;</li>
<li>When it comes to medians, <code>auto.arima()</code>, <code>ets()</code> and <code>auto.ssarima()</code> seem to be doing better than ADAM, but not by a large margin.
</ul>
<p>In order to see if the performance of functions is statistically different, we run <a href="/en/2020/08/17/accuracy-of-forecasting-methods-can-you-tell-the-difference/">the RMCB test</a> for MASE, RMSSE and MIS. Note that RMCB compares the median performance of functions. Here is the R code:<br />
<div class="su-spoiler su-spoiler-style-fancy su-spoiler-icon-plus su-spoiler-closed" data-scroll-offset="0" data-anchor-in-url="no"><div class="su-spoiler-title" tabindex="0" role="button"><span class="su-spoiler-icon"></span>A smaller chunk of code in R for the MCB test</div><div class="su-spoiler-content su-u-clearfix su-u-trim">
<pre class="decode"># Load the package with the function
library(greybox)
# Run it for each separate measure, automatically producing plots
rmcbResultMASE <- rmcb(t(testResults[,,"MASE"]))
rmcbResultRMSSE <- rmcb(t(testResults[,,"RMSSE"]))
rmcbResultsMIS <- rmcb(t(testResults[,,"sMIS"]))</pre>
</div></div>
<p>And here are the figures that we get by running that code</p>
<div id="attachment_2599" style="width: 310px" class="wp-caption aligncenter"><a href="https://openforecast.org/wp-content/webpc-passthru.php?src=https://openforecast.org/wp-content/uploads/2021/01/adamTestsRMCBMASE.png&amp;nocache=1"><img loading="lazy" decoding="async" aria-describedby="caption-attachment-2599" src="https://openforecast.org/wp-content/webpc-passthru.php?src=https://openforecast.org/wp-content/uploads/2021/01/adamTestsRMCBMASE-300x175.png&amp;nocache=1" alt="RMCB test for MASE" width="300" height="175" class="size-medium wp-image-2599" srcset="https://openforecast.org/wp-content/webpc-passthru.php?src=https://openforecast.org/wp-content/uploads/2021/01/adamTestsRMCBMASE-300x175.png&amp;nocache=1 300w, https://openforecast.org/wp-content/webpc-passthru.php?src=https://openforecast.org/wp-content/uploads/2021/01/adamTestsRMCBMASE-1024x597.png&amp;nocache=1 1024w, https://openforecast.org/wp-content/webpc-passthru.php?src=https://openforecast.org/wp-content/uploads/2021/01/adamTestsRMCBMASE-768x448.png&amp;nocache=1 768w, https://openforecast.org/wp-content/webpc-passthru.php?src=https://openforecast.org/wp-content/uploads/2021/01/adamTestsRMCBMASE.png&amp;nocache=1 1200w" sizes="auto, (max-width: 300px) 100vw, 300px" /></a><p id="caption-attachment-2599" class="wp-caption-text">RMCB test for MASE</p></div>
<div id="attachment_2598" style="width: 310px" class="wp-caption aligncenter"><a href="https://openforecast.org/wp-content/webpc-passthru.php?src=https://openforecast.org/wp-content/uploads/2021/01/adamTestsRMCBRMSSE.png&amp;nocache=1"><img loading="lazy" decoding="async" aria-describedby="caption-attachment-2598" src="https://openforecast.org/wp-content/webpc-passthru.php?src=https://openforecast.org/wp-content/uploads/2021/01/adamTestsRMCBRMSSE-300x175.png&amp;nocache=1" alt="RMCB test for RMSSE" width="300" height="175" class="size-medium wp-image-2598" srcset="https://openforecast.org/wp-content/webpc-passthru.php?src=https://openforecast.org/wp-content/uploads/2021/01/adamTestsRMCBRMSSE-300x175.png&amp;nocache=1 300w, https://openforecast.org/wp-content/webpc-passthru.php?src=https://openforecast.org/wp-content/uploads/2021/01/adamTestsRMCBRMSSE-1024x597.png&amp;nocache=1 1024w, https://openforecast.org/wp-content/webpc-passthru.php?src=https://openforecast.org/wp-content/uploads/2021/01/adamTestsRMCBRMSSE-768x448.png&amp;nocache=1 768w, https://openforecast.org/wp-content/webpc-passthru.php?src=https://openforecast.org/wp-content/uploads/2021/01/adamTestsRMCBRMSSE.png&amp;nocache=1 1200w" sizes="auto, (max-width: 300px) 100vw, 300px" /></a><p id="caption-attachment-2598" class="wp-caption-text">RMCB test for RMSSE</p></div>
<p>As we can see from the two figures above, ADAM-ETS(Z,X,Z) performs better than the other functions, although statistically not different than ETS implemented in <code>es()</code> and <code>ets()</code> functions. ADAM-ARIMA is the worst performing function for the moment, as we have already noticed in the previous analysis. The ranking is similar for both MASE and RMSSE.</p>
<p>And here is the sMIS plot:</p>
<div id="attachment_2597" style="width: 310px" class="wp-caption aligncenter"><a href="https://openforecast.org/wp-content/webpc-passthru.php?src=https://openforecast.org/wp-content/uploads/2021/01/adamTestsRMCBsMIS.png&amp;nocache=1"><img loading="lazy" decoding="async" aria-describedby="caption-attachment-2597" src="https://openforecast.org/wp-content/webpc-passthru.php?src=https://openforecast.org/wp-content/uploads/2021/01/adamTestsRMCBsMIS-300x175.png&amp;nocache=1" alt="RMCB test for sMIS" width="300" height="175" class="size-medium wp-image-2597" srcset="https://openforecast.org/wp-content/webpc-passthru.php?src=https://openforecast.org/wp-content/uploads/2021/01/adamTestsRMCBsMIS-300x175.png&amp;nocache=1 300w, https://openforecast.org/wp-content/webpc-passthru.php?src=https://openforecast.org/wp-content/uploads/2021/01/adamTestsRMCBsMIS-1024x597.png&amp;nocache=1 1024w, https://openforecast.org/wp-content/webpc-passthru.php?src=https://openforecast.org/wp-content/uploads/2021/01/adamTestsRMCBsMIS-768x448.png&amp;nocache=1 768w, https://openforecast.org/wp-content/webpc-passthru.php?src=https://openforecast.org/wp-content/uploads/2021/01/adamTestsRMCBsMIS.png&amp;nocache=1 1200w" sizes="auto, (max-width: 300px) 100vw, 300px" /></a><p id="caption-attachment-2597" class="wp-caption-text">RMCB test for sMIS</p></div>
<p>When it comes to sMIS, the leader in terms of medians is <code>auto.arima()</code>, doing quite similar to <code>ets()</code>, but this is mainly because they have lower ranges, incidentally resulting in lower than needed coverage (as seen from the summary performance above). ADAM-ETS does similar to <code>ets()</code> and <code>es()</code> in this aspect (the intervals of the three intersect).</p>
<p>Obviously, we could provide more detailed analysis of performance of functions on different types of data and see, how they compare in each category, but the aim of this post is just to demonstrate how the new function works, I do not have intent to investigate this in detail.</p>
<p>Finally, I will present ADAM with several case studies in <a href="https://cmaf-fft.lp151.com/" rel="noopener" target="_blank">CMAF Friday Forecasting Talk</a> on 15th January. If you are interested to hear more and have some questions, please <a href="https://www.meetup.com/cmaf-friday-forecasting-talks/" rel="noopener" target="_blank">register on MeetUp</a> or <a href="https://www.linkedin.com/events/cmaffft-toinfinityandbeyond-for6751883043834773504/" rel="noopener" target="_blank">via LinkedIn</a> and join us online.</p>
<p>Message <a href="https://openforecast.org/2021/01/13/the-creation-of-adam-next-step-in-statistical-forecasting/">The creation of ADAM &#8211; next step in statistical forecasting</a> first appeared on <a href="https://openforecast.org">Open Forecasting</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://openforecast.org/2021/01/13/the-creation-of-adam-next-step-in-statistical-forecasting/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>International Symposium on Forecasting 2019</title>
		<link>https://openforecast.org/2019/07/03/international-symposium-on-forecasting-2019/</link>
					<comments>https://openforecast.org/2019/07/03/international-symposium-on-forecasting-2019/#comments</comments>
		
		<dc:creator><![CDATA[Ivan Svetunkov]]></dc:creator>
		<pubDate>Wed, 03 Jul 2019 09:12:25 +0000</pubDate>
				<category><![CDATA[Conferences]]></category>
		<category><![CDATA[Regression]]></category>
		<category><![CDATA[Univariate models]]></category>
		<category><![CDATA[conferences]]></category>
		<category><![CDATA[intermittent demand]]></category>
		<category><![CDATA[ISF]]></category>
		<category><![CDATA[presentations]]></category>
		<guid isPermaLink="false">https://openforecast.org/?p=1996</guid>

					<description><![CDATA[<p>The ISF2019 took place in Thessaloniki, Greece. This time I presented a spin-off of my research on intermittent demand in retail, entitled as &#8220;What about those sweet melons? Using mixture models for demand forecasting in retail&#8221;. The idea is quite trivial and simple: use mixture distribution regressions (e.g. logistic and log-normal distributions) in order to [&#8230;]</p>
<p>Message <a href="https://openforecast.org/2019/07/03/international-symposium-on-forecasting-2019/">International Symposium on Forecasting 2019</a> first appeared on <a href="https://openforecast.org">Open Forecasting</a>.</p>
]]></description>
										<content:encoded><![CDATA[<p>The ISF2019 took place in Thessaloniki, Greece. This time I presented a spin-off of my research on intermittent demand in retail, entitled as &#8220;What about those sweet melons? Using mixture models for demand forecasting in retail&#8221;. The idea is quite trivial and simple: use mixture distribution regressions (e.g. logistic and log-normal distributions) in order to predict the seasonally-intermittent sales in retail. The model is quite simple and easy to implement in practice. The main problem that I&#8217;ve faced so far is the absence of the proper data. I only had 24 series of weekly sales of tomatoes provided by a small company, but I need more in order to see, which of the approaches works best. For this research, I need the data like this:<br />
<div id="attachment_2004" style="width: 310px" class="wp-caption alignnone"><a href="/wp-content/uploads/2019/07/tomatoDataExport.jpg"><img loading="lazy" decoding="async" aria-describedby="caption-attachment-2004" src="/wp-content/uploads/2019/07/tomatoDataExport-300x180.jpg" alt="" width="300" height="180" class="size-medium wp-image-2004" srcset="https://openforecast.org/wp-content/webpc-passthru.php?src=https://openforecast.org/wp-content/uploads/2019/07/tomatoDataExport-300x180.jpg&amp;nocache=1 300w, https://openforecast.org/wp-content/webpc-passthru.php?src=https://openforecast.org/wp-content/uploads/2019/07/tomatoDataExport-768x461.jpg&amp;nocache=1 768w, https://openforecast.org/wp-content/webpc-passthru.php?src=https://openforecast.org/wp-content/uploads/2019/07/tomatoDataExport-1024x614.jpg&amp;nocache=1 1024w, https://openforecast.org/wp-content/webpc-passthru.php?src=https://openforecast.org/wp-content/uploads/2019/07/tomatoDataExport.jpg&amp;nocache=1 2000w" sizes="auto, (max-width: 300px) 100vw, 300px" /></a><p id="caption-attachment-2004" class="wp-caption-text">Retail sales of tomatoes</p></div>
Until I have the data, I cannot write a paper on that topic&#8230;</p>
<p>Anyway, <a href="/wp-content/uploads/2019/07/2019-ISF-Svetunkov-Mixture-Distribution.pdf">here are the slides</a> if anyone wants to have a look.</p>
<p>Message <a href="https://openforecast.org/2019/07/03/international-symposium-on-forecasting-2019/">International Symposium on Forecasting 2019</a> first appeared on <a href="https://openforecast.org">Open Forecasting</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://openforecast.org/2019/07/03/international-symposium-on-forecasting-2019/feed/</wfw:commentRss>
			<slash:comments>5</slash:comments>
		
		
			</item>
	</channel>
</rss>
