Первая модель на scikit-learn: классификация за 20 минут
Пошаговый разбор: как обучить и проверить модель классификации на реальном датасете с помощью scikit-learn, не вникая в математику под капотом.

К концу этой инструкции у вас будет обученная модель, которая по параметрам цветка ириса определяет его вид с точностью около 95%. Заодно вы поймёте, зачем данные делят на две части и почему точность на обучающей выборке ничего не значит. Времени уйдёт минут двадцать, если Python уже установлен. Математику не трогаем — scikit-learn считает всё сам, ваша задача правильно подготовить данные и прочитать результат.
Что нужно до начала
Никакого GPU и мощного железа для этой задачи не требуется — датасет крошечный, всё считается на ноутбуке за доли секунды. Проверьте перед стартом:
- Python 3.9 или новее. Проверить:
python --versionв терминале. - Установленный scikit-learn. Статья написана под версию 1.5.x. Ставится командой
pip install scikit-learn. Вместе с ней подтянутся NumPy и SciPy — они нужны библиотеке для работы. - Любой способ запускать код: файл
.py, Jupyter Notebook или интерактивная консоль. Для первого раза удобнее Jupyter — видно результат каждого шага.
Датасет скачивать не нужно: набор ирисов Фишера встроен прямо в scikit-learn.
Что такое датасет ирисов
Это классический учебный набор из 150 строк. Каждая строка — один цветок с четырьмя измерениями (длина и ширина чашелистика и лепестка в сантиметрах) и меткой вида: setosa, versicolor или virginica. Задача — научить модель по четырём числам угадывать вид. Такой тип задачи называется классификацией: результат — одна из нескольких заранее известных категорий.1
Шаг 1. Загрузить данные
Импортируем набор и посмотрим, что внутри.
# scikit-learn 1.5.x
from sklearn.datasets import load_iris
iris = load_iris()
print("Форма матрицы признаков:", iris.data.shape)
print("Названия признаков:", iris.feature_names)
print("Классы:", iris.target_names)
В консоли должно появиться: Форма матрицы признаков: (150, 4), список из четырёх признаков и три класса. iris.data — это 150 строк по 4 числа, iris.target — 150 меток (числа 0, 1, 2, соответствующие видам).
Шаг 2. Разделить данные на обучающую и тестовую части
Ключевой момент, который новички часто пропускают. Если обучить модель на всех данных, а потом на них же проверить, она покажет отличную точность — но это самообман: модель уже видела ответы. Настоящую способность угадывать проверяют на данных, которых модель не видела.
from sklearn.model_selection import train_test_split
X_train, X_test, y_train, y_test = train_test_split(
iris.data,
iris.target,
test_size=0.3, # 30% данных уходит в тест
random_state=42, # фиксируем случайность ради воспроизводимости
stratify=iris.target # сохраняем пропорции классов в обеих частях
)
print("Обучающая выборка:", X_train.shape[0], "строк")
print("Тестовая выборка:", X_test.shape[0], "строк")
Должно вывести Обучающая выборка: 105 строк и Тестовая выборка: 45 строк. Параметр random_state=42 — любое фиксированное число: оно делает разбиение одинаковым при каждом запуске, чтобы результаты совпадали с этой статьёй.
Точность на данных, которые модель уже видела, — это не оценка модели, а оценка вашей памяти. Проверять надо на том, чего она не видела.
Шаг 3. Обучить модель
Возьмём метод k ближайших соседей — он интуитивно понятен: новый цветок относят к тому виду, к которому принадлежит большинство из k ближайших к нему по измерениям точек.
from sklearn.neighbors import KNeighborsClassifier
# n_neighbors=5 — смотрим на 5 ближайших примеров
model = KNeighborsClassifier(n_neighbors=5)
# обучение: fit принимает признаки и правильные ответы
model.fit(X_train, y_train)
Метод fit и есть "обучение". Ошибок в консоли быть не должно; в Jupyter выведется строка с параметрами модели вроде KNeighborsClassifier(). У всех моделей scikit-learn один и тот же интерфейс: fit для обучения, predict для предсказания. Захотите позже попробовать другой алгоритм — меняете только строку с классом модели.
Шаг 4. Проверить точность
Теперь спрашиваем модель про тестовую выборку — те самые 45 строк, которых она не видела.
from sklearn.metrics import accuracy_score, classification_report
y_pred = model.predict(X_test)
print("Точность:", accuracy_score(y_test, y_pred))
print(classification_report(y_test, y_pred, target_names=iris.target_names))
Точность окажется в районе 0.95 — модель верно определила примерно 43 из 45 цветков. classification_report покажет разбивку по классам: как правило, setosa угадывается идеально, а versicolor и virginica иногда путаются между собой, потому что их измерения пересекаются.
Как читать точность
Значение 0.95 значит "95% тестовых цветков распознаны верно". Для трёх классов случайное угадывание дало бы около 0.33, так что 0.95 — хороший результат. Но одна цифра точности не всё: если один класс встречается редко, модель может "выигрывать" на нём, игнорируя его. Поэтому и смотрят отчёт по классам, а не одно число.
Шаг 5. Предсказать для нового цветка
Модель готова принимать данные, которых нет в датасете вовсе.
import numpy as np
# длина/ширина чашелистика, длина/ширина лепестка в см
novyj_cvetok = np.array([[5.1, 3.5, 1.4, 0.2]])
prognoz = model.predict(novyj_cvetok)
print("Предсказанный вид:", iris.target_names[prognoz[0]])
Для этих чисел модель ответит setosa. Обратите внимание: признаки передаются в том же порядке, что и в обучении, и обёрнуты в двойные скобки — predict ждёт список строк, даже если строка одна.
Если не получилось
ModuleNotFoundError: No module named 'sklearn'— библиотека не установлена или установлена в другое окружение. Выполнитеpip install scikit-learnв том же окружении, где запускаете код. Имя пакета для установки —scikit-learn, а для импорта —sklearn, это нормально.ValueError: Expected 2D array, got 1D array insteadпри вызовеpredict— вы передали один список чисел вместо списка строк. Оберните данные в двойные скобки:[[5.1, 3.5, 1.4, 0.2]], а не[5.1, 3.5, 1.4, 0.2].- Точность заметно ниже 0.9 — скорее всего, при разбиении перепутаны местами признаки и метки в
train_test_splitили вfit. Порядок аргументов уfit: сначала признакиX_train, потом ответыy_train. - Результаты не совпадают с моими при каждом запуске — не указан
random_state. Разбиение случайно, поэтому цифры плавают. Зафиксируйте любое число. NotFittedErrorпри вызовеpredict— вы забылиmodel.fit(...)перед предсказанием. Модель нельзя спрашивать до обучения.
Что делать дальше
Вы прошли полный цикл: загрузка, разбиение, обучение, проверка, предсказание. Дальше стоит попробовать три вещи, не меняя структуру кода:
- Замените
KNeighborsClassifierнаDecisionTreeClassifierизsklearn.tree— интерфейс тот же, сравните точность. - Поменяйте
n_neighborsс 5 на 1 и на 15 — увидите, как параметр влияет на результат. - Возьмите свой датасет из CSV через
pandas.read_csvи подайте столбцы в тот жеfit. Здесь всплывёт то, чего нет в учебном наборе: пропущенные значения и нечисловые признаки — их придётся обрабатывать до обучения. Это отдельная большая тема, называется предобработкой данных.
Официальный туториал по scikit-learn разбирает те же шаги подробнее и показывает, как выбирать между алгоритмами.
Задачи: математика, физика, химия: Разбор задачи по шагам с проверкой и похожей задачей
Спросить за 10 ₽Источники: scikit-learn: An introduction to machine learning with scikit-learn, scikit-learn API Reference: KNeighborsClassifier
Частые вопросы
А если у меня scikit-learn другой версии?
Точность у меня 1.0 — это нормально или ошибка?
Нужно ли масштабировать данные перед обучением?
Можно ли этим методом решать не классификацию, а предсказание чисел?
Модель обучилась, но как её сохранить, чтобы не обучать каждый раз?
Почему модель путает versicolor и virginica?
Материал носит информационный характер и подготовлен редакцией «Агентуры». Он не является офертой, рекламой или индивидуальной консультацией. Упомянутые продукты, компании и торговые знаки принадлежат их правообладателям. Перед принятием решений, влекущих юридические или финансовые последствия, обратитесь к профильному специалисту.