- Регистрация
- 12.04.17
- Сообщения
- 19.095
- Реакции
- 107
- Репутация
- 0

ВСТУПЛЕНИЕ
В каком году — рассчитывай,
В какой земле — угадывай,
На столбовой дороженьке
Сошлись семь мужиков:
Семь временнообязанных,
Подтянутой губернии,
Уезда Терпигорева,
Пустопорожней волости,
Из смежных деревень:
Заплатова, Дырявина,
Разутова, Знобишина.
Горелова, Неелова —
Неурожайка тож,
Сошлися — и заспорили:
Кому живется весело,
Вольготно на Руси?
Н.Некрасов
Пару месяцев назад на одном IT мероприятии мне довелось лицезреть в работе Pandas. Парень, который с ним работал не делал ничего особенно удивительного. Но простые сложения значений, вычисления средних, группировки производились так виртуозно, что, даже при всей своей предвзятости к Питону, я был очарован. Манипуляции выполнялись на довольно приличных датасетах по данным капитального ремонта за период кажется с 2004 по 2019 год. Сотни тысяч строк, но все работало очень быстро.
В общем когда мне еще через пару месяцев пришлось кое-что анализировать, я решил попробовать сделать это с помощью Pandas. Провозился пару дней с тем, что с помощью Excel я бы смог сделать за день. Тем не менее мне удалось.
С апреля мы все сидим на карантине. Сидел я и думал, что бы мне такое сделать, чтобы не очень сложное и чтобы стильно и модно было. К тому времени я уже видел кучу всякой инфографики про коронавирус, про пожары в лесу, про выборы. Делать то, что уже делали не хотелось, да и браться сразу за сложное не решался, сомневаясь, что смогу закончить. Тут мне попалась какая-то статья про уже отшумевшее явление "barchart race" или по-русски "гонки столбчатых диаграмм". Вы можете подумать, что эта статья будет про barchart race. Да, но только отчасти. Barchart race будет только в конце, а статья скорее о том, как не обладая, какими-то выдающимися способностями и знаниями в области матана и прочей черной магии, можно сделать анализ
Идея
Сами "гонки" мне уже не раз попадались в ленте Твиттера, тогда я даже не знал, что это вот называется гонками. А узнал я об этом, когда прочитал очередную статью, возможно даже здесь на Хабре. Не помню точно как это было, помню только, что я сильно воодушевился возможностью сорвать покровы и стать первооткрывателем. Идея сделать свою гонку на базе форм бюджетной отчетности по исполнению федерального бюджета. Я довольно давно так или иначе касаюсь сферы госфинансов, но годного сравнительного анализа мне видеть не доводилось, что сильно увеличивало шансы сделать что-то новое. Взять за источник формы бюджетной отчетности круто по двум причинам:
- Эти бюрократические бумажки сильно формализованы, что делает их чуть ли не единственным государственным сырьем машиночитаемых данных.
- Отчетность делается годами с монотонной регулярностью, те кто эту отчетность готовит в стопятидесятый раз вообще не переживает, что в ней может быть что-то ценное. Поэтому отчетность в свободном доступе на сайте Казначейства и Минфина.
План был такой:
Взять как можно более длинный временной диапазон данных об исполнении федерального бюджета России. Посмотреть из каких показателей можно сделать красочную гонку ну и сделать эту гонку.
Коротко о бюджетной классификации
Как говорит наш президент: "Буду краток". Постараюсь только самую суть. Говорим только о бюджетных расходах. Все бюджетные расходы предусматриваются на какую-то конкретную цель. Эта запланированная цель отражается в коде бюджетной классификации.
КБК — 20-ти разрядный цифровой код, отражающий цель расходов, их экономический и функциональный характер. В теории, зная КБК каких-то определенных расходов, можно определить не только их цель но и способ их расходования (например, заработная плата), отрасль экономики и функцию государства, к которой расход относится и, наконец, ведомство через которое эти расходы будут производится.
По-умному это все называется функциональная, экономическая и ведомственная классификация бюджетных расходов. Структура КБК постоянно меняется, более или менее неизменными являются первые 7 разрядов КБК, а имено первые 3 — код ППП (перечень прямых получателей) разряды 4, 5 — раздел, 6, 7 — подраздел. Остальные разряды КБК меняются так часто, что даже не заглядывая в данные, можно быть уверенным, что сопоставить расходы даже двух соседних лет будет почти невозможно.
Сейчас структура КБК расходов федерального бюджета выглядит так:

