Прогноз потребительских расходов муниципалитетов и раннее обнаружение структурных сдвигов по данным СберИндекса
Forecasting municipal consumer spending and detecting structural breaks early with SberIndex data
У каждого муниципалитета в данных СберИндекса всего 24 месяца наблюдений, зато муниципалитетов около двух тысяч. Внутри одного ряда нельзя надёжно оценить ни сезонность, ни шум, ни точку разлома. Рабочий тезис: информацию надо занимать поперёк панели, а не вдоль ряда. Первый прогон его подтверждает.
Each municipality in the SberIndex data has only 24 monthly observations, but there are about two thousand municipalities. Within a single series one cannot reliably estimate seasonality, noise or a break point. The working thesis: borrow information across the panel rather than along the series. The first run supports it.
Это рабочая версия. Даты в реестре событий ещё сверяются по первоисточникам, новости в проверке детекторов смоделированы, модели-основы (Chronos, TimesFM) пока не запускались. Числа обновятся после финального прогона.
This is a working version. Event dates in the registry are still being checked against primary sources, the news in the detector test is simulated, and foundation models (Chronos, TimesFM) have not yet been run. Figures will be updated after the final run.
Основной ряд — «Потребительские безналичные расходы на уровне муниципальных образований» СберИндекса: 303 126 наблюдений, январь 2023 — декабрь 2024, шесть категорий (все категории, продовольствие, здоровье, общественное питание, транспорт, маркетплейсы), по 2 190 рядов в каждой. Файл выгрузки зафиксирован контрольной суммой sha256, чтобы результат воспроизводился на той же версии данных.
The core series is SberIndex's "Cashless consumer spending at the municipal level": 303,126 observations, January 2023 to December 2024, six categories (all categories, food, health, restaurants, transport, marketplaces), 2,190 series in each. The data file is pinned by a sha256 checksum so that results reproduce on the same data version.
Скользящий бэктест: прогноз строится из июня, июля, августа и сентября 2024 года на один, два и три месяца вперёд, 400 случайных МО, 4 800 пар «МО — точка — горизонт». Каждая модель видит только данные до точки прогноза.
Rolling backtest: forecasts are made from June, July, August and September 2024, one to three months ahead, for 400 random municipalities — 4,800 municipality–origin–horizon pairs. Each model sees only data up to its forecast origin.
Сезонный наивный прогноз (MAE 4 332) не показан: он в три раза хуже Prophet и сжал бы шкалу. Бустинг без признаков событий совпадает с бустингом с ними (1 260).
The seasonal naive forecast (MAE 4,332) is omitted: it is three times worse than Prophet and would compress the scale. Boosting without event features matches boosting with them (1,260).
| Модель | Model | Идея | Idea | MAE | R² прироста | R² growth |
|---|---|---|---|---|---|---|
| ets_relative | ETS на отклонении МО от медианного; сезонность — у панели | ETS on the deviation from the median municipality; seasonality from the panel | 932 | 0,24 | ||
| snaive_growth | прошлогодний уровень × годовой прирост за 3 месяца | last year's level × 3-month average annual growth | 1 021 | 0,10 | ||
| lgbm | глобальный бустинг, поправка к предыдущей модели | global boosting, a correction to the model above | 1 260 | −0,19 | ||
| prophet | Prophet на каждом ряду — базовая модель конкурса | Prophet per series — the contest baseline | 1 456 | −0,70 |
R² прироста — доля дисперсии годового прироста, объяснённая моделью. R² уровня здесь у всех моделей 0,97–0,99 и ничего не различает.
R² growth is the share of variance in annual growth explained by the model. R² on levels is 0.97–0.99 for every model and does not discriminate.
Разрыв растёт с горизонтом: на месяц вперёд панельная модель точнее Prophet на 14 %, на три месяца ошибка Prophet почти вдвое больше. Prophet пытается оценить годовую сезонность по 24 точкам и не справляется. Глобальный бустинг пока хуже простой модели, к которой он строит поправку, — это открытый пункт.
The gap widens with the horizon: one month ahead the panel model is 14 % more accurate than Prophet; three months ahead Prophet's error is almost twice as large. Prophet tries to estimate annual seasonality from 24 points and fails. Global boosting is still worse than the simple model it corrects — an open item.
Все детекторы работают с одним рядом — годовым приростом МО за вычетом прироста медианного МО в том же месяце:
All detectors work on the same series — a municipality's annual growth minus the median municipality's growth in the same month:
Годовой прирост убирает сезонность, вычитание медианы — общероссийские движения. Декабрьский пик или рост ставки, задевший всех, для отдельного МО шоком не считается.
Annual growth removes seasonality; subtracting the median removes nationwide movements. A December peak or a rate hike that hit everyone is not a shock for any single municipality.
Настоящих дат шоков по МО нет, поэтому проверка полусинтетическая: в половину из 600 реальных рядов вносится ступенька уровня на ±5, ±10 или ±20 % в случайный месяц апреля–декабря 2024 года, три повтора.
There are no true shock dates for municipalities, so the test is semi-synthetic: half of 600 real series receive a level step of ±5, ±10 or ±20 % in a random month of April–December 2024, three repeats.
| Детектор | Detector | Точность | Precision | Полнота | Recall | F1 | Ложных на 100 | False per 100 |
|---|
«Ложных на 100» — тревоги на 100 ряд-месяцев в рядах без внесённого шока. В этих рядах есть и собственные настоящие шоки, поэтому точность занижена. Строка «+ новости» — тот же BOCPD, которому заранее сообщают о возможном событии (60 % шоков имеют новость, 5 % новостей ложные).
"False per 100" counts alarms per 100 series-months in series with no injected shock. Those series contain genuine shocks of their own, so precision is understated. The "+ news" row is the same BOCPD told in advance about a possible event (60 % of shocks come with news, 5 % of news items are false).
Шоки от 10 % обнаруживаются в месяц появления. Панельный детектор находит 96–99 % шоков в 20 % и 60–63 % шоков в 10 %, но почти не видит сдвиги в 5 %: на коротком ряду они неотличимы от шума.
Shocks of 10 % or more are detected in the month they occur. The panel detector finds 96–99 % of 20 % shocks and 60–63 % of 10 % shocks, but hardly sees 5 % shifts: on a short series they are indistinguishable from noise.
В апреле 2024 года в Оренбургской области произошёл паводок, пострадавшие получали выплаты. Если это видно в расходах, прирост Орска относительно медианного МО должен подскочить после апреля.
In April 2024 the Orenburg region was flooded and affected residents received payments. If this shows in spending, Orsk's growth relative to the median municipality should jump after April.
Орск подскакивает в мае: с +5,1 до +9,5 п. п. и держится выше +9 в июне, затем постепенно возвращается. В Новотроицке после апреля продолжается снижение, в Оренбурге небольшой подъём в июне. Ни один детектор не дал тревоги по Орску: Орск и до паводка рос быстрее медианы, и скачок на 4,4 п. п. укладывается в его собственный разброс. Это ограничение метода, и именно здесь нужна новость: зная о выплатах заранее, детектор может снизить порог.
Orsk jumps in May, from +5.1 to +9.5 pp, stays above +9 in June, and then gradually returns. Novotroitsk keeps declining after April; Orenburg shows a small rise in June. No detector raised an alarm for Orsk: it was already growing faster than the median before the flood, and a 4.4 pp jump is within its own spread. This is a limitation of the method, and exactly where news helps: knowing about the payments in advance, a detector can lower its threshold.
Даты паводка и перечень затронутых МО ещё сверяются по первоисточникам.
Flood dates and the list of affected municipalities are still being checked against primary sources.
Весь конвейер — загрузка с проверкой sha256, прогнозы, детекторы, рисунки — запускается одной командой python -m sshocks.cli all. Параметры лежат в YAML, сырые данные СберИндекса в репозиторий не кладутся: их скачивает загрузчик. Код, дизайн исследования и разбор первого прогона — в репозитории github.com/rav11l/sberindex-shocks.
The whole pipeline — download with sha256 check, forecasts, detectors, figures — runs with one command, python -m sshocks.cli all. Parameters live in YAML; raw SberIndex data is not stored in the repository but fetched by the loader. Code, research design and the first-run analysis are at github.com/rav11l/sberindex-shocks.
Digital Economy Lab · Равиль Ахтямов, к. э. н. · ORCID 0000-0002-0783-8573
Данные: СберИндекс, sberindex.ru. Код — MIT, текст — CC BY 4.0.
Digital Economy Lab · Ravil Akhtyamov, PhD in Economics · ORCID 0000-0002-0783-8573
Data: SberIndex, sberindex.ru. Code under MIT, text under CC BY 4.0.