🔴 Сложный ⏱️ 50 минут

Случайные события

📋 Содержание урока

Случайные события 🎲

Ты дообучил классификатор, прогнал его на тесте и получил accuracy 0,91. Радуешься. Меняешь random_state=42 на random_state=1337, переобучаешь — и получаешь 0,87. Ничего в коде не поменялось: те же данные, та же архитектура, тот же оптимизатор. Поменялось только то, какими числами инициализировались веса и в каком порядке батчи легли в обучение. Четыре процентных пункта разницы взялись буквально из ниоткуда — из случайности.

И вот тут начинается настоящий машинный learning. Пока ты не умеешь говорить про случайность строго, у тебя нет ответа на самые базовые вопросы профессии. Насколько 0,91 отличается от 0,87 «по-настоящему»? Сколько нужно замеров, чтобы поверить, что модель А лучше модели Б? Почему honest-разбиение выборки обязано быть случайным, а не «первые 80% строк»? Почему dropout, который на первый взгляд просто ломает сеть, делает её лучше? Все эти вопросы — вероятностные, и все они начинаются с одного и того же фундамента: с описания того, что вообще может произойти в твоём эксперименте и какие из этих исходов тебя интересуют.

Этот урок — первый в разделе теории вероятностей, и он самый «скучный» на вид и самый несущий по сути. Мы не будем считать вероятности — числа появятся уже в следующем уроке. Здесь мы строим язык: что такое случайный эксперимент, что такое пространство элементарных исходов $\Omega$, почему событие — это ровно подмножество этого пространства, и как операции над событиями («и», «или», «не») превращаются в операции над множествами (пересечение, объединение, дополнение). Это тот самый слой, который в учебниках проскакивают за полстраницы, а потом полкурса мучаются, потому что люди путают «событие» с «числом».

Забегая вперёд: почти каждая метрика качества, которую ты видел — precision, recall, FPR, ROC-AUC, — это отношение количеств, посчитанных для конкретных событий вида «объект положительный и модель сказала положительный». Как только ты научишься аккуратно выписывать такие события через $\Omega$, все формулы метрик перестанут быть заклинаниями из документации и станут очевидными следствиями определений. Поехали.

🎯 Ты узнаешь:

  • Что такое случайный эксперимент и как для него строится пространство элементарных исходов $\Omega$ — и как выглядит $\Omega$ для задачи классификации
  • Почему событие — это подмножество $\Omega$, и как из этого автоматически получаются достоверное, невозможное и противоположное события
  • Как сумма, произведение и разность событий переводятся в объединение, пересечение и разность множеств — и почему диаграммы Эйлера—Венна экономят часы отладки логики
  • Что такое несовместные события и полная группа, и почему softmax — это буквально полная группа в коде
  • Что такое частота события, что такое статистическая устойчивость, и почему она — эмпирический фундамент всего, что ты делаешь с валидацией моделей

История: откуда это взялось?

Формально теория вероятностей началась с азартных игр — и это не легенда, а документированный факт. В 1654 году французский аристократ и заядлый игрок Антуан Гомбо, шевалье де Мере, столкнулся с задачей, которая ломала его интуицию. Он много лет успешно ставил на то, что при четырёх бросках одной кости выпадет хотя бы одна шестёрка, и выигрывал. Потом решил, что аналогичная ставка на «хотя бы одну пару шестёрок за 24 броска двух костей» тоже выгодна — ведь пропорция вроде бы та же. И начал стабильно проигрывать. Де Мере написал Блезу Паскалю, Паскаль обсудил задачу в переписке с Пьером Ферма, и из этой переписки лета—осени 1654 года выросла вся дисциплина. Ключевым в их решении было именно то, чем мы займёмся в этом уроке: они впервые аккуратно перечислили все возможные исходы и стали считать, сколько из них благоприятны. Не «на глазок», а как множество.

Дальше история двигалась рывками. Христиан Гюйгенс в 1657 году написал первый учебник — «De ratiociniis in ludo aleae» («О расчётах в азартной игре»), где ввёл понятие математического ожидания. Якоб Бернулли в посмертно изданной «Ars Conjectandi» (1713) доказал первую версию закона больших чисел — то самое утверждение, что частота события при росте числа испытаний стягивается к вероятности; мы к нему подойдём в уроке 242, но эмпирическую сторону этого факта обсудим уже сегодня. Пьер-Симон Лаплас в «Аналитической теории вероятностей» (1812) вывел дисциплину далеко за пределы игр — в астрономию, демографию, теорию ошибок измерений.

Но целых два столетия у теории была неприятная особенность: она отлично работала, при этом никто не мог внятно сказать, что такое вероятность. Определения ходили по кругу («равновозможные исходы» — а что такое «равновозможные», если не «равновероятные»?). Разрешил это в 1933 году Андрей Николаевич Колмогоров в работе «Grundbegriffe der Wahrscheinlichkeitsrechnung» («Основные понятия теории вероятностей»). Его ход был неожиданным и радикальным: он перестал спрашивать, что такое вероятность по сути, и вместо этого сказал — возьмём произвольное множество $\Omega$, назовём его исходами, возьмём семейство его подмножеств, назовём их событиями, и зададим на них функцию с тремя простыми свойствами. Всё. Теория вероятностей стала частью теории меры — раздела математики, который к тому моменту уже был построен Борелем и Лебегом.

Именно колмогоровская конструкция и лежит перед тобой в этом уроке. И именно она — причина, по которой современный ML вообще возможен как строгая дисциплина, а не как коллекция эвристик. Когда в статье пишут «пусть $(x, y) \sim \mathcal{D}$» — то есть «пара объект-ответ порождается распределением $\mathcal{D}$» — за этой строчкой стоит ровно та тройка $(\Omega, \mathcal{F}, P)$, которую Колмогоров описал в 1933-м. Мы разберём первые две буквы этой тройки прямо сейчас, а третья, $P$, начнётся со следующего урока.


Случайный эксперимент и пространство элементарных исходов

Интуиция

Представь, что ты запускаешь скрипт. Один и тот же скрипт, на одних и тех же входных данных, с одним и тем же кодом. Если он каждый раз выдаёт одно и то же — это детерминированный эксперимент, и вероятность тут ни при чём. А если результаты гуляют — на печать выходит то 0,91, то 0,87, то 0,89 — значит, где-то внутри есть источник неопределённости, и эксперимент случайный.

Ключевое слово тут — «повторяемость при неизменных условиях». Случайный эксперимент — это не «что-то непредсказуемое произошло один раз», а процедура, которую в принципе можно повторять сколько угодно раз, причём условия повторения ты фиксируешь, а результат всё равно меняется. Бросок монеты. Вытаскивание случайного объекта из датасета. Инициализация слоя нейросети. Прогон А/В-теста на новой когорте пользователей. Всё это — случайные эксперименты.

Определение: Случайный эксперимент (испытание, опыт) — это процедура, которая может быть повторена сколько угодно раз при неизменном комплексе условий и результат которой заранее однозначно не определён.

Теперь главный конструктивный шаг: прежде чем что-то считать, надо перечислить, что вообще может выйти. Причём перечислить так, чтобы варианты были неделимыми (не распадались на более мелкие) и взаимно исключающими (ровно один из них реализуется). Такие неделимые результаты и называются элементарными исходами, а их совокупность — пространством элементарных исходов.

Определение: Элементарный исход $\omega$ — неделимый взаимоисключающий результат случайного эксперимента. Пространство элементарных исходов $\Omega$ — множество всех элементарных исходов данного эксперимента.

Два требования к $\Omega$, которые нарушают чаще всего:

  • Полнота (исчерпывающность): в результате эксперимента обязательно реализуется хотя бы один $\omega \in \Omega$. Ничего «за пределами» $\Omega$ случиться не может.
  • Взаимоисключаемость: реализуется ровно один исход, два одновременно — нельзя.

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

Обрати внимание на важную тонкость: $\Omega$ не задан природой, его выбираешь ты. Один и тот же физический опыт можно описать разными пространствами, и от выбора зависит, какие вопросы ты сможешь задать. Бросили две кости. Если тебя интересует только сумма, можно взять $\Omega_1 = \{2, 3, 4, \dots, 12\}$ — 11 исходов. Если интересуют конкретные грани, берёшь $\Omega_2 = \{(i,j): i,j \in \{1,\dots,6\}\}$ — 36 исходов. Оба описания корректны. Но во втором можно спросить «выпал ли дубль?», а в первом — нет: информация про дубли в нём просто отсутствует. Правило-ориентир: $\Omega$ должно быть достаточно подробным, чтобы все интересующие тебя события в нём выражались. Ровно так же ты проектируешь схему логирования эксперимента: если не записал seed, ты потом не ответишь на вопрос «а что было с этим seed'ом».

Примеры с разбором

Пример 1 (простой): опиши $\Omega$ для двукратного подбрасывания монеты

Решение:

Шаг 1. Определим, что считать элементарным исходом. Один бросок даёт «орёл» ($О$) или «решка» ($Р$). Два броска — упорядоченная пара результатов, потому что первый и второй бросок различимы.

Шаг 2. Перечислим все пары:

$$\Omega = \{ОО,\ ОР,\ РО,\ РР\}$$

Шаг 3. Проверим два требования. Полнота: любой результат двух бросков — это одна из четырёх пар, других вариантов нет ✅. Взаимоисключаемость: реализоваться может ровно одна пара, $ОР$ и $РО$ одновременно невозможны ✅.

Шаг 4. Посчитаем мощность: $|\Omega| = 2 \cdot 2 = 4$.

Ответ: $\Omega = \{ОО, ОР, РО, РР\}$, $|\Omega| = 4$.

📌 Заметь, почему нельзя взять $\Omega = \{\text{«два орла», «орёл и решка», «две решки»}\}$ и считать эти три исхода равноправными. Формально это корректное разбиение результатов, но исход «орёл и решка» не элементарный — он склеен из двух ($ОР$ и $РО$). Именно на этой ошибке в XVIII веке спотыкался даже Даламбер.


Пример 2 (средний): случайно выбирается объект из тестовой выборки, модель бинарной классификации выдаёт по нему предсказание. Опиши $\Omega$

Решение:

Шаг 1. Поймём, что в этом эксперименте случайно. Случаен выбор объекта. Модель после обучения детерминирована: на конкретном объекте она всегда даст один и тот же ответ. Значит, вся случайность сидит в том, какой именно объект вытащили.

Шаг 2. Самое подробное описание — $\Omega = \{\text{все объекты тестовой выборки}\}$, то есть $\Omega = \{o_1, o_2, \dots, o_N\}$, где $N$ — размер теста. Здесь элементарный исход — конкретный объект.

Шаг 3. Но для разговора про метрики такая детализация избыточна. Нас интересуют только две вещи про объект: его истинный класс $y \in \{0, 1\}$ и предсказание модели $\hat{y} \in \{0, 1\}$. Огрубим пространство до пар:

$$\Omega = \{(y, \hat{y})\} = \{(0,0),\ (0,1),\ (1,0),\ (1,1)\}$$

Шаг 4. Проверим полноту и взаимоисключаемость. У каждого объекта ровно один истинный класс и ровно одно предсказание, значит, попадёт он ровно в одну пару ✅. И любой объект куда-то попадёт ✅.

