Москва: проверенные б/у ноутбуки с гарантией и проверкой перед оплатой
+7 906 722-94-45

Главная → Статьи → scikit-learn без GPU: обучение на ноутбуке

scikit-learn на ноутбуке: классический ML без GPU и без боли

Практика scikit-learn на обычном ноутбуке: какие алгоритмы быстры на CPU, подготовка данных и Pipeline, кросс-валидация, подбор гиперпараметров, когда данных «слишком много» — рабочие рецепты.

Прямой ответ

GPU для scikit-learn не нужен по определению: библиотека изначально CPU-ориентирована, и на табличных данных (до миллионов строк, сотни признаков) ноутбук с 16 ГБ RAM решает большинство задач — от линейных моделей до градиентного бустинга — за секунды-минуты. Ключ к скорости — не железо, а порядок работы: подготовка данных в Pipeline (утечек нет, код воспроизводим), быстрые алгоритмы для старта (HistGradientBoosting, LogisticRegression с saga/LBFGS, линейные модели на разреженных данных), кросс-валидация с n_jobs=-1 (параллель по ядрам), и масштабирование признаков там, где алгоритм этого требует. GPU-история начинается у нейросетей (PyTorch — отдельная статья); локальные LLM — тоже не sklearn (про Ollama здесь).

Что быстро на CPU, а что нет

Быстро (секунды–минуты на 100k строк): линейные модели (LogisticRegression/LinearRegression/Ridge — оптимизированы, разреженные матрицы поддерживаются), HistGradientBoosting (гистограммный бустинг — ответ sklearn на LightGBM, nan поддерживает нативно), RandomForest (параллелится по деревьям, n_jobs=-1), k-means/MiniBatchKMeans, SGD-классификаторы (потоковые, частичное обучение partial_fit). Медленно/осторожно: SVM с RBF на >50k строк (квадратичная сложность — берите LinearSVC/SGD), KNeighbors на больших данных (без индекса — перебор; ограничение — размерность и объём), полный GridSearch по большим сеткам (см. ниже). Правило: если обучение «залипло» — сначала проверьте алгоритм и размерность, потом думайте про железо.

Pipeline: воспроизводимость вместо лапши

Pipeline([("prep", ColumnTransformer(...)), ("model", ...)]) — каноническая форма: предобработка (импутация, скейлинг, кодирование категорий) и модель — один объект, который fit/predict атомарно. Главная причина — не удобство, а утечки: скейлер, обученный на всех данных до кросс-валидации, «подсматривает» в тест — метрики завышены, модель в проде хуже. ColumnTransformer разделяет числовые и категориальные ветки (один импутер+стандартизация, другой — one-hot/ordinal), а set_output(transform="pandas") сохраняет имена колонок для отладки. Подготовка самих таблиц (типы, пропуски) — до sklearn, в pandas (производительность); sklearn любит числовые матрицы и честные NaN только в отдельных алгоритмах (HistGB).

Валидация и подбор: дисциплина вместо магии

Разделение данных: train/test один раз (train_test_split, стратифицировано для дисбаланса), подбор — кросс-валидацией на train (cross_val_score, KFold/StratifiedKFold), тест — только финальная оценка. Подбор гиперпараметров: GridSearchCV — маленькие сетки; RandomizedSearchCV — большие (за тот же бюджет времени пробует разнообразнее); HistGradientBoosting с early stopping (валидационная доля внутри fit) — часто отменяет отдельный поиск числа итераций. n_jobs=-1 параллелит фолды по ядрам ноутбука; память — главный лимит (каждый job дублирует данные — на больших датасетах n_jobs=физические ядра, не гиперпоточные). Метрика под задачу (не accuracy по умолчанию: ROC-AUC/PR-AUC для дисбаланса, MAE/quantile для регрессии) — решение предметное, принимается до экспериментов.

Когда данных больше, чем удобно

