Відкриті дані Києва під аудитом: що придатне для аналізу, а що губиться
Відтворюваний аудит міських даних: машинозчитуваність, повнота, оновлення, геокодування, документація та наслідки пропусків. Двадцять суспільно важливих наборів перевірено через паспорти, словники, файли й кінцеві точки доступу, а кожен висновок прив’язано до контрольної таблиці.. Коротка відповідь: рахувати треба не картки, а придатні зв’язки. Як сформована вибірка й що означають сім критеріїв. Лабораторний журнал: двадцять карток без прикрашання результату. П’ять провалів: що справді знайшлося, а що ні. Три міські питання, на які дані вже дозволяють відповісти. Як виправити набір і як чесно описати його межі. Підсумковий реєстр: три різні рівні довіри. Наступний крок: перетворити разову перевірку на робочий регламент
На порталі може бути багато карток, красивих дашбордів і кнопок завантаження, але це ще не означає, що бухгалтер, керівник чи аналітик зможе повторити розрахунок. Для роботи потрібен не напис «набір оприлюднено», а ланцюжок, який не розсипається: ресурс відкривається, рядки мають зрозумілу структуру, ключі не змінюються, координати справді заповнені, а нове оновлення не стирає попереднє.
Коротка відповідь: рахувати треба не картки, а придатні зв’язки
Кількість наборів нічого не говорить про їхню придатність, бо один запис у каталозі може приховувати кілька дуже різних ресурсів. У транспортному наборі, наприклад, одночасно можуть бути робочий архів GTFS, окремий CSV із маршрутами та посилання на файл, що повертає помилку. Формально це один набір. Для користувача це три різні ситуації: даними можна користуватися, дані треба з’єднати, один із дублювальних шляхів зламаний.
Є й зворотна помилка: незручний інтерфейс не означає відсутність даних. Два фінансові ресурси не віддали архів простому клієнту, але завантажилися з коректними браузерними HTTP-заголовками. Усередині виявилися тисячі XML-файлів за кварталами. Тому технічний збій одного способу доступу не можна називати приховуванням, а успішне відкриття сторінки — доказом повноти.
У нашій вибірці 10 наборів можна аналізувати для заявлених практичних питань, 8 потребують очищення або обхідного шляху, а 2 не дають підстав для міського висновку. Це не рейтинг розпорядників і не оцінка всього каталогу. Це журнал конкретних перевірок конкретних ресурсів.
Як сформована вибірка й що означають сім критеріїв
Вибірка навмисно не є списком найпопулярніших сторінок. Ми взяли рівно двадцять наборів із восьми сфер і обрали ті, за якими містянин або управлінець міг би поставити перевірне запитання: де розташовані зупинки, чи є звіти до цільових програм, хто обслуговує будинок, які заклади культури працюють у районах, що відбувається зі зверненнями. Розподіл такий: три транспортні набори, три бюджетні, три з благоустрою, два житлові, три екологічні, один культурний, три освітні та два набори про звернення.
Для кожного набору відкривали сторінку Порталу даних Києва, завантажували паспорт і машинозчитувану структуру, а потім зверталися до кожного ключового файла або API. На національному порталі перевіряли наявність київських копій, але не складали їх із міськими ресурсами як два незалежні джерела. Офіційні рекомендації Мінцифри використали як еталон словника: назва поля, людиночитаний заголовок, опис, тип даних і ознака обов’язковості.
Оцінка за кожним критерієм має три рівні: 0 — критична прогалина, 1 — частково придатно або потрібна ручна перевірка, 2 — умову виконано. Максимум — 14 балів. Сума допомагає порівнювати набори, але не скасовує здорового глузду: повністю порожня ключова колонка може відправити набір на очищення навіть за високого підсумку.
- Машинозчитуваність. Два бали — файл або endpoint відкривається і парситься; один — працює лише запасний ресурс чи потрібні нетипові заголовки; нуль — табличних даних отримати не вдалося.
- Повнота. Перевіряли не абстрактну кількість колонок, а поля, необхідні для питання: назву, ключ, період, статус, суму, адресу або іншу суттєву ознаку.
- Фактичне оновлення. Порівнювали заявлену частоту з датами ресурсів, періодами у файлах і часовими мітками записів. Оновлена картка не прирівнювалася до оновлених значень.
- Геокодування. Для просторових наборів шукали координати чи геометрію та рахували пропуски. Для фінансових і реєстрових таблиць, де карта не потрібна для основного питання, відсутність координат не штрафували.
- Сталі ідентифікатори. Перевіряли наявність ключа, його заповнення й унікальність у межах логічної сутності. Повтор ключа міг бути нормальним для історії вимірювань, але потребував складеного ключа з часом.
- Словник полів. Два бали отримував набір із описаними колонками, типами й обов’язковістю; один — частковий словник або розбіжність із файлом; нуль — замість схеми стояла риска чи опис був лише prose-текстом.
- Ліцензія й опис доступу. Усі двадцять паспортів містили ліцензійну умову. Другий бал залежав від того, чи пояснено ресурс, параметри API або статичний спосіб завантаження достатньо для повторення.
Такий scorecard зручно вести у звичайній контрольній книзі: один рядок на набір, окремі колонки для балів, пропусків і наслідку. Для читача, який хоче впевненіше сортувати, з’єднувати й перевіряти великі таблиці, доречним наступним кроком може бути курс Microsoft Excel для аналізу даних. Він допомагає опанувати роботу з таблицями, формулами, фільтрами й діаграмами, але не замінює документацію міського API.