Шаг 5. Опознаем эти четыре исхода — это буквально ячейки матрицы ошибок:

  • $(1,1)$ — истинно положительный, TP
  • $(0,0)$ — истинно отрицательный, TN
  • $(0,1)$ — ложноположительный, FP (модель сказала «да», а класс отрицательный)
  • $(1,0)$ — ложноотрицательный, FN (модель сказала «нет», а класс положительный)

Ответ: $\Omega = \{(0,0), (0,1), (1,0), (1,1)\}$, $|\Omega| = 4$; исходы — это в точности TN, FP, FN, TP.

Вот это и есть тот момент, ради которого стоило разбираться с $\Omega$. Матрица ошибок 2×2, которую все зубрят как таблицу, — это просто пространство элементарных исходов для эксперимента «взяли случайный объект и посмотрели, что сказала модель». Не таблица, а $\Omega$.


Пример 3 (сложный): опиши $\Omega$ для эксперимента «обучаем нейросеть со случайной инициализацией и случайным перемешиванием, замеряем accuracy на фиксированном тесте»

Решение:

Шаг 1. Найдём все источники случайности. Их три: (а) начальные веса $W_0$, (б) порядок перемешивания обучающих данных, (в) маски dropout на каждом шаге, если dropout включён. Тест зафиксирован, архитектура зафиксирована, гиперпараметры зафиксированы.

Шаг 2. Сформулируем «честное» $\Omega$: элементарный исход — это полный набор всех случайных решений за всё обучение,

$$\omega = (W_0,\ \pi_1, \pi_2, \dots, \pi_E,\ M_1, M_2, \dots, M_T),$$

где $\pi_e$ — перестановка выборки на эпохе $e$, а $M_t$ — dropout-маска на шаге $t$. Это пространство чудовищно большое: $W_0$ — вектор вещественных чисел, перестановок $N!$ штук на каждую эпоху, масок $2^{\text{(число нейронов)}}$ на каждый шаг.

Шаг 3. Заметим ключевое: accuracy — это функция от $\omega$. Один $\omega$ → одно обучение → одно число. Пишут $A = A(\omega)$. Такая функция «исход → число» называется случайной величиной, и ей будет посвящён урок 234; сейчас нам важно только, что она детерминированно определяется исходом.

Шаг 4. Практическое огрубление. Работать с исходным $\Omega$ невозможно, зато на практике весь $\omega$ порождается одним целым числом — random seed. Пайплайн устроен так: seed → генератор псевдослучайных чисел → все веса, перестановки и маски. Поэтому рабочее пространство:

$$\Omega_{\text{практ}} = \{0, 1, 2, \dots, 2^{32}-1\}$$

— множество допустимых seed'ов. Это конечное пространство, и accuracy на нём — обычная функция от seed'а.

Шаг 5. Проверим корректность огрубления. Полнота: любой запуск стартует с какого-то seed'а ✅. Взаимоисключаемость: seed один ✅. И самое главное — из $\omega$ (seed'а) результат восстанавливается однозначно, а это и есть определение воспроизводимости.

Ответ: строго $\Omega$ — множество всех наборов (начальные веса, перестановки, dropout-маски); практически — множество значений random seed, а accuracy есть функция от элементарного исхода.

📌 Отсюда сразу следует профессиональный вывод: единственный замер accuracy — это одно наблюдение одного элементарного исхода. Сравнивать две модели по одному запуску — то же самое, что сравнивать две монеты по одному броску каждой. В статьях по этой причине пишут «5 seeds, mean ± std», и теперь ты понимаешь, что это не ритуал, а прямое следствие структуры $\Omega$.

Почему это важно

Пока $\Omega$ не выписано, любой разговор о вероятности бессодержателен: вопрос «какова вероятность события $A$?» не имеет смысла, если не сказано, из какого множества исходов вырезается $A$. Классические парадоксы теории вероятностей — от парадокса Бертрана до задачи Монти Холла — почти все сводятся к тому, что спорщики молча используют разные $\Omega$ и потом удивляются разным ответам.

В ML эта дисциплина проявляется даже жёстче. «Какова вероятность, что модель ошибётся?» — вопрос неполный, пока не сказано: на объекте из тестовой выборки? из продакшн-трафика следующего месяца? при усреднении по случайным инициализациям? Это три разных $\Omega$ и три разных числа. Половина споров про «модель деградировала в проде» — это на самом деле смена пространства элементарных исходов, которую никто не заметил (в теории это называется distribution shift). Привычка сначала выписывать $\Omega$, а потом считать — самая дешёвая страховка от таких споров.


Событие: подмножество, а не число

Интуиция

Ты выписал $\Omega$ — все возможные исходы. Но интересуют тебя обычно не отдельные исходы, а вопросы с ответом «да/нет»: «выпало чётное число?», «модель ошиблась?», «в батче есть хотя бы один объект редкого класса?». Каждый такой вопрос делит $\Omega$ на две части: исходы, при которых ответ «да», и исходы, при которых ответ «нет». Первая часть и есть событие.

Отсюда — центральная идея всего урока, которую стоит вбить намертво: событие — это множество исходов, а не число и не «то, что случилось». Событие $A$ = «выпало чётное число очков» — это подмножество $\{2, 4, 6\} \subset \Omega = \{1,\dots,6\}$. Событие «модель ошиблась» — это подмножество $\{(0,1), (1,0)\} \subset \Omega$. Число (вероятность) появится потом, как мера этого множества.

Говорят, что событие $A$ произошло (наступило), если реализовавшийся элементарный исход $\omega$ принадлежит $A$. Формально: $A$ наступило $\iff \omega \in A$. Всё, это вся семантика.

Определение: Случайным событием называется любое подмножество $A \subseteq \Omega$ пространства элементарных исходов. Событие $A$ наступило в данном испытании, если реализовавшийся исход $\omega$ принадлежит $A$.

Полезно сразу почувствовать масштаб: если $|\Omega| = n$, то различных событий ровно $2^n$ — столько же, сколько подмножеств у $n$-элементного множества. Для одной кости ($n=6$) это 64 события. Для матрицы ошибок ($n=4$) — 16 событий, и все они осмысленны: «модель сказала 1» $=\{(0,1),(1,1)\}$, «объект положительный» $=\{(1,0),(1,1)\}$, «модель права» $=\{(0,0),(1,1)\}$ и так далее.

Два подмножества стоят особняком — самое большое и самое маленькое.

Определение: Событие $\Omega$ (всё пространство целиком) называется достоверным: оно наступает при любом исходе. Событие $\varnothing$ (пустое множество) называется невозможным: оно не наступает никогда.

И ещё одна конструкция, которая в ML используется буквально в каждой второй выкладке — противоположное событие.

Определение: Противоположным (дополнительным) к событию $A$ называется событие $\bar{A} = \Omega \setminus A$, состоящее из всех исходов, при которых $A$ не наступает. Всегда верно: $A \cup \bar{A} = \Omega$ и $A \cap \bar{A} = \varnothing$.

Обозначения $\bar{A}$, $A^c$, $\lnot A$ означают одно и то же. Приём «перейти к противоположному» — главный вычислительный трюк новичка: событие «хотя бы один» почти всегда считать тяжело в лоб и легко через дополнение «ни одного».

Примеры с разбором

Пример 4 (простой): бросок кости, $\Omega = \{1,2,3,4,5,6\}$. Выпиши как подмножества события $A$ = «выпало чётное», $B$ = «выпало больше 4», $\bar{B}$, а также приведи пример достоверного и невозможного события

Решение:

Шаг 1. $A$: перебираем исходы и оставляем те, где число чётное: $2, 4, 6$. Значит $A = \{2, 4, 6\}$, $|A| = 3$.

Шаг 2. $B$: строго больше четырёх — это $5$ и $6$. Значит $B = \{5, 6\}$, $|B| = 2$.

Шаг 3. $\bar{B} = \Omega \setminus B = \{1, 2, 3, 4\}$. Проверим: $B \cup \bar{B} = \{1,2,3,4,5,6\} = \Omega$ ✅, $B \cap \bar{B} = \varnothing$ ✅.

Шаг 4. Достоверное: «выпало число от 1 до 6» $=\{1,2,3,4,5,6\} = \Omega$. Невозможное: «выпало 7» $= \varnothing$.

Ответ: $A = \{2,4,6\}$, $B = \{5,6\}$, $\bar{B} = \{1,2,3,4\}$; достоверное — $\Omega$, невозможное — $\varnothing$.


Пример 5 (средний): для $\Omega = \{(0,0),(0,1),(1,0),(1,1)\}$ (пары «истинный класс, предсказание») выпиши события «модель ошиблась», «модель предсказала положительный класс», «объект положительный», и найди противоположное к первому

Решение:

Шаг 1. $E$ = «модель ошиблась» — это исходы, где $y \neq \hat{y}$. Перебираем: $(0,0)$ — совпало, нет; $(0,1)$ — не совпало, да; $(1,0)$ — не совпало, да; $(1,1)$ — совпало, нет.

$$E = \{(0,1),\ (1,0)\} = \{\text{FP}, \text{FN}\}$$

Шаг 2. $P$ = «модель предсказала 1» — второй компонент равен 1: $(0,1)$ и $(1,1)$.

$$P = \{(0,1),\ (1,1)\} = \{\text{FP}, \text{TP}\}$$

Шаг 3. $Y$ = «объект положительный» — первый компонент равен 1: $(1,0)$ и $(1,1)$.

$$Y = \{(1,0),\ (1,1)\} = \{\text{FN}, \text{TP}\}$$

Шаг 4. $\bar{E} = \Omega \setminus E = \{(0,0), (1,1)\} = \{\text{TN}, \text{TP}\}$ — это событие «модель права».

Проверим себя на смысл: accuracy — это доля исходов из $\bar{E}$, то есть $\dfrac{TP + TN}{N}$ ✅ — ровно каноническая формула. Precision — доля правильных среди $P$, то есть $\dfrac{TP}{TP+FP}$ ✅. Recall — доля пойманных среди $Y$: $\dfrac{TP}{TP+FN}$ ✅.

Ответ: $E = \{\text{FP},\text{FN}\}$, $P = \{\text{FP},\text{TP}\}$, $Y = \{\text{FN},\text{TP}\}$, $\bar{E} = \{\text{TN},\text{TP}\}$.

Смотри, что получилось: precision и recall — это одна и та же «сердцевина» $Y \cap P = \{TP\}$, поделённая на два разных знаменателя. Precision делит на $P$ (то, что модель назвала положительным), recall — на $Y$ (то, что положительно на самом деле). Больше не нужно запоминать формулы: достаточно помнить, какое множество в знаменателе.


Пример 6 (сложный): из датасета с двумя классами случайно берут батч из 3 объектов (с возвращением). Опиши $\Omega$, выпиши событие $H$ = «в батче есть хотя бы один объект редкого класса» и его противоположное. Сколько исходов в каждом?

Решение:

Шаг 1. Обозначим классы: $r$ — редкий, $c$ — частый. Элементарный исход — упорядоченная тройка, потому что позиции в батче различимы (первый элемент, второй, третий):

$$\Omega = \{(a_1,a_2,a_3): a_i \in \{r, c\}\}$$

