Машинное обучение
Модели, извлекающие закономерности из данных: постановка задачи, классические алгоритмы, нейронные сети и конвейер scikit-learn
Вячеслав Федоров
Лекция 16
Разработка и применение ПО
в физических исследованиях
Изложение. Шестнадцатая лекция продолжает часть курса, посвящённую обработке данных: после NumPy, pandas, SciPy и визуализации следующим шагом становится автоматическое извлечение закономерностей из данных — модели, которые классифицируют события, предсказывают значения физических величин и находят структуру там, где визуальный анализ её уже не обнаруживает. Машинное обучение рассматривается как рабочий инструмент физика того же рода, что метод наименьших квадратов или преобразование Фурье: каждый метод опирается на математику, чаще всего сводящую обучение к задаче оптимизации, и рецепты без объяснения в лекции не приводятся. Надпись на титуле — fit: этим методом в scikit-learn обучается любая модель.
Демонстрации. Слайды с розовым выделением слова «Демонстрация» отмечают места, где изложение прерывается для работы в терминале виртуальной машины lab с Python 3.12, scikit-learn 1.9, NumPy 2.5, pandas 3.0 и Matplotlib 3.11, далее называемой стендом: на слайде проигрывается запись тех же команд. Используются датасеты из состава scikit-learn — Wine, Digits и Diabetes — и синтетические данные с известным законом природы, поэтому каждый результат можно сверить с ответом; все расчёты занимают секунды.
Содержание
От постановки задачи до конвейера, которому можно доверять
Изложение. Лекция состоит из семи частей. Первая вводит терминологию и типы задач машинного обучения. Вторая посвящена методу ближайших соседей и линейной регрессии вместе с регуляризацией. Третья рассматривает классификацию: логистическую регрессию, метрики качества и деревья решений. Четвёртая — ансамбли деревьев: разложение ошибки на смещение и разброс, случайный лес и градиентный бустинг. Пятая посвящена обучению без учителя, то есть понижению размерности и кластеризации. Шестая — нейронным сетям: нейрону, обратному распространению ошибки, оптимизаторам, инициализации и регуляризации. Седьмая собирает всё в конвейер scikit-learn с кросс-валидацией, подбором гиперпараметров и сохранением модели.
Цель лекции
Понимать, что делает модель, и измерять её качество так, чтобы измерению можно было доверять
Для физика обучение модели представляет собой минимизацию функционала, а регуляризация — способ сделать некорректную задачу корректной. Новое состоит в другом: модель оценивается не по невязке на подогнанных точках, а по качеству на данных, которых она не видела.
Изложение. Цель лекции состоит в том, чтобы понимать, что делает модель, и измерять её качество так, чтобы измерению можно было доверять. Терминология машинного обучения сложилась стихийно, и за привычными словами «модель» и «обучение» стоит не совсем то, что принято в физике; однако сам материал физику знаком под другими названиями. Обучение модели является задачей оптимизации, функция потерь представляет собой минимизируемый функционал, а регуляризация — способ сделать некорректную задачу корректной, известный по обратным задачам. Отличие от привычной подгонки состоит в том, что модель оценивается не по невязке на подогнанных точках, а по качеству предсказания на данных, которых она не видела: обучающая выборка позволяет найти параметры, но не позволяет судить о результате. Таким образом, приёмы лекции — разбиение выборки, кросс-валидация, конвейер предобработки — служат одной цели: оценке качества, которую можно повторить и проверить.
Постановка задачи
Термины, типы задач, признаки и модель как параметрическая функция
01
Постановка задачи
Соседи и регрессия
Классификация
Ансамбли
Без учителя
Нейронные сети
Конвейер sklearn
Изложение. Первая часть вводит терминологию машинного обучения, типы задач и устройство модели: что подаётся на вход, что требуется предсказать и чем параметры модели отличаются от гиперпараметров.
Термины
и данные
Искусственный интеллект
решения на основе восприятия мира
Машинное обучение
решения на основе накопленных данных
Глубокое обучение
глубокие нейронные сети
01
Датасет, выборка
набор объектов, поданный алгоритму
02
Признак X
измеряемый параметр объекта
03
Целевая переменная y
метка или значение, которое предсказывается
04
Закон природы
скрытое отображение X → y, которое восстанавливает модель
Для физика
Модель приближает неизвестную функцию, известную лишь в точках измерений.
Изложение. Искусственным интеллектом называют систему, способную принимать решения на основе восприятия окружающего мира. Машинное обучение составляет его подраздел: решения принимаются на основе накопленного опыта, то есть данных, и текущего состояния мира. Глубокое обучение, в свою очередь, составляет часть машинного обучения, основанную на глубоких нейронных сетях. Рядом употребляются термины Data Science — дисциплина, объединяющая сбор, обработку, анализ и извлечение знаний из данных, — и Big Data, обработка данных такого объёма, что стандартные инструменты с ними уже не справляются. Для работы необходимы четыре понятия, связанные с данными. Датасет, или выборка, представляет собой набор объектов, поданный алгоритму. Признак — измеряемый параметр объекта, он обозначается X. Целевая переменная, она же метка, задаёт значение, которое требуется предсказать, и обозначается y. Наконец, законом природы в машинном обучении называют скрытое отображение из пространства признаков в пространство меток, которое модель восстанавливает по примерам. Для физика это понятие привычно: модель является приближением неизвестной функциональной зависимости, известной лишь в точках измерений.
Типы
задач
Задача Метка y Пример
Классификация конечное множество отбор событий «сигнал / фон»
Регрессия вещественное число энергия по отклику калориметра
Ранжирование порядок объектов выдача поиска
Кластеризация нет группы спектров по форме линий
Снижение размерности нет многомерная выборка на плоскости
Генерация образцы выборки новые объекты, похожие на обучающие
Пояснение
С учителем: разметка у каждого объекта, цель — закон X → y.
Пояснение
Без учителя: разметки нет, ищется структура самих данных.
Изложение. Задачи машинного обучения делятся по тому, есть ли у объектов разметка. В обучении с учителем каждому объекту обучающей выборки сопоставлена правильная метка, и целью является восстановление закона природы X → y. Пример — отбор событий на детекторе: модель обучают на событиях, смоделированных методом Монте-Карло, для каждого из которых известно, сигнал это или фон, и затем применяют к зарегистрированным событиям, разметить которые вручную невозможно. В обучении без учителя разметки нет, и алгоритм ищет структуру в самих данных, например разбивает события на группы по форме сигнала, когда заранее неизвестно, сколько процессов в них присутствует. Внутри двух парадигм выделяют типовые постановки. Классификация относит объект к одному из конечного множества классов, бинарная — к одному из двух. Регрессия предсказывает вещественную величину, например энергию частицы по отклику калориметра. Ранжирование упорядочивает объекты по релевантности. Кластеризация разбивает данные на группы похожих объектов, а снижение размерности уменьшает число признаков с сохранением структуры, что позволяет увидеть многомерную выборку на плоскости и ослабить проклятие размерности. Генерация создаёт новые объекты, похожие на обучающие, но не совпадающие ни с одним из них. Таким образом, тип задачи определяется наличием и видом метки, а от него зависят и модель, и метрика качества.
Модель
и обучение
01
Параметры
веса w, подобранные по данным
02
Гиперпараметры
заданы до обучения: K, λ, глубина, шаг
03
Обучение
минимизация функции потерь на выборке
04
Проверка
качество — только на отложенных данных
02
Номинальные
тип детектора, режим
03
Порядковые
плохо, хорошо, отлично
04
Числовые
ток, энергия, расстояние
Для физика
Числовой признак, разбитый на интервалы, становится порядковым.
Изложение. Моделью машинного обучения называют параметрическую функцию, отображающую пространство признаков в пространство ответов. Внутренние настройки модели называют параметрами, а их подбор по данным — обучением: параметры изменяются так, чтобы предсказания на обучающей выборке как можно ближе сходились с метками или, если меток нет, чтобы модель выявила скрытую структуру. Величины, которые задаются до обучения и самим обучением не подбираются, — число соседей, коэффициент регуляризации, глубина дерева, скорость обучения — называют гиперпараметрами; их выбирают отдельной процедурой, которой посвящена последняя часть лекции. От типа признака зависят и выбор модели, и предобработка. Бинарный признак принимает два значения, номинальный — значение из конечного множества без порядка, например тип детектора, порядковый — из упорядоченного множества, числовой — вещественная величина. Типы допускают преобразование: числовой признак, разбитый на интервалы с заранее выбранными границами, становится порядковым. На качество обученной модели влияют качество данных, выбор алгоритма, его гиперпараметры и аккуратность процедуры обучения.
Соседи и регрессия
Метод ближайших соседей, метод наименьших квадратов, градиентный спуск и регуляризация
02
Постановка задачи
Соседи и регрессия
Классификация
Ансамбли
Без учителя
Нейронные сети
Конвейер sklearn
Изложение. Вторая часть рассматривает два простейших метода: классификацию по ближайшим соседям, которая не обучается вовсе, и линейную регрессию, которая обучается аналитически или градиентным спуском, а также регуляризацию, защищающую линейную модель от неустойчивости.
Метод
ближайших соседей
Пояснение
Гипотеза компактности: объекты одного класса лежат близко в пространстве признаков, разных классов — далеко.
01
Расстояния
от нового объекта до всех объектов выборки
02
K ближайших
K является гиперпараметром
03
Голосование
класс большинства, вес соседа ~ 1/d
Свойство kNN
Обучение запоминание выборки
Предсказание O(N) расстояний на объект
Параметры нет
Гиперпараметры K, метрика, веса
Объяснение по конкретным соседям
Важно
Малое K — шум и выбросы, большое K — сглаженная граница.
Изложение. Метод K ближайших соседей является одним из простейших алгоритмов классификации. В его основе лежит гипотеза компактности: объекты одного класса расположены близко друг к другу в пространстве признаков, а объекты разных классов — далеко. Гипотеза сводит классификацию к поиску близких объектов, уже размеченных в обучающей выборке. Предсказание выполняется в три шага: для нового объекта вычисляются расстояния до всех объектов выборки, выбираются K объектов с наименьшим расстоянием, и объекту присваивается класс, чаще всего встречающийся среди них. Голосование можно взвесить, приписав соседу вес, обратно пропорциональный расстоянию до него или экспоненциально убывающий с расстоянием. Число соседей K — гиперпараметр: при малом K модель чувствительна к шуму и выбросам, при большом граница решений сглаживается, но теряет локальные особенности. Свойства метода необычны. Обучения в классическом смысле нет — модель запоминает всю выборку, и параметров, подобранных по данным, у неё нет вовсе. Вместе с тем предсказание дорого: на каждый объект необходимо вычислить расстояния до всех запомненных. Решение интерпретируемо: соседи, по которым оно принято, позволяют его объяснить.
Расстояние
и масштаб
манхэттенское: d = Σ |x − x'| евклидово: d = √Σ (x − x')² косинусное: d = 1 − x·x' / (|x|·|x'|)
Для физика
Косинусное расстояние сравнивает направления векторов признаков, а не их длины.
01
Масштаб
признак в тысячах подавляет признаки в долях единицы
02
Нормировка
стандартизация μ = 0, σ = 1 или приведение к [0, 1]
03
Скорость
kD-дерево, Ball tree, HNSW, эталоны FRiS-Stolp
Изложение. Понятие близости задаётся метрикой. Манхэттенское расстояние суммирует модули разностей признаков, евклидово равно корню из суммы квадратов, косинусное измеряет угол между векторами и потому применимо там, где важна ориентация вектора признаков, а его длина значения не имеет. У метрик общая проблема — зависимость от масштаба признаков. Если один признак измеряется тысячами, а остальные — долями единицы, в расстоянии доминирует первый, и метод фактически работает с одним признаком. Решение даёт нормировка, которая позволяет уравнять вклады признаков: минимакс-нормализация приводит значения к отрезку от нуля до единицы, стандартизация — к нулевому среднему и единичной дисперсии. Вторая проблема — вычислительная сложность: на большой выборке поиск соседей требует O(N) сравнений на объект. Её решают структуры данных: kD-дерево делит пространство по одному признаку на каждом уровне, Ball tree строит иерархию гиперсфер, HNSW — граф для приближённого поиска, а метод FRiS-Stolp отбирает эталоны, заменяющие собой группы объектов. Эталон считается хорошим, если объекты его класса лежат к нему близко, а чужих — далеко; это выражает функция FRiS = (r₂ − r₁)/(r₂ + r₁), где r₁ — расстояние до ближайшего объекта своего класса, r₂ — чужого.
Демонстрация:
kNN и масштаб
01
Wine: 178 образцов, 13 признаков
02
Масштабы признаков: СКО от 0,12 до 315
03
kNN без масштабирования и со StandardScaler
04
Вклад proline в квадрат расстояния
Что наблюдается
Без масштабирования 0,78–0,81, после StandardScaler 0,97–1,00: proline даёт 99,97 % квадрата расстояния.
root@lab — запись со стенда
Демонстрация. Датасет Wine входит в состав scikit-learn: 178 образцов вина трёх сортов, по 59, 71 и 48 образцов, описанных 13 признаками химического анализа. Сценарий data.py показывает масштабы признаков: содержание пролина меняется от 278 до 1680 при СКО 315, а содержание нефлаваноидных фенолов — от 0,13 до 0,66 при СКО 0,124, то есть разброс различается в 2530 раз. Сценарий knn.py откладывает пятую часть выборки для проверки с сохранением долей классов и обучает kNN при K = 1, 5 и 15 дважды: на исходных признаках и после StandardScaler, статистики которого вычислены только по обучающей части. Без масштабирования доля верных ответов составляет 0,778–0,806, после стандартизации — 0,972–1,000. Последняя строка объясняет разницу: для первого образца теста медианный вклад пролина в квадрат расстояния до образцов обучающей выборки составляет 99,97 %, и для остальных образцов картина та же, то есть без масштабирования метод сравнивает образцы по одному признаку из тринадцати. Таким образом, для методов, опирающихся на расстояние, стандартизация является не формальностью, а условием работы метода.
Линейная регрессия
и МНК
ŷ = Xw (в X добавлен столбец единиц) Q(w) = ‖Xw − y‖² → min ∇Q = 2X⊤(Xw − y) = 0 X⊤X·w = X⊤y (нормальное уравнение) w = np.linalg.solve(X.T @ X, X.T @ y) w = np.linalg.lstsq(X, y)[0] # SVD
01
Необратимость
коллинеарные признаки или признаков больше, чем объектов
02
Сложность
обращение матрицы — O(k³)
03
Практика
QR или SVD вместо явного обращения
Для физика
Подгонка прямой из лабораторного практикума, записанная для k признаков.
Изложение. Линейная регрессия предсказывает непрерывную величину по линейной комбинации признаков: ŷ = w₁x₁ + … + w_k x_k + w₀. Смещение w₀ включается в вектор весов добавлением к каждому объекту фиктивного признака, равного единице, после чего модель записывается в матричной форме ŷ = Xw. Будем минимизировать квадрат нормы невязки ‖Xw − y‖², то есть среднеквадратичную ошибку с точностью до множителя. Приравняв градиент к нулю, получим нормальное уравнение X⊤Xw = X⊤y и аналитическое решение с обратной матрицей (X⊤X)⁻¹. На практике этой формулой почти не пользуются по двум причинам. Матрица X⊤X может быть необратимой: при линейной зависимости признаков и когда признаков больше, чем объектов, решений бесконечно много. Кроме того, обращение матрицы требует O(k³) операций. Библиотеки решают задачу через QR- или SVD-разложение — так устроены numpy.linalg.lstsq и LinearRegression, — что устойчивее явного обращения: число обусловленности X⊤X равно квадрату числа обусловленности X. Для физика метод знаком по подгонке прямой в лабораторном практикуме; линейная регрессия позволяет решать ту же задачу для произвольного числа признаков.
Градиентный
спуск
w ← w − α·∇Q(w) ∇Q = (2/N)·X⊤(Xw − y) H = (2/N)·X⊤X: α < 2/λmax(H)
01
Полный
градиент по всей выборке
02
Стохастический
по одному случайному объекту
03
Мини-батч
по небольшой случайной подвыборке
01
Скорость α
велика — расходится, мала — медленно
02
Обусловленность
отношение λmax/λmin задаёт число шагов
03
Momentum
v ← ρv + α∇Q, w ← w − v
Пояснение
MSE выпукла: локальный минимум совпадает с глобальным.
Изложение. Когда аналитическое решение неприменимо или неэффективно, используют итеративный метод — градиентный спуск. Веса инициализируются произвольно и многократно сдвигаются против градиента функции потерь: w ← w − α∇Q(w), где α — скорость обучения. Для среднеквадратичной ошибки градиент равен (2/N)·X⊤(Xw − y). Варианты метода различаются числом объектов, по которым вычисляется градиент на шаге: полный спуск использует всю выборку, стохастический — один случайный объект, мини-батч — небольшую случайную подвыборку, что позволяет обрабатывать выборки, не помещающиеся в память. Функция MSE выпукла, поэтому локальных минимумов, отличных от глобального, у неё нет, и основная трудность состоит в выборе скорости обучения. Оценим её границу. Функция потерь квадратична, её матрица вторых производных равна H = (2/N)·X⊤X, и вдоль собственного вектора с собственным значением λ отклонение от минимума на каждом шаге умножается на 1 − αλ. Следовательно, спуск сходится, только если α < 2/λmax, а число шагов определяется отношением наибольшего и наименьшего собственных значений, то есть обусловленностью задачи; стандартизация признаков улучшает обусловленность и ускоряет спуск. Инерция (momentum) накапливает скорость предыдущих шагов и позволяет проходить пологие участки быстрее.
Коллинеарность
и регуляризация
x2 = 2·x1: y = 6·x1 + 8·x2 + 5 = 0·x1 + 11·x2 + 5 = 22·x1 + 0·x2 + 5
Важно
Веса линейно зависимых признаков неустойчивы и не интерпретируются.
Метод Штраф Действие
Ridge, L2 λ·‖w‖² уменьшает и выравнивает веса
Lasso, L1 λ·Σ|w| обнуляет лишние веса
λ = 0 — обычная регрессия
λ → ∞ — все веса стремятся к нулю
Пояснение
λ является гиперпараметром и подбирается на отложенной выборке.
Изложение. Рассмотрим, что происходит при линейной зависимости признаков. Пусть x₂ = 2x₁; тогда закон y = 6x₁ + 8x₂ + 5 записывается и как 0·x₁ + 11x₂ + 5, и как 22x₁ + 5, и бесконечным числом других способов. Задача поиска весов становится некорректной: решение не единственно, а при почти точной зависимости неустойчиво к шуму, и веса теряют смысл. Качество линейной модели снижают и другие обстоятельства: нелинейная зависимость, которую прямая не описывает, — тогда необходим новый признак, например площадь как произведение длины на ширину; выбросы, к которым MSE чувствительна из-за квадратичного штрафа, — против них помогают MAE и функция Хьюбера; шумные нерелевантные признаки, для которых модель выучивает большие веса. Регуляризация добавляет к функции потерь штраф, растущий с весами. L2-регуляризация, или Ridge, штрафует сумму квадратов весов, уменьшает их по модулю и даёт устойчивое решение: в нормальном уравнении к X⊤X прибавляется NλI. L1-регуляризация, или Lasso, штрафует сумму модулей и обнуляет веса нерелевантных признаков, выполняя их отбор. При λ = 0 получается обычная регрессия, при λ → ∞ все веса стремятся к нулю; оптимальное λ подбирается на отложенной выборке как гиперпараметр. Таким образом, Ridge представляет собой регуляризацию Тихонова, знакомую по обратным задачам физики.
Демонстрация:
МНК и регуляризация
01
Калибровка: энергия по амплитуде
02
Нормальное уравнение, lstsq и LinearRegression
03
Градиентный спуск при α от 0,1 до 1,1
04
Почти копия признака: Ridge и Lasso
Что наблюдается
Три решения совпадают. Спуск сходится при α < 1 и расходится при 1,1. При x2 ≈ 2·x1 веса 458 и −218 у Ridge становятся 4,41 и 8,79, у Lasso — 0 и 10,97.
root@lab — запись со стенда
Демонстрация. Сценарий lsq.py моделирует калибровку: энергия частицы линейно зависит от амплитуды сигнала калориметра, E = 0,05·A + 0,3 ГэВ, с шумом 0,1 ГэВ на 500 событиях. Нормальное уравнение, numpy.linalg.lstsq и LinearRegression дают одни и те же веса, 0,05034 и 0,2765, однако число обусловленности X⊤X без масштабирования составляет 12 780. Затем амплитуда стандартизуется, и запускается градиентный спуск с разной скоростью. Для стандартизованного признака матрица вторых производных равна удвоенной единичной, λ = 2, поэтому, согласно оценке предыдущего слайда, спуск сходится при α < 1: при α = 0,5 отклонение обнуляется за один шаг, при 0,1 и 0,9 — за 67 шагов, поскольку множители 0,8 и −0,8 равны по модулю, при α = 1 колебания не затухают, а при 1,1 спуск расходится. Второй запуск строит почти точную копию признака, x₂ = 2x₁ с шумом 0,0001. LinearRegression находит веса 458,32 и −218,16: их комбинация w₁ + 2w₂ = 22 верна, но сами числа случайны. Ridge с alpha = 0,01 даёт 4,41 и 8,79 — решение с наименьшей нормой, а Lasso с тем же alpha — 0 и 10,97, то есть оставляет один признак, как в записи 0·x₁ + 11x₂ + 5 из главы. Параметр alpha библиотеки не совпадает с λ предыдущего слайда: Ridge прибавляет αI к X⊤X без деления потерь на N, а Lasso делит сумму квадратов на 2N.
Классификация
Логистическая регрессия, метрики качества, порог и деревья решений
03
Постановка задачи
Соседи и регрессия
Классификация
Ансамбли
Без учителя
Нейронные сети
Конвейер sklearn
Изложение. Третья часть посвящена классификации: переходу от линейного отклика к вероятности, метрикам качества классификатора, выбору порога и деревьям решений, а также тому, почему доля правильных ответов не позволяет судить о модели.
Логистическая
регрессия
f(x) = w⊤x log(p / (1 − p)) = f(x) p = σ(f) = 1 / (1 + e^(−f)) M = y·f(x), y ∈ {−1, +1} L(w) = Σ log(1 + e^(−M)) → min
01
Шанс
логарифм шанса равен линейной функции
02
Отступ M
M > 0 — верно; чем больше, тем увереннее
03
Log loss
максимум правдоподобия независимых объектов
04
Обучение
градиентный спуск, L1 или L2
Изложение. Линейный классификатор строит решающую границу в виде гиперплоскости: вычисляется линейная функция f(x) = w⊤x, и класс определяется её знаком. Для многих задач требуется не только класс, но и вероятность принадлежности к нему, а значения f лежат на всей числовой оси. Переход выполняется через шанс: отношение p/(1 − p) лежит в интервале от нуля до бесконечности, его логарифм — на всей оси, и логистическая регрессия приравнивает логарифм шанса линейной функции. Выразив p, получим сигмоиду p = 1/(1 + e^(−f)). Качество классификации объекта удобно описывать отступом M = y·f(x) при метках ±1: положительный отступ означает верный ответ, и чем он больше, тем увереннее модель. Веса подбираются по максимуму правдоподобия выборки в предположении независимых и одинаково распределённых объектов: вероятность верного ответа на объекте равна σ(M), логарифм правдоподобия — сумме log σ(M), и его максимизация равносильна минимизации функции потерь log loss, равной сумме log(1 + e^(−M)). Эта функция штрафует малые и отрицательные отступы: при M → +∞ потери стремятся к нулю, при M → −∞ растут линейно. Минимизируется она тем же градиентным спуском, что и MSE, а от переобучения защищает та же регуляризация L1 или L2.
Метрики
классификации
предсказан 1 предсказан 0
реально 1 TP FN
реально 0 FP TN
precision = TP / (TP + FP) recall = TP / (TP + FN) F1 = 2·P·R / (P + R)
Важно
100 000 здоровых и 10 больных: ответ «здоров» даёт accuracy 99,99 % и не находит ни одного больного.
Для физика
При отборе событий recall называют эффективностью отбора, precision — чистотой выборки.
Пояснение
Положительный класс указывается всегда: его смена меняет смысл чисел.
Изложение. Выбор метрики важен, особенно при сильном дисбалансе классов. Доля правильных ответов, accuracy, вводит в заблуждение: при 100 000 здоровых и 10 больных классификатор, всегда отвечающий «здоров», имеет accuracy 99,99 % и бесполезен, поскольку не находит ни одного больного. Подробнее результат описывает матрица ошибок, сводящая предсказания и истину в четыре числа: TP — положительные объекты, отнесённые к положительным, TN — отрицательные, отнесённые к отрицательным, FP — ошибки первого рода, FN — ошибки второго рода. По ним вычисляются precision, то есть доля действительно положительных среди отнесённых к положительному классу, и recall — доля найденных среди всех положительных. Если модель нашла одного больного из десяти и не ошиблась на здоровых, её precision равна единице, а recall — 0,1. Баланс между ними выражает F-мера — гармоническое среднее, чаще всего F1. Обе метрики вычисляются по положительному классу, и его необходимо указывать всегда: если в том же примере искать здоровых, precision составит 0,99991, а recall — единицу, хотя предсказания не изменились. Для физика эти величины знакомы под другими названиями: при отборе событий recall называют эффективностью отбора, а precision — чистотой выборки.
Порог
и ROC-кривая
01
Вероятность p
класс задаёт сравнение p с порогом
02
TPR = recall
доля найденных положительных
03
FPR = FP / (FP + TN)
доля ложных срабатываний
04
ROC-кривая
TPR от FPR при всех порогах
AUC Смысл
1 идеальное ранжирование
0,5 случайное угадывание
любое вероятность, что положительный объект оценён выше отрицательного
Для физика
Порог выбирает задача: при поиске сигнала — максимум значимости S/√B, при измерении сечения — минимум погрешности √(S + B)/S.
Изложение. Многие классификаторы, включая логистическую регрессию, выдают вероятность положительного класса, а метку получают сравнением с порогом. Порог можно варьировать: при понижении растёт доля найденных положительных объектов TPR, совпадающая с recall, но растёт и доля ложных срабатываний FPR, то есть отрицательных объектов, ошибочно отнесённых к положительным. ROC-кривая показывает зависимость TPR от FPR при всех порогах сразу, а площадь под ней, AUC, характеризует качество ранжирования независимо от порога: AUC = 1 соответствует идеальному классификатору, 0,5 — случайному угадыванию. Отметим полезную интерпретацию: AUC равна вероятности того, что случайно выбранный положительный объект получит от модели большую оценку, чем случайно выбранный отрицательный. Выбор порога является не технической деталью, а решением, которое принимает физик, причём критерий задаёт цель измерения. При поиске сигнала порог выбирают по наибольшей ожидаемой значимости, в простейшем случае S/√B, где S и B — числа отобранных сигнальных и фоновых событий; при малой доле сигнала такой критерий требует прежде всего подавления фона, то есть чистоты, а не эффективности. При измерении сечения минимизируют погрешность: статистическую, √(S + B)/S, вместе с систематическими погрешностями эффективности и доли фона.
Демонстрация:
метрики при дисбалансе
01
Сигнал — 1 % событий, два признака
02
Классификатор «всегда фон»
03
Логистическая регрессия: пороги 0,5; 0,2; 0,05
04
ROC-AUC и положительный класс «фон»
Что наблюдается
«Всегда фон»: accuracy 0,990, recall 0. Порог 0,5 → 0,05: recall 0,21 → 0,71, precision 0,77 → 0,19; AUC 0,960.
root@lab — запись со стенда
Демонстрация. Сценарий metrics.py моделирует отбор событий: фон и сигнал описываются двумя признаками с нормальными распределениями, центры которых разнесены, а сигнал составляет 1 % из 100 000 событий; 30 % событий отложены для проверки с сохранением доли сигнала, и в тесте 300 сигнальных событий. Классификатор, всегда отвечающий «фон», получает accuracy 0,990 при нулевом recall. Логистическая регрессия при пороге 0,5 повышает accuracy лишь до 0,9914: она находит 62 сигнальных события из 300, ошибаясь на 19 фоновых, то есть precision составляет 0,765, а recall — 0,207. Понижение порога до 0,2 и 0,05 увеличивает recall до 0,440 и 0,713, но уменьшает precision до 0,455 и 0,194; accuracy при этом падает ниже уровня тривиального ответа, до 0,9891 и 0,9675, хотя найденного сигнала становится в 3,5 раза больше. Фона же при пороге 0,05 отбирается около 890 событий вместо 19, и значимость S/√B уменьшается примерно с 14 до 7: для поиска сигнала выгоднее высокий порог. ROC-AUC составляет 0,960: модель ранжирует события хорошо, а точку на ROC-кривой выбирает задача. Последняя строка повторяет пример главы: если положительным классом объявить фон, precision 0,9920 и recall 0,9994 выглядят превосходно при тех же предсказаниях. Таким образом, при дисбалансе классов accuracy не позволяет сравнивать модели, а метрики необходимо указывать вместе с положительным классом и порогом.
Дерево
решений
Q → L (x < t), R (x ≥ t) G = |L|/|Q|·H(L) + |R|/|Q|·H(R) → min доля ошибок: H = 1 − max p энтропия: H = −Σ p·log2 p Джини: H = 1 − Σ p²
01
Жадное построение
лучшее разбиение в каждом узле
02
Регрессия
мера неоднородности — дисперсия
03
Глубина
без ограничений дерево запоминает выборку
04
Остановка
глубина, объекты в узле и листе, обрезка
Изложение. Дерево решений является непараметрическим методом, строящим цепочку правил вида «признак меньше порога», которые применяются к объекту последовательно. Рассмотрим построение. Для каждого признака объекты сортируются и перебираются пороги, делящие выборку узла Q на левую и правую части; качество разбиения оценивается взвешенной неопределённостью дочерних узлов G = |L|/|Q|·H(L) + |R|/|Q|·H(R), и выбирается разбиение с наименьшим G. Неопределённость узла задаётся одной из трёх функций долей классов: долей ошибок 1 − max p, энтропией −Σ p log₂ p или индексом Джини 1 − Σ p². Для регрессии мерой неоднородности служит дисперсия значений в узле, то есть MSE относительно среднего, или MAE относительно медианы. Дерево строится жадно, узел за узлом, и если не ограничивать его рост, оно запомнит каждый объект обучающей выборки. Поэтому необходимы критерии остановки: ограничение глубины, минимального числа объектов в узле для деления и в листе, либо обрезка — построение большого дерева с последующим удалением ветвей, не дающих прироста качества на валидации.
Дерево:
сильные и слабые стороны
01
Объяснимость
решение читается как схема правил
02
Масштаб
нормировать признаки не требуется
03
Пропуски
часть реализаций их обрабатывает
04
Настройка
гиперпараметров немного
01
Ступенчатая граница
разбиения перпендикулярны осям
02
Подстройка под шум
глубокое дерево запоминает выборку
03
Нестабильность
сдвиг нескольких точек меняет дерево
04
Экстраполяция
за пределами данных — константа
Важно
Модель, обученная на токах до 2 кА, на 3 кА предскажет то же, что на 2, и не предупредит об этом.
Изложение. Основным достоинством дерева является интерпретируемость: обученная модель изображается схемой, и специалист, не знакомый с машинным обучением, может понять, почему предсказание получилось именно таким. Для физического эксперимента это существенно: решение модели необходимо проверить и обосновать, и прозрачная схема правил такую проверку упрощает. Непрозрачные ансамбли и сети в опубликованных анализах также применяются, но их эффективность и доля фона проверяются на контрольных выборках. Дерево нечувствительно к масштабу признаков, некоторые реализации обрабатывают пропущенные значения, а гиперпараметров немного. Недостатки вытекают из того же устройства. Разбиения перпендикулярны осям, поэтому наклонную границу между классами дерево приближает ступенчатой линией. Оно подстраивается под шум: достаточно увеличить глубину, и обучающая выборка будет запомнена целиком. Оно нестабильно: сдвиг нескольких точек перестраивает структуру. Для физика наиболее важно то, что дерево не экстраполирует: за пределами обучающих данных оно возвращает значение крайнего листа, поскольку дальше крайнего разбиения информации у него нет.
Демонстрация:
экстраполяция
01
Закон k = 0,8·I², токи от 0 до 2 кА
02
Дерево, лес, бустинг, kNN, линейная по I и I²
03
Предсказания на 2,5 и 3 кА
Что наблюдается
При 3 кА закон даёт 7,20; дерево, лес, бустинг и kNN — 3,11–3,21, как при 2 кА; линейная модель по I и I² — 7,16.
root@lab — запись со стенда
Демонстрация. Сценарий extrapolate.py рассматривает фокусирующую силу соленоида, пропорциональную квадрату поля и, следовательно, квадрату тока: k = 0,8·I² в условных единицах. Обучающие измерения с шумом 0,05 взяты при токах от 0,01 до 1,99 кА. Пять моделей — дерево глубины 5, лес из 200 деревьев, градиентный бустинг, kNN и линейная регрессия по признакам I и I² — внутри диапазона воспроизводят закон с точностью до шума: при 1,5 кА предсказания лежат между 1,78 и 1,82 при истинных 1,80. За пределами диапазона картина иная. При 2,5 и 3 кА закон даёт 5,00 и 7,20, а дерево, лес, бустинг и kNN возвращают 3,16, 3,18, 3,21 и 3,11 — те же числа, что при 2 кА, без какого-либо предупреждения. Линейная модель по I и I² даёт 4,97 и 7,16, поскольку её вид совпадает с видом закона. Вывод не в пользу какого-либо метода: экстраполяция возможна лишь тогда, когда форма зависимости заложена в модель, а модель, обученная на данных, отвечает только в их пределах.
Результат:
экстраполяция
Что наблюдается
Внутри данных все модели совпадают с законом; за 2 кА дерево и лес дают горизонтальную линию, линейная модель по I и I² продолжает параболу.
Демонстрация. На рисунке серые точки — обучающие измерения до 2 кА, пунктир — закон k = 0,8·I², закрашенная область — токи, которых в обучающих данных нет. Синяя линия леса и оранжевая штриховая линия дерева внутри данных повторяют закон вместе с шумом: дерево ступенчато, лес сглаживает ступени усреднением. За границей обе линии горизонтальны: последний лист дерева и крайние листья деревьев леса не меняются. Зелёная линия линейной модели по I и I² продолжает параболу. Отметим, что по качеству на обучающем диапазоне модели неразличимы, и никакая метрика, вычисленная на данных до 2 кА, не позволяет обнаружить различие в экстраполяции.
Ансамбли
Смещение и разброс, бэггинг, случайный лес и градиентный бустинг
04
Постановка задачи
Соседи и регрессия
Классификация
Ансамбли
Без учителя
Нейронные сети
Конвейер sklearn
Изложение. Четвёртая часть объясняет, почему ансамбли деревьев на протяжении многих лет остаются наиболее точными моделями для табличных данных: разлагает ошибку модели на смещение и разброс и рассматривает два противоположных способа объединения моделей — бэггинг со случайным лесом и бустинг.
Смещение
и разброс
y = f(x) + ε, Mε = 0, Dε = σ² MSE = M(y − b)² = (f − Mb)² + Db + σ² = bias² + variance + σ²
Для физика
Смещение играет роль систематической погрешности, разброс — случайной.
01
Bias
простая модель не достигает закона
02
Variance
сложная подстраивается под выборку
03
σ²
шум измерения — неустранимая часть
Изложение. Чтобы понять, чем полезны ансамбли, разложим ошибку модели. Пусть измерения подчиняются закону y = f(x) + ε, где шум ε имеет нулевое среднее и дисперсию σ², а b(x) — модель, обученная на случайной выборке; её предсказание в точке x — случайная величина с математическим ожиданием Mb и дисперсией Db. Подставим y в среднеквадратичную ошибку и воспользуемся независимостью шума и модели: M(by) = f·Mb. Получим MSE = (f − Mb)² + Db + σ². Первое слагаемое называют квадратом смещения (bias), второе — разбросом (variance), третье — неустранимая ошибка: это шум измерения в самих данных, и его не компенсирует ни одна модель. Два первых слагаемых действуют в противоположных направлениях: простая модель не достигает закона природы и накапливает смещение, сложная подстраивается под конкретную выборку и накапливает разброс, и между этими крайностями приходится выбирать. Для физика разложение знакомо: смещение играет роль систематической погрешности, разброс — случайной.
Демонстрация:
смещение и разброс
01
Закон sin 2πx, шум σ = 0,3
02
Сто выборок по 50 точек
03
Линейная регрессия, два дерева и лес
04
Разложение и прямая проверка
Что наблюдается
Линейная: bias² 0,156. Дерево без ограничений: variance 0,093, лес — 0,046, вдвое меньше, а не в сто раз. Сумма совпадает с проверкой до 0,003.
root@lab — запись со стенда
Демонстрация. Сценарий bv.py проверяет разложение численно. Закон природы — синус sin 2πx на отрезке от 0 до 1, шум измерения σ = 0,3, то есть σ² = 0,09. Сто раз разыгрывается обучающая выборка из 50 точек, каждая модель обучается на ней и предсказывает значения в 50 точках отрезка; по ста предсказаниям в каждой точке вычисляются смещение и разброс. Для независимой проверки после каждого обучения разыгрываются новые зашумлённые измерения в тех же точках, и ошибка на них усредняется. Линейная регрессия не достигает синуса: квадрат смещения 0,156 при разбросе 0,013. Дерево без ограничений, наоборот, почти не смещено, 0,001, но его разброс составляет 0,093. Дерево глубины 3 и случайный лес из 100 деревьев находятся между крайностями, суммарная ошибка 0,139 и 0,137. Во всех строках сумма bias² + variance + σ² совпадает с прямой проверкой с точностью до 0,003. Отметим отношение разбросов дерева и леса: лес уменьшил разброс вдвое, хотя деревьев в нём сто. Оценка, согласно которой усреднение n моделей уменьшает разброс в n раз, справедлива для некоррелированных ошибок, а деревья, обученные на подвыборках одной выборки, ошибаются похоже.
Бэггинг
и случайный лес
Для физика
Ярмарка: около 800 человек угадывали вес быка, 1198 фунтов; среднее всех догадок — 1197.
01
Bootstrap
подвыборки с возвращением
02
Усреднение
разброс падает, если ошибки не коррелированы
03
Случайные признаки
разбиение ищется по случайной части признаков
Случайный лес
Точность высокая без настройки
Выбросы устойчив
Параллельность деревья на всех ядрах
Прозрачность сотни деревьев не прочитать
Экстраполяция нет, как у дерева
Изложение. Идея ансамблей видна на примере, описанном Ф. Гальтоном в 1907 году: на ярмарке около 800 человек угадывали на глаз вес быка, 1198 фунтов, и среднее арифметическое всех догадок составило 1197 фунтов. Каждый участник ошибался в свою сторону, и при усреднении ошибки компенсировали друг друга — так же ведёт себя случайная погрешность, усреднённая по серии измерений. Бэггинг усредняет предсказания нескольких моделей, обученных на разных подвыборках; подвыборки формируются методом bootstrap — выбором объектов с возвращением, так что один объект может попасть в подвыборку несколько раз. Если ошибки моделей несмещены и некоррелированы, среднеквадратичная ошибка среднего из n моделей в n раз меньше средней ошибки одной модели, то есть бэггинг снижает разброс. Случайный лес развивает эту идею для деревьев: кроме разных подвыборок, при построении каждого узла лучшее разбиение ищется лишь по случайной части признаков, что позволяет уменьшить корреляцию деревьев. Лес является удобной моделью по умолчанию: он точен, устойчив к выбросам, менее одиночного дерева склонен к переобучению, распараллеливается и обычно хорошо работает без настройки. Платой служат прозрачность и ресурсы: лес из сотен деревьев не поддаётся прочтению, он требует памяти, плохо работает с разреженными признаками и, как и одиночное дерево, не экстраполирует.
Градиентный
бустинг
Возраст Цена f₁ Остаток Дерево f₂
25 700 560 140 140 700
50 800 560 240 140 700
75 600 560 40 140 700
80 400 560 −160 −210 350
100 300 560 −260 −210 350
Важно
Деревья неглубокие, три-четыре уровня: сила ансамбля в их числе.
01
Начало
приближение — среднее, 560
02
Шаг
дерево обучается на остатках
03
Остаток
антиградиент потерь: для MSE — y − f
04
Скорость η
вклад каждого дерева уменьшается
Изложение. В бустинге модели выстраиваются в цепочку: каждая следующая исправляет ошибки предыдущих. Базовые модели намеренно выбираются слабыми, часто это пни — деревья глубины 1. Рассмотрим пример главы: цена товара по его возрасту в днях. Начальное приближение — среднее цен 700, 800, 600, 400 и 300, то есть 560; остатки равны 140, 240, 40, −160 и −260. Пень, обученный на остатках, делит выборку по возрасту 80 дней и выдаёт средние остатки ветвей, 140 и −210. Прибавив их к приближению, получим 700, 700, 700, 350 и 350, а новые остатки уменьшатся до 0, 100, −100, 50 и −50. Далее процедура повторяется. В общем виде на каждом шаге строится дерево, приближающее антиградиент функции потерь по текущему предсказанию, — отсюда название метода; для MSE антиградиент пропорционален остатку y − f. Вклад каждого дерева обычно умножают на скорость обучения η < 1, а коэффициент шага подбирают отдельно. Деревья делают неглубокими, в три-четыре уровня: если дерево в начале цепочки подстроилось под шум, последующие этого не исправят. Базовой моделью бустинга может быть не только дерево, однако сумма линейных моделей остаётся линейной, поэтому градиентный бустинг почти всегда строят из деревьев.
Демонстрация:
бустинг главы
01
Пять товаров: возраст и цена
02
Пень глубины 1 на остатках
03
Шаг 1,0 и 0,1, от 1 до 20 деревьев
Что наблюдается
Порог 77,5 дня, листья 140 и −210, приближение 700, 700, 700, 350, 350 — как в таблице главы. Двадцать деревьев: MSE 13,5 при шаге 1,0 и 2492 при 0,1.
root@lab — запись со стенда
Демонстрация. Сценарий boost.py повторяет пример главы средствами scikit-learn: GradientBoostingRegressor с одним деревом глубины 1 и шагом 1,0. Начальное приближение 560 и остатки 140, 240, 40, −160 и −260 совпадают с ручным расчётом, первое дерево выбирает порог возраста 77,5 дня, середину между 75 и 80, и выдаёт в листьях 140 и −210. Приближение после первого шага, 700, 700, 700, 350 и 350, и остатки 0, 100, −100, 50 и −50 совпадают с таблицей главы. Последние восемь строк показывают роль шага: при шаге 1,0 ошибка на обучающих данных падает с 5000 после одного дерева до 13,5 после двадцати, при шаге 0,1 — с 28 814 до 2492. Малый шаг требует большего числа деревьев, однако на новых данных обычно обобщает лучше; ошибка на пяти обучающих точках этого не показывает, и для выбора числа деревьев и шага необходима отложенная выборка.
Бэггинг
против бустинга
Свойство Бэггинг, лес Бустинг
Деревья независимы цепочка
Глубина глубокие 3–4 уровня
Снижает разброс смещение
Переобучение устойчив склонен, нужен тест
Параллельность по деревьям внутри дерева
Таблицы точен обычно точнее
Для физика
Ни лес, ни бустинг не экстраполируют: оба составлены из деревьев.
Изложение. Оба метода строят ансамбль деревьев, но устроены противоположно. В бэггинге деревья независимы и глубоки, каждое по отдельности переобучено, а усреднение снижает разброс. В бустинге деревья выстроены в цепочку и неглубоки, каждое по отдельности — слабая модель, а последовательное исправление ошибок снижает смещение. По точности на табличных данных бустинг обычно превосходит случайный лес и потому стал первым выбором, однако сильнее склонен к переобучению, и отложенная выборка для него обязательна. Бустинг плохо распараллеливается: деревья строятся последовательно, и распараллелить можно лишь построение одного дерева, тогда как деревья леса вычисляются одновременно на всех ядрах, и на большой выборке эта разница оказывается решающей. Наконец, оба ансамбля составлены из деревьев и наследуют их неспособность к экстраполяции, показанную в предыдущей части.
Без учителя
Понижение размерности: PCA и t-SNE; кластеризация: k-средних, иерархическая, DBSCAN
05
Постановка задачи
Соседи и регрессия
Классификация
Ансамбли
Без учителя
Нейронные сети
Конвейер sklearn
Изложение. Пятая часть посвящена обучению без учителя, необходимому, когда о данных ещё ничего не известно: понижению размерности, позволяющему увидеть многомерную выборку, и кластеризации, разделяющей её на группы. Размеченного ответа здесь нет, и результат сверяется с физическим смыслом.
Метод
главных компонент
cov(X) = X⊤X / N (выборка центрирована) cov·v = λ·v λ — дисперсия вдоль оси v потеря = Σ отброшенных λ / Σ всех λ
Важно
Структуры, не похожие на эллипс, линейный метод не передаёт.
01
Новый базис
оси эллипса рассеяния
02
Отбрасывание
оси с наименьшей дисперсией
03
Стандартизация
иначе первая ось — признак в больших единицах
Изложение. Понижение размерности является переходом к пространству меньшей размерности с сохранением расстояний: соседи должны остаться соседями, а удалённые точки — удалёнными. Простое отбрасывание одной из осей почти всегда оказывается плохим решением: в худшем случае облако точек схлопнется. Метод главных компонент предполагает, что облако данных описывается эллипсом, и меняет базис на оси этого эллипса. Для центрированной выборки ковариационная матрица равна X⊤X/N; она симметрична, на её диагонали стоят дисперсии признаков, направление наибольшей дисперсии совпадает с собственным вектором при наибольшем собственном значении, а само собственное значение равно дисперсии вдоль этой оси. Отбрасываются оси с наименьшими собственными значениями, а доля потерянной информации оценивается отношением их суммы к сумме всех собственных значений. Метод имеет два ограничения. Признаки, измеренные в разных единицах, необходимо стандартизировать, иначе признак, выраженный в больших единицах, займёт первую компоненту; признаки одной природы, например яркости пикселей в демонстрации с цифрами, стандартизации не требуют. И структуры, не похожие на эллипс, метод не передаёт, поскольку он линеен.
t-SNE:
пружины между точками
p(j|i) ~ exp(−|xi − xj|² / 2σi²) q(ij) ~ 1 / (1 + |yi − yj|²) KL(P, Q) = Σ p·log(p / q) → min
Пояснение
Тяжёлые хвосты распределения Стьюдента устраняют скученность точек на карте.
01
Сходства
гауссовы в исходном пространстве
02
Карта
распределение Стьюдента на плоскости
03
Силы
градиент KL — притяжение и отталкивание
04
Ограничения
новые точки не проецируются, счёт долгий
Изложение. Метод t-SNE строит нелинейную карту и удобен для визуализации сложных структур. Механическая аналогия такова: объекты помещаются на плоскость, соединяются пружинами, сила которых зависит от того, насколько расстояние на плоскости отличается от расстояния в исходном пространстве, и система отпускается. Формально в исходном пространстве для каждой точки вычисляется условное сходство с остальными по гауссову закону, причём дисперсия своя у каждой точки и подбирается под плотность окрестности; параметр perplexity задаёт эффективное число соседей. На плоскости сходство описывается распределением Стьюдента с одной степенью свободы, нормированным по всем парам. Положения точек находятся градиентным спуском, минимизирующим расстояние Кульбака—Лейблера между двумя распределениями, а градиент представляет собой равнодействующую сил притяжения и отталкивания. Тяжёлые хвосты распределения Стьюдента решают проблему скученности: при гауссовом законе на плоскости точки сжимались бы к центру. Ограничения метода следующие: новые данные нельзя спроецировать без переобучения, вычисления длительны, а расстояния между далёкими группами и размеры групп на карте смысла не несут.
Демонстрация:
PCA и t-SNE
01
Wine: PCA без стандартизации
02
Wine: PCA после StandardScaler
03
Цифры 8×8: PCA и t-SNE на плоскости
04
kNN по двум координатам карты
Что наблюдается
Без стандартизации PC1 — это proline, 99,8 % дисперсии; после неё две компоненты дают 55 %. На цифрах kNN по карте: PCA 0,603, t-SNE 0,976.
root@lab — запись со стенда
Демонстрация. Сценарий pca.py начинает с датасета Wine. Без стандартизации первая главная компонента объясняет 99,8 % дисперсии, а её нагрузка на пролин равна единице: метод нашёл не структуру данных, а признак с наибольшими единицами измерения. После StandardScaler первые две компоненты объясняют 36,2 и 19,2 % дисперсии, наибольшие нагрузки первой приходятся на флаваноиды и фенолы, а для 90 % дисперсии необходимы 8 компонент из 13. Второй запуск обращается к датасету Digits: 1797 рукописных цифр, изображения 8×8, то есть 64 признака. PCA и t-SNE переводят их на плоскость, PCA — мгновенно, t-SNE — за 2 с на стенде, и две компоненты PCA объясняют лишь 28,5 % дисперсии. Качество карты оценим численно: kNN, обученный только по двум координатам карты, верно определяет цифру в 60,3 % случаев для PCA и в 97,6 % для t-SNE. Такая оценка позволяет измерить разделимость групп на карте, но не даёт классификатора: проецировать новые изображения t-SNE не умеет.
Результат:
PCA и t-SNE
Что наблюдается
PCA сохраняет глобальные направления, и цифры в центре перекрываются; t-SNE сохраняет соседство: десять групп разделены.
Демонстрация. Слева — проекция цифр на две главные компоненты, справа — карта t-SNE; цвет и подпись обозначают цифру, подпись поставлена в медиану группы. На проекции PCA различимы лишь крайние группы — нули, шестёрки, четвёрки и тройки, — а цифры в центре перекрываются: две линейные оси передают меньше трети дисперсии. Карта t-SNE разделяет все десять цифр; единицы распались на три группы, от двоек, троек, семёрок и девяток отделились небольшие группы, а несколько точек оказались в чужих группах. Отметим ограничения прочтения: размеры групп и расстояния между ними на карте t-SNE не отражают ни разброса, ни сходства цифр, сохраняется лишь соседство.
Кластеризация:
три метода
Метод Число кластеров Форма Выбросы
k-средних задаётся, по «локтю» выпуклая нет
иерархическая разрез дендрограммы по связи нет
DBSCAN определяет сам любая метка −1
Пояснение
DBSCAN: eps — радиус окрестности, min_samples — число точек в ней, включая саму точку.
Для физика
Выбросы DBSCAN — готовый инструмент поиска аномалий в данных установки.
Изложение. Вторая задача без учителя — разделение на группы объектов, не размеченных заранее. Метод k-средних является наиболее распространённым: задаётся число кластеров, центры размещаются случайно, каждая точка приписывается ближайшему центру, центр переносится в центр масс приписанных точек, и два последних шага повторяются до сходимости. Метод быстр, но требует заранее заданного числа кластеров, чувствителен к начальному расположению центров и предполагает кластеры шарообразными и сопоставимыми по размеру. Число кластеров подбирают по сумме квадратов расстояний до центров: как только с ростом k она перестаёт резко падать, можно останавливаться — это правило локтя. Агломеративная кластеризация строит всё дерево слияний снизу вверх, объединяя на каждом шаге два ближайших кластера, а разрез на нужном уровне выполняется затем по дендрограмме; число кластеров заранее знать не требуется, но метод плохо масштабируется. DBSCAN ищет области повышенной плотности: точка, у которой в радиусе eps не меньше min_samples точек, включая её саму, является ядром кластера, соседи ядра присоединяются к кластеру, а точки, не попавшие ни в один кластер, получают метку −1. Такие выбросы — не ещё один кластер: общего между ними лишь то, что плотности вокруг каждой не хватило. Выбор между методами следующий: известное число компактных групп — k-средних, неизвестное число при небольшой выборке — иерархическая, сложная форма или необходимость отделить выбросы — DBSCAN.
Демонстрация:
кластеризация
01
k-средних на четырёх облаках: локоть
02
Два полумесяца и 20 выбросов
03
k-средних, иерархическая и DBSCAN
Что наблюдается
Локоть при k = 4: сумма падает в 5,2 раза, далее в 1,1. На полумесяцах ARI: k-средних 0,253, иерархическая 0,239, DBSCAN 1,000 и 14 выбросов из 20.
root@lab — запись со стенда
Демонстрация. Сценарий cluster.py сначала подбирает число кластеров k-средних для 600 точек из четырёх облаков. Сумма квадратов расстояний до центров падает при переходе к k = 2, 3 и 4 в 4,16, 2,20 и 5,20 раза, а дальше — лишь в 1,11–1,13 раза: локоть указывает на четыре кластера. Затем рассматриваются 400 точек двух переплетённых полумесяцев и 20 равномерно разбросанных выбросов, имитирующих редкие сбои. Согласие найденного разбиения с полумесяцами оценивается скорректированным индексом Рэнда ARI: единица означает совпадение, ноль — согласие на уровне случайного разбиения. k-средних и иерархическая кластеризация по Уорду делят плоскость на две выпуклые части, ARI 0,253 и 0,239, и включают выбросы в кластеры. DBSCAN с радиусом 0,15 и пятью точками в окрестности восстанавливает оба полумесяца без единой ошибки, ARI 1,000, и помечает выбросами 14 точек, все из числа 20 сбоев; остальные шесть оказались в окрестностях точек полумесяцев и присоединены к ним.
Результат:
кластеризация
Что наблюдается
Локоть при k = 4. k-средних делит полумесяцы прямой линией; DBSCAN повторяет их форму и отмечает крестиками сбои вдали от них.
Демонстрация. Слева — правило локтя: кривая резко падает до k = 4 и далее почти горизонтальна. В центре — разбиение k-средних на два кластера: граница — прямая, перпендикулярная отрезку между центрами, поэтому концы каждого полумесяца отходят к чужому кластеру, а выбросы приписаны ближайшему центру. Справа — DBSCAN: полумесяцы восстановлены целиком, а крестиками отмечены точки, вокруг которых плотности не хватило. Отметим, что результат DBSCAN зависит от радиуса: при большем радиусе полумесяцы сольются, при меньшем — распадутся на части; радиус подбирают по графику расстояний до k-го соседа.
Нейронные сети
Нейрон, скрытые слои, обратное распространение ошибки, оптимизаторы, инициализация и регуляризация
06
Постановка задачи
Соседи и регрессия
Классификация
Ансамбли
Без учителя
Нейронные сети
Конвейер sklearn
Изложение. Шестая часть посвящена нейронным сетям — моделям, которые выучивают признаки самостоятельно: от одного нейрона и задачи XOR через обратное распространение ошибки к оптимизаторам, инициализации весов и регуляризации, без которых работа с готовыми фреймворками превращается в перебор настроек наугад.
Нейрон
и скрытый слой
S = W1·X1 + W2·X2 + W3·X3 Y = 1, если S ≥ 0.5 W = (0.5, −0.5, 0.5)
01
X1
задавал вопросы на лекциях
02
X2
попал к лектору на экзамене
03
X3
сдал лабораторные работы
01
Один слой
одна разделяющая плоскость
02
XOR
ровно одно из двух — плоскостью не разделить
03
Скрытый слой
новое пространство признаков
04
Активация
дифференцируемая: σ, tanh, ReLU
Изложение. Классические алгоритмы хорошо работают с признаками, сформулированными человеком; нейронные сети позволяют выучивать признаки из сырого сигнала — снимка камеры, осциллограммы, спектра. Математический нейрон взвешивает входные сигналы и пропускает сумму через функцию активации. Рассмотрим пример главы: по трём признакам требуется предсказать, сдаст ли студент экзамен. Признаки бинарные: задавал ли студент вопросы, попал ли к лектору, сдал ли лабораторные работы. Если студент попал к лектору, он сдаёт только при условии, что задавал вопросы и сдал лабораторные; если не попал — достаточно одного из двух. Для такой логики подходят веса 0,5, −0,5 и 0,5 при пороге 0,5: попадание к лектору вычитает 0,5 и превращает условие «или» в условие «и». Один нейрон проводит в пространстве признаков единственную разделяющую плоскость. Поэтому задачу, классы которой не разделяются плоскостью, например «ровно одно из двух» — исключающее ИЛИ, XOR, — он не решает: никакая прямая не отделит точки (0, 1) и (1, 0) от (0, 0) и (1, 1). Скрытый слой строит новое признаковое пространство, в котором прежде неразделимая задача решается одной плоскостью.
Демонстрация:
нейрон и XOR
01
Нейрон главы: таблица истинности
02
XOR: логистическая регрессия
03
Сеть со скрытым слоем из 1, 2 и 4 нейронов
04
Новые признаки скрытого слоя
Что наблюдается
Нейрон главы: 0 несовпадений из 8. XOR: логистическая регрессия 0,500, один скрытый нейрон 0,750, два — 1,000; углы (0, 0) и (1, 1) переходят в одну точку.
root@lab — запись со стенда
Демонстрация. Сценарий xor.py сначала проверяет нейрон главы: для всех восьми комбинаций признаков вычисляется взвешенная сумма, ответ порогового нейрона сравнивается с правилом, и несовпадений нет. Затем рассматривается XOR признаков «задавал вопросы» и «сдал лабораторные»: студент сдаёт, если выполнено ровно одно из двух. Четыре угла квадрата повторены по 50 раз с шумом измерения 0,1. Логистическая регрессия, то есть один нейрон с сигмоидой, отвечает верно ровно в половине случаев, а её веса близки к нулю: на симметричных данных XOR минимум log loss достигается при нулевых весах, хотя прямая, отделяющая один угол от трёх остальных, верно классифицирует три объекта из четырёх. Сеть MLPClassifier со скрытым слоем из одного нейрона достигает именно 0,750: её выход монотонно зависит от одной линейной комбинации признаков, и граница остаётся прямой. Скрытый слой из двух и четырёх нейронов даёт 1,000. Последние строки показывают, что делает скрытый слой из двух нейронов: углы (0, 0) и (1, 1), относящиеся к одному классу, переходят в одну и ту же точку (+1, −1), а углы другого класса — в (−1, −1) и (+1, +1). В новом пространстве классы разделяются прямой, то есть скрытый слой выучил признаки, в которых задача стала линейной.
Обратное
распространение ошибки
f = (x + y)·z, q = x + y df/dx = df/dq · dq/dx = z · 1 σ'(x) = σ(x)·(1 − σ(x)) δ_скрытый = (W⊤δ)·σ'
01
Цепное правило
производная композиции — произведение производных
02
Прямой проход
вычисляет выходы слоёв
03
Обратный проход
переносит ошибку к входу через веса
04
Сигмоида
затухающий градиент, выход > 0, дорогая экспонента
Изложение. Для обучения сети градиентным спуском необходимо знать производную функции потерь по каждому весу. Для выходного слоя ошибка вычисляется непосредственно, а для скрытых слоёв применяется метод обратного распространения ошибки, основанный на цепном правиле: производная композиции равна произведению производных. Рассмотрим пример главы: f = (x + y)·z. Введём промежуточную величину q = x + y; тогда df/dq = z, dq/dx = 1, и df/dx = z. В сети так же: прямой проход вычисляет выходы всех слоёв, обратный переносит ошибку от выхода к входу, умножая её на веса следующего слоя и на производную функции активации. Поэтому функция активации должна быть дифференцируема: пороговая функция для обучения не подходит, её производная равна нулю всюду, кроме точки порога. Сигмоида дифференцируема, и её производная выражается через неё саму: σ' = σ(1 − σ). Однако у сигмоиды три недостатка, из-за которых в глубоких сетях её вытеснила функция ReLU: на хвостах производная близка к нулю, и в глубокой сети градиент затухает, не доходя до нижних слоёв; выход всегда положителен, что даёт зигзагообразный ход обучения; экспонента вычисляется дорого.
Демонстрация:
обратный проход
01
Сеть 2–3–1 с сигмоидой на XOR
02
Градиенты по цепному правилу
03
Сверка с центральными разностями
Что наблюдается
Градиенты 13 параметров совпали с разностями до восьмого знака. Log loss 1,048 → 0,002, выходы 0,000; 0,997; 0,998; 0,003.
root@lab — запись со стенда
Демонстрация. Сценарий backprop.py реализует обратное распространение без библиотек машинного обучения: сеть с двумя входами, тремя скрытыми нейронами и одним выходом, сигмоида на обоих слоях, функция потерь log loss, задача XOR из четырёх точек. Функция backward вычисляет градиенты по цепному правилу: ошибка выхода для сигмоиды и log loss равна разности выхода и метки, ошибка скрытого слоя получается умножением на веса выходного слоя и на производную сигмоиды. Прежде чем обучать сеть, проверим градиенты независимым способом: каждый из 13 параметров сдвигается на одну миллионную в обе стороны, и центральная разность потерь сравнивается с вычисленным градиентом. Наибольшая относительная разница составляет 1,5·10⁻⁸, то есть реализация верна. Затем сеть обучается полным градиентным спуском с шагом 1: за 100 эпох log loss падает с 1,048 до 0,559, за 1000 — до 0,013, за 5000 — до 0,002, и выходы на четырёх точках равны 0,000, 0,997, 0,998 и 0,003. Таким образом, сверка с разностями позволяет проверить собственную реализацию градиента и потому обязательна: ошибка в одном множителе цепного правила часто не останавливает обучение, а лишь замедляет его или уводит в сторону, и по ходу обучения её трудно заметить.
Оптимизаторы
градиентного спуска
Метод Идея Обновление
SGD шаг против градиента x ← x − α·g
Momentum инерция v ← ρv + α·g; x ← x − v
Nesterov градиент после сдвига инерцией v ← ρv − α·g(x + ρv); x ← x + v
Adagrad шаг по истории параметра c ← c + g²; x ← x − α·g/√c
RMSProp история забывается c ← βc + (1 − β)·g²
Adam RMSProp + инерция поправки 1 − γ^t и 1 − β^t
Пояснение
Отправная точка — Adam или метод Нестерова: сеть из типовых слоёв обучается без ручного подбора.
Изложение. Для минимизации функции потерь применяются варианты градиентного спуска. Базовый SGD делает шаг против градиента с постоянной скоростью α. Momentum накапливает инерцию и сглаживает колебания: скорость v складывается из прежней скорости с коэффициентом ρ и текущего градиента. Метод Нестерова вычисляет градиент в точке, куда параметры сдвинет инерция, и потому реже проскакивает минимум. Adagrad адаптирует скорость для каждого параметра: шаг делится на корень из накопленной суммы квадратов градиентов, и сильно сдвинутые веса меняются меньше; недостаток метода — неограниченный рост суммы, способный остановить обучение. RMSProp заменяет сумму экспоненциальным скользящим средним и забывает старые значения. Adam объединяет RMSProp с инерцией; оба накопителя стартуют с нуля и на первых шагах занижены, поэтому вводится поправка на смещение — деление на 1 − γ^t и 1 − β^t. Без этой поправки Adam сводится к RMSProp, дополненному инерцией. В качестве отправной точки обычно выбирают Adam или метод Нестерова: с ними сеть из типовых слоёв в большинстве случаев обучается без ручного подбора.
Инициализация
и нормализация
D(s) = D(Σ w·x) = n·D(w)·D(x) D(s) = D(x) ⇒ D(w) = 1/n ЛеКун D(w) = 2/(n_in + n_out) Ксавье D(w) = 2/n для ReLU Хе z = (x − μ) / √(σ² + ε), y = γ·z + β
01
Нули, константа
нейроны слоя одинаковы — слой вырождается
02
По умолчанию
Keras — Ксавье; PyTorch — kaiming, a = √5
03
Batch norm
нормировка по батчу, γ и β обучаются
04
Инференс
скользящие средние вместо статистик батча
Изложение. Признаки перед подачей в сеть приводятся к сопоставимым масштабам: это защищает от потери точности, необходимо для корректной регуляризации L1 и L2 и ускоряет обучение. Инициализация весов требует того же внимания. Нули и константа не работают: все нейроны слоя одинаковы, получают один и тот же градиент, и слой вырождается в один нейрон. Случайные значения работают, если масштаб подобран так, чтобы слой не менял дисперсию сигнала. Оценим его. Дисперсия суммы n независимых произведений w·x с нулевыми средними равна n·D(w)·D(x), и условие D(s) = D(x) требует D(w) = 1/n; это инициализация ЛеКуна, сохраняющая дисперсию в прямом проходе. Инициализация Ксавье, предложенная Глоро и Бенджио, выравнивает прямой и обратный проходы и использует D(w) = 2/(n_in + n_out). Для ReLU половина выходов обнуляется, поэтому дисперсия весов берётся вдвое больше, 2/n, — это инициализация Хе. Фреймворки по умолчанию используют другое: Keras у слоёв Dense и Conv2D — Ксавье, PyTorch у Linear и Conv2d — kaiming_uniform с параметром a = √5, поэтому инициализацию под ReLU обычно задают явно. Batch normalization нормирует активации внутри батча и затем масштабирует их обучаемыми параметрами γ и β; на инференсе батча может не быть, и используются скользящие средние, накопленные при обучении. Слой ускоряет сходимость и позволяет брать больший шаг обучения, хотя объяснение, предложенное авторами, — сдвиг распределений входов слоя — впоследствии было оспорено.
Регуляризация
сети
01
L1, L2, Elastic Net
штраф за большие веса, как в регрессии
02
Dropout
случайное выключение нейронов при обучении
03
Остаточные связи
обход слоёв для обучения глубоких сетей, не регуляризация
04
Аугментация
повороты, сдвиги и шум обучающих примеров
Пояснение
Inverted dropout делит на долю оставленных нейронов при обучении: на инференсе слой просто отключается.
Изложение. От переобучения сети защищают несколько приёмов. Штраф за большие веса — L2, L1 или их комбинация Elastic Net — действует так же, как в линейной регрессии. Dropout случайным образом выключает часть нейронов на каждой итерации обучения, и сеть не может опираться на отдельные нейроны; его можно трактовать как обучение ансамбля прореженных сетей с общими весами, которые на инференсе приближённо усредняются, — приём, родственный бэггингу. На инференсе включены все нейроны, и масштаб сигнала должен совпадать с обучением: в исходной работе выходы домножались на долю оставленных нейронов при выводе, а в современных реализациях при обучении делят на эту долю, поэтому model.eval() в PyTorch и training=False в Keras просто отключают слой. Остаточные связи к регуляризации не относятся, хотя упоминаются рядом с ней: они складывают признаки, взятые в обход нескольких слоёв, и позволяют донести градиент до нижних слоёв очень глубоких сетей. Таким образом, они решают задачу оптимизации, а не переобучения: без них с ростом глубины растёт ошибка уже на обучающей выборке. Аугментация расширяет обучающую выборку повёрнутыми, сдвинутыми и зашумлёнными копиями примеров, и сеть перестаёт опираться на случайные особенности изображений.
Демонстрация:
оптимизаторы
01
Овраг (x² + 50·y²)/2: SGD при трёх шагах
02
Momentum, Nesterov, Adagrad, RMSProp, Adam
04
СКО сигнала через 20 слоёв
Что наблюдается
SGD: 394 шага, при lr 0,041 > 2/50 расходится; Nesterov — 86, RMSProp без поправки на смещение — 22. Через 20 слоёв ReLU: ЛеКун 0,001, Хе 0,76.
root@lab — запись со стенда
Демонстрация. Сценарий optim.py минимизирует вытянутую квадратичную функцию (x² + 50y²)/2: кривизна поперёк оврага в 50 раз больше, чем вдоль, как у плохо обусловленной функции потерь. Старт — точка (−4, 1), останов — когда значение функции становится меньше одной миллионной. Для SGD устойчивость ограничена большей кривизной: шаг должен быть меньше 2/50 = 0,04. При шаге 0,02 спуск требует 394 шагов, при 0,039 — 201, при 0,041 он расходится. Momentum с тем же шагом 0,02 доходит за 147 шагов, метод Нестерова — за 86. Адаптивные методы делят шаг на накопленный масштаб градиента по каждой координате и тем самым выравнивают кривизны: Adagrad требует 158 шагов, Adam — 150, поскольку его инерция даёт колебания вокруг минимума. Результат RMSProp, 22 шага, объясняется иначе: в сценарии β = 0,999, а поправки на смещение нет, поэтому накопитель на первых шагах занижен и шаг завышен — на первом шаге примерно в 30 раз, на десятом в 10 раз. С поправкой, как у Adam, тому же методу необходимы около 300 шагов, а при β = 0,9 и том же шаге спуск до порога не доходит. Число шагов зависит от выбранной скорости, поэтому таблица сравнивает не методы вообще, а их поведение на конкретной функции. Сценарий init.py пропускает тысячу векторов единичной дисперсии через 20 слоёв ширины 256. При весах N(0, 1) с tanh СКО сигнала остаётся около 0,97, но 86 % выходов насыщены, и градиент через такие нейроны не проходит. С инициализацией ЛеКуна и ReLU дисперсия на каждом слое уменьшается вдвое, и к двадцатому слою СКО падает до 0,001, а инициализация Хе сохраняет его около 0,8.
Результат:
траектории
Что наблюдается
SGD сразу гасит поперечную координату и медленно идёт вдоль оврага; Momentum разгоняется, но раскачивается; Adam идёт по плавной кривой.
Демонстрация. На рисунке — первые 60 шагов трёх методов из точки (−4, 1), линии уровня функции и минимум, отмеченный звёздочкой. SGD с шагом 0,02 за один шаг гасит координату y, поскольку произведение шага на поперечную кривизну равно единице, а вдоль оврага сдвигается на 2 % оставшегося расстояния за шаг и к 60-му шагу проходит лишь до x ≈ −1,2. Momentum с тем же шагом разгоняется вдоль оврага и за те же 60 шагов уже проскакивает минимум, но сильно раскачивается поперёк. Adam нормирует шаг по каждой координате и идёт по плавной кривой, однако поперечная координата из-за инерции совершает медленные затухающие колебания на всём пути, а не только вблизи минимума.
Конвейер sklearn
Единый API, разбиение и утечка данных, Pipeline, кросс-валидация, подбор гиперпараметров, сохранение модели
07
Постановка задачи
Соседи и регрессия
Классификация
Ансамбли
Без учителя
Нейронные сети
Конвейер sklearn
Изложение. Седьмая часть собирает рассмотренные методы в конвейер библиотеки scikit-learn: датасет, разбиение, предобработка, обучение, метрики, подбор гиперпараметров и сохранение модели. Конвейер один и тот же для любой задачи, меняются только данные и модель.
Единый
API
Метод Модель Преобразователь
fit(X, y) подбирает параметры запоминает статистики
predict(X) метки новых объектов —
predict_proba(X) вероятности классов —
transform(X) — преобразует данные
fit_transform(X) — обучает и преобразует
Пояснение
load_* — учебные наборы пакета, fetch_* — загрузка из сети, make_* — синтетические данные.
Проверка
Замена kNN на лес или сеть — одна строка: интерфейс общий.
Изложение. Стандартом де-факто для классического машинного обучения в Python является библиотека scikit-learn, построенная поверх NumPy и SciPy, принимающая также таблицы pandas и охватывающая весь конвейер: датасет, разбиение, предобработка, обучение, метрики, подбор гиперпараметров и сохранение модели. Популярность библиотеке обеспечивает единообразный интерфейс. Объекты делятся на модели, которые обучаются предсказывать целевую величину, — KNeighborsClassifier, LinearRegression, RandomForestClassifier, MLPClassifier, — и преобразователи, которые подготавливают данные, — StandardScaler, OneHotEncoder, PCA. Метод fit обучает объект: модель подбирает параметры, преобразователь запоминает статистики выборки, например среднее и дисперсию каждого признака. Метод predict предсказывает метки новых объектов, predict_proba — вероятности классов, transform преобразует данные, fit_transform обучает и преобразует одним вызовом. Поэтому замена одного алгоритма другим сводится к изменению одной строки. Датасеты библиотеки делятся на три семейства: функции load_* возвращают небольшие учебные наборы из состава пакета, fetch_* загружают большие наборы из сети при первом обращении, make_* генерируют синтетические данные; демонстрации лекции используют первые и третьи.
Разбиение
и утечка данных
X_train, X_test, y_train, y_test = train_test_split( X, y, test_size=0.2, random_state=42, stratify=y) scaler = StandardScaler() X_train_s = scaler.fit_transform(X_train) X_test_s = scaler.transform(X_test)
01
Тест
откладывается первым, до любой обработки
02
stratify=y
доли классов совпадают
03
Утечка
сведения о тесте попали в обучение
04
Категории
OneHotEncoder, OrdinalEncoder, ColumnTransformer
Изложение. Качество модели нельзя оценивать на тех же данных, на которых она обучалась: так измеряется способность запоминать, а не обобщать. Поэтому в первую очередь откладывается тестовая выборка — функцией train_test_split с параметром test_size. Параметр random_state фиксирует случайность для воспроизводимости, а stratify=y обеспечивает совпадение долей классов в обеих частях, что важно при дисбалансе. Отложенная выборка не используется до финальной оценки: она представляет данные, которых модель не видела. Методы, опирающиеся на расстояния и на градиентный спуск, требуют масштабирования признаков, и здесь возникает первая ловушка. StandardScaler обучается только на обучающей выборке, а тестовая лишь преобразуется выученными статистиками. Если обучить его на всей выборке, сведения о тестовой части попадут в обучение; это называется утечкой данных и может завысить оценку качества. Категориальные признаки, например тип детектора или режим установки, кодируются: OneHotEncoder превращает каждую категорию в отдельный бинарный признак и подходит для номинальных признаков, OrdinalEncoder — в целое число и подходит для порядковых, если порядок задан явно параметром categories: по умолчанию категории упорядочиваются по алфавиту, и «отлично» получает меньший номер, чем «плохо». Разные преобразования для разных столбцов объединяет ColumnTransformer.
Pipeline
и подбор
model = Pipeline([("scaler", StandardScaler()), ("knn", KNeighborsClassifier(5))]) cv = StratifiedKFold(5, shuffle=True, random_state=42) cross_val_score(model, X_train, y_train, cv=cv, scoring="f1_macro") GridSearchCV(model, {"knn__n_neighbors": [1, 3, 5, 7, 9, 15], "knn__weights": ["uniform", "distance"]}, cv=cv, scoring="f1_macro")
01
Pipeline
предобработка обучается внутри фолда
02
Кросс-валидация
среднее и разброс по k фолдам
03
GridSearchCV
сетка, имя «шаг__параметр»
04
Тест
один раз, после выбора модели
Изложение. Пара из масштабирования и модели встречается настолько часто, что для неё предусмотрен класс Pipeline, объединяющий цепочку преобразований и финальную модель в один объект с тем же интерфейсом. Метод fit конвейера сам обучает масштабирование на обучающих данных и передаёт преобразованные данные модели, predict сам преобразует новые данные выученными статистиками. Конвейер решает три задачи: код сокращается, утечка исключается, поскольку преобразователи всегда обучаются только на обучающей части, а весь конвейер передаётся в кросс-валидацию и подбор гиперпараметров как единое целое. Одно разбиение даёт одну случайную оценку, поэтому надёжнее кросс-валидация: выборка делится на k фолдов, модель k раз обучается на k − 1 из них и проверяется на оставшемся, а оценки усредняются. Разброс оценок по фолдам не менее важен, чем среднее: большая дисперсия указывает на нестабильную модель или слишком малую выборку. Гиперпараметры подбирает GridSearchCV, оценивая кросс-валидацией каждую комбинацию сетки; имя параметра составляется из имени шага конвейера и имени параметра через двойное подчёркивание. Тестовая выборка не участвует ни в обучении, ни в подборе и используется один раз, в финальной оценке. При большой сетке вместо полного перебора применяют RandomizedSearchCV.
Демонстрация:
конвейер главы
01
Pipeline: метрики на тесте
02
Кросс-валидация по пяти фолдам
03
GridSearchCV по K и весам
Что наблюдается
Числа главы воспроизведены: F1 0,951 ± 0,036, лучшие K = 15 и uniform, тест 1,000, MAE 46,1, R² 0,419. K = 7 и 15 различаются на 0,001 при разбросе 0,04.
root@lab — запись со стенда
Демонстрация. Сценарий pipeline.py выполняет на стенде код главы без изменений. Конвейер из StandardScaler и kNN с пятью соседями на тесте из 36 образцов даёт accuracy 0,972 и F1 0,972 при одной ошибке: образец второго сорта отнесён к третьему; ROC-AUC составляет 0,999. Кросс-валидация на обучающей части повторяет главу до последнего знака: F1 по фолдам 0,894, 1,000, 0,967, 0,930 и 0,967, среднее 0,951 ± 0,036. GridSearchCV выбирает 15 соседей и обычное голосование с F1 0,959 на кросс-валидации и 1,000 на тесте — те же числа, что в главе; обычное голосование выбрано лишь потому, что при равных оценках GridSearchCV берёт первую комбинацию сетки. Дополнительные строки показывают, насколько выбор надёжен: K = 7 и K = 15 различаются на 0,0008 при разбросе по фолдам 0,04, а взвешенное и обычное голосование на этой выборке совпадают при каждом K. Следовательно, сетка указывает не на единственное лучшее K, а на область от 7 до 15, а F1 = 1,000 на 36 образцах означает лишь отсутствие ошибок на тесте: одна ошибка снизила бы его примерно до 0,97. Регрессия Ridge на Diabetes даёт MAE 46,1, RMSE 55,5 и R² 0,419, как в главе; для сравнения, предсказание средним даёт MAE 64,0.
Демонстрация:
утечка данных
01
100 объектов, 10 000 признаков-шумов
02
Отбор 20 признаков до кросс-валидации
03
Тот же отбор внутри Pipeline
Что наблюдается
Отбор до кросс-валидации: 0,870 на чистом шуме; внутри Pipeline — 0,470, уровень угадывания. Для StandardScaler на Wine разницы нет: 0,961 и 0,961.
root@lab — запись со стенда
Демонстрация. Сценарий leak.py показывает, к чему приводит утечка. Признаки — 10 000 столбцов нормального шума на 100 объектов, метки — подброшенная монета, то есть закономерности в данных нет. Если сначала отобрать по всей выборке 20 признаков, сильнее всего связанных с метками, а затем оценить логистическую регрессию кросс-валидацией, доля верных ответов составит 0,870 ± 0,075: отбор уже видел метки тех объектов, на которых модель потом проверяется. Тот же отбор внутри конвейера выполняется заново на каждом фолде, и оценка падает до 0,470 ± 0,093 — уровня угадывания, как и должно быть для шума. Второй запуск повторяет пример утечки из главы — StandardScaler, обученный на всей выборке Wine, — и разницы не обнаруживает: 0,961 в обоих случаях. Утечка через среднее и дисперсию признаков, вычисленные без меток, мала; опасны шаги, использующие метки или иные сведения о тестовых объектах. Поэтому правило одно для всех шагов: всё, что обучается на данных, помещается в конвейер.
Сохранение
модели
joblib.dump(best_model, "wine_knn.joblib") loaded = joblib.load("wine_knn.joblib") loaded.predict(X_test) # предобработка внутри
Важно
Файл модели из непроверенного источника равносилен чужому скрипту.
01
Весь конвейер
масштабирование и модель одним файлом
02
Доверие
загрузка pickle выполняет код
03
Версия
scikit-learn закреплена в зависимостях
04
Признак
InconsistentVersionWarning при другой версии
Изложение. Обученную модель не требуется переобучать при каждом запуске: её сохраняют на диск. Для объектов scikit-learn обычно применяют joblib, который умеет сжимать файл и отображать большие массивы NumPy в память при загрузке, и сохраняют весь конвейер, так что загруженная модель принимает исходные признаки без предобработки. Два обстоятельства требуют внимания. Файл joblib, как и pickle, при загрузке может выполнить произвольный код, поэтому модели загружают только из доверенных источников; безопаснее формат skops.io, который загружает лишь типы, признанные доверенными. Модель, сохранённая одной версией библиотеки, не обязательно загрузится другой, поэтому версию scikit-learn необходимо фиксировать среди зависимостей проекта, как описано в главе «От скрипта к приложению»; при несовпадении версий библиотека выдаёт предупреждение InconsistentVersionWarning, означающее, что поведение загруженной модели не гарантировано.
Демонстрация:
сохранение модели
01
joblib.dump: конвейер в файл
02
joblib.load: F1 на тесте
03
Файл с меткой версии 1.5.2
04
Файл, выполняющий код при загрузке
Что наблюдается
Файл 36 144 байта, F1 1,000 без предупреждений. С меткой 1.5.2 — три InconsistentVersionWarning. Чужой файл напечатал строку при загрузке.
root@lab — запись со стенда
Демонстрация. Сценарий save.py обучает конвейер из StandardScaler и kNN с 15 соседями и сохраняет его в файл размером 36 144 байта; load.py загружает файл, получает F1 1,000 на тесте и предупреждений не выдаёт. Затем сценарий сохраняет ту же модель с подменённой меткой версии 1.5.2: scikit-learn записывает версию в состояние каждого объекта, и такой файл имитирует модель, сохранённую старой библиотекой. При загрузке появляются три предупреждения InconsistentVersionWarning — по одному на конвейер, масштабирование и классификатор; предсказания в этом случае совпали, но в общем случае библиотека их не гарантирует. Последние две команды показывают, почему файлы моделей загружают только из доверенных источников. Сценарий evil.py сохраняет объект, метод __reduce__ которого предписывает вызвать функцию при распаковке; вместо вредоносного действия вызывается print, и строка появляется в терминале при простом вызове joblib.load, ещё до какого-либо обращения к модели.
Итоги
лекции
01
Обучение — минимизация функционала; качество — только на невиденных данных.
02
Методы на расстояниях и градиентах требуют масштабирования признаков.
03
Регуляризация стабилизирует веса при коллинеарности и шуме; λ — на валидации.
04
При дисбалансе accuracy бесполезна: precision, recall, порог, класс.
05
Деревья не экстраполируют; лес снижает разброс, бустинг — смещение.
06
Градиент сверяется с разностями, инициализация — под активацию.
07
Всё, что обучается на данных, — в Pipeline; версия — в зависимостях.
Изложение. Подведём итоги. Обучение модели сводится к минимизации функционала, а её качество измеряется только на данных, которых она не видела. Методы, опирающиеся на расстояния и на градиентный спуск, требуют масштабирования признаков: без него kNN на Wine работал по одному признаку из тринадцати. Линейная зависимость признаков и шум делают задачу некорректной, и её исправляет регуляризация, коэффициент которой подбирается на отложенной выборке. При дисбалансе классов доля правильных ответов не позволяет сравнивать модели; необходимы precision и recall, выбор порога и явное указание положительного класса. Деревья и их ансамбли не экстраполируют; случайный лес снижает разброс, бустинг — смещение, и разложение ошибки подтверждается прямым расчётом. Собственную реализацию градиента необходимо сверять с разностями, а масштаб инициализации — согласовывать с функцией активации. Наконец, всё, что обучается на данных, помещается в конвейер, а модель сохраняется вместе с закреплённой версией библиотеки.
Упражнения
и задание
01
Свой kNN
на NumPy, сравнение с KNeighborsClassifier
02
Ridge и Lasso
подбор λ кросс-валидацией на Diabetes
03
Порог
ROC-кривая metrics.py и порог для чистоты 0,9
04
Экстраполяция
MLPRegressor на законе k = 0,8·I²
Пояснение
Практикум книги «Базовые методы ИИ в физических исследованиях»: свои kNN, линейная и логистическая регрессия, соревнование Kaggle, сеть прямого распространения.
Для физика
Вывод о модели подкрепляется отложенной выборкой, а не невязкой на обучающих данных.
Изложение. Упражнения служат самопроверке. Первое — реализовать метод ближайших соседей на NumPy и сравнить его ответы и время работы с KNeighborsClassifier на датасете Wine. Второе — подобрать кросс-валидацией коэффициент регуляризации Ridge и Lasso на датасете Diabetes и сравнить, какие признаки Lasso обнуляет. Третье — построить ROC-кривую для демонстрации metrics.py и выбрать порог, при котором чистота отобранных событий составляет 0,9, указав соответствующую эффективность отбора. Четвёртое — обучить MLPRegressor на законе k = 0,8·I² и проверить, экстраполирует ли сеть за пределы обучающих токов. Задания с самостоятельной реализацией алгоритмов собраны в практикуме книги «Базовые методы ИИ в физических исследованиях»: свои kNN, линейная и логистическая регрессия, соревнование Kaggle для начинающих и классификация сетью прямого распространения.
Источники
2
Hastie T., Tibshirani R., Friedman J. The elements of statistical learning. – 2nd ed. – Springer, 2009; Bishop C. M. Pattern recognition and machine learning. – Springer, 2006
3
Гудфеллоу Я., Бенджио И., Курвилль А. Глубокое обучение. – ДМК Пресс, 2018; Жерон О. Прикладное машинное обучение с помощью Scikit-Learn, Keras и TensorFlow. – 2-е изд. – Диалектика, 2020
Изложение. Лекции соответствует часть книги курса «Машинное обучение»: главы об основных понятиях, классических алгоритмах, нейронных сетях и библиотеке scikit-learn. Строгие выкладки по классическим методам приведены у Хасти, Тибширани и Фридмана и у Бишопа, по нейронным сетям — у Гудфеллоу, Бенджио и Курвилля, а рецепты, доведённые до работающего кода, — у Жерона. Расширенная версия раздела с практическими заданиями, в которых алгоритмы реализуются самостоятельно, вышла отдельной книгой «Базовые методы ИИ в физических исследованиях», а готовые рецепты обучения основных моделей собраны в сборнике рецептов по машинному обучению. Справочником по интерфейсу служит руководство пользователя scikit-learn.
Спасибо за внимание
Вопросы
phys-dev.github.io/soft-dev-book
Изложение. Лекция завершена. Вопросы по материалу удобно задавать, опираясь на главы части «Машинное обучение» и на демонстрации: все сценарии используют встроенные или синтетические данные и выполняются за секунды, поэтому любой результат можно повторить и изменить.