Python для машинного обучения: почему именно он, какие библиотеки нужны и с чего начать

Python для машинного обучения: почему именно он, какие библиотеки нужны и с чего начать Полезное

Python для машинного обучения — это язык, на котором описывают весь путь модели: загрузку и очистку данных, обучение, проверку качества и запуск. При этом тяжелые вычисления делает не сам Python, а библиотеки, написанные на C, C++, Fortran и CUDA: Python управляет ими как удобный «пульт». Поэтому ML на Python — это всегда связка «язык + стек библиотек», а не один язык.

Ниже — почему в ML победил именно Python и где у него границы, какие библиотеки за что отвечают, минимальная рабочая модель с разбором и дорожная карта для старта. Примеры проверены 24.09.2026 на Python 3.14.7, NumPy 2.5.3, pandas 3.0.6 и scikit-learn 1.9.1.

Четыре термина, которые путают

  • Язык — Python сам по себе: синтаксис, типы, стандартная библиотека. Моделей в нем нет.
  • Библиотека — готовый код, который вы вызываете сами: numpy.mean(), pandas.read_csv().
  • Фреймворк — каркас, в который вы встраиваете свой код, а он управляет процессом: PyTorch сам считает градиенты и прогоняет обучение на GPU. Граница условная: scikit-learn называют и библиотекой, и фреймворком.
  • Модель — обученный объект с параметрами, который получает данные и выдает прогноз. Ее создает библиотека, но модель — это результат обучения, а не код библиотеки.

Почему в машинном обучении используют Python

Причина не в том, что Python «быстрый»: чистый Python как раз медленный. Решают три вещи.

Первое — экосистема. Для каждой задачи ML есть зрелая библиотека с документацией, и все они обмениваются одними и теми же массивами NumPy. Второе — Python работает как «клей»: цикл на миллион элементов уходит внутрь NumPy и выполняется скомпилированным кодом. Третье — интерактивная работа в Jupyter: загрузил данные, посмотрел график, поправил признак, не перезапуская программу.

Разницу между циклом Python и векторным вызовом NumPy видно на простой сумме квадратов:

import time
import numpy as np

values = list(range(1_000_000))
arr = np.arange(1_000_000)

start = time.perf_counter()
total_py = sum(v * v for v in values)
t_py = time.perf_counter() - start

start = time.perf_counter()
total_np = int((arr * arr).sum())
t_np = time.perf_counter() - start

print(total_py == total_np, total_np)
print(f"чистый Python: {t_py * 1000:.1f} мс")
print(f"NumPy:         {t_np * 1000:.1f} мс")

На моем прогоне (Docker, Python 3.14.7) результат совпал, а время отличалось примерно в 20 раз:

True 333332833333500000
чистый Python: 22.9 мс
NumPy:         1.2 мс

Миллисекунды зависят от процессора и нагрузки, сравнивать стоит только порядок. Но у скорости есть цена: целые числа NumPy имеют фиксированную ширину, и переполнение происходит молча. Если в том же примере взять 10 миллионов элементов, получится так:

import numpy as np
n = 10_000_000
arr = np.arange(n)
print(arr.dtype, int((arr * arr).sum()))
print(sum(v * v for v in range(n)))
print(int((arr.astype(np.float64) ** 2).sum()))
int64 1291890006563070912
333333283333335000000
333333283333335023616

Первая строка — мусор без единого предупреждения: сумма вышла за предел int64 (около 9,2 * 10^18). Вторая — точный ответ Python, у которого целые числа не ограничены. Третья — float64: порядок верный, но последние цифры потеряны, потому что точность float64 около 15-16 значащих цифр. Правило простое: если значения могут выйти за int64, считайте в float64 (понимая потерю точности) или уменьшайте масштаб данных.