Шаг 2. Мощность: на каждой из трёх позиций 2 варианта, значит $|\Omega| = 2^3 = 8$. Перечислим:

$$\Omega = \{ccc,\ ccr,\ crc,\ crr,\ rcc,\ rcr,\ rrc,\ rrr\}$$

Шаг 3. Событие $H$ = «есть хотя бы один $r$». Считать в лоб — значит перебрать исходы с одним, двумя и тремя $r$. Пойдём умнее: сначала найдём противоположное.

Шаг 4. $\bar{H}$ = «ни одного $r$» = «все три объекта частого класса» $= \{ccc\}$. Ровно один исход, $|\bar{H}| = 1$.

Шаг 5. Тогда $H = \Omega \setminus \bar{H}$, и $|H| = 8 - 1 = 7$:

$$H = \{ccr,\ crc,\ crr,\ rcc,\ rcr,\ rrc,\ rrr\}$$

Проверим прямым перебором: с одним $r$ — три исхода ($ccr, crc, rcc$); с двумя — три ($crr, rcr, rrc$); с тремя — один ($rrr$). Итого $3+3+1 = 7$ ✅.

Ответ: $|\Omega| = 8$; $|H| = 7$, $|\bar{H}| = 1$, $\bar{H} = \{ccc\}$.

📌 Это шаблон, который ты будешь использовать постоянно. «Хотя бы один» в лоб требует перебора нескольких случаев, через дополнение — одного. Практическая версия этого рассуждения: «какой размер батча нужен, чтобы в нём почти наверняка был хотя бы один объект редкого класса?» — считается ровно через $\bar{H}$ = «весь батч из частого класса». Числа мы подставим в уроках 227 и 233, схема — уже здесь.

Почему это важно

Отождествление «событие = подмножество» — не педантизм, а рабочий инструмент. Как только событие стало множеством, к нему применим весь аппарат теории множеств: включения, объединения, законы де Моргана, диаграммы. Дальше вероятность определяется как функция на этих множествах, и все её свойства наследуют структуру множеств: если $A \subseteq B$, то $P(A) \leq P(B)$ просто потому, что меньшее множество не может иметь бо́льшую меру.

В ML это даёт неожиданно много. Любая метрика — это счётчик исходов, попавших в конкретное подмножество $\Omega$. Любой фильтр в SQL-запросе к логам («покажи запросы, где модель ответила класс 3, а разметчик поставил класс 1») — это выделение события. Любое обсуждение «в каких случаях модель ломается» — это поиск подмножества $\Omega$ с высокой долей исхода «ошибка». Ты и так всю жизнь работаешь с событиями, просто теперь у них появилось имя и математика.


Операции над событиями: «или», «и», «но не»

Интуиция

Реальные вопросы редко бывают простыми. Обычно они звучат так: «модель ошиблась или уверенность была ниже 0,6», «объект из редкого класса и попал в валидацию», «попал в трейн, но не попал в валидацию». Это три логические связки — «или», «и», «не» — и каждой из них соответствует ровно одна операция над множествами. Причём соответствие настолько прямое, что после десяти минут привыкания ты перестанешь их различать.

Держи словарь-переводчик, который стоит выписать на бумажку и повесить перед глазами:

  • «$A$ или $B$» (наступило хотя бы одно) → сумма событий $A + B$, она же объединение $A \cup B$
  • «$A$ и $B$» (наступили оба сразу) → произведение событий $A \cdot B$, оно же пересечение $A \cap B$
  • «$A$, но не $B$» → разность $A \setminus B$, она же $A \cap \bar{B}$
  • «не $A$» → дополнение $\bar{A} = \Omega \setminus A$

Обозначения $A+B$ и $A \cup B$ (соответственно $AB$ и $A \cap B$) абсолютно равноправны; «сумма/произведение» — старая вероятностная традиция, «объединение/пересечение» — теоретико-множественная. В ML-литературе на английском ты встретишь только вторую нотацию, в русских учебниках — обе.

Определение: Суммой событий $A$ и $B$ называется событие $A \cup B$, состоящее из исходов, принадлежащих $A$ или $B$ (или обоим сразу). Произведением называется событие $A \cap B$, состоящее из исходов, принадлежащих и $A$, и $B$ одновременно. Разностью называется событие $A \setminus B$, состоящее из исходов, принадлежащих $A$, но не принадлежащих $B$.

Одна ловушка русского языка, о которой надо знать сразу: математическое «или» — включающее. «$A$ или $B$» истинно и тогда, когда произошло только $A$, и когда только $B$, и когда оба сразу. Бытовое «или» часто исключающее («чай или кофе» обычно значит «что-то одно»). Если тебе нужно именно исключающее «или» — «ровно одно из двух», — это отдельное событие $(A \setminus B) \cup (B \setminus A)$, симметрическая разность. В коде она же XOR.

Свойства операций — те же, что у множеств, и их полезно знать в лицо:

  • Коммутативность: $A \cup B = B \cup A$, $A \cap B = B \cap A$
  • Ассоциативность: $(A \cup B) \cup C = A \cup (B \cup C)$
  • Дистрибутивность: $A \cap (B \cup C) = (A \cap B) \cup (A \cap C)$ и $A \cup (B \cap C) = (A \cup B) \cap (A \cup C)$
  • Законы де Моргана: $\overline{A \cup B} = \bar{A} \cap \bar{B}$ и $\overline{A \cap B} = \bar{A} \cup \bar{B}$
  • Поглощение: $A \cup \Omega = \Omega$, $A \cap \Omega = A$, $A \cup \varnothing = A$, $A \cap \varnothing = \varnothing$
  • Идемпотентность: $A \cup A = A$, $A \cap A = A$

Законы де Моргана словами звучат так: «не (хотя бы одно) = ни одного» и «не (оба) = хотя бы одного нет». Первый — тот самый переход, который мы использовали в примере 6 с батчем. Второй — рабочая лошадка при разборе условий вида «система упала, потому что не все реплики живы».

Самый быстрый способ проверить любое тождество — диаграмма Эйлера—Венна: рисуешь прямоугольник $\Omega$, внутри два-три пересекающихся круга и заштриховываешь области. Для трёх событий картинка распадается на 8 областей (по числу подмножеств множества $\{A,B,C\}$), и любое тождество проверяется сравнением закрашенных областей. Для программиста есть эквивалент ещё быстрее: сравнить таблицы истинности из строк по нулям и единицам — те же 8 строк.

Примеры с разбором

Пример 7 (простой): бросок кости. $A = \{2,4,6\}$ (чётное), $B = \{5,6\}$ (больше 4). Найди $A \cup B$, $A \cap B$, $A \setminus B$, $B \setminus A$

Решение:

Шаг 1. $A \cup B$ — собираем все элементы из обоих множеств без повторов: $\{2,4,6\} \cup \{5,6\} = \{2,4,5,6\}$.

Шаг 2. $A \cap B$ — оставляем только общие: в $A$ есть 6, в $B$ есть 6 — оставляем; 2 и 4 в $B$ нет; 5 в $A$ нет. Итог: $\{6\}$.

Шаг 3. $A \setminus B$ — из $A$ выбрасываем всё, что есть в $B$: $\{2,4,6\} \setminus \{5,6\} = \{2,4\}$.

Шаг 4. $B \setminus A = \{5,6\} \setminus \{2,4,6\} = \{5\}$.

Проверка счётом: $|A \cup B| = |A| + |B| - |A \cap B| = 3 + 2 - 1 = 4$ ✅ (в $\{2,4,5,6\}$ действительно 4 элемента). Это формула включений-исключений — тот же принцип, который в следующем уроке даст теорему сложения вероятностей.

Ответ: $A \cup B = \{2,4,5,6\}$, $A \cap B = \{6\}$, $A \setminus B = \{2,4\}$, $B \setminus A = \{5\}$.

📌 Обрати внимание: $A \setminus B \neq B \setminus A$. Разность событий, в отличие от суммы и произведения, некоммутативна — путать порядок нельзя.


Пример 8 (средний): для матрицы ошибок $\Omega = \{TN, FP, FN, TP\}$ заданы события $Y$ = «объект положительный» $=\{FN, TP\}$ и $P$ = «модель сказала положительный» $=\{FP, TP\}$. Вырази через операции над $Y$ и $P$ события: TP, FP, FN, TN

Решение:

Шаг 1. TP — объект положительный и модель сказала «положительный». Связка «и» → пересечение:

$$\{TP\} = Y \cap P$$

Проверим: $\{FN,TP\} \cap \{FP,TP\} = \{TP\}$ ✅.

Шаг 2. FP — модель сказала «положительный», но объект не положительный. Связка «но не» → разность:

$$\{FP\} = P \setminus Y = P \cap \bar{Y}$$

Проверим: $\bar{Y} = \{TN, FP\}$, тогда $\{FP,TP\} \cap \{TN,FP\} = \{FP\}$ ✅.

Шаг 3. FN — объект положительный, но модель этого не сказала:

$$\{FN\} = Y \setminus P = Y \cap \bar{P}$$

Проверим: $\bar{P} = \{TN, FN\}$, тогда $\{FN,TP\} \cap \{TN,FN\} = \{FN\}$ ✅.

Шаг 4. TN — ни то, ни другое: объект не положительный и модель не сказала «положительный»:

$$\{TN\} = \bar{Y} \cap \bar{P} = \overline{Y \cup P}$$

Второе равенство — закон де Моргана. Проверим напрямую: $Y \cup P = \{FN, TP, FP\}$, дополнение $= \{TN\}$ ✅.

Шаг 5. Соберём вывод: четыре ячейки матрицы ошибок — это четыре области диаграммы Венна для двух событий $Y$ и $P$. Ровно четыре, потому что два события разбивают $\Omega$ на $2^2 = 4$ куска.

Ответ: $TP = Y \cap P$, $FP = P \setminus Y$, $FN = Y \setminus P$, $TN = \overline{Y \cup P}$.

Полезное следствие: событие «модель ошиблась» $= FP \cup FN = (P \setminus Y) \cup (Y \setminus P)$ — это симметрическая разность $Y$ и $P$, то есть XOR. Одной строчкой на numpy: errors = (y_true != y_pred). То есть код, который ты уже сто раз писал, и есть симметрическая разность событий.


Пример 9 (сложный): в ансамбле три модели. $A_i$ = «$i$-я модель ошиблась на данном объекте», $i = 1,2,3$. Вырази через $A_i$ события: (а) ансамбль-голосование большинством ошибся; (б) ошиблась ровно одна модель; (в) все модели правы. Упрости (в) по де Моргану

Решение:

Шаг 1. (а) Голосование большинством из трёх ошибается тогда, когда ошиблись минимум две модели — тогда неверный ответ соберёт 2 или 3 голоса против 1 или 0. Значит, надо перечислить все способы «ошиблись хотя бы две»:

$$M = (A_1 \cap A_2) \cup (A_1 \cap A_3) \cup (A_2 \cap A_3)$$

Шаг 2. Проверим, что тройная ошибка не потерялась. Если ошиблись все три, то $A_1 \cap A_2$ уже выполнено, значит, исход попал в объединение ✅. Отдельно дописывать $A_1 \cap A_2 \cap A_3$ не надо — оно уже внутри (объединение включающее).

