Машинное обучение Машинное обучение: карта трека, типы задач и постановка
0%

Машинное обучение: карта трека, типы задач и постановка

Машинное обучение: карта трека, типы задач и постановка

Эта статья — вход в трек. Она не пересказывает пятнадцать последующих материалов, а даёт систему координат, без которой они превращаются в список библиотечных вызовов. После неё вы сможете про любую задачу ответить на четыре вопроса: чему именно учится модель, на каких данных, что мы минимизируем и как узнаем, что не обманываем себя. Практически все катастрофы в ML-проектах — это неверный ответ на один из этих четырёх вопросов, а вовсе не «взяли не тот градиентный бустинг».

1. Почему вообще нужно учиться по данным

Начнём с честного вопроса: зачем ML, если есть обычный код? Возьмём задачу «отличить спам от не-спама». Первое решение очевидно и не требует никакой математики — правила:

def is_spam(text: str) -> bool:
    # Ручные правила: работают ровно до тех пор, пока противник о них не узнал
    lowered = text.lower()
    if "виагра" in lowered:
        return True
    if lowered.count("!") > 5:
        return True
    return False

Такой код живёт неделю. Дальше происходит ровно три вещи. Спамеры пишут «в и а г р а», и правило рассыпается. Правил становится четыреста, они начинают противоречить друг другу, и никто не решается удалить ни одно из них. Появляется вторая страна с другим языком, и всю пирамиду надо строить заново.

Ключевое наблюдение: мы не умеем выписать правило, но умеем узнать ответ, когда видим пример. Разметить сто тысяч писем «спам / не спам» скучно, но выполнимо; выписать функцию, отделяющую одно от другого, — нет. Машинное обучение — это инженерный ответ именно на такую асимметрию: вместо программы мы пишем процедуру порождения программы из примеров. Классическая формулировка Тома Митчелла: программа обучается на опыте E относительно класса задач T и меры качества P, если её качество на задачах T, измеренное через P, растёт с накоплением опыта E (Mitchell, Machine Learning, 1997).

Отсюда сразу следует критерий применимости, который стоит применять до любого кода:

ML уместен, когда ML не нужен (и вреден), когда
правило существует, но его сложно выписать явно правило известно и стабильно — это if, а не модель
есть исторические данные с наблюдаемым исходом исход не наблюдается или наблюдается через годы
ошибки допустимы и стоят конечных денег цена единичной ошибки катастрофична и необъяснима
распределение данных меняется медленно правила меняются приказом каждый месяц
решение принимается часто, выигрыш масштабируется решение принимается пять раз в год — дешевле эксперт

Отдельно: ML не создаёт информацию, которой нет в данных. Если по имеющимся признакам два объекта неотличимы, а исходы у них разные, никакая модель их не разделит — это неустранимая (байесовская) ошибка. Половина проектов, которые «не взлетели из-за слабой модели», на самом деле упёрлись в отсутствие сигнала, и правильный ход был — идти собирать новые признаки, а не менять RandomForest на CatBoost.

2. Формальная постановка: риск, эмпирический риск, обобщение

Договоримся о языке — он единый для всего трека.

  • Объект x ∈ X — то, о чём принимаем решение (письмо, клиент, снимок). Обычно вектор признаков x ∈ ℝᵈ.
  • Ответ (таргет) y ∈ Y — то, что предсказываем. Y = ℝ — регрессия, Y = {0,1} — бинарная классификация.
  • Распределение P(x, y) — неизвестный источник данных. Мы видим лишь выборку S = {(xᵢ, yᵢ)}ᵢ₌₁ⁿ, предположительно независимую и одинаково распределённую (i.i.d.) из P.
  • Гипотеза h: X → Y из семейства H (все линейные функции, все деревья глубины ≤ 6, все сети данной архитектуры). H — это и есть «что модель в принципе способна выразить».
  • Функция потерь L(y, ŷ) ≥ 0 — цена одной ошибки. Квадратичная (y − ŷ)², абсолютная |y − ŷ|, логистическая −[y·log p + (1−y)·log(1−p)].

Цель — минимизировать риск (ожидаемые потери на всём распределении, включая примеры, которых мы никогда не видели):

R(h) = E_{(x,y) ~ P} [ L(y, h(x)) ]

Беда в том, что P неизвестно, и R(h) невычислим. Всё, что доступно, — эмпирический риск на выборке:

R̂(h) = (1/n) · Σᵢ L(yᵢ, h(xᵢ))

Метод обучения, минимизирующий по h ∈ H, называется минимизацией эмпирического риска (ERM). Почти всё в классическом ML — это ERM плюс регуляризатор: линейная регрессия, логистическая регрессия, SVM, бустинг, нейросети отличаются выбором H, L и способом оптимизации. Держите эту рамку в голове, читая статьи трека, — она склеивает их в одну картину.

Разложим ошибку на три слагаемых — это самая полезная схема для диагностики:

R(ĥ) − R* = [ R(h*) − R* ]   +   [ R(ĥ) − R(h*) ]
              ошибка аппроксимации      ошибка оценивания

где R* — байесовский риск (неустранимый шум), h* — лучшая гипотеза внутри H, ĥ — то, что реально нашёл алгоритм на конечной выборке. Первое слагаемое падает, если расширять H (брать более гибкие модели); второе слагаемое от этого растёт, потому что на конечной выборке легче случайно подогнаться. Это и есть компромисс смещение — разброс (bias-variance), которому целиком посвящена статья https://courses.digitable.life/post/machine-learning/11-overfitting-and-regularization/.

Кривая обобщения: ошибка на обучении падает монотонно, ошибка на отложенной выборке имеет минимум

Из картинки следуют два практических правила, которые нарушают чаще всего:

  1. Ошибка на обучающей выборке ничего не говорит о качестве модели. Модель «запомнить всю таблицу» имеет нулевую ошибку на train и бесполезна. Любая цифра, полученная на тех же данных, на которых шло обучение, — не оценка, а самообман.
  2. Минимум справа существует не всегда. Для сильно переопределённых моделей (большие нейросети) кривая валидации после пика может снова пойти вниз — эффект double descent (Belkin et al., 2019, arxiv.org/abs/1812.11118). Классическая U-образная картинка — про модели умеренной ёмкости, то есть про почти весь табличный ML.

И фундаментальное ограничение, известное как теорема об отсутствии бесплатных завтраков (Wolpert, 1996): усреднённо по всем возможным задачам все алгоритмы одинаковы. Работают они только потому, что реальные задачи не случайны — в них есть гладкость, локальность, иерархия. Выбор алгоритма — это выбор предположения о структуре мира, а не поиск «объективно лучшего». Отсюда следует, что вопрос «какая модель лучше?» без указания задачи и данных некорректен, а единственный ответ — эксперимент на вашей выборке.

3. Таксономия: какие вообще бывают задачи

Разберём по существу, а не по названиям.