Есть и другие честные минусы. Чистый Python медленный в циклах, поэтому код ML пишут векторно. Параллельность потоков в обычной сборке CPython ограничена GIL; начиная с Python 3.13 есть отдельная сборка без GIL, но библиотеки поддерживают ее не все. Для мобильных и встраиваемых устройств модель обычно обучают на Python, а запускают через экспорт в другой формат (например, ONNX) на C++, Java или Swift.

Стек библиотек: что за что отвечает

Старый список «десять библиотек подряд» не помогает выбрать. Удобнее идти от задачи.

Задача Что взять Когда нужно другое
Массивы и линейная алгебра NumPy Данные не помещаются в память — Dask, Polars, Spark
Таблицы: загрузка, очистка, группировка pandas Очень большие таблицы и скорость — Polars
Графики Matplotlib, Seaborn Интерактивные графики в браузере — Plotly, Bokeh
Классическое ML на таблицах scikit-learn Нужна максимальная точность на таблицах — градиентный бустинг: XGBoost, LightGBM, CatBoost
Нейросети, изображения, звук PyTorch Уже есть проект на TensorFlow/Keras или JAX
Готовые языковые и визуальные модели Hugging Face Transformers (поверх PyTorch) Нужен только вызов по API без своего обучения
Среда для экспериментов Jupyter (JupyterLab, VS Code) Код для продакшена — обычные модули .py и тесты

Несколько уточнений к таблице. SciPy — научные вычисления поверх NumPy (оптимизация, статистика, разреженные матрицы); scikit-learn использует его внутри, отдельно его ставят реже. Keras 3 умеет работать поверх TensorFlow, JAX и PyTorch. PyTorch создан в Facebook AI Research, с 2022 года развивается фондом PyTorch Foundation, и это не «новый инструмент без документации»: по нему больше всего учебных материалов в глубоком обучении.

Из старых подборок часто кочуют инструменты, которые брать не стоит: Pattern давно не развивается; Basemap хоть и выпускает обновления, но для новых карт в экосистеме Matplotlib рекомендуют Cartopy; а Scrapy и NLTK к ML относятся косвенно — это сбор веб-данных и классическая обработка текста.

Первая модель: минимальный полный пример

Задача — учебная копия антифрода: по 10 числовым признакам операции предсказать, мошенническая она или нет. Данные синтетические (их генерирует make_classification), зато в них есть главная трудность настоящего антифрода: мошеннических операций около 5%. На реальных данных на подготовку уходит больше времени, чем на модель.

import pandas as pd
from sklearn.datasets import make_classification
from sklearn.model_selection import train_test_split
from sklearn.pipeline import make_pipeline
from sklearn.preprocessing import StandardScaler
from sklearn.linear_model import LogisticRegression
from sklearn.dummy import DummyClassifier
from sklearn.metrics import accuracy_score, recall_score

# Учебные данные "как в антифроде": 2000 операций, из них около 5% мошеннических
X, y = make_classification(
    n_samples=2000, n_features=10, n_informative=6,
    weights=[0.95], random_state=42,
)
X = pd.DataFrame(X, columns=[f"f{i}" for i in range(10)])
y = pd.Series(y, name="fraud")
print(X.shape, y.value_counts().to_dict())

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

baseline = DummyClassifier(strategy="most_frequent").fit(X_train, y_train)
plain = make_pipeline(StandardScaler(), LogisticRegression()).fit(X_train, y_train)
balanced = make_pipeline(
    StandardScaler(), LogisticRegression(class_weight="balanced")
).fit(X_train, y_train)

for name, clf in [("baseline", baseline), ("plain", plain), ("balanced", balanced)]:
    pred = clf.predict(X_test)
    print(f"{name:8} accuracy={accuracy_score(y_test, pred):.3f} "
          f"recall(fraud)={recall_score(y_test, pred):.3f}")

В консоли появятся размер данных и три строки метрик:

(2000, 10) {0: 1892, 1: 108}
baseline accuracy=0.946 recall(fraud)=0.000
plain    accuracy=0.968 recall(fraud)=0.407
balanced accuracy=0.806 recall(fraud)=0.852