Шаг 3. (б) «Ровно одна ошиблась» — значит, одна ошиблась, а две другие правы. Три взаимоисключающих варианта:

$$E_1 = (A_1 \cap \bar{A_2} \cap \bar{A_3}) \cup (\bar{A_1} \cap A_2 \cap \bar{A_3}) \cup (\bar{A_1} \cap \bar{A_2} \cap A_3)$$

Каждое слагаемое фиксирует, кто именно ошибся, и явно требует, чтобы остальные были правы. Без чёрточек над остальными получилось бы «хотя бы одна», а не «ровно одна» — это самая частая ошибка в таких выкладках.

Шаг 4. (в) «Все правы» — это пересечение дополнений:

$$C = \bar{A_1} \cap \bar{A_2} \cap \bar{A_3}$$

Шаг 5. Применим де Моргана: пересечение дополнений равно дополнению объединения,

$$C = \overline{A_1 \cup A_2 \cup A_3}$$

Словами: «все правы» = «не (хотя бы одна ошиблась)». Логично и проверяемо: если неверно, что хотя бы одна ошиблась, значит, не ошибся никто.

Шаг 6. Проверим на конкретном исходе. Пусть ошиблась только первая модель: $\omega \in A_1$, $\omega \notin A_2$, $\omega \notin A_3$. Тогда: $M$? Нужны две ошибки — нет, $\omega \notin M$ ✅ (большинство право, ансамбль угадал). $E_1$? Первое слагаемое выполнено — да, $\omega \in E_1$ ✅. $C$? Первая ошиблась — нет ✅.

Ответ: (а) $M = (A_1A_2) \cup (A_1A_3) \cup (A_2A_3)$; (б) $E_1 = A_1\bar{A_2}\bar{A_3} \cup \bar{A_1}A_2\bar{A_3} \cup \bar{A_1}\bar{A_2}A_3$; (в) $C = \bar{A_1}\bar{A_2}\bar{A_3} = \overline{A_1 \cup A_2 \cup A_3}$.

Именно эта выкладка объясняет, почему ансамбли работают. Ансамбль ошибается не когда ошибается модель, а когда ошибается большинство — событие $M$ существенно «меньше», чем каждое из $A_i$, если ошибки моделей не совпадают. Разнообразие моделей в бэггинге и random forest нужно ровно для того, чтобы пересечения $A_i \cap A_j$ были как можно тоньше.

Почему это важно

Операции над событиями — это то место, где «математика» и «код» смыкаются вплотную. Булев массив в numpy — это индикатор события; &, |, ~ — это пересечение, объединение, дополнение. Когда ты пишешь mask = (y_true == 1) & (y_pred == 0), ты буквально вычисляешь $Y \cap \bar{P}$ — событие FN. Когда фильтруешь логи «ошибка ИЛИ таймаут», ты строишь $A \cup B$.

А ещё именно на операциях держатся все теоремы следующих уроков. Теорема сложения (урок 229) отвечает на вопрос «чему равна вероятность $A \cup B$», теорема умножения — «чему равна вероятность $A \cap B$», условная вероятность (урок 230) — «как меняется взгляд на $A$, если известно, что $B$ произошло». Все три опираются на то, что $A \cup B$, $A \cap B$ и $A \setminus B$ определены как множества. Сначала множества, потом числа — порядок именно такой.


Совместные, несовместные события и полная группа

Интуиция

Два события называются несовместными, если они не могут произойти одновременно. Формально это значит, что у них нет общих исходов: $A \cap B = \varnothing$. На диаграмме Венна — два круга, которые не касаются.

Определение: События $A$ и $B$ называются несовместными, если их совместное наступление невозможно, то есть $A \cap B = \varnothing$. Иначе события называются совместными.

Различие практически важное: для несовместных событий счёт становится проще, потому что не надо бояться двойного учёта. Если $A$ и $B$ несовместны, то $|A \cup B| = |A| + |B|$; если совместны — $|A \cup B| = |A| + |B| - |A \cap B|$, и «минус пересечение» как раз убирает исходы, посчитанные дважды. В следующих уроках это станет теоремой сложения вероятностей в двух версиях, но логика ровно та же и она уже понятна тебе на уровне множеств.

Осторожно с распространённой путаницей: несовместность — это не независимость. Более того, они почти противоположны по смыслу. Несовместность значит «если случилось одно, второе точно не случилось» — это максимально сильная зависимость. Независимость (её формально введут в уроке 229) значит «знание об одном ничего не говорит о другом». Два разных класса объекта — несовместны. Два броска монеты — независимы. Путать их — классика.

Теперь укрупним конструкцию. Часто нужен не один вопрос «да/нет», а полное разбиение всех возможностей на варианты: объект принадлежит классу 1, или классу 2, ..., или классу $K$. Такой набор называется полной группой.

Определение: События $H_1, H_2, \dots, H_n$ образуют полную группу, если они попарно несовместны ($H_i \cap H_j = \varnothing$ при $i \neq j$) и в объединении дают всё пространство ($H_1 \cup H_2 \cup \dots \cup H_n = \Omega$). Такой набор ещё называют разбиением пространства $\Omega$.

Смысл: при любом испытании наступает ровно одно событие из полной группы — не меньше (потому что объединение покрывает $\Omega$) и не больше (потому что они попарно несовместны). Простейшая полная группа из двух элементов — это $\{A, \bar{A}\}$: событие и его противоположное всегда образуют полную группу.

Полные группы — не абстракция, а самая узнаваемая конструкция в ML. Метки классов в многоклассовой классификации образуют полную группу: у объекта ровно один класс. Выход softmax — вектор из $K$ чисел, которые неотрицательны и суммируются в единицу, — это распределение вероятностей на полной группе. Разбиение выборки на train/validation/test — тоже полная группа событий для случайно взятого объекта: он попадает ровно в одну часть, и три части покрывают всю выборку. Фолды в $k$-fold кросс-валидации — полная группа из $k$ элементов.

А вот multi-label классификация (объекту можно приписать несколько тегов сразу) — как раз пример, где события совместны и полной группы нет. Именно поэтому там на выходе не softmax, а $K$ независимых сигмоид, и суммы в единицу никто не требует. Разница «softmax vs sigmoid» — это ровно разница «полная группа vs совместные события», и теперь ты понимаешь её не как рецепт, а как математику.

Примеры с разбором

Пример 10 (простой): бросок кости. Проверь на совместность пары событий: (а) $A=\{2,4,6\}$ и $B=\{1,3,5\}$; (б) $A=\{2,4,6\}$ и $C=\{5,6\}$; (в) образует ли $\{A, B\}$ полную группу?

Решение:

Шаг 1. (а) Ищем общие элементы $A$ и $B$: в $A$ чётные, в $B$ нечётные — общих нет. $A \cap B = \varnothing$, события несовместны.

Шаг 2. (б) $A \cap C = \{2,4,6\} \cap \{5,6\} = \{6\} \neq \varnothing$ — события совместны (при выпадении шестёрки происходят оба).

Шаг 3. (в) Проверяем два условия полной группы. Попарная несовместность: уже показано в шаге 1 ✅. Покрытие: $A \cup B = \{2,4,6\} \cup \{1,3,5\} = \{1,2,3,4,5,6\} = \Omega$ ✅.

Шаг 4. Оба условия выполнены — да, полная группа. Более того, $B = \bar{A}$, а событие и его дополнение всегда образуют полную группу из двух элементов.

Ответ: (а) несовместны; (б) совместны; (в) да, $\{A, B\}$ — полная группа.


Пример 11 (средний): выборка из 10 000 объектов случайно делится на train (70%), validation (15%) и test (15%). Для случайно выбранного объекта рассмотрим события $T$ = «попал в train», $V$ = «в validation», $S$ = «в test». Образуют ли они полную группу? Что означает $\bar{T}$? Выполнено ли $|T| + |V| + |S| = |\Omega|$?

Решение:

Шаг 1. Проверим попарную несовместность. Корректное разбиение устроено так, что каждый объект попадает ровно в одну часть: $T \cap V = \varnothing$, $T \cap S = \varnothing$, $V \cap S = \varnothing$ ✅.

Шаг 2. Проверим покрытие: каждый объект попадает хоть куда-то, «бесхозных» объектов нет, значит $T \cup V \cup S = \Omega$ ✅.

Шаг 3. Оба условия выполнены — да, полная группа из трёх событий.

Шаг 4. $\bar{T} = \Omega \setminus T = V \cup S$ — «объект не в обучении», то есть «в валидации или в тесте». Это ровно те 30% данных, которые модель не видела при обучении.

Шаг 5. Так как события попарно несовместны, мощности складываются без поправок:

$$|T| + |V| + |S| = 7000 + 1500 + 1500 = 10\,000 = |\Omega| \ \checkmark$$

Ответ: да, полная группа; $\bar{T} = V \cup S$ — 3000 объектов; равенство мощностей выполнено, потому что события попарно несовместны.

📌 А теперь диагностический вопрос, который спасал не один проект: что будет, если в данных есть дубликаты и один и тот же объект попал и в train, и в test? Тогда $T \cap S \neq \varnothing$, полная группа ломается, и все выводы про «честную» оценку качества рушатся. Утечка данных (data leakage) на языке этого урока — это ровно нарушение несовместности событий разбиения. Проверять её надо не «на глазок», а как проверку $T \cap S = \varnothing$.


Пример 12 (сложный): многоклассовая классификация на $K$ классов. $C_k$ = «истинный класс объекта равен $k$», $\hat{C}_m$ = «модель предсказала класс $m$». Опиши структуру $\Omega$, покажи, что $\{C_k\}$ — полная группа, и вырази событие «модель ошиблась» двумя способами

Решение:

Шаг 1. Элементарный исход — пара «истинный класс, предсказанный класс»:

$$\Omega = \{(k, m):\ k, m \in \{1, 2, \dots, K\}\},\qquad |\Omega| = K^2$$

Это в точности $K \times K$ ячеек многоклассовой матрицы ошибок.

Шаг 2. Событие $C_k$ как подмножество — это целая строка матрицы: $C_k = \{(k, m): m = 1,\dots,K\}$, $|C_k| = K$.

Шаг 3. Проверим попарную несовместность $\{C_k\}$: если $k_1 \neq k_2$, то у исходов из $C_{k_1}$ первая координата $k_1$, у исходов из $C_{k_2}$ — $k_2$, совпасть они не могут. Значит $C_{k_1} \cap C_{k_2} = \varnothing$ ✅.

Шаг 4. Проверим покрытие: у любого исхода $(k,m)$ первая координата чему-то равна, значит он лежит в соответствующем $C_k$. Отсюда $\bigcup_{k=1}^{K} C_k = \Omega$ ✅. Полная группа подтверждена.

Шаг 5. Аналогично $\{\hat{C}_m\}_{m=1}^{K}$ — это столбцы матрицы, и они тоже образуют полную группу (по тем же двум проверкам).

Шаг 6. Событие «модель права» — это исходы, где $k = m$, то есть главная диагональ:

$$R = \bigcup_{k=1}^{K} (C_k \cap \hat{C}_k),\qquad |R| = K$$

Шаг 7. Отсюда «модель ошиблась» двумя способами. Через дополнение диагонали:

$$E = \bar{R} = \overline{\bigcup_{k=1}^{K} (C_k \cap \hat{C}_k)}$$

Через прямое перечисление недиагональных ячеек:

$$E = \bigcup_{k \neq m} (C_k \cap \hat{C}_m),\qquad |E| = K^2 - K = K(K-1)$$

Проверка при $K=2$: $|\Omega| = 4$ ✅ (наша матрица 2×2), $|R| = 2$ (TN и TP) ✅, $|E| = 2 \cdot 1 = 2$ (FP и FN) ✅ — полностью совпадает с примером 5.

Ответ: $|\Omega| = K^2$; $\{C_k\}$ и $\{\hat{C}_m\}$ — две полные группы (строки и столбцы); $E = \bar{R}$, $|E| = K(K-1)$.

Обрати внимание на красивую вещь: $\Omega$ здесь — это «решётка» из пересечений двух полных групп. Каждая ячейка $C_k \cap \hat{C}_m$ — элементарный исход. Именно так устроены все таблицы сопряжённости в статистике, и на этой конструкции позже вырастет критерий хи-квадрат (урок 248).

Почему это важно

Полная группа — это то, на что «вешается» распределение вероятностей. Как только у тебя есть разбиение $\Omega$ на $H_1,\dots,H_n$, ты можешь приписать каждому куску число, и эти числа обязаны в сумме давать единицу. Отсюда — softmax с его нормировкой, отсюда — все формулы полной вероятности (урок 231) и Байеса (урок 232), где сумма идёт «по гипотезам», то есть по элементам полной группы.

Понимание, совместны твои события или нет, экономит время каждый день. Если классы взаимоисключающие — бери softmax и cross-entropy. Если объекту можно приписать несколько меток — бери сигмоиды и binary cross-entropy по каждой метке. Если разбиение на фолды не образует полную группу (объекты пересекаются между фолдами) — результаты кросс-валидации завышены. Всё это одна и та же проверка: попарные пересечения пусты? объединение покрывает всё?


Частота события и статистическая устойчивость

Интуиция

До сих пор мы работали чисто логически: перечислили исходы, вырезали подмножества. Ни одного числа, кроме мощностей, не появилось. Но настоящая сила теории вероятностей — в предсказании того, как часто событие происходит. И здесь начинается эмпирика.

Проведём эксперимент $n$ раз. Пусть событие $A$ наступило $m$ раз. Число $m$ называют абсолютной частотой, а отношение $m/n$ — относительной частотой.

Определение: Абсолютной частотой события $A$ в серии из $n$ испытаний называется число $m$ испытаний, в которых $A$ наступило. Относительной частотой (частостью) называется отношение

$$W_n(A) = \frac{m}{n}$$

Всегда $0 \leq W_n(A) \leq 1$, причём $W_n(\varnothing) = 0$ и $W_n(\Omega) = 1$.

Ключевое слово — «в серии». Частота не свойство события, она свойство конкретной серии испытаний. Проведёшь другую серию — получишь другое число. Брось монету 10 раз — можешь получить 3 орла ($W = 0{,}3$), 5 орлов ($0{,}5$), 7 орлов ($0{,}7$). Разброс огромный.

А теперь главное наблюдение, ради которого вся дисциплина и существует. Если серию удлинять — 100 бросков, 1000, 100 000 — частота перестаёт скакать и начинает липнуть к одному числу. Она всё ещё колеблется, но амплитуда колебаний уменьшается. Это и называется статистической устойчивостью.

Определение: Статистическая устойчивость частот — эмпирически наблюдаемое свойство массовых случайных явлений: при увеличении числа испытаний $n$ относительная частота $W_n(A)$ колеблется около некоторого постоянного числа, и амплитуда этих колебаний убывает.

Это число, к которому «липнет» частота, и есть содержательный смысл вероятности $P(A)$. Строгая формулировка того, в каком именно смысле «липнет» (это не обычный предел из анализа! обычного предела там нет, есть сходимость по вероятности), — это закон больших чисел, урок 242. Сегодня достаточно эмпирической стороны: чем длиннее серия, тем надёжнее оценка.

Историческая иллюстрация, которую стоит запомнить: французский естествоиспытатель Жорж Бюффон в XVIII веке бросил монету 4040 раз и получил 2048 орлов, то есть $W = 0{,}5069$. Английский статистик Карл Пирсон бросал 24 000 раз и получил 12 012 орлов, $W = 0{,}5005$. Южноафриканский математик Джон Керрич, сидя в датском лагере для интернированных во время Второй мировой, бросил монету 10 000 раз и получил 5067 орлов, $W = 0{,}5067$. Никто не получил ровно 0,5 — и не мог получить. Но все получили что-то очень близкое, и чем длиннее серия, тем ближе.

Дальше — практическое правило, которое ты будешь использовать постоянно. Точность оценки частоты растёт не пропорционально $n$, а пропорционально $\sqrt{n}$. Типичное отклонение частоты от истинной вероятности имеет порядок

$$\sigma_{W} \approx \sqrt{\frac{p(1-p)}{n}}$$

Откуда это берётся — увидишь в уроке 238; сейчас важно следствие. Чтобы уменьшить погрешность вдвое, нужно увеличить выборку вчетверо. Отсюда суровая арифметика ML: на тесте из 100 объектов accuracy известна с точностью примерно $\pm 0{,}05$ (при $p \approx 0{,}9$: $\sqrt{0{,}9 \cdot 0{,}1/100} = 0{,}03$, а «две сигмы» — это $\pm 0{,}06$). То есть 0,91 против 0,87 на сотне объектов — вообще не разница, это шум. На тесте в 10 000 объектов та же величина даёт $\sigma \approx 0{,}003$, и разница в 4 пункта уже осмысленна.

Примеры с разбором

Пример 13 (простой): монету бросили 50 раз, орёл выпал 23 раза. Найди частоту орла и частоту решки, проверь их сумму

Решение:

Шаг 1. Частота орла: $W_{50}(О) = \dfrac{23}{50} = 0{,}46$.

Шаг 2. Решка выпала $50 - 23 = 27$ раз, значит $W_{50}(Р) = \dfrac{27}{50} = 0{,}54$.

Шаг 3. Сумма: $0{,}46 + 0{,}54 = 1$ ✅.

Шаг 4. Почему сумма обязана равняться единице? Потому что $\{О, Р\}$ — полная группа: ровно одно из двух наступает в каждом испытании, поэтому $m_О + m_Р = n$, и деление на $n$ даёт сумму частот 1.

Ответ: $W(О) = 0{,}46$, $W(Р) = 0{,}54$, сумма равна 1, что следует из того, что события образуют полную группу.


Пример 14 (средний): классификатор прогнали на тесте из 800 объектов, он ошибся на 96. Найди частоту ошибки и accuracy. Оцени, насколько надёжно это число, и на сколько объектов надо расширить тест, чтобы вдвое уменьшить погрешность

Решение:

Шаг 1. Частота ошибки: $W(E) = \dfrac{96}{800} = 0{,}12$.

Шаг 2. Accuracy — это частота противоположного события $\bar{E}$:

$$W(\bar{E}) = 1 - W(E) = 1 - 0{,}12 = 0{,}88$$

Проверим напрямую: правильных ответов $800 - 96 = 704$, и $704/800 = 0{,}88$ ✅.

Шаг 3. Оценим типичное отклонение. Подставим $p \approx 0{,}12$ (частота ошибки) и $n = 800$:

$$\sigma \approx \sqrt{\frac{0{,}12 \cdot 0{,}88}{800}} = \sqrt{\frac{0{,}1056}{800}} = \sqrt{0{,}000132} \approx 0{,}0115$$

Шаг 4. Значит, разумный «коридор» для истинной доли ошибок — примерно $0{,}12 \pm 2\sigma$, то есть от $0{,}097$ до $0{,}143$. В терминах accuracy: примерно от $0{,}857$ до $0{,}903$.

Шаг 5. Чтобы уменьшить $\sigma$ вдвое, нужно, чтобы $\sqrt{n}$ вырос вдвое, а значит $n$ вырос вчетверо:

$$n_{\text{нов}} = 4 \cdot 800 = 3200$$

Проверим: $\sqrt{0{,}1056/3200} = \sqrt{0{,}000033} \approx 0{,}00574$ — действительно примерно вдвое меньше, чем $0{,}0115$ ✅.

Ответ: $W(E) = 0{,}12$, accuracy $= 0{,}88$, $\sigma \approx 0{,}0115$; для двукратного уменьшения погрешности нужен тест из 3200 объектов.

📌 Отсюда честный вывод, который многим не нравится: заявление «моя модель дала 88,0%, а базовая 87,4%, значит моя лучше» на тесте из 800 объектов не выдерживает никакой критики. Разница 0,6 пункта втрое меньше одной сигмы. Хочешь ловить такие разницы — расти тест или бери парные сравнения на одних и тех же объектах.


Пример 15 (сложный): монету бросают сериями. Результаты: после 10 бросков 7 орлов; после 100 — 58; после 1000 — 519; после 10 000 — 5032. Посчитай частоты, отклонения от 0,5 и проверь, согласуется ли скорость их убывания с законом $1/\sqrt{n}$

Решение:

Шаг 1. Считаем частоты:

  • $n = 10$: $W = 7/10 = 0{,}700$
  • $n = 100$: $W = 58/100 = 0{,}580$
  • $n = 1000$: $W = 519/1000 = 0{,}519$
  • $n = 10\,000$: $W = 5032/10\,000 = 0{,}5032$

Шаг 2. Считаем модули отклонений от 0,5:

  • $n = 10$: $|0{,}700 - 0{,}5| = 0{,}200$
  • $n = 100$: $|0{,}580 - 0{,}5| = 0{,}080$
  • $n = 1000$: $|0{,}519 - 0{,}5| = 0{,}019$
  • $n = 10\,000$: $|0{,}5032 - 0{,}5| = 0{,}0032$

Шаг 3. Что предсказывает теория? Типичное отклонение $\sigma = \sqrt{0{,}25/n} = \dfrac{0{,}5}{\sqrt{n}}$:

  • $n = 10$: $0{,}5/3{,}16 \approx 0{,}158$
  • $n = 100$: $0{,}5/10 = 0{,}050$
  • $n = 1000$: $0{,}5/31{,}6 \approx 0{,}0158$
  • $n = 10\,000$: $0{,}5/100 = 0{,}005$

Шаг 4. Сравним наблюдённое с предсказанным: $0{,}200$ vs $0{,}158$; $0{,}080$ vs $0{,}050$; $0{,}019$ vs $0{,}0158$; $0{,}0032$ vs $0{,}005$. Все наблюдения того же порядка, что предсказание — от $0{,}6\sigma$ до $1{,}6\sigma$. Это ровно тот разброс, который и должен быть: отклонение не обязано равняться $\sigma$, оно «в среднем» такого размера.

Шаг 5. Проверим скорость убывания. При росте $n$ в 10 раз $\sqrt{n}$ растёт примерно в $3{,}16$ раза, значит отклонение должно падать примерно втрое. Наблюдаем: $0{,}200 \to 0{,}080$ (в 2,5 раза), $0{,}080 \to 0{,}019$ (в 4,2 раза), $0{,}019 \to 0{,}0032$ (в 5,9 раза). В среднем — да, порядка тройки, с естественным разбросом.