Обучение с учителем (supervised). Есть пары (x, y) — известен правильный ответ. Девяносто процентов прикладных задач здесь. Внутри деление по типу Y:

  • Регрессия: Y = ℝ. Прогноз цены, времени доставки, потребления. Метрики — MAE, RMSE, MAPE. См. https://courses.digitable.life/post/machine-learning/03-linear-and-logistic-regression/.
  • Классификация: Y — конечное множество. Отток клиента, дефект на снимке, тема письма. Важнейший нюанс: модель почти всегда выдаёт вероятность, а не класс; превращение вероятности в решение — отдельный шаг с порогом, который выбирается по цене ошибок (https://courses.digitable.life/post/machine-learning/10-model-evaluation/).
  • Ранжирование: нужно упорядочить кандидатов, а не оценить каждого в отдельности. Метрики попарные и списочные (NDCG, MAP). Базис рекомендаций и поиска (https://courses.digitable.life/post/machine-learning/12-recommender-systems/).
  • Прогнозирование рядов: формально регрессия, но наблюдения зависимы во времени, и обычная кросс-валидация ломается (https://courses.digitable.life/post/machine-learning/13-time-series/).

Обучение без учителя (unsupervised). Есть только x. Модель ищет структуру: группы похожих объектов (https://courses.digitable.life/post/machine-learning/08-clustering/), низкоразмерное представление (https://courses.digitable.life/post/machine-learning/09-dimensionality-reduction/), редкие события. Главная сложность здесь не алгоритмическая, а оценочная: правильного ответа нет, поэтому «хорошесть» кластеризации приходится определять через внешнюю задачу или экспертизу. Никогда не запускайте кластеризацию, не сформулировав заранее, какое решение вы примете по её результату.

Self-supervised. Ответ конструируется из самих данных: предскажи следующее слово, закрытый кусок картинки, близость двух аугментаций одного объекта. Это то, на чём стоят современные языковые и визуальные модели — тема трека нейросетей (https://courses.digitable.life/post/neural-networks/00-overview/).

Обучение с подкреплением (RL). Нет фиксированной выборки: агент действует, среда отвечает наградой, а действия меняют будущие данные. Здесь возникают свои сущности — состояние, политика, отложенное вознаграждение (https://courses.digitable.life/post/machine-learning/14-reinforcement-learning/). Частный и очень практичный случай — многорукие бандиты для распределения трафика.

Причинность и uplift. Отдельный контур, который путают с классификацией чаще всего. Обычная модель отвечает на вопрос «кто уйдёт?», а бизнесу почти всегда нужен ответ на вопрос «кого удержит скидка?». Это разные величины: первая — P(y|x), вторая — разница P(y|x, воздействие) − P(y|x, без воздействия), которую нельзя получить из наблюдательных данных без эксперимента или сильных допущений. Правильный ответ на «кто уйдёт» и неправильная интерпретация стоили компаниям очень дорого; см. Pearl, The Book of Why и обзор uplift-моделирования в causalml.

4. Постановка задачи: путь от вопроса бизнеса к обучающей выборке

Самая дорогая работа в ML делается до первой строки кода. Схема ниже — рабочий чек-лист.

Четыре узла этой схемы разберём подробно, потому что именно они ломаются.

Что такое одна строка. Ответ неочевиден чаще, чем кажется. «Отток клиентов» — это строка на клиента, на клиента-месяц или на клиента-день? От выбора зависит всё: размер выборки, определение таргета, зависимость строк между собой и корректность разбиения. Строки «клиент-месяц» коррелируют внутри клиента, поэтому случайное разбиение раскидает один и тот же клиент в train и test, и оценка будет завышенной. Лечится группировкой (GroupKFold).

Момент t0 и горизонт. Модель в проде работает в момент t0 и имеет доступ ровно к тем данным, что существовали к t0. Таргет наблюдается позже — через горизонт H (уйдёт ли клиент в течение 30 дней). Значит, обучающая выборка должна собираться так же: признаки — срезом на t0, таргет — из окна (t0, t0+H]. Нарушение этого правила — самая частая и самая незаметная утечка целевой переменной (data leakage). Каноничный пример: признак «количество обращений в поддержку», посчитанный по всей истории, включая обращение, которым клиент сообщил об уходе. Модель показывает AUC 0.98 на валидации и 0.55 в проде. Подробный разбор видов утечек — https://courses.digitable.life/post/machine-learning/02-data-and-features/.

Метрика. Их всегда три уровня, и их нельзя смешивать:

Уровень Пример Кто смотрит Когда измеряется
Бизнес-метрика удержанная выручка, отток в % продукт, финансы недели, A/B-тест
Прокси / офлайн-метрика решения precision@k при бюджете 5000 звонков аналитик, DS сразу на holdout
Функция потерь при обучении logloss, MSE, pairwise-loss оптимизатор каждый шаг

Функция потерь оптимизируется, потому что она гладкая и дифференцируемая. Метрика решения — то, по чему выбирается модель и порог. Бизнес-метрика — то, ради чего всё затевалось. Классическая ошибка — выбирать модель по accuracy, когда решение принимается по топ-5% скоринга, или гнаться за AUC при том, что в проде важна калибровка вероятностей (если вероятность умножается на сумму убытка — она обязана быть настоящей вероятностью, см. https://courses.digitable.life/post/machine-learning/10-model-evaluation/).

Baseline. До любой модели зафиксируйте три числа: качество константы (среднее / самый частый класс), качество текущего правила, если оно есть, и качество простейшей модели (логистическая регрессия на пяти очевидных признаках). Без этого невозможно понять, много ли даёт «AUC 0.81». Половина запущенных в прод моделей проигрывала правилу «позвонить тем, у кого просрочка больше 30 дней», и никто не заметил, потому что правило не измеряли.

5. Данные и честная оценка

Обобщение проверяется только на данных, которые не участвовали ни в обучении, ни в выборе гиперпараметров, ни в отборе признаков. Отсюда трёхчастное разбиение и его вариации.

Три схемы разбиения выборки: hold-out, K-fold и разбиение по времени

Ключевые правила:

  • Test трогают один раз. Как только вы посмотрели на test и что-то поменяли — test стал валидацией, и оценка снова оптимистична. Это неформальный, но абсолютно реальный механизм переобучения «руками аналитика».
  • Схема разбиения должна повторять способ применения. Прод предсказывает будущее по прошлому — валидация обязана делать то же. Прод видит новых клиентов — валидация должна разделять по клиентам, а не по строкам.
  • Все преобразования учатся только на train. Среднее для заполнения пропусков, параметры масштабирования, словарь для target-encoding — всё считается внутри фолда. Именно поэтому в scikit-learn существует Pipeline: он гарантирует это структурно, а не силой воли.
  • Стратификация при дисбалансе. При 1% положительного класса случайное разбиение даёт фолды с сильно разной долей класса, и метрики скачут. StratifiedKFold решает вопрос.

Минимальный, но полностью корректный baseline на scikit-learn — шаблон, который стоит копировать в каждый новый проект:

import numpy as np
import pandas as pd
from sklearn.compose import ColumnTransformer
from sklearn.dummy import DummyClassifier
from sklearn.ensemble import HistGradientBoostingClassifier
from sklearn.impute import SimpleImputer
from sklearn.linear_model import LogisticRegression
from sklearn.metrics import average_precision_score, roc_auc_score
from sklearn.model_selection import StratifiedKFold, cross_val_score, train_test_split
from sklearn.pipeline import Pipeline
from sklearn.preprocessing import OneHotEncoder, StandardScaler

df = pd.read_parquet("churn_snapshot.parquet")      # признаки — срезом на t0
y = df.pop("churn_30d").to_numpy()                  # таргет — из окна (t0, t0+30 дней]

num_cols = df.select_dtypes(include="number").columns.tolist()
cat_cols = df.select_dtypes(include=["object", "category"]).columns.tolist()

# Все преобразования — ВНУТРИ пайплайна, иначе статистики протекут из валидации в обучение
prep = ColumnTransformer([
    ("num", Pipeline([
        ("impute", SimpleImputer(strategy="median")),
        ("scale", StandardScaler()),
    ]), num_cols),
    ("cat", Pipeline([
        ("impute", SimpleImputer(strategy="most_frequent")),
        # handle_unknown="ignore" — в проде обязательно появятся невиданные категории
        ("ohe", OneHotEncoder(handle_unknown="ignore", min_frequency=20)),
    ]), cat_cols),
])

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

models = {
    "константа": DummyClassifier(strategy="prior"),
    "логрегрессия": Pipeline([("prep", prep), ("clf", LogisticRegression(max_iter=1000, C=1.0))]),
    # Бустинг по гистограммам сам работает с пропусками и не требует масштабирования
    "бустинг": HistGradientBoostingClassifier(max_depth=6, learning_rate=0.06, max_iter=400),
}

cv = StratifiedKFold(n_splits=5, shuffle=True, random_state=42)
for name, model in models.items():
    # PR-AUC информативнее ROC-AUC при сильном дисбалансе классов
    scores = cross_val_score(model, X_train, y_train, cv=cv, scoring="average_precision")
    print(f"{name:14s} PR-AUC = {scores.mean():.3f} ± {scores.std():.3f}")

Замечание о дисперсии оценки: разброс ±0.02 при разнице моделей в 0.01 означает, что разницы нет. Сравнивать модели нужно по одним и тем же фолдам (парный тест), а не по независимым запускам, — иначе шум разбиения маскирует эффект.

6. ERM своими руками: что на самом деле делает fit

Чтобы формулы из раздела 2 перестали быть абстракцией, реализуем логистическую регрессию с нуля — это ровно ERM с логистической потерей и L2-регуляризатором, оптимизируемый градиентным спуском.

Псевдокод:

вход: X (n×d), y ∈ {0,1}^n, шаг η, регуляризация λ, число итераций T
w ← 0, b ← 0
повторить T раз:
    z ← X·w + b                       # линейные оценки
    p ← σ(z) = 1 / (1 + exp(−z))      # вероятности
    g_w ← (1/n)·Xᵀ·(p − y) + λ·w      # градиент logloss + L2
    g_b ← (1/n)·Σ(p − y)
    w ← w − η·g_w ;  b ← b − η·g_b
вернуть w, b
import numpy as np


def sigmoid(z: np.ndarray) -> np.ndarray:
    """Численно устойчивая сигмоида: exp не переполняется ни при каком знаке z."""
    out = np.empty_like(z, dtype=float)
    pos, neg = z >= 0, z < 0
    out[pos] = 1.0 / (1.0 + np.exp(-z[pos]))
    ez = np.exp(z[neg])
    out[neg] = ez / (1.0 + ez)
    return out


def fit_logreg(X: np.ndarray, y: np.ndarray, lr: float = 0.5,
               l2: float = 1e-3, epochs: int = 2000) -> tuple[np.ndarray, float]:
    n, d = X.shape
    w, b = np.zeros(d), 0.0
    for step in range(epochs):
        p = sigmoid(X @ w + b)
        residual = p - y                       # (p − y) — градиент logloss по z
        grad_w = X.T @ residual / n + l2 * w
        grad_b = residual.mean()
        w -= lr * grad_w
        b -= lr * grad_b
        if step % 500 == 0:
            eps = 1e-12                        # защита от log(0)
            loss = -np.mean(y * np.log(p + eps) + (1 - y) * np.log(1 - p + eps))
            print(f"эпоха {step:5d}  logloss = {loss + 0.5 * l2 * w @ w:.4f}")
    return w, b


rng = np.random.default_rng(0)
X = rng.normal(size=(4000, 3))
true_w = np.array([1.5, -2.0, 0.7])
y = (rng.uniform(size=4000) < sigmoid(X @ true_w - 0.3)).astype(float)

w, b = fit_logreg(X, y)
print("восстановленные веса:", np.round(w, 2), "смещение:", round(b, 2))

Сложность: одна итерация — O(n·d) по времени и O(d) дополнительной памяти, всего O(T·n·d). Отсюда сразу понятно, почему стохастический градиентный спуск (мини-батчи) выигрывает на больших n: он делает n/B шагов за ту же стоимость одного полного прохода и обычно сходится за 1–3 эпохи вместо тысяч итераций. Для сравнения: точное решение линейной регрессии через нормальные уравнения стоит O(n·d² + d³) — при d ≈ 10⁴ это уже неприемлемо, и итеративные методы становятся единственным вариантом.

Обратите внимание на две детали, которые в учебниках проскакивают мимо, а в проде стоят дней отладки: устойчивая сигмоида (наивная 1/(1+exp(-z)) переполняется при z ≈ −800 и даёт NaN в градиенте) и eps под логарифмом. Численная устойчивость — не педантизм, а причина, по которой существуют log_loss с клиппингом и logsumexp. Подробнее о математической подложке — https://courses.digitable.life/post/machine-learning/01-math-foundations/.

7. Как выбирать семейство моделей

Правило, которое экономит месяцы: начинайте с самой простой модели, которая может сработать, и усложняйте только при доказанной нехватке. Для табличных данных практическая последовательность такова: константа → логистическая или линейная регрессия → градиентный бустинг на деревьях → и только если бустинг явно упирается, всё остальное. Нейросети на табличных данных систематически не выигрывают у бустинга — это подтверждено аккуратными сравнениями (Grinsztajn et al., 2022, arxiv.org/abs/2207.08815).

Что стоит за координатами:

  • Логистическая регрессия остаётся стандартом там, где решение надо объяснять регулятору: коэффициенты имеют смысл, модель монотонна, калибровка хорошая из коробки (https://courses.digitable.life/post/machine-learning/03-linear-and-logistic-regression/).
  • kNN и наивный Байес — быстрые, почти без обучения, отличные baseline; kNN страдает от проклятия размерности, Байес — от предположения независимости (https://courses.digitable.life/post/machine-learning/04-knn-and-naive-bayes/).
  • SVM блистает на средних выборках с чётким зазором, но плохо масштабируется: ядровые методы требуют O(n²) памяти (https://courses.digitable.life/post/machine-learning/05-svm/).
  • Деревья интерпретируемы и не требуют масштабирования, но нестабильны — одна строка меняет всё дерево (https://courses.digitable.life/post/machine-learning/06-decision-trees/). Ровно эта нестабильность и делает их идеальным строительным блоком для ансамблей (https://courses.digitable.life/post/machine-learning/07-ensembles-and-boosting/).
  • Стекинг даёт последние доли процента ценой невозможности отладки и хрупкости в проде. На соревнованиях — всегда, в продакшене — почти никогда.

Приблизительные ориентиры по стоимости обучения (n — объекты, d — признаки, k — деревья/соседи/компоненты):

Метод Обучение Предсказание одного объекта Память
Линейная/логистическая регрессия (SGD) O(T·n·d) O(d) O(d)
kNN O(1) (хранение) O(n·d) или O(log n) с KD-деревом O(n·d)
Решающее дерево O(n·d·log n) O(глубина) O(число узлов)
Случайный лес (k деревьев) O(k·n·d·log n) O(k·глубина) O(k·узлов)
Бустинг по гистограммам O(k·(n + бины·d)) O(k·глубина) O(n + k·узлов)
SVM с ядром от O(n²·d) до O(n³·d) O(число опорных·d) O(n²)
k-means O(T·n·k·d) O(k·d) O(n·d)
PCA (полное SVD) O(n·d·min(n,d)) O(d·компонент) O(d²)

8. Модель в проде: не событие, а жизненный цикл

Обученная модель — это не конец, а начало эксплуатации. Файл с весами протухает, потому что мир меняется: меняется поведение пользователей (concept drift — меняется P(y|x)), меняется состав аудитории (covariate shift — меняется P(x)), ломается поставщик признака, и колонка молча заполняется нулями.

Три обязательных для прода вещи, которые чаще всего забывают:

  1. Теневой запуск. Модель считает предсказания на живом трафике, но на решения не влияет. Ловит ровно тот класс ошибок, который офлайн-оценка не видит принципиально: расхождение офлайн- и онлайн-признаков (training-serving skew), задержки, отсутствующие в бою поля.
  2. Мониторинг трёх слоёв. Распределения входных признаков (PSI, KS-статистика), распределение самих предсказаний (среднее предсказанной вероятности — самый ранний и дешёвый сигнал беды, доступный ещё до того, как станет известен факт) и бизнес-метрика с лагом.
  3. Воспроизводимость. Зафиксированы версия данных, версия кода, seed, версия признаков. Без этого фраза «перевыкатите модель прошлой недели» невыполнима. Всему этому посвящена https://courses.digitable.life/post/machine-learning/15-mlops/, а инфраструктуре данных под ней — трек https://courses.digitable.life/post/data-engineering/00-overview/.

Ещё одна особенность, отличающая ML-системы от обычного софта: обратная связь. Скоринг-модель решает, кому выдать кредит; данные о невозвратах приходят только по выданным кредитам; следующая модель обучается на выборке, которую сама же и отобрала. Это цензурирование данных, и без явных мер (случайный процент одобрений вне модели, inverse propensity weighting) система постепенно сходится к собственным предубеждениям. Тот же механизм в рекомендациях называется петлёй обратной связи и разбирается в https://courses.digitable.life/post/machine-learning/12-recommender-systems/. Классическое чтение по накопленной сложности таких систем — «Hidden Technical Debt in Machine Learning Systems» (Sculley et al., NeurIPS 2015, papers.nips.cc).

9. Типичные ошибки — по убыванию частоты

  1. Утечка целевой переменной. Признак, который в момент t0 физически не существовал. Симптом — подозрительно высокое качество. Проверка: для каждого признака ответьте, откуда он берётся в проде и с какой задержкой.
  2. Неправильная схема валидации. Случайное разбиение на временных данных или на данных с группами. Симптом — офлайн отлично, онлайн никак.
  3. Оценка на данных, использованных для отбора. Отобрали признаки по всей выборке, потом сделали CV. Отбор — часть обучения, он обязан быть внутри фолда.
  4. Accuracy при дисбалансе. При 1% положительных константа «всё отрицательно» даёт 99%. Смотрите PR-AUC, recall при фиксированном бюджете, матрицу ошибок.
  5. Оптимизация метрики вместо решения. Модель улучшила AUC на 0.01, но порог не пересчитали, и в проде ничего не изменилось.
  6. Отсутствие baseline. Невозможно понять, есть ли выигрыш вообще.
  7. Игнорирование дисперсии оценки. Выбор модели по разнице, лежащей внутри доверительного интервала, — выбор шума.
  8. Обучение на «почищенных» данных, применение на грязных. Выкинули строки с пропусками при обучении — в проде они никуда не делись.
  9. Дообучение препроцессинга на всей выборке. Классика: StandardScaler().fit(X) до разбиения.
  10. Модель без владельца. Через полгода никто не знает, кто её переобучает и что делать при деградации.

10. Как устроен трек

Порядок чтения и что забирать из каждой статьи:

Статья Зачем она вам
https://courses.digitable.life/post/machine-learning/01-math-foundations/ — Математика для ML векторы, градиенты, вероятности — язык всех остальных статей
https://courses.digitable.life/post/machine-learning/02-data-and-features/ — Данные и признаки 80% результата: кодирование, масштабирование, пропуски, утечки
https://courses.digitable.life/post/machine-learning/03-linear-and-logistic-regression/ — Регрессии базовая модель и интуиция про веса, вероятности, регуляризацию
https://courses.digitable.life/post/machine-learning/04-knn-and-naive-bayes/ — kNN и Байес метрики близости, проклятие размерности, генеративный подход
https://courses.digitable.life/post/machine-learning/05-svm/ — SVM зазор, опорные векторы, ядерный трюк как общая идея
https://courses.digitable.life/post/machine-learning/06-decision-trees/ — Деревья нелинейность без масштабирования, критерии разбиения
https://courses.digitable.life/post/machine-learning/07-ensembles-and-boosting/ — Ансамбли рабочая лошадь табличного ML: бэггинг, RF, бустинг
https://courses.digitable.life/post/machine-learning/08-clustering/ — Кластеризация структура без разметки и как её честно оценивать
https://courses.digitable.life/post/machine-learning/09-dimensionality-reduction/ — Снижение размерности PCA/SVD/t-SNE/UMAP, сжатие и визуализация
https://courses.digitable.life/post/machine-learning/10-model-evaluation/ — Оценка метрики, кросс-валидация, пороги, калибровка
https://courses.digitable.life/post/machine-learning/11-overfitting-and-regularization/ — Переобучение bias-variance, L1/L2, ранняя остановка
https://courses.digitable.life/post/machine-learning/12-recommender-systems/ — Рекомендации коллаборативная фильтрация, ранжирование, петли обратной связи
https://courses.digitable.life/post/machine-learning/13-time-series/ — Временные ряды зависимость во времени, ARIMA, признаки для бустинга
https://courses.digitable.life/post/machine-learning/14-reinforcement-learning/ — RL среда, политика, отложенная награда, бандиты
https://courses.digitable.life/post/machine-learning/15-mlops/ — MLOps воспроизводимость, деплой, мониторинг, переобучение

Если нужен только прикладной минимум для работы — читайте 02, 03, 07, 10, 11, 15. Это шесть статей, которые покрывают подавляющее большинство реальных табличных задач.

11. Источники, которым стоит доверять

Учебники (в порядке возрастания сложности):

  • Hastie, Tibshirani, Friedman. The Elements of Statistical Learning — канон классического ML, доступен бесплатно: hastie.su.domains/ElemStatLearn.
  • James et al. An Introduction to Statistical Learning — та же линия, но мягче и с кодом: statlearning.com.
  • Bishop. Pattern Recognition and Machine Learning — вероятностный взгляд, байесовская линия.
  • Shalev-Shwartz, Ben-David. Understanding Machine Learning: From Theory to Algorithms — теория обобщения и PAC-обучение строго: cs.huji.ac.il.
  • Murphy. Probabilistic Machine Learning — современный и очень полный: probml.github.io.

Практика и продакшн:

Мини-итог

  • ML нужен там, где правило существует, но не выписывается явно, а примеры доступны.
  • Формально почти всё обучение — минимизация эмпирического риска в выбранном классе гипотез плюс регуляризатор.
  • Ошибка раскладывается на неустранимый шум, ошибку аппроксимации и ошибку оценивания; борьба с одной обычно увеличивает другую.
  • Тип задачи определяется тем, что такое y и наблюдается ли он вообще, — и от этого зависит всё остальное.
  • Постановка (объект, таргет, t0, горизонт, метрика, разбиение) важнее выбора алгоритма.
  • Честная оценка требует данных, не участвовавших ни в обучении, ни в настройке; схема разбиения обязана повторять способ применения модели.
  • Модель в проде — жизненный цикл с дрейфом, мониторингом и переобучением, а не одноразовый артефакт.

Что дальше

Дальше — язык, на котором записано всё остальное: векторы и матрицы как способ говорить об объектах и признаках, производные и градиенты как механизм обучения, вероятности как способ выражать неуверенность.

Математика для ML: линейная алгебра, анализ, вероятности

Нашли неточность? Выделите фрагмент текста — рядом появится жучок.

Нужен разбор именно вашей ситуации?

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

Доска запросов