Изучаем машинное обучение scikit-learn за одну статью: от понимания API до боевого пайплайна. data science.. data science. machine learning.. data science. machine learning. python.. data science. machine learning. python. scikit-learn.. data science. machine learning. python. scikit-learn. для начинающих.. data science. machine learning. python. scikit-learn. для начинающих. Машинное обучение.. data science. machine learning. python. scikit-learn. для начинающих. Машинное обучение. руководство.

1. Введение: что за зверь этот scikit-learn и зачем он вам

Если вы начинаете погружаться в машинное обучение на Python, scikit-learn (в народе просто sklearn) — это ваша отправная точка. Это абсолютный индустриальный стандарт и швейцарский нож для классического ML.

Для чего он идеален:

  • Табличные данные. Всё, что можно представить в виде CSV-файла или таблицы в базе данных.

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

Для чего он НЕ подходит:

  • Глубокое обучение (Deep Learning).

  • Работа с «тяжелыми» неструктурированными данными: распознавание лиц на фото, генерация текстов, обработка видео или аудио.

  • Практический совет: если ваша задача требует нейросетей, sklearn вам не помощник — для этого нужно брать PyTorch или TensorFlow.

Что нужно знать, прежде чем читать дальше? Я не буду продавать вам иллюзию, что ML — это магия из двух строчек кода, понятная вообще всем. Чтобы примеры ниже не выглядели как заклинания, вам понадобится базовый джентльменский набор:

  1. Python — понимание переменных, функций и того, как вызывать методы у объектов. Моя статья как выучить Python и не разориться: 5 лучших бесплатных курсов для новичков.

  2. pandas — хотя бы на уровне «могу загрузить таблицу и посмотреть на колонки». Мой бесплатный курс на Stepik Pandas для анализа данных: Полный курс.

  3. numpy — базовое представление о том, что такое массивы и матрицы. Моя статья NumPy с нуля: понятный гайд для тех, кто хочет в Data Science.

Если этот фундамент есть — отлично. Поехали разбираться, как тут всё устроено.

2. Главный секрет sklearn: Единый API

Знаете, почему scikit-learn так любят? Из-за его гениальной предсказуемости. Разработчики библиотеки сделали так, что вам не нужно учить новый синтаксис для каждого алгоритма.

Поняв принцип один раз, вы сможете использовать и простую линейную регрессию, и навороченный случайный лес, просто меняя название алгоритма. Всё строится вокруг единого стандарта (API) и двух ключевых концепций: правильного формата данных и методов.

Концепция 1: Матрица X и вектор y

Алгоритмы не понимают абстрактных слов. Им нужны цифры, разложенные по правильным полочкам. В ML эти полочки всегда делятся на две части:

  • Матрица признаков X (большая X): Это ваша основная таблица с данными. Если мы предсказываем цену квартиры, то X — это площадь, этаж, удаленность от метро. По сути, это ваш датафрейм (таблица) без той колонки, которую мы пытаемся предсказать.

  • Вектор ответов y (маленькая y): Это наша цель (target). Та самая колонка с ценами, которую мы отрезали от таблицы X. Это правильные ответы, на которых модель будет учиться.

Почему X большая, а y маленькая? Это математическая традиция: X — это двумерная матрица, а y — одномерный вектор.

Концепция 2

Вся работа с любой моделью или инструментом подготовки данных в sklearn сводится к трем главным командам:

  1. .fit() — Обучение (поиск закономерностей) Вы говорите модели: «Смотри, вот данные (X), а вот правильные ответы (y). Ищи связь!». В коде это выглядит элементарно: model.fit(X, y). В этот момент внутри алгоритма крутится математика, и он «умнеет».

  2. .predict() — Предсказание (экзамен) Модель обучилась. Теперь мы даем ей новые данные, которых она раньше не видела (назовем их X_new), и просим предсказать ответы. Код: predictions = model.predict(X_new). Модель выдаст свой массив с ответами.

  3. .transform() — Преобразование (подготовка данных) Этот метод используется не для самих предсказаний, а для подготовки данных (например, когда нужно привести все числа к одному масштабу или заполнить пропуски). Инструмент сначала “изучает” данные через .fit(), а потом физически меняет их через .transform(). Лайфхак: часто используют метод-гибрид .fit_transform(), который делает оба действия за один шаг.