Шаг 6. Главный вывод для интерпретации: частота не сходится монотонно и никогда не «садится» ровно на 0,5. Она блуждает, но коридор блуждания сужается как $1/\sqrt{n}$.

Ответ: частоты $0{,}700 \to 0{,}580 \to 0{,}519 \to 0{,}5032$; отклонения $0{,}200 \to 0{,}080 \to 0{,}019 \to 0{,}0032$ — убывают согласованно с законом $1/\sqrt{n}$, статистическая устойчивость подтверждается.

Почему это важно

Вся практика оценки моделей — это работа с частотами. Accuracy, precision, recall, доля кликов в А/В-тесте, конверсия, процент отказов сервиса — всё это $m/n$ для конкретных событий. И у всех этих чисел есть общее свойство, о котором постоянно забывают: они сами случайны. Метрика, посчитанная на тесте, — это не «качество модели», а одна реализация частоты, вокруг которой есть коридор шириной порядка $\sqrt{p(1-p)/n}$.

Отсюда растут все профессиональные привычки: не сравнивать модели по третьему знаку после запятой; считать доверительные интервалы (урок 246); проверять статистические гипотезы перед выкаткой (урок 247); строить кросс-валидацию, чтобы усреднить по нескольким разбиениям; прогонять по нескольким seed'ам. Каждая из этих практик — способ побороть тот факт, что частота на конечной выборке шумит.


Случайность внутри ML: где именно она живёт

Интуиция

В обучении модели случайность не одна и не в одном месте. Полезно держать в голове карту: где именно вероятностный процесс встроен в пайплайн и какое $\Omega$ ему соответствует.

1. Порождение данных. Самое фундаментальное. Базовое допущение почти всего ML: пары $(x_i, y_i)$ порождаются независимо из одного и того же распределения $\mathcal{D}$ — это допущение i.i.d. (independent and identically distributed). Здесь элементарный исход — это целая обучающая выборка целиком, а $\Omega$ — множество всех выборок размера $N$, которые в принципе могли быть вытянуты.

2. Инициализация весов. Веса нейросети стартуют не с нулей (при нулевой инициализации все нейроны слоя получают одинаковые градиенты и остаются одинаковыми навсегда — сеть вырождается), а из случайного распределения. Схемы Хавьера (Glorot, 2010) и Хе (He, 2015) задают дисперсию инициализации так, чтобы сигнал не затухал и не взрывался при прохождении через слои. $\Omega$ здесь — множество всех допустимых стартовых матриц весов.

3. Перемешивание данных. Стохастический градиентный спуск работает по батчам, и порядок батчей влияет на траекторию оптимизации. Перемешивание перед каждой эпохой убирает артефакты исходного порядка (представь датасет, отсортированный по классам: без shuffle первые батчи будут состоять из одного класса, и градиенты будут тянуть модель в одну сторону). $\Omega$ — множество перестановок выборки.

4. Dropout. На каждом шаге обучения часть нейронов случайно «выключается» — с вероятностью $p$ выход нейрона зануляется. Каждый шаг обучает свою прореженную подсеть; на инференсе dropout выключают и масштабируют активации. $\Omega$ — множество бинарных масок.

5. Разбиение выборки. Train/val/test и фолды кросс-валидации формируются случайно, чтобы разбиение не коррелировало с содержательными свойствами данных.

6. Стохастические алгоритмы. Bootstrap в бэггинге (выборка с возвращением), случайный выбор подмножества признаков в random forest, инициализация центроидов в k-means, negative sampling в word2vec, аугментации изображений, температурное семплирование в языковых моделях.

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

Независимость наблюдений: главное допущение

Практически весь классический ML стоит на предположении, что наблюдения независимы. Формальное определение независимости появится в уроке 229, но содержательно оно означает: знание того, что произошло с одним объектом, не даёт информации о другом.

Зачем это нужно? Затем, что при независимости вероятность совместного наступления событий равна произведению вероятностей, а это превращает громоздкую совместную вероятность выборки в произведение простых множителей:

$$P(\text{выборка}) = \prod_{i=1}^{N} P(x_i, y_i)$$

Прологарифмировав, получаешь сумму — и это ровно та функция потерь, которую минимизирует твой оптимизатор. Cross-entropy loss — это минус логарифм правдоподобия при допущении независимости. MSE — то же самое при допущении независимых гауссовых шумов. Наивный байесовский классификатор назван «наивным» именно потому, что предполагает независимость признаков внутри объекта. Без независимости эти суммы не раскладываются, и никакого «сложи лоссы по батчу и подели на размер батча» не было бы.

И вот главный практический вывод: допущение независимости часто нарушено, и это ломает оценки качества сильнее, чем плохая архитектура. Классические ситуации:

  • Временные ряды. Значение сегодня коррелирует со вчерашним. Случайное перемешивание перед разбиением на train/test даёт утечку из будущего в прошлое, и метрика на тесте становится фантастически завышенной. Нужен разрез по времени, а не случайный.
  • Сгруппированные данные. Несколько фотографий одного пациента, несколько сессий одного пользователя, несколько кадров одного видео. Если разные записи одной группы попали в train и в test, модель «узнаёт» объект, а не решает задачу. Лечится GroupKFold — разбиением по группам, а не по строкам.
  • Дубликаты и почти-дубликаты. Частая беда в веб-скрейпленных датасетах: один и тот же текст в разных формулировках попадает и в обучение, и в тест.
  • Пространственная корреляция. Соседние участки в геоданных или спутниковых снимках похожи, случайное разбиение даёт утечку.

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

Seed и воспроизводимость

Вернёмся к тому, с чего начинали. Компьютер не умеет генерировать настоящую случайность: np.random.rand() вызывает детерминированный алгоритм — генератор псевдослучайных чисел (PRNG), например Mersenne Twister или PCG. Он берёт внутреннее состояние, преобразует его по фиксированной формуле и выдаёт следующее число. Задав начальное состояние — seed — ты полностью определяешь всю последовательность.

На языке этого урока: фиксация seed — это выбор конкретного элементарного исхода $\omega$ из $\Omega_{\text{практ}}$. И это даёт два разных инструмента, которые нельзя путать:

  • Фиксированный seed → воспроизводимость. Один и тот же результат при каждом запуске. Нужно для отладки, ревью, статей, регрессионных тестов, сравнения версий кода. Без этого нельзя понять, изменился результат из-за твоей правки или из-за шума.
  • Несколько разных seed'ов → оценка разброса. Прогнав обучение на 5–10 seed'ах, ты получаешь выборку значений метрики и можешь оценить среднее и стандартное отклонение. Только так можно честно сказать, что модель А лучше модели Б.

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

Практические детали, о которых стоит знать. В Python seed'ов обычно несколько независимых: random.seed() для стандартной библиотеки, np.random.seed() (лучше — отдельный Generator через np.random.default_rng(seed)), torch.manual_seed() для CPU и torch.cuda.manual_seed_all() для GPU. Плюс отдельно задаётся seed для DataLoader'а с несколькими воркерами. И даже при всём этом полная битовая воспроизводимость на GPU не гарантирована: некоторые CUDA-ядра недетерминированы из-за порядка суммирования при параллельной редукции — сложение чисел с плавающей точкой неассоциативно. Отсюда флаги вроде torch.use_deterministic_algorithms(True), которые ценой скорости дают строгую воспроизводимость.

Пример с разбором

Пример 16 (сложный, ML): модель обучили на 5 seed'ах, accuracy получилась 0,905; 0,882; 0,913; 0,897; 0,868. Опиши эксперимент в терминах $\Omega$, посчитай среднее и разброс, и ответь: можно ли считать, что модель лучше базовой с accuracy 0,890?

Решение:

Шаг 1. Опишем эксперимент. $\Omega$ = множество seed'ов; элементарный исход $\omega$ = конкретный seed; accuracy $A(\omega)$ — функция от исхода. У нас пять наблюдений этой функции.

Шаг 2. Среднее:

$$\bar{A} = \frac{0{,}905 + 0{,}882 + 0{,}913 + 0{,}897 + 0{,}868}{5} = \frac{4{,}465}{5} = 0{,}893$$

Шаг 3. Отклонения от среднего: $+0{,}012;\ -0{,}011;\ +0{,}020;\ +0{,}004;\ -0{,}025$.

Квадраты: $0{,}000144;\ 0{,}000121;\ 0{,}000400;\ 0{,}000016;\ 0{,}000625$. Сумма $= 0{,}001306$.

Шаг 4. Выборочная дисперсия (делим на $n-1 = 4$): $s^2 = 0{,}001306/4 = 0{,}0003265$. Стандартное отклонение:

$$s = \sqrt{0{,}0003265} \approx 0{,}0181$$

Шаг 5. Стандартная ошибка среднего: $s/\sqrt{5} = 0{,}0181/2{,}236 \approx 0{,}0081$.

Шаг 6. Сравним с базовой. Разница средних: $0{,}893 - 0{,}890 = 0{,}003$. Это в 2,7 раза меньше стандартной ошибки $0{,}0081$. То есть наблюдаемое превосходство полностью тонет в разбросе по seed'ам.

Шаг 7. Отдельно отметим: максимальное значение в серии — 0,913, и соблазн отчитаться именно им очень велик. Но 0,913 — это верхний хвост разброса, а не свойство модели. Отчитываться надо средним и разбросом: $0{,}893 \pm 0{,}018$.

Ответ: $\bar{A} = 0{,}893$, $s \approx 0{,}018$; разница с базовой (0,003) меньше стандартной ошибки среднего (0,008), значит преимущество не подтверждается — модели неразличимы на этих данных.

📌 Обрати внимание, что размах пяти значений — от 0,868 до 0,913 — это 4,5 процентных пункта. Внутри одной и той же модели, на одних и тех же данных. Именно поэтому «я улучшил accuracy на 1%» без указания числа seed'ов и разброса — не результат.

Почему это важно

Это тот раздел, который отличает инженера от человека, запускающего чужие ноутбуки. Понимание, где в пайплайне живёт случайность, даёт три практических умения: воспроизводить свои же результаты; корректно измерять улучшения; находить утечки данных, которые убивают проект на этапе продакшна. Всё это — прямое приложение того, что мы разбирали выше: описать $\Omega$, выделить нужное событие, посчитать частоту, оценить её надёжность.


Практика: 30 заданий

Базовые (задания 1-10)

Задание 1: Монету подбрасывают три раза. Опиши пространство элементарных исходов $\Omega$, найди $|\Omega|$ и выпиши событие $A$ = «выпало ровно два орла».

Задание 2: Бросают игральную кость. Выпиши как подмножества $\Omega = \{1,2,3,4,5,6\}$ события $A$ = «выпало число, кратное 3» и $B$ = «выпало число меньше 5». Найди их мощности.

Задание 3: Из чисел $\Omega = \{1, 2, \dots, 10\}$ случайно выбирают одно. $A$ = «выбрано чётное число». Найди $\bar{A}$ и проверь свойства противоположного события.

Задание 4: В $\Omega = \{1,2,3,4,5,6\}$ заданы $A = \{1,2,3,4\}$ и $B = \{3,4,5,6\}$. Найди $A \cup B$, $A \cap B$, $A \setminus B$, $B \setminus A$, $\overline{A \cup B}$.

