<?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 Social media - OpenForecast</title>
	<atom:link href="https://openforecast.org/category/social-media/feed/" rel="self" type="application/rss+xml" />
	<link>https://openforecast.org/category/social-media/</link>
	<description>How to look into the future</description>
	<lastBuildDate>Fri, 18 Sep 2026 15:54:20 +0000</lastBuildDate>
	<language>en-GB</language>
	<sy:updatePeriod>
	hourly	</sy:updatePeriod>
	<sy:updateFrequency>
	1	</sy:updateFrequency>
	<generator>https://wordpress.org/?v=7.1.2</generator>

<image>
	<url>https://openforecast.org/wp-content/webpc-passthru.php?src=https://openforecast.org/wp-content/uploads/2026/07/cropped-of-logo-short-1-32x32.png&amp;nocache=1</url>
	<title>Archives Social media - OpenForecast</title>
	<link>https://openforecast.org/category/social-media/</link>
	<width>32</width>
	<height>32</height>
</image> 
	<item>
		<title>The Menace of ML: Simple Moving Average</title>
		<link>https://openforecast.org/2026/09/21/simple-moving-average/</link>
					<comments>https://openforecast.org/2026/09/21/simple-moving-average/#respond</comments>
		
		<dc:creator><![CDATA[Ivan Svetunkov]]></dc:creator>
		<pubDate>Mon, 21 Sep 2026 09:01:58 +0000</pubDate>
				<category><![CDATA[Simple Methods]]></category>
		<category><![CDATA[Social media]]></category>
		<category><![CDATA[extrapolation methods]]></category>
		<category><![CDATA[SMA]]></category>
		<category><![CDATA[theory]]></category>
		<category><![CDATA[time series]]></category>
		<guid isPermaLink="false">https://openforecast.org/?p=4648</guid>

					<description><![CDATA[<p>And here is another forecasting method that is hard to beat in practice. In a recent competition, it gave data scientists huge headaches and even outperformed some powerful ML methods. What&#8217;s the name of this beast?! Simple Moving Average! The idea behind the Simple Moving Average (SMA) is to take the average of the last ... <a title="The Menace of ML: Simple Moving Average" class="read-more" href="https://openforecast.org/2026/09/21/simple-moving-average/" aria-label="Read more about The Menace of ML: Simple Moving Average">Read more</a></p>
<p>Message <a href="https://openforecast.org/2026/09/21/simple-moving-average/">The Menace of ML: Simple Moving Average</a> first appeared on <a href="https://openforecast.org">OpenForecast</a>.</p>
]]></description>
										<content:encoded><![CDATA[<p>And here is another forecasting method that is hard to beat in practice. In a recent competition, it gave data scientists huge headaches and even outperformed some powerful ML methods. What&#8217;s the name of this beast?! Simple Moving Average!</p>
<p>The idea behind the Simple Moving Average (SMA) is to take the average of the last few observations and use it as a forecast for the next several steps ahead. Very crude and very simple. In fact, it has Naive (from <a href="/2026/08/27/why-naive-is-popular-and-important/">this post</a>) as a special case if you take the average of one most recent observation. On the other hand, if you increase the order to include all the observations, you will end up with the Global Mean. And this simple method works quite well if you have level data, i.e. no apparent strong trend, no obvious seasonality, and no other important elements of structure.</p>
<p>The only thing that makes it a bit harder to use in practice is the choice of the order, i.e. the number of observations to average over. Unfortunately, there is no universal answer here. But people report that the order of 12 or 13 is fine for weekly data, although it&#8217;s not completely clear why. In the academic literature, <a href="https://doi.org/10.1016/j.ijforecast.2004.10.001">Aris Syntetos &#038; John Boylan (2005)</a> found that SMA(13) performed quite well on intermittent demand data, which was unexpected given the nature of the data (lots of zeroes). And almost 10 years ago, <a href="/2017/09/20/old-dog-new-tricks-a-modelling-view-of-simple-moving-averages/">Fotios Petropoulos and I proposed a model</a> underlying SMA with automatic order selection. We showed that it outperforms other simple benchmarks on supply chain data.</p>
<p>There is also some evidence from the VN2 inventory competition by Nicolas Vandeput. The benchmark there was built around a 13-week moving average with a simple seasonal adjustment, and only 25 out of 180+ participants <a href="https://nicolas-vandeput.medium.com/my-learning-points-from-vn2-the-first-inventory-competition-a4bffcc92856">managed to beat it</a>. Many sophisticated ML pipelines lost to a method that predates computers.</p>
<p>So, if you work, for example, in retail or in supply chain, SMA is a method to consider for your sanity-check pool of models. But don&#8217;t expect miracles from it! It is still a simple method that works for level time series. Use it as a stepping stone to find a better model that has more features.</p>
<p>Anyone else found SMA to be a strong contender? Leave a comment &#8211; it would be interesting to see how many of you have had the same experience.</p>
<p>And yes, we discuss it in our &#8220;Demand Forecasting Principles&#8221; training in more detail. The next one will be held online in November, with live sessions from 2pm to 4pm UK time. We still have a few places left, so <a href="https://openforecast.org/training/demand-forecasting-principles/">register here</a>.</p>
<p>Message <a href="https://openforecast.org/2026/09/21/simple-moving-average/">The Menace of ML: Simple Moving Average</a> first appeared on <a href="https://openforecast.org">OpenForecast</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://openforecast.org/2026/09/21/simple-moving-average/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Five assumptions behind &#8220;forecastability&#8221;</title>
		<link>https://openforecast.org/2026/09/14/five-assumptions-behind-forecastability/</link>
					<comments>https://openforecast.org/2026/09/14/five-assumptions-behind-forecastability/#respond</comments>
		
		<dc:creator><![CDATA[Ivan Svetunkov]]></dc:creator>
		<pubDate>Mon, 14 Sep 2026 08:03:00 +0000</pubDate>
				<category><![CDATA[Forecast evaluation]]></category>
		<category><![CDATA[Social media]]></category>
		<category><![CDATA[Theory of forecasting]]></category>
		<category><![CDATA[extrapolation methods]]></category>
		<category><![CDATA[opinion]]></category>
		<category><![CDATA[theory]]></category>
		<category><![CDATA[time series]]></category>
		<guid isPermaLink="false">https://openforecast.org/?p=4636</guid>

					<description><![CDATA[<p>Here is a confession. I don&#8217;t like the idea of &#8220;forecastability&#8221;. I think it does not bring value and can be harmful in some cases. Let me explain. One of the definitions I see on the internet: &#8220;A measure of the degree to which something may be forecast with accuracy&#8221;. This definition is so disturbing ... <a title="Five assumptions behind &#8220;forecastability&#8221;" class="read-more" href="https://openforecast.org/2026/09/14/five-assumptions-behind-forecastability/" aria-label="Read more about Five assumptions behind &#8220;forecastability&#8221;">Read more</a></p>
<p>Message <a href="https://openforecast.org/2026/09/14/five-assumptions-behind-forecastability/">Five assumptions behind &#8220;forecastability&#8221;</a> first appeared on <a href="https://openforecast.org">OpenForecast</a>.</p>
]]></description>
										<content:encoded><![CDATA[<p>Here is a confession. I don&#8217;t like the idea of &#8220;forecastability&#8221;. I think it does not bring value and can be harmful in some cases. Let me explain.</p>
<p>One of the definitions I see on the internet: &#8220;A measure of the degree to which something may be forecast with accuracy&#8221;. This definition is so disturbing that I cannot resist ranting about it. The thing that annoys me the most is the &#8220;with accuracy&#8221;, which is really arbitrary and can mean anything. Your Naive method produces a relative RMSE of 1.0. Is that accurate enough? Does this make the time series forecastable? What if ETS produces 1.2, while LightGBM delivers 0.8? Is the data forecastable now? And when do you say &#8220;this is fine&#8221;?</p>
<p>But let me breathe and take a step back. The thing is, any method of measuring forecastability has assumptions behind it. Here is my list of five (did I miss any?):</p>
<ol>
<li>The models you use: each time series has its own characteristics, so you can only say that the data is &#8220;forecastable&#8221; given the set of models you have. The data with trend might look unforecastable for the model that only has the level component.</li>
<li>The features/indicators that are available: if you do not know when promotions happen, some observations will look unforecastable. It&#8217;s a similar argument to (1), but more about what you include in your model. If you spend more time on feature generation and transformation, then the series that looked very hard might become quite easily forecastable.</li>
<li>The statistic you focus on: this could be the conditional mean, the median, some quantile, or the whole predictive distribution. A model can do great in terms of point forecasts but very poorly when it comes to prediction intervals. Does that make the time series unforecastable? Which one do you care more about?</li>
<li>The forecast horizon: the longer it is, the less accurate the forecasts become. One-step-ahead forecasts are easy, multiple steps ahead are hard. Which one do you use to measure forecastability?</li>
<li>The error measures: I&#8217;ll just leave this here: <a href="/category/forecasting-theory/forecast-evaluation/">https://openforecast.org/category/forecasting-theory/forecast-evaluation/</a></li>
</ol>
<p>Do I hear someone mentioning the coefficient of variation (CoV) as a good measure of forecastability? This is, by the way, what is used in the conventional XYZ classification. Well, let&#8217;s check the five points above against it and see what it assumes: (1) the global mean is suitable and the variance is constant; (2) no features are available; (3) conditional mean as the statistic of interest; (4) 1-step-ahead point forecast; (5) Root Mean Squared Error (the core of the CoV). So, it is suitable for a very small set of time series. If you use it universally, you might decide that some time series with a very clear structure are not forecastable. And the same exercise works for the more sophisticated measures, entropy-based ones included: run them through the five questions and see what they silently assume.</p>
<p>And then we come to the final point: so what? Let&#8217;s say you split your data into the &#8220;forecastable/not&#8221; categories. What are you going to do with that? The intention behind this is legitimate — you cannot babysit ten thousand SKUs equally, so you want to know where to spend your time. But the label &#8220;unforecastable&#8221; answers the wrong question. The right question is why the series is hard to forecast: missing promotion information? Wrong model? Genuinely random demand? Each of these implies a different action. It might well be that your &#8220;unforecastable&#8221; time series just require more time and effort to become forecastable again.</p>
<p>We don&#8217;t teach &#8220;forecastability&#8221; in our Demand Forecasting Principles course — because, as you can see, I don&#8217;t believe in it. What we do teach is everything in the list above: models, their assumptions, features, horizons, and how to evaluate forecasts properly. See details about the next course <a href="/training/demand-forecasting-principles/">here</a>.</p>
<p>This is my personal view. Happy to hear what others have to say.</p>
<p>Message <a href="https://openforecast.org/2026/09/14/five-assumptions-behind-forecastability/">Five assumptions behind &#8220;forecastability&#8221;</a> first appeared on <a href="https://openforecast.org">OpenForecast</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://openforecast.org/2026/09/14/five-assumptions-behind-forecastability/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>smooth in python: Multiple Seasonal ARIMA</title>
		<link>https://openforecast.org/2026/09/10/smooth-in-python-multiple-seasonal-arima/</link>
					<comments>https://openforecast.org/2026/09/10/smooth-in-python-multiple-seasonal-arima/#respond</comments>
		
		<dc:creator><![CDATA[Ivan Svetunkov]]></dc:creator>
		<pubDate>Thu, 10 Sep 2026 08:01:44 +0000</pubDate>
				<category><![CDATA[ARIMA]]></category>
		<category><![CDATA[Python]]></category>
		<category><![CDATA[smooth for Python]]></category>
		<category><![CDATA[Social media]]></category>
		<category><![CDATA[ADAM]]></category>
		<category><![CDATA[Seasonality]]></category>
		<category><![CDATA[smooth]]></category>
		<guid isPermaLink="false">https://openforecast.org/?p=4632</guid>

					<description><![CDATA[<p>ARIMA has been a workhorse for decades. But the standard implementations quietly hard-code assumptions: one seasonal cycle, Gaussian errors, regressors handled separately etc. This is fine for textbook well-behaved data. But what do you do when you face real data? The conventional implementations (statsmodels or pmdarima in Python, stats in R) do their job well: ... <a title="smooth in python: Multiple Seasonal ARIMA" class="read-more" href="https://openforecast.org/2026/09/10/smooth-in-python-multiple-seasonal-arima/" aria-label="Read more about smooth in python: Multiple Seasonal ARIMA">Read more</a></p>
<p>Message <a href="https://openforecast.org/2026/09/10/smooth-in-python-multiple-seasonal-arima/">smooth in python: Multiple Seasonal ARIMA</a> first appeared on <a href="https://openforecast.org">OpenForecast</a>.</p>
]]></description>
										<content:encoded><![CDATA[<p>ARIMA has been a workhorse for decades. But the standard implementations quietly hard-code assumptions: one seasonal cycle, Gaussian errors, regressors handled separately etc. This is fine for textbook well-behaved data. But what do you do when you face real data?</p>
<p>The conventional implementations (statsmodels or pmdarima in Python, stats in R) do their job well: they estimate SARIMA via likelihood, select orders automatically, and produce sensible forecasts for series with trend and one seasonality. Monthly or quarterly demand data is their home ground. The problems start when the data has more than one cycle: the classical SARIMA formulation has a slot for exactly one seasonal lag, so for the half-hourly electricity demand you would have to pick either the hour-of-day or the day-of-week cycle and discard the other.</p>
<p>MSARIMA (Multiple Seasonal ARIMA) solves this by reformulating ARIMA in the Single Source of Error (SSOE) state space form. Each AR, I, and MA element becomes a state in the model, so nothing restricts you to one seasonal lag: you can have as many as you want. In the smooth package, orders are specified per lag, matched to a lags list. Here is an example on the classical taylor series (half-hourly electricity demand in England and Wales), with two seasonal cycles:</p>
<p><code>from fcompdata import taylor<br />
from smooth import MSARIMA</p>
<p># MSARIMA(3,0,1)(0,1,1)[48](0,1,1)[336]
model = MSARIMA(<br />
    orders={"ar": [3, 0, 0], "i": [0, 1, 1], "ma": [1, 1, 1]},<br />
    lags=[1, 48, 336],<br />
    h=336, holdout=True<br />
)<br />
model.fit(taylor.y)<br />
model.predict(h=336, interval="prediction", level=0.95)</code></p>
<p>In Python, it takes only 1.5 seconds for the function to fit the model to the data and estimate its parameters, which is fast for a double-seasonal model fit to roughly four thousand observations:</p>
<figure id="attachment_4634" aria-describedby="caption-attachment-4634" style="width: 290px" class="wp-caption aligncenter"><a href="https://openforecast.org/wp-content/webpc-passthru.php?src=https://openforecast.org/wp-content/uploads/2026/09/2026-04-30-smooth-posts-07-msarima.png&amp;nocache=1"><img fetchpriority="high" decoding="async" src="https://openforecast.org/wp-content/webpc-passthru.php?src=https://openforecast.org/wp-content/uploads/2026/09/2026-04-30-smooth-posts-07-msarima-300x207.png&amp;nocache=1" alt="Python/R output of the double seasonal ARIMA" width="300" height="207" class="size-medium wp-image-4634" srcset="https://openforecast.org/wp-content/webpc-passthru.php?src=https://openforecast.org/wp-content/uploads/2026/09/2026-04-30-smooth-posts-07-msarima-300x207.png&amp;nocache=1 300w, https://openforecast.org/wp-content/webpc-passthru.php?src=https://openforecast.org/wp-content/uploads/2026/09/2026-04-30-smooth-posts-07-msarima.png&amp;nocache=1 632w" sizes="(max-width: 300px) 100vw, 300px" /></a><figcaption id="caption-attachment-4634" class="wp-caption-text">Python/R output of the double seasonal ARIMA</figcaption></figure>
<p>But the smooth implementation brings several additional practical benefits.</p>
<p>First, model.fit() accepts a matrix of external regressors via xreg, estimated jointly with the ARIMA components &#8211; no separate pre-filtering step. The logic and the code are identical to ETSX, <a href="/2026/05/05/smooth-in-python-ets-with-explanatory-variables/">which I covered earlier</a>.</p>
<p>Second, you can swap the loss: loss=&#8221;GTMSE&#8221; or &#8220;MSEh&#8221; optimises the model directly on multistep errors, with the same shrinkage mechanism I discussed in <a href="/2026/08/31/smooth-in-python-multistep-losses/">the post on multistep losses</a>.</p>
<p>Third, you don&#8217;t need to stick with the Gaussian distribution &#8211; you can choose other ones if you think that, for example, Laplace is more suitable for the data (<a href="/2026/05/27/smooth-in-python-non-normal-distributions-in-ets-arima/">this post</a>).</p>
<p>And there is one more thing. Because MSARIMA now lives in the same state space framework as ETS, the two models can be combined into one and compared with each other directly via information criteria. But that deserves a post of its own, so stay tuned.</p>
<p>Read <a href="/adam/ADAMARIMA.html">Chapter 9 on ADAM ARIMA</a>.<br />
Or check out the documentation in <a href="https://github.com/openforecast-org/smooth/wiki/MSARIMA">smooth wiki</a>.</p>
<p>An why not try it yourself? <code>pip install smooth</code></p>
<p>Message <a href="https://openforecast.org/2026/09/10/smooth-in-python-multiple-seasonal-arima/">smooth in python: Multiple Seasonal ARIMA</a> first appeared on <a href="https://openforecast.org">OpenForecast</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://openforecast.org/2026/09/10/smooth-in-python-multiple-seasonal-arima/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Another important Naïve method</title>
		<link>https://openforecast.org/2026/09/03/another-important-naive-method/</link>
					<comments>https://openforecast.org/2026/09/03/another-important-naive-method/#respond</comments>
		
		<dc:creator><![CDATA[Ivan Svetunkov]]></dc:creator>
		<pubDate>Thu, 03 Sep 2026 09:05:47 +0000</pubDate>
				<category><![CDATA[Simple Methods]]></category>
		<category><![CDATA[Social media]]></category>
		<category><![CDATA[Theory of forecasting]]></category>
		<category><![CDATA[Seasonality]]></category>
		<category><![CDATA[theory]]></category>
		<guid isPermaLink="false">https://openforecast.org/?p=4614</guid>

					<description><![CDATA[<p>There is another forecasting method that is extremely popular, hard to beat, and has no parameters to estimate. It also has &#8220;Naïve&#8221; in its name. Do you know what I&#8217;m talking about? It is called &#8220;Seasonal Naïve&#8221;. While the simple Naïve copies the last observed actual into the future as a forecast, the seasonal one ... <a title="Another important Naïve method" class="read-more" href="https://openforecast.org/2026/09/03/another-important-naive-method/" aria-label="Read more about Another important Naïve method">Read more</a></p>
<p>Message <a href="https://openforecast.org/2026/09/03/another-important-naive-method/">Another important Naïve method</a> first appeared on <a href="https://openforecast.org">OpenForecast</a>.</p>
]]></description>
										<content:encoded><![CDATA[<p>There is another forecasting method that is extremely popular, hard to beat, and has no parameters to estimate. It also has &#8220;Naïve&#8221; in its name. Do you know what I&#8217;m talking about?</p>
<p>It is called &#8220;Seasonal Naïve&#8221;. While the simple Naïve copies the last observed actual into the future as a forecast, the seasonal one copies the whole seasonal shape of the data and uses it as a forecast. The logic is straightforward: if you see an increase in sales every January, why not use the actual sales of January 2025 as the forecast for January 2026? Simple, easy to do, and hard to beat in some cases, especially when your demand does not have high variability.</p>
<p>What this method doesn&#8217;t do is filter out the noise in the data. This means that if you had a promotion-driven spike this February, Seasonal Naïve will happily copy it into next February&#8217;s forecast. So, if you have some distinct components in your time series and/or effects of explanatory variables on sales, Seasonal Naïve might not be a good choice. But it remains an essential benchmark for any seasonal data.</p>
<p>I actually have an anecdote related to the Seasonal Naïve. Yves Sagaert and I were working on a paper, and we decided to apply our new method to data with multiple seasonality. It worked great, better than the double seasonal exponential smoothing and ARIMA. I was really hyped and was ready to celebrate, when Yves suggested trying the Seasonal Naïve as well. It&#8217;s good that he did, because it turned out that Seasonal Naïve beat them all, including our new method, without even blinking. This was a great demonstration of a principle I had been preaching to others: if you have seasonal data, always use Seasonal Naïve as a benchmark.</p>
<p>In the Demand Forecasting Principles course in November, we cover simple methods like this one properly, including when to stop trusting them. Details and booking can be found <a href="/training/demand-forecasting-principles/">here</a>.</p>
<p>Message <a href="https://openforecast.org/2026/09/03/another-important-naive-method/">Another important Naïve method</a> first appeared on <a href="https://openforecast.org">OpenForecast</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://openforecast.org/2026/09/03/another-important-naive-method/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>smooth in python: Multistep losses</title>
		<link>https://openforecast.org/2026/08/31/smooth-in-python-multistep-losses/</link>
					<comments>https://openforecast.org/2026/08/31/smooth-in-python-multistep-losses/#respond</comments>
		
		<dc:creator><![CDATA[Ivan Svetunkov]]></dc:creator>
		<pubDate>Mon, 31 Aug 2026 08:47:20 +0000</pubDate>
				<category><![CDATA[Python]]></category>
		<category><![CDATA[smooth for Python]]></category>
		<category><![CDATA[Social media]]></category>
		<category><![CDATA[ADAM]]></category>
		<category><![CDATA[ARIMA]]></category>
		<category><![CDATA[ETS]]></category>
		<category><![CDATA[extrapolation methods]]></category>
		<category><![CDATA[Loss functions]]></category>
		<guid isPermaLink="false">https://openforecast.org/?p=4605</guid>

					<description><![CDATA[<p>Why train a forecasting model on one-step-ahead errors when you care about 10-step-ahead accuracy? This is the core motivation behind multistep losses in dynamic models. This has connection with the so-called &#8220;direct forecasting strategy&#8221;. And here what it is and how to work with it in Python. Conventional maximum likelihood estimation minimises one-step-ahead errors. It ... <a title="smooth in python: Multistep losses" class="read-more" href="https://openforecast.org/2026/08/31/smooth-in-python-multistep-losses/" aria-label="Read more about smooth in python: Multistep losses">Read more</a></p>
<p>Message <a href="https://openforecast.org/2026/08/31/smooth-in-python-multistep-losses/">smooth in python: Multistep losses</a> first appeared on <a href="https://openforecast.org">OpenForecast</a>.</p>
]]></description>
										<content:encoded><![CDATA[<p>Why train a forecasting model on one-step-ahead errors when you care about 10-step-ahead accuracy? This is the core motivation behind multistep losses in dynamic models. This has connection with the so-called &#8220;direct forecasting strategy&#8221;. And here what it is and how to work with it in Python.</p>
<p>Conventional maximum likelihood estimation minimises one-step-ahead errors. It works well in many standard situations and produces quite robust models. But in practice, you are rarely interested in just the next observation. Supply chains operate on lead times. Budgets are planned quarterly. The model you trained on one-step-ahed forecast is not the model that minimises your actual decision-relevant error.</p>
<p><strong>Multistep losses address this directly</strong>. Instead of minimising \(\mathrm{MSE}_1\), they minimise errors computed \(h\) steps ahead from every in-sample point. The key theoretical result (<a href="/2023/08/09/multi-step-estimators-and-shrinkage-effect-in-time-series-models/">Svetunkov et al., 2023</a>) is that this implies *shrinkage* of smoothing parameters towards zero — the model becomes less stochastic, less reactive to noise, and more stable across longer horizons. Shrinkage strength grows with \(h\) and weakens as sample size increases.</p>
<p>ADAM supports several multistep losses, each with a different trade-off:</p>
<ul>
<li><strong>MSEh</strong> — minimises the \(h\)-step-ahead variance only; strongest shrinkage, simplest interpretation;</li>
<li><strong>TMSE</strong> — sums \(\mathrm{MSE}_j\) for \(j=1,&#8230;,h\), i.e. sum of the MSEs between 1 and h steps ahead; balances all horizons but is dominated by longer-horizon errors;</li>
<li><strong>GTMSE</strong> — takes the log of each \(\mathrm{MSE}_j\) before summing; equalises the influence of short and long horizons, milder shrinkage;</li>
<li><strong>MSCE</strong> — minimises cumulative forecast error; directly relevant for inventory decisions with lead time \(h\);</li>
<li><strong>GPL</strong> — the full General Predictive Likelihood; accounts for the entire covariance structure of multistep errors and encompasses all the above.</li>
</ul>
<p>All of these are accessible in the Python <code>smooth</code> package with a single parameter change. Here is an example of the code with GTMSE:</p>
<pre class="decode">from fcompdata import AirPassengers
from smooth import ADAM

model = ADAM(model="AAA", lags=12, loss="GTMSE", h=12)
model.fit(AirPassengers.y)
model.predict(h=10)</pre>
<p>The <code>h</code> parameter sets the horizon over which multistep errors are evaluated during estimation. This allows connecting the loss with the specific decision horizon better. The image in the post shows the ETS model fit and forecasts, when estimated with several different losses, including the conventional one.</p>
<p>One practical note: on small samples, MSEh and MSCE can produce noticeably biased parameter estimates (closer to zero) due to strong shrinkage. GTMSE tends to be a safer default for small samples.</p>
<p>Read more about these and other losses in the <a href="/adam/multistepLosses.html">ADAM monograph</a> or in the <a href="https://github.com/openforecast-org/smooth/wiki">wiki of the package</a>.</p>
<p>Message <a href="https://openforecast.org/2026/08/31/smooth-in-python-multistep-losses/">smooth in python: Multistep losses</a> first appeared on <a href="https://openforecast.org">OpenForecast</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://openforecast.org/2026/08/31/smooth-in-python-multistep-losses/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Why Naïve is popular and important</title>
		<link>https://openforecast.org/2026/08/27/why-naive-is-popular-and-important/</link>
					<comments>https://openforecast.org/2026/08/27/why-naive-is-popular-and-important/#respond</comments>
		
		<dc:creator><![CDATA[Ivan Svetunkov]]></dc:creator>
		<pubDate>Thu, 27 Aug 2026 09:03:02 +0000</pubDate>
				<category><![CDATA[Simple Methods]]></category>
		<category><![CDATA[Social media]]></category>
		<category><![CDATA[Theory of forecasting]]></category>
		<category><![CDATA[Competitions]]></category>
		<category><![CDATA[extrapolation methods]]></category>
		<category><![CDATA[theory]]></category>
		<guid isPermaLink="false">https://openforecast.org/?p=4599</guid>

					<description><![CDATA[<p>There is one forecasting method that appears more often than any other in competitions and evaluations. An experienced forecaster will always use it as a benchmark. This method is called &#8220;Naïve&#8221;, and here is why it is popular and important. Naïve is a very simple forecasting method: the forecast equals to the last observed value. ... <a title="Why Naïve is popular and important" class="read-more" href="https://openforecast.org/2026/08/27/why-naive-is-popular-and-important/" aria-label="Read more about Why Naïve is popular and important">Read more</a></p>
<p>Message <a href="https://openforecast.org/2026/08/27/why-naive-is-popular-and-important/">Why Naïve is popular and important</a> first appeared on <a href="https://openforecast.org">OpenForecast</a>.</p>
]]></description>
										<content:encoded><![CDATA[<p>There is one forecasting method that appears more often than any other in competitions and evaluations. An experienced forecaster will always use it as a benchmark. This method is called &#8220;Naïve&#8221;, and here is why it is popular and important.</p>
<p>Naïve is a very simple forecasting method: the forecast equals to the last observed value. So, for example, if the room temperature at 12pm was 20 degrees Celsius, then Naive will forecast exactly the same temperature for 1pm, and it will usually be roughly right. That is what makes it dangerous to sophisticated models: it is often surprisingly hard to beat. If your model cannot beat Naïve, it is not worth deploying, no matter how sophisticated and beautiful it is.</p>
<p>This is why there is a well-established rule in forecasting: any proper evaluation should include simple benchmarks, and Naïve is the easiest one to implement, because it does not have any parameters to estimate and can work with the sample of one observation. This is why you will find it in every decent forecasting competition.</p>
<p>This is not a new finding, by the way. Back in 1979, Spyros Makridakis and Michèle Hibon <a href="https://doi.org/10.2307/2345077">published a paper</a>, showing on a set of 111 real time series that simple methods were often at least as accurate as the sophisticated statistical ones. The audience did not take it well: the discussion that followed was openly hostile, with eminent statisticians suggesting that the results said more about the authors&#8217; skills than about the methods. Spyros&#8217; response was to test the claim at a much larger scale, which is how the M-competitions were born. <a href="/2024/03/14/the-role-of-m-competitions-in-forecasting/">I wrote a post</a> about that some time ago. But the lesson survived the criticism: always compare your approach with the simple forecasting methods.</p>
<p>In our training course on Demand Forecasting Principles, we discuss this and other simple methods in more detail, showing where they work and where they fail. They are all building blocks for understanding applied forecasting.</p>
<p>The next course runs online in October, over Zoom. <a href="https://openforecast.org/training/demand-forecasting-principles/">Details and booking can be found here</a>.</p>
<p>P.S. There is one case where Naïve is not a good benchmark, read <a href="/2024/12/02/why-naive-is-not-a-good-benchmark-for-intermittent-demand/">this post</a>.</p>
<p>Message <a href="https://openforecast.org/2026/08/27/why-naive-is-popular-and-important/">Why Naïve is popular and important</a> first appeared on <a href="https://openforecast.org">OpenForecast</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://openforecast.org/2026/08/27/why-naive-is-popular-and-important/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>stick function for the EDA in time series</title>
		<link>https://openforecast.org/2026/06/26/stick-function-for-the-eda-in-time-series/</link>
					<comments>https://openforecast.org/2026/06/26/stick-function-for-the-eda-in-time-series/#respond</comments>
		
		<dc:creator><![CDATA[Ivan Svetunkov]]></dc:creator>
		<pubDate>Fri, 26 Jun 2026 11:24:43 +0000</pubDate>
				<category><![CDATA[Applied forecasting]]></category>
		<category><![CDATA[greybox in Python]]></category>
		<category><![CDATA[Package greybox for R]]></category>
		<category><![CDATA[Social media]]></category>
		<category><![CDATA[EDA]]></category>
		<category><![CDATA[Python]]></category>
		<category><![CDATA[R]]></category>
		<category><![CDATA[time series]]></category>
		<guid isPermaLink="false">https://openforecast.org/?p=4157</guid>

					<description><![CDATA[<p>You have probably seen my post about the STI classification of Hans Levenbach (this one). Well, I&#8217;ve decided to implement it, and it has landed in the greybox package for R/Python. What&#8217;s greybox? It is a package for statistical modelling focusing on forecasting and time series analysis. I created it back in 2018 to split ... <a title="stick function for the EDA in time series" class="read-more" href="https://openforecast.org/2026/06/26/stick-function-for-the-eda-in-time-series/" aria-label="Read more about stick function for the EDA in time series">Read more</a></p>
<p>Message <a href="https://openforecast.org/2026/06/26/stick-function-for-the-eda-in-time-series/">stick function for the EDA in time series</a> first appeared on <a href="https://openforecast.org">OpenForecast</a>.</p>
]]></description>
										<content:encoded><![CDATA[<p>You have probably seen my post about the STI classification of Hans Levenbach (<a href="/2026/05/18/hans-levenbach-s-classification-scheme-for-trend-seasonal-components/">this one</a>). Well, I&#8217;ve decided to implement it, and it has landed in the greybox package for R/Python.</p>
<p>What&#8217;s greybox? It is a package for statistical modelling focusing on forecasting and time series analysis. I created it back in 2018 to split the static models (such as linear regression) from the dynamic ones that landed in the smooth package. Greybox has evolved since then, and now has linear regression (alm), regression selection (stepwise) and combinations (calm), a variety of tools for feature generation, diagnostics, forecast evaluation (e.g. rolling origin) etc. You can <a href="https://github.com/config-i1/greybox/wiki">read more about it here</a>. Originally, the package was available for R only, but Claude and I ported its main functions to Python back in February.</p>
<p>The Exploratory Data Analysis techniques for time series fit the package quite well, although I don&#8217;t have many of those yet. So, I&#8217;ve implemented the main idea of the STI of Hans Levenbach in a function called &#8220;stick&#8221; (Seasonal, Trend, Irregular Contribution Kit) in the greybox package for R/Python. The idea is straightforward: apply stick to a time series, it will use ANOVA, and give you the strength of each component. Here, for example, is how to apply the function to the AirPassengers data (everyone&#8217;s favourite toy time series) in R:</p>
<pre class="decode">library(greybox)
stick(AirPassengers)</pre>
<p>and in Python:</p>
<pre class="decode">from fcompdata import AirPassengers
from greybox import stick

result = stick(AirPassengers.y, lags=12)
print(result)</pre>
<p>which gives exactly the same result:</p>
<pre>Strength of the components:
seasonal12      trend  irregular
    0.1061     0.8613     0.0326</pre>
<p>So, trend dominates the time series, explaining 86.13% of its variability, meaning that if you capture it correctly, you solve a big chunk of the problem. This split also gives you a rough idea about the structure-versus-noise breakdown in the time series, although it assumes that the seasonal component does not evolve over time.</p>
<p>The function supports several seasonal components, and I might extend it to include external information (e.g. promotions) in the future if there is demand for it.</p>
<p>Message <a href="https://openforecast.org/2026/06/26/stick-function-for-the-eda-in-time-series/">stick function for the EDA in time series</a> first appeared on <a href="https://openforecast.org">OpenForecast</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://openforecast.org/2026/06/26/stick-function-for-the-eda-in-time-series/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>smooth in python: Non-normal distributions in ETS/ARIMA</title>
		<link>https://openforecast.org/2026/05/27/smooth-in-python-non-normal-distributions-in-ets-arima/</link>
					<comments>https://openforecast.org/2026/05/27/smooth-in-python-non-normal-distributions-in-ets-arima/#respond</comments>
		
		<dc:creator><![CDATA[Ivan Svetunkov]]></dc:creator>
		<pubDate>Wed, 27 May 2026 14:17:46 +0000</pubDate>
				<category><![CDATA[ETS]]></category>
		<category><![CDATA[Python]]></category>
		<category><![CDATA[smooth for Python]]></category>
		<category><![CDATA[Social media]]></category>
		<category><![CDATA[ADAM]]></category>
		<category><![CDATA[extrapolation methods]]></category>
		<category><![CDATA[smooth]]></category>
		<guid isPermaLink="false">https://openforecast.org/?p=4152</guid>

					<description><![CDATA[<p>So, you know quite well that the normal distribution is one of the most popular distributions in statistics. The reasons are manifold, including convenience for the academic community and the fact that it is taught in every single statistics course in the world. But what if we don&#8217;t want to be normal? There are situations ... <a title="smooth in python: Non-normal distributions in ETS/ARIMA" class="read-more" href="https://openforecast.org/2026/05/27/smooth-in-python-non-normal-distributions-in-ets-arima/" aria-label="Read more about smooth in python: Non-normal distributions in ETS/ARIMA">Read more</a></p>
<p>Message <a href="https://openforecast.org/2026/05/27/smooth-in-python-non-normal-distributions-in-ets-arima/">smooth in python: Non-normal distributions in ETS/ARIMA</a> first appeared on <a href="https://openforecast.org">OpenForecast</a>.</p>
]]></description>
										<content:encoded><![CDATA[<p>So, you know quite well that the normal distribution is one of the most popular distributions in statistics. The reasons are manifold, including convenience for the academic community and the fact that it is taught in every single statistics course in the world. But what if we don&#8217;t want to be normal?</p>
<p>There are situations where non-normal distributions fit considerably better. The main candidate for substitution is the conditional distribution of the response variable. For example, sales of engines cannot follow the normal distribution by definition: they are intermittent and integer-based — you cannot sell 1.78 engines. More generally, while demand can be fractional, it cannot be negative. It is therefore only logical to use distributions that support positive values only in these situation. Examples include Log-Normal, Gamma, and Inverse Gaussian, among many others.</p>
<p>In my last paper with John Boylan (<a href="/2024/01/10/staying-positive-challenges-and-solutions-in-using-pure-multiplicative-ets-models/">this one</a>), we discussed how ETS can be extended to use these three distributions instead of the normal one. I implemented this functionality (together with the others, such as Laplace and Generalised Normal) in ADAM. It supports any of these distributions with any ETS/ARIMA/regression model, for both additive and multiplicative error terms. There is some maths involved, which you can find <a href="https://openforecast.org/adam/ADAMETSAdditiveDistributions.html">here</a> and <a href="https://openforecast.org/adam/ADAMETSMultiplicativeDistributions.html">here</a>.</p>
<p>Why bother? The main is in the predictive distribution. If the data is not normal, we may end up with poorly calibrated forecasts and misleading prediction intervals. Using a more appropriate distribution can resolve this.</p>
<p>But how do we choose the right distribution for our data?</p>
<p>A possible solution (similar to selecting ETS components) is to fit models with different distributions and pick the one with the lowest information criterion. This is implemented in the ADAM function from the smooth package. We can do this manually, or use AutoADAM (called auto.adam in R) to select the most suitable distribution based on AICc automatically:</p>
<pre class="decode">from fcompdata import AirPassengers
from smooth import AutoADAM

model = AutoADAM(lags=[12], h=12, holdout=True, orders=None, verbose=True)
model.fit(AirPassengers.y)
model.summary()</pre>
<p>The <code>orders=None</code> line stops the function from trying different ARIMA orders &#8211; something we will come back to in a future post. For this example, the output is:</p>
<pre>Model estimated using ADAM() function: ETS(MAM)
Response variable: y
Distribution used in the estimation: Normal
Loss function type: likelihood; Loss function value: 523.2756
Coefficients:
       Estimate  Std. Error  Lower 2.5%  Upper 97.5%   
alpha    0.7575      0.0895      0.5807       0.9343  *
beta     0.0000      0.0080      0.0000       0.0158   
gamma    0.0000      0.0503      0.0000       0.0994   
Error standard deviation: 0.0358
Sample size: 144
Number of estimated parameters: 4
Number of degrees of freedom: 140
Information criteria:
      AIC     AICc       BIC      BICc
1054.5512 1054.839 1066.4305 1067.1455</pre>
<p>Boring&#8230; the function found that the Normal distribution has the lowest AICc among those tested &#8211; the Air Passengers data is too well-behaved.</p>
<p>Oh, and don&#8217;t forget to produce the forecasts:</p>
<pre class="decode">model.predict(h=18, interval="prediction")</pre>
<p>Smooth forecasting!</p>
<p>Install smooth: <code>pip install smooth</code></p>
<p>Message <a href="https://openforecast.org/2026/05/27/smooth-in-python-non-normal-distributions-in-ets-arima/">smooth in python: Non-normal distributions in ETS/ARIMA</a> first appeared on <a href="https://openforecast.org">OpenForecast</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://openforecast.org/2026/05/27/smooth-in-python-non-normal-distributions-in-ets-arima/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Hans Levenbach&#8217;s classification scheme for trend/seasonal components</title>
		<link>https://openforecast.org/2026/05/18/hans-levenbach-s-classification-scheme-for-trend-seasonal-components/</link>
					<comments>https://openforecast.org/2026/05/18/hans-levenbach-s-classification-scheme-for-trend-seasonal-components/#respond</comments>
		
		<dc:creator><![CDATA[Ivan Svetunkov]]></dc:creator>
		<pubDate>Mon, 18 May 2026 08:01:28 +0000</pubDate>
				<category><![CDATA[Social media]]></category>
		<category><![CDATA[Statistics]]></category>
		<category><![CDATA[Theory of forecasting]]></category>
		<category><![CDATA[EDA]]></category>
		<category><![CDATA[Seasonality]]></category>
		<category><![CDATA[time series]]></category>
		<guid isPermaLink="false">https://openforecast.org/?p=4145</guid>

					<description><![CDATA[<p>Here is a curious idea: if we can somehow estimate the importance of trend/seasonal components for your data, you can use this in model building and forecasting. But how can we do this first step? Hans Levenbach has an answer with his simple EDA technique. Let me explain. The core idea is simple and neat. ... <a title="Hans Levenbach&#8217;s classification scheme for trend/seasonal components" class="read-more" href="https://openforecast.org/2026/05/18/hans-levenbach-s-classification-scheme-for-trend-seasonal-components/" aria-label="Read more about Hans Levenbach&#8217;s classification scheme for trend/seasonal components">Read more</a></p>
<p>Message <a href="https://openforecast.org/2026/05/18/hans-levenbach-s-classification-scheme-for-trend-seasonal-components/">Hans Levenbach&#8217;s classification scheme for trend/seasonal components</a> first appeared on <a href="https://openforecast.org">OpenForecast</a>.</p>
]]></description>
										<content:encoded><![CDATA[<p>Here is a curious idea: if we can somehow estimate the importance of trend/seasonal components for your data, you can use this in model building and forecasting. But how can we do this first step? Hans Levenbach has an answer with his simple EDA technique. Let me explain.</p>
<p>The core idea is simple and neat. For this example, I’ll use monthly data, like the time series in this image:</p>
<figure id="attachment_4147" aria-describedby="caption-attachment-4147" style="width: 290px" class="wp-caption aligncenter"><a href="https://openforecast.org/wp-content/webpc-passthru.php?src=https://openforecast.org/wp-content/uploads/2026/05/2026-05-13-Hans-Levenbach-and-STI-01.png&amp;nocache=1"><img decoding="async" src="https://openforecast.org/wp-content/webpc-passthru.php?src=https://openforecast.org/wp-content/uploads/2026/05/2026-05-13-Hans-Levenbach-and-STI-01-300x180.png&amp;nocache=1" alt="" width="300" height="180" class="size-medium wp-image-4147" srcset="https://openforecast.org/wp-content/webpc-passthru.php?src=https://openforecast.org/wp-content/uploads/2026/05/2026-05-13-Hans-Levenbach-and-STI-01-300x180.png&amp;nocache=1 300w, https://openforecast.org/wp-content/webpc-passthru.php?src=https://openforecast.org/wp-content/uploads/2026/05/2026-05-13-Hans-Levenbach-and-STI-01-768x461.png&amp;nocache=1 768w, https://openforecast.org/wp-content/webpc-passthru.php?src=https://openforecast.org/wp-content/uploads/2026/05/2026-05-13-Hans-Levenbach-and-STI-01.png&amp;nocache=1 1000w" sizes="(max-width: 300px) 100vw, 300px" /></a><figcaption id="caption-attachment-4147" class="wp-caption-text">Series N2568 from the M3 dataset</figcaption></figure>
<p>You can see that the data has strong seasonality, and we can qualitatively say that capturing that seasonal component correctly will probably solve the main problem in capturing the structure. But how can we quantify this?</p>
<p>All you need to do is put the data in a &#8220;wide&#8221; format, with months in rows and years in columns. Then, as Hans proposed, run a two-way ANOVA with &#8220;month&#8221; and &#8220;year&#8221; to capture variability due to year (trend) and due to month (seasonality). Roughly, we take row/column means to get mean seasonal profiles and mean annual changes (trend), as in the following two images:</p>
<figure id="attachment_4149" aria-describedby="caption-attachment-4149" style="width: 290px" class="wp-caption aligncenter"><a href="https://openforecast.org/wp-content/webpc-passthru.php?src=https://openforecast.org/wp-content/uploads/2026/05/2026-05-13-Hans-Levenbach-and-STI-02.png&amp;nocache=1"><img decoding="async" src="https://openforecast.org/wp-content/webpc-passthru.php?src=https://openforecast.org/wp-content/uploads/2026/05/2026-05-13-Hans-Levenbach-and-STI-02-300x180.png&amp;nocache=1" alt="Seasonal profile of the data" width="300" height="180" class="size-medium wp-image-4149" srcset="https://openforecast.org/wp-content/webpc-passthru.php?src=https://openforecast.org/wp-content/uploads/2026/05/2026-05-13-Hans-Levenbach-and-STI-02-300x180.png&amp;nocache=1 300w, https://openforecast.org/wp-content/webpc-passthru.php?src=https://openforecast.org/wp-content/uploads/2026/05/2026-05-13-Hans-Levenbach-and-STI-02-768x461.png&amp;nocache=1 768w, https://openforecast.org/wp-content/webpc-passthru.php?src=https://openforecast.org/wp-content/uploads/2026/05/2026-05-13-Hans-Levenbach-and-STI-02.png&amp;nocache=1 1000w" sizes="(max-width: 300px) 100vw, 300px" /></a><figcaption id="caption-attachment-4149" class="wp-caption-text">Seasonal profile of the data</figcaption></figure>
<figure id="attachment_4148" aria-describedby="caption-attachment-4148" style="width: 290px" class="wp-caption aligncenter"><a href="https://openforecast.org/wp-content/webpc-passthru.php?src=https://openforecast.org/wp-content/uploads/2026/05/2026-05-13-Hans-Levenbach-and-STI-03.png&amp;nocache=1"><img loading="lazy" decoding="async" src="https://openforecast.org/wp-content/webpc-passthru.php?src=https://openforecast.org/wp-content/uploads/2026/05/2026-05-13-Hans-Levenbach-and-STI-03-300x180.png&amp;nocache=1" alt="Trend profile" width="300" height="180" class="size-medium wp-image-4148" srcset="https://openforecast.org/wp-content/webpc-passthru.php?src=https://openforecast.org/wp-content/uploads/2026/05/2026-05-13-Hans-Levenbach-and-STI-03-300x180.png&amp;nocache=1 300w, https://openforecast.org/wp-content/webpc-passthru.php?src=https://openforecast.org/wp-content/uploads/2026/05/2026-05-13-Hans-Levenbach-and-STI-03-768x461.png&amp;nocache=1 768w, https://openforecast.org/wp-content/webpc-passthru.php?src=https://openforecast.org/wp-content/uploads/2026/05/2026-05-13-Hans-Levenbach-and-STI-03.png&amp;nocache=1 1000w" sizes="auto, (max-width: 300px) 100vw, 300px" /></a><figcaption id="caption-attachment-4148" class="wp-caption-text">Trend profile</figcaption></figure>
<p>The former has no trend, the latter has no seasonality, so they can be analysed separately. Then we calculate the sums of squares of these means from the global mean to estimate variation due to months (seasonality) and years (trend). We can also calculate the sum of squares of the irregular component (what is left), giving three elements that add up to the total sum of squares.</p>
<p>Next step is trivial and straightforward: calculate the shares of each component in the total sum of squares. For our example, using <code>aov()</code> in R and then computing the total:</p>
<pre>Seasonal:  292,307,558
Trend:     176,308,365
Irregular:  33,618,630

Total:     502,234,552</pre>
<p>So, the seasonal contribution is 292,307,558 / 502,234,552 ≈ 58.2%, the trend contribution is 35.1%, and the irregular component is 6.69%.</p>
<p>Why bother? This simple EDA technique tells you roughly what to focus in forecasting. In this example, capturing seasonality correctly is roughly 60% of the story, with trend being second in importance. Hans goes further in his derivations, see <a href="https://www.linkedin.com/pulse/sticlass-scheme-classification-framework-model-levenbach-phd-cpdf-va7ae/">his LinkedIn post</a>. He also analysed M3 results at some point, explaining why some methods performed better (trend dominated the data).</p>
<p>It is worth pointing out that this approach assumes that the seasonal component does not evolve over time, which is reasonable but not always correct. And the model behind this is essentially a regression with dummy variables for year and month. Nonetheless, it is a great starting point for EDA.</p>
<p>P.S. Hans Levenbach passed away on 7 April 2026. I wasn’t sure whether to write about it and what to write about him, but I had several nice discussions with him, and I have admired his approach to forecasting: first explore the data, then build a model. His passing is a loss for the forecasting community.</p>
<p>P.P.S. You can read a bit about him on <a href="https://forecasters.org/blog/2026/04/10/hans-levenbach-1940-2026/">the IIF website</a>.</p>
<p><a href="https://youtu.be/bjXTF7gKXA8?si=m1Ym5FBDeUWbftv7">CMAF had a webinar with Hans a couple of years ago</a>. We had technical issues, but he managed to explain his idea well.</p>
<p>Message <a href="https://openforecast.org/2026/05/18/hans-levenbach-s-classification-scheme-for-trend-seasonal-components/">Hans Levenbach&#8217;s classification scheme for trend/seasonal components</a> first appeared on <a href="https://openforecast.org">OpenForecast</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://openforecast.org/2026/05/18/hans-levenbach-s-classification-scheme-for-trend-seasonal-components/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>smooth in python: multiple seasonal ETS</title>
		<link>https://openforecast.org/2026/05/11/smooth-in-python-multiple-seasonal-ets/</link>
					<comments>https://openforecast.org/2026/05/11/smooth-in-python-multiple-seasonal-ets/#respond</comments>
		
		<dc:creator><![CDATA[Ivan Svetunkov]]></dc:creator>
		<pubDate>Mon, 11 May 2026 08:08:38 +0000</pubDate>
				<category><![CDATA[ETS]]></category>
		<category><![CDATA[Python]]></category>
		<category><![CDATA[smooth for Python]]></category>
		<category><![CDATA[Social media]]></category>
		<category><![CDATA[extrapolation methods]]></category>
		<category><![CDATA[smooth]]></category>
		<guid isPermaLink="false">https://openforecast.org/?p=4140</guid>

					<description><![CDATA[<p>Another interesting case in demand forecasting is the high frequency data. For example, if you work with demand on daily level, you might notice that demand increases every Monday but also exhibits proper seasonal fluctuations (e.g. decline every Winter). What do you do in this case? One of the solutions (old but gold) is the ... <a title="smooth in python: multiple seasonal ETS" class="read-more" href="https://openforecast.org/2026/05/11/smooth-in-python-multiple-seasonal-ets/" aria-label="Read more about smooth in python: multiple seasonal ETS">Read more</a></p>
<p>Message <a href="https://openforecast.org/2026/05/11/smooth-in-python-multiple-seasonal-ets/">smooth in python: multiple seasonal ETS</a> first appeared on <a href="https://openforecast.org">OpenForecast</a>.</p>
]]></description>
										<content:encoded><![CDATA[<p>Another interesting case in demand forecasting is the high frequency data. For example, if you work with demand on daily level, you might notice that demand increases every Monday but also exhibits proper seasonal fluctuations (e.g. decline every Winter). What do you do in this case?</p>
<p>One of the solutions (old but gold) is the multiple seasonal ETS model, which was originally developed by James Taylor (<a href="https://doi.org/10.1057/palgrave.jors.2601589">2003</a>) for the pure additive exponential smoothing. The idea was quite simple: to model multiple seasonal cycles, one can add multiple seasonal components, i.e. to capture the day-of-week (frequency 7) and the day-of-year (frequency 365) effects. While it worked fine for some examples, the main issue with it has been its computational speed (or rather slowness): the original ETS needs to estimate all smoothing parameters + all the initial values for seasonal indices and other components. Both ADAM and ES in the smooth package support multiple seasonalities and avoid the whole issue by using a different model initialisation called &#8220;backcasting&#8221;.</p>
<p>Here is a classical example from James&#8217; paper on the half-hourly electricity demand (see the image in the post). It is clear that there is a half-hour-of-day and the day-of-week effects. In ES, this means that we need to provide the vector for the lags variable:</p>
<pre class="decode">from smooth import ES
from fcompdata import taylor

# Fit ES with automatic ETS model selection
model = ES(lags=[48, 336], h=336, holdout=True)
model.fit(taylor.y)
model.predict(h=336)
print(model)</pre>
<p>This is the output I get from the function:</p>
<pre>Time elapsed: 2.03 seconds
Model estimated using ES() function: ETS(MNM)
With backcasting initialisation
Distribution assumed in the model: Normal
Loss function type: likelihood; Loss function value: 25391.1773
Persistence vector g:
 alpha gamma1 gamma2
0.2899 0.1283 0.5270
Sample size: 3696
Number of estimated parameters: 4
Number of degrees of freedom: 3692
Information criteria:
      AIC      AICc       BIC      BICc
50790.3546 50790.3654 50815.2146 50815.2591

Forecast errors:
ME: 829.1195; MAE: 942.1447; RMSE: 1065.1127
sCE: 941.5012%; Asymmetry: 9.2%; sMAE: 3.1841%; sMSE: 0.1296%
MASE: 1.4491; RMSSE: 1.1286; rMAE: 0.1408; rRMSE: 0.1300</pre>
<p>The computational time on this data was only 2.03 second. In this time, the function tried several possible ETS models and selected the best one based on the AICc value. The resulting best model is ETS(M,N,M), which makes perfect sense for this data.</p>
<p>Is there a way to improve this model? Yes! Taylor mentions that adding AR(1) to the cocktail tends to improve the accuracy in case of multiple seasonal series. We can try that if we switch to ADAM:</p>
<pre class="decode">from smooth import ADAM

# Fit ADAM ETS(MNM)+AR(1) model
model = ADAM(model="MNM", ar_orders=1, lags=[48, 336], h=336, holdout=True)
model.fit(taylor.y)
print(model)
model.plot(7)</pre>
<p>Here is the output:</p>
<pre>Time elapsed: 1.04 seconds
Model estimated using ADAM() function: ETS(MNM)+ARIMA(1,0,0)
With backcasting initialisation
Distribution assumed in the model: Gamma
Loss function type: likelihood; Loss function value: 24157.2473
Persistence vector g:
 alpha gamma1 gamma2
0.1097 0.2225 0.3481
ARMA parameters of the model:
             Lag 1
AR(1)       0.6852
Sample size: 3696
Number of estimated parameters: 5
Number of degrees of freedom: 3691
Information criteria:
      AIC      AICc       BIC      BICc
48324.4947 48324.5109 48355.5697 48355.6365

Forecast errors:
ME: 276.4061; MAE: 462.5092; RMSE: 588.5957
sCE: 313.8711%; Asymmetry: 2.1%; sMAE: 1.5631%; sMSE: 0.0396%
MASE: 0.7114; RMSSE: 0.6237; rMAE: 0.0691; rRMSE: 0.0719</pre>
<p>The resulting model has lower AICc, but also produces more accurate point forecasts (compare RMSSE values) for the holdout set. The following image shows the data and the point forecasts for it:</p>
<figure id="attachment_4142" aria-describedby="caption-attachment-4142" style="width: 290px" class="wp-caption aligncenter"><a href="https://openforecast.org/wp-content/webpc-passthru.php?src=https://openforecast.org/wp-content/uploads/2026/05/2026-04-17-smooth-posts-04-Multiple-seasonal-ETS-02.png&amp;nocache=1"><img loading="lazy" decoding="async" src="https://openforecast.org/wp-content/webpc-passthru.php?src=https://openforecast.org/wp-content/uploads/2026/05/2026-04-17-smooth-posts-04-Multiple-seasonal-ETS-02-300x214.png&amp;nocache=1" alt="Double seasonal ETS(M,N,M) applied to the half-hourly electricity demand data" width="300" height="214" class="size-medium wp-image-4142" srcset="https://openforecast.org/wp-content/webpc-passthru.php?src=https://openforecast.org/wp-content/uploads/2026/05/2026-04-17-smooth-posts-04-Multiple-seasonal-ETS-02-300x214.png&amp;nocache=1 300w, https://openforecast.org/wp-content/webpc-passthru.php?src=https://openforecast.org/wp-content/uploads/2026/05/2026-04-17-smooth-posts-04-Multiple-seasonal-ETS-02.png&amp;nocache=1 700w" sizes="auto, (max-width: 300px) 100vw, 300px" /></a><figcaption id="caption-attachment-4142" class="wp-caption-text">Double seasonal ETS(M,N,M) applied to the half-hourly electricity demand data</figcaption></figure>
<p>What else can we do here? Actually, quite a lot: multistep losses, seasonal ARIMA, explanatory variables &#8211; things can get only more complicated from here. Have a look <a href="https://openforecast.org/adam/ADAMMultipleFrequenciesExamples.html">at this</a>.</p>
<p>Do I hear someone shouting &#8220;TBATS&#8221;? TBATS is the exponential smoothing with additional bells and whistles (ETS + adapted Fourier terms + ARMA errors). I don&#8217;t have it as a separate function in the smooth just yet, but you can reproduce it, for example, <a href="https://openforecast.org/adam/ETSXMultipleSeasonality.html">like this</a>.</p>
<p>So, what are you waiting for? Dive in and see how it works for yourself!</p>
<p>Install smooth: pip install smooth</p>
<p>Message <a href="https://openforecast.org/2026/05/11/smooth-in-python-multiple-seasonal-ets/">smooth in python: multiple seasonal ETS</a> first appeared on <a href="https://openforecast.org">OpenForecast</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://openforecast.org/2026/05/11/smooth-in-python-multiple-seasonal-ets/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
	</channel>
</rss>