Итого: Создали модель rightarrow скормили ей данные через .fit(X, y) rightarrow получили прогнозы через .predict(X_new). Это база, на которой строится 90% кода в классическом ML.

3. Шаг 1. Подготовка данных: Разделяй и властвуй

Прежде чем скармливать данные алгоритму, их нужно подготовить. В машинном обучении работает жесткое правило: «мусор на входе — мусор на выходе».

Для начала загрузим наши данные:

import pandas as pd
from sklearn.datasets import fetch_california_housing

# Загружаем встроенный датасет
california = fetch_california_housing()

# Создаем матрицу признаков X (наша таблица) и вектор ответов y (наша цель - цена)
X = pd.DataFrame(california.data, columns=california.feature_names)
y = california.target # Цена в сотнях тысяч долларов

Разделение выборки (Train/Test Split)

Представьте, что вы школьный учитель. Вы дали ученикам выучить 10 билетов, а на экзамене спросили ровно эти же 10 билетов. Все сдали на пятерки. Значит ли это, что ученики гениально знают предмет? Нет, они просто зазубрили ответы.

Алгоритмы машинного обучения тоже обожают «зазубривать» данные (это называется переобучением). Чтобы честно оценить модель, мы должны спрятать от нее часть квартир во время обучения, а потом использовать эту заначку как экзамен. Модель должна показать хороший результат на домах, которых она никогда раньше не видела.

Рубим наши данные на две части: обучающую (80%) и тестовую (20%).

from sklearn.model_selection import train_test_split

# test_size=0.2 означает, что 20% данных уходит на "экзамен"
# random_state=42 фиксирует случайность, чтобы при каждом запуске данные бились одинаково

X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)

Всё. Теперь учить модель мы будем строго на X_train, а тестировать — на X_test.

Масштабирование признаков (Scaling)

Теперь второй, совершенно неочевидный для новичков момент. Давайте посмотрим на два признака из наших калифорнийских данных: медианный доход (MedInc) и население района (Population).

Если мы выведем пару строк, то увидим, что доход измеряется единицами (например, 8.3 — это 83 тысячи долларов), а население — тысячами (например, 3220 человек).

Внутри большинства алгоритмов работает базовая математика: они складывают числа или ищут расстояния между точками. Алгоритм не понимает физического смысла колонок. Для него 3220 — это гигантское число, а 8.3 — какая-то мелочь. Из-за этого модель может решить, что население важнее дохода в сотни раз, и просто проигнорирует зарплаты людей (хотя для цены квартиры доход куда важнее!). Алгоритм в прямом смысле “сойдет с ума” от разницы в масштабах.

Чтобы уравнять признаки в правах, данные нужно масштабировать. Мы используем StandardScaler, который пересчитывает колонки так, чтобы среднее значение стало равно 0, а разброс данных был сопоставимым. Никто не будет перетягивать одеяло на себя.

from sklearn.preprocessing import StandardScaler

# 1. Создаем наш инструмент (объект класса)
scaler = StandardScaler()

# 2. "Учим" скалер на тренировочных данных и сразу преобразуем их
# Метод 2-в-1: .fit_transform()
X_train_scaled = scaler.fit_transform(X_train)

# 3. ВАЖНО! Тестовые данные мы ТОЛЬКО преобразуем методом .transform()
# Мы НЕ делаем .fit() на тесте, иначе информация из теста "протечет" в обучение 
# (это называется Data Leakage), и мы обманем сами себя.
X_test_scaled = scaler.transform(X_test)