Задание 5: Из колоды в 36 карт вынимают одну. Совместны ли события: (а) $A$ = «вынут туз» и $B$ = «вынута карта червовой масти»; (б) $C$ = «вынут туз» и $D$ = «вынут король»?

Задание 6: Бросают кость. Образуют ли полную группу события $A$ = «выпало меньше 3», $B$ = «выпало 3 или 4», $C$ = «выпало больше 4»?

Задание 7: Из 200 входящих писем спам-фильтр пометил 46 как спам. Найди относительную частоту события «письмо помечено как спам» и противоположного события.

Задание 8: В урне 5 белых шаров и ни одного шара другого цвета. Наугад вынимают 2 шара. Приведи пример достоверного и невозможного события для этого эксперимента.

Задание 9: Классификатор на тесте из 500 объектов дал: TP = 120, FP = 30, FN = 50, TN = 300. Проверь, что четыре исхода образуют полную группу, и найди частоты событий «модель предсказала положительный класс» и «модель ошиблась».

Задание 10: Пространство элементарных исходов содержит 5 исходов. Сколько всего различных событий можно задать в этом эксперименте? Сколько из них содержат заданный фиксированный исход $\omega_1$?

Средние (задания 11-20)

Задание 11: Бросают две игральные кости. Найди $|\Omega|$, выпиши события $A$ = «сумма очков равна 7» и $B$ = «выпал дубль», определи их совместность и найди $|A \cup B|$.

Задание 12: В $\Omega = \{1,2,\dots,8\}$ заданы $A = \{1,2,3,4\}$, $B = \{3,4,5,6\}$. Проверь оба закона де Моргана прямым вычислением.

Задание 13: Из датасета с редким и частым классом случайно (с возвращением) набирают батч из 5 объектов. Опиши $\Omega$ по составу классов, найди мощности событий: $H$ = «хотя бы один объект редкого класса», $O$ = «ровно один редкий», $D$ = «не менее двух редких».

Задание 14: Даны события $A$, $B$, $C$. Запиши через операции над событиями: (а) произошло только $A$; (б) произошло хотя бы два события; (в) произошло не более одного события.

Задание 15: Ансамбль из 5 моделей голосует большинством. $A_i$ = «$i$-я модель ошиблась». Сколько наборов ошибок (из всех возможных) приводят к ошибке ансамбля? Какую долю от $\Omega$ они составляют?

Задание 16: А/В-тест: вариант А показан 1200 раз, кликов 96; вариант B показан 1500 раз, кликов 135. Найди частоты кликов и оцени, отличаются ли варианты, зная, что типичное отклонение частоты равно $\sqrt{p(1-p)/n}$.

Задание 17: Датасет из 10 000 объектов разбили на train (8000) и test (2000). Проверка показала, что $|T \cup S| = 9850$. Что это означает? Найди $|T \cap S|$.

Задание 18: Многоклассовая классификация на $K = 4$ класса. Найди $|\Omega|$, мощность события «модель права», мощность события «модель ошиблась», а также $|C_2|$, $|\hat{C}_3|$ и $|C_2 \cap \hat{C}_3|$.

Задание 19: В $\Omega = \{1,\dots,6\}$ даны $A = \{1,2,3\}$, $B = \{3,4\}$. Найди симметрическую разность $A \triangle B$ = «произошло ровно одно из двух событий» двумя способами и сравни.

Задание 20: На тесте из 250 объектов модель ошиблась 30 раз. Найди частоту ошибки, оцени её погрешность и определи, можно ли утверждать, что доля ошибок меньше 0,16.

Продвинутые (задания 21-30)

Задание 21: Докажи тождество $A \cup B = A \cup (B \setminus A)$ и покажи, что справа стоят несовместные события. Проверь на примере $A = \{1,2,3\}$, $B = \{2,3,4,5\}$.

Задание 22: Даны три события $A$, $B$, $C$. На сколько непересекающихся областей они делят $\Omega$? Выпиши все области и докажи, что они образуют полную группу.

Задание 23: Докажи, что события $A \cap B$, $A \cap \bar{B}$, $\bar{A} \cap B$, $\bar{A} \cap \bar{B}$ образуют полную группу. Как это связано с матрицей ошибок?

Задание 24: В группе $n$ человек. Опиши $\Omega$ для эксперимента «записали дни рождения всех» (год считаем в 365 дней), найди $|\Omega|$ и мощность события $R$ = «все дни рождения различны». Вырази событие «хотя бы у двоих совпали».

Задание 25: Бинарный классификатор выдаёт score $s(x) \in [0,1]$, а решение принимается по порогу: $A_t$ = «$s(x) \geq t$». Покажи, что при $t_1 < t_2$ события вложены, и объясни, что из этого следует для ROC-кривой.

Задание 26: Выборку из 1000 объектов делят на 5 фолдов по 200 для кросс-валидации. Покажи, что фолды образуют полную группу. Сколько раз каждый объект попадает в обучение и сколько — в контроль?

Задание 27: Бутстрап: из выборки размера $N$ делают $N$ независимых извлечений с возвращением. Опиши $\Omega$, найди мощность события «конкретный объект $j$ не выбран ни разу» и его долю при $N = 1000$.

Задание 28: Докажи закон де Моргана для $n$ событий: $\overline{A_1 \cup A_2 \cup \dots \cup A_n} = \bar{A_1} \cap \bar{A_2} \cap \dots \cap \bar{A_n}$. Как это применяется к событию «хотя бы одна модель ошиблась»?

Задание 29: Accuracy модели около 0,9. (а) Какого размера нужен тест, чтобы погрешность оценки $\sigma$ не превышала 0,005? (б) Какого размера нужны два независимых теста, чтобы уверенно (на уровне $2\sigma$) различать модели, отличающиеся на 1 процентный пункт?

Задание 30: Multi-label классификация: объекту можно приписать любой набор из 3 тегов. Опиши $\Omega$, найди $|\Omega|$ и мощности событий $T_k$ = «объекту присвоен тег $k$». Образуют ли $T_1, T_2, T_3$ полную группу? Сколько всего событий в этом эксперименте?


Частые ошибки

Ошибка 1: путать несовместность и независимость

Неправильно: «События $A$ и $B$ не могут произойти вместе, значит они независимы — одно не влияет на другое».

Правильно: несовместность ($A \cap B = \varnothing$) — это, наоборот, самая сильная зависимость: если ты узнал, что $A$ произошло, ты немедленно знаешь, что $B$ не произошло. Независимость же означает, что информация об одном событии никак не меняет взгляд на другое. Классы объекта в многоклассовой задаче — несовместны. Два разных броска монеты — независимы. Это разные, почти противоположные по духу понятия.

Почему важно: на этой путанице ломаются все расчёты в уроках 229-230. Для несовместных складывают, для независимых умножают — перепутаешь операцию, получишь бессмыслицу вроде вероятности больше единицы.


Ошибка 2: считать событие числом, а не множеством

Неправильно: «Событие $A$ = 3» (при броске кости) или «событие = 0,5».

Правильно: событие — это подмножество $\Omega$. Даже когда оно состоит из одного исхода, это множество: $A = \{3\}$, а не $A = 3$. Число 0,5 — это не событие, это вероятность события, которая появится только в следующем уроке.

Почему важно: пока событие — множество, к нему применимы объединение, пересечение, дополнение, включение. Как только ты мысленно превратил его в число, весь аппарат исчезает, и начинаются попытки «складывать события» арифметически.


Ошибка 3: строить $\Omega$ из неравноправных, склеенных исходов

Неправильно: для двух монет взять $\Omega = \{\text{«два орла», «орёл и решка», «две решки»}\}$ и считать эти три исхода элементарными.

Правильно: исход «орёл и решка» склеен из двух различимых: $ОР$ и $РО$. Правильное пространство — $\{ОО, ОР, РО, РР\}$ из четырёх исходов.

Почему важно: это ровно та ошибка, на которой в 1754 году споткнулся Даламбер, и она до сих пор — источник неверных ответов в задачах. В ML тот же дефект возникает, когда огрубляют $\Omega$ до уровня, на котором нужное событие уже не выражается: например, логируют только итоговую accuracy без seed'а, а потом пытаются ответить на вопрос «а из-за чего был разброс».


Ошибка 4: терять условие «остальные не произошли»

Неправильно: «Ровно одна модель из трёх ошиблась» $= A_1 \cup A_2 \cup A_3$.

Правильно: $A_1 \cup A_2 \cup A_3$ — это «хотя бы одна ошиблась», сюда попадают и случаи с двумя, и с тремя ошибками. «Ровно одна» требует явных дополнений:

$$(A_1 \cap \bar{A_2} \cap \bar{A_3}) \cup (\bar{A_1} \cap A_2 \cap \bar{A_3}) \cup (\bar{A_1} \cap \bar{A_2} \cap A_3)$$

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


Ошибка 5: считать частоту точным значением вероятности

Неправильно: «Из 20 запусков модель ошиблась 3 раза, значит вероятность ошибки ровно 0,15».

Правильно: $0{,}15$ — это относительная частота в конкретной серии из 20 испытаний, а не вероятность. Её погрешность здесь порядка $\sqrt{0{,}15 \cdot 0{,}85/20} \approx 0{,}08$, то есть истинное значение вполне может лежать где-то между $0$ и $0{,}31$. Частота приближается к вероятности при росте $n$, и приближается медленно — как $1/\sqrt{n}$.

Почему важно: отсюда растёт вся культура доверительных интервалов и статистических тестов. Заявления вида «новая модель на 1% лучше» на тестах в несколько сотен объектов — это почти всегда отчёт о шуме, а не о качестве.


Ошибка 6: молча менять $\Omega$ по ходу рассуждения

Неправильно: посчитать частоту ошибок на исторических данных, а вывод сделать про будущий продакшн-трафик, не оговорив, что это два разных эксперимента.

Правильно: каждое утверждение о вероятности привязано к конкретному $\Omega$. «Ошибка на объекте из тестовой выборки», «ошибка на объекте из трафика следующего месяца» и «ошибка при усреднении по seed'ам» — три разных события в трёх разных пространствах.

Почему важно: это математическая суть distribution shift и главная причина расхождения «на валидации было отлично, в проде провал». Половина классических парадоксов теории вероятностей — от Бертрана до Монти Холла — тоже сводятся к молчаливой подмене $\Omega$.


Ошибка 7: считать, что несовместных событий «половина на половину»

Неправильно: «Наборов ошибок ансамбля, приводящих к провалу, ровно половина, значит ансамбль ошибается в 50% случаев».

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

Почему важно: это ровно тот шаг, который отделяет сегодняшний урок от следующего. Классическое определение вероятности (урок 227) требует равновозможности исходов — и это требование надо каждый раз проверять, а не предполагать по умолчанию.


