<?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>Архивы R - Open Forecasting</title>
	<atom:link href="https://openforecast.org/ru/tag/r/feed/" rel="self" type="application/rss+xml" />
	<link>https://openforecast.org/ru/tag/r/</link>
	<description>О том как смотреть в будущее</description>
	<lastBuildDate>Tue, 02 Aug 2022 12:27:23 +0000</lastBuildDate>
	<language>ru-RU</language>
	<sy:updatePeriod>
	hourly	</sy:updatePeriod>
	<sy:updateFrequency>
	1	</sy:updateFrequency>
	<generator>https://wordpress.org/?v=6.9.4</generator>

<image>
	<url>https://openforecast.org/wp-content/webpc-passthru.php?src=https://openforecast.org/wp-content/uploads/2015/08/cropped-usd-05-32x32.png&amp;nocache=1</url>
	<title>Архивы R - Open Forecasting</title>
	<link>https://openforecast.org/ru/tag/r/</link>
	<width>32</width>
	<height>32</height>
</image> 
	<item>
		<title>Комплексное Экспоненциальное Сглаживание</title>
		<link>https://openforecast.org/ru/2022/08/02/kompleksnoe-eksponencialnoe-sglazhivanie/</link>
					<comments>https://openforecast.org/ru/2022/08/02/kompleksnoe-eksponencialnoe-sglazhivanie/#comments</comments>
		
		<dc:creator><![CDATA[Ivan Svetunkov]]></dc:creator>
		<pubDate>Tue, 02 Aug 2022 12:23:39 +0000</pubDate>
				<category><![CDATA[CES]]></category>
		<category><![CDATA[R]]></category>
		<category><![CDATA[Пакет smooth для R]]></category>
		<category><![CDATA[Статьи]]></category>
		<category><![CDATA[статьи]]></category>
		<guid isPermaLink="false">https://openforecast.org/?p=3010</guid>

					<description><![CDATA[<p>Авторы: Ivan Svetunkov, Nikolaos Kourentzes, Keith Ord. Журнал: Naval Research Logistics Аннотация на английском: Exponential smoothing has been one of the most popular forecasting methods used to support various decisions in organisations, in activities such as inventory management, scheduling, revenue management and other areas. Although its relative simplicity and transparency have made it very attractive [&#8230;]</p>
<p>Сообщение <a href="https://openforecast.org/ru/2022/08/02/kompleksnoe-eksponencialnoe-sglazhivanie/">Комплексное Экспоненциальное Сглаживание</a> появились сначала на <a href="https://openforecast.org/ru">Open Forecasting</a>.</p>
]]></description>
										<content:encoded><![CDATA[<p><strong>Авторы</strong>: Ivan Svetunkov, Nikolaos Kourentzes, Keith Ord.</p>
<p><strong>Журнал</strong>: Naval Research Logistics</p>
<p><strong>Аннотация на английском</strong>: Exponential smoothing has been one of the most popular forecasting methods used to support various decisions in organisations, in activities such as inventory management, scheduling, revenue management and other areas. Although its relative simplicity and transparency have made it very attractive for research and practice, identifying the underlying trend remains challenging with significant impact on the resulting accuracy. This has resulted in the development of various modifications of trend models, introducing a model selection problem. With the aim of addressing this problem, we propose the Complex Exponential Smoothing (CES), based on the theory of functions of complex variables. The basic CES approach involves only two parameters and does not require a model selection procedure. Despite these simplifications, CES proves to be competitive with, or even superior to existing methods. We show that CES has several advantages over conventional exponential smoothing models: it can model and forecast both stationary and non-stationary processes, and CES can capture both level and trend cases, as defined in the conventional exponential smoothing classification. CES is evaluated on several forecasting competition datasets, demonstrating better performance than established benchmarks. We conclude that CES has desirable features for time series modelling and opens new promising avenues for research.</p>
<p><a href="/wp-content/uploads/2022/07/Svetunkov-et-al.-2022-Complex-Exponential-Smoothing.pdf">Ссылка на черновую версию статьи</a>.</p>
<p>DOI: <a href="https://doi.org/10.1002/nav.22074" targe="blank">10.1002/nav.22074</a></p>
<p><a href="/en/2022/08/02/the-long-and-winding-road-the-story-of-complex-exponential-smoothing/">История статьи на английском</a>.</p>
<h2>Идея Комплексного Экспоненциального Сглаживания</h2>
<p>Одна из фундаментальных идей в прогнозировании &#8212; это декомпозиция временного ряда на несколько ненаблюдаемых компонент (описание этого процесса есть, например, <a href="http://<a href="https://openforecast.org/adam/tsComponents.html">&#171;>в моей монографии</a>). Обычно говорят, что временной ряд содержит компоненты уровня, тренда, сезонности, а так же ошибку. Это популярное разбиение на компоненты и используется, например, при построении <a href="https://openforecast.org/adam/ETSConventional.html">ETS</a>, внутри которой выбор подходящих компонент осуществляется <a href="https://openforecast.org/adam/ETSSelection.html">на основе информационных критериев</a>. Однако, не у всех временных рядов есть такое чёткое разделение на компоненты, да и само разделение можно считать условным. Например, ряд со слабым трендом на практике может быть не отличим от ряда с быстро меняющимся уровнем. Кроме того, в реальности всё немного сложнее, чем нам кажется и взаимодействие компонент может быть нелинейным.</p>
<p>Комплексное Экспоненциальное Сглаживание (КЭС) моделирует нелинейность во временных рядах и позволяет описывать структуру ряда по-другому. Вот как выглядит модель КЭС математически:<br />
\begin{equation} \label{eq:cesalgebraic}<br />
	\hat{y}_{t} + i \hat{e}_{t} = (\alpha_0 + i\alpha_1)(y_{t-1} + i e_{t-1}) + (1 &#8212; \alpha_0 + i &#8212; i\alpha_1)(\hat{y}_{t-1} + i \hat{e}_{t-1}) ,<br />
\end{equation}<br />
где \(y_t\) &#8212; это фактическое значение, \(e_t\) &#8212; это ошибка прогноза, \(\hat{y}_t\) &#8212; прогнозируемое значение на шаг вперёд, \(\hat{e}_t\) &#8212; это прокси прошлых ошибок, \(\alpha_0\) и \(\alpha_1\) &#8212; это постоянные сглаживания, а \(i\) &#8212; это мнимая единица, число удовлетворяющее уравнению \(i^2=-1\). Из-за использования комплексных переменных, модель позволяет распределять веса во времени нелинейным образом. Это становится более понятно, если в правую часть уравнения \eqref{eq:cesalgebraic} включить само же уравнение, затем повторить это и получить:<br />
\begin{equation} \label{eq:cesalgebraicExpanded}<br />
	\begin{aligned}<br />
		\hat{y}_{t} + i \hat{e}_{t} = &#038; (\alpha_0 + i\alpha_1)(y_{t-1} + i e_{t-1}) + \\<br />
					      &#038; (\alpha_0 + i\alpha_1) (1 &#8212; \alpha_0 + i &#8212; i\alpha_1) (y_{t-2} + i e_{t-2}) + \\<br />
					      &#038; (\alpha_0 + i\alpha_1) (1 &#8212; \alpha_0 + i &#8212; i\alpha_1)^2 (y_{t-3} + i e_{t-3}) + \\<br />
					      &#038; &#8230; + \\<br />
					      &#038; (\alpha_0 + i\alpha_1) (1 &#8212; \alpha_0 + i &#8212; i\alpha_1)^{t-2} (y_{1} + i e_{1}) + \\<br />
					      &#038; (1 &#8212; \alpha_0 + i &#8212; i\alpha_1)^{t-1} (\hat{y}_{1} + i \hat{e}_{1}) .<br />
	\end{aligned}<br />
\end{equation}<br />
Возведение комплексного числа \((1 &#8212; \alpha_0 + i &#8212; i\alpha_1)\) в степень в формуле выше позволяет распределять веса между наблюдениями нелинейным образом. Графически это может быть представлено следующим образом (синяя линия &#8212; веса для фактических значений, зелёная &#8212; для прогнозных ошибок):</p>
<div id="attachment_2978" style="width: 650px" class="wp-caption aligncenter"><a href="/wp-content/uploads/2022/07/cspweights.png"><img fetchpriority="high" decoding="async" aria-describedby="caption-attachment-2978" src="/wp-content/uploads/2022/07/cspweights-1024x410.png" alt="" width="640" height="256" class="size-large wp-image-2978" srcset="https://openforecast.org/wp-content/webpc-passthru.php?src=https://openforecast.org/wp-content/uploads/2022/07/cspweights-1024x410.png&amp;nocache=1 1024w, https://openforecast.org/wp-content/webpc-passthru.php?src=https://openforecast.org/wp-content/uploads/2022/07/cspweights-300x120.png&amp;nocache=1 300w, https://openforecast.org/wp-content/webpc-passthru.php?src=https://openforecast.org/wp-content/uploads/2022/07/cspweights-768x307.png&amp;nocache=1 768w, https://openforecast.org/wp-content/webpc-passthru.php?src=https://openforecast.org/wp-content/uploads/2022/07/cspweights-1536x614.png&amp;nocache=1 1536w, https://openforecast.org/wp-content/webpc-passthru.php?src=https://openforecast.org/wp-content/uploads/2022/07/cspweights-2048x819.png&amp;nocache=1 2048w" sizes="(max-width: 640px) 100vw, 640px" /></a><p id="caption-attachment-2978" class="wp-caption-text">Распределение весов между наблюдениями на комплексной и действительной плоскостях. Синяя линия &#8212; веса для фактических значений, зелёная &#8212; для прогнозных ошибок.</p></div>
<p>В зависимости от значение комплексной постоянной сглаживания \(\alpha_0 + i\alpha_1\), распределение весов будет иметь разный вид. Но оно не обязательно должно быть гармоническим как на рисунке выше, оно может и убывать по классической экспоненте (как у простого экспоненциального сглаживания ака метода Брауна). Именно это гибкое распределение весов даёт КЭС особенную гибкость и позволяет ему быть эффективно применимым как к стационарным, так и нестационарным данным без переключения между компонентами временного ряда.</p>
<p>В опубликованной статье, мы также обсуждаем сезонную модификацию КЭС, которая позволяет моделировать как аддитивную, так и мультипликативную сезонность. Я не привожу формулы и детальное объяснение в данной статье, рекомендую всех заинтересованных обратиться к <a href="/wp-content/uploads/2022/07/Svetunkov-et-al.-2022-Complex-Exponential-Smoothing.pdf">первоисточнику</a>.</p>
<h2>Пример в R</h2>
<p>В R, КЭС реализовано в функции <code>ces()</code> пакета <code>smooth</code>. В том же пакете есть функция <code>auto.ces()</code>, позволяющая автоматически выбирать между не сезонными и сезонными моделями КЭС на основе информационных критериев. Синтакс функций похож на синтекс <code>es()</code> и <code>adam()</code>. Вот пример применения функции:</p>
<pre class="decode">cesModel <- smooth::auto.ces(BJsales, holdout=TRUE, h=12)
cesModel</pre>
<pre>Time elapsed: 0.05 seconds
Model estimated: CES(n)
a0 + ia1: 1.9981+1.0034i
Initial values were produced using backcasting.

Loss function type: likelihood; Loss function value: 249.4613
Error standard deviation: 1.4914
Sample size: 138
Number of estimated parameters: 3
Number of degrees of freedom: 135
Information criteria:
     AIC     AICc      BIC     BICc 
504.9227 505.1018 513.7045 514.1457 

Forecast errors:
MPE: 0%; sCE: 0.7%; Asymmetry: -5%; MAPE: 0.4%
MASE: 0.857; sMAE: 0.4%; sMSE: 0%; rMAE: 0.329; rRMSE: 0.338</pre>
<p>Описание выше уже как-то обсуждалось <a href="/2016/11/02/smooth-package-for-r-es-function-part-ii-pure-additive-models-ru/">в одном из прошлых постов</a> на примере функции <code>es()</code>. Главное отличие между тем, что возвращают функции <code>es()</code> и <code>ces()</code> - это параметры. В данном случае, мы видим, что комплексная постоянная сглаживания \(\alpha_0 + i\alpha_1 = 1.9981 + i 1.0034\). Полученную модель можно использовать в прогнозировании, например, так:</p>
<pre class="decode">cesModel |> forecast(h=12, interval="p") |> plot()</pre>
<p>что даст такой график:</p>
<div id="attachment_3007" 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/07/cesForecast.png&amp;nocache=1"><img decoding="async" aria-describedby="caption-attachment-3007" src="https://openforecast.org/wp-content/webpc-passthru.php?src=https://openforecast.org/wp-content/uploads/2022/07/cesForecast-300x210.png&amp;nocache=1" alt="" width="300" height="210" class="size-medium wp-image-3007" srcset="https://openforecast.org/wp-content/webpc-passthru.php?src=https://openforecast.org/wp-content/uploads/2022/07/cesForecast-300x210.png&amp;nocache=1 300w, https://openforecast.org/wp-content/webpc-passthru.php?src=https://openforecast.org/wp-content/uploads/2022/07/cesForecast-768x538.png&amp;nocache=1 768w, https://openforecast.org/wp-content/webpc-passthru.php?src=https://openforecast.org/wp-content/uploads/2022/07/cesForecast.png&amp;nocache=1 1000w" sizes="(max-width: 300px) 100vw, 300px" /></a><p id="caption-attachment-3007" class="wp-caption-text">Прогноз КЭС для ряда продаж из книги Box & Jenkins.</p></div>
<p>Сама функция <code>ces()</code> не изменилась с момента окончания мною PhD в 2016 году, так что результаты, например, <a href="/en/2018/01/01/smooth-functions-in-2017/">вот этого</a> сравнения всё ещё актуальны. Модель не обязательно даёт самые точные прогнозы во всех случаях, но как, например, было показано в статье <a href="https://doi.org/10.1016/j.ijforecast.2019.01.006">Petropoulos & Svetunkov (2020)</a>, она привносит в комбинации то, чего не привносят другие модели. Всё из-за того, что КЭС позволяет хорошо вылавливать долгосрочные тенденции во временных рядах.</p>
<h2>Послесловие</h2>
<p>В качестве послесловия, я хотел бы выразить свои благодарности нескольким людям. Во-первых, это <a href="http://kourentzes.com/forecasting/">Никос Курентзес</a>, который поверил в мою модель в далёком 2012 году и поддерживал меня все эти годы без колебаний. Во-вторых, это <a href="https://scholar.google.com/citations?user=-0p44ukAAAAJ">Кит Орд</a>, который помог мне в некоторых выкладках и затем оказал серьёзную поддержку статье и помог придать ей ту форму, которая она имеет в конце концов. Ну, и, конечно же, я благодарен своему папе, <a href="https://sergey.svetunkov.ru/">Сергею Геннадьевичу Светунькову</a>, который направлял меня в моей исследовательской деятельности в самом её начале и верил в меня и мои исследования ещё тогда, когда никто о них ничего не подозревал.</p>
<p>Если вы хотите узнать больше про модель, вам придётся прочитать <a href="/wp-content/uploads/2022/07/Svetunkov-et-al.-2022-Complex-Exponential-Smoothing.pdf">статью на английском</a> (она также доступна <a href="https://doi.org/10.1002/nav.22074" targe="blank">онлайн</a> на сайте издателя) или же прочитать на английском <a href="/en/2022/08/02/the-long-and-winding-road-the-story-of-complex-exponential-smoothing/">историю статьи</a>.</p>
<p>Сообщение <a href="https://openforecast.org/ru/2022/08/02/kompleksnoe-eksponencialnoe-sglazhivanie/">Комплексное Экспоненциальное Сглаживание</a> появились сначала на <a href="https://openforecast.org/ru">Open Forecasting</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://openforecast.org/ru/2022/08/02/kompleksnoe-eksponencialnoe-sglazhivanie/feed/</wfw:commentRss>
			<slash:comments>1</slash:comments>
		
		
			</item>
		<item>
		<title>Точность прогнозных методов: а есть ли разница?</title>
		<link>https://openforecast.org/ru/2020/08/17/tochnost-prognoznyh-metodov-a-est-li-raznica/</link>
					<comments>https://openforecast.org/ru/2020/08/17/tochnost-prognoznyh-metodov-a-est-li-raznica/#comments</comments>
		
		<dc:creator><![CDATA[Ivan Svetunkov]]></dc:creator>
		<pubDate>Mon, 17 Aug 2020 16:04:56 +0000</pubDate>
				<category><![CDATA[R]]></category>
		<category><![CDATA[Оценка точности прогнозов]]></category>
		<category><![CDATA[Теория прогнозирования]]></category>
		<category><![CDATA[Прогнозные ошибки]]></category>
		<category><![CDATA[теория]]></category>
		<guid isPermaLink="false">https://openforecast.org/?p=2513</guid>

					<description><![CDATA[<p>В предыдущих статьях мы обсудили, как измерять точность точечных и интервальных прогнозов в разных случаях. Теперь мы можем глубже взглянуть на эту проблему и разобраться, в какой именно степени разные методы отличаются друг от друга. Представим гипотетическую ситуацию, в которой мы имеем дело с четырьмя методами на 100 временных рядах, точность которых измеряется с помощью [&#8230;]</p>
<p>Сообщение <a href="https://openforecast.org/ru/2020/08/17/tochnost-prognoznyh-metodov-a-est-li-raznica/">Точность прогнозных методов: а есть ли разница?</a> появились сначала на <a href="https://openforecast.org/ru">Open Forecasting</a>.</p>
]]></description>
										<content:encoded><![CDATA[<p>В предыдущих статьях мы обсудили, как измерять точность <a href="/2019/08/25/kak-izmerit-tochnost-prognozov/">точечных</a> и <a href="/2019/10/18/o-tom-kak-ocenit-adekvatnost-prognoznyh-intervalov/">интервальных</a> прогнозов в разных случаях. Теперь мы можем глубже взглянуть на эту проблему и разобраться, в какой именно степени разные методы отличаются друг от друга. Представим гипотетическую ситуацию, в которой мы имеем дело с четырьмя методами на 100 временных рядах, точность которых измеряется с помощью RMSSE:</p>
<pre class="decode">smallCompetition <- matrix(NA, 100, 4, dimnames=list(NULL, paste0("Method",c(1:4))))
smallCompetition[,1] <- rnorm(100,1,0.35)
smallCompetition[,2] <- rnorm(100,1.2,0.2)
smallCompetition[,3] <- runif(100,0.5,1.5)
smallCompetition[,4] <- rlnorm(100,0,0.3)</pre>
<p>Мы можем сравнить среднюю и медианы в данном примере, чтобы понять, как они в целом себя ведут:</p>
<pre class="decode">overalResults <- matrix(c(colMeans(smallCompetition),apply(smallCompetition,2,median)),
                        4, 2, dimnames=list(colnames(smallCompetition),c("Mean","Median")))
round(overalResults,5)</pre>
<pre>          Mean   Median
Method1 0.99869 1.01157
Method2 1.18413 1.19839
Method3 1.00315 1.00768
Method4 1.08543 1.04730</pre>
<p>В этом искусственном примере, самым точным (в соответствии со средней RMSSE) оказался первый метод, в то время как самым неточным, оказался метод 2. Что касается медиан, то тут лидирует Метод 3. Однако разность в точность между методами 1, 3 и 4 не выглядит существенной, особенно в случае с медианами. Можем ли мы заключить, что метод 1 самый лучший и надо отдать ему предпочтение? Давайте взглянём на распределение ошибок:</p>
<pre class="decode">boxplot(overalResults)
points(colMeans(smallCompetition),col="red",pch=16)</pre>
<div id="attachment_2474" 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/07/smallCompetitionBoxplots.png&amp;nocache=1"><img decoding="async" aria-describedby="caption-attachment-2474" src="https://openforecast.org/wp-content/webpc-passthru.php?src=https://openforecast.org/wp-content/uploads/2020/07/smallCompetitionBoxplots-300x180.png&amp;nocache=1" alt="Ящичковая диаграмма по распределению прогнозных ошибок" width="300" height="180" class="size-medium wp-image-2474" srcset="https://openforecast.org/wp-content/webpc-passthru.php?src=https://openforecast.org/wp-content/uploads/2020/07/smallCompetitionBoxplots-300x180.png&amp;nocache=1 300w, https://openforecast.org/wp-content/webpc-passthru.php?src=https://openforecast.org/wp-content/uploads/2020/07/smallCompetitionBoxplots-768x461.png&amp;nocache=1 768w, https://openforecast.org/wp-content/webpc-passthru.php?src=https://openforecast.org/wp-content/uploads/2020/07/smallCompetitionBoxplots.png&amp;nocache=1 1000w" sizes="(max-width: 300px) 100vw, 300px" /></a><p id="caption-attachment-2474" class="wp-caption-text">Ящичковая диаграмма по распределению прогнозных ошибок</p></div>
<p>Эти диаграммы нам показывают, что распределение ошибок метода 2 немного смещено вверх, по сравнению с распределениями для остальных методов. При этом дисперсия ошибок во втором методе ниже, чем в остальных (это из-за того, что мы использовали <code>sd=0.2</code>, когда генерировали данные). Кроме того, по такой диаграмме тяжело однозначно заключить, что метод 1 лучше метода 3 или наоборот - их ящичковые диаграммы пересекаются и очень похожи. Ну, и последнее, метод 4 в целом кажется чуть-чуть хуже, но это возможно из-за нескольких выбросов (несколько рядов, в которых метод не сработал).</p>
<p>Это всё основные описательные статистики, которые мы обычно используем для анализа случайных величин. Они нам позволяют заключить, что методы 1 и 3 очень похожи в плане точности прогнозов, а метод 2 им уступает. Это так же находит отражение в средних и медианных ошибках, которые мы рассчитали ранее. Что же нам заключить по результатам такого анализа? Что выбрать? Метод 1 или метод 3?</p>
<p>Давайте не будем делать поспешных решений. Вспомним, что мы имеем дело с выборкой из временных рядов (100 штук). Это означает, что средняя / медианная точность методов может измениться, если в нашей выборке появится ещё несколько рядов (или если из неё выкинуть несколько). Если бы в нашем распоряжении были все временные ряды во вселенной, мы могли бы оценить наши методы на них (удачи<br />
и терпения в таком случае!) и прийти к каким-то более обоснованным выводам относительно их точности. Но мы имеем дело с выборкой, поэтому имеет смысл понять, является ли разница в точности методов статистически значимой или нет. Как это сделать?</p>
<p>Для начала, мы могли бы сравнить средние распределения ошибок с помощью какого-нибудь параметрического теста. Можно попробовать <a href="https://ru.wikipedia.org/wiki/F-%D1%82%D0%B5%D1%81%D1%82" rel="noopener noreferrer" target="_blank">F-тест</a> для того, чтобы понять, имеются ли какие бы то ни было различия в точности методов или нет. К сожалению, тест не скажет нам, какие именно методы оказались лучше, а какие хуже. Для этих целей можно использовать парный <a href="https://ru.wikipedia.org/wiki/T-%D0%BA%D1%80%D0%B8%D1%82%D0%B5%D1%80%D0%B8%D0%B9_%D0%A1%D1%82%D1%8C%D1%8E%D0%B4%D0%B5%D0%BD%D1%82%D0%B0" rel="noopener noreferrer" target="_blank">t-тест</a>, но он позволяет сравнить одновременно только два метода друг с другом. Как вариант, можно построить регрессию с фиктивными переменными, для каждого метода и на основе интервалов для полученных параметров понять, как точность в среднем отличается от метода к методу. Главная проблема во всём этом заключается в том, что эти подходы предполагают, что распределение средних ошибок нормальное. В случае с большими выборками (тысячи рядов), центральная предельная теорема может начать работать, и эта предпосылка будет иметь смысл. Но в случае с малыми выборками, она, скорее всего, будет нарушена, особенно учитывая то, что прогнозные ошибки обычно распределены асимметрично, с длинным правым хвостом.</p>
<p>Возможное решение проблемы в этой ситуации - непараметрические тесты. Мы можем сравнить медианы распределений, вместо средних. Медианы менее подвержены влиянию выбросов, так что даже в случае с асимметричным распределением на малых выборках, они будут вести себя более предсказуемо, чем средние. В этой ситуации можно провести <a href="https://ru.wikipedia.org/wiki/%D0%9A%D1%80%D0%B8%D1%82%D0%B5%D1%80%D0%B8%D0%B9_%D0%A4%D1%80%D0%B8%D0%B4%D0%BC%D0%B0%D0%BD%D0%B0" rel="noopener noreferrer" target="_blank">тест Фридмана</a>, для того, чтобы понять, есть ли различия в медианах между методами (его можно считать непараметрическим аналогом F-теста). Для попарного сравнения можно использовать <a href="https://ru.wikipedia.org/wiki/%D0%9A%D1%80%D0%B8%D1%82%D0%B5%D1%80%D0%B8%D0%B9_%D0%A3%D0%B8%D0%BB%D0%BA%D0%BE%D0%BA%D1%81%D0%BE%D0%BD%D0%B0" rel="noopener noreferrer" target="_blank">тест Уилкоксона</a> вместо t-теста, но он так же покажет нам только, отличаются ли друг от друга выбранные два метода или нет (а у нас их четыре).</p>
<p>Хорошо, что у нас есть тест Nemenyi (<a href="http://www.jmlr.org/papers/v7/demsar06a.html" rel="noopener noreferrer" target="_blank">Demšar, 2006</a>), который <a href="https://kourentzes.com/forecasting/2012/04/19/statistical-significance-of-forecasting-methods-an-empirical-evaluation-of-the-robustness-and-interpretability-of-the-mcb-anom-and-friedman-nemenyi-test/" rel="noopener noreferrer" target="_blank">эквивалентен тесту MCB</a> (<a href="https://doi.org/10.1016/j.ijforecast.2004.10.003" rel="noopener noreferrer" target="_blank">Koning et al., 2005</a>). Если не вдаваться в детали, то что делает тест, так это ранжирует точность методов для каждого временного ряда, а затем сравнивает средние величины. Средняя рангов соответствует медиане, так что тест фактически сравнивает медианы прогнозных ошибок. Далее строятся доверительные интервалы для каждого из средних рангов и сравниваются друг с другом. Если какие-то интервалы пересекаются, то разница между медианами этих методов не значима статистически. Существуют разные методы представления результатов этого теста, один из них реализован в функции <code>nemenyi()</code> из пакета <code>tsutils</code> для R. Функция поддерживает разные виды графиков (<a href="https://kourentzes.com/forecasting/2019/01/14/r-package-tsutils/" rel="noopener noreferrer" target="_blank">Никос Курентзес</a> обсуждал эту функцию в своём блоге), мне лично нравится стиль MCB:</p>
<pre class="decode">library(tsutils)
nemenyi(smallCompetition, plottype="mcb")</pre>
<div id="attachment_2473" 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/07/smallCompetitionMCB.png&amp;nocache=1"><img loading="lazy" decoding="async" aria-describedby="caption-attachment-2473" src="https://openforecast.org/wp-content/webpc-passthru.php?src=https://openforecast.org/wp-content/uploads/2020/07/smallCompetitionMCB-300x180.png&amp;nocache=1" alt="Пример теста MCB" width="300" height="180" class="size-medium wp-image-2473" srcset="https://openforecast.org/wp-content/webpc-passthru.php?src=https://openforecast.org/wp-content/uploads/2020/07/smallCompetitionMCB-300x180.png&amp;nocache=1 300w, https://openforecast.org/wp-content/webpc-passthru.php?src=https://openforecast.org/wp-content/uploads/2020/07/smallCompetitionMCB-768x461.png&amp;nocache=1 768w, https://openforecast.org/wp-content/webpc-passthru.php?src=https://openforecast.org/wp-content/uploads/2020/07/smallCompetitionMCB.png&amp;nocache=1 1000w" sizes="auto, (max-width: 300px) 100vw, 300px" /></a><p id="caption-attachment-2473" class="wp-caption-text">Тест MCB для сравнения медианных ошибок</p></div>
<p>По этому графику видно, что медианные ошибки методов 1, 3 и 4 не отличаются на 95% доверительном уровне (потому что их интервалы на графике пересекаются). При этом, как и ранее видно, что метод 3 лучше других (его медиана меньше всех), а метод 2 - хуже всех. Помимо этого, интервалы между методом 2 и методами 1 и 3 не пересекаются, так что можно заключить, что их медианные ошибки отличаются на 5% уровне остаточной вероятности. Что любопытно, интервалы второго и четвёртого методов пересекаются, так что между ними нет статистически значимой разницы. Тем не менее, мы можем заключить, что второй метод плохо работает на этих данных, а вот методы 1, 3 и 4 не сильно отличаются друг от друга. Эта ситуация может измениться, если у нас изменится выборка (например, добавится ещё сотня рядов) или увеличится число прогнозных методов.</p>
<p>Альтернативой тесту <code>nemenyi()</code>, дающей примерно такие же результаты, является построение регрессии с фиктивными переменными по рангам прогнозных ошибок. В этом случае мы получим коэффициенты модели и их доверительные интервалы, которые можно так же графически изобразить, как и в случае с Nemenyi / MCB. F-тест в таком случае покажет, отличается ли медианная ошибка хотя бы одного метода от всех остальных или нет (аналог теста Фридмана). Конечно же, статистически более правильным было бы построение порядковой логистической регрессии, но и такой простой метод с простой линейной регрессией даст необходимые результаты. К тому же, с ним значительно проще работать, чем с логистической моделью. Функция <code>rmcb()</code> из пакета <code>greybox</code> как раз реализует подобный подход. Преимущество этого метода по сравнению с <code>nemenyi()</code> заключается в скорости, особенно на больших выборках. Вот пример:</p>
<pre class="decode">library(greybox)
ourTest <- rmcb(smallCompetition,plottype="none")
ourTest
plot(ourTest,"mcb")</pre>
<pre>Regression for Multiple Comparison with the Best
The significance level is 5%
The number of observations is 100, the number of methods is 4
Significance test p-value: 0</pre>
<div id="attachment_2490" 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/07/smallCompetitionRMCB.png&amp;nocache=1"><img loading="lazy" decoding="async" aria-describedby="caption-attachment-2490" src="https://openforecast.org/wp-content/webpc-passthru.php?src=https://openforecast.org/wp-content/uploads/2020/07/smallCompetitionRMCB-300x180.png&amp;nocache=1" alt="RMCB test example" width="300" height="180" class="size-medium wp-image-2490" srcset="https://openforecast.org/wp-content/webpc-passthru.php?src=https://openforecast.org/wp-content/uploads/2020/07/smallCompetitionRMCB-300x180.png&amp;nocache=1 300w, https://openforecast.org/wp-content/webpc-passthru.php?src=https://openforecast.org/wp-content/uploads/2020/07/smallCompetitionRMCB-768x461.png&amp;nocache=1 768w, https://openforecast.org/wp-content/webpc-passthru.php?src=https://openforecast.org/wp-content/uploads/2020/07/smallCompetitionRMCB.png&amp;nocache=1 1000w" sizes="auto, (max-width: 300px) 100vw, 300px" /></a><p id="caption-attachment-2490" class="wp-caption-text">RMCB test for medians of error measures for the small competition</p></div>
<p>Результаты теста аналогичны тому, что мы уже видели ранее: методы 3, 1 и 4 статистически не различимы в плане медианных RMSSE, а метод 2 оказался значительно менее точным, чем остальные. Главная разница между Nemenyi и регрессией по рангам заключается в том, как именно считаются критические значения в статистике: <code>nemenyi()</code> использует Стьюдентезированный размах, а <code>rmcb()</code> использует распределение Стьюдента (это два разных распределения). Первое более чувствительно к числу методов, которые сравниваются в тесте, чем второе. Однако, с увеличением выборки, результаты тестов будут приближаться друг к другу. Из-за этой разницы <code>rmcb()</code> утверждает, что медиана метод 4 значительно (статистически) ниже медианы метода 2 на 5% уровне остаточной вероятности. Я бы рекомендовал использовать этот метод на больших выборках.</p>
<p>Что касается выводов из всего вышенаписанного, судя по всему, хоть методы и ведут себя по-разному на наших условных данных, медианы некоторых из них не значительно отличаются друг от друга на 5% уровне (методы 3, 1 и 4). Для того, чтобы прийти к какому-то более точному выводы, нам следовало бы собрать больше данных и провести повторный анализ. Вполне возможно, что на выборке из 1000 рядов, разница между методами стала бы статистически значимой на 5% уровне, и мы смогли бы выявить явного лидера. Однако, в нашем случае для выбора наилучшего метода имеет смысл обратиться к другим важным факторам, таким как простота методов или время, требуемое на построение прогнозов. Как видим, статистические тесты могут помочь нам в принятии более взвешенное решение относительно того, какому прогнозному методу отдать предпочтение.</p>
<p>Сообщение <a href="https://openforecast.org/ru/2020/08/17/tochnost-prognoznyh-metodov-a-est-li-raznica/">Точность прогнозных методов: а есть ли разница?</a> появились сначала на <a href="https://openforecast.org/ru">Open Forecasting</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://openforecast.org/ru/2020/08/17/tochnost-prognoznyh-metodov-a-est-li-raznica/feed/</wfw:commentRss>
			<slash:comments>2</slash:comments>
		
		
			</item>
		<item>
		<title>О том, как оценить адекватность прогнозных интервалов</title>
		<link>https://openforecast.org/ru/2019/10/18/o-tom-kak-ocenit-adekvatnost-prognoznyh-intervalov/</link>
					<comments>https://openforecast.org/ru/2019/10/18/o-tom-kak-ocenit-adekvatnost-prognoznyh-intervalov/#comments</comments>
		
		<dc:creator><![CDATA[Ivan Svetunkov]]></dc:creator>
		<pubDate>Fri, 18 Oct 2019 20:18:40 +0000</pubDate>
				<category><![CDATA[R]]></category>
		<category><![CDATA[Оценка точности прогнозов]]></category>
		<category><![CDATA[Теория прогнозирования]]></category>
		<category><![CDATA[ETS]]></category>
		<category><![CDATA[smooth]]></category>
		<category><![CDATA[Прогнозные ошибки]]></category>
		<guid isPermaLink="false">https://openforecast.org/?p=2235</guid>

					<description><![CDATA[<p>Введение Некоторые люди считают, что главная идея прогнозирования заключается в том, чтобы как можно более точно предсказать будущее. У меня для них плохие новости. На самом деле главная идея прогнозирования заключается в уменьшении неопределённости относительно будущего. Ведь, будущее не предопределено, мы никогда не знаем, что именно произойдёт, когда и как. Но с помощью методов прогнозирования [&#8230;]</p>
<p>Сообщение <a href="https://openforecast.org/ru/2019/10/18/o-tom-kak-ocenit-adekvatnost-prognoznyh-intervalov/">О том, как оценить адекватность прогнозных интервалов</a> появились сначала на <a href="https://openforecast.org/ru">Open Forecasting</a>.</p>
]]></description>
										<content:encoded><![CDATA[<h3>Введение</h3>
<p>Некоторые люди считают, что главная идея прогнозирования заключается в том, чтобы как можно более точно предсказать будущее. У меня для них плохие новости. На самом деле главная идея прогнозирования заключается в уменьшении неопределённости относительно будущего. Ведь, будущее не предопределено, мы никогда не знаем, что именно произойдёт, когда и как. Но с помощью методов прогнозирования мы можем хотя бы сказать, чего не стоит ждать и очертить область, в которой, вероятно, событие произойдёт&#8230;</p>
<p>В принципе, любое событие, которое мы хотим рассмотреть с точки зрения прогнозирования, может быть представлено некой систематической составляющей \(\mu_t\), которую можно описать с помощью некоторой модели, а так же случайной компонентой \(\epsilon_t\). Последняя может и не быть случайной по природе, но будет считаться случайной для целей моделирования. А всё из-за того, что мы не можем, например, предсказать, пойдёт ли конкретный человек в поликлинику в определённый день или нет. Поэтому тот спрос (или с чем вы там работаете), который мы наблюдаем в виде конкретных величин, может быть грубо описан математически следующим образом:<br />
\begin{equation} \label{eq:demand}<br />
y_t = \mu_t + \epsilon_t,<br />
\end{equation}<br />
где \(y_t\) &#8212; это фактические значения спроса (есть и другие формулы для нелинейных моделей, но они не меняют суть дискуссии, поэтому пока тут мы будем говорить о простой линейной модели). Что же мы обычно делаем в прогнозировании? Мы пытаемся как можно точнее описать систематическую составляющую \(\mu_t\), пытаясь выловить структуру и каким-то образом так же получить представление о неопределённости \(\epsilon_t\) вокруг этой структуры. Когда речь заходит об ошибке \(\epsilon_t\), мы обычно можем только что-то сказать о том, как это величина распределена, и какие у неё параметры (например, математическое ожидание и дисперсия). </p>
<p>Поэтому, когда перед нами имеется какой-нибудь вот такой временной ряд:</p>
<p><a href="https://openforecast.org/wp-content/webpc-passthru.php?src=https://openforecast.org/wp-content/uploads/2019/10/UncertaintyExample.png&amp;nocache=1"><img loading="lazy" decoding="async" class="aligncenter size-medium wp-image-2202" src="https://openforecast.org/wp-content/webpc-passthru.php?src=https://openforecast.org/wp-content/uploads/2019/10/UncertaintyExample-300x175.png&amp;nocache=1" alt="" width="300" height="175" srcset="https://openforecast.org/wp-content/webpc-passthru.php?src=https://openforecast.org/wp-content/uploads/2019/10/UncertaintyExample-300x175.png&amp;nocache=1 300w, https://openforecast.org/wp-content/webpc-passthru.php?src=https://openforecast.org/wp-content/uploads/2019/10/UncertaintyExample-768x448.png&amp;nocache=1 768w, https://openforecast.org/wp-content/webpc-passthru.php?src=https://openforecast.org/wp-content/uploads/2019/10/UncertaintyExample-1024x597.png&amp;nocache=1 1024w, https://openforecast.org/wp-content/webpc-passthru.php?src=https://openforecast.org/wp-content/uploads/2019/10/UncertaintyExample.png&amp;nocache=1 1200w" sizes="auto, (max-width: 300px) 100vw, 300px" /></a></p>
<p>то мы можем сказать, что средний уровень продаж составляет 1000 единиц, но так же, что вокруг этого уровня имеются некие случайные отклонения, характеризуемые каким-то СКО \(\sigma \approx 100 \). Суть прогнозирования сводится к тому, чтобы оценить как можно точнее \(\mu_t\) и \(\sigma\). Если нам удастся это сделать, то мы построим точечные прогнозы (синяя линия на графике) и прогнозный интервал шириной \(1-\alpha\) (скажем, 95-ти процентный, серая область на графике), который в идеальной ситуации будет накрывать \((1-\alpha) \times 100\)% наблюдений.</p>
<p>В реальности, мы никогда не знаем переменную \(\mu_t\), поэтому, в процессе построения модели мы можем либо переоценить её (&#171;underestimate&#187;, например, не включив сезонную компоненту), что приведёт к излишне высокой дисперсии и увеличенной ширине прогнозного интервала, либо недооценить её (&#171;overestimate&#187;, например, включив тренд, когда это ненужно), что приведёт к заниженной дисперсии и не реалистично узким прогнозным интервалам. Поэтому при выборе модели, мы пытаемся добраться как можно ближе к значениям \(\mu_t\) и \(\sigma\). </p>
<p>Когда речь заходит о непосредственном прогнозировании, мы обычно строим точечные прогнозы, которые соответствуют условной средней величине модели, призванной точно отразить будущие значения \(\mu_t\), а так же прогнозные интервалы, которые соответствуют определённым квантилям распределения и по идеи должны каким-то образом описать неопределённость случайной величины \(\epsilon_t\). На этом сайте уже была <a href="/2017/06/11/prediction-intervals/">статья на тему прогнозных интервалов</a>, а так же пару статей на тему <a href="/2019/08/25/kak-izmerit-tochnost-prognozov/">измерения точности точечных прогнозов</a>. В этой статье мы обсудим, как понять, правильно ли модель выловила эту самую неопределённость или нет.</p>
<h3>Интервальный оценки</h3>
<p>Рассмотрим следующий пример в R с использованием функций пакета smooth v2.5.4. Сгенерируем данные на основе модели ETS(A,N,A) с построим по этим данным несколько моделей:</p>
<pre class="decode">library(smooth)
x <- sim.es("ANA", obs=120, frequency=12, persistence=c(0.3,0.1), initial=c(1000), mean=0, sd=100)
modelUnderfit <- es(x$data, "ANN", silent=F, interval=T, holdout=T, h=24)
modelOverfit <- es(x$data, "AAA", silent=F, interval=T, holdout=T, h=24)
modelCorrect <- es(x$data, "ANA", silent=F, interval=T, holdout=T, h=24)
modelTrue <- es(x, silent=F, interval=T, holdout=T, h=24)</pre>
<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>Четыре картинки с модельками</div><div class="su-spoiler-content su-u-clearfix su-u-trim">
<div id="attachment_2207" style="width: 310px" class="wp-caption aligncenter"><a href="https://openforecast.org/wp-content/webpc-passthru.php?src=https://openforecast.org/wp-content/uploads/2019/10/Intervals-ANA-ANN.png&amp;nocache=1"><img loading="lazy" decoding="async" aria-describedby="caption-attachment-2207" class="size-medium wp-image-2207" src="https://openforecast.org/wp-content/webpc-passthru.php?src=https://openforecast.org/wp-content/uploads/2019/10/Intervals-ANA-ANN-300x175.png&amp;nocache=1" alt="" width="300" height="175" srcset="https://openforecast.org/wp-content/webpc-passthru.php?src=https://openforecast.org/wp-content/uploads/2019/10/Intervals-ANA-ANN-300x175.png&amp;nocache=1 300w, https://openforecast.org/wp-content/webpc-passthru.php?src=https://openforecast.org/wp-content/uploads/2019/10/Intervals-ANA-ANN-768x448.png&amp;nocache=1 768w, https://openforecast.org/wp-content/webpc-passthru.php?src=https://openforecast.org/wp-content/uploads/2019/10/Intervals-ANA-ANN-1024x597.png&amp;nocache=1 1024w, https://openforecast.org/wp-content/webpc-passthru.php?src=https://openforecast.org/wp-content/uploads/2019/10/Intervals-ANA-ANN.png&amp;nocache=1 1200w" sizes="auto, (max-width: 300px) 100vw, 300px" /></a><p id="caption-attachment-2207" class="wp-caption-text">Модель, недооценивающая данные</p></div>
<div id="attachment_2206" style="width: 310px" class="wp-caption aligncenter"><a href="https://openforecast.org/wp-content/webpc-passthru.php?src=https://openforecast.org/wp-content/uploads/2019/10/Intervals-ANA-AAA.png&amp;nocache=1"><img loading="lazy" decoding="async" aria-describedby="caption-attachment-2206" class="size-medium wp-image-2206" src="https://openforecast.org/wp-content/webpc-passthru.php?src=https://openforecast.org/wp-content/uploads/2019/10/Intervals-ANA-AAA-300x175.png&amp;nocache=1" alt="" width="300" height="175" srcset="https://openforecast.org/wp-content/webpc-passthru.php?src=https://openforecast.org/wp-content/uploads/2019/10/Intervals-ANA-AAA-300x175.png&amp;nocache=1 300w, https://openforecast.org/wp-content/webpc-passthru.php?src=https://openforecast.org/wp-content/uploads/2019/10/Intervals-ANA-AAA-768x448.png&amp;nocache=1 768w, https://openforecast.org/wp-content/webpc-passthru.php?src=https://openforecast.org/wp-content/uploads/2019/10/Intervals-ANA-AAA-1024x597.png&amp;nocache=1 1024w, https://openforecast.org/wp-content/webpc-passthru.php?src=https://openforecast.org/wp-content/uploads/2019/10/Intervals-ANA-AAA.png&amp;nocache=1 1200w" sizes="auto, (max-width: 300px) 100vw, 300px" /></a><p id="caption-attachment-2206" class="wp-caption-text">Модель, переоценивающая данные</p></div>
<div id="attachment_2208" style="width: 310px" class="wp-caption aligncenter"><a href="https://openforecast.org/wp-content/webpc-passthru.php?src=https://openforecast.org/wp-content/uploads/2019/10/Intervals-ANA-ANA-1.png&amp;nocache=1"><img loading="lazy" decoding="async" aria-describedby="caption-attachment-2208" class="size-medium wp-image-2208" src="https://openforecast.org/wp-content/webpc-passthru.php?src=https://openforecast.org/wp-content/uploads/2019/10/Intervals-ANA-ANA-1-300x175.png&amp;nocache=1" alt="" width="300" height="175" srcset="https://openforecast.org/wp-content/webpc-passthru.php?src=https://openforecast.org/wp-content/uploads/2019/10/Intervals-ANA-ANA-1-300x175.png&amp;nocache=1 300w, https://openforecast.org/wp-content/webpc-passthru.php?src=https://openforecast.org/wp-content/uploads/2019/10/Intervals-ANA-ANA-1-768x448.png&amp;nocache=1 768w, https://openforecast.org/wp-content/webpc-passthru.php?src=https://openforecast.org/wp-content/uploads/2019/10/Intervals-ANA-ANA-1-1024x597.png&amp;nocache=1 1024w, https://openforecast.org/wp-content/webpc-passthru.php?src=https://openforecast.org/wp-content/uploads/2019/10/Intervals-ANA-ANA-1.png&amp;nocache=1 1200w" sizes="auto, (max-width: 300px) 100vw, 300px" /></a><p id="caption-attachment-2208" class="wp-caption-text">Правильная модель</p></div>
<div id="attachment_2204" style="width: 310px" class="wp-caption aligncenter"><a href="https://openforecast.org/wp-content/webpc-passthru.php?src=https://openforecast.org/wp-content/uploads/2019/10/Intervals-ANA-True.png&amp;nocache=1"><img loading="lazy" decoding="async" aria-describedby="caption-attachment-2204" class="size-medium wp-image-2204" src="https://openforecast.org/wp-content/webpc-passthru.php?src=https://openforecast.org/wp-content/uploads/2019/10/Intervals-ANA-True-300x175.png&amp;nocache=1" alt="" width="300" height="175" srcset="https://openforecast.org/wp-content/webpc-passthru.php?src=https://openforecast.org/wp-content/uploads/2019/10/Intervals-ANA-True-300x175.png&amp;nocache=1 300w, https://openforecast.org/wp-content/webpc-passthru.php?src=https://openforecast.org/wp-content/uploads/2019/10/Intervals-ANA-True-768x448.png&amp;nocache=1 768w, https://openforecast.org/wp-content/webpc-passthru.php?src=https://openforecast.org/wp-content/uploads/2019/10/Intervals-ANA-True-1024x597.png&amp;nocache=1 1024w, https://openforecast.org/wp-content/webpc-passthru.php?src=https://openforecast.org/wp-content/uploads/2019/10/Intervals-ANA-True.png&amp;nocache=1 1200w" sizes="auto, (max-width: 300px) 100vw, 300px" /></a><p id="caption-attachment-2204" class="wp-caption-text">Истинная модель</p></div>
</div></div>
<p>Сами данные демонстрируют меняющийся уровень ряда и изменяющуюся во времени сезонность. А четыре модели, которые мы использовали, это:</p>
<ol>
<li>ETS(A,N,N), которая недооценивает данные (underfitting) из-за отсутствия сезонной компоненты,</li>
<li>ETS(A,A,A), которая переоценивает данные (overfitting) из-за лишней компоненты (тренд),</li>
<li>ETS(A,N,A), которая правильно специфицирована, но параметры которой рассчитаны на основе выборки,</li>
<li>ETS(A,N,A) - истинная модель, с правильными параметрами.</li>
</ol>
<p>Все эти модели дают нам точечные прогнозы, точность которых можно оценить с помощью <a href="/2019/08/25/kak-izmerit-tochnost-prognozov/">каких-нибудь ошибок</a>:</p>
<pre class="decode">errorMeasures <- rbind(modelUnderfit$accuracy,
                       modelOverfit$accuracy,
                       modelCorrect$accuracy,
                       modelTrue$accuracy)[,c("sMAE","sMSE","sCE")]
rownames(errorMeasures) <- c("Model Underfit","Model Overfit","Model Correct","Model True")
errorMeasures*100</pre>
<pre>                    sMAE      sMSE       sCE
Model Underfit 45.134368 25.510527 -122.3740
Model Overfit  19.797382  5.026588 -449.8459
Model Correct   9.580048  1.327130 -149.7284
Model True      9.529042  1.318951 -139.8342</pre>
<p>Обратите внимание, что в нашем примере первая модель дала наименее точный прогноз из-за отсутствия сезонной компоненты, но при этом дала наименее смещённый прогноз (sCE=-122.3740), что могло произойти просто по счастливой случайности. Вторая модель оказалась точнее первой, потому что в ней есть необходимая компонента, но не такой точной, как правильная модель из-за наличия тренда, который продолжает нисходящую траекторию на проверочной выборке. Что касается последних двух моделей, то разница в их точности достаточно мала, но, судя по всему, истинная модель оказалась немного точнее модели, оцененной по выборке.</p>
<p>Что более важно, все эти модели дали разные интервальные прогнозы. Проблема в том, что графически их проанализировать затруднительно. Поэтому нам стоит оценить их точность с помощью каких-нибудь показателей. Например, <strong>Mean Interval Score</strong> (MIS), предложенной <a href="https://doi.org/10.1198/016214506000001437" target="_blank" rel="noopener noreferrer">Gneiting (2011)</a> и популяризованной во время <a href="https://www.mcompetitions.unic.ac.cy/m4/" target="_blank" rel="noopener noreferrer">M4 Competition</a>:<br />
\begin{equation} \label{MIS}<br />
\begin{matrix}<br />
\text{MIS} = & \frac{1}{h} \sum_{j=1}^h \left( (u_{t+j} -l_{t+j}) + \frac{2}{\alpha} (l_{t+j} -y_{t+j}) \mathbb{1}(y_{t+j} < l_{t+j}) \right. \\ &#038; \left. + \frac{2}{\alpha} (y_{t+j} -u_{t+j}) \mathbb{1}(y_{t+j} > u_{t+j}) \right) ,<br />
\end{matrix}<br />
\end{equation}<br />
где \(u_{t+j}\) - это верхняя граница, \(l_{t+j}\) - это нижняя граница  интервала, \(\alpha\) - это уровень значимости, а \(\mathbb{1}(\cdot)\) - это индикаторная функция, значение которой равно единице, в случае, если условие внутри неё верно, и нулю в противном случае. Идея MIS заключается в том, чтобы оценить размах интервала вместе с его охватом (сколько наблюдений было накрыто интервалом). Если фактические значения лежат вне интервала, то ошибка увеличивается пропорционально расстоянию до них с коэффициентом \(\frac{2}{\alpha}\). Кроме того, ширина интервала положительно влияет на значение индекса: чем шире интервал, тем больше значение MIS. Идеалистическая модель со значением MIS=0 должна содержать значения на границах интервал, причём \(u_{t+j}=l_{t+j}\), что означает, что будущее предопределено, никакой случайно составляющей нет. Конечно же, в реальности это просто невозможно.</p>
<p>Этот индекс доступен в пакете greybox для R:</p>
<pre class="decode">c(MIS(modelUnderfit$holdout,modelUnderfit$lower,modelUnderfit$upper,level=0.95),
  MIS(modelOverfit$holdout,modelOverfit$lower,modelOverfit$upper,level=0.95),
  MIS(modelCorrect$holdout,modelCorrect$lower,modelCorrect$upper,level=0.95),
  MIS(modelTrue$holdout,modelTrue$lower,modelTrue$upper,level=0.95))</pre>
<pre>[1] 1541.6667 1427.7527  431.7717  504.8203</pre>
<p>Полученные цифры сами по себе ничего нам не говорят, их надо сравнивать друг с другом. Как видим, первая модель показала себя хуже всех в плане прогнозных интервалов, в то время как правильная модель 3 настолько хороша, что даже уделала истинную модель 4 (это могло произойти по чистой случайности). </p>
<p>К сожалению, мы не можем сказать ничего больше по поводу интервалов на основе MIS. Поэтому для того, чтобы понять, что же именно произошло, мы можем обратиться к среднему размаху интервалов (range):<br />
\begin{equation} \label{range}<br />
\text{range} = \frac{1}{h} \sum_{j=1}^h (u_{t+j} -l_{t+j}) ,<br />
\end{equation}<br />
которая на человеческом языке означает среднюю фактической ширины интервалов с первого по h шагов вперёд. Вот как это рассчитать в R:</p>
<pre class="decode">c(mean(modelUnderfit$upper - modelUnderfit$lower),
  mean(modelOverfit$upper - modelOverfit$lower),
  mean(modelCorrect$upper - modelCorrect$lower),
  mean(modelTrue$upper - modelTrue$lower))</pre>
<pre>[1] 1541.6667  297.1488  431.7717  504.8203</pre>
<p>Глядя на эти цифры, становится понятно, что вторая модель (которая переоценивает данные) произвела самые узкие интервалы из четырёх моделей, и серьёзно недооценила неопределённость. Это привело к тому, что большая часть значений оказалась вне интервала. Заметьте так же, что ширина интервалов первой модели значительно больше ширины других интервалов. Это плохо, потому что принимать решения на их основе будет затруднительно (что-то типа "завтра мы продадим от 100 до 1600 единиц хлеба").</p>
<p>Что можно ещё сделать, так это рассчитать среднюю величину покрытия интервалами (coverage):<br />
\begin{equation} \label{coverage}<br />
\text{coverage} = \frac{1}{h} \sum_{j=1}^h \left( \mathbb{1}(y_{t+j} < l_{t+j}) \times \mathbb{1}(y_{t+j} > u_{t+j}) \right) ,<br />
\end{equation}<br />
что может быть сделано в R следующим образом:</p>
<pre class="decode">c(sum((modelUnderfit$holdout > modelUnderfit$lower & modelUnderfit$holdout < modelUnderfit$upper)) / length(modelUnderfit$holdout),
  sum((modelOverfit$holdout > modelOverfit$lower & modelOverfit$holdout < modelOverfit$upper)) / length(modelOverfit$holdout),
  sum((modelCorrect$holdout > modelCorrect$lower & modelCorrect$holdout < modelCorrect$upper)) / length(modelCorrect$holdout),
  sum((modelTrue$holdout > modelTrue$lower & modelTrue$holdout < modelTrue$upper)) / length(modelTrue$holdout))</pre>
<pre>[1] 1.0000000 0.5416667 1.0000000 1.0000000</pre>
<p>К сожалению, в нашем случае эта величина оказалось не очень полезной. Например, первая, третья и четвёртая модели содержат в своих интервалах 100% наблюдений, хотя должны бы содержать 95%. Что же касается второй модели, то она накрывает только 54.2% наблюдений, что, конечно же, тоже плохо. Тем не менее, глядя на размах и величину покрытия мы можем заключить, что проблема второй модели заключается в излишне узком интервале, проблема первой - в излишне широком, в то время как третья и четвёртая неплохо себя проявили в этом упражнении.</p>
<p>Если нам нужно получить ещё более подробную оценку точности интервалов, мы можем обратиться к <a href="/etextbook/forecasting_toolbox/estimation-simple-methods/">пинбольной функции</a> для каждой границы по отдельности (кажется, она была предложена <a href="https://doi.org/10.2307/1913643" target="_blank" rel="noopener noreferrer">Koenker & Basset, 1978</a>):<br />
\begin{equation} \label{pinball}<br />
\text{pinball} = (1 -\alpha) \sum_{y_{t+j} < b_{t+j}, j=1,\dots,h } |y_{t+j} -b_{t+j}| + \alpha \sum_{y_{t+j} \geq b_{t+j} , j=1,\dots,h } |y_{t+j} -b_{t+j}|,
\end{equation}
где \(b_{t+j}\) - это значение границы интервала (верхней или нижней). Пинбол, по идеи, должен показывать, насколько точно мы оценили конкретный квантиль распределения. Чем меньше его значение, тем ближе мы оказались к квантилю. Если он равен нулю, то мы идеально попали в соответствующий квантиль.

В нашем случае, мы строили 95% прогнозный интервал, что означает, что мы целились в 2.5% и 97.5% квантили. Пинбол можно рассчитать с помощью функции пакета greybox в R:


<pre class="decode">pinballValues <- cbind(c(pinball(modelUnderfit$holdout,modelUnderfit$lower,0.025),
                         pinball(modelOverfit$holdout,modelOverfit$lower,0.025),
                         pinball(modelCorrect$holdout,modelCorrect$lower,0.025),
                         pinball(modelTrue$holdout,modelTrue$lower,0.025)),
                       c(pinball(modelUnderfit$holdout,modelUnderfit$upper,0.975),
                         pinball(modelOverfit$holdout,modelOverfit$upper,0.975),
                         pinball(modelCorrect$holdout,modelCorrect$upper,0.975),
                         pinball(modelTrue$holdout,modelTrue$upper,0.975)))
rownames(pinballValues) <- c("Model Underfit","Model Overfit","Model Correct","Model True")
colnames(pinballValues) <- c("lower","upper")
pinballValues</pre>
<pre>                  lower    upper
Model Underfit 484.0630 440.9371
Model Overfit  168.4098 688.2418
Model Correct  155.9144 103.1486
Model True     176.0856 126.8066</pre>
<p>Мы вновь можем заметить, что сами по себе значения пинболов нам ни о чём не говорят - они должны сравниваться друг с другом. На основе этого сравнения можно заключить, что правильная модель 3 оказалась точнее как для 2.5%, так и для 97.5% квантилей. Она даже побила истинную модель в этом примере, что согласуется с нашими предыдущими наблюдениями. Впрочем, это пример на одном временном ряде, так что это не показательно.</p>
<p>Кроме того, мы видим, что первая модель оказалась хуже правильной модели в плане как верхней, так и нижней границ интервала. Это всё из-за того, что размах её интервалов оказался завышенным. Она смогла только побить вторую модель (с переоценкой) по 97.5% квантилю, а так она показала себя достаточно плохо.</p>
<p>Что касается второй модели, нижняя граница её интервала оказалась достаточно точной, но вот верхняя оказалась совсем никудышной. Это всё из-за тренда, который тянет прогнозы вниз.</p>
<p>Стоит отдельно заметить, что с пинболами работать достаточно затруднительно, так как для точной оценки квантилей требуются большие выборки. Например, для того, чтобы получить более-менее адекватное представление о том, как себя проявил 97.5% квантильный прогноз, в нашем распоряжении должно быть как минимум 40 наблюдений, чтобы 39 из них лежали ниже границы (\(\frac{39}{40} = 0.975\)). На самом деле, с квантилями вообще тяжело работать, потому что их не всегда можно точно определить. Для напоминания, математически квантиль определяется так:<br />
\begin{equation} \label{quantile}<br />
P \left(y_t < q_{\alpha} \right) = \alpha ,
\end{equation}
что на человеческом языке означает "вероятность того, что значение окажется ниже определённого \(\alpha\)-квантиля равна \(\alpha\)". Продолжая наш пример, если в нашем распоряжении всего лишь 20 наблюдений, мы можем хоть с какой-то точностью определить только \(\frac{19}{20} = 0.95\) квантиль. Всё, что находится между 95% и 100% в этом случае - это серая зона.

Последнее, что хотелось бы сказать по поводу всех этих индексов, это то, что они измеряются в оригинальных единицах (например, литры пива). Поэтому их нельзя агрегировать для разных временных рядов. Для того, чтобы получить правильное представление о точности интервалов, нам нужно как-то избавиться от единиц измерения. Мы можем, например, всё масштабировать с помощью средней величины (как <a href="https://doi.org/10.1057/jors.2014.62" target="_blank" rel="noopener noreferrer">Petropoulos & Kourentzes (2015)</a>), либо на основе средних разностей (как <a href="https://doi.org/10.1016/j.ijforecast.2006.03.001" target="_blank" rel="noopener noreferrer">Hyndman & Koehler (2006)</a>), либо на основе относительных значений (как similar to <a href="https://doi.org/10.1016/j.ijforecast.2012.09.002" target="_blank" rel="noopener noreferrer">Davydenko & Fildes (2013)</a>).</p>
<h3>Эксперимент в R</h3>
<p>Для того, чтобы понять, как ведут себя все эти индексы, попробуем провести эксперимент на выборке из 1000 рядов, сгенерированных таким же образом, как и наш пример до того. Вот пример скрипта для R:</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>Кусок кода в R</div><div class="su-spoiler-content su-u-clearfix su-u-trim">
<pre class="decode">library(smooth)
# 4 models, 5 measures: MIS, Coverage, Range, Pinball L, Pinball U, 1000 iterations
errorMeasures <- array(NA, c(1000,4,5), dimnames=list(NULL, c("Model Underfit","Model Overfit","Model Correct","Model True"),
                                                      c("MIS","Range","Coverage","Lower","Upper")))

for(i in 1:1000){
    x <- sim.es("ANA", obs=120, frequency=12, persistence=c(0.3,0.1), initial=c(1000), mean=0, sd=100)
    
    modelUnderfit <- es(x$data, "ANN", silent=T, interval="p", holdout=T, h=24)
    modelOverfit <- es(x$data, "AAA", silent=T, interval="p", holdout=T, h=24)
    modelCorrect <- es(x$data, "ANA", silent=T, interval="p", holdout=T, h=24)
    modelTrue <- es(x, silent=T, interval=T, holdout=T, h=24)
    
    errorMeasures[i,,1] <- c(MIS(modelUnderfit$holdout,modelUnderfit$lower,modelUnderfit$upper,level=0.95),
                             MIS(modelOverfit$holdout,modelOverfit$lower,modelOverfit$upper,level=0.95),
                             MIS(modelCorrect$holdout,modelCorrect$lower,modelCorrect$upper,level=0.95),
                             MIS(modelTrue$holdout,modelTrue$lower,modelTrue$upper,level=0.95));
    
    errorMeasures[i,,2] <- c(mean(modelUnderfit$upper - modelUnderfit$lower),
                             mean(modelOverfit$upper - modelOverfit$lower),
                             mean(modelCorrect$upper - modelCorrect$lower),
                             mean(modelTrue$upper - modelTrue$lower));
    
    errorMeasures[i,,3] <- c(sum(modelUnderfit$holdout > modelUnderfit$lower & modelUnderfit$holdout < modelUnderfit$upper),
                             sum(modelOverfit$holdout > modelOverfit$lower & modelOverfit$holdout < modelOverfit$upper),
                             sum(modelCorrect$holdout > modelCorrect$lower & modelCorrect$holdout < modelCorrect$upper),
                             sum(modelTrue$holdout > modelTrue$lower & modelTrue$holdout < modelTrue$upper)) / length(modelUnderfit$holdout);
    
    errorMeasures[i,,4] <- c(pinball(modelUnderfit$holdout,modelUnderfit$lower,0.025),
                             pinball(modelOverfit$holdout,modelOverfit$lower,0.025),
                             pinball(modelCorrect$holdout,modelCorrect$lower,0.025),
                             pinball(modelTrue$holdout,modelTrue$lower,0.025));
    
    errorMeasures[i,,5] <- c(pinball(modelUnderfit$holdout,modelUnderfit$upper,0.975),
                             pinball(modelOverfit$holdout,modelOverfit$upper,0.975),
                             pinball(modelCorrect$holdout,modelCorrect$upper,0.975),
                             pinball(modelTrue$holdout,modelTrue$upper,0.975));
}</pre>
</div></div>
<p>Признаюсь, это не самый эффективный код, можно было бы его распараллелить, но посчитал, что для целей нашего эксперимента, можно и подождать минут десять.</p>
<p>Проблема, с которой мы теперь сталкиваемся, рассчитав все эти значения по выборке из 1000 рядов - это как раз единицы измерения. Простое решение - взять одну из моделей за эталон и рассчитать относительные индексы на основе неё. В качестве такой модели я возьму правильную модель 3 (обратите внимание, что покрытие, coverage, уже измеряется в относительных величинах, поэтому его ненужно модифицировать):</p>
<pre class="decode">errorMeasuresRelative <- errorMeasures
for(i in 1:4){
    errorMeasuresRelative[,i,c(1,2,4,5)] <- errorMeasures[,i,c(1,2,4,5)] / errorMeasures[,3,c(1,2,4,5)]
}</pre>
<p>Таким образом мы будем анализировать относительные размах, MIS и пинбол, которые можно аггрегировать как угодно, но лучше - с помощью средних геометрических:</p>
<pre class="decode">round(cbind(exp(apply(log(errorMeasuresRelative[,,-3]),c(2,3),mean)),
            apply(errorMeasuresRelative,c(2,3),mean)[,3,drop=FALSE]),3)</pre>
<pre>                 MIS Range Lower Upper Coverage
Model Underfit 2.091 2.251 2.122 2.133    0.958
Model Overfit  1.133 1.040 1.123 1.113    0.910
Model Correct  1.000 1.000 1.000 1.000    0.938
Model True     0.962 1.013 0.964 0.963    0.951</pre>
<p>Как видим, модель, которая недооценивает данные дала на 125.1% более широкие интервалы, чем правильная модель. У неё так же более высокие значения пинболов (на 112.2% и 113.3% выше соответственно), что означает, что она сильно промахнулась относительно 2.5% и 97.5% квантилей. Резюмируя, модель переоценила неопределённость из-за того, что в ней не оказалось необходимой сезонной компоненты. Однако, покрытие у неё оказалось очень близко к 95%, что говорит о том, что сам подход к построению интервалов оказался корректным.</p>
<p>Вторая модель, которая переоценила данные, обладает более широким размахом, чем правильная модель, но при этом покрывает меньше фактических наблюдений своими интервалами. В целом, хоть ситуация с этой моделью не такая критическая, как с первой, решения на основе её интервалов принимать не безопасно.</p>
<p>Истинная модель (последняя в таблице) произвела интервалы чуть шире, чем модель, оценённая по выборке, но при этом оказалась точнее в плане конкретных квантилей и покрыла 95.1% наблюдений, что практически неотличимо от номинального значения.</p>
<p>А что касается третьей модели, она оказалась лучше первых двух в плане MIS, размаха и пинбола, но при этом покрыла только 93.8% значений в выборке, что существенно ниже, чем 95%. Это всё из-за того, что мы оценивали параметры по выборке и того, как именно учитывается неопределённость в моделях ETS - подход <a href="https://www.springer.com/gp/book/9783540719168" rel="noopener noreferrer" target="_blank">Hyndman et al. (2008)</a> подразумевает, что параметры известны... Это одна из неизученных проблем в области ETS на данный момент.</p>
<p>Вообще же, могут быть и другие причины в том, почему правильная модель дала не самые точные интервалы, некоторые из которых мы уже <a href="/2017/06/11/prediction-intervals/">обсуждали в прошлом</a>. Но главная мысль данной статьи заключается в том, что, несмотря на то, как именно мы конструируем интервалы, несмотря на то, какие модели используем и как их выбираем, у нас есть специальные инструменты, которые могут позволить нам понять, насколько правильно мы смогли уловить неопределённость.</p>
<p>Сообщение <a href="https://openforecast.org/ru/2019/10/18/o-tom-kak-ocenit-adekvatnost-prognoznyh-intervalov/">О том, как оценить адекватность прогнозных интервалов</a> появились сначала на <a href="https://openforecast.org/ru">Open Forecasting</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://openforecast.org/ru/2019/10/18/o-tom-kak-ocenit-adekvatnost-prognoznyh-intervalov/feed/</wfw:commentRss>
			<slash:comments>4</slash:comments>
		
		
			</item>
		<item>
		<title>Как измерить точность прогнозов</title>
		<link>https://openforecast.org/ru/2019/08/25/kak-izmerit-tochnost-prognozov/</link>
					<comments>https://openforecast.org/ru/2019/08/25/kak-izmerit-tochnost-prognozov/#respond</comments>
		
		<dc:creator><![CDATA[Ivan Svetunkov]]></dc:creator>
		<pubDate>Sun, 25 Aug 2019 17:59:40 +0000</pubDate>
				<category><![CDATA[R]]></category>
		<category><![CDATA[Оценка точности прогнозов]]></category>
		<category><![CDATA[Теория прогнозирования]]></category>
		<category><![CDATA[Прогнозные ошибки]]></category>
		<category><![CDATA[теория]]></category>
		<guid isPermaLink="false">https://openforecast.org/?p=2070</guid>

					<description><![CDATA[<p>Два года назад я написал статью на английском языке про прогнозные ошибки и о том, как можно и как ненужно измерять точность прогнозов. Переводить на русский я её не стал из-за нехватки времени и дублирования частей статьи вот этим постом на русскоязычной версии сайта. Но прошло время, моё понимание проблемы немного изменилось, и я решил [&#8230;]</p>
<p>Сообщение <a href="https://openforecast.org/ru/2019/08/25/kak-izmerit-tochnost-prognozov/">Как измерить точность прогнозов</a> появились сначала на <a href="https://openforecast.org/ru">Open Forecasting</a>.</p>
]]></description>
										<content:encoded><![CDATA[<p>Два года назад я написал <a href="/en/2017/07/29/naughty-apes-and-the-quest-for-the-holy-grail/">статью на английском языке</a> про прогнозные ошибки и о том, как можно и как ненужно измерять точность прогнозов. Переводить на русский я её не стал из-за нехватки времени и дублирования частей статьи <a href="/etextbook/forecasting_toolbox/models_quality/">вот этим постом</a> на русскоязычной версии сайта. Но прошло время, моё понимание проблемы немного изменилось, и я решил написать продолжение статьи. В этот раз я решил перевести продолжение, так как в нём, как мне кажется, есть полезная информация.</p>
<h3>Введение</h3>
<p>Начнём с того, что в статистике есть понимание, что <a href="/etextbook/forecasting_toolbox/models_quality/">MSE</a> минимизируется средней величиной, в то время как <a href="/etextbook/forecasting_toolbox/models_quality/">MAE</a> минимизируется медианой. В сети Интернет можно найти много статей на эту тему. Вот, например, <a href="http://dx.doi.org/10.1080/00031305.1990.10475690" rel="noopener noreferrer" target="_blank">первая</a>, <a href="https://doi.org/10.1016/j.ijforecast.2015.12.004" rel="noopener noreferrer" target="_blank">вторая</a> и <a href="https://math.stackexchange.com/questions/2554243/understanding-the-mean-minimizes-the-mean-squared-error/2554276" rel="noopener noreferrer" target="_blank">третья</a>. Они на английском, но по-разному так или иначе объясняют эту идею. Но в связи с этим среди прогнозистов и статистиков иногда возникает недопонимание того, что можно делать, измеряя точность моделей, а чего нельзя.</p>
<p>Во-первых, некоторые аналитики считают, что подобное соотношение применимо только при оценке моделей. По какой-то причине они считают, что оценка точности на проверочной выборке разительно отличается от процесса построения модели. Однако при выборе модели на основе некой ошибки, мы так или иначе накладываем условия на сами прогнозы. Если один метод гарантирует меньшую MAE, чем другой на проверочной выборке, то это означает что его прогноз ближе к медиане данных.</p>
<p>Для того, чтобы лучше понять эту идею, возьмём пример с нулевым прогнозом. В случае с прерывистым спросом (когда спрос происходит не предсказуемо) нулевой прогноз будет наилучшим в соответствии с MAE, особенно, если нулей в данных больше 50%. Причина этого эффекта проста: если ваши данные содержат большое количество нулей, то самый простой и безопасный прогноз &#8212; это сказать, что мы ничего в будущем не продадим. Полезность такого прогноза сомнительна, но он будет достаточно точным. Именно поэтому <strong>ошибки на основе MAE нельзя использовать на данных прерывистого спроса</strong>.</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>Не до конца понятно? Давайте объясню...</div><div class="su-spoiler-content su-u-clearfix su-u-trim">
Проясним эту идею на примере, используя R. Мы сгенерируем ряд данных из смеси нормального распределения и распределения Бернулли (с вероятностью \(p=0.4\)):</p>
<pre class="decode">x <- rnorm(150,30,10) * rbinom(150, 1, 0.4)</pre>
<p>Ряд будет выглядеть примерно так:</p>
<pre class="decode">plot.ts(x)</pre>
<div id="attachment_2169" style="width: 310px" class="wp-caption aligncenter"><a href="https://openforecast.org/wp-content/webpc-passthru.php?src=https://openforecast.org/wp-content/uploads/2019/08/MAE-MSE-IntermittentExample.png&amp;nocache=1"><img loading="lazy" decoding="async" aria-describedby="caption-attachment-2169" src="https://openforecast.org/wp-content/webpc-passthru.php?src=https://openforecast.org/wp-content/uploads/2019/08/MAE-MSE-IntermittentExample-300x175.png&amp;nocache=1" alt="" width="300" height="175" class="size-medium wp-image-2169" srcset="https://openforecast.org/wp-content/webpc-passthru.php?src=https://openforecast.org/wp-content/uploads/2019/08/MAE-MSE-IntermittentExample-300x175.png&amp;nocache=1 300w, https://openforecast.org/wp-content/webpc-passthru.php?src=https://openforecast.org/wp-content/uploads/2019/08/MAE-MSE-IntermittentExample-768x448.png&amp;nocache=1 768w, https://openforecast.org/wp-content/webpc-passthru.php?src=https://openforecast.org/wp-content/uploads/2019/08/MAE-MSE-IntermittentExample-1024x597.png&amp;nocache=1 1024w, https://openforecast.org/wp-content/webpc-passthru.php?src=https://openforecast.org/wp-content/uploads/2019/08/MAE-MSE-IntermittentExample.png&amp;nocache=1 1200w" sizes="auto, (max-width: 300px) 100vw, 300px" /></a><p id="caption-attachment-2169" class="wp-caption-text">Пример условного ряда</p></div>
<p>Далее мы используем 100 наблюдений для построения прогнозов и 50 для сравнения их точности. Будем использовать два метода прогнозирования: простую среднюю по обучающей выборке и нулевой прогноз (который в нашем случае соответствует медиане). Они выглядят примерно так:</p>
<pre class="decode">plot.ts(x)
abline(h=mean(x[1:100]),col="blue", lwd=2)
abline(h=0,col="purple", lwd=2)
abline(v=100, col="red", lwd=2)</pre>
<div id="attachment_2170" style="width: 310px" class="wp-caption aligncenter"><a href="https://openforecast.org/wp-content/webpc-passthru.php?src=https://openforecast.org/wp-content/uploads/2019/08/MAE-MSE-IntermittentExampleForecast.png&amp;nocache=1"><img loading="lazy" decoding="async" aria-describedby="caption-attachment-2170" src="https://openforecast.org/wp-content/webpc-passthru.php?src=https://openforecast.org/wp-content/uploads/2019/08/MAE-MSE-IntermittentExampleForecast-300x175.png&amp;nocache=1" alt="" width="300" height="175" class="size-medium wp-image-2170" srcset="https://openforecast.org/wp-content/webpc-passthru.php?src=https://openforecast.org/wp-content/uploads/2019/08/MAE-MSE-IntermittentExampleForecast-300x175.png&amp;nocache=1 300w, https://openforecast.org/wp-content/webpc-passthru.php?src=https://openforecast.org/wp-content/uploads/2019/08/MAE-MSE-IntermittentExampleForecast-768x448.png&amp;nocache=1 768w, https://openforecast.org/wp-content/webpc-passthru.php?src=https://openforecast.org/wp-content/uploads/2019/08/MAE-MSE-IntermittentExampleForecast-1024x597.png&amp;nocache=1 1024w, https://openforecast.org/wp-content/webpc-passthru.php?src=https://openforecast.org/wp-content/uploads/2019/08/MAE-MSE-IntermittentExampleForecast.png&amp;nocache=1 1200w" sizes="auto, (max-width: 300px) 100vw, 300px" /></a><p id="caption-attachment-2170" class="wp-caption-text">Пример условного ряда и прогнозов по двум методам: синяя линия - простая средняя, фиолетовая линия - нулевой прогноз. Красная линия делит выборку на обучающую и проверочную части</p></div>
<p>Очевидно, что средняя дала более адекватный прогноз, чем метод с нулями. По крайней мере, точечный прогноз проходит более-менее в середине ряда и на основе него можно принимать какие-то решения (например, что в среднем мы продадим около 12 единиц в день). Нулевой же прогноз не несёт никакой ценности, так как мы даже не можем сказать, стоит ли продолжать продажи продукта. Что же нам скажут наши ошибки?</p>
<pre class="decode">errorMeasures <- matrix(c(mean(abs(x&#091;101:150&#093; - mean(x&#091;1:100&#093;))),
                          mean(abs(x&#091;101:150&#093; - 0)),
                          mean((x&#091;101:150&#093; - mean(x&#091;1:100&#093;))^2),
                          mean((x&#091;101:150&#093; - 0)^2)),
                        2,2,dimnames=list(c("Average","Zero"),c("MAE","MSE")))
errorMeasures</pre>
<pre>        MAE     MSE
Average 15.4360 264.9922
Zero    12.3995 418.4934</pre>
<p>Как видим, MAE рекомендует использовать нулевой прогноз (ошибка составила 12.3995 против 15.4360 в случае со средней), в то время как MSE рекомендует среднюю (264.9922 против 418.4934). Это простая иллюстрация тезиса, высказанного выше про средние и медианы.</div></div>
<p>Во-вторых, некоторые исследователи считают, что если модель оценена путём минимизации, например, MSE, то она может быть оценена только с помощью соответствующих ошибок на основе MSE. Это не совсем так. Да, скорее всего, ваша модель лучше себя покажет в том случае, если целевая функция при оценке соответствует целевой функции при тестировании модели на отдельной выборке (например, MSE и там, и там). Но это не означает, что мы не можем использовать ошибки на основе других функций. Выбор метрики должен быть мотивирован конкретными задачами (для чего мы делаем прогноз), а не тем, как мы оценивали модель. В идеале ваше конкретное управленческое решение должно быть согласовано с выбранной ошибкой. Например, при управлении запасами нам может быть важно знать, насколько модель позволяет точно сформировать страховой запас. В этом случае нам вообще могут быть нужны не ошибки на основе MAE или MSE, а более продвинутые эксперименты с симуляцией спроса.</p>
<p>В качестве промежуточных выводов отметим, что ошибки на основе MSE должны использоваться тогда, когда нам требуется идентифицировать метод, дающий наиболее точный средний прогноз, в то время, как ошибки на основе MAE должны использоваться для оценки медианы, вне зависимости от того, как модель была оценена.</p>
<p>Один из вопросов, который может возникнуть по прочтении всего этого: что же минимизируют <a href="/etextbook/forecasting_toolbox/models_quality/">MAPE и SMAPE</a>? Стефан Коласса и Мартин Роланд (<a href="https://foresight.forecasters.org/product/foresight-issue-23/" rel="noopener noreferrer" target="_blank">Stephan Kolassa and Martin Roland, 2011</a>) показали на простом примере, что минимум MAPE достигается смещённым прогнозом, а сам Стефан в своей статье (<a href="https://doi.org/10.1016/j.ijforecast.2015.12.004" rel="noopener noreferrer" target="_blank">Stephan Kolassa, 2016</a>) обратил внимание на то, что в случае с лог нормальным распределением случайной величины MAPE минимизируется модой. Однако до сих пор совершенно непонятно, что происходит в случае с SMAPE. Это ещё одна причина, по которой SMAPE лучше не использовать (остальные обсуждались в <a href="/etextbook/forecasting_toolbox/models_quality/">соответствующей статье</a>).</p>
<p>Мы уже знакомы с <a href="/etextbook/forecasting_toolbox/models_quality/">некоторыми видами ошибок</a>, поэтому здесь мы рассмотрим только масштабированную и относительную ошибки ("scaled" и "relative" соответственно).</p>
<h3>Масштабированные ошибки</h3>
<p>Эти ошибки могут быть достаточно информативными при сравнении моделей. Например, sMAE и sMSE (<a href="https://doi.org/10.1057/jors.2014.62" rel="noopener noreferrer" target="_blank">Petropoulos & Kourentzes, 2015</a>):<br />
\begin{equation} \label{eq:sMAE}<br />
	\text{sMAE} = \frac{\text{MAE}}{\bar{y}},<br />
\end{equation}<br />
\begin{equation} \label{eq:sMSE}<br />
	\text{sMSE} = \frac{\text{MSE}}{\bar{y}^2},<br />
\end{equation}<br />
где \(\bar{y}\) - это простая средняя по обучающей выборке. У этих ошибок достаточно простая интерпретация, сходная с MAPE: они показывают средний процент отклонения по отношению к средней величине по ряду данных. Преимуществом этих ошибок является то, что они одинаково относятся к ситуациям, когда фактические значения оказались выше или ниже прогноза. Однако они привязаны к уровню ряда, поэтому в случае с нестационарными рядами могут давать противоречивые результаты. Например, в случае с рядом на графике внизу слева ошибки будут достаточно информативными, так как средняя по ряду не будет сильно меняться, однако в случае с рядом на втором графике, средняя будет меняться, поэтому и значение ошибки может изменяться только из-за этого.</p>
<div id="attachment_2051" style="width: 310px" class="wp-caption aligncenter"><a href="https://openforecast.org/wp-content/webpc-passthru.php?src=https://openforecast.org/wp-content/uploads/2019/08/MeasuresTSExample.png&amp;nocache=1"><img loading="lazy" decoding="async" aria-describedby="caption-attachment-2051" src="https://openforecast.org/wp-content/webpc-passthru.php?src=https://openforecast.org/wp-content/uploads/2019/08/MeasuresTSExample-300x175.png&amp;nocache=1" alt="" width="300" height="175" class="size-medium wp-image-2051" srcset="https://openforecast.org/wp-content/webpc-passthru.php?src=https://openforecast.org/wp-content/uploads/2019/08/MeasuresTSExample-300x175.png&amp;nocache=1 300w, https://openforecast.org/wp-content/webpc-passthru.php?src=https://openforecast.org/wp-content/uploads/2019/08/MeasuresTSExample-768x448.png&amp;nocache=1 768w, https://openforecast.org/wp-content/webpc-passthru.php?src=https://openforecast.org/wp-content/uploads/2019/08/MeasuresTSExample-1024x597.png&amp;nocache=1 1024w, https://openforecast.org/wp-content/webpc-passthru.php?src=https://openforecast.org/wp-content/uploads/2019/08/MeasuresTSExample.png&amp;nocache=1 1200w" sizes="auto, (max-width: 300px) 100vw, 300px" /></a><p id="caption-attachment-2051" class="wp-caption-text">Пример двух рядов данных</p></div>
<p><a href="https://doi.org/10.1016/j.ijforecast.2006.03.001" rel="noopener noreferrer" target="_blank">Rob Hyndman и Anne Koehler (2006)</a> предложили MASE, ошибку у которой нет такой проблемы благодаря использованию первых разностей в знаменателе:<br />
\begin{equation} \label{eq:MASE}<br />
	\text{MASE} = \frac{\text{MAE}}{\frac{1}{T-1}\sum_{t=2}^{T}|y_t -y_{t-1}|}.<br />
\end{equation}<br />
Идея в этом случае достаточно простая: если ряд нестационарный, можно взять его разности, которые (скорее всего) будут стационарны. Поэтому знаменатель формулы получается более-менее фиксированным, что решает обозначенную выше проблему.</p>
<p>К сожалению, у MASE другая проблема - её очень сложно интерпретировать. Если, например, она равна 1.3, то это ничего не значит. Да, знаменатель \eqref{eq:MASE} можно интерпретировать как среднюю абсолютную одношаговую ошибку метода Naive на обучающей выборке, но это нисколько не помогает в интерпретации. Это ошибка может использоваться для исследовательских целей, но мне сложно представить её использование на практике.</p>
<p>Ну, и не стоит забывать о "MAE минимизируется медианами", что в очередной раз говорит нам о том, что ни MASE, ни sMAE не следует использовать в случае с прерывистым спросом.</p>
<h3>Относительные ошибки</h3>
<p>Что касается относительных ошибок, то они достаточно просты в работе и интерпретации. Всё, что нужно - это посчитать MAE или RMSE, или что бы то ни было ещё нескольких методов по рядам, затем разделить эти значения для каждого ряда на ошибки метода-бенчмарка. Считаются они по следующим формулам:<br />
\begin{equation} \label{eq:rMAE}<br />
	\text{rMAE} = \frac{\text{MAE}_a}{\text{MAE}_b},<br />
\end{equation}<br />
\begin{equation} \label{eq:rRMSE}<br />
	\text{rRMSE} = \frac{\text{RMSE}_a}{\text{RMSE}_b},<br />
\end{equation}<br />
где в числителе ошибки интересующего нас метода, а в знаменателе - ошибки бенчмарка. Зачастую в качестве метода "b" выступает метод Naive, который очень легко применить к данным. Учитывая то, что как числитель, так и знаменатель рассчитаны по одному и тому же ряду, по одной и той же его части, мы обходим проблемы с меняющимся уровнем ряда и масштабирования. К тому же, у этих ошибок простая интерпретация: если она больше 1, то наш метод оказался менее точным, чем бенчмарк, если же она меньше 1, то прогноз по нашему методу оказался точней прогноза бенчмарка. Кроме того, относительные ошибки хорошо согласуются с идеей "ценности прогноза" (Forecast Value), <a href="https://www.wiley.com/en-gb/The+Business+Forecasting+Deal:+Exposing+Myths,+Eliminating+Bad+Practices,+Providing+Practical+Solutions-p-9780470574430" rel="noopener noreferrer" target="_blank">разработанной</a> <a href="https://blogs.sas.com/content/author/mikegilliland/" rel="noopener noreferrer" target="_blank">Майком Гиллиландом из SAS</a>, которую можно, например, рассчитать так:<br />
\begin{equation} \label{eq:FV}<br />
	\text{FV} = 1-\text{rMAE} \cdot 100\%.<br />
\end{equation}<br />
Так что, например, rMAE = 0.96 означает, что наш метод увеличивает точность прогнозов на 4% по сравнению с бенчмарком (с точки зрения MAE).</p>
<p>Ну, и как заметили <a href="https://doi.org/10.1016/j.ijforecast.2012.09.002" rel="noopener noreferrer" target="_blank">Davydenko и Fildes (2013)</a>, если вы хотите получить агрегированную величину rMAE, то имеет смысл использовать геометрическую среднюю, а не арифметическую, так как мы имеем дело с отношением, а не с вычитанием. Кроме того, геометрическая средняя более робастна, чем арифметическая.</p>
<p>Главная же проблема относительных ошибок заключается в том, что если для какого-то ряда либо числитель, либо знаменатель оказывается равен нулю, то рассчитать агрегированную величину не удастся. Впрочем, это не так страшно, потому что мы всегда можем провести анализ распределения ошибок, не обязательно опираться только на одно число. К тому же, мы не часто встречаем эту проблему в реальности. Такое может наблюдаться, например, в случае с прерывистым спросом, когда в тестовой выборке сплошные нули, и Naive дал нулевой прогноз. Однако в случае с прерывистым спросом лучше не использовать Naive - он не информативен, простая средняя по ряду даст более полезную информацию. В любом случае, если вы столкнулись с подобной ситуацией, то имеет смысл просто исключить из рассмотрения ряды, в которых это произошло, потому что ситуация, в которой метод даёт прогноз с нулевой ошибкой означает, что вам ненужно строить прогноз по этому ряду.</p>
<p>Резюмируя всё вышенаписанное, я бы рекомендовал использовать относительные ошибки, держа в голове идею о том, что MAE минимизируется медианами, а MSE минимизируется средними. А для того, чтобы решить, что именно выбрать из этих двух, стоит задаться вопросом: что именно нам нужно измерить? В некоторых случаях может оказаться, что вам не интересны ни медиана, ни средняя, а вас интересуют квантили и верхняя граница прогнозного интервала... Но это уже совсем другая история.</p>
<h3>Примеры в R</h3>
<p>Для того, чтобы посмотреть, как можно работать с ошибками, мы рассмотрим простой пример с пакетом <span class="lang:r decode:true crayon-inline">smooth</span> v2.5.3 и несколькими рядами из базы M3.</p>
<p>Загрузим необходимые пакеты:</p>
<pre class="decode">library(smooth)
library(Mcomp)</pre>
<p>Возьмём подвыборку месячных рядов демографических данных (это всего 111 рядов - должно быть достаточно для примера):</p>
<pre class="decode">M3Subset <- subset(M3, 12, "demographic")</pre>
<p>Создадим массив для двух ошибок: rMAE и rRMSE (они будут рассчитаны на основе функции <span class="lang:r decode:true crayon-inline">measures()</span> из пакета <span class="lang:r decode:true crayon-inline">greybox</span>). Мы попробуем применить три модели: <a href="https://doi.org/10.13140/RG.2.1.3757.2562" rel="noopener noreferrer" target="_blank">CES</a>, <a href="/2017/01/24/smooth-package-for-r-es-function-part-iv-model-selection-and-combination-of-forecasts-2/">ETS</a> с автоматическим выбором среди 30 моделей и ETS с выбором среди моделей с не мультипликативным трендом:</p>
<pre class="decode">errorMeasures <- array(NA, c(length(M3Subset),2,3),
                       dimnames=list(NULL, c("rMAE","rRMSE"),
                                     c("CES","ETS(Z,Z,Z)","ETS(Z,X,Z)")))</pre>
<p>Проведём расчёты в цикле, записывая значения ошибок. По умолчанию, в качестве бенчмарка в rMAE и rRMSE используется метод Naive.</p>
<pre class="decode">for(i in 1:length(M3Subset)){
    errorMeasures[i,,1] <- auto.ces(M3Subset[[i]])$accuracy[c("rMAE","rRMSE")]
    errorMeasures[i,,2] <- es(M3Subset[[i]])$accuracy[c("rMAE","rRMSE")]
    errorMeasures[i,,3] <- es(M3Subset[[i]],"ZXZ")$accuracy[c("rMAE","rRMSE")]
    cat(i); cat(", ")
}</pre>
<p>И проанализируем результаты. Начнём с ArMAE и ArRMSE:</p>
<pre class="decode">exp(apply(log(errorMeasures),c(2,3),mean))</pre>
<pre>      CES        ETS(Z,Z,Z) ETS(Z,X,Z)
rMAE  0.6339194  0.8798265  0.8540869
rRMSE 0.6430326  0.8843838  0.8584140</pre>
<p>Как видим, все модели в среднем показали себя лучше, чем Naive: ETS примерно на 12 - 16% лучше, чем Naive, а CES лучше более чем на 35%. Кроме того, CES оказалась точнее, чем оба варианта ETS как по rMAE, так и по rRMSE. Разница выглядит достаточно ощутимой. Но для более чёткого понимания ситуации, мы можем сменить бенчмарк в ошибках на ETS(Z,Z,Z):</p>
<pre class="decode">errorMeasuresZZZ <- errorMeasures
for(i in 1:3){
    errorMeasuresZZZ[,,i] <- errorMeasuresZZZ[,,i] / errorMeasures[,,"ETS(Z,Z,Z)"]
}

exp(apply(log(errorMeasuresZZZ),c(2,3),mean))</pre>
<pre>      CES        ETS(Z,Z,Z) ETS(Z,X,Z)
rMAE  0.7205050          1  0.9707448
rRMSE 0.7270968          1  0.9706352</pre>
<p>В этом случае мы можем сказать, что CES оказалась примерно на 28% точнее, чем ETS(Z,Z,Z). Кроме того, исключение мультипликативного тренда из рассмотрения повышает точность прогнозов примерно на 3% как для MAE, так и для RMSE.</p>
<p>Как я и писал ранее, мы можем не ограничиваться просто значениями, мы можем проанализировать распределение ошибок, что может дать нам дополнительную информацию о наших моделях. Самый простой вариант анализа - это <a href="/etextbook/forecasting_toolbox/data-analysis/">боксплот</a>:</p>
<pre class="decode">boxplot(errorMeasures[,1,])
abline(h=1, col="grey", lwd=2)
points(exp(apply(log(errorMeasures[,1,]),2,mean)),col="red",pch=16)</pre>
<div id="attachment_2100" style="width: 310px" class="wp-caption aligncenter"><a href="https://openforecast.org/wp-content/webpc-passthru.php?src=https://openforecast.org/wp-content/uploads/2019/08/M3rMAEBoxplot.png&amp;nocache=1"><img loading="lazy" decoding="async" aria-describedby="caption-attachment-2100" src="https://openforecast.org/wp-content/webpc-passthru.php?src=https://openforecast.org/wp-content/uploads/2019/08/M3rMAEBoxplot-300x175.png&amp;nocache=1" alt="" width="300" height="175" class="size-medium wp-image-2100" srcset="https://openforecast.org/wp-content/webpc-passthru.php?src=https://openforecast.org/wp-content/uploads/2019/08/M3rMAEBoxplot-300x175.png&amp;nocache=1 300w, https://openforecast.org/wp-content/webpc-passthru.php?src=https://openforecast.org/wp-content/uploads/2019/08/M3rMAEBoxplot-768x448.png&amp;nocache=1 768w, https://openforecast.org/wp-content/webpc-passthru.php?src=https://openforecast.org/wp-content/uploads/2019/08/M3rMAEBoxplot-1024x597.png&amp;nocache=1 1024w, https://openforecast.org/wp-content/webpc-passthru.php?src=https://openforecast.org/wp-content/uploads/2019/08/M3rMAEBoxplot.png&amp;nocache=1 1200w" sizes="auto, (max-width: 300px) 100vw, 300px" /></a><p id="caption-attachment-2100" class="wp-caption-text">Boxplot of rMAE for a subset of time series from the M3</p></div>
<p>Учитывая то, что распределение ошибок не симметрично, проанализировать его оказывается иногда затруднительно. Тем не менее, мы можем заметить, что ящичковая диаграмма для CES расположена ниже диаграмм других моделей, что указывает на то, что CES оказывается точнее других моделей в подавляющем числе случаев. Серая горизонтальная линия на графике соответствует единице, то есть нашему бенчмарку, Naive. Как видим, в среднем модели оказались точнее, чем бенчмарк, хотя в некоторых случаях они себя проявили хуже (части ящичков лежат над прямой линией).</p>
<p>В некоторых случаях боксплот в логарифмах может дать более детальную информацию:</p>
<pre class="decode">boxplot(log(errorMeasures[,1,]))
abline(h=0, col="grey", lwd=2)
points(apply(log(errorMeasures[,1,]),2,mean),col="red",pch=16)</pre>
<div id="attachment_2101" style="width: 310px" class="wp-caption aligncenter"><a href="https://openforecast.org/wp-content/webpc-passthru.php?src=https://openforecast.org/wp-content/uploads/2019/08/M3rMAEBoxplotLog.png&amp;nocache=1"><img loading="lazy" decoding="async" aria-describedby="caption-attachment-2101" src="https://openforecast.org/wp-content/webpc-passthru.php?src=https://openforecast.org/wp-content/uploads/2019/08/M3rMAEBoxplotLog-300x175.png&amp;nocache=1" alt="" width="300" height="175" class="size-medium wp-image-2101" srcset="https://openforecast.org/wp-content/webpc-passthru.php?src=https://openforecast.org/wp-content/uploads/2019/08/M3rMAEBoxplotLog-300x175.png&amp;nocache=1 300w, https://openforecast.org/wp-content/webpc-passthru.php?src=https://openforecast.org/wp-content/uploads/2019/08/M3rMAEBoxplotLog-768x448.png&amp;nocache=1 768w, https://openforecast.org/wp-content/webpc-passthru.php?src=https://openforecast.org/wp-content/uploads/2019/08/M3rMAEBoxplotLog-1024x597.png&amp;nocache=1 1024w, https://openforecast.org/wp-content/webpc-passthru.php?src=https://openforecast.org/wp-content/uploads/2019/08/M3rMAEBoxplotLog.png&amp;nocache=1 1200w" sizes="auto, (max-width: 300px) 100vw, 300px" /></a><p id="caption-attachment-2101" class="wp-caption-text">Boxplot of rMAE in logarithms for a subset of time series from the M3</p></div>
<p>Серая горизонтальная линия на графике опять соответствует Naive, но на этот раз в логарифмах (log(1)=0). В нашем случае эта диаграмма не привносит дополнительной информации, но в других случаях она может помочь в читаемости графика, так как логарифмирование может убрать влияние выбросом. Единственное, что обращает на себя внимание - это то, что первый, второй и третий квартели CES оказались ниже соответствующих квартилей ETS, но при этом есть ряд случаев, где CES оказалась менее точной (верхний ус и выбросы).</p>
<p>Существуют и другие методы анализа распределений, посмотрите, например, на то, как можно провести <a href="/etextbook/forecasting_toolbox/data-analysis/">графический</a> или <a href="/etextbook/forecasting_toolbox/data-analysis-stat/">статистический</a> анализ случайных величин. Можно так же провести какой-нибудь <a href="/etextbook/forecasting_toolbox/statistics-and-hypothesis/">статистический тест</a> (например, Nemenyi), для того, чтобы выяснить, значимы ли отличия между методами статистически. Однако всё это - материалы для будущих статей.</p>
<p>Сообщение <a href="https://openforecast.org/ru/2019/08/25/kak-izmerit-tochnost-prognozov/">Как измерить точность прогнозов</a> появились сначала на <a href="https://openforecast.org/ru">Open Forecasting</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://openforecast.org/ru/2019/08/25/kak-izmerit-tochnost-prognozov/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>useR!2019, Тулуза, Франция</title>
		<link>https://openforecast.org/ru/2019/07/11/user-2019-tuluza-franciya/</link>
					<comments>https://openforecast.org/ru/2019/07/11/user-2019-tuluza-franciya/#respond</comments>
		
		<dc:creator><![CDATA[Ivan Svetunkov]]></dc:creator>
		<pubDate>Thu, 11 Jul 2019 19:25:36 +0000</pubDate>
				<category><![CDATA[R]]></category>
		<category><![CDATA[smooth]]></category>
		<category><![CDATA[презентация]]></category>
		<guid isPermaLink="false">https://openforecast.org/?p=2190</guid>

					<description><![CDATA[<p>Salut mes amis! Сегодня я презентовал свой пакет для R smooth на конференции useR!2019 в Тулузе, Франция. Это достаточно любопытная конференция, посвящённая решению конкретных проблем. Люди здесь скорее презентуют конкретные функции из своих пакетов, нежели модели, которые лежат в их основе (как, например, на ISF). С одной стороны, у такого формата есть свои ограничения, но [&#8230;]</p>
<p>Сообщение <a href="https://openforecast.org/ru/2019/07/11/user-2019-tuluza-franciya/">useR!2019, Тулуза, Франция</a> появились сначала на <a href="https://openforecast.org/ru">Open Forecasting</a>.</p>
]]></description>
										<content:encoded><![CDATA[<p>Salut mes amis!</p>
<p>Сегодня я презентовал свой пакет для R <span class="lang:r decode:true crayon-inline">smooth</span> на конференции useR!2019 в Тулузе, Франция. Это достаточно любопытная конференция, посвящённая решению конкретных проблем. Люди здесь скорее презентуют конкретные функции из своих пакетов, нежели модели, которые лежат в их основе (как, например, на <a href="/tag/isf/">ISF</a>). С одной стороны, у такого формата есть свои ограничения, но с другой, это не так плохо, потому что, посещая конференцию можно узнать о том, какие решения существуют для вашей конкретной проблемы. Например, теперь я знаю, какие пакеты можно использовать для определения аномалий.</p>
<p>Моя презентация, кажется, прошла неплохо, хотя я и не чувствовал себя расковано из-за того, что меня приковали к микрофону и стойке с компьютером. Мою свободу ограничили, гады! :). Конечно, это было необходимо для того, чтобы записать видео презентации, но я бы предпочёл свободно бегать по аудитории и танцевать&#8230;</p>
<p>Слайды презентации можно скачать <a href="/wp-content/uploads/2019/07/2019-Svetunkov-smooth-useR.pdf">отсюда</a>.</p>
<p>ОБНОВЛЕНИЕ: Видео презентации теперь доступно на канале YouTube <a href="https://www.youtube.com/channel/UC_R5smHVXRYGhZYDJsnXTwg" rel="noopener noreferrer" target="_blank">R Consortium</a>:<br />
<iframe loading="lazy" width="560" height="315" src="https://www.youtube.com/embed/lPqofwegy2g" frameborder="0" allow="accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe></p>
<p>Сообщение <a href="https://openforecast.org/ru/2019/07/11/user-2019-tuluza-franciya/">useR!2019, Тулуза, Франция</a> появились сначала на <a href="https://openforecast.org/ru">Open Forecasting</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://openforecast.org/ru/2019/07/11/user-2019-tuluza-franciya/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Пакет «smooth» для R. Прерывистый спрос. Часть 1. Введение</title>
		<link>https://openforecast.org/ru/2018/09/18/intermittent-state-space-intro/</link>
					<comments>https://openforecast.org/ru/2018/09/18/intermittent-state-space-intro/#respond</comments>
		
		<dc:creator><![CDATA[Ivan Svetunkov]]></dc:creator>
		<pubDate>Tue, 18 Sep 2018 20:52:14 +0000</pubDate>
				<category><![CDATA[R]]></category>
		<category><![CDATA[О функции es()]]></category>
		<category><![CDATA[Пакет smooth для R]]></category>
		<category><![CDATA[Экстраполяционные методы]]></category>
		<category><![CDATA[smooth]]></category>
		<category><![CDATA[прерывистый спрос]]></category>
		<guid isPermaLink="false">https://openforecast.org/?p=1867</guid>

					<description><![CDATA[<p>ОБНОВЛЕНИЕ: Начиная с версии smooth v 2.5.0, модели и соответствующие функции были изменены. Теперь вместо intermittent и iss() в пакете существуют occurrence и oes(). Пожалуйста, используйте новые функции и новые параметры. Старый функционал будет удален в следующей версии пакета. Этот статья была обновлена 25 апреля 2019 года. Одно из преимуществ функций пакета smooth заключается во [&#8230;]</p>
<p>Сообщение <a href="https://openforecast.org/ru/2018/09/18/intermittent-state-space-intro/">Пакет «smooth» для R. Прерывистый спрос. Часть 1. Введение</a> появились сначала на <a href="https://openforecast.org/ru">Open Forecasting</a>.</p>
]]></description>
										<content:encoded><![CDATA[<p><strong>ОБНОВЛЕНИЕ</strong>: Начиная с версии smooth v 2.5.0, модели и соответствующие функции были изменены. Теперь вместо <span class="lang:r decode:true crayon-inline">intermittent</span> и <span class="lang:r decode:true crayon-inline">iss()</span> в пакете существуют <span class="lang:r decode:true crayon-inline">occurrence</span> и <span class="lang:r decode:true crayon-inline">oes()</span>. Пожалуйста, используйте новые функции и новые параметры. Старый функционал будет удален в следующей версии пакета. Этот статья была обновлена 25 апреля 2019 года.</p>
<p>Одно из преимуществ функций пакета <span class="lang:r decode:true crayon-inline">smooth</span> заключается во встроенной возможности работать с прерывистыми данными и с данными с периодически возникающими нулями.</p>
<p>Прерывистый спрос &#8212; это такой спрос на продукцию, который происходит нерегулярно (<a href="/en/2017/11/07/multiplicative-state-space-models-for-intermittent-time-series/">Svetuknov and Boylan, 2017</a>). Например, продажи зелёной губной помады имеют такой характер: её редко, кто покупает, но это всё-таки происходит время от времени. Данные по продажам такой продукции будут содержать много нулей, и предсказать, когда именно произойдёт продажа такого товара &#8212; крайне затруднительно. Может показаться, что я беру в пример какой-то экзотический товар, а значит и проблема прерывистого спроса надумана. Но вообще-то это не так. Если обратиться к тому, что происходит сейчас в сфере ритейла, то на себя обращает внимание увеличение частоты измерений данных. Раньше была возможность только сохранять количество проданных каких-нибудь хлопьев в неделю, сейчас же можно измерять продажи хоть раз в минуту (можно и чаще, но надо ли?). А как предсказать, когда купят хлопья в магазине, когда данные измеряются в такой частоте? В общем, проблема есть, и она вполне реальна.</p>
<p>Другая типичная проблема &#8212; это продукты, продающиеся сезонно. Например, продажи арбузов летом будут носить вполне себе непрерывный характер, а вот в остальное время года &#8212; не факт: в какие-то сезоны их не будет физически (естественные нули), а в другие спрос на них будет нестабилен.</p>
<p>В общем, со всеми этими интересными особенностями как раз и призваны справиться функции пакета <span class="lang:r decode:true crayon-inline">smooth</span>. Для этого в нём реализованы так называемые модели со смешанными распределениями.</p>
<p>В данной статье мы обсудим самую простую, можно сказать, базовую модель, реализованную в пакете.</p>
<p>Здесь мы будем делать акцент на прерывистый спрос, но вообще-то функции хорошо работают и в других случаях, в которых возникают нули в данных.</p>
<h3>Модель</h3>
<p>Во-первых, стоит заметить, что всё, что мы будем далее обсуждать основано на идее разделения ряда прерывистого спроса на две части (<a href="https://doi.org/10.2307/3007885" rel="noopener noreferrer" target="_blank">Croston, 1972</a>):</p>
<ol>
<li>Появление спроса, которая представлена бинарной переменной (0 &#8212; спроса нет, 1 &#8212; спрос есть);</li>
<li>Размер спроса, которая отражает, сколько единиц продукции было куплено, если спрос появился.</li>
</ol>
<p>Математически это всё представляется вот так вот:<br />
\begin{equation} \label{eq:iSS}<br />
	y_t = o_t z_t ,<br />
\end{equation}<br />
где \(o_t\) &#8212; это бинарная переменная появления, \(z_t\) &#8212; это объём спроса и \(y_t\) &#8212; это финальная величина, которую мы измеряем. Это уравнение было предложено в <a href="https://doi.org/10.2307/3007885" rel="noopener noreferrer" target="_blank">Croston, (1972)</a>, хотя Кростон ограничился лишь разработкой прогнозного метода, и не занимался стохастической моделью.</p>
<p>В литературе встречается несколько методов для прогнозирования прерывистого спроса: Кростон (<a href="https://doi.org/10.2307/3007885" rel="noopener noreferrer" target="_blank">Croston, 1972</a>), SBA (<a href="https://doi.org/10.1057/palgrave.jors.2601841" rel="noopener noreferrer" target="_blank">Syntetos &#038; Boylan, 2000</a> &#8212; SBA &#8212; Syntetos-Boylan Approximation) и TSB (<a href="https://doi.org/10.1016/j.ejor.2011.05.018" rel="noopener noreferrer" target="_blank">Teunter et al., 2011</a> &#8212; по фамилиям авторов метода). Это всё хорошие методы, которые себя хорошо зарекомендовали. Единственное ограничение &#8212; это то, что они &#171;методы&#187;, а не &#171;стохастические модели&#187;. Модель позволяет достаточно легко включать дополнительные компоненты и переменные, конструировать прогнозные интервалы и возможность осуществлять <a href="/forecasting_toolbox/model-selection/">выбор наилучшей модели</a> среди некоторого пула. Не имея модель, всё это сделать затруднительно. Мы с Джоном Бойланом (John Boylan) разработали модель, которая лежит в основе этих методов (<a href="/en/2017/11/07/multiplicative-state-space-models-for-intermittent-time-series/">Svetunkov &#038; Boylan, 2017</a>), с помощью \eqref{eq:iSS}. Учитывая то, что все эти методы основаны на простом экспоненциальном сглаживании, мы назвали свою модель &#171;iETS&#187; &#8212; &#171;intermittent ETS&#187; &#8212; &#171;прерывистая ETS&#187;. В статье, которая сейчас находится на стадии рецензирования в International Journal for Forecasting, мы рассматривали частный случай этой модели &#8212; iETS(M,N,N), то есть модель с мультипликативной ошибкой, без тренда и сезонности, так как именно эта модель лежит в основе простого экспоненциального сглаживания. Одно из ключевых предположений в нашей модели &#8212; это независимость появления спроса от размера спроса. Это, конечно, явное упрощение, которой мы получили по наследству от метода Кростона, но даже с ним модель работает хорошо в большинстве случаев.</p>
<p>Модель iETS(M,N,N) формулируется следующим образом:<br />
\begin{equation} \label{eq:iETS}<br />
	\begin{matrix}<br />
		y_t = o_t z_t \\<br />
		z_t = l_{z,t-1} \left(1 + \epsilon_t \right) \\<br />
		l_{z,t} = l_{z,t-1}( 1  + \alpha_z \epsilon_t) \\<br />
		o_t \sim \text{Bernoulli}(p_t)<br />
	\end{matrix} ,<br />
\end{equation}<br />
где \(z_t\) &#8212; это модель ETS(M,N,N), \(l_{z,t}\) это уровень ненулевого спроса, \(\alpha_z\) &#8212; постоянная сглаживания, а \(\epsilon_t\) &#8212; ошибка модели. Важное допущение в модели &#8212; это то, что  \(\left(1 + \epsilon_t \right) \sim \text{log}\mathcal{N}(0, \sigma_\epsilon^2) \) &#8212; нечто, что мы уже <a href="/2016/11/18/smooth-package-for-r-es-function-part-iii-pure-multiplicative-models-ru/">как-то обсуждали</a>. Это допущение важно, так как ограничивает область значений только положительными значениями. Впрочем, если в вашем контексте возможны так же и отрицательные значения, то никто не мешает вместо мультипликативных моделей использовать <a href="/2016/11/02/smooth-package-for-r-es-function-part-ii-pure-additive-models-ru/">аддитивные</a>.</p>
<p>Прелесть модели \eqref{eq:iETS} заключается в том, что она может быть легко расширена (в неё можно добавить тренд, сезонность, экзогенные переменные), и то, что все её параметры могут быть оценены путём <a href="/forecasting_toolbox/estimation-simple-methods/">максимизации функции правдоподобия</a>.</p>
<p>Для моделирования части, отвечающей за появление спроса, мы предложили следующие три модели:</p>
<ol>
<li>iETS\(_F\) &#8212; модель предполагает, что вероятность появления спроса фиксирована (\(p_t = p\)).</li>
<li>iETS\(_O\) &#8212; &#171;Odds Ratio&#187;, модель отношения шансов, которая использует логистическую кривую для обновления вероятности появления значения. В этом случае модель сфокусирована именно на вероятности появления спроса.</li>
<li>iETS\(_I\) &#8212; &#171;Inverse Odds Ratio&#187;, модель обратного отношения шансов, которая использует похожие принципы, как и iETS\(_O\), однако прогнозы её сфокусированы на вероятности не появления спроса. Эта модель даёт статистическое объяснение для метода <a href="https://doi.org/10.2307/3007885" rel="noopener noreferrer" target="_blank">Croston (1972)</a>, но использует несколько другой принцип обновления вероятности: вместо того, чтобы обновлять вероятность, когда происходит продажа, она это делает на каждом наблюдении.</li>
<li>iETS\(_D\) &#8212; &#171;Direct probability&#187;, модель непосредственной вероятности, которая использует принцип, предложенный <a href="https://doi.org/10.1016/j.ejor.2011.05.018" rel="noopener noreferrer" target="_blank">Teunter et al., (2011)</a>. В этом случае вероятность обновляется на прямую с помощью простого экспоненциального сглаживания.</li>
<li>iETS\(_G\) &#8212; &#171;General&#187;, обобщённая модель, которая фактически включает в себя все предыдущие. Она состоит из двух под-моделей для вероятности, фактически учитывая как вероятности возникновения, так и вероятность не возникновения продаж.</li>
</ol>
<p>В случае (1) модель для вероятности значительно упрощается, её можно оценить с помощью функции правдоподобия и использовать для прогноза. В остальных случаях мы предлагаем использовать ещё одну модель ETS(M,N,N) для каждой из частей процессов. Так что в каждом из этих случаев прогноз представляет собой прямую линию. Финальный прогноз для всех этих моделей считается по формуле:<br />
\begin{equation} \label{eq:iSSForecast}<br />
	\hat{y}_{t+h} = \hat{p}_{t+h} \hat{z}_{t+h} ,<br />
\end{equation}<br />
где \(\hat{p}_{t+h}\) &#8212; это прогнозируемая вероятность, \(\hat{z}_t\) &#8212; это прогнозируемый объём спроса, а \(\hat{y}_t\) &#8212; это финальный прогноз для прерывистого спроса. Фактически на выходе мы получает некую оценку того, сколько будет продано в среднем за единицу времени.</p>
<p>Для того, чтобы разделить общую модель \eqref{eq:iETS} с её частью для объёмов спроса и для появления спроса, мы предлагаем использовать разные названия. Например, iETS\(_G\)(M,N,N) обозначает полную модель \eqref{eq:iETS} (\(y_t\)), oETS\(_G\)(M,N,N) обозначает модель для появления спроса (\(o_t\)), а ETS(M,N,N) используется для обозначения модели для объёмов спроса (\(z_t\)). Во всех этих трёх случаях часть &#171;(M,N,N)&#187; показывает, что мы используем модель экспоненциального сглаживания с мультипликативной ошибкой, без тренда и сезонности. Более продвинутые обозначения для модели будут обсуждены в следующих статьях на сайте. Пока же мы будем ориентироваться на простую модель экспоненциального сглаживания.</p>
<p>Обобщая преимущества нашей модели:</p>
<ol>
<li>Она расширяема. Это означает, что в неё можно добавлять любые компоненты, которые вы пожелаете. Такая возможность уже существует в пакете <span class="lang:r decode:true crayon-inline">smooth</span>. К слову, базовая модель \eqref{eq:iSS} позволяет использовать всё, что угодно для объёма спроса и множество разных моделей для появления спроса;</li>
<li>Модель позволяет выбирать между теми самыми пятью случаями (iETS\(_F\), iETS\(_O\), iETS\(_I\), iETS\(_D\) и iETS\(_G\)) с помощью информационных критериев. Этот механизм работает хорошо на больших выборках, но не всегда показывает такие же хорошие результаты на малых;</li>
<li>Модель позволяет конструировать параметрические прогнозные интервалы на несколько шагов вперёд;</li>
<li>Оценка моделей осуществляется с помощью функции правдоподобия, которая даёт <a href="/forecasting_toolbox/statistics-and-hypothesis/">эффективные и состоятельные оценки</a>;</li>
<li>Хотя модель и предполагает непрерывную случайную величину для объёма спроса, <a href="/2017/11/07/multiplicative-state-space-models-for-intermittent-time-series-2/">мы показали в своей статье</a>, что она часто работает лучше, чем модели целочисленных случайных величин (типа Пуассона или Биномиального распределения).</li>
</ol>
<p>Что же, посмотрим, как это работает&#8230;</p>
<h3>Появление спроса</h3>
<p>В пакете <span class="lang:r decode:true crayon-inline">smooth</span> есть функция <span class="lang:r decode:true crayon-inline">oes()</span> (Occurrence Exponential Smoothing), которая отвечает за модель появления спроса. Так же, в каждой прогнозной функции пакета есть параметр <span class="lang:r decode:true crayon-inline">occurrence</span>, который может быть: &#171;none&#187; (никакой модели), &#171;fixed&#187; (oETS\(_F\)), &#171;odds-ratio&#187; (oETS\(_O\)), &#171;inverse-odds-ratio&#187; (oETS\(_I\)), &#171;direct&#187; (oETS\(_D\)), &#171;general&#187; (oETS\(_G\)) и &#171;auto&#187; (автоматический выбор). Автоматическую опцию мы пока не рассматриваем, обсудим те самые пять моделей. Рассмотрим их на условном примере:</p>
<pre class="decode">x <- c(rpois(25,5),rpois(25,1),rpois(25,0.5),rpois(25,0.1))</pre>
<p>В этом искусственном временном ряду вероятность и размер спроса меняются ступенчато каждые 25 наблюдений. Сгенерированные данные отражают нечто под названием "вымирающий спрос" или "устаревающий спрос". Построим наши три модели:</p>
<pre class="decode">oesFixed <- oes(x, occurrence="f", h=25)</pre>
<pre>Occurrence state space model estimated: Fixed probability
Underlying ETS model: oETS[F](MNN)
Smoothing parameters:
level 
    0 
Vector of initials:
level 
 0.55 
Information criteria: 
     AIC     AICc      BIC     BICc 
139.6278 139.6686 142.2329 142.3269</pre>
<pre class="decode">oesOdds <- oes(x, occurrence="o", h=25)</pre>
<pre>Occurrence state space model estimated: Odds ratio
Underlying ETS model: oETS[O](MNN)
Smoothing parameters:
level 
0.828 
Vector of initials:
 level 
14.442 
Information criteria: 
     AIC     AICc      BIC     BICc 
116.3124 116.4361 121.5227 121.8076 </pre>
<pre class="decode">oesInverse <- oes(x, occurrence="i", h=25)</pre>
<pre>Occurrence state space model estimated: Inverse odds ratio
Underlying ETS model: oETS[I](MNN)
Smoothing parameters:
level 
0.116 
Vector of initials:
level 
0.039 
Information criteria: 
     AIC     AICc      BIC     BICc 
 98.5508  98.6745 103.7611 104.0460</pre>
<pre class="decode">oesDirect <- oes(x, occurrence="d", h=25)</pre>
<pre>Occurrence state space model estimated: Direct probability
Underlying ETS model: oETS[D](MNN)
Smoothing parameters:
level 
0.115 
Vector of initials:
level 
0.884 
Information criteria: 
     AIC     AICc      BIC     BICc 
106.5982 106.7219 111.8086 112.0934</pre>
<pre class="decode">oesGeneral <- oes(x, occurrence="g", h=25)</pre>
<pre>Occurrence state space model estimated: General
Underlying ETS model: oETS[G](MNN)(MNN)
Information criteria: 
     AIC     AICc      BIC     BICc 
102.5508 102.9718 112.9715 113.9410</pre>
<p>Анализируя результаты, можно заметить, что модель oETS\(_I\) показала себя лучше на этих данных - её информационные критерии ниже, чем у других моделей. Это всё потому что данный тип модели хорошо подходит под ряды с угасающим спросом из-за того, что модель сфокусирована на вероятности исчезновения. Обратите внимание, что постоянная сглаживания в модели oETS\(_O\) достаточно высока. Это потому что модель сфокусирована на вероятности возникновения спроса, а он у нас угасает. Если бы динамика была противоположной (частота спроса возрастала), то и ситуация была бы другой: постоянная сглаживания в oETS\(_O\) была бы ниже, чем постоянная сглаживания в oETS\(_I\). Так же можно заметить, что стартовый уровень в модели oETS\(_I\) равен 0.116, что соответствует вероятности возникновения в \(\frac{1}{1+0.116} \approx 0.89\).</p>
<p>На себя так же обращает внимание модель oETS\(_G\), которая не спешит делиться деталями о моделях внутри неё. Это потому что в ней две модели (которые называются modelA и modelB в R), каждая из которых имеет свои параметры. Вот они:</p>
<pre class="decode">oesGeneral$modelA
oesGeneral$modelB</pre>
<pre>Occurrence state space model estimated: General
Underlying ETS model: oETS(MNN)_A
Smoothing parameters:
level 
    0 
Vector of initials:
level 
   16 
Information criteria: 
     AIC     AICc      BIC     BICc 
 98.5508  98.6745 103.7611 104.0460

Occurrence state space model estimated: General
Underlying ETS model: oETS(MNN)_B
Smoothing parameters:
level 
0.116 
Vector of initials:
level 
0.628 
Information criteria: 
     AIC     AICc      BIC     BICc 
 98.5508  98.6745 103.7611 104.0460 </pre>
<p>oETS\(_G\) и обе подмодели A и B имеют одно и то же значение функции правдоподобия, так как они являются частями единого целого. Однако информационные критерии у них различаются, так как у них разное число оценённых параметров: в моделях A и B их по двое, в то время как в целой модели их, соответственно, 4. Заметьте, что оптимальная постоянная сглаживания в модели A оказалась равной нулю, что означает, что компоненты её не обновляются во времени. Мы ещё вернёмся к этому наблюдению чуть позже.</p>
<p>Мы так же можем построить линейные графики по этим моделям, чтобы увидеть, как именно они работают:</p>
<pre class="decode">plot(oesFixed)</pre>
<p><a href="https://openforecast.org/wp-content/webpc-passthru.php?src=https://openforecast.org/wp-content/uploads/2018/09/oesFixedExample.png&amp;nocache=1"><img loading="lazy" decoding="async" src="https://openforecast.org/wp-content/webpc-passthru.php?src=https://openforecast.org/wp-content/uploads/2018/09/oesFixedExample-300x175.png&amp;nocache=1" alt="" width="300" height="175" class="alignnone size-medium wp-image-1968" srcset="https://openforecast.org/wp-content/webpc-passthru.php?src=https://openforecast.org/wp-content/uploads/2018/09/oesFixedExample-300x175.png&amp;nocache=1 300w, https://openforecast.org/wp-content/webpc-passthru.php?src=https://openforecast.org/wp-content/uploads/2018/09/oesFixedExample-768x448.png&amp;nocache=1 768w, https://openforecast.org/wp-content/webpc-passthru.php?src=https://openforecast.org/wp-content/uploads/2018/09/oesFixedExample-1024x597.png&amp;nocache=1 1024w, https://openforecast.org/wp-content/webpc-passthru.php?src=https://openforecast.org/wp-content/uploads/2018/09/oesFixedExample.png&amp;nocache=1 1200w" sizes="auto, (max-width: 300px) 100vw, 300px" /></a></p>
<pre class="decode">plot(oesOdds)</pre>
<p><a href="https://openforecast.org/wp-content/webpc-passthru.php?src=https://openforecast.org/wp-content/uploads/2018/09/oesOddsExample.png&amp;nocache=1"><img loading="lazy" decoding="async" src="https://openforecast.org/wp-content/webpc-passthru.php?src=https://openforecast.org/wp-content/uploads/2018/09/oesOddsExample-300x175.png&amp;nocache=1" alt="" width="300" height="175" class="alignnone size-medium wp-image-1966" srcset="https://openforecast.org/wp-content/webpc-passthru.php?src=https://openforecast.org/wp-content/uploads/2018/09/oesOddsExample-300x175.png&amp;nocache=1 300w, https://openforecast.org/wp-content/webpc-passthru.php?src=https://openforecast.org/wp-content/uploads/2018/09/oesOddsExample-768x448.png&amp;nocache=1 768w, https://openforecast.org/wp-content/webpc-passthru.php?src=https://openforecast.org/wp-content/uploads/2018/09/oesOddsExample-1024x597.png&amp;nocache=1 1024w, https://openforecast.org/wp-content/webpc-passthru.php?src=https://openforecast.org/wp-content/uploads/2018/09/oesOddsExample.png&amp;nocache=1 1200w" sizes="auto, (max-width: 300px) 100vw, 300px" /></a></p>
<pre class="decode">plot(oesInverse)</pre>
<p><a href="https://openforecast.org/wp-content/webpc-passthru.php?src=https://openforecast.org/wp-content/uploads/2018/09/oesInverseExample.png&amp;nocache=1"><img loading="lazy" decoding="async" src="https://openforecast.org/wp-content/webpc-passthru.php?src=https://openforecast.org/wp-content/uploads/2018/09/oesInverseExample-300x175.png&amp;nocache=1" alt="" width="300" height="175" class="alignnone size-medium wp-image-1970" srcset="https://openforecast.org/wp-content/webpc-passthru.php?src=https://openforecast.org/wp-content/uploads/2018/09/oesInverseExample-300x175.png&amp;nocache=1 300w, https://openforecast.org/wp-content/webpc-passthru.php?src=https://openforecast.org/wp-content/uploads/2018/09/oesInverseExample-768x448.png&amp;nocache=1 768w, https://openforecast.org/wp-content/webpc-passthru.php?src=https://openforecast.org/wp-content/uploads/2018/09/oesInverseExample-1024x597.png&amp;nocache=1 1024w, https://openforecast.org/wp-content/webpc-passthru.php?src=https://openforecast.org/wp-content/uploads/2018/09/oesInverseExample.png&amp;nocache=1 1200w" sizes="auto, (max-width: 300px) 100vw, 300px" /></a></p>
<pre class="decode">plot(oesDirect)</pre>
<p><a href="https://openforecast.org/wp-content/webpc-passthru.php?src=https://openforecast.org/wp-content/uploads/2018/09/oesDirectExample.png&amp;nocache=1"><img loading="lazy" decoding="async" src="https://openforecast.org/wp-content/webpc-passthru.php?src=https://openforecast.org/wp-content/uploads/2018/09/oesDirectExample-300x175.png&amp;nocache=1" alt="" width="300" height="175" class="alignnone size-medium wp-image-1967" srcset="https://openforecast.org/wp-content/webpc-passthru.php?src=https://openforecast.org/wp-content/uploads/2018/09/oesDirectExample-300x175.png&amp;nocache=1 300w, https://openforecast.org/wp-content/webpc-passthru.php?src=https://openforecast.org/wp-content/uploads/2018/09/oesDirectExample-768x448.png&amp;nocache=1 768w, https://openforecast.org/wp-content/webpc-passthru.php?src=https://openforecast.org/wp-content/uploads/2018/09/oesDirectExample-1024x597.png&amp;nocache=1 1024w, https://openforecast.org/wp-content/webpc-passthru.php?src=https://openforecast.org/wp-content/uploads/2018/09/oesDirectExample.png&amp;nocache=1 1200w" sizes="auto, (max-width: 300px) 100vw, 300px" /></a></p>
<pre class="decode">plot(oesGeneral)</pre>
<p><a href="https://openforecast.org/wp-content/webpc-passthru.php?src=https://openforecast.org/wp-content/uploads/2018/09/oesGeneralExample.png&amp;nocache=1"><img loading="lazy" decoding="async" src="https://openforecast.org/wp-content/webpc-passthru.php?src=https://openforecast.org/wp-content/uploads/2018/09/oesGeneralExample-300x175.png&amp;nocache=1" alt="" width="300" height="175" class="alignnone size-medium wp-image-1969" srcset="https://openforecast.org/wp-content/webpc-passthru.php?src=https://openforecast.org/wp-content/uploads/2018/09/oesGeneralExample-300x175.png&amp;nocache=1 300w, https://openforecast.org/wp-content/webpc-passthru.php?src=https://openforecast.org/wp-content/uploads/2018/09/oesGeneralExample-768x448.png&amp;nocache=1 768w, https://openforecast.org/wp-content/webpc-passthru.php?src=https://openforecast.org/wp-content/uploads/2018/09/oesGeneralExample-1024x597.png&amp;nocache=1 1024w, https://openforecast.org/wp-content/webpc-passthru.php?src=https://openforecast.org/wp-content/uploads/2018/09/oesGeneralExample.png&amp;nocache=1 1200w" sizes="auto, (max-width: 300px) 100vw, 300px" /></a></p>
<p>Обратите внимание, что разные модели улавливают динамику вероятности по-разному: в то время как iETS\(_F\) всё усредняет, остальные модели реагируют на изменения вероятности, но не одинаково.<br />
Так oETS\(_O\) более живо реагирует на динамику появления спроса, пытаясь угнаться за меняющейся вероятностью. Модель oETS\(_I\) при этом ведёт себя спокойней, воспроизводя более гладкую линию. oETS\(_D\) оказалась реактивней предыдущей модель, но не такой резкой, как модель отношения шансов. Ну, и модель oETS\(_G\) скопировала динамику модели oETS\(_I\). Это всё из-за того, что оптимальная постоянная сглаживания в модели A в oETS\(_G\) оказалась равной нулю, что привело к тому, что модель oETS\(_G\) выродилась в oETS\(_I\). Тем не менее, все эти модели спрогнозировали, что вероятность спроса будет достаточно низкой, что соответствует динамики сгенерированного ряда.</p>
<p>Что же, перейдём к полной модели...</p>
<h3>Полная модель</h3>
<p>Для того, чтобы дать финальный прогноз для прерывистого спроса, мы можем использовать любую прогнозную функцию из пакета: <span class="lang:r decode:true crayon-inline">es()</span>, <span class="lang:r decode:true crayon-inline">ssarima()</span>, <span class="lang:r decode:true crayon-inline">ces()</span>, <span class="lang:r decode:true crayon-inline">gum()</span> - во всех них есть соответствующий параметр <span class="lang:r decode:true crayon-inline">occurrence</span>, который по умолчанию равен "none". Для простоты пока будем использовать модель ETS. И для простоты мы будем использовать iETS\(_I\), так как она хорошо себя проявила на этом ряде:</p>
<pre class="decode">es(x, "MNN", occurrence="i", silent=FALSE, h=25)</pre>
<p><a href="https://openforecast.org/wp-content/webpc-passthru.php?src=https://openforecast.org/wp-content/uploads/2018/09/iETSMNNIMNN.png&amp;nocache=1"><img loading="lazy" decoding="async" src="https://openforecast.org/wp-content/webpc-passthru.php?src=https://openforecast.org/wp-content/uploads/2018/09/iETSMNNIMNN-300x175.png&amp;nocache=1" alt="" width="300" height="175" class="alignnone size-medium wp-image-1971" srcset="https://openforecast.org/wp-content/webpc-passthru.php?src=https://openforecast.org/wp-content/uploads/2018/09/iETSMNNIMNN-300x175.png&amp;nocache=1 300w, https://openforecast.org/wp-content/webpc-passthru.php?src=https://openforecast.org/wp-content/uploads/2018/09/iETSMNNIMNN-768x448.png&amp;nocache=1 768w, https://openforecast.org/wp-content/webpc-passthru.php?src=https://openforecast.org/wp-content/uploads/2018/09/iETSMNNIMNN-1024x597.png&amp;nocache=1 1024w, https://openforecast.org/wp-content/webpc-passthru.php?src=https://openforecast.org/wp-content/uploads/2018/09/iETSMNNIMNN.png&amp;nocache=1 1200w" sizes="auto, (max-width: 300px) 100vw, 300px" /></a></p>
<p>Прогноз этой модели - прямая линия, близкая к нулю, что вызвано снижением значений как в объёме спроса, так и в вероятности появления. Однако, зная, что спрос снижается, мы можем использовать модель с трендом для объёма спроса, ETS(M,M,N):</p>
<pre class="decode">es(x, "MMN", occurrence="i", silent=FALSE, h=25)</pre>
<p><a href="https://openforecast.org/wp-content/webpc-passthru.php?src=https://openforecast.org/wp-content/uploads/2018/09/iETSMMNIMNN.png&amp;nocache=1"><img loading="lazy" decoding="async" src="https://openforecast.org/wp-content/webpc-passthru.php?src=https://openforecast.org/wp-content/uploads/2018/09/iETSMMNIMNN-300x175.png&amp;nocache=1" alt="" width="300" height="175" class="alignnone size-medium wp-image-1972" srcset="https://openforecast.org/wp-content/webpc-passthru.php?src=https://openforecast.org/wp-content/uploads/2018/09/iETSMMNIMNN-300x175.png&amp;nocache=1 300w, https://openforecast.org/wp-content/webpc-passthru.php?src=https://openforecast.org/wp-content/uploads/2018/09/iETSMMNIMNN-768x448.png&amp;nocache=1 768w, https://openforecast.org/wp-content/webpc-passthru.php?src=https://openforecast.org/wp-content/uploads/2018/09/iETSMMNIMNN-1024x597.png&amp;nocache=1 1024w, https://openforecast.org/wp-content/webpc-passthru.php?src=https://openforecast.org/wp-content/uploads/2018/09/iETSMMNIMNN.png&amp;nocache=1 1200w" sizes="auto, (max-width: 300px) 100vw, 300px" /></a></p>
<p>Прогноз в этом случае оказывается ближе к нулю, а уж асимптотически он точно будет нуль... Это означает, что мы имеем дело с угосающим спросом.</p>
<p>Мы можем так же построить прогнозные интервалы и использовать модель с автоматическим выбором компонент для объёма спроса. Если мы знаем, что данные не могут быть отрицательными (например, какие-нибудь продажи помидоров), то я бы рекомендовал обратиться к чистым мультипликативным моделям:</p>
<pre class="lang:r decode:true">es(x, "YYN", occurrence="i", silent=FALSE, h=25, intervals=TRUE)</pre>
<pre>Forming the pool of models based on... MNN, MMN, Estimation progress: 100%... Done! 
Time elapsed: 1.02 seconds
Model estimated: iETS(MMN)
Occurrence model type: Inverse odds ratio
Persistence vector g:
alpha  beta 
0.268 0.000 
Initial values were optimised.
7 parameters were estimated in the process
Residuals standard deviation: 0.386
Cost function type: MSE; Cost function value: 0.149

Information criteria:
     AIC     AICc      BIC     BICc 
333.4377 334.0760 348.5648 339.9301 
95% parametric prediction intervals were constructed</pre>
<p><a href="https://openforecast.org/wp-content/webpc-passthru.php?src=https://openforecast.org/wp-content/uploads/2018/09/iETSYYNIMNN.png&amp;nocache=1"><img loading="lazy" decoding="async" src="https://openforecast.org/wp-content/webpc-passthru.php?src=https://openforecast.org/wp-content/uploads/2018/09/iETSYYNIMNN-300x175.png&amp;nocache=1" alt="" width="300" height="175" class="alignnone size-medium wp-image-1973" srcset="https://openforecast.org/wp-content/webpc-passthru.php?src=https://openforecast.org/wp-content/uploads/2018/09/iETSYYNIMNN-300x175.png&amp;nocache=1 300w, https://openforecast.org/wp-content/webpc-passthru.php?src=https://openforecast.org/wp-content/uploads/2018/09/iETSYYNIMNN-768x448.png&amp;nocache=1 768w, https://openforecast.org/wp-content/webpc-passthru.php?src=https://openforecast.org/wp-content/uploads/2018/09/iETSYYNIMNN-1024x597.png&amp;nocache=1 1024w, https://openforecast.org/wp-content/webpc-passthru.php?src=https://openforecast.org/wp-content/uploads/2018/09/iETSYYNIMNN.png&amp;nocache=1 1200w" sizes="auto, (max-width: 300px) 100vw, 300px" /></a></p>
<p>Как видим, в данном случае наиболее подходящей оказалась модель с мультипликативным трендом. Прогнозные интервалы в этом случае сужаются, так как уровень спроса приближается к нулю. Сравните этот график с графиком чистой аддитивной модели:</p>
<pre class="decode">es(x, "XXN", occurrence="i", silent=FALSE, h=25, intervals=TRUE)</pre>
<pre>Forming the pool of models based on... ANN, AAN, Estimation progress:    ... Done! 
Time elapsed: 0.23 seconds
Model estimated: iETS(ANN)
Occurrence model type: Inverse odds ratio
Persistence vector g:
alpha 
0.251 
Initial values were optimised.
5 parameters were estimated in the process
Residuals standard deviation: 1.125
Cost function type: MSE; Cost function value: 1.265

Information criteria:
     AIC     AICc      BIC     BICc 
459.8706 460.1206 472.8964 464.2617 
95% parametric prediction intervals were constructed</pre>
<p><a href="https://openforecast.org/wp-content/webpc-passthru.php?src=https://openforecast.org/wp-content/uploads/2018/09/iETSXXNIMNN.png&amp;nocache=1"><img loading="lazy" decoding="async" src="https://openforecast.org/wp-content/webpc-passthru.php?src=https://openforecast.org/wp-content/uploads/2018/09/iETSXXNIMNN-300x175.png&amp;nocache=1" alt="" width="300" height="175" class="alignnone size-medium wp-image-1974" srcset="https://openforecast.org/wp-content/webpc-passthru.php?src=https://openforecast.org/wp-content/uploads/2018/09/iETSXXNIMNN-300x175.png&amp;nocache=1 300w, https://openforecast.org/wp-content/webpc-passthru.php?src=https://openforecast.org/wp-content/uploads/2018/09/iETSXXNIMNN-768x448.png&amp;nocache=1 768w, https://openforecast.org/wp-content/webpc-passthru.php?src=https://openforecast.org/wp-content/uploads/2018/09/iETSXXNIMNN-1024x597.png&amp;nocache=1 1024w, https://openforecast.org/wp-content/webpc-passthru.php?src=https://openforecast.org/wp-content/uploads/2018/09/iETSXXNIMNN.png&amp;nocache=1 1200w" sizes="auto, (max-width: 300px) 100vw, 300px" /></a></p>
<p>В последнем случае нижняя граница интервала оказывается отрицательной, что в некоторых случаях не имеет смысла. Обратите внимание так же, что информационные критерии для чистой мультипликативной модели оказались ниже. Это из-за того, что мы имеем дело с гетероскедастичностью: дисперсия спроса меняется каждый 25 наблюдений, вместе с изменением уровня ряда.</p>
<p>Здесь нужно сделать важную ремарку. Несмотря на то, что я бы рекомендовал использовать чистые мультипликативные модели, модель ETS(M,M,N) с положительным трендом взрывоопасна. Фактически мы имеем дело с экспонентой, а значит и прогноз может быть в форме взрывного спроса. Пока что решения этой проблемы нет, так что я бы рекомендовал вручную выбирать между ETS(M,N,N) и ETS(M,Md,N) (модель с демпфированным трендом). Я не рекомендую модели с аддитивным трендом, так как в случае с низким уровнем ряда и негативным трендом может получаться всякий бред (отрицательные значения и лош-нормальное распределение - это что-то странное).</p>
<p>Как видим, теперь в нашем распоряжении оказалось на пять моделей экспоненциального сглаживания больше, что может усложнить жизнь практикующему прогнозисту. Теперь надо понять, как выбрать наиболее подходящую модель из этих пяти, как выбрать модель экспоненциального сглаживания для oETS (не останавливаться же на простом экспоненциальном сглаживании при прогнозировании вероятности возникновения) и как включать объясняющие переменные в модель. Если бы мы могли всё это сделать, то это расширило бы инструментарий для прогнозирования в разы, не так ли? Всё это, на самом деле, уже доступно в пакете <span class="lang:r decode:true crayon-inline">smooth</span>, и мы перейдём к этим деталям в следующей статье. До новых встреч!</p>
<p>Сообщение <a href="https://openforecast.org/ru/2018/09/18/intermittent-state-space-intro/">Пакет «smooth» для R. Прерывистый спрос. Часть 1. Введение</a> появились сначала на <a href="https://openforecast.org/ru">Open Forecasting</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://openforecast.org/ru/2018/09/18/intermittent-state-space-intro/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Пакет greybox для R</title>
		<link>https://openforecast.org/ru/2018/05/04/greybox-for-r/</link>
					<comments>https://openforecast.org/ru/2018/05/04/greybox-for-r/#comments</comments>
		
		<dc:creator><![CDATA[Ivan Svetunkov]]></dc:creator>
		<pubDate>Fri, 04 May 2018 12:22:35 +0000</pubDate>
				<category><![CDATA[R]]></category>
		<category><![CDATA[Пакет greybox для R]]></category>
		<category><![CDATA[Прикладное прогнозирование]]></category>
		<category><![CDATA[greybox]]></category>
		<category><![CDATA[программирование]]></category>
		<category><![CDATA[статистика]]></category>
		<guid isPermaLink="false">https://openforecast.org/?p=1737</guid>

					<description><![CDATA[<p>На днях я разместил в CRAN новый пакет &#8212; greybox (серый ящик). Идея названия произрастает из принципов моделирования, в соответствии с которыми все модели могут быть условно разделены на три типа: Чёрный ящик &#8212; модель, в которой неизвестны ни структура, ни параметры. Мы видим только входной и выходной сигналы Белый ящик &#8212; модель, в которой [&#8230;]</p>
<p>Сообщение <a href="https://openforecast.org/ru/2018/05/04/greybox-for-r/">Пакет greybox для R</a> появились сначала на <a href="https://openforecast.org/ru">Open Forecasting</a>.</p>
]]></description>
										<content:encoded><![CDATA[<p><a href="https://openforecast.org/wp-content/webpc-passthru.php?src=https://openforecast.org/wp-content/uploads/2018/05/greybox2.png&amp;nocache=1"><img loading="lazy" decoding="async" src="https://openforecast.org/wp-content/webpc-passthru.php?src=https://openforecast.org/wp-content/uploads/2018/05/greybox2-260x300.png&amp;nocache=1" alt="Hexagon for greybox" width="260" height="300" class="size-medium wp-image-1719" srcset="https://openforecast.org/wp-content/webpc-passthru.php?src=https://openforecast.org/wp-content/uploads/2018/05/greybox2-260x300.png&amp;nocache=1 260w, https://openforecast.org/wp-content/webpc-passthru.php?src=https://openforecast.org/wp-content/uploads/2018/05/greybox2-768x888.png&amp;nocache=1 768w, https://openforecast.org/wp-content/webpc-passthru.php?src=https://openforecast.org/wp-content/uploads/2018/05/greybox2-886x1024.png&amp;nocache=1 886w, https://openforecast.org/wp-content/webpc-passthru.php?src=https://openforecast.org/wp-content/uploads/2018/05/greybox2.png&amp;nocache=1 1206w" sizes="auto, (max-width: 260px) 100vw, 260px" /></a></p>
<p>На днях я разместил в <a href="https://cran.r-project.org/" rel="noopener" target="_blank">CRAN</a> новый пакет &#8212; <a href="https://cran.r-project.org/package=greybox" rel="noopener" target="_blank">greybox</a> (серый ящик). Идея названия произрастает из принципов моделирования, в соответствии с которыми все модели могут быть условно разделены на три типа:</p>
<ol>
<li><strong>Чёрный ящик</strong> &#8212; модель, в которой неизвестны ни структура, ни параметры. Мы видим только входной и выходной сигналы</li>
<li><strong>Белый ящик</strong> &#8212; модель, в которой известно всё. Можно сказать, что это <a href="/about/systems-models/">детерминированная модель</a>, в ней нет никакой случайности, и всё предопределено.</li>
<li><strong>Серый ящик</strong> &#8212; нечто среднее, между предыдущими двумя. Фактически это и есть та самая <a href="/about/systems-models/">стохастическая модель</a>, с которой мы обычно имеем дело в прогнозировании.</li>
</ol>
<p>Так что пакет greybox, фактически может включать в себя всё, что угодно, связанное с моделированием. Однако акцент в нём будет сделан на процессе построении регрессионных моделей и выборе объясняющих переменных.</p>
<p>Этот пакет мне оказался нужным по нескольким причинам:</p>
<ol>
<li>У меня накопилось несколько функций, которые не подходили к другим пакетам (в т.ч. к пакету <a href="/tag/smooth-ru/">smooth</a>). Они все так или иначе относятся к регрессиям и к построению моделей;</li>
<li>Мои исследования и работа в университете в последнее время оказываются связанными с регрессиями и выбором наилучшей модели. Для этого нужны разные функции (например, для комбинирования моделей), и мне оказалось проще написать одну свою, нежели использовать несколько из разных пакетов.</li>
<li>В CRAN не нашлось пакетов для выбора моделей и последующего использования их в прогнозировании, которые полностью меня бы устраивали. Кроме того, мне не нравится тяга многих пакетов к <a href="/forecasting_toolbox/statistics-and-hypothesis/">p-values и проверке статистических гипотез</a>. Мы живём в 21 веке, и уже существуют другие инструменты для выбора моделей и анализа результатов.</li>
</ol>
<p>Поэтому я решил, что надо сделать свой пакет с теми функциями, которые нужны мне, реализованными в том виде, в каком я считаю их необходимыми.</p>
<p>На данный момент в пакет перекочевали функции <span class="lang:r decode:true crayon-inline">xregExpander()</span> и <span class="lang:r decode:true crayon-inline">stepwise()</span> из пакета <span class="lang:r decode:true crayon-inline">smooth</span>, а так же функция <span class="lang:r decode:true crayon-inline">ro()</span> из пакета <a href="https://github.com/trnnick/TStools" rel="noopener" target="_blank">TStools</a>. На тему первых двух на сайте <a href="/2018/02/10/xreg-advanced/">уже была отдельная статья</a>, а по поводу работы третьей можно почитать в <a href="https://cran.r-project.org/web/packages/greybox/vignettes/ro.html" rel="noopener" target="_blank">виньетах</a> пакета (к сожалению, только на английском).</p>
<p>Пакет будет развиваться и обновляться, а я буду периодически писать о том, как всё это движется.</p>
<p>Сообщение <a href="https://openforecast.org/ru/2018/05/04/greybox-for-r/">Пакет greybox для R</a> появились сначала на <a href="https://openforecast.org/ru">Open Forecasting</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://openforecast.org/ru/2018/05/04/greybox-for-r/feed/</wfw:commentRss>
			<slash:comments>2</slash:comments>
		
		
			</item>
		<item>
		<title>Сравнение аддитивной и мультипликативной регрессий с помощью AIC в R</title>
		<link>https://openforecast.org/ru/2018/03/22/additive_vs_multiplicative_aic/</link>
					<comments>https://openforecast.org/ru/2018/03/22/additive_vs_multiplicative_aic/#respond</comments>
		
		<dc:creator><![CDATA[Ivan Svetunkov]]></dc:creator>
		<pubDate>Thu, 22 Mar 2018 18:57:35 +0000</pubDate>
				<category><![CDATA[R]]></category>
		<category><![CDATA[Многомерные модели]]></category>
		<category><![CDATA[Теория прогнозирования]]></category>
		<category><![CDATA[Экстраполяционные методы]]></category>
		<category><![CDATA[статистика]]></category>
		<category><![CDATA[теория]]></category>
		<guid isPermaLink="false">https://openforecast.org/?p=1698</guid>

					<description><![CDATA[<p>Один из основных принципов, которому учат студентов в курсе статистикик заключается в том, что сравнение регрессионных моделей с помощью информационных критериев возможно только в том случае, когда выходная переменная в моделях одинаковая. Например, модель с выходной переменной \(\log(y_t)\) не может быть сравнена с моделью с \(y_t\) с помощью AIC. Причина в том, что переменные имеют [&#8230;]</p>
<p>Сообщение <a href="https://openforecast.org/ru/2018/03/22/additive_vs_multiplicative_aic/">Сравнение аддитивной и мультипликативной регрессий с помощью AIC в R</a> появились сначала на <a href="https://openforecast.org/ru">Open Forecasting</a>.</p>
]]></description>
										<content:encoded><![CDATA[<p>Один из основных принципов, которому учат студентов в курсе статистикик заключается в том, что сравнение регрессионных моделей с помощью информационных критериев возможно только в том случае, когда выходная переменная в моделях одинаковая. Например, модель с выходной переменной \(\log(y_t)\) не может быть сравнена с моделью с \(y_t\) с помощью AIC. Причина в том, что переменные имеют разный масштаб, а значит и значение функции правдоподобия у моделей будет разное. Но есть метод, позволяющий таки провести сравнение. Всё, что нужно сделать &#8212; это понять, как распределены обе перемемнные в исходной шкале. В нашем примере мы фактически допускаем, что \(\log(y_t) \sim \mathcal{N}(0, \sigma^2_{l}) \) (где \(\sigma^2_{l}\) &#8212; это дисперсия остатков модели в логарифмах), а значит экспонента этой переменной будет распределена лог-нормально:<br />
\begin{equation}<br />
y_t \sim \text{log}\mathcal{N}(0, \sigma^2_{l})<br />
\end{equation}<br />
В качестве напоминания, все информационные критерии основаны на значения функции правдоподобия. Вот, например, формуля для AIC:<br />
\begin{equation} \label{eq:AIC}<br />
AIC = 2k -2\ell ,<br />
\end{equation}<br />
где \(k\) &#8212; число оценённых параметров, а \(\ell\) &#8212; значение функции правдоподобия.</p>
<p>Если использовать функцию правдоподобия лог-нормального распределения вместо нормального в \eqref{eq:AIC} для переменной \(y_t\) в логарифмах, тогда  и информационные критерии будут сравнимы. Для того, чтобы понять, что нужно сделать для получения лог-нормального распределения, обратимся к соответствующим функциями. Вот нормальное для переменной \(\log y_t\):<br />
\begin{equation} \label{eq:normal}<br />
f(y_t | \theta, \sigma^2_{l}) = \frac{1}{\sqrt{2 \pi \sigma^2_{l}}} e ^{-\frac{\left(\log y_t -\log \mu_{t} \right)^2}{2 \sigma^2_{l}}}<br />
\end{equation}<br />
а вот лог-нормальное для переменной \(y_t = \exp(\log(y_t))\) (мультипликативная модель с выходной переменной в исходной шкале):<br />
\begin{equation} \label{eq:log-normal}<br />
f(y_t | \theta, \sigma^2_{l}) = \frac{1}{y_t} \frac{1}{\sqrt{2 \pi \sigma^2_{l}}} e ^{-\frac{\left(\log y_t -\log \mu_{t} \right)^2}{2 \sigma^2_{l}}} ,<br />
\end{equation}<br />
где \(\theta\) &#8212; это вектор параметров модели. Разница между \eqref{eq:normal} и \eqref{eq:log-normal} заключается в части \(\frac{1}{y_t}\). логарифм функции правдоподобия для всей выборки на основе \eqref{eq:log-normal} выглядит так:<br />
\begin{equation} \label{eq:loglikelihoodlognormal}<br />
\ell(\theta, \sigma^2_{l} | Y) = -\frac{1}{2} \left(T \log \left( 2 \pi {\sigma}^2_{l} \right) +\sum_{t=1}^T \frac{\left(\log y_t -\log \mu_{t} \right)^2}{2\sigma^2_{l}} \right) -\sum_{t=1}^T \log y_t ,<br />
\end{equation}<br />
где \(Y\) &#8212; это вектор всех фактических значений выходной перменной. Когда мы извлекаем значение функции правдоподобия модели в логарифмах, мы фактически обращаемся только к первой части \eqref{eq:loglikelihoodlognormal}, до &#171;\(-\sum_{t=1}^T \log y_t \)&#187;, что соответствует нормальному распределению. Таким образом, для того, чтобы прийти к функции правдоподобия в исходной шкале для переменной в логарифмах, нам нужно вычесть сумму логарифмов выходной переменной.</p>
<p>Функция <span class="lang:r decode:true crayon-inline">AIC()</span> в R, применённая к модели в логарифмах, даст нам значение на основе первой части \eqref{eq:loglikelihoodlognormal}. Чтобы &#171;починить&#187; информационный критерий нам нужно учесть тот самый хвост из \eqref{eq:loglikelihoodlognormal} в формуле \eqref{eq:AIC}:<br />
\begin{equation} \label{eq:AICNew}<br />
AIC^{\prime} = 2k -2\ell + 2 \sum_{t=1}^T \log y_t = AIC + 2 \sum_{t=1}^T \log y_t,<br />
\end{equation}</p>
<p>Обратимся к R. Для нашего примера мы будем использовать данные <span class="lang:r decode:true crayon-inline">longley</span> из пакета <span class="lang:r decode:true crayon-inline">datasets</span>. Для начала оценим две простые модели (аддитивную и мультипликативную):</p>
<pre class="decode">modelAdditive <- lm(GNP~Employed,data=longley)
modelMultiplicative <- lm(log(GNP)~Employed,data=longley)</pre>
<p>Теперь посмотрим на информационные критерии:</p>
<pre class="decode">AIC(modelAdditive)
> 142.7824
AIC(modelMultiplicative)
> -44.5661</pre>
<p>Как видим, значения не сравнимы. Скорректируем второй информационный критерий:</p>
<pre class="decode">
AIC(modelMultiplicative)+2*sum(log(longley$GNP))
> 145.118</pre>
<p>Теперь стало намного лучше! Можем заключить, что по информационному критерию первая модель (аддитивная) лучше второй.</p>
<p>Эти принципы преобразования информационных критериев так же можно применить и для других случаев трансформации (корень из числа или трансформация Бокса-Кокса). Однако в этом случае нужно вывыести более сложные распределения и понять, как они связаны с нормальным, что может быть отдельной нетривиальной задачей.</p>
<p>Сообщение <a href="https://openforecast.org/ru/2018/03/22/additive_vs_multiplicative_aic/">Сравнение аддитивной и мультипликативной регрессий с помощью AIC в R</a> появились сначала на <a href="https://openforecast.org/ru">Open Forecasting</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://openforecast.org/ru/2018/03/22/additive_vs_multiplicative_aic/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Пакет «smooth» для R. Общие параметры. Часть 4. Экзогенные переменные. Продвинутый уровень</title>
		<link>https://openforecast.org/ru/2018/02/10/xreg-advanced/</link>
					<comments>https://openforecast.org/ru/2018/02/10/xreg-advanced/#respond</comments>
		
		<dc:creator><![CDATA[Ivan Svetunkov]]></dc:creator>
		<pubDate>Sat, 10 Feb 2018 15:51:33 +0000</pubDate>
				<category><![CDATA[R]]></category>
		<category><![CDATA[Общая информация]]></category>
		<category><![CDATA[Пакет smooth для R]]></category>
		<category><![CDATA[Экстраполяционные методы]]></category>
		<category><![CDATA[smooth]]></category>
		<guid isPermaLink="false">https://openforecast.org/?p=1663</guid>

					<description><![CDATA[<p>В прошлый раз мы рассмотрели основы по работе с экзогенными переменными в функциях пакета smooth. Сегодня мы поговорим о более продвинутых вещах. Но прежде чем перейти к ним, нам нужно поговорить о вспомогательных функциях, которые реализованы в пакете greybox и используются в smooth. Первая из них называется xregExpander() и позволяет генерировать лаговые переменные на основе [&#8230;]</p>
<p>Сообщение <a href="https://openforecast.org/ru/2018/02/10/xreg-advanced/">Пакет «smooth» для R. Общие параметры. Часть 4. Экзогенные переменные. Продвинутый уровень</a> появились сначала на <a href="https://openforecast.org/ru">Open Forecasting</a>.</p>
]]></description>
										<content:encoded><![CDATA[<p>В прошлый раз мы рассмотрели основы по работе с экзогенными переменными в функциях пакета <span class="lang:r decode:true crayon-inline">smooth</span>. Сегодня мы поговорим о более продвинутых вещах. Но прежде чем перейти к ним, нам нужно поговорить о вспомогательных функциях, которые реализованы в пакете <span class="lang:r decode:true crayon-inline">greybox</span> и используются в <span class="lang:r decode:true crayon-inline">smooth</span>. Первая из них называется <span class="lang:r decode:true crayon-inline">xregExpander()</span> и позволяет генерировать лаговые переменные на основе предоставленного вектора или матрицы. В качестве примера возьмём ряд <span class="lang:r decode:true crayon-inline">BJsales.lead</span>, который мы обсуждали в <a href="/2018/01/15/xreg-basics/">прошлом посте</a>. Предположим, что влияние переменной на продажи носит более сложный характер, чем мы предполагали до того: <span class="lang:r decode:true crayon-inline">BJsales.lead</span> влияет на <span class="lang:r decode:true crayon-inline">BJsales</span> с лагом и 0, 5 и 10 дней. Это означает, что нам нужно учесть этот лаговый эффект, и это как раз то, что позволяет нам делать функция <span class="lang:r decode:true crayon-inline">xregExpander()</span>:</p>
<pre class="decode">newXreg <- xregExpander(BJsales.lead, lags=c(-5,-10))</pre>
<p>Переменная <span class="lang:r decode:true crayon-inline">newXreg</span> представляет собой матрицу, которая содержит оригинальную переменную, а так же её же с лагами 5 и 10. Заметим, что, если бы мы просто сдвинули переменную во времени, то у нас образовались бы пропущенные значения (NAs). Поэтому <span class="lang:r decode:true crayon-inline">xregExpander()</span> заполняет пропущенные значения их прогнозами либо с помощью функции <span class="lang:r decode:true crayon-inline">es()</span>, либо с помощью <span class="lang:r decode:true crayon-inline">iss()</span> (в зависимости от типа переменной). Это так же означает, что, если вы пытаетесь сделать лаговой бинарную переменную, то пропущенные значения будут заменены средним значением (например, 0.7812). Так что будьте внимательны с тем, что получаете на выходе. Возможно, в вашем случае будет правильней заменить эти значения на нули или единицы...</p>
<p>Иногда так же бывают нужны и ведущие переменные (с положительными лагами) - переменные, значение которых в будущем определяет значение некоторой переменной сегодня. Подобные эффекты могут наблюдаться, например, в моделировании эффектов от акций в супермаркетах, когда покупатели ожидают снижения цены на товар через какое-то время. Это всё регулирует по средствам добавления положительных значений в <span class="lang:r decode:true crayon-inline">xregExpander()</span>:</p>
<pre class="decode">newXreg <- xregExpander(BJsales.lead, lags=c(7,-5,-10))</pre>
<p>Значения в этом случае так же сдвигаются, но уже в другую сторону, а недостающие наблюдения заменяются их прогнозными значениями.</p>
<p>После того, как мы трансформировали переменные, мы можем из использовать в функциях пакета <span class="lang:r decode:true crayon-inline">smooth</span> для прогнозирования. Всё, что мы обсуждали в <a href="/2018/01/15/xreg-basics/">прошлом посте</a>, применимо и здесь:</p>
<pre class="decode">es(BJsales, "XXN", xreg=newXreg, h=10, holdout=TRUE)</pre>
<p>Но что нам делать, если в нашем распоряжении несколько переменных, и мы не уверены в том, какие лаги включать? У этой задачи есть много решений, одно из них реализовано в функциях пакета <span class="lang:r decode:true crayon-inline">smooth</span>. Стоит заметить, что это решение не обязательно гарантирует точные прогнозы, но это хоть какое-то решение. Основано оно на работе функции <span class="lang:r decode:true crayon-inline">stepwise()</span> из пакета <span class="lang:r decode:true crayon-inline">greybox</span>, которая осуществляет пошаговый отбор на основе информационных критериев и частной корреляции. Для работы данной функции, нужно, чтобы выходная переменная была в первом столбце матрицы. Идея функции проста, и весь алгоритм сводится к следующему:</p>
<ol>
<li>Строится базовая модель первой переменной от константы (что соответствует простой средней по ряду). Рассчитывается информационный критерий;</li>
<li>Рассчитываются корреляции остатков модели с имеющимися экзогенными переменными;</li>
<li>Строится регрессионная модель выходной переменной от всех уже включённых переменных, плюс той, которая сильнее всего коррелирует с остатками. Для этого используется функция <span class="lang:r decode:true crayon-inline">lm()</span>;</li>
<li>Рассчитывается информационный критерий новой модели, и сравнивается с предыдущим значением. Если новое значение меньше, то происходит переход к шагу (2). Иначе процесс прекращается и выбирается предыдущая модель.</li>
</ol>
<p>Таким образом мы не проводим поиск переменных "вслепую", но осуществляем своеобразный поиск хорошей модели по некоторой траектории: если какая-то значимая часть переменной ещё осталась необъяснённой, то корреляция по остаткам покажет её, а значит и соответствующая переменная будет включена в модель. Использование корреляций позволяет включать только "осмысленные" переменные, а использование информационных критериев позволяет обойти проблему неопределённости статистических гипотез. В целом, функция позволяет найти модель с одним из наименьших информационных критериев в сжатые временные сроки. Это, конечно же, не гарантирует наиболее точные прогнозы, но для этого эволюция как раз и наградила людей мозгом: статистика - это хорошо, но не стоит забывать о здравом смысле!</p>
<p>Взглянем на работу функции на примере с 10 лаговыми и 10 ведущими переменными:</p>
<pre class="decode">newXreg <- as.data.frame(xregExpander(BJsales.lead,lags=c(-10:10)))
newXreg <- cbind(as.matrix(BJsales),newXreg)
colnames(newXreg)[1] <- "y"</pre>
<p>Код выше гарантирует, что в нашем распоряжении будет data frame с красивыми именами, а не какой-нибудь трэш. Замети ещё раз, что для функции <span class="lang:r decode:true crayon-inline">stepwise()</span> важно, чтобы выходная переменная была в первом столбце матрицы.</p>
<pre class="decode">ourModel <- stepwise(newXreg)</pre>
<p>И вот, что у нас получилось в итоге:</p>
<pre>Call:
lm(formula = y ~ xLag4 + xLag9 + xLag3 + xLag10 + xLag5 + xLag6 + 
    xLead9 + xLag7 + xLag8, data = newXreg)

Coefficients:
(Intercept)        xLag4        xLag9        xLag3       xLag10        xLag5        xLag6  
    17.6448       3.3712       1.3724       4.6781       1.5412       2.3213       1.7075  
     xLead9        xLag7        xLag8  
     0.3767       1.4025       1.3370</pre>
<p>Переменные в функции перечислены по мере включения их в модель. Функция работает достаточно быстро, так как ей не приходится проходить через все возможные комбинации моделей.</p>
<p>Вы спросите: ну и что? А вот что! Эти две функции можно использовать вместе с функциями пакета <span class="lang:r decode:true crayon-inline">smooth</span>: в <span class="lang:r decode:true crayon-inline">es()</span>, <span class="lang:r decode:true crayon-inline">ssarima()</span>, <span class="lang:r decode:true crayon-inline">ces()</span> и <span class="lang:r decode:true crayon-inline">ges()</span> реализован механизм выбора переменных на основе <span class="lang:r decode:true crayon-inline">stepwise()</span>, регулируемый с помощью параметра <span class="lang:r decode:true crayon-inline">xregDo</span>, которые по умолчанию задан как "use" (использовать все переменные), но может быть так же принимать значение "select" (выбрать наилучшую модель). В этом случае функция <span class="lang:r decode:true crayon-inline">stepwise()</span> будет применена к остаткам модели, и, когда подходящие переменные будут найдены, итоговая модель будет переоценена для избавления от потенциального смещения в оценках параметров.</p>
<p>Посмотрим, как это работает на том же примере. Для начала просто построим модель со всеми переменными (я уберу от греха подальше первую переменную из уже имеющегося data frame, которая является выходной переменной):</p>
<pre class="decode">newXreg <- newXreg[,-1]
ourModelUse <- es(BJsales, "XXN", xreg=newXreg, h=10, holdout=TRUE, silent=FALSE, xregDo="use", intervals="sp")</pre>
<pre>Time elapsed: 1.13 seconds
Model estimated: ETSX(ANN)
Persistence vector g:
alpha 
0.922 
Initial values were optimised.
24 parameters were estimated in the process
Residuals standard deviation: 0.287
Xreg coefficients were estimated in a normal style
Cost function type: MSE; Cost function value: 0.068

Information criteria:
      AIC      AICc       BIC 
 69.23731  79.67209 139.83673 
95% semiparametric prediction intervals were constructed
100% of values are in the prediction interval
Forecast errors:
MPE: 0%; Bias: 55.7%; MAPE: 0.1%; SMAPE: 0.1%
MASE: 0.166; sMAE: 0.1%; RelMAE: 0.055; sMSE: 0%</pre>
<div id="attachment_1621" style="width: 310px" class="wp-caption alignnone"><a href="https://openforecast.org/wp-content/webpc-passthru.php?src=https://openforecast.org/wp-content/uploads/2018/01/BJsalesETSXUse.png&amp;nocache=1"><img loading="lazy" decoding="async" aria-describedby="caption-attachment-1621" src="https://openforecast.org/wp-content/webpc-passthru.php?src=https://openforecast.org/wp-content/uploads/2018/01/BJsalesETSXUse-300x175.png&amp;nocache=1" alt="" width="300" height="175" class="size-medium wp-image-1621" srcset="https://openforecast.org/wp-content/webpc-passthru.php?src=https://openforecast.org/wp-content/uploads/2018/01/BJsalesETSXUse-300x175.png&amp;nocache=1 300w, https://openforecast.org/wp-content/webpc-passthru.php?src=https://openforecast.org/wp-content/uploads/2018/01/BJsalesETSXUse-768x448.png&amp;nocache=1 768w, https://openforecast.org/wp-content/webpc-passthru.php?src=https://openforecast.org/wp-content/uploads/2018/01/BJsalesETSXUse-1024x597.png&amp;nocache=1 1024w, https://openforecast.org/wp-content/webpc-passthru.php?src=https://openforecast.org/wp-content/uploads/2018/01/BJsalesETSXUse.png&amp;nocache=1 1200w" sizes="auto, (max-width: 300px) 100vw, 300px" /></a><p id="caption-attachment-1621" class="wp-caption-text">Ряд BJsales и модель ETSX со всеми переменными</p></div>
<p>Как видим, прогноз стало более точным, чем он был в <a href="/2018/01/15/xreg-basics/">прошлой статье</a>, в которой мы не использовали лаги. Это означает, что в ряде данных действительно наблюдается влияние лаговых эффектов на продажи. Впрочем, из-за того, что мы включили всё подряд, полученная модель, возможно, стала слишком сильно аппроксимировать ряд, что может плохо сказаться на точности прогнозов. Хорошо бы выкинуть все лишние переменные...</p>
<pre class="decode">ourModelSelect <- es(BJsales, "XXN", xreg=newXreg, h=10, holdout=TRUE, silent=FALSE, xregDo="select", intervals="sp")</pre>
<pre>Time elapsed: 0.98 seconds
Model estimated: ETSX(ANN)
Persistence vector g:
alpha 
    1 
Initial values were optimised.
11 parameters were estimated in the process
Residuals standard deviation: 0.283
Xreg coefficients were estimated in a normal style
Cost function type: MSE; Cost function value: 0.074

Information criteria:
     AIC     AICc      BIC 
54.55463 56.61713 86.91270 
95% semiparametric prediction intervals were constructed
100% of values are in the prediction interval
Forecast errors:
MPE: 0%; Bias: 61.4%; MAPE: 0.1%; SMAPE: 0.1%
MASE: 0.159; sMAE: 0.1%; RelMAE: 0.052; sMSE: 0%</pre>
<div id="attachment_1622" style="width: 310px" class="wp-caption alignnone"><a href="https://openforecast.org/wp-content/webpc-passthru.php?src=https://openforecast.org/wp-content/uploads/2018/01/BJsalesETSXSelect.png&amp;nocache=1"><img loading="lazy" decoding="async" aria-describedby="caption-attachment-1622" src="https://openforecast.org/wp-content/webpc-passthru.php?src=https://openforecast.org/wp-content/uploads/2018/01/BJsalesETSXSelect-300x175.png&amp;nocache=1" alt="" width="300" height="175" class="size-medium wp-image-1622" srcset="https://openforecast.org/wp-content/webpc-passthru.php?src=https://openforecast.org/wp-content/uploads/2018/01/BJsalesETSXSelect-300x175.png&amp;nocache=1 300w, https://openforecast.org/wp-content/webpc-passthru.php?src=https://openforecast.org/wp-content/uploads/2018/01/BJsalesETSXSelect-768x448.png&amp;nocache=1 768w, https://openforecast.org/wp-content/webpc-passthru.php?src=https://openforecast.org/wp-content/uploads/2018/01/BJsalesETSXSelect-1024x597.png&amp;nocache=1 1024w, https://openforecast.org/wp-content/webpc-passthru.php?src=https://openforecast.org/wp-content/uploads/2018/01/BJsalesETSXSelect.png&amp;nocache=1 1200w" sizes="auto, (max-width: 300px) 100vw, 300px" /></a><p id="caption-attachment-1622" class="wp-caption-text">Ряд BJsales и модель ETSX с выбранными переменными</p></div>
<p>Несмотря на то, что по графику тяжело сказать, улучшился ли прогноз или нет, по ошибкам улучшение таки заметно: MASE уменьшилась с 0.166 до 0.159. AICc также уменьшился с 79.67209 до 56.61713. Это из-за того, что вторая модель включает только 8 переменных (вместо 21):</p>
<pre class="decode">ncol(ourModelUse$xreg)
ncol(ourModelSelect$xreg)</pre>
<p>Выбор переменных работает даже в случае с комбинированием прогнозов. Так экзогенные переменные выбираются для каждой модели отдельно, после чего производятся прогнозы, которые затем и комбинируются на основе весов IC. Пример:</p>
<pre class="decode">ourModelCombine <- es(BJsales, c("ANN","AAN","AAdN","CCN"), xreg=newXreg, h=10, holdout=TRUE, silent=FALSE, xregDo="s", intervals="sp")</pre>
<pre>Time elapsed: 1.46 seconds
Model estimated: ETSX(CCN)
Initial values were optimised.
Residuals standard deviation: 0.272
Xreg coefficients were estimated in a normal style
Cost function type: MSE

Information criteria:
(combined values)
     AIC     AICc      BIC 
54.55463 56.61713 86.91270 
95% semiparametric prediction intervals were constructed
100% of values are in the prediction interval
Forecast errors:
MPE: 0%; Bias: 61.4%; MAPE: 0.1%; SMAPE: 0.1%
MASE: 0.159; sMAE: 0.1%; RelMAE: 0.052; sMSE: 0%</pre>
<p>Учитывая то, что модель ETSX(A,N,N) оказалась значительно лучше других моделей с точки зрения AICc, вес этой модели оказался наибольшим. Поэтому прогнозы ourModelSelect и ourModelCombine фактически идентичны. Начиная с версии v2.3.2, функция <span class="lang:r decode:true crayon-inline">es()</span> возвращает матрицу с информационными критериями для моделей, которые были оценены в процессе, так что мы можем посмотреть на AICc разных моделей:</p>
<pre class="decode">ourModelCombine$ICs</pre>
<pre>               AIC      AICc      BIC
ANN       54.55463  56.61713  86.9127
AAN      120.85273 122.91523 153.2108
AAdN     107.76905 110.22575 143.0688
Combined  54.55463  56.61713  86.9127</pre>
<p>Как видим, информационные критерии модели ETS(A,N,N) действительно оказались значительно ниже критериев других моделей, что привело к её превалированию в финальной комбинации.</p>
<p>Обратим внимание, что комбинация прогнозов - это не то же самое, что и комбинации моделей. Эта функция пока не доступна в функциях пакета <span class="lang:r decode:true crayon-inline">smooth</span>, и я не уверен, что она когда-нибудь появится.</p>
<p>В заключении заметим, что метод выбора в пакете ставит на первое место динамическую часть модель (в нашем примере - это ETS), нежели часть с экзогенными переменными. Это соответствует подходу прогнозистов к моделированию: мы используем экзогенные переменные как инструмент для объяснения тех характеристик временного ряда, которые обычная модель не смогла выловить. Классический подход эконометристов обычно подразумевает обратное: построение регрессии с последующим включением динамических компонент (например, авторегрессии). У такого подхода другая цель, поэтому и результаты будут другими.</p>
<p>Сообщение <a href="https://openforecast.org/ru/2018/02/10/xreg-advanced/">Пакет «smooth» для R. Общие параметры. Часть 4. Экзогенные переменные. Продвинутый уровень</a> появились сначала на <a href="https://openforecast.org/ru">Open Forecasting</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://openforecast.org/ru/2018/02/10/xreg-advanced/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Пакет «smooth» для R. Общие параметры. Часть 3. Экзогенные переменные. Основы</title>
		<link>https://openforecast.org/ru/2018/01/15/xreg-basics/</link>
					<comments>https://openforecast.org/ru/2018/01/15/xreg-basics/#comments</comments>
		
		<dc:creator><![CDATA[Ivan Svetunkov]]></dc:creator>
		<pubDate>Mon, 15 Jan 2018 14:42:01 +0000</pubDate>
				<category><![CDATA[R]]></category>
		<category><![CDATA[Общая информация]]></category>
		<category><![CDATA[Пакет smooth для R]]></category>
		<category><![CDATA[Экстраполяционные методы]]></category>
		<category><![CDATA[ARIMA]]></category>
		<category><![CDATA[ETS]]></category>
		<category><![CDATA[smooth]]></category>
		<guid isPermaLink="false">https://openforecast.org/?p=1632</guid>

					<description><![CDATA[<p>Одно из преимуществ функций пакета smooth &#8212; это возможность использовать экзогенные переменные (регрессоры). Это потенциально может привести к росту точности прогнозов, в случае, если у вас в распоряжении есть хорошие оценки будущих значений включённых переменных. Например, в случае с ритейлом в качестве экзогенной переменной может выступать наличие акции в магазине (&#171;купите один шампунь, получите ящик [&#8230;]</p>
<p>Сообщение <a href="https://openforecast.org/ru/2018/01/15/xreg-basics/">Пакет «smooth» для R. Общие параметры. Часть 3. Экзогенные переменные. Основы</a> появились сначала на <a href="https://openforecast.org/ru">Open Forecasting</a>.</p>
]]></description>
										<content:encoded><![CDATA[<p>Одно из преимуществ функций пакета smooth &#8212; это возможность использовать экзогенные переменные (регрессоры). Это потенциально может привести к росту точности прогнозов, в случае, если у вас в распоряжении есть хорошие оценки будущих значений включённых переменных. Например, в случае с ритейлом в качестве экзогенной переменной может выступать наличие акции в магазине (&#171;купите один шампунь, получите ящик пива в подарок&#187;). Эту информацию мы можем знать заранее, причём со 100% точностью, если мы планируем проводить похожие акции в будущем. И, конечно же, использование этой информации должно повысить точность прогнозов по нашей модели.</p>
<p>Для подобных целей в R уже есть функция <span class="lang:r decode:true crayon-inline">arima()</span> из пакета <span class="lang:r decode:true crayon-inline">stats</span>, но, к сожалению, любимая практикующими прогнозистами модель экспоненциального сглаживания (<span class="lang:r decode:true crayon-inline">ets()</span> из пакета <span class="lang:r decode:true crayon-inline">forecast</span>) не поддерживает экзогенные переменные. Это была одна из причин, почему я взялся за разработку функций пакета <span class="lang:r decode:true crayon-inline">smooth</span>. Теперь все функции в пакете (кроме <span class="lang:r decode:true crayon-inline">sma()</span>) предоставляют возможность по включению экзогенных переменных.</p>
<p>В <span class="lang:r decode:true crayon-inline">smooth</span> реализовано две модели для работы с экзогенными переменными: модель с аддитивными и с мультипликативными ошибками. Первая формулируется следующим образом:<br />
\begin{equation} \label{eq:additive}<br />
	y_t = w&#8217; v_{t-l} + a_1 x_{1,t} + a_2 x_{2,t} + … + a_k x_{k,t} + \epsilon_t ,<br />
\end{equation}<br />
где \(a_1, a_2, …, a_k\) &#8212; параметры соответствующих регрессоров \(x_{1,t}, x_{2,t}, …, x_{t,k}\). Все остальные переменные мы уже обсуждали <a href="/2016/11/02/smooth-package-for-r-es-function-part-ii-pure-additive-models-ru/">в предыдущих статьях</a>.<br />
Вторая модель выглядит немного по-другому, так как она основана на <a href="/2016/11/18/smooth-package-for-r-es-function-part-iii-pure-multiplicative-models-ru/">мультипликативной ETS</a>:<br />
\begin{equation} \label{eq:multiplicative}<br />
	\log y_t = w&#8217; \log(v_{t-1}) + a_1 x_{1,t} + a_2 x_{2,t} + … + a_k x_{k,t} + \log(1 + \epsilon_t) ,<br />
\end{equation}<br />
Она может быть так же представлена в следующем виде:<br />
\begin{equation} \label{eq:multiplicativeAlternative}<br />
	y_t =\exp \left({w&#8217; \log(v_{t-1})} \right) \exp(a_1 x_{1,t}) \exp(a_2 x_{2,t}) \dots \exp(a_k x_{k,t}) (1 + \epsilon_t).<br />
\end{equation}<br />
Эта модель соответствует лог-линейной. Такая форма принята для того, чтобы в качестве экзогенных можно было бы использовать фиктивные переменные. Если вам нужна лог-лог модель, то для этого достаточно всего лишь прологарифмировать экзогенную переменную перед использованием её в функции.</p>
<p>Важно отметить, что смешанные модели могут вызвать проблемы, так как в таком случае некоторые компоненты складываются, а другие &#8212; перемножаются. Поэтому я бы рекомендовал использовать либо <a href="/2016/11/02/smooth-package-for-r-es-function-part-ii-pure-additive-models-ru/">чистые аддитивные</a>, либо <a href="/2016/11/18/smooth-package-for-r-es-function-part-iii-pure-multiplicative-models-ru/">чистые мультипликативные</a> ETSX (<a href="/2017/01/24/smooth-package-for-r-es-function-part-iv-model-selection-and-combination-of-forecasts-2/">в статье про выбор моделей</a> описано, как можно осуществить выбор на основе чистых моделей).</p>
<p>Итак, для того, чтобы построить модель с заданными регрессорами, достаточно просто передать в функцию вектор, матрицу либо data.frame: </p>
<pre class="decode">ourModel <- es(BJsales, "XXN", xreg=BJsales.lead, h=10, holdout=TRUE, silent=FALSE)</pre>
<pre>Estimation progress: 100%... Done! 
Time elapsed: 0.27 seconds
Model estimated: ETSX(AAdN)
Persistence vector g:
alpha  beta 
0.939 0.301 
Damping parameter: 0.877
Initial values were optimised.
7 parameters were estimated in the process
Residuals standard deviation: 1.381
Xreg coefficients were estimated in a normal style
Cost function type: MSE; Cost function value: 1.811

Information criteria:
     AIC     AICc      BIC 
494.4490 495.2975 515.0405 
Forecast errors:
MPE: 1.2%; Bias: 91.3%; MAPE: 1.3%; SMAPE: 1.3%
MASE: 2.794; sMAE: 1.5%; RelMAE: 0.917; sMSE: 0%</pre>
<div id="attachment_1623" style="width: 310px" class="wp-caption alignnone"><a href="/wp-content/uploads/2018/01/BJsalesETSXSimple.png"><img loading="lazy" decoding="async" aria-describedby="caption-attachment-1623" src="/wp-content/uploads/2018/01/BJsalesETSXSimple-300x175.png" alt="" width="300" height="175" class="size-medium wp-image-1623" srcset="https://openforecast.org/wp-content/webpc-passthru.php?src=https://openforecast.org/wp-content/uploads/2018/01/BJsalesETSXSimple-300x175.png&amp;nocache=1 300w, https://openforecast.org/wp-content/webpc-passthru.php?src=https://openforecast.org/wp-content/uploads/2018/01/BJsalesETSXSimple-768x448.png&amp;nocache=1 768w, https://openforecast.org/wp-content/webpc-passthru.php?src=https://openforecast.org/wp-content/uploads/2018/01/BJsalesETSXSimple-1024x597.png&amp;nocache=1 1024w, https://openforecast.org/wp-content/webpc-passthru.php?src=https://openforecast.org/wp-content/uploads/2018/01/BJsalesETSXSimple.png&amp;nocache=1 1200w" sizes="auto, (max-width: 300px) 100vw, 300px" /></a><p id="caption-attachment-1623" class="wp-caption-text">BJsales series and ETSX with a leading indicator</p></div>
<p>В этом примере мы используем данные о продажах из книги Box & Jenkins (1976). Я попросил функцию использовать провести процедуру ретропрогноза и сделать прогноз на 10 шагов вперёд, так что последние 10 наблюдений переменной <span class="lang:r decode:true crayon-inline">BJsales.lead</span> используются для построения прогнозов. Функция построила модель и доложила нам, что параметры были оценены обычным методом (7 parameters were estimated in the process). Это значит, что мы предполагаем, что коэффициенты при регрессорах не меняются во времени. Альтернативный этому подход будет рассмотрен когда-нибудь в будущем.</p>
<p>Судя по всему, выбранная модель ETS(A,Ad,N) дала не самые точные, да ещё и смещённые прогнозы (систематическое отклонение от фактических значений в проверочной выборке). Пока что особых улучшений от включения переменной не видно...</p>
<p>Если в какой-то момент времени вы, вдруг, забудете о том, какая именно модель перед вами, вы можете воспользоваться функцией <span class="lang:r decode:true crayon-inline">formula()</span>, которая в случае с функциями <span class="lang:r decode:true crayon-inline">smooth</span> носит чисто описательный характер:</p>
<pre class="decode">formula(ourModel)</pre>
<pre>"y[t] = l[t-1] + b[t-1] + a1 * x[t] + e[t]"</pre>
<p>Функция рассказала нам, что уровень l[t-1], тренд b[t-1], экзогенная переменная "x[t]" и ошибка в нашей модели складываются. Если бы мы передали матрицу с экзогенными переменными или же построили модель с динамически меняющимися параметрами, то это было бы отражено в формуле. Использовать эту формулу так же, как и это сделается в lm(), к сожалению, нельзя.</p>
<p>Для сравнения построим следующую смешанную модель и посмотрим на её формулу:</p>
<pre class="decode">ourModel <- es(BJsales, "MAN", xreg=BJsales.lead, h=10, holdout=TRUE)
formula(ourModel)</pre>
<pre>"y[t] = (l[t-1] + b[t-1]) * exp(a1 * x[t]) * e[t]"</pre>
<p>Как видим, вначале тренд и уровень складываются, а потом это всё умножается на экспоненту нашей переменной. Если по какой-то причине тренд будет негативным, а уровень окажется близок к нулю, то экзогенная переменная будет умножена на отрицательное число. В результате получится бессмысленный прогноз. Это одна из причин, почему я не люблю смешанные модели и говорю, что использовать их надо с осторожностью.</p>
<p>Однако, вернёмся к нашим баранам. Если в нашем распоряжении нет значений экзогенной переменной для проверочной части выборки, то функции пакета <span class="lang:r decode:true crayon-inline">smooth</span> автоматически построят прогнозы для каждой из экзогенных переменных с помощью <span class="lang:r decode:true crayon-inline">es()</span> или <span class="lang:r decode:true crayon-inline">iss()</span> в зависимости от того, имеем мы дело с обычной или же с бинарной переменной. В последнем случае в качестве прогноза будет получена условная средняя, поэтому не удивляйтесь, если для вашей фиктивной переменной прогнозом будет что-нибудь типа 0,784. Так что не стоит использовать функцию вслепую, когда <span class="lang:r decode:true crayon-inline">holdout=FALSE</span>, будьте осторожны. Вот как функция работает в этом случае:</p>
<pre class="decode">es(BJsales, "XXN", xreg=BJsales.lead, h=10, holdout=FALSE, silent=FALSE)</pre>
<p>Нам должны сообщить о том, что функция сделала для нас (построила прогнозы экзогенных переменных):</p>
<pre>Warning message:
xreg did not contain values for the holdout, so we had to predict missing values.</pre>
<p>Если ваши переменные по размеру превышают выходную переменную, то функция удалит последние лишние наблюдения:</p>
<pre class="decode">ourModel <- es(BJsales[1:140], "XXN", xreg=BJsales.lead, h=10, holdout=TRUE)</pre>
<p>и сообщит нам об этом:</p>
<pre>Warning message:
xreg contained too many observations, so we had to cut off some of them.</pre>
<p>Как видите, функцию можно использовать напрямую, но, если вам хочется работать с <span class="lang:r decode:true crayon-inline">forecast()</span> (что совершенно необязательно), то это можно сделать так:</p>
<pre class="decode">forecast(ourModel, h=10, xreg=BJsales.lead)</pre>
<p>Из-за того, как реализовано использование экзогенных переменных в функциях пакета <span class="lang:r decode:true crayon-inline">smooth</span>, переменная <span class="lang:r decode:true crayon-inline">xreg</span> должна содержать все значения, а не только те, которые соответствуют проверочной выборке. Если вы вместо <span class="lang:r decode:true crayon-inline">xreg</span> передадите значения из проверочной выборки, то функция решит, что у вас мало наблюдений и построит прогнозы.</p>
<p>Я бы рекомендовал плюнуть на функцию <span class="lang:r decode:true crayon-inline">forecast()</span> и использовать <span class="lang:r decode:true crayon-inline">es()</span>, <span class="lang:r decode:true crayon-inline">ssarima()</span> и другие функции пакета <span class="lang:r decode:true crayon-inline">smooth</span> напрямую. Так вы сможете подготовить свои переменные и использовать их напрямую без дополнительных строк кода.</p>
<p>Аналогично тому, как это обсуждалось <a href="/2017/06/11/prediction-intervals/">в прошлой статье</a>, вы можете попросить функцию построить прогнозные интервалы. Только имейте в виду, что параметрические интервалы на данный момент не очень точны, так как не берут в расчёт возможный корреляции между экзогенными переменными и компонентами ETS. Сделать это сложно, поэтому эта функция и не реализована. Поэтому я бы рекомендовал в случае с ETSX, ARIMAX и пр. строить полупараметрические и непараметрические интервалы.</p>
<p>Наконец, вы всегда можете задать параметры для экзогенных переменных вручную, через переменную <span class="lang:r decode:true crayon-inline">initialX</span>:</p>
<pre class="decode">ourModel <- es(BJsales, "XXN", xreg=BJsales.lead, h=10, holdout=T, initialX=c(-1))</pre>
<p>Помимо всего этого, функции достаточно умны, чтобы определить, коррелируют ли переданные регрессоры друг с другом и есть ли в них дисперсия. Если что-то из переданного функции не так, она выкинет те переменные, которые вызывают проблемы:</p>
<pre class="decode">es(BJsales, "XXN", xreg=cbind(BJsales.lead,BJsales.lead), h=10, holdout=TRUE)</pre>
<pre>Warning message:
Some exogenous variables were perfectly correlated. We've dropped them out.</pre>
<p>Из-за того, что мы включили BJsales.lead дважды, регрессор вызвал совершенную мультиколлинеарность, поэтому функция выкинула один из них.</p>
<pre class="decode">es(BJsales, "XXN", xreg=cbind(BJsales.lead,rep(100,150)), h=10, holdout=TRUE)</pre>
<pre>Warning message:
Some exogenous variables do not have any variability. Dropping them out.</pre>
<p>А тут функция заметила, что вторая переменная постоянна, а значит и не может быть использована для моделирования, и, опять же, выкинула её.</p>
<p>Если вы случайно включите выходную переменную (в нашем примере это BJsales) в число регрессоров, то функция так же выкинет её:</p>
<pre class="decode">es(BJsales, "XXN", xreg=cbind(BJsales,BJsales.lead), h=10, holdout=TRUE)</pre>
<pre>Warning message:
One of exogenous variables and the forecasted data are exactly the same. We have dropped it.</pre>
<p>На этом основы заканчиваются. Далее мы перейдём к более продвинутым и интересным аспектам по использованию экзогенных переменных в функциях пакета <span class="lang:r decode:true crayon-inline">smooth</span>.</p>
<p>Сообщение <a href="https://openforecast.org/ru/2018/01/15/xreg-basics/">Пакет «smooth» для R. Общие параметры. Часть 3. Экзогенные переменные. Основы</a> появились сначала на <a href="https://openforecast.org/ru">Open Forecasting</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://openforecast.org/ru/2018/01/15/xreg-basics/feed/</wfw:commentRss>
			<slash:comments>5</slash:comments>
		
		
			</item>
	</channel>
</rss>