Контрольна таблиця зберігає не лише бали. У ній є ідентифікатор сторінки, назви перевірених ресурсів, очікувані поля, фактична кількість рядків і колонок, частка порожніх значень, технічна помилка та її наслідок. Саме ця деталізація робить підрахунок відтворюваним.
Лабораторний журнал: двадцять карток без прикрашання результату
1. Зупинки міського транспорту
Очікували: ідентифікатор, назву, адресу, широту, довготу й ознаку доступності. Отримали: JSON на 2991 запис із 22 полями; координати заповнені, uid унікальний. Пропуск: GeoJSON endpoint повернув серверну помилку, а словника головного JSON немає; заявлену частоту «більш як раз на день» файл не підтверджує. Наслідок: точки можна аналізувати із завантаженого JSON, але автоматизацію на GeoJSON слід замінити, а оперативність не припускати.
2. Розклад руху
Очікували: основні таблиці GTFS — перевізників, маршрути, зупинки, рейси, час прибуття, календар і геометрію. Отримали: робочий архів із дев’ятьма таблицями: 161 маршрут, 1492 зупинки, 24 275 рейсів і 104 134 записи часу зупинок; окремий CSV містить 102 маршрути, а його три версії мають однакові заголовки. Пропуск: окремий agency.csv повернув 404, хоча agency.txt є в GTFS. Наслідок: базовий розклад можна відтворити; битий дублювальний файл не блокує аналіз.
3. Паркувальні майданчики
Очікували: майданчик, оператора, місткість, тариф, геометрію та стабільний ключ. Отримали: 1181 GeoJSON-об’єкт, у кожного є геометрія, globalid та objectid унікальні; окремий CSV описує оператора. Пропуск: для головного GeoJSON немає словника, а частина цінових і контактних атрибутів порожня. Наслідок: розташування й місткість аналізуються, другорядні поля потребують звірки з описом сторінки.
4. Фінансова звітність комунального сектору
Очікували: код підприємства, звітний період, форму балансу й показники. Отримали: ZIP із 21 335 XML-файлів від 2020 року до останнього доступного кварталу; код підприємства й період зашиті в назві файла. Пропуск: простий клієнт отримував 403, браузерний запит завантажив архів; словника XML-елементів немає. Наслідок: динаміку можна рахувати після розпакування й нормалізації, але одиниці та теги треба перевірити вручну.
5. Звіти про виконання фінансових планів
Очікували: код підприємства, квартал, планові та фактичні показники. Отримали: 4643 XML-файли від 2023 року до останнього доступного кварталу. Пропуск: повторюється бар’єр із 403 для простого клієнта й відсутній словник елементів. Наслідок: періоди порівняти можна, але без документованої семантики автоматичне тлумачення кожного тега ризиковане.
6. Цільові місцеві програми
Очікували: програму, розпорядника, правовий акт, зміни, звіти, період і посилання на документ. Отримали: 41 програму, 112 змін та 30 звітів; заголовки відповідають словникам, обов’язкові поля заповнені. Пропуск: один URL звіту порожній, а повна історія версій є лише для таблиці звітів. Наслідок: три ресурси надійно з’єднуються ідентифікаторами; можна перевірити, до яких програм прикріплено звіти.
7. Громадські вбиральні
Очікували: тип, адресу, координати, графік, платність і доступність. Отримали: CSV на 38 об’єктів із повними координатами та унікальним uid. Пропуск: GeoJSON endpoint повернув 500; тип порожній приблизно у кожному двадцятому рядку, а поля доступності заповнені нерівномірно. Наслідок: карту з CSV побудувати можна, порівняння умов для маломобільних людей буде неповним.
8. Комунальні контейнери
Очікували: тип, вид відходів, кількість, балансоутримувача, графік, адресу й координати. Отримали: 6776 рядків, 33 колонки, унікальний uid і вісім збережених версій. Пропуск: type, balanceHolderId та balanceHolderName порожні повністю, координат немає у 0,72% рядків. Наслідок: кількість і розміщення піддаються обробці, але відповісти, до якого типу належить об’єкт і хто за нього відповідає, з цього файла не можна.
9. Зелені насадження, що підлягають видаленню
Очікували: акт, дату, адресу, координати, вид, стан, кількість і причину. Отримали: 34 538 рядків, 33 колонки та сім версій зі сталою структурою. Пропуск: lat і lon порожні повністю, у 12,11% рядків немає назви вулиці, uid повторюється в частині записів. Наслідок: підсумок за видами чи актами можливий, просторовий висновок потребує окремого геокодування та складеного ключа.
10. ОСББ та ЖБК
Очікували: код ЄДРПОУ, назву, адресу, керівника, контакти, координати й дату створення. Отримали: 2925 рядків і 22 фактичні колонки; координати є у 92,03% рядків. Пропуск: словник описує 23 поля, але contactPointTelephone у файлі немає; entityId не унікальний у 11,04% записів. Наслідок: перелік придатний для пошуку, але підрахунок організацій і будинків потребує дедублікації.
11. Обслуговування житлового фонду
Очікували: адресу будинку, координати, providerId, назву й контакти обслуговувача. Отримали: 8299 адрес і 10 надавачів, між таблицями є ключ providerId. Пропуск: 12,6% адрес не мають координат; один заголовок містить нерозривний пробіл і формально не збігається зі словником; історії версій немає. Наслідок: зону обслуговування можна відтворити після нормалізації заголовка та геокодування пропусків.
12. Оцінка якості повітря
Очікували: станцію, координати, час, концентрації забруднювачів, радіацію та статус. Отримали: історичний JSON на 72 202 вимірювання з повними координатами й показниками; окремий API повернув сім станцій і мав посилання на Swagger. Пропуск: часові мітки live-відповіді відстають від публікації набору, хоча заявлено багаторазове щоденне оновлення; словника немає. Наслідок: історичні ряди досліджувати можна, називати API поточним станом повітря без перевірки свіжості — ні.
13. Дозволи на викиди
Очікували: дозвіл, суб’єкта, адресу джерела, координати, строк дії та документи. Отримали: 273 записи, 44 колонки за словником і унікальний uid. Пропуск: lat, lon та addressThoroughfare порожні повністю; багато колонок документів також не заповнені. Наслідок: реєстровий підрахунок можливий, просторова картина джерел викидів — ні.
14. Муніципальні пляжі
Очікували: ідентифікатор, назву, статус, інфраструктуру та геометрію. Отримали: 15 GeoJSON-об’єктів із геометрією, унікальними globalid та objectid. Пропуск: словника немає, для 20% об’єктів порожні окремі контактні або часові атрибути, версії не зберігаються. Наслідок: розташування й базову інфраструктуру порівнювати можна, рідкісні атрибути — лише з обережним тлумаченням.
15. Заклади культури
Очікували: uid, тип, назву, адресу, контакти, години роботи, координати й послуги. Отримали: 286 рядків, 30 колонок за словником, унікальний uid і повні координати. Пропуск: institutionId порожній у 53,85% записів, хоча окремий uid заповнений; необов’язкові сервісні URL є не всюди. Наслідок: заклади можна рахувати й розподіляти за районами, але універсальним ключем має бути uid, не institutionId.
16. Заклади дошкільної освіти
Очікували: повний перелік закладів із ключем, назвою, типом, адресою, координатами, контактами й групами. Отримали: endpoint повернув лише чотири заклади; координати є у вкладеному contacts. Пропуск: структурований address порожній, дані дублюються в іншому блоці, документації параметрів і словника немає. Наслідок: чотири записи не є підставою для висновку про міську мережу.
17. Черга дітей до дитсадків
Очікували: черги за всіма закладами й періодами, номер, дату, вік, пільгу, заклад і статус. Отримали: 29 повних записів для одного жорстко заданого kindergartenid. Пропуск: немає довідника ідентифікаторів закладів і документації API; один приклад не формує міську сукупність, а поєднання року народження з віковою групою потребують пояснення. Наслідок: загальну довжину й динаміку черги визначити неможливо.
18. Заклади професійної освіти
Очікували: uid, id, назву, тип, адресу, контакти, профіль, дуальну освіту й гуртожиток. Отримали: 18 закладів, 25 колонок за словником, унікальні uid та id, заповнені обов’язкові поля. Пропуск: окремих lat і lon немає, хоча структурована адреса є; історії версій теж немає. Наслідок: профілі та характеристики порівнюються без додаткової роботи, для карти адреси треба геокодувати.
19. Звернення до контактного центру
Очікували: ідентифікатор, час, тип, категорію, зміст, адресу, виконавця, статус і результат. Отримали: параметризований JSON API віддає дані за роком і місяцем; контрольний місяць містив 71 227 записів та 21 поле, Id унікальний. Пропуск: словник і відповідь розходяться на одному адресному полі, у відповіді додано Id, 18,11% назв вулиць порожні, координат немає. Наслідок: теми, виконавців і строки аналізуються, просторовий розріз потребує очищення адрес.
20. Електронні петиції
Очікували: петицію, uid, тему, статус, дату, кількість голосів, відповідь і голосування. Отримали: 2706 петицій із 15 полями та унікальним uid; ZIP голосувань доступний, має дві версії й важить близько 255 МБ. Пропуск: словника немає, великий архів є практичним бар’єром, а answerText порожній у 92,46% усіх записів. Наслідок: теми й статуси аналізуються; наявність відповіді слід оцінювати лише серед завершених петицій, архів завантажувати потоково.