Главное запомнить

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

  2. $\Omega$ — пространство элементарных исходов: множество неделимых взаимоисключающих результатов. Оно не задано природой, ты его выбираешь — и оно должно быть достаточно подробным, чтобы все интересующие события в нём выражались.

  3. Событие — это подмножество $\Omega$, а не число и не «то, что случилось». Событие $A$ наступило $\iff$ реализовавшийся исход $\omega \in A$. Если $|\Omega| = n$, то различных событий ровно $2^n$.

  4. Три особых события: достоверное $\Omega$ (наступает всегда), невозможное $\varnothing$ (не наступает никогда), противоположное $\bar{A} = \Omega \setminus A$. Всегда $A \cup \bar{A} = \Omega$ и $A \cap \bar{A} = \varnothing$.

  5. Словарь операций: «или» → $A \cup B$ (сумма), «и» → $A \cap B$ (произведение), «но не» → $A \setminus B = A \cap \bar{B}$, «не» → $\bar{A}$. Математическое «или» всегда включающее.

  6. Законы де Моргана: $\overline{A \cup B} = \bar{A} \cap \bar{B}$ («не хотя бы одно» = «ни одного») и $\overline{A \cap B} = \bar{A} \cup \bar{B}$. Это главный вычислительный трюк для событий вида «хотя бы один».

  7. Несовместные события — те, у которых $A \cap B = \varnothing$. Несовместность $\neq$ независимость: несовместность это сильнейшая зависимость, независимость — отсутствие информационной связи.

  8. Полная группа — попарно несовместные события, объединение которых даёт $\Omega$. Наступает ровно одно из них. Примеры из ML: метки классов (отсюда softmax), фолды кросс-валидации, разбиение train/val/test, ячейки матрицы ошибок.

  9. Относительная частота $W_n(A) = m/n$ — свойство серии, а не события. При росте $n$ она стягивается к вероятности (статистическая устойчивость), с типичным отклонением порядка $\sqrt{p(1-p)/n}$ — то есть точность растёт как $\sqrt{n}$, и для удвоения точности нужно вчетверо больше данных.

  10. В ML случайность — инструмент, а не помеха: инициализация весов, shuffle, dropout, bootstrap, случайное разбиение. Фиксированный seed даёт воспроизводимость, набор разных seed'ов — оценку разброса. Одного запуска для сравнения моделей не бывает достаточно.


Связь с другими темами курса

Что было до: формально этот урок стартует с нуля — вероятностей в курсе до него не было. Но опирается он на два уже знакомых пласта. Первый — теория множеств: подмножества, объединение, пересечение, дополнение, законы де Моргана. Всё, что мы делали с событиями, это буквально операции над множествами с вероятностными именами. Второй — комбинаторика: подсчёт числа исходов через правило произведения, размещения и сочетания ($|\Omega| = 2^n$ для $n$ бинарных решений, $C_n^k$ для выбора $k$ позиций из $n$). Кроме того, привычка к строгим определениям и доказательствам двойным включением пришла из линейной алгебры и анализа.

Что дальше: прямо со следующего урока начинается счёт. Урок 227 вводит классическое определение вероятности $P(A) = m/n$ — отношение числа благоприятных исходов к общему, и заодно объясняет, когда им пользоваться можно, а когда нельзя (требуется равновозможность исходов). Урок 228 — геометрическая вероятность для случаев с бесконечным $\Omega$: длины, площади, объёмы вместо счёта. Урок 229 — теоремы сложения и умножения: как считать $P(A \cup B)$ и $P(A \cap B)$, здесь же формально появляется независимость. Урок 230 — условная вероятность $P(A \mid B)$, ключ ко всей байесовской логике. Уроки 231-232 — формула полной вероятности и формула Байеса, работающие ровно на полных группах, которые мы сегодня разбирали. Урок 233 — схема Бернулли, то есть повторение независимых испытаний, откуда формально выводится всё, что мы прикидывали про «хотя бы один объект редкого класса в батче». Урок 234 превращает событие в случайную величину — функцию $\omega \mapsto \mathbb{R}$, ровно как accuracy была функцией от seed'а. Урок 242 доказывает закон больших чисел — строгую версию статистической устойчивости.

Где это применяется в жизни и в ML/данных:

📊 Метрики качества: accuracy, precision, recall, F1, FPR, специфичность — все они частоты событий, выделенных из матрицы ошибок; ROC и PR-кривые — семейства вложенных событий $A_t$ по порогу.

🧪 Валидация и эксперименты: train/val/test как полная группа, GroupKFold и TimeSeriesSplit как способы не нарушить независимость, out-of-bag оценка в random forest, А/В-тестирование и оценка значимости различий.

🔧 Обучение моделей: случайная инициализация Хавьера и Хе, shuffle батчей, dropout, bootstrap в бэггинге, случайные подпространства признаков, negative sampling, temperature sampling в LLM.

🩺 Медицина и скрининг: чувствительность и специфичность теста — это те же recall и TNR; на языке событий формулируется вся диагностика, а формула Байеса из урока 232 объясняет, почему положительный результат редкого теста часто ничего не значит.

🛡 Надёжность систем: «сервис доступен» = «работает хотя бы одна реплика» = дополнение к «упали все» — прямое приложение де Моргана; расчёт SLA строится на этой конструкции.

🔐 Безопасность и хеши: парадокс дней рождения объясняет частоту коллизий, а через него — требования к длине хеша и к размеру пространства идентификаторов.


Интересные факты

💡 Теория вероятностей родилась из проигрышей игрока. Шевалье де Мере годами выигрывал на ставке «хотя бы одна шестёрка за 4 броска» и разорялся на ставке «хотя бы одна пара шестёрок за 24 броска двух костей». Его интуиция «пропорция та же» была неверна: первая ставка чуть выгоднее 50/50, вторая — чуть невыгоднее. Разница между ними меньше двух процентных пунктов, но за сотни партий она превратилась в реальные деньги. Из его письма Паскалю выросла целая наука.

💡 Строгое определение вероятности появилось только в 1933 году. Двести семьдесят лет теория работала без фундамента: определения ходили по кругу через «равновозможность». Колмогоров разорвал круг радикально — объявив вероятность просто мерой на множестве, с тремя аксиомами, и не пытаясь объяснять, «что это такое на самом деле». Тот же приём — определить объект списком свойств, а не описанием сущности — сделал возможной современную математику в целом.

💡 В группе из 23 человек совпадение дней рождения вероятнее, чем его отсутствие. Интуиция подсказывает, что нужны сотни людей, ведь дней 365. Но событий-пар в группе из 23 человек уже $C_{23}^2 = 253$ — и именно число пар, а не число людей, определяет ответ. Тот же эффект работает с хешами: чтобы коллизия стала вероятной, нужно примерно $\sqrt{M}$ объектов при $M$ возможных значений хеша, а не $M$.

💡 Джон Керрич бросил монету 10 000 раз в лагере для интернированных. Датский лагерь, Вторая мировая, много свободного времени. Результат — 5067 орлов, частота 0,5067. Его записи до сих пор цитируют как самую наглядную демонстрацию статистической устойчивости: он фиксировал промежуточные частоты и показал, как коридор колебаний сжимается с ростом числа бросков.

💡 Ноль вероятности не означает невозможность. Как только $\Omega$ становится бесконечным (например, «выбрать случайную точку отрезка»), появляются события ненулевые, но с вероятностью 0 — попадание в конкретную точку. Событие $\varnothing$ невозможно, но обратное неверно: не всякое событие вероятности 0 пусто. Эта тонкость всплывёт в уроке 228 и станет принципиальной при работе с непрерывными распределениями.


Лайфхаки и полезные трюки

1. Всегда начинай с явного $\Omega$ — даже если кажется, что задача простая

Девять из десяти ошибок в вероятностных задачах — это не арифметика, а неправильно построенное пространство исходов. Возьми за правило первой строкой решения писать «$\Omega = \{\dots\}$, $|\Omega| = \dots$». В ML-задачах формулируй это вслух: «эксперимент — взяли случайный объект из теста; исход — пара (истинный класс, предсказание)». Половина вопросов отпадает сама.


2. «Хотя бы один» — сразу переходи к дополнению

Это самый рентабельный рефлекс во всей теории вероятностей. «Хотя бы одна модель ошиблась» → «не все правы». «Хотя бы один редкий объект в батче» → «весь батч из частого класса». Прямой подсчёт требует перебора всех случаев (один, два, три...), через дополнение — один случай. Работает благодаря де Моргану.


3. Переводи словесную формулировку в формулу по словарю связок

Читаешь условие и подчёркиваешь связки: «и» → $\cap$, «или» → $\cup$, «не» → черта, «но не» → разность. Отдельно проверяй, не потерялось ли слово «ровно» (оно требует явных дополнений для остальных) и не подменил ли ты включающее «или» бытовым исключающим.


4. Проверяй любое тождество на маленьком конкретном примере

Прежде чем доверять преобразованию, возьми $\Omega = \{1,\dots,6\}$, два-три конкретных подмножества и посчитай обе стороны руками. Тридцать секунд работы отлавливают большинство ошибок в раскрытии скобок и де Моргановских переходах. Для программиста ещё быстрее — прогнать булевы маски на numpy: ((~(A | B)) == (~A & ~B)).all().


5. Проверяй разбиение по мощностям: сумма должна сойтись ровно

Если события претендуют на полную группу, сумма их размеров обязана равняться $|\Omega|$. Сумма больше — события пересекаются (утечка данных, дубликаты между фолдами). Сумма меньше — что-то не покрыто (объекты выпали из разбиения). Эта однострочная проверка — самый дешёвый детектор leakage в пайплайне: assert len(train) + len(val) + len(test) == len(data) и assert not set(train_ids) & set(test_ids).


6. Помни правило $\sqrt{n}$ и держи в голове порядок погрешности

Перед тем как радоваться улучшению метрики, прикинь $\sigma \approx \sqrt{p(1-p)/n}$ в уме. Для $p$ около $0{,}5$ и $n = 100$ это $0{,}05$; для $n = 10\,000$ — $0{,}005$. Если наблюдаемое улучшение меньше двух сигм, ты смотришь на шум. Чтобы вдвое улучшить точность оценки — вчетверо больше данных, третьего варианта нет.


7. Заведи привычку «5 seed'ов минимум»

Одно число — это одно наблюдение одного элементарного исхода. Прогоняй обучение на нескольких seed'ах и отчитывайся парой «среднее ± стандартное отклонение». И не поддавайся соблазну выбрать лучший seed: подбор seed'а по тесту — это то же переобучение, что и подбор гиперпараметров по тесту, просто менее заметное.


8. Рисуй диаграмму Венна, когда путаешься в условии

Прямоугольник — это $\Omega$, круги — события. Три события дают ровно 8 областей, и любую словесную формулировку можно просто заштриховать. Особенно помогает в задачах вида «не более одного», «ровно два», «хотя бы два», где формулы громоздкие, а картинка мгновенно показывает нужные куски.


Ты только что построил язык, на котором говорит вся вероятностная часть машинного обучения. Пока это выглядит как игра в множества — исходы, подмножества, пересечения, — но именно на этом каркасе через несколько уроков вырастут формула Байеса, функция правдоподобия, cross-entropy loss и доверительные интервалы. Ни одна из этих конструкций не имеет смысла без вопроса «а что такое $\Omega$ в этой задаче?» — и теперь ты умеешь на него отвечать.

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

Понял тему? Закрепи в боте! 🚀

Попрактикуйся на задачах и получи персональные рекомендации от AI

💪 Начать тренировку
💬 Есть вопрос? Спроси бота!