Как я делал Tasqyn
Честно, как всё было: почему я начал, откуда данные, какой стек, как на самом деле работает прогноз и какие ошибки пришлось чинить.
Весной 2025 года я снова смотрел, как Петропавл сильно топит. И понял, что хуже всего, внезапность, хотя вода намекала на это за месяцы. Тогда я сел и сделал предсказатель. Всё от начала до конца сделал сам.
Откуда данные
Сначала я разобрался, как устроен настоящий мониторинг, на USGS Water Data увидел, как грамотно работают с гидропостами, стоком и перцентилями. Погоду брал из реанализа ERA5 через Open-Meteo (снежный покров, температура, влажность почвы), это бесплатно и без ключа. Основа всего, локальный месячный ряд уровня Ишима (Есиля) у Петропавла с 1995 по 2022 год.
Стек
- Python на всё, pandas для данных, аккуратный пайплайн src/ (загрузка → признаки → модель → оценка).
- XGBoost + scikit-learn, модель на градиентном бустинге с 47 признаками без утечек.
- FastAPI отдаёт модель; один и тот же код признаков работает и при обучении, и в API.
- Expo / React Native для приложения, Docker и CI, чтобы всё воспроизводилось.
Как работает прогноз
Каждый месяц превращается в строку признаков: недавние уровни, температура и снег, с лагами и скользящими окнами. Модель выдаёт вероятность паводка, которую я калибрую, чтобы заявленные 70% и правда означали примерно 70%. Бутстрап из 15 моделей добавляет доверительный интервал. Самый сильный сигнал, который она нашла, снег, выпавший примерно за четыре месяца до паводка.
Почему именно так
Снеготаяние, медленный сигнал, который виден за месяцы, поэтому прогноз на месяц вперёд физически оправдан. Когда данных всего несколько сотен месяцев, дерево на бустинге обыгрывает глубокую сеть, оно тянет маленькие табличные данные и нелинейности и не так легко переобучается. И мне была важнее честная проверка, чем красивая архитектура.
Что шло не так (и было исправлено)
- Утечка данных. Первые скользящие окна позволяли месяцу подсматривать сам себя. Метрика выглядела отлично и была враньём. Я сдвинул каждое окно на месяц и закрепил это тестом.
- Ловушка идеального результата. Наивный сплит дал ROC-AUC 1.00. Вместо того чтобы радоваться, я его выбросил и перешёл на leave-one-year-out walk-forward, он даёт честные 0.91.
- Баг с единицами. Живая влажность почвы приходила в ×100 от обучающей. Я поймал это, сравнив живые входы с обучающими диапазонами, и поправил масштаб.
- Честные ограничения. Положительный класс крошечный, и полный локальный ряд есть только по Петропавлу, поэтому другие бассейны оцениваются переносом и явно помечены как ориентировочные.
Это по-прежнему полностью мой проект, работа с данными, модель, API, приложение и эти страницы. Tasqyn, первое, что выпускает моя студия Trest.