Программа курса «Вычислительная математике в школе. От машинного обучения до физического моделирования»
Предисловие
Лицензия: CC BY-NC-SA. Эту программу курса разрешено использовать полностью или частично преподавателям в некоммерческом секторе. При использовании для создания коммерческих курсов, требуется отдельная договорённость, по-дефолту это не разрешено. При использовании/изменении программы требуется указывать ссылку на исходный документ. Производные работы должны распространяться по той же лицензии.
Формат, концепция и целеполагание курса
Сегодня в школьные курсы информатики нередко пытаются включать машинное обучение и анализ данных (далее ML) как одну из востребованных областей IT. Мы хотим поделиться своей концепцией обучения школьников ML. Но прежде, чем обсуждать программу, стоит описать наши предпосылки и целеполагание.
Мы полагаем, что классический курс информатики, вершиной которого является обучение школьников программированию, сильно отстаёт от реалий, и не реализует ни потребностей, ни возможностей школьников. В наших профильных классах школьники обучаются азам программирования уже к началу 7-го класса, всего за два года, и возникает вопрос, чему было бы наиболее полезно обучить детей.
Мы полагаем, что большая часть школьников из профильных классов пойдёт получать высшее образование (причём не всегда в области IT), где в любом случае научится наиболее актуальным на момент обучения технологиям. А значит школа не должна готовить из школьников профессиональных программистов и IT-специалистов. Поэтому мы полагаем, что более полезно использовать уроки информатики для выстраивания на их основе межпредметных связей, а не для изучения современных технологий. Поэтому наш курс машинного обучения не ставит целью обучение школьников прикладному ML. Вместо этого мы используем ML как полигон для пропедевтики высшей математики.
Вузовские курсы высшей математики вводят множество абстрактных понятий, описанных на весьма формализованном языке, и закрепляют знания при помощи множества вычислительных задач на бумаге. Такой подход с одной стороны сильно мешает студентам сложить интуитивное понимание о предмете и выстраивает жёсткие границы между областями знаний, а с другой отдаляет их от современной инженерной практики, в которой все подобные вычисления принято делать с использованием компьютеров.
Курс машинного обучения позволяет приходить к разным элементам высшей математики постепенным и естественным путём, и тренировать их на простых задачах, попутно привыкая к стандартному формализму, степень которого мы можем варьировать в очень широких пределах. Нам представляется, что это поможет школьникам в студенческие годы существенно лучше понимать изучаемые предметы и связи между ними, а также уметь применять их на практике. Проходит он в формате семинара: лекционная часть периодически прерывается на решение возникающих в процессе задач, а затем мы возвращаемся к разбору результатов.
Машинное обучение — это наука о поиске закономерностей в данных. В ней активно используются методы линейной алгебры, математического анализа, статистики и теории вероятностей. Обычно мы сначала самостоятельно программируем методы решения возникающих математических задач, а затем обращаемся к библиотекам, которые реализовали это за нас.
Иногда мы также включаем в курс методы математического моделирования физических (в первую очередь кинематических), экономических или экологических процессов, которые демонстрируют основы дифференциальных уравнений. Это помогает школьникам освоиться не только и не столько с математикой, сколько с механикой.
Статистика обычно вызывает у студентов наибольшие сложности. Я полагаю, что студентам тяжело уяснить разницу между расределениями, описывающими данные и выборочным статистиками, и тем более распределениями этой самой выборочной статистики. Компьютерное моделирование позволяет моментально генерировать случайные выборки и вычислять соответствующие статистики, что существенно «удешевляет» эксперименты в этой области. Это позволяет со школьниками дойти до таких непростых тем как проверка статистических гипотез.
Поскольку наша цель заключается скорее в том, чтобы у школьников появился инструмент и привычка к экспериментированию с математикой и умение применять компьютер для реализации математических методов, чем в изучении конкретного набора фактов. Набор изучаемых тем можно изменять по вкусу преподавателя. Программа выстроена как набор сюжетов в разной степени зависимых друг от друга. Мы стараемся не замыкаться в пределах ML, и когда возникает возможность, делаем отступления в область физического моделирования, криптографии, алгоритмов итд.
В качестве языка программирования мы пользуемся python, но большую часть программы легко перенести на любой другой язык. Некоторые части курса вполне естественно ложатся даже на excel.
Набор сюжетов
Мы начинаем разговор с линейной регрессии с одной переменной и метода наименьших квадратов. Это приводит нас к идее модели данных, концепции функции потерь и задаче её оптимизации.
Эту задачу можно начать с поиска вершины параболы (если ограничиться одним изменяющимся параметром кривых). Для начала можно это делать даже вручную в табличке excel, затем вывести формулу.
При переходе к прямым общего вида, нам проще заняться поиском минимума путём приравнивания нулю частных производных. На этом этапе мы можем обсудить производные многочленов. Посмотреть на производные как способ приближённого вычисления функций, численно помоделировать и порисовать их. Есть возможность углубиться в тему вплоть до ряда Тейлора. Также мы обсуждаем символьное дифференцирование и деревья абстрактного синтаксиса. Иногда сами реализуем алгоритм. Иногда отдаём задачу на откуп sympy.
Затем мы переходим к полиномиальной регрессии. Теперь в процессе оптимизации у нас возникает система линейных уравнений.
Мы осваиваем матричную форму записи таких систем, разбираем метод Гаусса. Обсуждаем, как работать с матрицами вплоть до их умножения и идеи о том, что существует обратная матрица. Здесь же школьники знакомятся с многомерными векторами, скалярным произведением. В список тем можно добавить многомерную теорему Пифагора и измерение угла между многомерными векторами.
После того как школьники поработали с матрицами руками, мы переходим к библиотеке numpy и осваиваем базовый набор матричных операций, научаемся решать (невырожденные) системы уравнений.
Обсуждаем концепцию переобучения и учимся подбирать оптимальную степень полинома на валидационной выборке. Обсуждаем разбиение данных на train/test/validation. Здесь можно сделать философское отступление в сторону позитивизма и пришедшего ему на смену критерия Поппера.
Чтобы проверить работоспособность метода, мы строим графики в matplotlib. Также мы учимся генерировать данные по модели с добавленным к ней случайным шумом.
Поработав с регрессиями мы открываем библиотеку sklearn, которая их умеет делать за нас. Рассматриваем интерфейс fit-predict и типичную схемы работы с библиотекой.
Теперь можно отойти от приближённых регрессий к полиномиальной интерполяции, проходящей в точности через наши точки. Строим интерполяционный многочлен Лагранжа. Тут можно провести связку с криптографией и схемой разделения ключа Шамира или с кодами восстановления ошибок.
Строим ещё один вариант интерполяции — квадратичные или кубические сплайны, чтобы показать, что модель не обязана быть цельной, а может быть собрана из кусочков.
Возвращаемся к линейной регрессии, но на этот раз от нескольких переменных. Говорим про R^2 как метрику качества (полезно обратиться к линии тренда в Excel). Сталкиваемся с проблемой переобучения за счёт скоррелированных переменных. Обсуждаем базовые статистические величины: среднее, дисперсию и стандартное отклонение, корреляцию. Изучаем датасет на предмет скоррелированных признаков. Обсуждаем регуляризацию функции потерь и то, как вместо минимизации двух отдельных величин мы минимизируем их (взвешенную) сумму.
Обсуждая регуляризацию мы видим, что возникает проблема с переменными разных масштабов. Обсуждаем шкалирование и вообще саму идею того, что не бывает больших и малых чисел самих по себе, пока их не с чем сравнить. В процессе изучения реальных датасетов мы натыкаемся ещё и на категориальные переменные, обсуждаем, как превратить такие признаки в числовые. И что можно делать, если значения в таблице пропущены.
Обсуждаем задачи классического машинного обучения за пределами регрессии: классификация, кластеризация.
Классификация — это повод поговорить про линейную разделимость классов. Это ведёт нас к концепции гиперплоскости и её уравнения, снова вспоминаем про скалярное произведение с нормалью и вычисляем расстояние до плоскости. Учимся переводить эти расстояния в вероятности. Если курс пойдёт в сторону нейросетей, обычно мы затрагиваем ещё softmax для многоклассовой классификации.
Далее нам приходится поговорить про метрики классификации и идею ошибок первого и второго рода.
Для подбора весов мы приходим к генеративной модели, которая задаёт нам функцию правдоподобия. Это повод обсудить условные вероятности и теорему Байеса. Обсуждаем, как произведение при помощи логарифмирования превращается в сумму.
Задачу оптимизации на этот раз решаем методом градиентного спуска. Это ведёт нас к элементам многомерного анализа. Мы учимся по частным производным вычислять приближённые (до первого порядка) значения функции в окрестности точки. Обсуждаем, почему градиент задаёт направление наибыстрейшего подъёма. Здесь нам опять приходится говорить про скалярное произведение и угол между векторами.
Иногда мы на этом месте решаем задачу поиска минимума произвольной функции. Для символьного дифференцирования берём sympy, и на его основе пишем градиентый спуск.
Метод итеративного улучшения весов перекликается с методом k-means кластеризации, к которой мы можем перейти. Задачи на кластеризацию можно давать довольно необычные. Например, перекрасить фотографию в 4 основных цвета, предварительно эти цвета получив при помощи кластеризации.
Близко к этой теме маломерные отображения многомерных пространств: от MDS до t-SNE/UMAP и PCA. Я предпочитаю MDS, т.к. можно провести аналогию с пружинками, которыми скреплены объекты.
Далее мы можем перейти к физическому моделированию. Достаточно будет разобрать простейший метод Эйлера на какой-нибудь системе с парой объектов: планета, вращающаяся вокруг Солнца, пара пружинок прикреплённых одна к другой итд. Мы можем численно решать дифференциальные уравнения и попутно проверять законы сохранения. Важнее всего чётко показать, как связаны сила с ускорением, скоростью и координатой, т.к. это сильно помогает в понимании механики.
Марковские процессы. Распределение ансамбля исходов по пространству состояний. Линейные операторы как преобразования пространства. Собственные векторы и собственные значения.
ML (ошмётки старых текстов)
Я иду от самых основ с большим упором на математику.
Сначала я долго мучаю школьников линейной регрессией. У них на лабах по физике есть метод наименьших квадратов. Здесь его выводим исходя из минимизации функции потерь. Тут можно впервые поговорить про тренировочные и тестовые данные.
Следующим шагом смотрим полиномиальную регрессию, снова дифференцируем лосс и приравниваем нулю, показываем, что опять линейные уравнения получаются.Тут мы учимся записывать уравнения на коэффициенты в матричной форме, учимся работать с матрицами. Школьники руками пишут метод Гаусса, потом я выдаю им numpy и мы разбираемся с обратной матрицей.
Сюда же хорошо ложится интерполяционный многочлен Лагранжа и можно показать, что это имеет применение в очень разных областях и показать схему разделения секрета Шамира. Тут можно построить графиков и показать, как многочлены разных степеней проходят. Заодно с матплотлибом пусть поработают.
Здесь же уместно поговорить про переобучение, про гиперпараметры и про train/val/test.
Хотя я тут промахнулся с примером, на практике получить ненулевые старшие коэффициенты при большом числе точек - непросто. Но всё-таки вполне можно построить графиков и увидеть, что делает неудачное число параметров с ошибкой на валидации.
Где-то здесь мы брали и второй метод искать минимум лосса - методом градиентного спуска. Но уже не помню, какую именно задачу я давал. Кажется, выдал просто какой-то сложный многочлен двух переменных (который мы предварительно в вольфрам альфе нарисовали)
Потом мы смотрели на интерполяцию сплайнами (и за компанию линейную интерполяцию цвета в барицентрических координатах треугольника, но это выбивается, конечно, из общей канвы). Здесь снова системы линейных уравнений, чтобы уж точно от зубов отлетали. Но это довольно сложный кусок, конечно.
Потом берём в руки пандас и строим линейную регрессию на несвязанных друг с другом параметрах. Мы брали предсказание цены квартиры. Поскольку руками уже всё проделали, показываю sklearn и его линейную регрессию. Ну и полный шаблон: разбиение данных, обучение, предсказание. Есть возможность поподбирать набор признаков и посмотреть на скор.
Дальше возникает вопрос, а что это за скор R^2, который нам выдал sklearn. Здесь нам нужно посмотреть, что такое корреляция. А перед этим на среднее и дисперсию. Благо это легко показать в любом разумном датасете на скаттерплотах.
Дальше можно поговорить про исключение скоррелированных переменных или регуляризацию на замену. Что такое лосс они к этому моменту уже неплохо понимают. Здесь же говорим про one-hot-encoding, так как у нас есть категориальные признаки. И здесь же говорим про заполнение пропусков в данных медианным значением как способом избежать полупустой таблицы.
Плюс мы дополнительно генерировали случайные точки и смотрели на то, как они себя ведут. Смотрели, что такое нормальное распределение. От генерации случайных точек можно делать отступления к методу Монте-Карло. Число пи посчитать и может ещё что-нибудь. Ибо не анализом данных единым жив человек. Но это всё как раз можно сделать и позже.
Наконец три месяца спустя мы дошли до логистической регрессии, которая вовсе не регрессия, а классификация. Разговариваем о том, каким уравнением задаётся (гипер)плоскость, что такое нормаль и как нам считать расстояние до плоскости. Вводим сигмоиду для перевода расстояний в вероятности.
Кроме того, теперь у нас есть другие метрики: accuracy и AUC ROC. Самое время поговорить про false positive/negative и тесты на ковид и про порог классификации. Сейчас мы остановились где-то здесь. Дальше я планирую (мы в прошлом году так делали) рассказать про максимизацию правдоподобия и потратить несколько недель на Байеса, на параметрические формулы вероятности класса. Ну и конечно ещё раз запрогать градиентный спуск, чтобы найти коэффициенты лог-рега. Здесь же можно поговорить про баланс классов, но лучше отложить до более простого примера в начале следующего семестра.
В общем я хочу, чтобы они знали основные понятия, но знали их надёжно и умели применять.
Анализ данных часть 2. Первый семестр закончится приблизительно разбором теорвера с условными вероятностями, функцией правдоподобия, теоремой Байеса. И принципом максимизации правдоподобия, применённом к логистической регрессии.
Дальше мы возьмём другой пример на параметрические вероятности: возьмём людей с двумя признаками вес-рост и попытаемся предсказать пол. На картинке это будут два пересекающихся облака формы повёрнутых эллипсов. Тут у нас вероятность параметризуется не расстоянием от гиперплоскости, а некоторым многомерным нормальным распределением. Тут придётся выдать формулу нормального распределения в каком-то разумном виде, потому что ковариационную матрицу рассматривать ну вообще не хочется. Я на самом деле думаю о том, чтобы упростить задачу и сделать эллипсы без поворота. Дальше мы пишем вероятность для одной точки быть из одного класса или из другого класса. Строим разделяющую поверхность между эллипсами, на которой уравниваются вероятности того, что точка — мальчик и что точка — девочка. Потом можно посмотреть, на баланс классов. Как изменится наше предсказание, если мы говорим про жителей Марса, у которых самок в десять раз меньше, чем самцов. Говорим про априорные и апостериорные вероятности. Можно сделать задачу чуть менее математической и более приближенной к реальности, добавив ещё одну ось возраста и сказать, что девочки сначала растут быстрее, а потом быстрее растут мальчики. Теперь мы знаем три признака, определить надо всё так же пол. Можно сравнить точность классификации для случая, когда возраст известен и когда неизвестен. Ок, про одну точку поняли. А теперь мы хотим определить параметры эллипсоидов, имея набор точек. И мы опять строим функцию правдоподобия и максимизируем её. В численном виде или аналитическом — по настроению.
Куда-то сюда хорошо ложится ещё кусок про то, как генерировать случайные точки, распределённые по некоторому закону. Как, например, сгенерировать случайные рост-вес. Тут на самом деле хорошо бы поговорить и про обычные генераторы псевдослучайных чисел.
Дальше можно взять наивный Байесовский классификатор и написать систему категоризацию писем, разделив их на спам и ещё пару-тройку категорий. Тут у нас снова тервер. Прицельно изучаем, что такое независимые случайные величины. Снова тренируем правдоподобия. Здесь же можно потрогать всякие прикладные штуки типа стеммеров. Хорошим ответвлением отсюда будет поговорить про марковские цепи, а может и про скрытые марковские цепи (цепь на синтаксис предложения + случайные слова на каждую часть речи). Разумеется безо всякой расчленёнки типа алгоритмов Витерби. Её и в универе непросто понять. Здесь это нужно скорее чтобы параллельно с курсом алгоритмов поговорить про конечные автоматы. Ну и вообще (1) дать представление о том как генерировать данные, (2) ещё раз подчеркнуть, что у системы есть скрытые параметры, которые мы не видим, а видим только результат; но зная результат можем делать какие-то выводы.
Ладно… дальше возвращаемся к какой-нибудь задаче классификации, где много признаков. Отбираем группы по несколько признаков (можно произнести слово бэггинг, но наверное незачем) и смотрим, как работают обычные логистические регрессии. Дальше соображаем, что можно сделать ансамбль из голосующих классификаторов. Получаем классификатор лучше всех базовых. Говорим про то, что можно подбирать веса, но за нас это сделает библиотека. Играемся с разными классификаторами из библиотеки. Радуемся тому, что общий интерфейс fit/predict/… позволяет подменять только конструирование объекта, а остальной код вообще не менять.
Дальше есть два разных варианта. По опыту оба рассказать не хватает немного времени. (I) От ансамблей логично перейти к перцептрону. Объяснить, что логистическая регрессия — это один нейрон. Показать, что нейросеть — это какие-то матричные перемножения. Показать, что многослойная нейросеть ничем не лучше однослойной (то есть фактически не лучше разделения гиперплоскостью), если не добавлять нелинейность. Рассказать, что есть простейшая задача XOR, которую такая нейросеть не решает. Зато как только добавляется нелинейность, всё работает отлично. Можно на базе ReLU-активаций сделать сетку для XOR. Дальше мы говорим, что нейросеть — это такая функция. Опять вводим Loss. А потом в общих чертах можно рассказать про backpropagation. Смотрим, чем стохастически градиентный спуск отличается от обычного градиентного спуска. Показываю pytorch и рассказать, что автодифференцирование сделано за нас. Рассмотреть какой-нибудь обучающий пример, чтобы понять, как обучение нейросетей вообще устроено. Потом можно поговорить про свёртки и всякие edge detection фильтры. Это можно закодить. Потом можно порассказывать 1–2 занятия про более-менее актуальные подходы идеи в нейросетях. Про свёрточные сети. Про автоэнкодеры и понятие эмбеддинга. Про концепцию рекуррентных сетей. Про seq2seq. Про GAN. На пальцах это всё довольно легко рассказывать. И это само по себе даёт довольно богатый язык для придумывания вещей
(II) Ок, мы рассмотрели кучу параметрических методов. Но есть и другие варианты. Мы только что рассмотрели ансамбль классификаторов. А теперь можем сделать kNN-голосование (k ближайших соседей).
Теперь, когда мы поговорили про методы предсказания с учителем, можно перейти к алгоритмам без учителя. Например, кластеризация. Реалистично закодить два разных метода кластеризации: k-means. И иерархическую кластеризацию UPGMA. Причём иерархическую можно показывать на примере, где у нас есть нет векторов признаков, но есть матрица расстояний. Например, скластеризовать слова по расстоянию Левенштейна.
Потом посмотреть, как визуализировать множество слов на плоскости: сделать уменьшение размерности методом многомерного шкалирования (сделать двумерные вектора для каждой точки и задать «пружинки» между парами точек с длинами, равными длинам в исходном многомерном пространстве). Нарисовать анимацию, как итеративно слова расходятся по плоскости.
Кластеризацию k-means хорошо рассказывать на уменьшении числа цветов на картинке. Мы так делали из разноцветной картинки 8-цветную по цветам кластеров.
Статистика
Мне кажется, один из самых тяжело укладываемых в голове курсов — статистика. Меня самого пытались научить статистике несколько раз, и это всякий раз было фиаско. Я не понимал буквально ничего. Считаем какие-то хи-квадраты из неясно каких данных и неясно, зачем. Пока Андрей Райгородский буквально за одну лекцию не объяснил основы так, что всё остальное встало на свои места. Статистику я так и не стал знать хорошо, но понимаю её основы и, кажется, научился их рассказывать.
В какой-то момент на «Слоне» мы с Л.В. делали курс двухнедельный курс по основам теорвера и статистики. Мы много где накосячили, но я всё ещё доволен тем опытом. Главный мой вывод с той школы заключался в том, что статистику обязательно надо преподавать с программированием. И, скажу больше, её категорически нельзя преподавать без программирования. Сейчас я в рамках курса биоинформатики пытаюсь дать блок статистики. Тоже выходит далеко от идеала, конечно, но косячу уже меньше (следует читать так: раньше косячил ещё больше). Программа очень сырая, но очень уж хочется её довести до хорошей.
Было бы здорово увидеть курс такого рода. Срочно покажите мне такой, пока я не захотел сам его делать! Я представляю это как учебник в формате интерактивной тетрадки, в которой можно будет писать код, смотреть на каноническое решение, менять в нём параметры и смотреть на графики.
Сразу скажу, что мне кажутся бессмысленными курсы вида «Язык R для статистики», потому что основные проблемы возникают не с языком (хотя R на редкость дурной), а с пониманием статистики. Туториалы, которые говорят «примените функцию бубубу, чтобы посчитать P-value точного теста Фишера» — бессмысленны, потому что весь текст после запятой для читателя оказывается в лучшем случае шумом. Хуже, когда у читателя складывается ложное ощущение, что он что-то понимает.
Я предпочитаю использовать Python вместо R, потому что чем меньше магии, тем лучше. Чтобы понимать статистику, нужно научиться с ней работать руками, а не при помощи кем-то другим написанных. Поэтому для работы я беру связку numpy.random + scipy.random + matplotlib/seaborn. Иногда прибавляю pandas.
Если вам близко то, о чём я говорю, давайте замутим курс. Или отговорите меня от этой идеи, показав, что такое уже есть. И желательно от людей, которые (в отличие от меня), по-настоящему знают статистику. Если хотите покритиковать, тоже welcome. Обычно нельзя, но в этом посте можно. Я недостаточно уверенно себя чувствую в теме, и буду рад улучшить своё понимание того, как должен выглядеть курс, и как он выглядеть не должен.
Дальше ↓ (https://t.me/schroedinger_jokes/426), извините читатели, будет техническая часть.
Какие я вижу must have вещи в модуле статистики (см. вводный пост ↑ (https://t.me/schroedinger_jokes/425)):
— написать генератор чисел под какое-то дискретное распределение. Позднее можно и под дискретное,
— погенерировать случайных чисел из разных распределений, встроенных в numpy и порисовать гистограммок (= график плотности вероятности)
— поучиться генерировать фейковые данные по принципу модель + шум
— посчитать базовые выборочные статистики: среднее, дисперсию и стандартное отклонение, размах, медиану, какие-нибудь квантили
— посмотреть на диаграммы рассеяния (scatterplot-ы) скоррелированных и нескоррелированных величин. Посчитать коэффициент корреляции руками. R^2
— посмотреть на статистики по выборке как на случайную величину. Брать по несколько выборок и смотреть, чему для каждой из выборок равны среднее и стандартное отклонение. Рисовать распределения выборочных статистик. Смотреть, как они меняются в зависимости от размера единичных выборок. Построить доверительные интервалы.
Мне нравится говорить на примере мешков, в которых разные сорта мандаринов. И мы измеряем средний размер мандарина в мешке.
— показать, что усреднение большого числа одинаковых распределений приводит нас к нормальному распределению — демонстрация ЦПТ в действии
— смоделировать одновыборочную t-статистику, взяв большое число выборок из одного распределения и показав, как t-статистика распределена. Показать, как имея (эмпирически полученное) распределение t-статистики, можно сказать, насколько выборка удовлетворяет нулевой гипотезе. Ввести понятия нулевой гипотезы, статистического теста, P-value. Берём теперь распределение с другим центром (не удовлетворяющее нулевой гипотезе) и смотрим, какие величины t-статистики и P-value получаются теперь. Изучаем зависимость распределения t-статистики от размера выборки и делаем выводы о том, насколько сложно отклонять
— показать проблему множественного тестирования: возьмём выборку много раз и добьёмся получения близкого к нулю P-value, несмотря на то, что нулевая гипотеза верна
— показать, как распределены разности средних по выборке для одного и того же нормального распределения (для простоты мы можем зафиксировать размеры выборок и величину дисперсии). Посмотреть, что происходит, когда мы вычисляем средние по выборке для двух разных распределений — и эмпирически посчитать P-value гипотезы о том, что две выборки взяты из единого нормального распределения.
— показать, что имея распределение Стьюдента мы можем вычислять P-value как 1 - cdf(threshold). Тут-то нам и понадобится scipy.
— разобрать, что такое pdf, что такое cdf. Поговорить про концепцию определённого интеграла и вероятность как площадь под графиком площади вероятности.
— критерий согласия Пирсона aka критерий согласия χ². Учимся понимать, соответствует ли серия бросков «кубику» d12 или двум кубикам d6.
— возможно, стоит попрактиковаться в критериях согласия ещё раз — на проверке нормальности распределения
— промоделировать точный тест Фишера. Убедиться, что мы можем эмпирически получить такие же P-value, как дают библиотечные функции
— понятие условной вероятности. Формула Байеса. Учимся вычислять апостериорную вероятность по серии экспериментов — и отличать фальшивую монету от настоящей при помощи максимизации правдоподобия.
…cписок не претендует на полноту, конечно. Это скорее наброски упражнений, чем готовый материал.