Обратите внимание на код: мы снова видим наш единый API в действии. Создали инструмент scaler rightarrow вызвали метод .fit() (или гибрид .fit_transform()) rightarrow применили к другим данным через .transform(). Всё максимально логично.

4. Шаг 2. Выбираем модель (Обучение с учителем)

В машинном обучении существуют десятки алгоритмов: деревья решений, метод опорных векторов, градиентный бустинг… Новички часто впадают в ступор, пытаясь выучить их все сразу.

Выдохните. Прелесть sklearn в том, что вам пока не нужно досконально знать математику под капотом каждого из них. Вам нужно лишь понять, какую задачу вы решаете. Все классические задачи обучения с учителем (когда у нас есть правильные ответы y) жестко делятся на два лагеря.

Лагерь 1: Задача Регрессии (предсказываем число)

Вы решаете задачу регрессии, если ваш ответ — это непрерывная величина. Температура на завтра, зарплата сотрудника или, как в нашем случае, цена квартиры в Калифорнии.

Для этой задачи отлично подходят LinearRegression (простая линейная модель) или RandomForestRegressor (мощный алгоритм на основе леса деревьев решений). Возьмем второй, он обычно сразу выдает отличный результат.

И вот они, те самые легендарные три строчки кода, за которые платят зарплату дата-саентистам:

from sklearn.ensemble import RandomForestRegressor

# 1. Создаем пустую модель (инициализируем алгоритм)
model = RandomForestRegressor(random_state=42)

# 2. Обучаем модель! Отдаем ей отмасштабированные признаки и правильные ответы
model.fit(X_train_scaled, y_train)

# 3. Экзамен. Просим модель предсказать цены для районов, которых она не видела
predictions = model.predict(X_test_scaled)

Всё. В переменной predictions теперь лежит массив чисел — цены, которые предсказал наш алгоритм.

Лагерь 2: Задача Классификации (предсказываем категорию)

Вы решаете задачу классификации, если ваш ответ — это конкретный класс (категория). Письмо: спам или не спам? Транзакция: мошенническая или легальная? Пациент: болен или здоров?

Популярные алгоритмы здесь — LogisticRegression (пусть слово “регрессия” в названии вас не путает, это исторический казус, алгоритм строго для классификации) или RandomForestClassifier.

Если бы мы вдруг решили переделать нашу калифорнийскую задачу и предсказывать не саму цену, а просто класс района (например, 1 — элитный, 0 — обычный), наш код выглядел бы так:

from sklearn.linear_model import LogisticRegression

# Те же самые 3 строчки кода!
classifier = LogisticRegression()
classifier.fit(X_train_scaled, y_train_classes) # y_train_classes - это нули и единицы
class_predictions = classifier.predict(X_test_scaled)

5. Шаг 3. Оценка качества: А не ерунду ли мы предсказали?

Итак, модель обучена, метод .predict() выдал нам массив каких-то чисел. Возникает логичный вопрос: а модель вообще молодец или она предсказывает погоду на Марсе? Нам нужно измерить её качество.

В sklearn для этого есть модуль metrics. Метрик существует огромное количество, но для старта достаточно понимать две главные концепции.

Для регрессии: Понятная бизнесу MAE

В задачах регрессии (где мы предсказывали цену квартиры) самая интуитивно понятная метрика — это MAE (Mean Absolute Error, Средняя абсолютная ошибка).

Как она работает: алгоритм берет предсказанную цену квартиры, вычитает из неё реальную цену (ту, что мы спрятали в y_test), убирает минус, если он есть, и считает среднее арифметическое по всем квартирам.

Её главное преимущество — она измеряется в тех же “попугаях”, что и ваша целевая переменная. Бизнесу не нужно объяснять сложную математику, вы просто говорите: «В среднем наша модель ошибается на 40 тысяч долларов».

from sklearn.metrics import mean_absolute_error

# Сравниваем реальные ответы с экзамена (y_test) с тем, что нарешала модель (predictions)
mae = mean_absolute_error(y_test, predictions)