Что здесь происходит по шагам:

  1. make_classification создает признаки и метки, а pandas превращает их в таблицу DataFrame и столбец Series — в таком виде данные обычно и приходят из pd.read_csv().
  2. train_test_split откладывает 25% данных, которые модель не увидит при обучении. stratify=y сохраняет долю мошеннических операций в обеих частях, random_state=42 делает разбиение воспроизводимым.
  3. DummyClassifier — базовая линия: всегда отвечает самым частым классом. Без нее не понять, хорош ли результат.
  4. make_pipeline склеивает масштабирование и логистическую регрессию в один объект. Среднее и разброс признаков StandardScaler берет только из обучающей части.
  5. class_weight="balanced" заставляет модель штрафовать ошибку на редком классе сильнее, пропорционально его редкости.

Главный урок — в сравнении трех строк. Базовая линия дает 94,6% верных ответов, не найдя ни одной мошеннической операции: accuracy на несбалансированных данных почти ничего не говорит. Обычная логистическая регрессия выигрывает у нее всего 2 пункта accuracy и ловит лишь 41% мошенничества. Взвешенная версия ловит 85%, но accuracy падает до 0,806: платой стали ложные тревоги.

Какая модель лучше, решает цена ошибки, а не метрика «по привычке»: если пропущенная кража дороже звонка клиенту для проверки, выбирают recall и вторую модель. Цифры — результат одного разбиения синтетических данных, а не гарантия качества; для честной оценки используют кросс-валидацию и отдельную отложенную выборку.

Типичная ошибка: утечка данных

Самая частая ошибка новичка — подготовить данные с учетом всей выборки, а потом проверять модель на ее части. Тестовые данные уже «подсмотрены», и метрика завышена. Нагляднее всего это на случайных данных, где предсказывать нечего:

import numpy as np
from sklearn.feature_selection import SelectKBest, f_classif
from sklearn.linear_model import LogisticRegression
from sklearn.model_selection import cross_val_score
from sklearn.pipeline import make_pipeline

rng = np.random.default_rng(0)
X = rng.normal(size=(100, 5000))   # 5000 случайных признаков
y = rng.integers(0, 2, size=100)   # случайные метки: предсказывать нечего

# Неверно: отбор признаков по ВСЕМ данным, потом кросс-валидация
X_best = SelectKBest(f_classif, k=20).fit_transform(X, y)
wrong = cross_val_score(LogisticRegression(), X_best, y, cv=5).mean()

# Верно: отбор внутри пайплайна, заново на каждом обучающем фолде
pipe = make_pipeline(SelectKBest(f_classif, k=20), LogisticRegression())
right = cross_val_score(pipe, X, y, cv=5).mean()

print(f"с утечкой:  {wrong:.2f}")
print(f"без утечки: {right:.2f}")
с утечкой:  0.85
без утечки: 0.48

Неверный вариант показал 85% точности на шуме: отбор признаков выбрал те 20 столбцов, которые случайно совпали с метками во всей выборке, включая будущие тестовые фолды. Исправление — любой шаг, который учится на данных (масштабирование, отбор признаков, заполнение пропусков), класть внутрь Pipeline. Тогда он обучается только на обучающей части, и честные 0,48 соответствуют угадыванию.

С чего начать: дорожная карта до первого проекта

Цель — не «выучить библиотеки», а получить артефакт: ноутбук или репозиторий с моделью на своих данных, базовой линией и честной метрикой.

  1. Python на уровне уверенного скрипта: списки, словари, функции, классы, виртуальные окружения. Окружение и библиотеки ставятся так: python -m venv .venv, затем python -m pip install numpy pandas scikit-learn matplotlib jupyterlab.
  2. NumPy и pandas: индексация, векторные операции, группировка, пропуски, объединение таблиц.
  3. Минимум математики: средние и дисперсия, вероятность, производная как «скорость изменения», векторы и матрицы. Глубже — по мере надобности.
  4. scikit-learn: разбиение данных, пайплайн, кросс-валидация, метрики, 2-3 модели (линейная, дерево, градиентный бустинг).
  5. Свой проект: открытый датасет по интересной вам теме, базовая линия, модель, выбор метрики по цене ошибки, короткий вывод.
  6. PyTorch — когда классические модели освоены и нужны изображения, текст или звук.

