Про вероятности

в 9:42, , рубрики: data mining, машинное обучение, теория вероятностей

image
(source)

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

А почему так важно, чтобы переменные в линейной регрессии были независимы?

или

А почему для изображений используются именно свёрточные сети, а не обычные полносвязные?

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

Так давайте не будем мучить себя и других и просто вспомним основные понятия теории вероятностей.

Случайные переменные

Представим, что у нас есть анкеты людей, где указаны их возраст, рост, пол и количество детей:

age height gender children
32 175 1 2
28 180 1 1
17 164 0 0
... ... .... ....

Каждая строчка в такой таблице — это объект. Каждая ячейка — значение переменной, характеризующей этот объект. Например, возраст первого человека — 32 года, а рост второго — 180см. А что, если мы хотим описать некоторую переменную сразу для всех наших объектов, т.е. взять целую колонку? В этом случае у нас будет не одно конкретное значение, а сразу несколько, каждое со своей частотой встречаемости. Список возможных значений + соответсвующая вероятность и называется случайной переменной (random variable, r.v.).

Дискретные и непрерывные случайные переменные

Чтобы это отложилось в голове, я повторю ещё раз: случайная переменная полностью задаётся распределением вероятностей своих значений. Есть 2 основных типа случайных переменных: дискретные (discrete) и непрерывные (continuous).

Дискретные переменные имеют конечное множество чётко разделимых значений. Обычно я изображаю их как-нибудь так (probability mass function, pmf):

Про вероятности - 2

Код на Julia

Pkg.add("Plots")
using Plots
plotly()

plot(["0","1"], [0.3, 0.7], linetype=:bar, legend=false)

А текстом это обычно записывается так (g — gender):

$p(g=0)=0.3\ p(g=1)=0.7$

Т.е. вероятность того, что случайно взятый человек из нашей выборки окажется женщиной ($g=0$) равна 0.3, а мужчиной ($g=1$) — 0.7, что эквивалентно тому, что в выборке было 30% женщин и 70% мужчин.

К дискретным же переменным относятся количество детей у человека, частота встречаемости слов в тексте, количество просмотров фильма и т.д. Результат классификации на конечное число классов, кстати, — это тоже дискретная случайная переменная.

Непрерывные переменные могут принимать любое значение в определённом интервале. Например, даже если мы записываем, что рост человека — 175см, т.е. округляем до 1 сантиметра, на самом деле он может быть 175.8231см. Изображают непрерывные переменные обычно с помощью кривой плотоности вероятности (probability density function, pdf):

Про вероятности - 6

Код

Pkg.add("Distributions")
using Distributions

xs = 140:0.1:200
ys = [pdf(Normal(172, 10), x) for x in xs]
plot(xs, ys; xlabel="h", ylabel="p(h)", legend=false, show=true)

График плотности вероятности — штука хитрая: в отличие от графика массы вероятности для дискретных переменных, где высота каждой колонки показывает непосредственно вероятность получить такое значение, плотность вероятности показывает относительное количество вероятности вокруг некоторой точки. Саму же вероятность в этом случае можно посчитать только для интервала. Например, в этом примере вероятность, что случайно взятый человек из нашей выборки будет иметь рост от 160 до 170см равна примерно 0.3.

Код

d = Normal(172, 10)
prob = cdf(d, 170) - cdf(d, 160)

Вопрос: может ли плотность вероятности в какой-то точке быть больше единицы? Ответ — да, конечно, главное, чтобы общая площадь под графиком (или, говоря математически, интеграл плотности вероятности) был равен единице.

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

$p(x)=frac{1}{sqrt{2pi sigma^2}}e^{-frac{(x - mu)^2}{2sigma^2}}$

где $mu$ (мат. ожидание, mean) и $sigma^2$ (дисперсия, variance) — параметры распределения. Т.е. имея всего 2 числа мы можем полностью описать распределение, посчитать его плотность вероятности в любой точке или суммарную веростность между двумя значениями. К сожалению, далеко не для любого набора данных найдётся распределение, которое сможет его красиво описать. Есть много способов бороться с этим (взять хотя бы смесь нормальных распределений), но это уже совсем другая тема.

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

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