# Так как в калифорнийском датасете цены указаны в сотнях тысяч, 
# умножим на 100 000 для наглядности
print(f"В среднем наша модель ошибается на ${mae * 100000:.0f}") 

Для классификации: Ловушка Accuracy и почему она врёт

С классификацией (где мы предсказываем категории) всё хитрее. Первое, что приходит в голову новичку — посчитать долю правильных ответов (Accuracy). Угадали 90 из 100? Значит Accuracy 90%. Звучит логично, но на несбалансированных данных эта метрика нагло врёт.

Классический пример: Представьте, что мы делаем модель для поиска редкой болезни. В нашей тестовой выборке 100 человек: 99 здоровы и 1 болен. Мы пишем самую глупую “модель” в мире, которая вообще не смотрит на анализы, а просто всем подряд выдает ответ: «Здоров!».

Какая у нее будет Accuracy? 99%! (Она угадала 99 здоровых из 100). Руководство в восторге, вам дают премию, а тот самый 1 больной человек уходит без лечения. Модель с точностью 99% оказалась абсолютно бесполезной.

Поэтому в серьезных задачах смотрят на две другие метрики:

  1. Precision (Точность): Из всех людей, которых модель назвала больными, сколько реально больных? (Не слишком ли часто мы поднимаем ложную тревогу?).

  2. Recall (Полнота): Из всех реально больных людей, скольких модель смогла найти? (Не пропустили ли мы кого-то важного?).

В sklearn есть шикарная функция, которая в одну строчку выводит красивый отчет по всем этим метрикам сразу:

from sklearn.metrics import classification_report

# Представим, что мы работаем с нашей гипотетической задачей классификации из Шага 2
# y_test_classes - реальные нули и единицы (элитный/обычный район)
# class_predictions - прогнозы нашей логистической регрессии

report = classification_report(y_test_classes, class_predictions)
print(report)

Вызвав этот метод, вы получите текстовую табличку, где для каждого класса (элитный или обычный) будут расписаны его Precision, Recall и общая Accuracy. Сразу видно, где модель молодец, а где халтурит.

6. Шаг 4. Уровень “Pro”: собираем всё в Pipeline

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

В предыдущих шагах мы делали всё руками: сначала создали скалер, обучили его на трейне, преобразовали трейн, потом не забыли (надеюсь!) аккуратно преобразовать тест с помощью .transform(), затем скормили всё это в модель…

Проблема: Почему ручной труд — это боль и риск

В реальных задачах подготовка данных состоит не из одного шага, а из пяти-шести: заполнить пропуски, закодировать текст в числа, отмасштабировать признаки, удалить выбросы.

Если делать .fit и .transform вручную на каждом этапе:

  1. Это дублирование кода. Ваш Jupyter Notebook превратится в нечитаемую простыню из переменных вида X_train_scaled_encoded_filled.

  2. Это огромный риск утечки данных (Data Leakage). Стоит вам один раз случайно написать .fit_transform(X_test) вместо .transform(X_test), как тестовые данные «сольют» информацию о себе алгоритму. Ваши метрики взлетят до небес, вы обрадуетесь, выкатите модель в продакшен, и там она с треском провалится, потому что на самом деле ничему не научилась.

Решение: Встречайте Pipeline (Конвейер)

Разработчики sklearn придумали гениальную вещь — класс Pipeline. Это буквально труба, в которую вы друг за другом засовываете все шаги подготовки данных и саму модель в конце.

Давайте перепишем наш код из Шагов 1 и 2 так, как это делают профессионалы. Нам больше не нужно вручную создавать отмасштабированные переменные.

from sklearn.pipeline import make_pipeline
from sklearn.preprocessing import StandardScaler
from sklearn.ensemble import RandomForestRegressor, RandomForestClassifier

# 1. Собираем наш конвейер. 
# Данные будут перетекать слева направо: сначала в StandardScaler, затем в модель.
# Вернемся к нашей задаче предсказания цен (регрессия):
pipeline = make_pipeline(
    StandardScaler(), 
    RandomForestRegressor(random_state=42)
)