П’ять провалів: що справді знайшлося, а що ні
PDF замість таблиці: нуль випадків у вибірці
Офіційні поради прямо застерігають від сканованих PDF і JPEG як заміни структурованих даних. У двадцяти відібраних наборах цього дефекту не виявлено: ключові ресурси були CSV, JSON, GeoJSON, XML або ZIP із такими файлами. Нуль — важливий результат, але не дозвіл узагальнювати його на весь каталог. Ми перевіряли суспільно важливу вибірку, а не кожну картку порталу.
Несталі колонки: не плутати ризик із доведеним фактом
У збережених версіях маршрутів, звітів, контейнерів і актів заголовки були стабільними. Натомість у трьох поточних ресурсах фактична структура не збіглася зі словником: у переліку ОСББ зник телефон, у таблиці надавачів житлових послуг до назви колонки потрапив невидимий пробіл, а у зверненнях одне поле відсутнє й одне додане. Це проблема контракту імпорту, але ще не доказ, що колонки постійно змінювалися в часі.
Порожні координати: сім наборів із різним масштабом проблеми
У контейнерах пропуск невеликий, у житлових таблицях координат бракує приблизно для кожної восьмої адреси, а в актах на видалення зелених насаджень і дозволах на викиди координати порожні повністю. Заклади професійної освіти мають структуровані адреси без lat і lon, звернення — частково заповнені адреси без координат. Тому «геодані Києва» — це не формат сторінки, а фактична можливість поставити кожен запис на карту.
Відсутній словник: вісім ключових ресурсів
Найгірше не те, що назва колонки англійська, а те, що невідомі її тип, допустимі значення та обов’язковість. Позначка «—» замість схеми трапилася у ключових ресурсах зупинок, двох фінансових архівів, якості повітря, пляжів, двох дошкільних наборів і петицій. Без словника користувач змушений виводити семантику з прикладів, а зміна формату перетворюється на тиху помилку.
Оновлення без історії: чотирнадцять наборів
Нова версія файла часто замінює стару. У такому режимі не можна відтворити минулий розрахунок, знайти виправлений запис або відрізнити реальну зміну від перезавантаження. Історію побачили лише в окремих ресурсах розкладу, цільових програм, контейнерів, зелених насаджень, ОСББ та голосувань за петиції. Навіть там версіонування не завжди охоплює всі частини набору.
Три міські питання, на які дані вже дозволяють відповісти
Чи можна відтворити базовий розклад громадського транспорту?
Так, у межах опублікованого GTFS. Є маршрути, зупинки, рейси, послідовність і час зупинок, календар та геометрія. Ключі route_id, stop_id, trip_id і service_id дають змогу з’єднати таблиці. Висновок не означає, що кожен фактичний приїзд відповідає плану; він означає, що публікація достатня для аналізу планового розкладу.
До скількох цільових програм прикріплено звіти?
Таблиця містить 41 унікальну програму, а 30 рядків звітів посилаються на 25 унікальних programId. Усі ці ключі знайдено в переліку програм, «сирітських» звітів немає. Отже, у вибраній публікації звіт представлено для 25 програм, а для 16 програм рядка у таблиці звітів немає. Це не твердження, що документ не існує ніде; це точний висновок про опублікований ресурс.
Як розподілені заклади культури за типами й районами?
У 286 рядках координати заповнені, райони вказані для всіх записів, uid унікальний. Серед типів найбільше бібліотек — 147, далі йдуть 42 мистецькі школи, 18 музеїв і 17 театрально-видовищних закладів. За районами найбільше записів у Шевченківському — 47, найменше у Святошинському — 16. Тут структура дозволяє не лише порахувати, а й перевірити просторовий розподіл.
Як виправити набір і як чесно описати його межі
Розпоряднику не обов’язково починати з нового порталу. Більшість проблем виправляється дисципліною публікації:
- експортувати первинну таблицю або JSON, а документ для читання залишати додатковим ресурсом;
- публікувати машинозчитуваний словник із назвою, заголовком, описом, типом та обов’язковістю кожного поля;
- закріпити незмінний ідентифікатор за сутністю та окремо документувати складений ключ для історичних вимірювань;
- перевіряти не тільки наявність колонок, а й частку порожніх значень у ключових полях;
- для просторових наборів валідовувати діапазони координат і публікувати частку негеокодованих записів;
- зберігати попередні версії, контрольну суму, короткий журнал змін і дату фактичного зрізу всередині метаданих ресурсу;
- для API давати опис параметрів, приклад відповіді, схему, коди помилок і правило пагінації;
- запускати автоматичний тест завантаження після кожної публікації, щоб 404, 500 або порожній архів не чекали на користувача.
Читачеві варто вести власний протокол. Запишіть назву ресурсу, код відповіді, розмір, кількість рядків, заголовки, частку порожніх ключів і спосіб завантаження. Якщо API не відповів, перевірте, чи є статичний файл, але не робіть вигляд, що помилки не було. Якщо координат немає, не замінюйте їх приблизним центром району без окремої примітки. Якщо показник має часову мітку, перевіряйте її, а не дату оновлення картки.
Формулювання висновку має точно повторювати межу даних. Не «у міста немає інформації про черги», а «опублікований endpoint повертає лише один заклад і не дає відтворити міську сукупність». Не «місто приховує географію викидів», а «в перевіреному CSV координати та назва вулиці порожні». Така мова менш гучна, зате її можна перевірити.