Обычно мы рассматриваем свойства объекта не по одному, а в комбинации с другими, и здесь появляется понятие совместного распределения (joint probability) нескольких переменных. Для двух дискретных переменных мы можем изобразить его в виде таблицы (g — gender, c — # of children):

c=0 c=1 c=2
g=0 0.1 0.1 0.1
g=1 0.2 0.4 0.1

Согласно этому распределению, вероятность встретить в нашем наборе данных женщину с 2-мя детьми равна $p(g=0, c=2)=0.1$, а бездетного мужчину — $p(g=1, c=0)=0.2$.

Для двух непрерывных переменных, например, роста и возраста, нам снова придётся задать аналитическую функцию распределения $p(h, a)$, аппроксимировав его,
например, многомерным нормальным. Таблицей это не запишешь, зато можно нарисовать:

Про вероятности - 13

Код

d = MvNormal([172.0, 30.0], [10 0; 0 5])
xs = 160:0.1:180
ys = 22:1:38
zs = [pdf(d, [x, y]) for x in xs, y in ys]
surface(zs)

Имея совместное распределение, мы можем найти распределение каждой переменной по отдельности, просто суммировав (в случае дискретных) или интегрировав (в случае непрерывных) остальные переменные:

$p(g)=sum_c p(g, c)\ p(h)=int p(a, h) da$

Это можно представить в виде суммирования по каждой строке или столбцу таблицы и вынесением результат на поля таблицы:

c=0 c=1 c=2
g=0 0.1 0.1 0.1 0.3
g=1 0.2 0.4 0.1 0.7

Так мы снова получаем $p(g=0)=0.3$ и $p(g=1)=0.7$. Процесс вынесения на поля (margin) даёт название и самому получившемуся распределению — маргинальное (marginal probability).

А что, если мы уже знаем значение одной из переменных? Например, мы видим, что перед нами мужчина и хотим получить распределение вероятностей количества его детей? Таблица совместной вероятности и тут нам поможет: поскольку мы уже точно знаем, что перед нами мужчина, т.е. $g=1$, мы можем выбросить из рассмотрения все остальные варианты и рассматривать только одну строчку:

c=0 c=1 c=2
g=1 0.2 0.4 0.1

$bar{p}(c=0 | g=1)=0.2\ bar{p}(c=1 | g=1)=0.4\ bar{p}(c=2 | g=1)=0.1$

Поскольку вероятности так или иначе должны суммироваться в единицу, получившиеся значения нужно нормализовать, после чего получится:

$p(c=0 | g=1)=0.29\ p(c=1 | g=1)=0.57\ p(c=2 | g=1)=0.14$

Распределение одной переменной при известном значении другой называется условным (conditional probability).

Правило цепи

А соединяются все эти вероятности одной просто формулой, которая называется правилом цепи (chain rule, не путать с правилом цепи в дифференцировании):

$p(x, y)=p(y|x)p(x)$

Формула эта симметричная, поэтому так тоже можно:

$p(x, y)=p(x|y)p(y)$

Интерпретация правила очень простая: если $p(x)$ — вероятность того, что я пойду на красный свет, а $p(y|x)$ — вероятность того, что человек, переходящий на красный свет, будет сбит, то совместная вероятность пойти на красный свет и быть сбитым как раз и равна произведению вероятностей этих двух событий. Но вообще лучше ходите на зелёный.

Зависимые и независимые переменные

Как уже говорилось, если у нас есть таблица совместного распределения, то мы знаем про систему всё: можно вычислить маргинальную веростность любой переменной, можно условное распределение одной переменной при известной другой и т.д. К сожалению, на практике составить такую таблицу (или просчитать параметры непрерывного распределения) в большинстве случаев невозможно. Например, если мы захотим посчитать совместное распределение встречаемости 1000 слов, то нам понадобится таблица из

107150860718626732094842504906000181056140481170553360744375038837035105112493612
249319837881569585812759467291755314682518714528569231404359845775746985748039345
677748242309854210746050623711418779541821530464749835819412673987675591655439460
77062914571196477686542167660429831652624386837205668069376

(чуть больше 1e301) ячеек. Для сравнения, количество атомов в наблюдаемой вселенной равно примерно 1e81. Пожалуй, покупкой дополнительной планки памяти тут не обойдёшься.

Но есть одна приятная деталь: не все переменные зависят друг от друга. Вероятность того, пойдёт ли завтра дождь, вряд ли зависит от того, перехожу ли я дорогу на красный свет. Для независимых переменных условное распределение одной от другой равно просто маргинальному распределению:

$p(y|x)=p(y)$

По-честному, совместная вероятность 1000 слов записывается так:

$p(w_1, w_2, ..., w_{1000})=p(w_1) times p(w_2|w_1) times p(w_3|w_1, w_2) times ... times p(w_{1000}|w_1, w_2, ...)$

А вот если мы "наивно" предположим, что слова не зависят друг от друга, то формула превратится в:

$p(w_1, w_2, ..., w_{1000})=p(w_1) times p(w_2) times p(w_3) times ... times p(w_{1000})$

А чтобы сохранить вероятности $p(w_i)$ для 1000 слов нужна таблица всего с 1000 ячеек, что вполне приемлемо.

Почему тогда не считать все переменные независимыми? Увы, так мы потеряем массу информации. Представим, что мы хотим посчитать вероятность того, что пациент болен гриппом в зависимости от двух переменных: боли в горле и повышенной температуры. Отдельно боль в горле может говорить как о болезни, так и том, что пациент только что громко пел. Отдельно повышенная температура может говорить как о болезни, так и о том, что человек только что вернулся с пробежки. А вот если мы одновременно наблюдаем и температуру, и боль в горле, то это уже серьёзная причина выписать пациенту больничный.

Логарифм

Очень часто в литературе можно увидеть, что используется не просто вероятность, а её логарифм. Зачем? Всё довольно прозаично:

  1. Логарифм — монотонно возрастающая функция, т.е. для любых $p(x_1)$ и $p(x_2)$ если $p(x_1) > p(x_2)$, то и $log p(x_1) > log p(x_2)$.
  2. Логарифм произведения равен сумме логарифмов: $log (p(x_1) p(x_2))=log p(x_1) + log p(x_2)$.

В примере со словами вероятность встретить любое слово $p(w_i)$, как правило, сильно меньше единицы. Если мы попробуем перемножить много маленьких вероятностей на компьютере с органиченной точностью вычислений, догадываетесь что будет? Ага, очень быстро наши вероятности округляться к нулю. А вот если мы сложим много отдельных логарифмов, то выйти за пределы точности вычислений будет практически невозможно.

Условная вероятность как функция

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

$p(y|x)=f(x) + epsilon$

где $epsilon$ — это некоторый шум. Виды шума — это тоже отдельная тема, в которую мы сейчас влезать не будем, а вот на функции $f(x)$ остановимся поподробней. В примерах с дискретными переменными выше в качестве функции мы использовали простой подсчёт встречаемости. Это само по себе хорошо работает во многих случаях, например, в наивном байесовском классификаторе для текста или поведения пользователей. Чуть более сложная модель — линейная регрессия:

$p(y|x)=f(x) + epsilon=theta_0 + sum_itheta_ix_i + epsilon$

Здесь тоже делается предположение о том, что переменные $x_i$ независимы друг от друга, но распределение $p(y|mathbf{x})$ уже моделируется с помощью линейной функции, параметры которой $mathbf{theta}$ нужно найти.

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

Свёрточная сеть работает с распределением пикселей в локальной области, покрываемой размером фильтра. Рекуррентные сети моделируют условное распределение следующего состояния от предыдущего и входных данных, а также выходной переменной от текущего состояния. Ну, в общем, вы поняли идею.

Теорема Байеса и умножение непрерывных переменных

Помните правило сети?

$p(x, y)=p(y|x)p(x)=p(x|y)p(y)$

Если убрать левую часть, то получим простое и очевидное равенство:

$p(y|x)p(x)=p(x|y)p(y)$

А если теперь перенесём $p(x)$ направо, то получим знаменитую формулу Байеса:

$p(y|x)=frac{p(x|y)p(y)}{p(x)}$

Про произношение

Итересный факт: русское произношение "байес" в английском звучит как слово "bias", т.е. "смещение". А вот фамилия учёного "Bayes" читается как "бэйс" или "бэйес" (лучше послушать в Yandex Translate).

Формула настолько избитая, что каждая её часть имеет своё название:

  • $p(y)$ называется априорным распределением (prior). Это то, что мы знаем ещё до того, как увидели конкретный объект, например, общее количество людей, вовремя выплативших кредит.
  • $p(x|y)$ носит название правдоподобия (likelihood). Это вероятность увидеть такой объект (описанный переменной $x$) при таком значении выходной переменной $y$. Например, вероятность того, что у человека, отдавшего кредит, двое детей.
  • $p(x)=int p(x, y) dy$ — маргинальное правдоподобие, вероятность вообще увидеть такой объект. Оно одинаково для всех $y$, так что его чаще всего не считают, а просто максимизируют числитель формулы Байеса.
  • $p(y|x)$ — апостериорное распределение (posterior). Это распределение вероятностей переменной $y$ после того, как мы увидели объект. Например, вероятность того, что человек с двумя детьми отдаст кредит вовремя.

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

Допустим, что у нас есть два распределения $p_1(y)$ и $p_2(y)$:

Про вероятности - 55

Код

d1 = Normal(175, 5)
d2 = Normal(168, 5)
space = 150:0.1:200
y1 = [pdf(d1, y) for y in space]
y2 = [pdf(d2, y) for y in space]
plot(space, y1, label="p_1(y)")
plot!(space, y2, label="p_2(y)")

И мы хотим получить их произведение:

$p(y)=p_1(y)p_2(y)$

Мы знаем плотность вероятности обоих распределений в каждой точке, поэтому, по-честному и в общем случае, нам нужно перемножить плотности в каждой точке. Но, если мы вели себя хорошо, то $p_1(y)$ и $p_2(y)$ у нас заданы параметрами, например, для нормального распределения 2-мя числами — матожиданием и дисперсией, а для их произведения придётся считать вероятность в каждой точке?

К счастью, произведение многих известных распределений даёт другое известное распределение с легко вычислимыми параметрами. Ключевое слово здесь — conjugate prior.

Как бы мы не вычисляли, произведение двух нормальных распределений даёт ещё одно нормальное распределение (правда, ненормализованное):

Про вероятности - 59

Код

# честно перемножаем плотности вероятности в каждой точке
# неэффективно, но работает для любых распределений
plot(space, y1 .* y2, label="p_1(y)p_2(y)")

Ну и просто для сравнения распределение смеси 3х нормальных распределений:

Про вероятности - 60

Код

plot(space, [pdf(Normal(130, 5), x) for x in space] .+ 
                 [pdf(Normal(150, 20), x) for x in space] .+ 
                 [pdf(Normal(190, 3), x) for x in space])

Вопросы

Раз уж это туториал и кто-нибудь наверняка захочет запомнить то, что здесь было написано, вот несколько вопросов для закрепления материала.

Пусть рост человека — случайная переменная с параметрами $mu=172$ и $sigma^2=10$. Какова вероятность встретить человека ростом ровно 178см?

Ответ

Правильными ответами можно считать "0", "бесконечно мала" или "не определена". А всё потому что вероятность непрерывной переменной считается на некотором интервале. Для точки интервал — это её ширина, в зависимости от того, где вы учили математику, длину точки можно считать нулём, бесконечно малой или вообще не определённой.

Пусть $x$ — количество детей у заёмщика кредита (3 возможными значения), $y$ — признак того, отдал ли человек кредит (2 возможных значения). Мы используем формулу Байеса для предсказания, отдаст ли конкретный клиент с 1 ребёнком кредит. Сколько возможных значений может принимать априорное и апостериорное распределения, а также правдоподобие и маргинальное правдоподобие?

Ответ

Таблица совместного распредления двух переменных в данном случае небольшая и имеет вид:

c=0 c=1 c=2
s=0 p(s=0,c=0) p(s=0,c=1) p(s=0,c=2)
s=1 p(s=1,c=0) p(s=1,c=1) p(s=1,c=2)

где $s$ — признак успешно отданного кредита.

Формула Байеса в данном случае имеет вид:

$p(s|c)=frac{p(c|s)p(s)}{p(c)}$

Если все значения известны, то:

  • $p(c)$ — это маргинальная вероятность увидеть человека с одним ребёнком, считается как сумма по колонке $с=1$ и является просто числом.
  • $p(s)$ — априорная/маргинальная вероятность того, что случайно взятый человек, про которого мы ничего не знаем, отдаст кредит. Может иметь 2 значения, соответствующих сумме по первой и по второй строке таблицы.
  • $p(c|s)$ — правдоподобие, условное распределение количества детей в зависимости от успешности кредита. Может показаться, что раз уж это распределение количества детей, то возможных значений должно быть 3, но это не так: мы уже точно знаем, что к нам пришёл человек с одним ребёнком, поэтому рассматриваем только одну колонку таблицы. А вот успешность кредита пока под вопросом, поэтому возможны 2 варианта — 2 строки таблицы.
  • $p(s|c)$ — апостериорное распределение, где мы знаем $c$, но рассматриваем 2 возможных варианта $s$.

Нейронные сети, оптимизирующие расстояние между двумя расспределениями $q(x)$ и $p(x)$, зачастую используют в качестве оптимизационной цели кросс-энтропию (cross entropy) или расстояние Кульбака-Лейблера (Kullback-Leibler divergence). Последнее определяется как:

$KL(q||p)=int q(x) log frac{q(x)}{p(x)}dx$

$int q(x) (.) dx$ — это мат. ожидание по $q(x)$, а почему в основной части — $log frac{q(x)}{p(x)}$ — используется деление, а не просто разница между плотностями двух функций $q(x) - p(x)$?

Ответ

$log frac{q(x)}{p(x)}=log q(x) - log p(x)$

Другими словами, это и есть разница между плотностями, но в логарифмическом пространстве, которе является вычислительно более стабильным.

Автор: ffriend

Источник

* - обязательные к заполнению поля


https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js