- Ведомственная классификация
- ППП — код ведомства
- Функциональная классификация
- РЗ — раздел
- ПР — подраздел
- ЦСР — целевая статья расходов
- ГП — госпрограмма
- ПП — подпрограмма
- ОМ — основное мероприятие
- НП — направление расходов
- Экономическая класссификация
- ВР — вид расходов
Классификация представляет собой иерархическую структуру, чем глубже ты погружаешься, тем более конкретными становятся расходы.
Мой первоначальный план был в том, чтобы сгруппировать расходы на уровне раздела и подраздела. Я наивно полагал, что бюрократам будет лень выдумывать новые коды и они из года в год будут использовать одни и те же. Я был прав только отчасти. Почти неизменными являются только коды ведомств. Пока ведомство существует оно имеет один и тот же код, когда ведомство умирает, его код уже не присваивается новому ведомству. Всего из 3 десятичных разрядов можно получить 10 в третьей степени вариантов, то есть тысячу комбинаций. Сейчас максимальный код у Министерства спорта. Номерок блатной три семерочки под силу пробить не каждому министру. Тут код пробивал еще сам Мутко. В бытность Госкомспорта это ведомство носило скромный номер 164. Именно с приходом Мутко Минспорта получило счастливые три семерки.
Часть первая. Наивная лобовая атака.
Довольно быстро мне удалось собрать у Казначейства и Минфина различные формы бюджетной отчетности по исполнению бюджета. Мой выбор пал на отчет по форме ОКУД 0507011, отчетность по этой форме мне удалось найти с 2002 по 2019. Остальные формы отчета об исполнении бюджета начинались где-то с 2007 года.
Попытка сопоставить коды сразу по подразделам с треском провалилась, мне не удалось найти ни одного кода подраздела, который бы не изменил своего содержания с 2002 по 2019 год.
Например, код РЗПР 0501 в 2003 был кодом "Органы внутренних дел", а в 2006 уже "Жилищное хозяйство". Даже относительно стабильные коды в 01 разделе менялись. 0103 в 2002 году был "Функционирование исполнительных органов государственной власти", а в 2005 стал уже "Функционирование законодательных (представительных) органов государственной власти и местного самоуправления".
С разделами не получилось, но я был готов к такому повороту. Следующая попытка была сгруппироваться уровнем выше, по разделам, но и здесь меня ждал неприятный сюрприз. Раздел 02 успел побыть национальной обороной и судебной властью, а раздел 03 был и международной и правоохранительной деятельностью. Менялись не только коды но и названия поэтому привязаться по названиям тоже не получалось. Такого поворота я не ждал, работа остановилась на несколько дней.
Поковыряв матчасть я наткнулся на очень интересные международные документы. Оказывается международное сообщество, в лице ООН, ОЭСР и МВФ озабоченные необходимостью сбора и анализа данных по государственным финансам разработали и в 1986 году издали эпохальный документ под названием A Manual on Government Finance Statistics (GFSM 1986).
You must be registered for see links
Труд оказался настолько удачным, что изменения в него вносились лишь дважды: в 2001 году и в 2014 году. Именно GFSM 2014 является действующей редакцией.
В составе этого мануала в 4 части есть глава "Functional classification", в которой сформулирована функциональная классификация государственных расходов. Называется она Classicifation of the Functions of Government или сокращенно COFOG. По-русски это назвали Классификацией функций органов государственного управления (КФОГУ). КФОГУ это достаточно общая, чтобы быть универсальной для любой страны иерархическая классификация. Коды КФОГУ состоят из 4 разрядов: первые 2 разряда — раздел, 3 разряд это глава и 4 разряд это класс. Судя по некоторому сходству и в нумерации и по содержанию российского КБК с международным КФОГУ, наш Минфин пытается приблизить КБК к международной классификации. Попытки продолжаются как минимум с 2002 года. Минфин с завидным упороством год, через год меняет содержание разделов и подразделов КБК, не говоря уже обо всем остальном.
В результате в России нет ни собственной функциональной классификации, ни международной.
В общем я решил привязать подразделы наших КБК к этой международной классификации COFOG, чтобы потом сгруппировать расходы именно по разделам COFOG.
Учитывая, что разделы и подразделы в российском КБК постоянно меняются, привязывать коды COFOG я решил не к кодам КБК, а к названиям. Для этого я собрал перечень всех уникальных названий подразделов отечественного КБК и сматчил их через самое короткое расстояние Левенштейна. Результат получился не очень точный, ошибки пришлось исправлять вручную. Пару дней я возился расставляя в таблице названий российских подразделов КБК правильные коды КФОГУ. Как же я обломался, когда стало понятно, что сделать это вообще невозможно, потому что в России по подразделу "Другие расходы" могут проходить и расходы на армию и на экологию, а по разделу 01 (Общие расходы) прохотят расходы из тематических разделов. Понять из каких именно тематических разделом эти расходы можно только, если каждый подраздел рассматривать отдельно по каждому ведомству, что кратно увеличивает количество. Но главное, что я уже начал сопоставление без кодов ведомств. Тут я совсем приуныл. Анализ расходов нашего государства на решение своих социально-экономических задач не удался. Снова приуныл.
Думаю: "Гори оно огнем, сделаю хоть что-то!"
Часть вторая. О том как что-то получилось.
Сделал я в итоге так. Собрал все расходы бюджета по ведомствам, сделал outer join всех лет по кодам ППП. Получилась таблица вида:

