На этом занятии мы переходим к детальному разбору первого практического класса задач машинного обучения с учителем — регрессионному анализу. Мы изучим его математический аппарат, разберем ключевые метрики ошибок и функции потерь, а также напишем собственный алгоритм оптимизации (градиентный спуск) на чистом Python и NumPy.
Регрессия — это тип задачи машинного обучения, где мы пытаемся предсказать непрерывное числовое значение (например, стоимость квартиры, мощность двигателя, калорийность блюда).
Термин «регрессия» был введен в конце XIX века сэром Фрэнсисом Гальтоном. Изучая распределение роста в популяции людей, он заметил феномен, который назвал «регрессией к среднему»: у экстремально высоких отцов сыновья в среднем оказывались чуть ниже них, стремясь к среднему росту по популяции (и наоборот — у низких отцов сыновья были в среднем чуть выше ростом). Линия, проведенная через облако точек на графике для описания этой тенденции, получила название «линии регрессии», а математический метод — регрессионного анализа.
В средней школе уравнение прямой линии записывалось в следующем виде:
\(y = kx + b\)
где \(x\) — независимая переменная, \(y\) — зависимая переменная, \(k\) — угловой коэффициент наклона, а \(b\) — свободный коэффициент (смещение по оси ординат).
В машинном обучении уравнение для простой линейной регрессии записывается в следующей нотации:
\(\hat{y} = wx + b\)
Процесс обучения модели линейной регрессии заключается в нахождении оптимальных параметров \(w\) и \(b\), при которых общая ошибка предсказания на обучающем наборе данных будет минимальной.
Для выполнения матричных математических операций над массивами данных стандартные списки Python (list) малоэффективны: они занимают много оперативной памяти и работают медленно, так как требуют написания явных циклов на интерпретируемом Python.
Массивы NumPy (ndarray) решают эти проблемы благодаря следующим свойствам:
Чтобы оценить качество построенной аппроксимирующей линии, нам необходимо измерить степень отклонения предсказаний от фактических точек. Для этого используются две основные метрики:
Представляет собой простое среднее арифметическое абсолютных значений ошибок:
$$ \text{MAE} = \frac{1}{n} \sum_{i=1}^{n} |y_i – \hat{y}_i| $$
Представляет собой среднее арифметическое квадратов ошибок:
$$ \text{MSE} = \frac{1}{n} \sum_{i=1}^{n} (y_i – \hat{y}_i)^2 $$
Важно различать понятия метрики и функции потерь:
Как модель автоматически находит те значения параметров \(w\) и \(b\), которые минимизируют функцию потерь L2 (MSE)? Основным рабочим инструментом для этого является градиентный спуск.
Представьте, что вы стоите на склоне горы (ландшафт функции потерь) в густом тумане. Ваша задача — дойти до самой низкой точки (минимума потерь). Вы не видите всю картину, только землю у себя под ногами.
Ваши действия:
$$ w_{\text{new}} = w_{\text{old}} – \alpha \cdot \frac{\partial L}{\partial w} $$
Где:
В машинном обучении важно четко различать два типа настроек:
| Характеристика | Параметры (\(w\), \(b\)) | Гиперпараметры (\(\alpha\), кол-во эпох) |
|---|---|---|
| Кто определяет? | Алгоритм обучения | Человек (ML-специалист) |
| Источник | Вычисляются непосредственно из данных в процессе оптимизации | Задаются вручную до начала процесса обучения |
| Роль | Составляют саму обученную модель (артефакты обучения) | Управляют ходом и конфигурацией процесса обучения |
В простейшей реализации градиентного спуска мы сталкиваемся со следующими проблемами:
Если признаки имеют разный масштаб (например, бюджет в тысячах рублей, а продажи в штуках), ландшафт функции потерь сильно растягивается. Шаги градиентного спуска начинают совершать колебания от стенки к стенке вместо прямого движения к центру.
Решение: Стандартизация (StandardScaler). Преобразует входные данные \(X\) так, чтобы их среднее значение стало равно 0, а стандартное отклонение — 1. Это превращает ландшафт функции потерь в почти идеальную круглую чашу, обеспечивая сопоставимые градиенты и кратно ускоряя сходимость.
Классический пакетный градиентный спуск (Batch GD) пересчитывает градиент по всем точкам датасета на каждом шаге, что неэффективно на миллионах строк.
Решение: Использование стохастического градиентного спуска (SGD), обновляющего веса после каждой случайной точки, или компромиссного метода Mini-batch градиентного спуска (обновление по небольшим подвыборкам — батчам), который является золотым стандартом в Deep Learning.
В реальном мире результат редко зависит только от одного фактора. Для построения более точной модели используется множественная линейная регрессия, учитывающая \(n\) признаков одновременно.
Формула для множественной регрессии:
$$ \hat{y} = w_1x_1 + w_2x_2 + \dots + w_nx_n + b $$
В векторно-матричном виде уравнение записывается лаконично:
$$ \hat{y} = W^T X + b $$
Важный вывод: С математической точки зрения переход к множественной регрессии не меняет логики оптимизации — вычисления переводятся в матричный формат. Однако на плечи инженера ложится новая важная задача — отбор значимых признаков (feature selection) и удаление избыточных колонок, вносящих шум в модель. На следующем практическом занятии мы подробно разберем этот процесс.
Все рассмотренные концепции мы реализуем в коде. Ознакомьтесь с материалами в Google Colab, попробуйте изменить значения learning_rate и epochs в цикле обучения, чтобы наглядно проследить за динамикой изменения среднеквадратичной ошибки.