Підсумковий реєстр: три різні рівні довіри
Можна аналізувати
- розклад руху міського електричного та автомобільного транспорту;
- дані про паркування;
- фінансова звітність суб’єктів комунального сектору;
- звіти про виконання фінансових планів;
- перелік цільових місцевих програм, змін і звітів;
- перелік муніципальних пляжів;
- перелік закладів культури;
- заклади професійної освіти;
- звернення до контактного центру;
- електронні петиції.
Цей статус не означає «бездоганно». Він означає, що для сформульованого питання є достатня таблиця, ключі й контрольований спосіб отримання, а виявлені дефекти не перекручують основну відповідь.
Потрібне очищення або обхідний шлях
- місця розміщення зупинок — статичний JSON працює, GeoJSON endpoint ні;
- громадські вбиральні — координати є, поля доступності неповні;
- комунальні контейнери — порожні тип і балансоутримувач;
- зелені насадження до видалення — немає координат і частини адрес;
- ОСББ та ЖБК — розбіжність словника, дублікати ключа й неповна географія;
- обслуговування житлового фонду — координатні пропуски та невидимий символ у заголовку;
- якість повітря — історія є, але live-відповідь не можна вважати свіжою без перевірки часу;
- дозволи на викиди — реєстр читається, просторові поля порожні.
Міський висновок неможливий
- заклади дошкільної освіти — endpoint повернув лише чотири записи без пояснення повноти;
- черга дітей до дошкільних закладів — доступний приклад для одного закладу без довідника параметрів.
Обидва ресурси технічно віддають JSON. Саме тому вони добре показують різницю між «файл існує» та «сукупність придатна для висновку». Машинозчитуваність — необхідна, але не достатня умова.
Наступний крок: перетворити разову перевірку на робочий регламент
Щоб повторити аудит, завантажте ті самі ресурси, проведіть їх через контрольні колонки й порівняйте не лише підсумкові бали, а й фактичні заголовки, кількість рядків, порожні ключі та часові мітки. Якщо частина роботи виконується в електронних таблицях, систематизувати сортування, формули, зв’язування й побудову контрольних діаграм допоможе програма навчання роботі з Excel. Для API, XML і великих архівів усе одно знадобляться окремі інструменти та технічна документація.
Головний висновок простий: відкритість вимірюється не кількістю опублікованих карток. Вона починається там, де інший користувач може завантажити ті самі рядки, зрозуміти кожне поле, повторити з’єднання й отримати той самий результат — разом із чесно записаними обмеженнями.