Лестница при нехватке ресурсов: MiniBatch-алгоритмы (partial_fit — SGD, MiniBatchKMeans: данные порциями, память ограничена); уменьшение объёма (сэмплирование строк для разведки, отбор признаков — SelectKBest/важности модели); эффективные типы (float32 вместо float64, разреженные матрицы scipy.sparse для one-hot высокой размерности — экономия в разы, как и dtypes в pandas); DuckDB/pandas-фильтрация до обучения (учить на нужном срезе, не на всём). Признак «пора на сервер» — не «медленно», а «не влезает и MiniBatch не помогает»; для большинства табличных задач это порог заметно выше, чем принято думать.

Интерпретация и продакшн модели

«Работает» ≠ «понятно»: permutation_importance (честная важность признаков против «грязной» importance бустинга), SHAP-значения для локальных объяснений, learning_curve (добавит ли данных — частый вопрос владельца). Сохранение — joblib.dump (pickle-семейство: та же хрупкость к версиям классов — фиксируйте версии sklearn в окружении; о сериализации — статья про pickle/json); продакшн-инференс sklearn-модели — обычный Python-код за API (FastAPI-сервис с моделью в lifespan — механика зависимостей), версионирование модели — рядом с версией пайплайна и данных.

Практический сценарий: предсказание оттока за вечер

Задача-классика: по таблице клиентов (50 тысяч строк, тридцать признаков) предсказать отток. Реалистичный порядок действий на ноутбуке. Разведка: pandas-профиль данных — пропуски, распределения, дисбаланс классов (отток — редкое событие, пять процентов; это определяет метрику: не accuracy, а ROC-AUC или PR-AUC). Разделение: train_test_split(stratify=y) один раз — тест откладывается и больше не трогается до финала. Pipeline: числовые признаки — импутация медианой + StandardScaler, категориальные — OneHot (небольшая кардинальность) через ColumnTransformer, модель — HistGradientBoostingClassifier (nan не страшны, скейлинг не обязателен, но в пайплайне порядок есть порядок). Оценка: cross_val_score с пятью фолдами и scoring="roc_auc", n_jobs=-1 — ноутбук считает секунды. Настройка: RandomizedSearchCV по небольшой сетке (глубина, learning rate, листы) — десять минут вместо грида на час; early stopping внутри HistGB бережёт от переобучения числом итераций. Интерпретация: permutation_importance — какие признаки реально двигают предсказание (часто выясняется, что половина таблицы не нужна — модель упрощается). Финал: fit на всём train, одна оценка на отложенном тесте, цифры — в отчёт; сохранение — joblib вместе с версиями sklearn и слепком данных. Весь вечер — и ни одного аргумента «нужен GPU»: табличные пятьдесят тысяч строк — весовая категория CPU.

FAQ

LightGBM/XGBoost или HistGradientBoosting? HistGB встроен в sklearn (ноль зависимостей, nan из коробки) и на большинстве задач близок по качеству; LightGBM/XGBoost — когда нужны их специфичные настройки, категориальные фичи нативно или максимум скорости. Начинать разумно со встроенного.

Правда ли, что нейросети всегда лучше на таблицах? Нет: на табличных данных градиентный бустинг регулярно выигрывает у нейросетей при порядки меньших затратах — это устойчивый результат бенчмарков. Нейросети — для изображений/текста/последовательностей, и вот там нужен GPU.

Сколько RAM нужно для обучения? Ориентир: 5–10× размер датасета в памяти для комфортной работы (копии в кросс-валидации, one-hot). Таблица 100k×50 (десятки МБ) — любой ноутбук; 10M строк — float32, MiniBatch или фильтрация.

Как ускорить, если всё же медленно? Порядок действий: float32 и разреженность → уменьшить сетку поиска (RandomizedSearch) → n_jobs по ядрам → MiniBatch/сэмплирование → и только потом думать про другое железо. Профилирование узкого места — как для любого Python-кода.

Источники: пользовательское руководство scikit-learn (pipeline, model evaluation) — ссылки в шапке.