Честного срока «за N недель» нет: он зависит от стартового уровня и часов в неделю. Ориентир — пункты 1-5 закрыты, когда вы сами, без подсказок, делаете пайплайн на новом датасете и объясняете, почему выбрали эту метрику.

Если не получилось

Симптом Причина Что делать
pip install sklearn падает с ошибкой «The ‘sklearn’ PyPI package is deprecated» Пакет называется иначе python -m pip install scikit-learn; в коде импорт остается import sklearn
ModuleNotFoundError, хотя библиотека установлена pip поставил пакет в другой интерпретатор Ставить через python -m pip тем же python, который запускает код; в Jupyter выбрать ядро из своего окружения
ConvergenceWarning: lbfgs failed to converge у LogisticRegression Признаки разного масштаба, мало итераций Добавить StandardScaler в пайплайн, увеличить max_iter
Метрика подозрительно высокая Утечка данных или дубликаты строк в train и test Все шаги подготовки — в Pipeline, проверить дубликаты и признаки «из будущего»
torch.cuda.is_available() возвращает False Установлена CPU-сборка PyTorch или нет драйвера Ставить сборку под свою версию CUDA по инструкции на сайте PyTorch; для учебы хватает CPU

Предупреждение о сходимости выглядит так (в конце вывода идут ссылки на документацию):

ConvergenceWarning: lbfgs failed to converge after 100 iteration(s) (status=1):
STOP: TOTAL NO. OF ITERATIONS REACHED LIMIT

Increase the number of iterations to improve the convergence (max_iter=100).
You might also want to scale the data as shown in:

Выводы

  • Python в машинном обучении — «клей» над быстрыми библиотеками на C/C++/CUDA: код пишется на Python, вычисления выполняет скомпилированный код.
  • Базовый стек: NumPy и pandas для данных, Matplotlib для графиков, scikit-learn для классического ML, PyTorch для нейросетей; выбирать по задаче, а не по списку.
  • Результат модели имеет смысл только рядом с базовой линией и метрикой, выбранной по цене ошибки: на редком классе accuracy обманывает.
  • Любая подготовка данных, которая учится на данных, должна жить внутри Pipeline, иначе метрика завышена утечкой.
  • Скорость NumPy имеет цену: фиксированные типы и молчаливое переполнение int64.

Где применяется / связь с практикой

Связка Python + scikit-learn + PyTorch используется в прогнозе спроса и оттока, скоринге, рекомендациях, поиске аномалий, компьютерном зрении и обработке текста. Разница между учебным примером и рабочей задачей — в данных: пропуски, дисбаланс классов, утечки, выбор метрики под бизнес-цель.

Освойте тему на практике

Эти навыки системно, с проектами на реальных данных, разбирают на курсе Machine Learning. Basic. Чтобы сначала посмотреть на формат и темы, можно прийти на бесплатные открытые уроки.

FAQ

Можно ли заниматься машинным обучением не на Python?
Да: есть R для статистики, Julia для научных расчетов, а модели запускают на C++, Java, Go и JavaScript. Но обучение и эксперименты в индустрии в основном идут на Python из-за экосистемы.

Нужна ли видеокарта, чтобы начать?
Нет. Классическое ML на scikit-learn работает на обычном процессоре, а для первых нейросетей хватает CPU или облачных ноутбуков с GPU.

Что учить первым: pandas или PyTorch?
pandas и scikit-learn. PyTorch решает задачи глубокого обучения, а подготовка данных, разбиение и выбор метрики нужны в любом проекте и переносятся в нейросети без изменений.

OTUS Журнал
Бесплатные открытые уроки (поп-ап)