UnionML в Google Colab: быстрый старт на примере классификации digits

Курс показывает, как оформить короткий Google Colab ноутбук с текстовыми блоками и кодовыми ячейками для проекта UnionML. На практике вы настроите Git, инициализируете шаблон unionml, опишете Dataset/Model и добавите reader, trainer, predictor и evaluator для LogisticRegression.

1. Структура Colab: текстовые блоки и кодовые ячейки

Структура Colab: текстовые блоки и кодовые ячейки

Зачем вообще думать о структуре ноутбука

Google Colab — это ноутбук, то есть документ, в котором вперемешку идут:

  • текстовые блоки (Markdown-ячейки) — объясняют, что вы делаете и зачем;
  • кодовые ячейки — выполняют Python или команды оболочки Linux.
  • В этом курсе мы будем использовать Colab как повторяемый мини-пайплайн: вы открываете ноутбук, запускаете ячейки сверху вниз и получаете обученную модель, метрику качества и (в следующих материалах) упаковку/развёртывание.

    Полезные ссылки:

  • Google Colab
  • Документация UnionML
  • Набор данных Digits в scikit-learn
  • !Схема, показывающая, как чередуются текстовые и кодовые ячейки и почему важен порядок выполнения

    Из чего состоит Colab-ноутбук

    Текстовые блоки

    Текстовые блоки нужны, чтобы:

  • зафиксировать цель следующего шага (например, инициализируем проект UnionML);
  • описать входы/выходы (например, читатель датасета возвращает pandas DataFrame);
  • оставить подсказки по запуску (например, выполните ячейки сверху вниз).
  • Практическое правило: всё, что объясняет смысл, должно быть в тексте. Всё, что делает работу, должно быть в коде.

    Кодовые ячейки

    Кодовые ячейки бывают двух типов по смыслу:

  • Python-ячейки: импорт библиотек, объявление функций, обучение, оценка качества.
  • Shell-ячейки: команды Linux (например, git config, создание структуры проекта).
  • В Colab shell-команды обычно запускают:

  • через %%sh в начале ячейки (вся ячейка выполняется как shell-скрипт);
  • или через !команда внутри Python-ячейки.
  • В этой статье мы будем использовать вариант с %%sh, потому что он делает ячейку полностью терминальной и удобной для блоков команд.

    Правило порядка выполнения

    В ноутбуках важен порядок:

  • Сначала выполняются импорты и установки (если нужны).
  • Затем объявляются объекты и функции.
  • Только потом запускаются обучение и оценка.
  • Если вы выполните ячейку ниже раньше, чем объявлены нужные функции/переменные, Colab выдаст ошибку (например, что имя не определено). Поэтому в курсе будем придерживаться простого режима: запускайте сверху вниз.

    Мини-шаблон ноутбука для UnionML

    Ниже — рекомендуемая структура ноутбука, которую вы можете прямо копировать в Colab. Текстовые блоки — это заголовки/пояснения, а под ними — кодовые ячейки.

    Подготовка окружения

    В Colab часто нужно установить зависимости, потому что окружение может быть “чистым”. Если библиотека unionml у вас ещё не установлена, добавьте отдельную ячейку (Python) и выполните.

    Если установка уже была сделана в текущей сессии, эту ячейку можно пропустить.

    Инициализация проекта на диске Colab

    Colab даёт временную файловую систему. Мы создадим каркас проекта UnionML командой unionml init. Это удобно, потому что структура получается стандартной, а позже её проще упаковывать и разворачивать.

    Кодовая ячейка (shell) — как в шаблоне ниже.

    Что здесь происходит:

  • git config ... задаёт имя/почту для Git в текущем окружении (часто требуется инструментам, которые создают репозитории/шаблоны).
  • unionml init --template basic-bentoml myproject создаёт папку myproject с базовым шаблоном, ориентированным на интеграцию с BentoML.
  • Важно: после создания проекта удобно работать из этой папки. В Colab можно либо cd в shell-ячейке, либо использовать абсолютные пути. В следующих статьях мы покажем наиболее удобный вариант.

    Описание Dataset и Model в UnionML

    Теперь создадим объекты Dataset и Model. Это центральная идея UnionML: вы описываете как читать данные, как обучать, как предсказывать и как оценивать, а UnionML связывает это в единый воспроизводимый пайплайн.

    Кодовая ячейка (Python) — как в шаблоне ниже.

    Разбор параметров:

  • name — имя сущности (полезно для логов/организации).
  • test_size=0.2 — 20% данных будет отделено под тест.
  • shuffle=True — данные будут перемешаны перед разделением.
  • targets=["target"] — название столбца-цели в датафрейме.
  • init=LogisticRegression — чем создавать модель (экземпляр оценщика scikit-learn).
  • Читатель данных: превращаем Digits в DataFrame

    UnionML ожидает, что @dataset.reader вернёт данные в табличном виде. Мы возьмём встроенный датасет рукописных цифр из scikit-learn.

    Что важно:

  • load_digits(as_frame=True).frame возвращает pandas.DataFrame, где признаки — это столбцы с пиксельными значениями, а target — правильный класс цифры.
  • Декоратор @dataset.reader регистрирует функцию как официальный способ чтения данных для этого Dataset.
  • Тренировка: как обучать LogisticRegression

    Тренер в UnionML получает:

  • estimator — созданный оценщик (в нашем случае LogisticRegression),
  • features — признаки,
  • target — целевую переменную.
  • И возвращает обученный estimator.

    Зачем target.squeeze():

  • иногда цель приходит как датафрейм с одним столбцом;
  • squeeze() превращает его в одномерную структуру, которую ожидает scikit-learn.
  • Предсказание: как получать классы

    Предиктор описывает, как из обученного оценщика и новых признаков получить предсказания.

    Замечание по типам:

  • для классификации LogisticRegression.predict вернёт метки классов (0–9),
  • мы приводим их к float, потому что так часто проще стандартизировать формат вывода в пайплайнах.
  • Оценка: accuracy

    Оценщик качества (evaluator) нужен, чтобы формально измерять результат на тестовой части данных.

    Что делает accuracy_score:

  • сравнивает истинные метки и предсказанные;
  • возвращает долю правильных ответов от 0 до 1.
  • Запуск пайплайна в ноутбуке

    После того как вы объявили reader/trainer/predictor/evaluator, вы можете запустить обучение и оценку в отдельной кодовой ячейке.

    Если всё настроено верно, вы увидите численное значение accuracy.

    Как оформлять ноутбук, чтобы к нему можно было вернуться через неделю

    Мини-чеклист:

  • Один смысловой шаг — один текстовый блок и одна кодовая ячейка.
  • Названия в тексте совпадают с названиями в коде (например, digits_dataset, digits_classifier).
  • Ячейки можно выполнить сверху вниз без ручных вмешательств.
  • Команды, меняющие файловую систему (unionml init, создание файлов), вынесены в shell-ячейки с %%sh.
  • Что будет дальше

    Эта статья дала “скелет” Colab-ноутбука: как чередовать объяснения и исполняемые блоки, и как уложить UnionML-пайплайн в понятные ячейки.

    В следующих материалах логично переходить к:

  • управлению параметрами модели и воспроизводимости (фиксирование версий, настройки LogisticRegression),
  • сохранению/загрузке артефактов,
  • упаковке и развёртыванию (через шаблон basic-bentoml).
  • 2. Настройка окружения и Git в Colab (%%sh)

    Настройка окружения и Git в Colab (%%sh)

    В предыдущей статье про структуру Colab мы договорились о простом правиле: каждый шаг ноутбука должен быть воспроизводимым и запускаться сверху вниз без ручных правок. Эта статья закрывает самый первый практический шаг: подготовить окружение Colab, настроить Git и создать каркас проекта UnionML через unionml init.

    !Краткая схема порядка действий в Colab перед работой с UnionML

    Что такое окружение в Colab и почему его нужно настраивать

    Google Colab запускает для вас виртуальную машину с Python и предустановленными библиотеками. Важно помнить два свойства:

  • Временность: если вы перезапустите среду выполнения или сессия завершится, установленные пакеты и созданные файлы могут исчезнуть.
  • Разные стартовые состояния: сегодня в Colab может быть одна версия библиотек, через неделю — другая.
  • Поэтому типичная практика для учебного и рабочего ноутбука:

  • в самом начале явно установить нужные зависимости;
  • при необходимости настроить инструменты командной строки (например, Git);
  • создать структуру проекта, чтобы код было проще переносить из ноутбука в репозиторий.
  • Зачем нужен %%sh и чем он отличается от !команда

    В Colab есть два популярных способа запускать shell-команды:

  • !команда внутри Python-ячейки — удобно для одной команды.
  • %%sh в начале ячейки — удобно, когда команд несколько, и вы хотите, чтобы вся ячейка работала как мини-скрипт.
  • В этом курсе мы используем %%sh, потому что:

  • так проще копировать готовые блоки команд;
  • команды логически объединены в один шаг (например, настройка Git + инициализация проекта);
  • результат легче читать: это терминальная ячейка, а не Python-код с восклицательными знаками.
  • Пример простой %%sh-ячейки:

    Установка зависимостей в Colab

    Перед тем как вызывать unionml как команду, библиотека должна быть установлена в текущей среде.

    Кодовая ячейка (Python):

    Пояснения:

  • pip install устанавливает пакеты в текущую Colab-сессию.
  • флаг -q делает вывод короче.
  • unionml — то, с чем мы строим пайплайн;
  • pandas и scikit-learn нужны для датасета digits и модели LogisticRegression;
  • bentoml нужен, потому что мы используем шаблон basic-bentoml при инициализации проекта.
  • Проверка, что всё установилось (опционально, но полезно при ошибках):

    Если импорт не проходит, значит установка не завершилась или сессия была перезапущена — выполните pip install ещё раз.

    Зачем настраивать Git в Colab

    В Colab Git обычно уже доступен как команда git. Но по умолчанию у Git может не быть настроены имя пользователя и email. Некоторые инструменты и шаблоны проектов в таких случаях:

  • показывают предупреждения;
  • могут не создавать коммит (если он подразумевался);
  • или просто усложняют дальнейшую работу, когда вы захотите сохранить проект в репозиторий.
  • Поэтому мы делаем минимальную настройку:

  • user.name
  • user.email
  • Важно:

  • настройка через --global действует внутри текущей Colab-сессии и обычно не переживает полный сброс runtime;
  • можно указать тестовые значения, если вы не собираетесь пушить код в публичный репозиторий из Colab.
  • Полезная ссылка: Документация Git: git-config

    Одна %%sh-ячейка: Git config + инициализация UnionML-проекта

    Ниже — тот самый блок, который удобно держать в начале ноутбука как единый шаг подготовки.

    Кодовая ячейка (shell):

    Что делает каждая строка:

  • git config --global user.email "you@example.com"
  • - записывает email в глобальную конфигурацию Git текущей среды.
  • git config --global user.name "Your Name"
  • - записывает имя пользователя в глобальную конфигурацию Git.
  • unionml init --template basic-bentoml myproject
  • - создаёт папку myproject со стандартной структурой UnionML-проекта на основе шаблона basic-bentoml.

    Полезная ссылка: Документация UnionML

    Как убедиться, что Git-настройки применились

    Кодовая ячейка (shell):

    Вы должны увидеть строки с user.name и user.email.

    Как проверить, что проект создался

    Кодовая ячейка (shell):

    Если папка myproject появилась, значит unionml init отработал успешно.

    Где вы находитесь в файловой системе Colab

    В большинстве Colab-ноутбуков рабочая директория — это /content. Именно там вы увидите папку myproject.

    Дальше у вас есть два способа работать с файлами проекта:

  • выполнять shell-команды с явными путями (например, ls myproject),
  • или перейти в папку проекта.
  • Пример перехода в папку проекта через %%sh:

    Важно: cd внутри %%sh действует только внутри этой ячейки. Если вы хотите сменить директорию для Python-ячейки, используйте магию Colab:

    Типовые проблемы и быстрые решения

    Команда unionml не найдена

    Причины и действия:

  • вы не выполнили ячейку pip install в этой сессии;
  • сессия перезапускалась.
  • Решение: снова выполните установку зависимостей.

    unionml init завершился с ошибкой

    Чаще всего помогает:

  • убедиться, что bentoml установлен;
  • проверить, что папка myproject не существует (если существует — удалите или выберите другое имя).
  • Удаление папки (осторожно):

    Почему Git-настройки пропали на следующий день

    Это нормально для Colab: глобальная конфигурация Git хранится в файловой системе текущей виртуальной машины. После сброса runtime её может не быть.

    Практика для курса: просто держите ячейку git config ... рядом с unionml init и запускайте при необходимости.

    Что дальше по курсу

    После того как окружение готово и проект инициализирован:

  • вы переходите к определению Dataset и Model UnionML;
  • добавляете reader, trainer, predictor, evaluator для digits;
  • запускаете обучение и оценку.
  • То есть эта статья — про нулевой шаг, без которого дальнейшие ячейки из предыдущего материала не будут воспроизводимыми.

    3. Инициализация UnionML проекта (template basic-bentoml)

    Инициализация UnionML проекта (template basic-bentoml)

    В предыдущих материалах мы договорились о двух базовых правилах работы в Google Colab:

  • держать ноутбук воспроизводимым и выполнять ячейки сверху вниз;
  • разделять объяснения (текстовые блоки) и действия (кодовые ячейки, в том числе %%sh).
  • Теперь сделаем следующий практический шаг: инициализируем проект UnionML на диске Colab с шаблоном basic-bentoml. Это создаст понятную структуру папок и подготовит основу для дальнейшей упаковки модели через BentoML.

    !Схема шагов инициализации проекта UnionML в Colab

    Зачем вообще инициализировать проект, если можно писать всё в ноутбуке

    Если код остаётся только в ноутбуке, через некоторое время появляются типичные проблемы:

  • сложно повторить запуск в другой среде;
  • сложно переносить код в репозиторий;
  • сложнее упаковывать и разворачивать модель как сервис.
  • unionml init решает это тем, что создаёт каркас проекта на файловой системе Colab. Дальше вы можете:

  • продолжать эксперименты в ноутбуке;
  • постепенно переносить рабочие части в файлы проекта;
  • использовать заготовку, ориентированную на интеграцию с BentoML.
  • Полезные ссылки:

  • Документация UnionML
  • Документация BentoML
  • Документация Git (git-config)
  • Google Colab
  • Что означает шаблон basic-bentoml

    В unionml init есть шаблоны, которые создают стартовую структуру проекта. Шаблон basic-bentoml полезен для курса по двум причинам:

  • он задаёт проектный формат, который удобно версионировать и переносить;
  • он заранее ориентирует проект на дальнейшую упаковку модели в формат, удобный для сервинга (через BentoML).
  • Важно: на этом шаге мы не разворачиваем сервис и не строим контейнер. Мы только создаём структуру, к которой вернёмся позже.

    Подготовка: убедитесь, что зависимости установлены

    Если вы ещё не выполняли установку в этой Colab-сессии, выполните Python-ячейку:

    Если установка уже была сделана выше по ноутбуку в этой же сессии, повторять не обязательно.

    Одна shell-ячейка: Git config и unionml init

    Ниже кодовая ячейка формата %%sh. Она делает два действия:

  • задаёт user.name и user.email для Git внутри текущей среды;
  • создаёт папку проекта myproject на диске Colab.
  • Почему здесь вообще нужен Git:

  • в Colab Git обычно уже установлен как команда;
  • некоторые генераторы шаблонов и рабочие процессы ожидают, что у Git задана минимальная идентичность пользователя;
  • даже если вы не будете пушить код из Colab, такие настройки помогают избежать предупреждений и упрощают дальнейшее переносение проекта.
  • Проверка, что проект создался

    Сразу после unionml init проверьте, что папка появилась в текущей директории (обычно это /content).

    Затем посмотрите содержимое папки проекта:

    Если вы хотите увидеть дерево файлов на пару уровней глубже:

    Где находится проект в Colab и как в него перейти

    По умолчанию Colab работает в директории /content, поэтому проект будет в /content/myproject.

    Есть две разные ситуации:

  • cd внутри %%sh влияет только на текущую shell-ячейку;
  • чтобы сменить рабочую директорию для Python-ячейки, используйте магию %cd.
  • Перейти в проект для дальнейшей работы в Python:

    А проверить текущую директорию и содержимое уже из Python:

    Типовые ошибки при unionml init и что делать

    Папка myproject уже существует

    Если вы запускаете инициализацию повторно, unionml init может отказать, потому что директория занята. Есть два безопасных варианта:

  • удалить папку и создать заново;
  • выбрать другое имя проекта.
  • Удаление папки (используйте внимательно):

    Команда unionml не найдена

    Это означает, что пакет unionml не установлен в текущей сессии или runtime перезапускался. Решение простое: снова выполните pip install из начала статьи.

    Как это связано с примером классификации digits

    В следующих шагах курса мы будем описывать Dataset и Model UnionML для датасета рукописных цифр digits из scikit-learn и запускать обучение и оценку прямо в ноутбуке.

    Практическая логика такая:

  • ноутбук остаётся местом для воспроизводимого сценария (ячейки сверху вниз);
  • папка проекта myproject становится местом, куда постепенно переедет рабочий код и откуда его будет удобнее упаковывать.
  • Справка по датасету, который мы будем использовать:

  • Digits dataset в scikit-learn
  • Что дальше

    После инициализации проекта следующий логичный шаг в ноутбуке:

  • объявить Dataset и Model;
  • добавить reader, trainer, predictor, evaluator;
  • запустить model.train() и model.evaluate().
  • То есть на текущем шаге вы сделали основу: у вас есть проектная структура, с которой удобно жить в Colab и которую легко переносить за пределы ноутбука.

    4. Dataset и Model: конфигурация для digits и LogisticRegression

    Dataset и Model: конфигурация для digits и LogisticRegression

    В предыдущих статьях вы:

  • разобрали, как правильно чередовать текстовые блоки и кодовые ячейки в Google Colab;
  • настроили окружение, Git и создали каркас проекта через unionml init --template basic-bentoml myproject.
  • На этом шаге мы соберём минимально полный пайплайн UnionML для классификации рукописных цифр на датасете digits из scikit-learn:

  • опишем Dataset и Model;
  • добавим функции reader, trainer, predictor, evaluator;
  • запустим model.train() и model.evaluate().
  • !Схема показывает, как функции UnionML связываются в единый пайплайн

    Что такое Dataset и Model в UnionML

    В UnionML вы описываете пайплайн декларативно:

  • Dataset отвечает за то, как получить данные и как выделить целевой столбец.
  • Model отвечает за то, как создать модель, как обучить, как предсказывать и как оценивать.
  • Идея в том, что после регистрации функций (через декораторы) у вас появляется воспроизводимый сценарий:

  • model.train() сам вызовет ваш reader, выделит признаки и цель, разделит на train/test и вызовет trainer.
  • model.evaluate(estimator) прогонит оценку на тестовой части через evaluator.
  • Полезные ссылки:

  • Документация UnionML
  • Digits dataset в scikit-learn
  • LogisticRegression в scikit-learn
  • accuracy_score в scikit-learn
  • Подготовка ноутбука в Colab

    Если вы продолжаете в том же ноутбуке, где уже ставили зависимости, этот шаг можно пропустить. Иначе установите библиотеки.

    Если вы создавали проект myproject в предыдущих шагах, можно перейти в него, чтобы все файлы были рядом.

    Создаём Dataset и Model

    В этом примере мы хотим:

  • прочитать датасет digits в виде pandas.DataFrame;
  • считать целевым столбцом target;
  • использовать LogisticRegression как базовую модель;
  • автоматически отделить 20% данных под тест.
  • Что означают параметры Dataset

  • name="digits_dataset" — имя сущности (удобно для логов и структуры проекта).
  • test_size=0.2 — доля тестовой выборки. То есть 20% данных уйдёт в тест.
  • shuffle=True — перемешивание перед разбиением. Это снижает риск, что в train/test окажутся несбалансированные куски.
  • targets=["target"] — список целевых столбцов в датафрейме. Здесь цель одна: target.
  • Что означает параметр init у Model

  • init=LogisticRegression — UnionML будет создавать объект модели как LogisticRegression().
  • Если вы столкнётесь с предупреждением о сходимости (convergence warning), чаще всего помогает увеличить число итераций, но это лучше делать осознанно и явно. Мы оставляем минимальную конфигурацию, чтобы не усложнять старт.

    reader: читаем digits и возвращаем DataFrame

    Функция чтения данных должна возвращать pandas.DataFrame. Датасет digits из scikit-learn умеет сразу возвращать данные в табличном виде.

    Что вы получите:

  • столбцы с признаками — это числовые значения пикселей (для изображения 8×8 это 64 признака);
  • столбец target — правильная цифра от 0 до 9.
  • trainer: обучаем LogisticRegression

    Тренер получает:

  • estimator — созданный объект LogisticRegression;
  • features — датафрейм признаков;
  • target — датафрейм цели.
  • И возвращает обученный estimator.

    Почему здесь есть target.squeeze():

  • UnionML передаёт цель как таблицу (часто это DataFrame с одним столбцом);
  • scikit-learn обычно ожидает одномерный вектор меток;
  • squeeze() превращает столбец в одномерную структуру.
  • predictor: получаем предсказания классов

    Предиктор описывает, как получить предсказания из обученного estimator.

    Замечание:

  • LogisticRegression.predict возвращает метки классов (0–9);
  • мы приводим их к float, чтобы выход был единообразным типом.
  • evaluator: считаем accuracy на тесте

    Оценщик получает estimator, features, target и должен вернуть число (метрику качества).

    Что делает accuracy_score:

  • сравнивает истинные классы и предсказанные;
  • возвращает долю правильных ответов в диапазоне от 0 до 1.
  • Запуск: обучение и оценка в двух строках

    После того как все функции зарегистрированы, пайплайн можно выполнить.

    Если всё собрано правильно, вы увидите число около 0.9 и выше (точное значение зависит от разбиения и параметров).

    Частые проблемы и быстрые правки

  • NameError или отсутствие декоратора
  • - причина: ячейки выполнены не сверху вниз; - решение: перезапустите runtime и выполните ячейки по порядку.
  • Ошибка формата цели
  • - причина: модель ожидает одномерную цель; - решение: убедитесь, что в trainer и evaluator используется target.squeeze().
  • Предупреждение о сходимости LogisticRegression
  • - причина: по умолчанию может не хватать итераций; - решение: на следующем шаге можно перейти к явной настройке модели (например, max_iter).

    Как это связано с папкой проекта myproject

    Даже если вы пока пишете всё в ноутбуке, структура myproject полезна как место, куда вы позже перенесёте рабочий код:

  • читатель данных;
  • код обучения;
  • упаковку и развёртывание (в следующих материалах, благодаря шаблону basic-bentoml).
  • На текущем шаге вы получили главное: рабочую конфигурацию Dataset и Model, которая запускается одной командой обучения и одной командой оценки.

    5. Reader: загрузка sklearn digits в pandas DataFrame

    Reader: загрузка sklearn digits в pandas DataFrame

    В предыдущих шагах курса вы уже подготовили Colab-окружение, инициализировали проект через unionml init и собрали минимальный пайплайн UnionML: Dataset, Model, trainer, predictor, evaluator. Теперь сфокусируемся на одном ключевом элементе, без которого пайплайн не стартует: reader.

    reader — это функция, которая возвращает данные в виде pandas.DataFrame, чтобы UnionML смог:

  • выделить целевой столбец (например, target),
  • отделить признаки от цели,
  • выполнить разбиение на train/test,
  • передать данные в trainer и evaluator.
  • !Визуальная цепочка от загрузки digits до использования данных в обучении и оценке

    Что именно должен делать reader в UnionML

    Требования на практике простые:

  • функция должна быть помечена декоратором @dataset.reader;
  • функция должна возвращать один объект: pandas.DataFrame;
  • в датафрейме должен быть столбец(ы) цели, указанные в Dataset(targets=[...]).
  • Если у вас targets=["target"], значит датафрейм обязан содержать столбец target.

    > Важно: reader обычно не делает train/test split сам. Разделение выполняет UnionML на основе параметров Dataset (например, test_size=0.2, shuffle=True).

    Почему load_digits(as_frame=True) — самый удобный вариант

    Датасет digits из scikit-learn доступен «из коробки» и хорошо подходит для учебного пайплайна:

  • данные уже очищены и приведены к числовому виду;
  • признаки — это 64 числовых столбца (пиксели изображения 8×8);
  • цель — метка класса цифры 09.
  • Мы используем load_digits(as_frame=True), потому что он возвращает данные сразу в табличном виде.

    Полезные ссылки:

  • Документация sklearn.datasets.load_digits
  • Документация pandas.DataFrame
  • Документация UnionML
  • Кодовая ячейка: минимальный reader

    Ниже — тот же reader, который вы уже использовали в общей статье про Dataset и Model, но теперь мы разберём его точечно.

    Что происходит:

  • load_digits(as_frame=True) просит scikit-learn вернуть данные как таблицу;
  • .frame — это готовый DataFrame, где:
  • - 64 столбца признаков (часто они будут иметь имена вида pixel_0_0 или похожие, в зависимости от версии sklearn), - 1 столбец цели target.

    Проверяем, что reader возвращает именно то, что нужно

    Проверки особенно полезны, если вы:

  • меняете источник данных,
  • добавляете предобработку,
  • сталкиваетесь с ошибками вида «нет столбца target» или «не тот тип данных».
  • Кодовая ячейка: быстрый осмотр таблицы

    Как интерпретировать вывод:

  • type(df) должен быть <class 'pandas.core.frame.DataFrame'>;
  • df.shape обычно будет примерно (1797, 65):
  • - 1797 строк (примеров), - 65 столбцов (64 признака + target);
  • в df.columns должен присутствовать target.
  • Кодовая ячейка: проверяем целевой столбец

    Зачем это нужно:

  • если target отсутствует или называется иначе, UnionML не сможет корректно выделить цель;
  • распределение классов помогает понять, нет ли перекоса (для digits обычно всё достаточно ровно).
  • Как UnionML использует результат reader

    После того как reader зарегистрирован, вы обычно не вызываете его вручную в основном сценарии. Вместо этого вы запускаете:

    И внутри model.train() UnionML делает цепочку действий:

  • вызывает ваш reader;
  • отделяет признаки от target на основе Dataset(targets=[...]);
  • перемешивает данные (если shuffle=True);
  • делит на train/test (если задан test_size);
  • вызывает ваш trainer на train части.
  • Частые ошибки именно на шаге reader и как их исправлять

  • Столбца target нет
  • - причина: вы вернули только матрицу признаков без цели или переименовали столбец; - исправление: убедитесь, что DataFrame содержит target, либо измените targets=["..."] на актуальное имя.

  • reader возвращает не DataFrame, а другой тип
  • - причина: использовали load_digits() без as_frame=True и вернули, например, Bunch или numpy.ndarray; - исправление: используйте as_frame=True и возвращайте .frame, либо вручную соберите DataFrame.

  • Вы добавили предобработку и случайно испортили типы
  • - пример: превратили часть признаков в строки; - исправление: проверьте df.dtypes и убедитесь, что признаки числовые.

    Кодовая ячейка: быстрая проверка типов

    Что дальше по курсу

    Когда reader надёжно возвращает корректный DataFrame, пайплайн становится действительно воспроизводимым: можно менять модель, параметры обучения и способ оценки, не трогая источник данных.

    Следующий логичный шаг — научиться делать reader чуть более «прикладным»: например, добавлять простую предобработку или контролировать формат входных данных так, чтобы переход к упаковке (в связке с шаблоном basic-bentoml) был максимально гладким.

    6. Trainer и Predictor: обучение и предсказания

    Trainer и Predictor: обучение и предсказания

    В предыдущих статьях вы настроили окружение в Google Colab, инициализировали проект UnionML и определили Dataset с reader, который возвращает датасет digits как pandas.DataFrame. Теперь разберём два ключевых компонента пайплайна, которые превращают данные в работающую модель:

  • trainer — обучает модель на тренировочных данных
  • predictor — делает предсказания на новых данных
  • !Как данные и модель проходят через reader, trainer и predictor

    Зачем в UnionML нужны отдельные trainer и predictor

    В обычном scikit-learn ноутбуке вы часто пишете всё «вручную»: загрузили данные, сделали train_test_split, вызвали fit, потом predict. В UnionML идея другая: вы описываете, как именно обучать и предсказывать, а UnionML берёт на себя orchestration.

    Практический эффект:

  • вы фиксируете логику обучения как функцию (её легко переносить из ноутбука в проект)
  • один и тот же predictor используется и для ручных предсказаний, и внутри оценки качества
  • model.train() становится воспроизводимым: UnionML сам вызывает reader, делит данные, вызывает ваш trainer
  • Полезные ссылки:

  • Документация UnionML
  • LogisticRegression в scikit-learn
  • Контекст: Dataset и Model, к которым мы «подключаем» trainer/predictor

    Ниже — минимальная основа, которая должна уже быть в ноутбуке перед тем, как вы объявляете trainer и predictor.

    Критически важно:

  • targets=["target"] означает, что в датафрейме обязан быть столбец target
  • init=LogisticRegression означает, что UnionML создаст объект как LogisticRegression() и передаст его в trainer параметром estimator
  • trainer: как устроено обучение

    Что получает trainer

    Функция, помеченная декоратором @model.trainer, получает три аргумента:

  • estimator: объект модели (у нас это LogisticRegression)
  • features: таблица признаков (все столбцы, кроме target)
  • target: целевая переменная (обычно DataFrame с одним столбцом)
  • И возвращает обученный estimator.

    Почему часто нужен target.squeeze()

    scikit-learn обычно ожидает цель как одномерный вектор меток (например, Series или ndarray формы (n_samples,)). Но в пайплайнах цель нередко передаётся как таблица с одним столбцом.

    target.squeeze() делает цель «плоской»:

  • из DataFrame с формой (n, 1) получается одномерная структура
  • LogisticRegression.fit получает то, что ожидает
  • Кодовая ячейка: trainer для LogisticRegression

    Практический комментарий про сходимость

    На digits иногда встречается предупреждение о сходимости, зависящее от версии scikit-learn и параметров solver.

    Если вы хотите сделать обучение стабильнее, вы можете явно задать параметры модели через init как функцию (важно: это тот же объект Model, просто другой способ инициализации):

    Смысл max_iter=1000: дать алгоритму больше итераций для оптимизации. На старте курса это не обязательно, но полезно, если вы видите предупреждения.

    predictor: как устроены предсказания

    Задача predictor в UnionML

    Функция, помеченная декоратором @model.predictor, отвечает за преобразование:

  • вход: обученный estimator и features
  • выход: предсказания в удобном формате
  • Желательно, чтобы результат был простым для логирования и сериализации (например, список чисел).

    Кодовая ячейка: predictor, возвращающий список классов

    Почему здесь float, хотя классы целочисленные:

  • в учебных пайплайнах часто унифицируют тип выхода (например, «список чисел»)
  • если позже вы будете упаковывать модель как сервис, простой JSON-совместимый формат удобнее
  • Если вы хотите оставить целые числа, можно вернуть List[int], но тогда стоит убедиться, что остальная часть пайплайна ожидает именно это.

    Мини-проверка в ноутбуке: обучить и предсказать на нескольких строках

    После того как объявлены reader (из предыдущей статьи), trainer и predictor, можно сделать короткий прогон.

    Кодовая ячейка: обучение

    Что произойдёт внутри model.train():

  • UnionML вызовет ваш reader и получит полный датафрейм
  • отделит признаки от target
  • сделает разбиение на train/test по test_size=0.2
  • вызовет ваш trainer на тренировочной части
  • Кодовая ячейка: предсказание на первых 5 объектах

    Ожидаемый результат:

  • список длины 5
  • элементы — числа, соответствующие предсказанным классам цифр
  • > Важно: в этом примере мы предсказываем на строках из полного датасета. Для «честной» проверки качества используйте evaluator (он прогонит тестовую часть), но сам факт работы predictor удобно проверить именно так.

    Типовые ошибки в trainer и predictor и быстрые исправления

    Ошибка: модель не обучается из-за формы target

    Признак:

  • ошибка от scikit-learn про размерность y
  • Исправление:

  • убедитесь, что в trainer используется target.squeeze()
  • Ошибка: в predictor передали не те данные

    Признак:

  • ошибка про несовпадение числа признаков
  • Причина:

  • в features случайно попал столбец target или столбцы отличаются от тех, что были при обучении
  • Исправление:

  • перед предсказанием всегда формируйте X как df.drop(columns=["target"])
  • Ошибка: predictor возвращает не тот тип

    Признак:

  • дальнейшие шаги пайплайна (например, оценка) падают на сравнении типов
  • Исправление:

  • возвращайте простой тип: List[float] или List[int]
  • придерживайтесь одного формата и в evaluator
  • Что дальше по курсу

    Теперь у вас есть два ключевых блока «поведения» модели:

  • trainer закрепляет, как именно обучать LogisticRegression на digits
  • predictor закрепляет, как именно получать предсказания
  • Следующий логичный шаг — закрепить это в оценке качества через evaluator и затем перейти к более прикладным аспектам: управлению параметрами, сохранению артефактов и упаковке (шаблон basic-bentoml для этого уже подготовлен).

    7. Evaluator: метрика accuracy и проверка качества

    Evaluator: метрика accuracy и проверка качества

    В прошлых статьях вы настроили окружение в Google Colab, создали проект через unionml init, определили Dataset с reader, а также описали trainer и predictor для LogisticRegression на датасете digits.

    Теперь добавим последний обязательный элемент минимального пайплайна: evaluator. Он отвечает за формальную проверку качества модели на тестовой части данных.

    !Схема показывает, что evaluator использует predictor и считает accuracy на тестовых данных

    Что делает evaluator в UnionML

    evaluator в UnionML — это функция, которую вы регистрируете декоратором @model.evaluator. Её роль:

  • получить обученный estimator и тестовые features и target
  • вызвать логику предсказания (обычно через ваш же predictor)
  • посчитать метрику качества и вернуть число (float)
  • Зачем это выделять в отдельную функцию:

  • метрика становится частью воспроизводимого пайплайна
  • одна и та же логика оценки переиспользуется при любом запуске
  • model.evaluate(estimator) превращается в стабильный “один вызов — один результат”
  • Полезные ссылки:

  • Документация UnionML
  • accuracy_score в scikit-learn
  • Digits dataset в scikit-learn
  • Метрика accuracy: что измеряем

    Accuracy — это доля правильных ответов.

    В терминах классификации:

  • модель делает предсказания классов (для digits это цифры от 0 до 9)
  • accuracy показывает, какая часть объектов классифицирована верно
  • Запись через формулу (чтобы было однозначно):

    Где:

  • число правильных предсказаний — сколько раз предсказанный класс совпал с истинным
  • общее число предсказаний — сколько объектов было в тестовой выборке
  • Практически это число в диапазоне от до .

    Код: evaluator для digits-классификатора

    Предполагается, что у вас уже определены:

  • dataset = Dataset(... targets=["target"])
  • model = Model(... init=LogisticRegression, dataset=dataset)
  • reader, trainer, predictor
  • Ниже — минимальная реализация evaluator, совместимая с остальными блоками.

    Почему здесь снова нужен target.squeeze()

    UnionML часто передаёт цель как DataFrame формы (n, 1). А accuracy_score ожидает одномерный вектор истинных меток.

    target.squeeze() делает цель “плоской”, чтобы тип и форма данных были корректными для scikit-learn.

    Почему evaluator вызывает predictor, а не estimator.predict

    Это важный стиль UnionML:

  • predictor фиксирует “контракт предсказания” в одном месте
  • вы не дублируете логику предсказания в нескольких местах
  • если вы поменяете формат выхода предиктора, вы обновите его один раз
  • Запуск оценки в Colab

    После того как объявлены все декораторы, вы запускаете обучение и оценку отдельной ячейкой.

    Интерпретация результата:

  • score — это accuracy на тестовой части
  • значение ближе к 1.0 означает более точную классификацию
  • Быстрая ручная проверка: одинаковая длина истинных и предсказанных меток

    Если вы отлаживаете пайплайн, полезно быстро убедиться, что предсказания “согласованы” по длине с целью.

    Что здесь важно:

  • это не замена model.evaluate, потому что нет тестового разделения
  • это полезно, чтобы поймать ошибки формата данных до запуска пайплайна UnionML
  • Частые ошибки на шаге evaluator и как их исправить

  • Ошибка про размерности y_true и y_pred
  • - причина: target остался DataFrame (n, 1), а где-то ожидается одномерный вектор - исправление: используйте target.squeeze() в evaluator

  • Ошибка про несовпадение числа признаков при предсказании
  • - причина: в features случайно попал столбец target или набор колонок отличается от обучающего - исправление: убедитесь, что признаки формируются как df.drop(columns=["target"])

  • model.evaluate(estimator) падает, потому что estimator не обучен
  • - причина: вы передали новый LogisticRegression() вместо результата model.train() - исправление: сначала estimator = model.train(), затем model.evaluate(estimator)

    Что дальше

    Теперь у вас есть полный минимальный пайплайн UnionML для классификации digits:

  • reader возвращает данные
  • trainer обучает модель
  • predictor делает предсказания
  • evaluator считает метрику accuracy
  • Следующие логичные улучшения после этого шага:

  • управлять параметрами модели (например, max_iter) для стабильной сходимости
  • добавлять дополнительные метрики и диагностику ошибок (например, матрицу ошибок)
  • переходить к упаковке и развёртыванию, для чего в курсе уже использован шаблон basic-bentoml