Дальше была довольно долгая и неприятная возня с названиями. В отчете об исполнении бюджета используются только полные наименования, поэтому даже у относительно коротких названий вроде Министерство спорта был хвост Российской Федерации. Просто менять Российской Федерации на РФ я не стал и названия вручную менял с официальные сокращенные. Пришлось посидеть, но зато я теперь я гораздо лучше ориентируюсь в российкой бюрократии. В период с 2002 по 2019 год существует или существовало 240 ведомств, там есть и отдельные бюджетные учреждения вроде Большого театра или Эрмитажа, но в основном там ведомства. Российская бюрократия каждый год представлена в ассортименте около 95 наименований. Если с 2002 их было 240, то каждый год за 17 лет менялось примерно 8 ведомств. Из вышепредставленной таблицы гонка получилась довольно быстро.
Посмотреть ее можете по ссылке:
Или в виде html тут:
You must be registered for see links
Видео с ведомственной группировкой получилось хорошим, но Минфин, который выполняет функции передаста по почти всем межбюджетным трансфертам просто затмевает всех остальных. А что же там у него внутри увидеть на уровне ведомства невозможно. Поэтому я отдохнул немного и снова взялся за дело.
Часть третья. Кому на нашем бюджете живется лучше других?
Пока я разбирался в хитросплетениях российского КБК я заметил 1 интересную особенность. Почти во всех ведомствах присутствовали расходы по 01 разделу, а этот раздел наиболее стабильный Владимир Путин с расходами на себя занимает в нем гордое первое место. Расходы на Президента всегда проходят по подразделу 0101.
За 17 лет его название менялось все однажды, а по содержанию это всегда расходы на Президента. Я подумал, что раз Минфин так любит проводить расходы на содержание самих ведомств по 01 разделу, то я смогу оценить т.н. "Затраты на руководство и управление" государственных функций просто сгруппировав подразделы по разделу 01. Впоследствии оказалось, что расходы на содержание ведомств проходят по 01, но так происходит далеко не всегда. Очень часто расходы проходят так, как это предусмотрено GFSM 2014, а именно расходы на управление какой-то функцией проходят по соответствующему тематическому разделу. Например, расходы на руководство полицией классифицируются по коду 70310 Руководство деятельностью полиции и связанными с ней услугами, включая регистрацию иностранцев, выдачу рабочих и проездных документов иммигрантам, ведение документации на арестованных и связанной с работой полиции статистики, регулирование дорожного движения и контроль за ним, предупреждение контрабандной деятельности и контроль за морским и океаническим рыболовным промыслом;
В отдельные годы расходы на управление проходили по 01 разделу, а в другие по какому-то тематическому. Я снова застрял в начале пути. Приходилось бросать сделанное и придумывать что-то другое. Была нужна какая-то более изощренная модель группировки. К тому времени я уже собрал для себя некоторый набор полезных функций для Pandas, которые постоянно использовал в работе. Я уже упомянал про levenshtein_merge(). С помощью этой функции можно сделать join двух Pandas DataFrame через нечеткое соответствие, а именно чере самое короткое расстояние Левенштейна. Функций становилось больше, я решил собрать их в библиотеку. Когда я начал свой бюджетный квест, это был просто класс в том же файле, что и основной проект, но сейчас это вполне годная самостоятельная библиотека, которую можно поставить через pip install и сильно облегчить себе жизнь при работе с Pandas DataFrame. Библиотеку я назвал полуфабрикат, что в переводе на английский будет prepack.
Сейчас без четверти 2 и я уже немного утомился, поэтому постараюсь продолжить статью в формате комментариев кода jupyter notebook в котором я и проводил все манипуляции.
# Сначала импорт нужных модулей
import pandas as pd
import numpy as np
import os, sys
# это мой модуль полуфабрикат
from prepack import prepack as pp
# Это настройки отображения данных в блокноте
pd.options.display.max_rows = 2000
pd.options.display.max_columns = 200
pd.options.display.max_colwidth = 500
pd.options.display.min_rows = 40
А вот здесь начинает работать полуфабрикат prepack. Этой функцией считывается zip архив. Содержимое архива возвращается в виде перечня имен файлов из архива и file-like объектов,
которые можно обрабатывать дальше. К примеру через pd.read_excel(), если в архиве файлы excel.
names, files = pp.read_zip("raw_data.zip")
Эта простая функция отличается от pd.read_excel() только тем, что меняет параметры открытия excel по умолчанию
Мой read_excel читает весь excel как текст, и не пытается взять заголовки колонок из первой строки.
Я открываю начало файла, чтобы правильно задать параметры для массового чтения всех файлов в архиве. По структуре файлы
не отличаются. Я задаю параметры для одного файла, а подходят они и ко всем остальным.
pp.read_excel(files[0]).iloc[8:13,:]
0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
8 | (тыс. руб.) | (тыс. руб.) |