Перейти к содержанию

Семплирование по Гиббсу

Эта статья находится на начальном уровне проработки, в одной из её версий выборочно используется текст из источника, распространяемого под свободной лицензией
Материал из энциклопедии Руниверсалис

Семплирование по Гиббсу — алгоритм для генерации выборки совместного распределения множества случайных величин. Он используется для оценки совместного распределения и для вычисления интегралов методом Монте-Карло. Этот алгоритм является частным случаем алгоритма Метрополиса-Гастингса и назван в честь физика Джозайи Гиббса.

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

Применяется семплирование по Гиббсу в тех случаях, когда совместное распределение случайных величин очень велико или неизвестно явно, но условные вероятности известны и имеют простую форму. Семплирование по Гиббсу особенно хорошо используется для работы с апостериорной вероятностью в байесовских сетях, поскольку в них заданы все необходимые условные вероятности.

Алгоритм

Пусть есть совместное распределение [math]\displaystyle{ p(x_1,...,x_d) }[/math] для [math]\displaystyle{ d }[/math] случайных величин, причём [math]\displaystyle{ d }[/math] может быть очень большим. Пусть на шаге [math]\displaystyle{ t }[/math] мы уже выбрали какое-то значение [math]\displaystyle{ X = \{x^t_i\} }[/math]. На каждом шаге делаются следующие действия:

  1. Выбирается индекс [math]\displaystyle{ i: (1 \le i \le d }[/math]).
  2. [math]\displaystyle{ x^{t+1}_i }[/math] выбирается по распределению [math]\displaystyle{ p(x_i | x^{t}_1,...,x^{t}_{i-1},x^{t}_{i+1},...,x^t_d) }[/math], а для остальных индексов значение не меняется: [math]\displaystyle{ x^{t+1}_j = x^t_j }[/math] (j≠i).

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

Пример

Пусть есть совместное распределение [math]\displaystyle{ p(x_1,x_2,x_3) }[/math] из трех случайных величин, каждая из которых находится в диапазоне от 0 до 10.

Примем, что первоначальное значение вектора, от которого начнется итерационный процесс, будет [math]\displaystyle{ X = \{5,2,7\} }[/math].

Далее фиксируем [math]\displaystyle{ x_2 }[/math] и [math]\displaystyle{ x_3 }[/math], после чего рассчитываем по известной заранее формуле условную вероятность [math]\displaystyle{ p(x_1 | x_2,x_3) }[/math], то есть [math]\displaystyle{ p(x_1 | x_2=2,x_3=7) }[/math], получая некоторый график плотности вероятности от переменной [math]\displaystyle{ x_1 }[/math]. То, что изначально [math]\displaystyle{ x_1 }[/math] мы положили равным 5, забываем, больше это значение не понадобится.

Теперь необходимо выполнить семплирование — сгенерировать новое случайное значение для [math]\displaystyle{ x_1 }[/math] в соответствии с полученной плотностью вероятности. Семплирование можно сделать, например, по алгоритму выборки с отклонением. Для этого генерируется случайное число с равномерным распределением от 0 до 10, после чего для этого сгенерированного числа вычисляется его вероятность по графику плотности вероятности [math]\displaystyle{ p(x_1 | x_2=2,x_3=7) }[/math].

Например, пусть сгенерировалось случайное число 4 и по графику плотности его вероятность равна 0.2. Тогда, в соответствии с алгоритмом выборки с отклонением, мы принимаем это сгенерированное число с вероятностью 0.2. А для этого, в свою очередь, генерируем ещё одно случайное число от 0 до 1 с равномерным распределением, и, если сгенерировалось число меньше 0.2, то мы принимаем число 4 как успешное. Иначе повторяем сначала — генерируем ещё одно число (например выпадает 3), для него находим вероятность (например, 0.3), для него генерируем ещё число от 0 до 1 (например, 0.1) и тогда уже принимаем окончательно, что на этой итерации [math]\displaystyle{ x_1=3 }[/math].

Далее необходимо повторить все действия выше с величиной [math]\displaystyle{ x_2 }[/math], причём [math]\displaystyle{ x_1 }[/math] мы уже используем «новое» — в нашем примере равное 3. Так, рассчитываем плотность вероятности [math]\displaystyle{ p(x_2 | x_1=3,x_3=7) }[/math], генерируем снова случайное число на роль кандидата нового значения [math]\displaystyle{ x_2 }[/math], делаем выборку с отклонением и повторяем её в случае, если значение «отклонено».

Аналогично действия повторяются для [math]\displaystyle{ x_3 }[/math] с новыми значениями [math]\displaystyle{ x_1 }[/math] и [math]\displaystyle{ x_2 }[/math]. Первая итерация алгоритма семплирования по Гиббсу завершена. Через несколько сотен/тысяч таких итераций случайные значения должны прийти к максимуму своей плотности, который может быть расположен достаточно далеко от нашего первого приближения [math]\displaystyle{ X = \{5,2,7\} }[/math] и семплироваться в той области. Дальнейшая тысяча итераций может уже использоваться по назначению (для поиска математического ожидания, например) как образец значений искомого распределения, не зависящих от первоначального вектора [math]\displaystyle{ X = \{5,2,7\} }[/math].

См. также

Ссылки