# Если бы мы решали задачу классификации (болен/здоров), код был бы таким:
# pipeline = make_pipeline(StandardScaler(), RandomForestClassifier())

# 2.  ОДИН вызов .fit() для всей цепочки.
# Пайплайн сам поймет, что для скалера нужно сделать .fit_transform(), 
# а для модели в конце — просто .fit()
pipeline.fit(X_train, y_train)

# 3. ОДИН вызов .predict() для экзамена.
# Пайплайн сам пропустит X_test через .transform() скалера и отдаст в модель.
# Никакого риска утечки данных!
predictions = pipeline.predict(X_test)

Что здесь произошло? Мы инкапсулировали (спрятали) всю логику в один объект pipeline. Снаружи он ведет себя как обычная модель: у него есть те же самые .fit() и .predict(). Вы отдаете в него сырые данные, а на выходе получаете готовые предсказания.

Именно в таком виде модели сохраняют на жесткий диск и отправляют работать на реальные сервера.

7. Заключение и куда копать дальше

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

Давайте зафиксируем 5 главных правил, которые мы сегодня выучили:

  1. API предсказуем. Всё строится вокруг святой троицы: .fit() (учимся), .predict() (предсказываем), .transform() (преобразуем данные).

  2. Не обманывайте себя. Всегда делите данные на обучение и тест (train_test_split), иначе модель просто “зазубрит” ответы.

  3. Масштабируйте признаки. Алгоритмы глупые, они верят цифрам. Используйте StandardScaler, чтобы зарплата в миллионах не задавила возраст в десятках.

  4. Смотрите на правильные метрики. Для предсказания чисел берите MAE, а для классификации забудьте про Accuracy на несбалансированных данных — смотрите на Precision и Recall.

  5. Используйте Pipeline. Это ваш билет в клуб профессионалов. Он спасает от дублирования кода и утечки данных (data leakage).

Анонсы новых статей, полезные материалы, а так же если в процессе у вас возникнут сложности, обсудить их или задать вопрос по этой статье можно в моём Telegram-сообществе. Смело заходите, если что-то пойдет не так, — постараемся разобраться вместе.

Что осталось за кадром? (Ваше домашнее задание)

scikit-learn огромен, и в одну статью его не впихнуть. Вот три темы, которые вам стоит изучить следующими, чтобы стать уверенным ML-инженером:

  • Обучение без учителя (Unsupervised Learning). Что делать, если у вас нет вектора ответов y, а есть просто данные, и в них нужно найти структуру? Почитайте про Кластеризацию (алгоритм K-Means, чтобы разбить клиентов на сегменты) и PCA (метод главных компонент для сжатия данных).

  • Подбор гиперпараметров. В нашем коде мы использовали модели “из коробки” с настройками по умолчанию. Но у каждого алгоритма есть десятки крутилок (глубина деревьев, скорость обучения). Почитайте про GridSearchCV — он умеет автоматически перебирать эти крутилки и находить лучшую комбинацию.

  • Кросс-валидация (Cross-Validation). Разбивать данные на train и test один раз — это хорошо, но разбивать их на 5 частей и гонять модель по кругу, меняя тестовую часть (K-Fold) — это надежно.

Полезные ссылки для практики

  1. Официальная документация scikit-learn — я не шучу, это одна из лучших документаций в мире опенсорса. Это не просто справочник по коду, это полноценный и бесплатный учебник по машинному обучению с крутейшими графиками и объяснением математики. Читайте User Guide.

  2. Датасеты для тренировки (Kaggle):

    • Для регрессии: Medical Cost Personal Datasets — попробуйте предсказать стоимость медицинской страховки на основе возраста, ИМТ и курения.

    • Для классификации: Spaceship Titanic — веселая альтернатива заезженному Титанику. Предскажите, кого из пассажиров космического корабля перенесло в другое измерение.

Автор: enamored_poc

Источник