<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="ru">
		<id>http://neerc.ifmo.ru/wiki/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=94.229.111.244&amp;*</id>
		<title>Викиконспекты - Вклад участника [ru]</title>
		<link rel="self" type="application/atom+xml" href="http://neerc.ifmo.ru/wiki/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=94.229.111.244&amp;*"/>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=%D0%A1%D0%BB%D1%83%D0%B6%D0%B5%D0%B1%D0%BD%D0%B0%D1%8F:%D0%92%D0%BA%D0%BB%D0%B0%D0%B4/94.229.111.244"/>
		<updated>2026-06-11T20:34:36Z</updated>
		<subtitle>Вклад участника</subtitle>
		<generator>MediaWiki 1.30.0</generator>

	<entry>
		<id>http://neerc.ifmo.ru/wiki/index.php?title=EM-%D0%B0%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC&amp;diff=73030</id>
		<title>EM-алгоритм</title>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=EM-%D0%B0%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC&amp;diff=73030"/>
				<updated>2020-03-21T11:51:23Z</updated>
		
		<summary type="html">&lt;p&gt;94.229.111.244: Исправил положение точки&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Определение ==&lt;br /&gt;
&lt;br /&gt;
'''Алгоритм EM''' (англ. ''expectation-maximization'') {{---}} итеративный алгоритм поиска оценок максимума правдоподобия модели, в ситуации, когда она зависит от скрытых (ненаблюдаемых) переменных.&lt;br /&gt;
&lt;br /&gt;
Алгоритм ищет параметры модели итеративно, каждая итерация состоит из двух шагов:&lt;br /&gt;
&lt;br /&gt;
'''E (Expectation)''' шаг {{---}} поиск наиболее вероятных значений скрытых переменных.&lt;br /&gt;
&lt;br /&gt;
'''M (Maximization)''' шаг {{---}} поиск наиболее вероятных значений параметров, для полученных на шаге E значений скрытых переменных.&lt;br /&gt;
&lt;br /&gt;
EM алгоритм подходит для решения задач двух типов:&lt;br /&gt;
&lt;br /&gt;
# Задачи с неполными данными.&lt;br /&gt;
# Задачи, в которых удобно вводить скрытые переменные для упрощения подсчета функции правдоподобия. Примером такой задачи может служить кластеризация.&lt;br /&gt;
&lt;br /&gt;
== Основной алгоритм == &lt;br /&gt;
&lt;br /&gt;
=== Постановка задачи ===&lt;br /&gt;
&lt;br /&gt;
Плотность распределения смеси имеет вид:&amp;lt;br/&amp;gt;&lt;br /&gt;
&amp;lt;tex&amp;gt;p(x) = \sum\limits_{j=1}^k w_j p_j(x)&amp;lt;/tex&amp;gt;.&amp;lt;br/&amp;gt;&lt;br /&gt;
Где &amp;lt;tex&amp;gt; \sum\limits_{j=1}^k w_j = 1;  w_j \geq 0; p_j(x) = \phi(x;\theta_j)&amp;lt;/tex&amp;gt; {{---}} функция правдоподобия &amp;lt;tex&amp;gt;j&amp;lt;/tex&amp;gt;-ой компонеты смеси, &amp;lt;tex&amp;gt;w_j&amp;lt;/tex&amp;gt; {{---}} априорная вероятность &amp;lt;tex&amp;gt;j&amp;lt;/tex&amp;gt;-ой компоненты смеси.&amp;lt;br/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Перед нами стоит две задачи:&amp;lt;br/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
# По заданной выборке &amp;lt;tex&amp;gt;X^m&amp;lt;/tex&amp;gt; случайных и независимых наблюдений полученных из смеси &amp;lt;tex&amp;gt;p(x)&amp;lt;/tex&amp;gt;, числу &amp;lt;tex&amp;gt;k&amp;lt;/tex&amp;gt; и функции &amp;lt;tex&amp;gt;\phi&amp;lt;/tex&amp;gt;, оценить вектор параметров &amp;lt;tex&amp;gt;\Theta = (w_1,..,w_k,\theta_1,..,\theta_k)&amp;lt;/tex&amp;gt;.&lt;br /&gt;
# Найти &amp;lt;tex&amp;gt;k&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Проблема === &lt;br /&gt;
&lt;br /&gt;
Задачи подобного рода мы умеем решать, максимизируя логармиф правдоподобия:&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;tex&amp;gt; Q(\Theta) = ln \prod\limits_{i=1}^mp(x_i) = \sum\limits_{i=1}^m ln\sum\limits_{j=1}^k w_j p_j(x_i; \theta_j) \longrightarrow \max\limits_{\Theta}&amp;lt;/tex&amp;gt;.&amp;lt;br/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Но проблeма в том, что мы не знаем как аналитически посчитать логарифм суммы. Тут нам и поможет алгоритм EM.&lt;br /&gt;
&lt;br /&gt;
=== Решение === &lt;br /&gt;
&lt;br /&gt;
Основная идея алгоритма EM заключается в том, что мы добавляем скрытые переменные такие, что:&amp;lt;br/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
# Они могут быть выражены через &amp;lt;tex&amp;gt;\Theta&amp;lt;/tex&amp;gt;.&lt;br /&gt;
# Они помогают разбить сумму так: &amp;lt;tex&amp;gt;p (X, H|\Theta) = \prod\limits_{i=1}^k p (X|H, \Theta) p(H|\Theta)&amp;lt;/tex&amp;gt;, где &amp;lt;tex&amp;gt;H&amp;lt;/tex&amp;gt; {{---}} матрица скрытых переменных.&lt;br /&gt;
&lt;br /&gt;
Тогда алгоритм EM сводится к повторению шагов, указанных в [[#Определение|Определении]].&lt;br /&gt;
&lt;br /&gt;
=== E-шаг === &lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt;p(x,\theta_j) = p(x)P(\theta_j | x) = w_jp_j(x)&amp;lt;/tex&amp;gt;.&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Скрытые переменные представляют из себя матрицу &amp;lt;tex&amp;gt;H = (h_{ij})_{m \times k}&amp;lt;/tex&amp;gt;,&amp;lt;br/&amp;gt;&lt;br /&gt;
где &amp;lt;tex&amp;gt;h_{ij} = P(\theta_j | x_i)&amp;lt;/tex&amp;gt; {{---}} вероятность того, что &amp;lt;tex&amp;gt;x_i&amp;lt;/tex&amp;gt; пренадлежит &amp;lt;tex&amp;gt;j&amp;lt;/tex&amp;gt;-ой компоненте.&amp;lt;br/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
По формуле Байеса справедливо равенство:&amp;lt;br /&amp;gt;&lt;br /&gt;
&amp;lt;tex&amp;gt; h_{ij} = \frac{w_jp_j(x_i)}{p (x_i)} = \frac{w_jp_j(x_i)}{\sum\limits_{s=1}^k w_s p_s(x_i)}&amp;lt;/tex&amp;gt;.&amp;lt;br/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Также &amp;lt;tex&amp;gt;\sum\limits_{j=1}^k h_{ij} = 1&amp;lt;/tex&amp;gt;.&amp;lt;br/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Таким образом, зная значения вектора параметров &amp;lt;tex&amp;gt;\Theta&amp;lt;/tex&amp;gt;, мы легко можем пересчитать значения скрытых переменных.&amp;lt;br/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== M-шаг === &lt;br /&gt;
&lt;br /&gt;
{{Теорема&lt;br /&gt;
|statement=&lt;br /&gt;
Если известны скрытые переменные, то задача минимизации &amp;lt;tex&amp;gt;Q(\Theta)&amp;lt;/tex&amp;gt; сводится к &amp;lt;tex&amp;gt;k&amp;lt;/tex&amp;gt; независимым подзадачам:&amp;lt;br/&amp;gt;&lt;br /&gt;
&amp;lt;center&amp;gt;&amp;lt;tex&amp;gt;\theta_j = \arg\max\limits_{\theta}\sum\limits_{i=1}^m h_{ij}*\ln\phi(x_i;\theta)&amp;lt;/tex&amp;gt;.&amp;lt;/center&amp;gt;&lt;br /&gt;
Оптимальные же веса считаются как:&amp;lt;br/&amp;gt;&lt;br /&gt;
&amp;lt;center&amp;gt;&amp;lt;tex&amp;gt; w_j = \frac {1} {m} \sum\limits_{i=1}^m h_{ij}&amp;lt;/tex&amp;gt;.&amp;lt;/center&amp;gt;&lt;br /&gt;
|proof=&lt;br /&gt;
Посчитаем логарифм правдоподобия:&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;tex&amp;gt; Q(\Theta) = \sum\limits_{i=1}^m ln\sum\limits_{j=1}^k w_j p_j(x_i; \theta_j) \longrightarrow \max\limits_{\Theta}&amp;lt;/tex&amp;gt;.&amp;lt;br/&amp;gt;&lt;br /&gt;
При условии, что&amp;lt;tex&amp;gt; \sum\limits_{j=1}^k w_j = 1; w_j \geq 0&amp;lt;/tex&amp;gt; имеет смысл рассматривать Лагранжиан задачи:&amp;lt;br/&amp;gt;&lt;br /&gt;
&amp;lt;tex&amp;gt; L(\Theta, X^m) = \sum\limits_{i=1}^m ln \biggl( \sum\limits_{j=1}^k w_j p_j(x_i) \biggr)  - \lambda \biggl(\sum\limits_{j=1}^k w_j - 1 \biggr) &amp;lt;/tex&amp;gt;.&amp;lt;br/&amp;gt;&lt;br /&gt;
Приравняв нулю производную Лагранжиана по &amp;lt;tex&amp;gt;w_j&amp;lt;/tex&amp;gt;, получим:&amp;lt;br/&amp;gt;&lt;br /&gt;
&amp;lt;tex&amp;gt;\frac{\partial L} {\partial w_j} = \sum\limits_{i=1}^m \frac{p_j(x_i)}{\sum\limits_{s=1}^kw_s p_s(x_i)} - \lambda = 0, j = 1..k&amp;lt;/tex&amp;gt;.&amp;lt;br/&amp;gt;&lt;br /&gt;
Умножим на &amp;lt;tex&amp;gt;w_j&amp;lt;/tex&amp;gt; и просуммируем уравнения для всех &amp;lt;tex&amp;gt;j&amp;lt;/tex&amp;gt;:&amp;lt;br /&amp;gt;&lt;br /&gt;
&amp;lt;tex&amp;gt;\sum\limits_{j=1}^k \sum\limits_{i=1}^m \frac{w_jp_j(x_i)}{\sum\limits_{s=1}^kw_s p_s(x_i)} = \lambda \sum\limits_{j=1}^kw_j&amp;lt;/tex&amp;gt;.&amp;lt;br /&amp;gt;&lt;br /&gt;
А так как &amp;lt;tex&amp;gt;\sum\limits_{j=1}^k \frac{w_jp_j(x_i)}{\sum\limits_{s=1}^kw_sp_s(x_i)} = 1&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;\sum\limits_{j=1}^kw_j = 1&amp;lt;/tex&amp;gt;, из чего следует &amp;lt;tex&amp;gt;\lambda = m&amp;lt;/tex&amp;gt;.&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt;w_j = \frac{1}{m}\sum\limits_{i=1}^m \frac{w_jp_j(x_i)}{\sum\limits_{s=1}^kw_sp_s(x_i)} = \frac{1}{m}\sum\limits_{i=1}^m h_{ij}&amp;lt;/tex&amp;gt;.&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Приравняв к нулю производную Лагранжиана по &amp;lt;tex&amp;gt;\theta_j&amp;lt;/tex&amp;gt;, схожим способом найдем:&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt; \theta_j = \arg\max\limits_{\theta}\sum\limits_{i=1}^m h_{ij}*\ln\phi(x_i;\theta).&amp;lt;/tex&amp;gt;&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
=== Критерий остановки === &lt;br /&gt;
&lt;br /&gt;
Алгоритм EM выполняется до сходимости, но как нам определить, что сходимость наступила? Мы можем останавливаться, когда либо &amp;lt;tex&amp;gt;Q(\Theta)&amp;lt;/tex&amp;gt;, либо &amp;lt;tex&amp;gt;H&amp;lt;/tex&amp;gt; перестают сильно меняться. Но, обычно, удобней контролировать изменения значений скрытых переменных, так как они имеют смысл вероятностей и принимают значения из отрезка &amp;lt;tex&amp;gt;[0,1]&amp;lt;/tex&amp;gt;. Поэтому один из возможных критериев остановки будет выглядеть так: &amp;lt;tex&amp;gt;\max\limits_{i,j} |h_{ij} - h_{ij}^{(0)}| &amp;gt; \delta&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Псевдокод === &lt;br /&gt;
&lt;br /&gt;
 Input:&amp;lt;tex&amp;gt;X^m, k, \Theta^{(0)}&amp;lt;/tex&amp;gt;&lt;br /&gt;
 Repeat&lt;br /&gt;
    '''E-step''': for all i = 1..m; j = 1..k:&lt;br /&gt;
        &amp;lt;tex&amp;gt;h_{ij} = \frac{w_j \phi(x_i; \theta_j)}{\sum\limits_{s=1}^k w_s \phi(x_i; \theta_j)}&amp;lt;/tex&amp;gt;&lt;br /&gt;
    '''M-step''': for all j = 1..k:&lt;br /&gt;
        &amp;lt;tex&amp;gt;\theta_j = \arg\max\limits_{\theta} \sum\limits_{i=1}^m h_{ij}*ln \phi (x_i, \theta)&amp;lt;/tex&amp;gt;&lt;br /&gt;
        &amp;lt;tex&amp;gt;w_j = \frac {1} {m} \sum\limits_{i=1}^m h_{ij}&amp;lt;/tex&amp;gt;&lt;br /&gt;
 Until a stopping criterion is satisfied&lt;br /&gt;
 Return &amp;lt;tex&amp;gt;\Theta = (\theta_j, w_j)_{j=1}^k&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Плюсы и минусы === &lt;br /&gt;
&lt;br /&gt;
Плюсы:&amp;lt;br/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Сходится в большинтсве случаев.&lt;br /&gt;
* Наиболее гибкое решение.&lt;br /&gt;
* Существуют простые модификации, позволяющие уменьшить чуствительность алгоритма к шуму в данных.&lt;br /&gt;
&lt;br /&gt;
Минусы:&amp;lt;br/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Чуствителен к начальному приближению. Могут быть ситуации, когда сойдемся к локальному экстремуму.&lt;br /&gt;
* Число компонент &amp;lt;tex&amp;gt;k&amp;lt;/tex&amp;gt; является [[Настройка_гиперпараметров|гиперпараметром]].&lt;br /&gt;
&lt;br /&gt;
== Модификации == &lt;br /&gt;
&lt;br /&gt;
Базовый алгоритм EM является очень гибким для модификаций, позволяющих улучшить его работу. В этом разделе мы приведем краткое описание некоторых из них.&lt;br /&gt;
&lt;br /&gt;
=== Generalized EM-algorithm === &lt;br /&gt;
&lt;br /&gt;
Осоновная идея этой модификации заключается в том, что на шаге M мы не будем пытаться найти наилучшее решение. Это применимо в случаях, когда максимизация &amp;lt;tex&amp;gt;Q(\Theta)&amp;lt;/tex&amp;gt; является сликшом дорогой, поэтому нам достаточно сделать лишь несколько итераций, для того, чтобы сместиться в сторону максимума значения &amp;lt;tex&amp;gt;Q(\Theta)&amp;lt;/tex&amp;gt;. Эта модификация имеет неплохую сходимость.&lt;br /&gt;
&lt;br /&gt;
=== Stochastic EM-algorithm ===&lt;br /&gt;
&lt;br /&gt;
Как уже было отмечено в [[#Плюсы_и_минусы|Плюсы и минусы]], базовый алгоритм чувствителен к начальному приближению и могут быть ситуации, когда алгоритм &amp;quot;застрянет&amp;quot; в локальном экстремуме. Для того, чтобы предотвратить это, будем на каждой итерации алгоритма случайно &amp;quot;встряхивать&amp;quot; выборку. В этой модификации у нас добавляется шаг S, на котором мы и будем &amp;quot;встряхивать&amp;quot; выборку. И на шаге M мы будем решать уже задачу максимуму невзвешенного правдоподобия. Эта модификация хороша тем, что нечуствиетльная к начальном приблежению. &lt;br /&gt;
&lt;br /&gt;
== Пример. Разделение смеси Гауссиана == &lt;br /&gt;
&lt;br /&gt;
[[Файл:Gaussians2.png|right|thumb|400px|Несколько итераций алгоритма]]&lt;br /&gt;
&lt;br /&gt;
Каноническим примером использования EM алгоритма является задача разделения смеси гауссиана. Данные у нас получены из нормального распределения. В этом случае параметрами функций ялвяются матожидание и дисперсия.&amp;lt;br/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt;\theta = (w_1,..,w_k;\;\mu_1,..,\mu_k;\;\sigma_1,..,\sigma_k)&amp;lt;/tex&amp;gt; {{---}} вектор параметров, &amp;lt;br/&amp;gt;&lt;br /&gt;
&amp;lt;tex&amp;gt;p_j(x) = N(x;\mu_j, \sigma_j) = \frac1{\sqrt{2\pi}\sigma_j} \exp \biggl(-\frac{(x - \mu_j)^2}{2\sigma_j^2}\biggr) &amp;lt;/tex&amp;gt; {{---}} плотность распределения.&amp;lt;br/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Посчитаем значения для каждого шага. &amp;lt;br/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
E-шаг:&lt;br /&gt;
&lt;br /&gt;
: &amp;lt;tex&amp;gt; h_{ij} = \frac{w_j N(x_i, \mu_j, \sigma_j)}{\sum\limits_{s=1}^k w_s N(x_i, \mu_s, \sigma_s)}.&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
M-шаг:&lt;br /&gt;
&lt;br /&gt;
: &amp;lt;tex&amp;gt;w_j = \frac{1}{m} \sum\limits_{i=1}^m h_{ij}.&amp;lt;/tex&amp;gt;&lt;br /&gt;
: &amp;lt;tex&amp;gt; \mu_j = \frac {1} {mw_j} \sum\limits_{i=1}^m h_{ij}x_i.&amp;lt;/tex&amp;gt;&lt;br /&gt;
: &amp;lt;tex&amp;gt; \sigma_j^2 = \frac {1} {mw_j} \sum\limits_{i=1}^m h_{ij}(x_i - \mu_j)^2, j = 1..k.&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Использование в задаче кластеризации ==&lt;br /&gt;
&lt;br /&gt;
[[Файл:kmeans.jpg|right|thumb|200px|Пример работы k-means]]&lt;br /&gt;
&lt;br /&gt;
Как уже упоминалось в [[#Определение|Определении]], алгоритм EM подходит для решения задачи кластеризации. И одной из его имплементаций для этой задачи является алгоритм [[Алгоритм_k-Means|&amp;lt;tex&amp;gt;k&amp;lt;/tex&amp;gt;-Means]]. В этом алгоритме в качестве скрытых переменных выступают метки классов объектов. Параметрами же являются центроиды искомых классов. Тогда на шаге E мы относим объекты к какому-то одному классу на основе расстояний до центроид. А на шаге M мы пересчитываем центроиды кластеров, исходя из полученной на шаге E разметке.&amp;lt;br/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Также стоит упомянуть алгоритм &amp;lt;tex&amp;gt;c&amp;lt;/tex&amp;gt;-means&amp;lt;ref&amp;gt;[https://en.wikipedia.org/wiki/Fuzzy_clustering#Fuzzy_C-means_clustering C-means clustering, Wikipedia]&amp;lt;/ref&amp;gt;. В нем качестве скрытых переменных выступают вероятности принадлежности объекта к классам. На шаге E мы пересчитывем вероятности принадлежности объектов, иходя из расстояния до центроид. Шаг M, идейно, остается без изменений.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Реализация на python ==&lt;br /&gt;
&lt;br /&gt;
В пакете sklearn алгоритм EM представлен объектом GaussianMixture. Проиллюстрируем его работу на примере задачи кластеризации и сравним его с алгоритмом &amp;lt;tex&amp;gt;k&amp;lt;/tex&amp;gt;-means:&lt;br /&gt;
 &lt;br /&gt;
 [[Файл:em_clustering.png|thumb|600px|Результат выполнения программы]]&lt;br /&gt;
 '''import''' numpy as np&lt;br /&gt;
 '''import''' matplotlib.pyplot as plt&lt;br /&gt;
 '''from''' sklearn '''import''' cluster, datasets, mixture&lt;br /&gt;
 '''from''' sklearn.preprocessing '''import''' StandardScaler&lt;br /&gt;
 '''from''' itertools '''import''' cycle, islice&lt;br /&gt;
 np.random.seed(12)&lt;br /&gt;
 &lt;br /&gt;
 &amp;lt;font color=&amp;quot;green&amp;quot;&amp;gt;# Создаем datasets с использованием стандартных sklearn.datasets&amp;lt;/font&amp;gt;&lt;br /&gt;
 n_samples = 2000&lt;br /&gt;
 random_state = 170&lt;br /&gt;
 noisy_circles = datasets.make_circles(n_samples=n_samples, factor=.5, noise=.05)&lt;br /&gt;
 noisy_moons = datasets.make_moons(n_samples=n_samples, noise=.05)&lt;br /&gt;
 blobs = datasets.make_blobs(n_samples=n_samples, random_state=8)&lt;br /&gt;
 varied = datasets.make_blobs(n_samples=n_samples, cluster_std=[1.0, 2.5, 0.5], random_state=random_state)&lt;br /&gt;
 &lt;br /&gt;
 &amp;lt;font color=&amp;quot;green&amp;quot;&amp;gt;# Создаем анизатропно разделенные данные&amp;lt;/font&amp;gt;&lt;br /&gt;
 X, y = datasets.make_blobs(n_samples=n_samples, random_state=random_state)&lt;br /&gt;
 transformation = [[0.6, -0.6], [-0.4, 0.8]]&lt;br /&gt;
 X_aniso = np.dot(X, transformation)&lt;br /&gt;
 aniso = (X_aniso, y)&lt;br /&gt;
 &lt;br /&gt;
 &amp;lt;font color=&amp;quot;green&amp;quot;&amp;gt;# Выставляем параметры для matplotlib.pyplot&amp;lt;/font&amp;gt;&lt;br /&gt;
 plt.figure(figsize=(9 * 2 + 3, 12.5))&lt;br /&gt;
 plt.subplots_adjust(left=.02, right=.98, bottom=.001, top=.96, wspace=.05, hspace=.01)&lt;br /&gt;
 plot_num = 1&lt;br /&gt;
 defaul_n = 3&lt;br /&gt;
 &lt;br /&gt;
 &amp;lt;font color=&amp;quot;green&amp;quot;&amp;gt;# Варьируем значение количества классов в зависимости от данных, ведь для нас это гиперпараметр&amp;lt;/font&amp;gt;&lt;br /&gt;
 datasets = [&lt;br /&gt;
    (varied, defaul_n),&lt;br /&gt;
    (aniso, defaul_n),&lt;br /&gt;
    (blobs, defaul_n),&lt;br /&gt;
    (noisy_circles, 2)]&lt;br /&gt;
 for i_dataset, (dataset, n_cluster) in enumerate(datasets):&lt;br /&gt;
    X, y = dataset&lt;br /&gt;
 &lt;br /&gt;
    &amp;lt;font color=&amp;quot;green&amp;quot;&amp;gt;# Нормализация данных&amp;lt;/font&amp;gt;&lt;br /&gt;
    X = StandardScaler().fit_transform(X)&lt;br /&gt;
 &lt;br /&gt;
    &amp;lt;font color=&amp;quot;green&amp;quot;&amp;gt;# Непосредственно наш алгоритм - Gaussian Mixture&amp;lt;/font&amp;gt;&lt;br /&gt;
    gmm = mixture.GaussianMixture(n_components=n_cluster, covariance_type='full')&lt;br /&gt;
    &lt;br /&gt;
    &amp;lt;font color=&amp;quot;green&amp;quot;&amp;gt;# Для сравнения берем алгоритм - k-means&amp;lt;/font&amp;gt;&lt;br /&gt;
    two_means = cluster.KMeans(n_clusters=n_cluster)&lt;br /&gt;
    clustering_algorithms = {&lt;br /&gt;
        'Real distribution': None,&lt;br /&gt;
        'Gaussian Mixture': gmm,&lt;br /&gt;
        'k-Means': two_means&lt;br /&gt;
    }&lt;br /&gt;
    for name, algorithm in clustering_algorithms:&lt;br /&gt;
 &lt;br /&gt;
        # Этап обучения&lt;br /&gt;
        if algorithm is not None:&lt;br /&gt;
            algorithm.fit(X)&lt;br /&gt;
        &lt;br /&gt;
        # Применяем алгоритм&lt;br /&gt;
         y_pred = y if algorithm is None else algorithm.predict(X)&lt;br /&gt;
        &lt;br /&gt;
        # Рисуем результаты&lt;br /&gt;
        plt.subplot(len(datasets), len(clustering_algorithms), plot_num)&lt;br /&gt;
        if i_dataset == 0:&lt;br /&gt;
            plt.title(name, size=18)&lt;br /&gt;
        colors = np.array(list(islice(cycle(['#377eb8', '#ff7f00', '#4daf4a']), int(max(y_pred) + 1))))&lt;br /&gt;
        plt.scatter(X[:, 0], X[:, 1], s=10, color=colors[y_pred])&lt;br /&gt;
        plt.xlim(-2.5, 2.5)&lt;br /&gt;
        plt.ylim(-2.5, 2.5)&lt;br /&gt;
        plt.xticks(())&lt;br /&gt;
        plt.yticks(())&lt;br /&gt;
        plot_num += 1&lt;br /&gt;
 plt.show()&lt;br /&gt;
&lt;br /&gt;
Как и следовало ожидать, алгоритм EM работает на некоторых данных лучше чем k-means, однако есть данные, с которыми он не справляется без дополнительных преобразований.&lt;br /&gt;
&lt;br /&gt;
== См. также ==&lt;br /&gt;
*[[Кластеризация]]&lt;br /&gt;
*[[Алгоритм_k-Means|Алгоритм k-Means]]&lt;br /&gt;
&lt;br /&gt;
==Примечания==&lt;br /&gt;
&amp;lt;references /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Источники информации ==&lt;br /&gt;
&lt;br /&gt;
# Материалы лекции про кластеризацию курса &amp;quot;Машинное обучение&amp;quot; университета ИТМО, 2019 год&lt;br /&gt;
# [http://www.machinelearning.ru/wiki/images/6/6d/Voron-ML-1.pdf Математические методы обучения по прецедентам К. В. Воронцов]&lt;br /&gt;
# [http://www.machinelearning.ru/wiki/index.php?title=EM-%D0%B0%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC Статья про EM-алгоритм на machinelearning.ru]&lt;br /&gt;
# [https://machinelearningmastery.com/expectation-maximization-em-algorithm/ A Gentle Introduction to Expectation-Maximization]&lt;br /&gt;
# [http://dendroid.sk/2011/05/09/k-means-clustering/ k-means]&lt;br /&gt;
&lt;br /&gt;
[[Категория: Машинное обучение]]&lt;br /&gt;
[[Категория: Кластеризация]]&lt;/div&gt;</summary>
		<author><name>94.229.111.244</name></author>	</entry>

	<entry>
		<id>http://neerc.ifmo.ru/wiki/index.php?title=EM-%D0%B0%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC&amp;diff=73029</id>
		<title>EM-алгоритм</title>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=EM-%D0%B0%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC&amp;diff=73029"/>
				<updated>2020-03-21T11:49:23Z</updated>
		
		<summary type="html">&lt;p&gt;94.229.111.244: Поправил примечание&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Определение ==&lt;br /&gt;
&lt;br /&gt;
'''Алгоритм EM''' (англ. ''expectation-maximization'') {{---}} итеративный алгоритм поиска оценок максимума правдоподобия модели, в ситуации, когда она зависит от скрытых (ненаблюдаемых) переменных.&lt;br /&gt;
&lt;br /&gt;
Алгоритм ищет параметры модели итеративно, каждая итерация состоит из двух шагов:&lt;br /&gt;
&lt;br /&gt;
'''E (Expectation)''' шаг {{---}} поиск наиболее вероятных значений скрытых переменных.&lt;br /&gt;
&lt;br /&gt;
'''M (Maximization)''' шаг {{---}} поиск наиболее вероятных значений параметров, для полученных на шаге E значений скрытых переменных.&lt;br /&gt;
&lt;br /&gt;
EM алгоритм подходит для решения задач двух типов:&lt;br /&gt;
&lt;br /&gt;
# Задачи с неполными данными.&lt;br /&gt;
# Задачи, в которых удобно вводить скрытые переменные для упрощения подсчета функции правдоподобия. Примером такой задачи может служить кластеризация.&lt;br /&gt;
&lt;br /&gt;
== Основной алгоритм == &lt;br /&gt;
&lt;br /&gt;
=== Постановка задачи ===&lt;br /&gt;
&lt;br /&gt;
Плотность распределения смеси имеет вид:&amp;lt;br/&amp;gt;&lt;br /&gt;
&amp;lt;tex&amp;gt;p(x) = \sum\limits_{j=1}^k w_j p_j(x)&amp;lt;/tex&amp;gt;.&amp;lt;br/&amp;gt;&lt;br /&gt;
Где &amp;lt;tex&amp;gt; \sum\limits_{j=1}^k w_j = 1;  w_j \geq 0; p_j(x) = \phi(x;\theta_j)&amp;lt;/tex&amp;gt; {{---}} функция правдоподобия &amp;lt;tex&amp;gt;j&amp;lt;/tex&amp;gt;-ой компонеты смеси, &amp;lt;tex&amp;gt;w_j&amp;lt;/tex&amp;gt; {{---}} априорная вероятность &amp;lt;tex&amp;gt;j&amp;lt;/tex&amp;gt;-ой компоненты смеси.&amp;lt;br/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Перед нами стоит две задачи:&amp;lt;br/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
# По заданной выборке &amp;lt;tex&amp;gt;X^m&amp;lt;/tex&amp;gt; случайных и независимых наблюдений полученных из смеси &amp;lt;tex&amp;gt;p(x)&amp;lt;/tex&amp;gt;, числу &amp;lt;tex&amp;gt;k&amp;lt;/tex&amp;gt; и функции &amp;lt;tex&amp;gt;\phi&amp;lt;/tex&amp;gt;, оценить вектор параметров &amp;lt;tex&amp;gt;\Theta = (w_1,..,w_k,\theta_1,..,\theta_k).&amp;lt;/tex&amp;gt;&lt;br /&gt;
# Найти &amp;lt;tex&amp;gt;k&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Проблема === &lt;br /&gt;
&lt;br /&gt;
Задачи подобного рода мы умеем решать, максимизируя логармиф правдоподобия:&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;tex&amp;gt; Q(\Theta) = ln \prod\limits_{i=1}^mp(x_i) = \sum\limits_{i=1}^m ln\sum\limits_{j=1}^k w_j p_j(x_i; \theta_j) \longrightarrow \max\limits_{\Theta}&amp;lt;/tex&amp;gt;.&amp;lt;br/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Но проблeма в том, что мы не знаем как аналитически посчитать логарифм суммы. Тут нам и поможет алгоритм EM.&lt;br /&gt;
&lt;br /&gt;
=== Решение === &lt;br /&gt;
&lt;br /&gt;
Основная идея алгоритма EM заключается в том, что мы добавляем скрытые переменные такие, что:&amp;lt;br/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
# Они могут быть выражены через &amp;lt;tex&amp;gt;\Theta&amp;lt;/tex&amp;gt;.&lt;br /&gt;
# Они помогают разбить сумму так: &amp;lt;tex&amp;gt;p (X, H|\Theta) = \prod\limits_{i=1}^k p (X|H, \Theta) p(H|\Theta)&amp;lt;/tex&amp;gt;, где &amp;lt;tex&amp;gt;H&amp;lt;/tex&amp;gt; {{---}} матрица скрытых переменных.&lt;br /&gt;
&lt;br /&gt;
Тогда алгоритм EM сводится к повторению шагов, указанных в [[#Определение|Определении]].&lt;br /&gt;
&lt;br /&gt;
=== E-шаг === &lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt;p(x,\theta_j) = p(x)P(\theta_j | x) = w_jp_j(x)&amp;lt;/tex&amp;gt;.&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Скрытые переменные представляют из себя матрицу &amp;lt;tex&amp;gt;H = (h_{ij})_{m \times k}&amp;lt;/tex&amp;gt;,&amp;lt;br/&amp;gt;&lt;br /&gt;
где &amp;lt;tex&amp;gt;h_{ij} = P(\theta_j | x_i)&amp;lt;/tex&amp;gt; {{---}} вероятность того, что &amp;lt;tex&amp;gt;x_i&amp;lt;/tex&amp;gt; пренадлежит &amp;lt;tex&amp;gt;j&amp;lt;/tex&amp;gt;-ой компоненте.&amp;lt;br/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
По формуле Байеса справедливо равенство:&amp;lt;br /&amp;gt;&lt;br /&gt;
&amp;lt;tex&amp;gt; h_{ij} = \frac{w_jp_j(x_i)}{p (x_i)} = \frac{w_jp_j(x_i)}{\sum\limits_{s=1}^k w_s p_s(x_i)}&amp;lt;/tex&amp;gt;.&amp;lt;br/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Также &amp;lt;tex&amp;gt;\sum\limits_{j=1}^k h_{ij} = 1&amp;lt;/tex&amp;gt;.&amp;lt;br/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Таким образом, зная значения вектора параметров &amp;lt;tex&amp;gt;\Theta&amp;lt;/tex&amp;gt;, мы легко можем пересчитать значения скрытых переменных.&amp;lt;br/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== M-шаг === &lt;br /&gt;
&lt;br /&gt;
{{Теорема&lt;br /&gt;
|statement=&lt;br /&gt;
Если известны скрытые переменные, то задача минимизации &amp;lt;tex&amp;gt;Q(\Theta)&amp;lt;/tex&amp;gt; сводится к &amp;lt;tex&amp;gt;k&amp;lt;/tex&amp;gt; независимым подзадачам:&amp;lt;br/&amp;gt;&lt;br /&gt;
&amp;lt;center&amp;gt;&amp;lt;tex&amp;gt;\theta_j = \arg\max\limits_{\theta}\sum\limits_{i=1}^m h_{ij}*\ln\phi(x_i;\theta)&amp;lt;/tex&amp;gt;.&amp;lt;/center&amp;gt;&lt;br /&gt;
Оптимальные же веса считаются как:&amp;lt;br/&amp;gt;&lt;br /&gt;
&amp;lt;center&amp;gt;&amp;lt;tex&amp;gt; w_j = \frac {1} {m} \sum\limits_{i=1}^m h_{ij}&amp;lt;/tex&amp;gt;.&amp;lt;/center&amp;gt;&lt;br /&gt;
|proof=&lt;br /&gt;
Посчитаем логарифм правдоподобия:&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;tex&amp;gt; Q(\Theta) = \sum\limits_{i=1}^m ln\sum\limits_{j=1}^k w_j p_j(x_i; \theta_j) \longrightarrow \max\limits_{\Theta}&amp;lt;/tex&amp;gt;.&amp;lt;br/&amp;gt;&lt;br /&gt;
При условии, что&amp;lt;tex&amp;gt; \sum\limits_{j=1}^k w_j = 1; w_j \geq 0&amp;lt;/tex&amp;gt; имеет смысл рассматривать Лагранжиан задачи:&amp;lt;br/&amp;gt;&lt;br /&gt;
&amp;lt;tex&amp;gt; L(\Theta, X^m) = \sum\limits_{i=1}^m ln \biggl( \sum\limits_{j=1}^k w_j p_j(x_i) \biggr)  - \lambda \biggl(\sum\limits_{j=1}^k w_j - 1 \biggr) &amp;lt;/tex&amp;gt;.&amp;lt;br/&amp;gt;&lt;br /&gt;
Приравняв нулю производную Лагранжиана по &amp;lt;tex&amp;gt;w_j&amp;lt;/tex&amp;gt;, получим:&amp;lt;br/&amp;gt;&lt;br /&gt;
&amp;lt;tex&amp;gt;\frac{\partial L} {\partial w_j} = \sum\limits_{i=1}^m \frac{p_j(x_i)}{\sum\limits_{s=1}^kw_s p_s(x_i)} - \lambda = 0, j = 1..k&amp;lt;/tex&amp;gt;.&amp;lt;br/&amp;gt;&lt;br /&gt;
Умножим на &amp;lt;tex&amp;gt;w_j&amp;lt;/tex&amp;gt; и просуммируем уравнения для всех &amp;lt;tex&amp;gt;j&amp;lt;/tex&amp;gt;:&amp;lt;br /&amp;gt;&lt;br /&gt;
&amp;lt;tex&amp;gt;\sum\limits_{j=1}^k \sum\limits_{i=1}^m \frac{w_jp_j(x_i)}{\sum\limits_{s=1}^kw_s p_s(x_i)} = \lambda \sum\limits_{j=1}^kw_j&amp;lt;/tex&amp;gt;.&amp;lt;br /&amp;gt;&lt;br /&gt;
А так как &amp;lt;tex&amp;gt;\sum\limits_{j=1}^k \frac{w_jp_j(x_i)}{\sum\limits_{s=1}^kw_sp_s(x_i)} = 1&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;\sum\limits_{j=1}^kw_j = 1&amp;lt;/tex&amp;gt;, из чего следует &amp;lt;tex&amp;gt;\lambda = m&amp;lt;/tex&amp;gt;.&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt;w_j = \frac{1}{m}\sum\limits_{i=1}^m \frac{w_jp_j(x_i)}{\sum\limits_{s=1}^kw_sp_s(x_i)} = \frac{1}{m}\sum\limits_{i=1}^m h_{ij}&amp;lt;/tex&amp;gt;.&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Приравняв к нулю производную Лагранжиана по &amp;lt;tex&amp;gt;\theta_j&amp;lt;/tex&amp;gt;, схожим способом найдем:&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt; \theta_j = \arg\max\limits_{\theta}\sum\limits_{i=1}^m h_{ij}*\ln\phi(x_i;\theta).&amp;lt;/tex&amp;gt;&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
=== Критерий остановки === &lt;br /&gt;
&lt;br /&gt;
Алгоритм EM выполняется до сходимости, но как нам определить, что сходимость наступила? Мы можем останавливаться, когда либо &amp;lt;tex&amp;gt;Q(\Theta)&amp;lt;/tex&amp;gt;, либо &amp;lt;tex&amp;gt;H&amp;lt;/tex&amp;gt; перестают сильно меняться. Но, обычно, удобней контролировать изменения значений скрытых переменных, так как они имеют смысл вероятностей и принимают значения из отрезка &amp;lt;tex&amp;gt;[0,1]&amp;lt;/tex&amp;gt;. Поэтому один из возможных критериев остановки будет выглядеть так: &amp;lt;tex&amp;gt;\max\limits_{i,j} |h_{ij} - h_{ij}^{(0)}| &amp;gt; \delta&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Псевдокод === &lt;br /&gt;
&lt;br /&gt;
 Input:&amp;lt;tex&amp;gt;X^m, k, \Theta^{(0)}&amp;lt;/tex&amp;gt;&lt;br /&gt;
 Repeat&lt;br /&gt;
    '''E-step''': for all i = 1..m; j = 1..k:&lt;br /&gt;
        &amp;lt;tex&amp;gt;h_{ij} = \frac{w_j \phi(x_i; \theta_j)}{\sum\limits_{s=1}^k w_s \phi(x_i; \theta_j)}&amp;lt;/tex&amp;gt;&lt;br /&gt;
    '''M-step''': for all j = 1..k:&lt;br /&gt;
        &amp;lt;tex&amp;gt;\theta_j = \arg\max\limits_{\theta} \sum\limits_{i=1}^m h_{ij}*ln \phi (x_i, \theta)&amp;lt;/tex&amp;gt;&lt;br /&gt;
        &amp;lt;tex&amp;gt;w_j = \frac {1} {m} \sum\limits_{i=1}^m h_{ij}&amp;lt;/tex&amp;gt;&lt;br /&gt;
 Until a stopping criterion is satisfied&lt;br /&gt;
 Return &amp;lt;tex&amp;gt;\Theta = (\theta_j, w_j)_{j=1}^k&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Плюсы и минусы === &lt;br /&gt;
&lt;br /&gt;
Плюсы:&amp;lt;br/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Сходится в большинтсве случаев.&lt;br /&gt;
* Наиболее гибкое решение.&lt;br /&gt;
* Существуют простые модификации, позволяющие уменьшить чуствительность алгоритма к шуму в данных.&lt;br /&gt;
&lt;br /&gt;
Минусы:&amp;lt;br/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Чуствителен к начальному приближению. Могут быть ситуации, когда сойдемся к локальному экстремуму.&lt;br /&gt;
* Число компонент &amp;lt;tex&amp;gt;k&amp;lt;/tex&amp;gt; является [[Настройка_гиперпараметров|гиперпараметром]].&lt;br /&gt;
&lt;br /&gt;
== Модификации == &lt;br /&gt;
&lt;br /&gt;
Базовый алгоритм EM является очень гибким для модификаций, позволяющих улучшить его работу. В этом разделе мы приведем краткое описание некоторых из них.&lt;br /&gt;
&lt;br /&gt;
=== Generalized EM-algorithm === &lt;br /&gt;
&lt;br /&gt;
Осоновная идея этой модификации заключается в том, что на шаге M мы не будем пытаться найти наилучшее решение. Это применимо в случаях, когда максимизация &amp;lt;tex&amp;gt;Q(\Theta)&amp;lt;/tex&amp;gt; является сликшом дорогой, поэтому нам достаточно сделать лишь несколько итераций, для того, чтобы сместиться в сторону максимума значения &amp;lt;tex&amp;gt;Q(\Theta)&amp;lt;/tex&amp;gt;. Эта модификация имеет неплохую сходимость.&lt;br /&gt;
&lt;br /&gt;
=== Stochastic EM-algorithm ===&lt;br /&gt;
&lt;br /&gt;
Как уже было отмечено в [[#Плюсы_и_минусы|Плюсы и минусы]], базовый алгоритм чувствителен к начальному приближению и могут быть ситуации, когда алгоритм &amp;quot;застрянет&amp;quot; в локальном экстремуме. Для того, чтобы предотвратить это, будем на каждой итерации алгоритма случайно &amp;quot;встряхивать&amp;quot; выборку. В этой модификации у нас добавляется шаг S, на котором мы и будем &amp;quot;встряхивать&amp;quot; выборку. И на шаге M мы будем решать уже задачу максимуму невзвешенного правдоподобия. Эта модификация хороша тем, что нечуствиетльная к начальном приблежению. &lt;br /&gt;
&lt;br /&gt;
== Пример. Разделение смеси Гауссиана == &lt;br /&gt;
&lt;br /&gt;
[[Файл:Gaussians2.png|right|thumb|400px|Несколько итераций алгоритма]]&lt;br /&gt;
&lt;br /&gt;
Каноническим примером использования EM алгоритма является задача разделения смеси гауссиана. Данные у нас получены из нормального распределения. В этом случае параметрами функций ялвяются матожидание и дисперсия.&amp;lt;br/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt;\theta = (w_1,..,w_k;\;\mu_1,..,\mu_k;\;\sigma_1,..,\sigma_k)&amp;lt;/tex&amp;gt; {{---}} вектор параметров, &amp;lt;br/&amp;gt;&lt;br /&gt;
&amp;lt;tex&amp;gt;p_j(x) = N(x;\mu_j, \sigma_j) = \frac1{\sqrt{2\pi}\sigma_j} \exp \biggl(-\frac{(x - \mu_j)^2}{2\sigma_j^2}\biggr) &amp;lt;/tex&amp;gt; {{---}} плотность распределения.&amp;lt;br/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Посчитаем значения для каждого шага. &amp;lt;br/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
E-шаг:&lt;br /&gt;
&lt;br /&gt;
: &amp;lt;tex&amp;gt; h_{ij} = \frac{w_j N(x_i, \mu_j, \sigma_j)}{\sum\limits_{s=1}^k w_s N(x_i, \mu_s, \sigma_s)}.&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
M-шаг:&lt;br /&gt;
&lt;br /&gt;
: &amp;lt;tex&amp;gt;w_j = \frac{1}{m} \sum\limits_{i=1}^m h_{ij}.&amp;lt;/tex&amp;gt;&lt;br /&gt;
: &amp;lt;tex&amp;gt; \mu_j = \frac {1} {mw_j} \sum\limits_{i=1}^m h_{ij}x_i.&amp;lt;/tex&amp;gt;&lt;br /&gt;
: &amp;lt;tex&amp;gt; \sigma_j^2 = \frac {1} {mw_j} \sum\limits_{i=1}^m h_{ij}(x_i - \mu_j)^2, j = 1..k.&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Использование в задаче кластеризации ==&lt;br /&gt;
&lt;br /&gt;
[[Файл:kmeans.jpg|right|thumb|200px|Пример работы k-means]]&lt;br /&gt;
&lt;br /&gt;
Как уже упоминалось в [[#Определение|Определении]], алгоритм EM подходит для решения задачи кластеризации. И одной из его имплементаций для этой задачи является алгоритм [[Алгоритм_k-Means|&amp;lt;tex&amp;gt;k&amp;lt;/tex&amp;gt;-Means]]. В этом алгоритме в качестве скрытых переменных выступают метки классов объектов. Параметрами же являются центроиды искомых классов. Тогда на шаге E мы относим объекты к какому-то одному классу на основе расстояний до центроид. А на шаге M мы пересчитываем центроиды кластеров, исходя из полученной на шаге E разметке.&amp;lt;br/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Также стоит упомянуть алгоритм &amp;lt;tex&amp;gt;c&amp;lt;/tex&amp;gt;-means&amp;lt;ref&amp;gt;[https://en.wikipedia.org/wiki/Fuzzy_clustering#Fuzzy_C-means_clustering C-means clustering, Wikipedia]&amp;lt;/ref&amp;gt;. В нем качестве скрытых переменных выступают вероятности принадлежности объекта к классам. На шаге E мы пересчитывем вероятности принадлежности объектов, иходя из расстояния до центроид. Шаг M, идейно, остается без изменений.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Реализация на python ==&lt;br /&gt;
&lt;br /&gt;
В пакете sklearn алгоритм EM представлен объектом GaussianMixture. Проиллюстрируем его работу на примере задачи кластеризации и сравним его с алгоритмом &amp;lt;tex&amp;gt;k&amp;lt;/tex&amp;gt;-means:&lt;br /&gt;
 &lt;br /&gt;
 [[Файл:em_clustering.png|thumb|600px|Результат выполнения программы]]&lt;br /&gt;
 '''import''' numpy as np&lt;br /&gt;
 '''import''' matplotlib.pyplot as plt&lt;br /&gt;
 '''from''' sklearn '''import''' cluster, datasets, mixture&lt;br /&gt;
 '''from''' sklearn.preprocessing '''import''' StandardScaler&lt;br /&gt;
 '''from''' itertools '''import''' cycle, islice&lt;br /&gt;
 np.random.seed(12)&lt;br /&gt;
 &lt;br /&gt;
 &amp;lt;font color=&amp;quot;green&amp;quot;&amp;gt;# Создаем datasets с использованием стандартных sklearn.datasets&amp;lt;/font&amp;gt;&lt;br /&gt;
 n_samples = 2000&lt;br /&gt;
 random_state = 170&lt;br /&gt;
 noisy_circles = datasets.make_circles(n_samples=n_samples, factor=.5, noise=.05)&lt;br /&gt;
 noisy_moons = datasets.make_moons(n_samples=n_samples, noise=.05)&lt;br /&gt;
 blobs = datasets.make_blobs(n_samples=n_samples, random_state=8)&lt;br /&gt;
 varied = datasets.make_blobs(n_samples=n_samples, cluster_std=[1.0, 2.5, 0.5], random_state=random_state)&lt;br /&gt;
 &lt;br /&gt;
 &amp;lt;font color=&amp;quot;green&amp;quot;&amp;gt;# Создаем анизатропно разделенные данные&amp;lt;/font&amp;gt;&lt;br /&gt;
 X, y = datasets.make_blobs(n_samples=n_samples, random_state=random_state)&lt;br /&gt;
 transformation = [[0.6, -0.6], [-0.4, 0.8]]&lt;br /&gt;
 X_aniso = np.dot(X, transformation)&lt;br /&gt;
 aniso = (X_aniso, y)&lt;br /&gt;
 &lt;br /&gt;
 &amp;lt;font color=&amp;quot;green&amp;quot;&amp;gt;# Выставляем параметры для matplotlib.pyplot&amp;lt;/font&amp;gt;&lt;br /&gt;
 plt.figure(figsize=(9 * 2 + 3, 12.5))&lt;br /&gt;
 plt.subplots_adjust(left=.02, right=.98, bottom=.001, top=.96, wspace=.05, hspace=.01)&lt;br /&gt;
 plot_num = 1&lt;br /&gt;
 defaul_n = 3&lt;br /&gt;
 &lt;br /&gt;
 &amp;lt;font color=&amp;quot;green&amp;quot;&amp;gt;# Варьируем значение количества классов в зависимости от данных, ведь для нас это гиперпараметр&amp;lt;/font&amp;gt;&lt;br /&gt;
 datasets = [&lt;br /&gt;
    (varied, defaul_n),&lt;br /&gt;
    (aniso, defaul_n),&lt;br /&gt;
    (blobs, defaul_n),&lt;br /&gt;
    (noisy_circles, 2)]&lt;br /&gt;
 for i_dataset, (dataset, n_cluster) in enumerate(datasets):&lt;br /&gt;
    X, y = dataset&lt;br /&gt;
 &lt;br /&gt;
    &amp;lt;font color=&amp;quot;green&amp;quot;&amp;gt;# Нормализация данных&amp;lt;/font&amp;gt;&lt;br /&gt;
    X = StandardScaler().fit_transform(X)&lt;br /&gt;
 &lt;br /&gt;
    &amp;lt;font color=&amp;quot;green&amp;quot;&amp;gt;# Непосредственно наш алгоритм - Gaussian Mixture&amp;lt;/font&amp;gt;&lt;br /&gt;
    gmm = mixture.GaussianMixture(n_components=n_cluster, covariance_type='full')&lt;br /&gt;
    &lt;br /&gt;
    &amp;lt;font color=&amp;quot;green&amp;quot;&amp;gt;# Для сравнения берем алгоритм - k-means&amp;lt;/font&amp;gt;&lt;br /&gt;
    two_means = cluster.KMeans(n_clusters=n_cluster)&lt;br /&gt;
    clustering_algorithms = {&lt;br /&gt;
        'Real distribution': None,&lt;br /&gt;
        'Gaussian Mixture': gmm,&lt;br /&gt;
        'k-Means': two_means&lt;br /&gt;
    }&lt;br /&gt;
    for name, algorithm in clustering_algorithms:&lt;br /&gt;
 &lt;br /&gt;
        # Этап обучения&lt;br /&gt;
        if algorithm is not None:&lt;br /&gt;
            algorithm.fit(X)&lt;br /&gt;
        &lt;br /&gt;
        # Применяем алгоритм&lt;br /&gt;
         y_pred = y if algorithm is None else algorithm.predict(X)&lt;br /&gt;
        &lt;br /&gt;
        # Рисуем результаты&lt;br /&gt;
        plt.subplot(len(datasets), len(clustering_algorithms), plot_num)&lt;br /&gt;
        if i_dataset == 0:&lt;br /&gt;
            plt.title(name, size=18)&lt;br /&gt;
        colors = np.array(list(islice(cycle(['#377eb8', '#ff7f00', '#4daf4a']), int(max(y_pred) + 1))))&lt;br /&gt;
        plt.scatter(X[:, 0], X[:, 1], s=10, color=colors[y_pred])&lt;br /&gt;
        plt.xlim(-2.5, 2.5)&lt;br /&gt;
        plt.ylim(-2.5, 2.5)&lt;br /&gt;
        plt.xticks(())&lt;br /&gt;
        plt.yticks(())&lt;br /&gt;
        plot_num += 1&lt;br /&gt;
 plt.show()&lt;br /&gt;
&lt;br /&gt;
Как и следовало ожидать, алгоритм EM работает на некоторых данных лучше чем k-means, однако есть данные, с которыми он не справляется без дополнительных преобразований.&lt;br /&gt;
&lt;br /&gt;
== См. также ==&lt;br /&gt;
*[[Кластеризация]]&lt;br /&gt;
*[[Алгоритм_k-Means|Алгоритм k-Means]]&lt;br /&gt;
&lt;br /&gt;
==Примечания==&lt;br /&gt;
&amp;lt;references /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Источники информации ==&lt;br /&gt;
&lt;br /&gt;
# Материалы лекции про кластеризацию курса &amp;quot;Машинное обучение&amp;quot; университета ИТМО, 2019 год&lt;br /&gt;
# [http://www.machinelearning.ru/wiki/images/6/6d/Voron-ML-1.pdf Математические методы обучения по прецедентам К. В. Воронцов]&lt;br /&gt;
# [http://www.machinelearning.ru/wiki/index.php?title=EM-%D0%B0%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC Статья про EM-алгоритм на machinelearning.ru]&lt;br /&gt;
# [https://machinelearningmastery.com/expectation-maximization-em-algorithm/ A Gentle Introduction to Expectation-Maximization]&lt;br /&gt;
# [http://dendroid.sk/2011/05/09/k-means-clustering/ k-means]&lt;br /&gt;
&lt;br /&gt;
[[Категория: Машинное обучение]]&lt;br /&gt;
[[Категория: Кластеризация]]&lt;/div&gt;</summary>
		<author><name>94.229.111.244</name></author>	</entry>

	<entry>
		<id>http://neerc.ifmo.ru/wiki/index.php?title=EM-%D0%B0%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC&amp;diff=73028</id>
		<title>EM-алгоритм</title>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=EM-%D0%B0%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC&amp;diff=73028"/>
				<updated>2020-03-21T11:44:51Z</updated>
		
		<summary type="html">&lt;p&gt;94.229.111.244: Добавил примечаения&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Определение ==&lt;br /&gt;
&lt;br /&gt;
'''Алгоритм EM''' (англ. ''expectation-maximization'') {{---}} итеративный алгоритм поиска оценок максимума правдоподобия модели, в ситуации, когда она зависит от скрытых (ненаблюдаемых) переменных.&lt;br /&gt;
&lt;br /&gt;
Алгоритм ищет параметры модели итеративно, каждая итерация состоит из двух шагов:&lt;br /&gt;
&lt;br /&gt;
'''E (Expectation)''' шаг {{---}} поиск наиболее вероятных значений скрытых переменных.&lt;br /&gt;
&lt;br /&gt;
'''M (Maximization)''' шаг {{---}} поиск наиболее вероятных значений параметров, для полученных на шаге E значений скрытых переменных.&lt;br /&gt;
&lt;br /&gt;
EM алгоритм подходит для решения задач двух типов:&lt;br /&gt;
&lt;br /&gt;
# Задачи с неполными данными.&lt;br /&gt;
# Задачи, в которых удобно вводить скрытые переменные для упрощения подсчета функции правдоподобия. Примером такой задачи может служить кластеризация.&lt;br /&gt;
&lt;br /&gt;
== Основной алгоритм == &lt;br /&gt;
&lt;br /&gt;
=== Постановка задачи ===&lt;br /&gt;
&lt;br /&gt;
Плотность распределения смеси имеет вид:&amp;lt;br/&amp;gt;&lt;br /&gt;
&amp;lt;tex&amp;gt;p(x) = \sum\limits_{j=1}^k w_j p_j(x)&amp;lt;/tex&amp;gt;.&amp;lt;br/&amp;gt;&lt;br /&gt;
Где &amp;lt;tex&amp;gt; \sum\limits_{j=1}^k w_j = 1;  w_j \geq 0; p_j(x) = \phi(x;\theta_j)&amp;lt;/tex&amp;gt; {{---}} функция правдоподобия &amp;lt;tex&amp;gt;j&amp;lt;/tex&amp;gt;-ой компонеты смеси, &amp;lt;tex&amp;gt;w_j&amp;lt;/tex&amp;gt; {{---}} априорная вероятность &amp;lt;tex&amp;gt;j&amp;lt;/tex&amp;gt;-ой компоненты смеси.&amp;lt;br/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Перед нами стоит две задачи:&amp;lt;br/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
# По заданной выборке &amp;lt;tex&amp;gt;X^m&amp;lt;/tex&amp;gt; случайных и независимых наблюдений полученных из смеси &amp;lt;tex&amp;gt;p(x)&amp;lt;/tex&amp;gt;, числу &amp;lt;tex&amp;gt;k&amp;lt;/tex&amp;gt; и функции &amp;lt;tex&amp;gt;\phi&amp;lt;/tex&amp;gt;, оценить вектор параметров &amp;lt;tex&amp;gt;\Theta = (w_1,..,w_k,\theta_1,..,\theta_k).&amp;lt;/tex&amp;gt;&lt;br /&gt;
# Найти &amp;lt;tex&amp;gt;k&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Проблема === &lt;br /&gt;
&lt;br /&gt;
Задачи подобного рода мы умеем решать, максимизируя логармиф правдоподобия:&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;tex&amp;gt; Q(\Theta) = ln \prod\limits_{i=1}^mp(x_i) = \sum\limits_{i=1}^m ln\sum\limits_{j=1}^k w_j p_j(x_i; \theta_j) \longrightarrow \max\limits_{\Theta}&amp;lt;/tex&amp;gt;.&amp;lt;br/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Но проблeма в том, что мы не знаем как аналитически посчитать логарифм суммы. Тут нам и поможет алгоритм EM.&lt;br /&gt;
&lt;br /&gt;
=== Решение === &lt;br /&gt;
&lt;br /&gt;
Основная идея алгоритма EM заключается в том, что мы добавляем скрытые переменные такие, что:&amp;lt;br/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
# Они могут быть выражены через &amp;lt;tex&amp;gt;\Theta&amp;lt;/tex&amp;gt;.&lt;br /&gt;
# Они помогают разбить сумму так: &amp;lt;tex&amp;gt;p (X, H|\Theta) = \prod\limits_{i=1}^k p (X|H, \Theta) p(H|\Theta)&amp;lt;/tex&amp;gt;, где &amp;lt;tex&amp;gt;H&amp;lt;/tex&amp;gt; {{---}} матрица скрытых переменных.&lt;br /&gt;
&lt;br /&gt;
Тогда алгоритм EM сводится к повторению шагов, указанных в [[#Определение|Определении]].&lt;br /&gt;
&lt;br /&gt;
=== E-шаг === &lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt;p(x,\theta_j) = p(x)P(\theta_j | x) = w_jp_j(x)&amp;lt;/tex&amp;gt;.&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Скрытые переменные представляют из себя матрицу &amp;lt;tex&amp;gt;H = (h_{ij})_{m \times k}&amp;lt;/tex&amp;gt;,&amp;lt;br/&amp;gt;&lt;br /&gt;
где &amp;lt;tex&amp;gt;h_{ij} = P(\theta_j | x_i)&amp;lt;/tex&amp;gt; {{---}} вероятность того, что &amp;lt;tex&amp;gt;x_i&amp;lt;/tex&amp;gt; пренадлежит &amp;lt;tex&amp;gt;j&amp;lt;/tex&amp;gt;-ой компоненте.&amp;lt;br/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
По формуле Байеса справедливо равенство:&amp;lt;br /&amp;gt;&lt;br /&gt;
&amp;lt;tex&amp;gt; h_{ij} = \frac{w_jp_j(x_i)}{p (x_i)} = \frac{w_jp_j(x_i)}{\sum\limits_{s=1}^k w_s p_s(x_i)}&amp;lt;/tex&amp;gt;.&amp;lt;br/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Также &amp;lt;tex&amp;gt;\sum\limits_{j=1}^k h_{ij} = 1&amp;lt;/tex&amp;gt;.&amp;lt;br/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Таким образом, зная значения вектора параметров &amp;lt;tex&amp;gt;\Theta&amp;lt;/tex&amp;gt;, мы легко можем пересчитать значения скрытых переменных.&amp;lt;br/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== M-шаг === &lt;br /&gt;
&lt;br /&gt;
{{Теорема&lt;br /&gt;
|statement=&lt;br /&gt;
Если известны скрытые переменные, то задача минимизации &amp;lt;tex&amp;gt;Q(\Theta)&amp;lt;/tex&amp;gt; сводится к &amp;lt;tex&amp;gt;k&amp;lt;/tex&amp;gt; независимым подзадачам:&amp;lt;br/&amp;gt;&lt;br /&gt;
&amp;lt;center&amp;gt;&amp;lt;tex&amp;gt;\theta_j = \arg\max\limits_{\theta}\sum\limits_{i=1}^m h_{ij}*\ln\phi(x_i;\theta)&amp;lt;/tex&amp;gt;.&amp;lt;/center&amp;gt;&lt;br /&gt;
Оптимальные же веса считаются как:&amp;lt;br/&amp;gt;&lt;br /&gt;
&amp;lt;center&amp;gt;&amp;lt;tex&amp;gt; w_j = \frac {1} {m} \sum\limits_{i=1}^m h_{ij}&amp;lt;/tex&amp;gt;.&amp;lt;/center&amp;gt;&lt;br /&gt;
|proof=&lt;br /&gt;
Посчитаем логарифм правдоподобия:&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;tex&amp;gt; Q(\Theta) = \sum\limits_{i=1}^m ln\sum\limits_{j=1}^k w_j p_j(x_i; \theta_j) \longrightarrow \max\limits_{\Theta}&amp;lt;/tex&amp;gt;.&amp;lt;br/&amp;gt;&lt;br /&gt;
При условии, что&amp;lt;tex&amp;gt; \sum\limits_{j=1}^k w_j = 1; w_j \geq 0&amp;lt;/tex&amp;gt; имеет смысл рассматривать Лагранжиан задачи:&amp;lt;br/&amp;gt;&lt;br /&gt;
&amp;lt;tex&amp;gt; L(\Theta, X^m) = \sum\limits_{i=1}^m ln \biggl( \sum\limits_{j=1}^k w_j p_j(x_i) \biggr)  - \lambda \biggl(\sum\limits_{j=1}^k w_j - 1 \biggr) &amp;lt;/tex&amp;gt;.&amp;lt;br/&amp;gt;&lt;br /&gt;
Приравняв нулю производную Лагранжиана по &amp;lt;tex&amp;gt;w_j&amp;lt;/tex&amp;gt;, получим:&amp;lt;br/&amp;gt;&lt;br /&gt;
&amp;lt;tex&amp;gt;\frac{\partial L} {\partial w_j} = \sum\limits_{i=1}^m \frac{p_j(x_i)}{\sum\limits_{s=1}^kw_s p_s(x_i)} - \lambda = 0, j = 1..k&amp;lt;/tex&amp;gt;.&amp;lt;br/&amp;gt;&lt;br /&gt;
Умножим на &amp;lt;tex&amp;gt;w_j&amp;lt;/tex&amp;gt; и просуммируем уравнения для всех &amp;lt;tex&amp;gt;j&amp;lt;/tex&amp;gt;:&amp;lt;br /&amp;gt;&lt;br /&gt;
&amp;lt;tex&amp;gt;\sum\limits_{j=1}^k \sum\limits_{i=1}^m \frac{w_jp_j(x_i)}{\sum\limits_{s=1}^kw_s p_s(x_i)} = \lambda \sum\limits_{j=1}^kw_j&amp;lt;/tex&amp;gt;.&amp;lt;br /&amp;gt;&lt;br /&gt;
А так как &amp;lt;tex&amp;gt;\sum\limits_{j=1}^k \frac{w_jp_j(x_i)}{\sum\limits_{s=1}^kw_sp_s(x_i)} = 1&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;\sum\limits_{j=1}^kw_j = 1&amp;lt;/tex&amp;gt;, из чего следует &amp;lt;tex&amp;gt;\lambda = m&amp;lt;/tex&amp;gt;.&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt;w_j = \frac{1}{m}\sum\limits_{i=1}^m \frac{w_jp_j(x_i)}{\sum\limits_{s=1}^kw_sp_s(x_i)} = \frac{1}{m}\sum\limits_{i=1}^m h_{ij}&amp;lt;/tex&amp;gt;.&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Приравняв к нулю производную Лагранжиана по &amp;lt;tex&amp;gt;\theta_j&amp;lt;/tex&amp;gt;, схожим способом найдем:&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt; \theta_j = \arg\max\limits_{\theta}\sum\limits_{i=1}^m h_{ij}*\ln\phi(x_i;\theta).&amp;lt;/tex&amp;gt;&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
=== Критерий остановки === &lt;br /&gt;
&lt;br /&gt;
Алгоритм EM выполняется до сходимости, но как нам определить, что сходимость наступила? Мы можем останавливаться, когда либо &amp;lt;tex&amp;gt;Q(\Theta)&amp;lt;/tex&amp;gt;, либо &amp;lt;tex&amp;gt;H&amp;lt;/tex&amp;gt; перестают сильно меняться. Но, обычно, удобней контролировать изменения значений скрытых переменных, так как они имеют смысл вероятностей и принимают значения из отрезка &amp;lt;tex&amp;gt;[0,1]&amp;lt;/tex&amp;gt;. Поэтому один из возможных критериев остановки будет выглядеть так: &amp;lt;tex&amp;gt;\max\limits_{i,j} |h_{ij} - h_{ij}^{(0)}| &amp;gt; \delta&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Псевдокод === &lt;br /&gt;
&lt;br /&gt;
 Input:&amp;lt;tex&amp;gt;X^m, k, \Theta^{(0)}&amp;lt;/tex&amp;gt;&lt;br /&gt;
 Repeat&lt;br /&gt;
    '''E-step''': for all i = 1..m; j = 1..k:&lt;br /&gt;
        &amp;lt;tex&amp;gt;h_{ij} = \frac{w_j \phi(x_i; \theta_j)}{\sum\limits_{s=1}^k w_s \phi(x_i; \theta_j)}&amp;lt;/tex&amp;gt;&lt;br /&gt;
    '''M-step''': for all j = 1..k:&lt;br /&gt;
        &amp;lt;tex&amp;gt;\theta_j = \arg\max\limits_{\theta} \sum\limits_{i=1}^m h_{ij}*ln \phi (x_i, \theta)&amp;lt;/tex&amp;gt;&lt;br /&gt;
        &amp;lt;tex&amp;gt;w_j = \frac {1} {m} \sum\limits_{i=1}^m h_{ij}&amp;lt;/tex&amp;gt;&lt;br /&gt;
 Until a stopping criterion is satisfied&lt;br /&gt;
 Return &amp;lt;tex&amp;gt;\Theta = (\theta_j, w_j)_{j=1}^k&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Плюсы и минусы === &lt;br /&gt;
&lt;br /&gt;
Плюсы:&amp;lt;br/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Сходится в большинтсве случаев.&lt;br /&gt;
* Наиболее гибкое решение.&lt;br /&gt;
* Существуют простые модификации, позволяющие уменьшить чуствительность алгоритма к шуму в данных.&lt;br /&gt;
&lt;br /&gt;
Минусы:&amp;lt;br/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Чуствителен к начальному приближению. Могут быть ситуации, когда сойдемся к локальному экстремуму.&lt;br /&gt;
* Число компонент &amp;lt;tex&amp;gt;k&amp;lt;/tex&amp;gt; является [[Настройка_гиперпараметров|гиперпараметром]].&lt;br /&gt;
&lt;br /&gt;
== Модификации == &lt;br /&gt;
&lt;br /&gt;
Базовый алгоритм EM является очень гибким для модификаций, позволяющих улучшить его работу. В этом разделе мы приведем краткое описание некоторых из них.&lt;br /&gt;
&lt;br /&gt;
=== Generalized EM-algorithm === &lt;br /&gt;
&lt;br /&gt;
Осоновная идея этой модификации заключается в том, что на шаге M мы не будем пытаться найти наилучшее решение. Это применимо в случаях, когда максимизация &amp;lt;tex&amp;gt;Q(\Theta)&amp;lt;/tex&amp;gt; является сликшом дорогой, поэтому нам достаточно сделать лишь несколько итераций, для того, чтобы сместиться в сторону максимума значения &amp;lt;tex&amp;gt;Q(\Theta)&amp;lt;/tex&amp;gt;. Эта модификация имеет неплохую сходимость.&lt;br /&gt;
&lt;br /&gt;
=== Stochastic EM-algorithm ===&lt;br /&gt;
&lt;br /&gt;
Как уже было отмечено в [[#Плюсы_и_минусы|Плюсы и минусы]], базовый алгоритм чувствителен к начальному приближению и могут быть ситуации, когда алгоритм &amp;quot;застрянет&amp;quot; в локальном экстремуме. Для того, чтобы предотвратить это, будем на каждой итерации алгоритма случайно &amp;quot;встряхивать&amp;quot; выборку. В этой модификации у нас добавляется шаг S, на котором мы и будем &amp;quot;встряхивать&amp;quot; выборку. И на шаге M мы будем решать уже задачу максимуму невзвешенного правдоподобия. Эта модификация хороша тем, что нечуствиетльная к начальном приблежению. &lt;br /&gt;
&lt;br /&gt;
== Пример. Разделение смеси Гауссиана == &lt;br /&gt;
&lt;br /&gt;
[[Файл:Gaussians2.png|right|thumb|400px|Несколько итераций алгоритма]]&lt;br /&gt;
&lt;br /&gt;
Каноническим примером использования EM алгоритма является задача разделения смеси гауссиана. Данные у нас получены из нормального распределения. В этом случае параметрами функций ялвяются матожидание и дисперсия.&amp;lt;br/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt;\theta = (w_1,..,w_k;\;\mu_1,..,\mu_k;\;\sigma_1,..,\sigma_k)&amp;lt;/tex&amp;gt; {{---}} вектор параметров, &amp;lt;br/&amp;gt;&lt;br /&gt;
&amp;lt;tex&amp;gt;p_j(x) = N(x;\mu_j, \sigma_j) = \frac1{\sqrt{2\pi}\sigma_j} \exp \biggl(-\frac{(x - \mu_j)^2}{2\sigma_j^2}\biggr) &amp;lt;/tex&amp;gt; {{---}} плотность распределения.&amp;lt;br/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Посчитаем значения для каждого шага. &amp;lt;br/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
E-шаг:&lt;br /&gt;
&lt;br /&gt;
: &amp;lt;tex&amp;gt; h_{ij} = \frac{w_j N(x_i, \mu_j, \sigma_j)}{\sum\limits_{s=1}^k w_s N(x_i, \mu_s, \sigma_s)}.&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
M-шаг:&lt;br /&gt;
&lt;br /&gt;
: &amp;lt;tex&amp;gt;w_j = \frac{1}{m} \sum\limits_{i=1}^m h_{ij}.&amp;lt;/tex&amp;gt;&lt;br /&gt;
: &amp;lt;tex&amp;gt; \mu_j = \frac {1} {mw_j} \sum\limits_{i=1}^m h_{ij}x_i.&amp;lt;/tex&amp;gt;&lt;br /&gt;
: &amp;lt;tex&amp;gt; \sigma_j^2 = \frac {1} {mw_j} \sum\limits_{i=1}^m h_{ij}(x_i - \mu_j)^2, j = 1..k.&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Использование в задаче кластеризации ==&lt;br /&gt;
&lt;br /&gt;
[[Файл:kmeans.jpg|right|thumb|200px|Пример работы k-means]]&lt;br /&gt;
&lt;br /&gt;
Как уже упоминалось в [[#Определение|Определении]], алгоритм EM подходит для решения задачи кластеризации. И одной из его имплементаций для этой задачи является алгоритм [[Алгоритм_k-Means|&amp;lt;tex&amp;gt;k&amp;lt;/tex&amp;gt;-Means]]. В этом алгоритме в качестве скрытых переменных выступают метки классов объектов. Параметрами же являются центроиды искомых классов. Тогда на шаге E мы относим объекты к какому-то одному классу на основе расстояний до центроид. А на шаге M мы пересчитываем центроиды кластеров, исходя из полученной на шаге E разметке.&amp;lt;br/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Также стоит упомянуть алгоритм &amp;lt;tex&amp;gt;c&amp;lt;/tex&amp;gt;-means&amp;lt;ref&amp;gt;[https://en.wikipedia.org/wiki/Fuzzy_clustering#Fuzzy_C-means_clustering Fuzzy C-means clustering, Wikipedia]&amp;lt;/ref&amp;gt;. В нем качестве скрытых переменных выступают вероятности принадлежности объекта к классам. На шаге E мы пересчитывем вероятности принадлежности объектов, иходя из расстояния до центроид. Шаг M, идейно, остается без изменений.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Реализация на python ==&lt;br /&gt;
&lt;br /&gt;
В пакете sklearn алгоритм EM представлен объектом GaussianMixture. Проиллюстрируем его работу на примере задачи кластеризации и сравним его с алгоритмом &amp;lt;tex&amp;gt;k&amp;lt;/tex&amp;gt;-means:&lt;br /&gt;
 &lt;br /&gt;
 [[Файл:em_clustering.png|thumb|600px|Результат выполнения программы]]&lt;br /&gt;
 '''import''' numpy as np&lt;br /&gt;
 '''import''' matplotlib.pyplot as plt&lt;br /&gt;
 '''from''' sklearn '''import''' cluster, datasets, mixture&lt;br /&gt;
 '''from''' sklearn.preprocessing '''import''' StandardScaler&lt;br /&gt;
 '''from''' itertools '''import''' cycle, islice&lt;br /&gt;
 np.random.seed(12)&lt;br /&gt;
 &lt;br /&gt;
 &amp;lt;font color=&amp;quot;green&amp;quot;&amp;gt;# Создаем datasets с использованием стандартных sklearn.datasets&amp;lt;/font&amp;gt;&lt;br /&gt;
 n_samples = 2000&lt;br /&gt;
 random_state = 170&lt;br /&gt;
 noisy_circles = datasets.make_circles(n_samples=n_samples, factor=.5, noise=.05)&lt;br /&gt;
 noisy_moons = datasets.make_moons(n_samples=n_samples, noise=.05)&lt;br /&gt;
 blobs = datasets.make_blobs(n_samples=n_samples, random_state=8)&lt;br /&gt;
 varied = datasets.make_blobs(n_samples=n_samples, cluster_std=[1.0, 2.5, 0.5], random_state=random_state)&lt;br /&gt;
 &lt;br /&gt;
 &amp;lt;font color=&amp;quot;green&amp;quot;&amp;gt;# Создаем анизатропно разделенные данные&amp;lt;/font&amp;gt;&lt;br /&gt;
 X, y = datasets.make_blobs(n_samples=n_samples, random_state=random_state)&lt;br /&gt;
 transformation = [[0.6, -0.6], [-0.4, 0.8]]&lt;br /&gt;
 X_aniso = np.dot(X, transformation)&lt;br /&gt;
 aniso = (X_aniso, y)&lt;br /&gt;
 &lt;br /&gt;
 &amp;lt;font color=&amp;quot;green&amp;quot;&amp;gt;# Выставляем параметры для matplotlib.pyplot&amp;lt;/font&amp;gt;&lt;br /&gt;
 plt.figure(figsize=(9 * 2 + 3, 12.5))&lt;br /&gt;
 plt.subplots_adjust(left=.02, right=.98, bottom=.001, top=.96, wspace=.05, hspace=.01)&lt;br /&gt;
 plot_num = 1&lt;br /&gt;
 defaul_n = 3&lt;br /&gt;
 &lt;br /&gt;
 &amp;lt;font color=&amp;quot;green&amp;quot;&amp;gt;# Варьируем значение количества классов в зависимости от данных, ведь для нас это гиперпараметр&amp;lt;/font&amp;gt;&lt;br /&gt;
 datasets = [&lt;br /&gt;
    (varied, defaul_n),&lt;br /&gt;
    (aniso, defaul_n),&lt;br /&gt;
    (blobs, defaul_n),&lt;br /&gt;
    (noisy_circles, 2)]&lt;br /&gt;
 for i_dataset, (dataset, n_cluster) in enumerate(datasets):&lt;br /&gt;
    X, y = dataset&lt;br /&gt;
 &lt;br /&gt;
    &amp;lt;font color=&amp;quot;green&amp;quot;&amp;gt;# Нормализация данных&amp;lt;/font&amp;gt;&lt;br /&gt;
    X = StandardScaler().fit_transform(X)&lt;br /&gt;
 &lt;br /&gt;
    &amp;lt;font color=&amp;quot;green&amp;quot;&amp;gt;# Непосредственно наш алгоритм - Gaussian Mixture&amp;lt;/font&amp;gt;&lt;br /&gt;
    gmm = mixture.GaussianMixture(n_components=n_cluster, covariance_type='full')&lt;br /&gt;
    &lt;br /&gt;
    &amp;lt;font color=&amp;quot;green&amp;quot;&amp;gt;# Для сравнения берем алгоритм - k-means&amp;lt;/font&amp;gt;&lt;br /&gt;
    two_means = cluster.KMeans(n_clusters=n_cluster)&lt;br /&gt;
    clustering_algorithms = {&lt;br /&gt;
        'Real distribution': None,&lt;br /&gt;
        'Gaussian Mixture': gmm,&lt;br /&gt;
        'k-Means': two_means&lt;br /&gt;
    }&lt;br /&gt;
    for name, algorithm in clustering_algorithms:&lt;br /&gt;
 &lt;br /&gt;
        # Этап обучения&lt;br /&gt;
        if algorithm is not None:&lt;br /&gt;
            algorithm.fit(X)&lt;br /&gt;
        &lt;br /&gt;
        # Применяем алгоритм&lt;br /&gt;
         y_pred = y if algorithm is None else algorithm.predict(X)&lt;br /&gt;
        &lt;br /&gt;
        # Рисуем результаты&lt;br /&gt;
        plt.subplot(len(datasets), len(clustering_algorithms), plot_num)&lt;br /&gt;
        if i_dataset == 0:&lt;br /&gt;
            plt.title(name, size=18)&lt;br /&gt;
        colors = np.array(list(islice(cycle(['#377eb8', '#ff7f00', '#4daf4a']), int(max(y_pred) + 1))))&lt;br /&gt;
        plt.scatter(X[:, 0], X[:, 1], s=10, color=colors[y_pred])&lt;br /&gt;
        plt.xlim(-2.5, 2.5)&lt;br /&gt;
        plt.ylim(-2.5, 2.5)&lt;br /&gt;
        plt.xticks(())&lt;br /&gt;
        plt.yticks(())&lt;br /&gt;
        plot_num += 1&lt;br /&gt;
 plt.show()&lt;br /&gt;
&lt;br /&gt;
Как и следовало ожидать, алгоритм EM работает на некоторых данных лучше чем k-means, однако есть данные, с которыми он не справляется без дополнительных преобразований.&lt;br /&gt;
&lt;br /&gt;
== См. также ==&lt;br /&gt;
*[[Кластеризация]]&lt;br /&gt;
*[[Алгоритм_k-Means|Алгоритм k-Means]]&lt;br /&gt;
&lt;br /&gt;
==Примечания==&lt;br /&gt;
&amp;lt;references /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Источники информации ==&lt;br /&gt;
&lt;br /&gt;
# Материалы лекции про кластеризацию курса &amp;quot;Машинное обучение&amp;quot; университета ИТМО, 2019 год&lt;br /&gt;
# [http://www.machinelearning.ru/wiki/images/6/6d/Voron-ML-1.pdf Математические методы обучения по прецедентам К. В. Воронцов]&lt;br /&gt;
# [http://www.machinelearning.ru/wiki/index.php?title=EM-%D0%B0%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC Статья про EM-алгоритм на machinelearning.ru]&lt;br /&gt;
# [https://machinelearningmastery.com/expectation-maximization-em-algorithm/ A Gentle Introduction to Expectation-Maximization]&lt;br /&gt;
# [http://dendroid.sk/2011/05/09/k-means-clustering/ k-means]&lt;br /&gt;
&lt;br /&gt;
[[Категория: Машинное обучение]]&lt;br /&gt;
[[Категория: Кластеризация]]&lt;/div&gt;</summary>
		<author><name>94.229.111.244</name></author>	</entry>

	<entry>
		<id>http://neerc.ifmo.ru/wiki/index.php?title=EM-%D0%B0%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC&amp;diff=73027</id>
		<title>EM-алгоритм</title>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=EM-%D0%B0%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC&amp;diff=73027"/>
				<updated>2020-03-21T11:37:58Z</updated>
		
		<summary type="html">&lt;p&gt;94.229.111.244: Поправил баги&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Определение ==&lt;br /&gt;
&lt;br /&gt;
'''Алгоритм EM''' (англ. ''expectation-maximization'') {{---}} итеративный алгоритм поиска оценок максимума правдоподобия модели, в ситуации, когда она зависит от скрытых (ненаблюдаемых) переменных.&lt;br /&gt;
&lt;br /&gt;
Алгоритм ищет параметры модели итеративно, каждая итерация состоит из двух шагов:&lt;br /&gt;
&lt;br /&gt;
'''E (Expectation)''' шаг {{---}} поиск наиболее вероятных значений скрытых переменных.&lt;br /&gt;
&lt;br /&gt;
'''M (Maximization)''' шаг {{---}} поиск наиболее вероятных значений параметров, для полученных на шаге E значений скрытых переменных.&lt;br /&gt;
&lt;br /&gt;
EM алгоритм подходит для решения задач двух типов:&lt;br /&gt;
&lt;br /&gt;
# Задачи с неполными данными.&lt;br /&gt;
# Задачи, в которых удобно вводить скрытые переменные для упрощения подсчета функции правдоподобия. Примером такой задачи может служить кластеризация.&lt;br /&gt;
&lt;br /&gt;
== Основной алгоритм == &lt;br /&gt;
&lt;br /&gt;
=== Постановка задачи ===&lt;br /&gt;
&lt;br /&gt;
Плотность распределения смеси имеет вид:&amp;lt;br/&amp;gt;&lt;br /&gt;
&amp;lt;tex&amp;gt;p(x) = \sum\limits_{j=1}^k w_j p_j(x)&amp;lt;/tex&amp;gt;.&amp;lt;br/&amp;gt;&lt;br /&gt;
Где &amp;lt;tex&amp;gt; \sum\limits_{j=1}^k w_j = 1;  w_j \geq 0; p_j(x) = \phi(x;\theta_j)&amp;lt;/tex&amp;gt; {{---}} функция правдоподобия &amp;lt;tex&amp;gt;j&amp;lt;/tex&amp;gt;-ой компонеты смеси, &amp;lt;tex&amp;gt;w_j&amp;lt;/tex&amp;gt; {{---}} априорная вероятность &amp;lt;tex&amp;gt;j&amp;lt;/tex&amp;gt;-ой компоненты смеси.&amp;lt;br/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Перед нами стоит две задачи:&amp;lt;br/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
# По заданной выборке &amp;lt;tex&amp;gt;X^m&amp;lt;/tex&amp;gt; случайных и независимых наблюдений полученных из смеси &amp;lt;tex&amp;gt;p(x)&amp;lt;/tex&amp;gt;, числу &amp;lt;tex&amp;gt;k&amp;lt;/tex&amp;gt; и функции &amp;lt;tex&amp;gt;\phi&amp;lt;/tex&amp;gt;, оценить вектор параметров &amp;lt;tex&amp;gt;\Theta = (w_1,..,w_k,\theta_1,..,\theta_k).&amp;lt;/tex&amp;gt;&lt;br /&gt;
# Найти &amp;lt;tex&amp;gt;k&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Проблема === &lt;br /&gt;
&lt;br /&gt;
Задачи подобного рода мы умеем решать, максимизируя логармиф правдоподобия:&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;tex&amp;gt; Q(\Theta) = ln \prod\limits_{i=1}^mp(x_i) = \sum\limits_{i=1}^m ln\sum\limits_{j=1}^k w_j p_j(x_i; \theta_j) \longrightarrow \max\limits_{\Theta}&amp;lt;/tex&amp;gt;.&amp;lt;br/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Но проблeма в том, что мы не знаем как аналитически посчитать логарифм суммы. Тут нам и поможет алгоритм EM.&lt;br /&gt;
&lt;br /&gt;
=== Решение === &lt;br /&gt;
&lt;br /&gt;
Основная идея алгоритма EM заключается в том, что мы добавляем скрытые переменные такие, что:&amp;lt;br/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
# Они могут быть выражены через &amp;lt;tex&amp;gt;\Theta&amp;lt;/tex&amp;gt;.&lt;br /&gt;
# Они помогают разбить сумму так: &amp;lt;tex&amp;gt;p (X, H|\Theta) = \prod\limits_{i=1}^k p (X|H, \Theta) p(H|\Theta)&amp;lt;/tex&amp;gt;, где &amp;lt;tex&amp;gt;H&amp;lt;/tex&amp;gt; {{---}} матрица скрытых переменных.&lt;br /&gt;
&lt;br /&gt;
Тогда алгоритм EM сводится к повторению шагов, указанных в [[#Определение|Определении]].&lt;br /&gt;
&lt;br /&gt;
=== E-шаг === &lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt;p(x,\theta_j) = p(x)P(\theta_j | x) = w_jp_j(x)&amp;lt;/tex&amp;gt;.&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Скрытые переменные представляют из себя матрицу &amp;lt;tex&amp;gt;H = (h_{ij})_{m \times k}&amp;lt;/tex&amp;gt;,&amp;lt;br/&amp;gt;&lt;br /&gt;
где &amp;lt;tex&amp;gt;h_{ij} = P(\theta_j | x_i)&amp;lt;/tex&amp;gt; {{---}} вероятность того, что &amp;lt;tex&amp;gt;x_i&amp;lt;/tex&amp;gt; пренадлежит &amp;lt;tex&amp;gt;j&amp;lt;/tex&amp;gt;-ой компоненте.&amp;lt;br/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
По формуле Байеса справедливо равенство:&amp;lt;br /&amp;gt;&lt;br /&gt;
&amp;lt;tex&amp;gt; h_{ij} = \frac{w_jp_j(x_i)}{p (x_i)} = \frac{w_jp_j(x_i)}{\sum\limits_{s=1}^k w_s p_s(x_i)}&amp;lt;/tex&amp;gt;.&amp;lt;br/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Также &amp;lt;tex&amp;gt;\sum\limits_{j=1}^k h_{ij} = 1&amp;lt;/tex&amp;gt;.&amp;lt;br/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Таким образом, зная значения вектора параметров &amp;lt;tex&amp;gt;\Theta&amp;lt;/tex&amp;gt;, мы легко можем пересчитать значения скрытых переменных.&amp;lt;br/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== M-шаг === &lt;br /&gt;
&lt;br /&gt;
{{Теорема&lt;br /&gt;
|statement=&lt;br /&gt;
Если известны скрытые переменные, то задача минимизации &amp;lt;tex&amp;gt;Q(\Theta)&amp;lt;/tex&amp;gt; сводится к &amp;lt;tex&amp;gt;k&amp;lt;/tex&amp;gt; независимым подзадачам:&amp;lt;br/&amp;gt;&lt;br /&gt;
&amp;lt;center&amp;gt;&amp;lt;tex&amp;gt;\theta_j = \arg\max\limits_{\theta}\sum\limits_{i=1}^m h_{ij}*\ln\phi(x_i;\theta)&amp;lt;/tex&amp;gt;.&amp;lt;/center&amp;gt;&lt;br /&gt;
Оптимальные же веса считаются как:&amp;lt;br/&amp;gt;&lt;br /&gt;
&amp;lt;center&amp;gt;&amp;lt;tex&amp;gt; w_j = \frac {1} {m} \sum\limits_{i=1}^m h_{ij}&amp;lt;/tex&amp;gt;.&amp;lt;/center&amp;gt;&lt;br /&gt;
|proof=&lt;br /&gt;
Посчитаем логарифм правдоподобия:&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;tex&amp;gt; Q(\Theta) = \sum\limits_{i=1}^m ln\sum\limits_{j=1}^k w_j p_j(x_i; \theta_j) \longrightarrow \max\limits_{\Theta}&amp;lt;/tex&amp;gt;.&amp;lt;br/&amp;gt;&lt;br /&gt;
При условии, что&amp;lt;tex&amp;gt; \sum\limits_{j=1}^k w_j = 1; w_j \geq 0&amp;lt;/tex&amp;gt; имеет смысл рассматривать Лагранжиан задачи:&amp;lt;br/&amp;gt;&lt;br /&gt;
&amp;lt;tex&amp;gt; L(\Theta, X^m) = \sum\limits_{i=1}^m ln \biggl( \sum\limits_{j=1}^k w_j p_j(x_i) \biggr)  - \lambda \biggl(\sum\limits_{j=1}^k w_j - 1 \biggr) &amp;lt;/tex&amp;gt;.&amp;lt;br/&amp;gt;&lt;br /&gt;
Приравняв нулю производную Лагранжиана по &amp;lt;tex&amp;gt;w_j&amp;lt;/tex&amp;gt;, получим:&amp;lt;br/&amp;gt;&lt;br /&gt;
&amp;lt;tex&amp;gt;\frac{\partial L} {\partial w_j} = \sum\limits_{i=1}^m \frac{p_j(x_i)}{\sum\limits_{s=1}^kw_s p_s(x_i)} - \lambda = 0, j = 1..k&amp;lt;/tex&amp;gt;.&amp;lt;br/&amp;gt;&lt;br /&gt;
Умножим на &amp;lt;tex&amp;gt;w_j&amp;lt;/tex&amp;gt; и просуммируем уравнения для всех &amp;lt;tex&amp;gt;j&amp;lt;/tex&amp;gt;:&amp;lt;br /&amp;gt;&lt;br /&gt;
&amp;lt;tex&amp;gt;\sum\limits_{j=1}^k \sum\limits_{i=1}^m \frac{w_jp_j(x_i)}{\sum\limits_{s=1}^kw_s p_s(x_i)} = \lambda \sum\limits_{j=1}^kw_j&amp;lt;/tex&amp;gt;.&amp;lt;br /&amp;gt;&lt;br /&gt;
А так как &amp;lt;tex&amp;gt;\sum\limits_{j=1}^k \frac{w_jp_j(x_i)}{\sum\limits_{s=1}^kw_sp_s(x_i)} = 1&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;\sum\limits_{j=1}^kw_j = 1&amp;lt;/tex&amp;gt;, из чего следует &amp;lt;tex&amp;gt;\lambda = m&amp;lt;/tex&amp;gt;.&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt;w_j = \frac{1}{m}\sum\limits_{i=1}^m \frac{w_jp_j(x_i)}{\sum\limits_{s=1}^kw_sp_s(x_i)} = \frac{1}{m}\sum\limits_{i=1}^m h_{ij}&amp;lt;/tex&amp;gt;.&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Приравняв к нулю производную Лагранжиана по &amp;lt;tex&amp;gt;\theta_j&amp;lt;/tex&amp;gt;, схожим способом найдем:&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt; \theta_j = \arg\max\limits_{\theta}\sum\limits_{i=1}^m h_{ij}*\ln\phi(x_i;\theta).&amp;lt;/tex&amp;gt;&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
=== Критерий остановки === &lt;br /&gt;
&lt;br /&gt;
Алгоритм EM выполняется до сходимости, но как нам определить, что сходимость наступила? Мы можем останавливаться, когда либо &amp;lt;tex&amp;gt;Q(\Theta)&amp;lt;/tex&amp;gt;, либо &amp;lt;tex&amp;gt;H&amp;lt;/tex&amp;gt; перестают сильно меняться. Но, обычно, удобней контролировать изменения значений скрытых переменных, так как они имеют смысл вероятностей и принимают значения из отрезка &amp;lt;tex&amp;gt;[0,1]&amp;lt;/tex&amp;gt;. Поэтому один из возможных критериев остановки будет выглядеть так: &amp;lt;tex&amp;gt;\max\limits_{i,j} |h_{ij} - h_{ij}^{(0)}| &amp;gt; \delta&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Псевдокод === &lt;br /&gt;
&lt;br /&gt;
 Input:&amp;lt;tex&amp;gt;X^m, k, \Theta^{(0)}&amp;lt;/tex&amp;gt;&lt;br /&gt;
 Repeat&lt;br /&gt;
    '''E-step''': for all i = 1..m; j = 1..k:&lt;br /&gt;
        &amp;lt;tex&amp;gt;h_{ij} = \frac{w_j \phi(x_i; \theta_j)}{\sum\limits_{s=1}^k w_s \phi(x_i; \theta_j)}&amp;lt;/tex&amp;gt;&lt;br /&gt;
    '''M-step''': for all j = 1..k:&lt;br /&gt;
        &amp;lt;tex&amp;gt;\theta_j = \arg\max\limits_{\theta} \sum\limits_{i=1}^m h_{ij}*ln \phi (x_i, \theta)&amp;lt;/tex&amp;gt;&lt;br /&gt;
        &amp;lt;tex&amp;gt;w_j = \frac {1} {m} \sum\limits_{i=1}^m h_{ij}&amp;lt;/tex&amp;gt;&lt;br /&gt;
 Until a stopping criterion is satisfied&lt;br /&gt;
 Return &amp;lt;tex&amp;gt;\Theta = (\theta_j, w_j)_{j=1}^k&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Плюсы и минусы === &lt;br /&gt;
&lt;br /&gt;
Плюсы:&amp;lt;br/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Сходится в большинтсве случаев.&lt;br /&gt;
* Наиболее гибкое решение.&lt;br /&gt;
* Существуют простые модификации, позволяющие уменьшить чуствительность алгоритма к шуму в данных.&lt;br /&gt;
&lt;br /&gt;
Минусы:&amp;lt;br/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Чуствителен к начальному приближению. Могут быть ситуации, когда сойдемся к локальному экстремуму.&lt;br /&gt;
* Число компонент &amp;lt;tex&amp;gt;k&amp;lt;/tex&amp;gt; является [[Настройка_гиперпараметров|гиперпараметром]].&lt;br /&gt;
&lt;br /&gt;
== Модификации == &lt;br /&gt;
&lt;br /&gt;
Базовый алгоритм EM является очень гибким для модификаций, позволяющих улучшить его работу. В этом разделе мы приведем краткое описание некоторых из них.&lt;br /&gt;
&lt;br /&gt;
=== Generalized EM-algorithm === &lt;br /&gt;
&lt;br /&gt;
Осоновная идея этой модификации заключается в том, что на шаге M мы не будем пытаться найти наилучшее решение. Это применимо в случаях, когда максимизация &amp;lt;tex&amp;gt;Q(\Theta)&amp;lt;/tex&amp;gt; является сликшом дорогой, поэтому нам достаточно сделать лишь несколько итераций, для того, чтобы сместиться в сторону максимума значения &amp;lt;tex&amp;gt;Q(\Theta)&amp;lt;/tex&amp;gt;. Эта модификация имеет неплохую сходимость.&lt;br /&gt;
&lt;br /&gt;
=== Stochastic EM-algorithm ===&lt;br /&gt;
&lt;br /&gt;
Как уже было отмечено в [[#Плюсы_и_минусы|Плюсы и минусы]], базовый алгоритм чувствителен к начальному приближению и могут быть ситуации, когда алгоритм &amp;quot;застрянет&amp;quot; в локальном экстремуме. Для того, чтобы предотвратить это, будем на каждой итерации алгоритма случайно &amp;quot;встряхивать&amp;quot; выборку. В этой модификации у нас добавляется шаг S, на котором мы и будем &amp;quot;встряхивать&amp;quot; выборку. И на шаге M мы будем решать уже задачу максимуму невзвешенного правдоподобия. Эта модификация хороша тем, что нечуствиетльная к начальном приблежению. &lt;br /&gt;
&lt;br /&gt;
== Пример. Разделение смеси Гауссиана == &lt;br /&gt;
&lt;br /&gt;
[[Файл:Gaussians2.png|right|thumb|400px|Несколько итераций алгоритма]]&lt;br /&gt;
&lt;br /&gt;
Каноническим примером использования EM алгоритма является задача разделения смеси гауссиана. Данные у нас получены из нормального распределения. В этом случае параметрами функций ялвяются матожидание и дисперсия.&amp;lt;br/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt;\theta = (w_1,..,w_k;\;\mu_1,..,\mu_k;\;\sigma_1,..,\sigma_k)&amp;lt;/tex&amp;gt; {{---}} вектор параметров, &amp;lt;br/&amp;gt;&lt;br /&gt;
&amp;lt;tex&amp;gt;p_j(x) = N(x;\mu_j, \sigma_j) = \frac1{\sqrt{2\pi}\sigma_j} \exp \biggl(-\frac{(x - \mu_j)^2}{2\sigma_j^2}\biggr) &amp;lt;/tex&amp;gt; {{---}} плотность распределения.&amp;lt;br/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Посчитаем значения для каждого шага. &amp;lt;br/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
E-шаг:&lt;br /&gt;
&lt;br /&gt;
: &amp;lt;tex&amp;gt; h_{ij} = \frac{w_j N(x_i, \mu_j, \sigma_j)}{\sum\limits_{s=1}^k w_s N(x_i, \mu_s, \sigma_s)}.&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
M-шаг:&lt;br /&gt;
&lt;br /&gt;
: &amp;lt;tex&amp;gt;w_j = \frac{1}{m} \sum\limits_{i=1}^m h_{ij}.&amp;lt;/tex&amp;gt;&lt;br /&gt;
: &amp;lt;tex&amp;gt; \mu_j = \frac {1} {mw_j} \sum\limits_{i=1}^m h_{ij}x_i.&amp;lt;/tex&amp;gt;&lt;br /&gt;
: &amp;lt;tex&amp;gt; \sigma_j^2 = \frac {1} {mw_j} \sum\limits_{i=1}^m h_{ij}(x_i - \mu_j)^2, j = 1..k.&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Использование в задаче кластеризации ==&lt;br /&gt;
&lt;br /&gt;
[[Файл:kmeans.jpg|right|thumb|200px|Пример работы k-means]]&lt;br /&gt;
&lt;br /&gt;
Как уже упоминалось в [[#Определение|Определении]], алгоритм EM подходит для решения задачи кластеризации. И одной из его имплементаций для этой задачи является алгоритм [[Алгоритм_k-Means|&amp;lt;tex&amp;gt;k&amp;lt;/tex&amp;gt;-Means]]. В этом алгоритме в качестве скрытых переменных выступают метки классов объектов. Параметрами же являются центроиды искомых классов. Тогда на шаге E мы относим объекты к какому-то одному классу на основе расстояний до центроид. А на шаге M мы пересчитываем центроиды кластеров, исходя из полученной на шаге E разметке.&amp;lt;br/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Также стоит упомянуть алгоритм [https://ru.wikipedia.org/wiki/Метод_нечёткой_кластеризации_C-средних &amp;lt;tex&amp;gt;c&amp;lt;/tex&amp;gt;-means]. В нем качестве скрытых переменных выступают вероятности принадлежности объекта к классам. На шаге E мы пересчитывем вероятности принадлежности объектов, иходя из расстояния до центроид. Шаг M, идейно, остается без изменений.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Реализация на python ==&lt;br /&gt;
&lt;br /&gt;
В пакете sklearn алгоритм EM представлен объектом GaussianMixture. Проиллюстрируем его работу на примере задачи кластеризации и сравним его с алгоритмом &amp;lt;tex&amp;gt;k&amp;lt;/tex&amp;gt;-means:&lt;br /&gt;
 &lt;br /&gt;
 [[Файл:em_clustering.png|thumb|600px|Результат выполнения программы]]&lt;br /&gt;
 '''import''' numpy as np&lt;br /&gt;
 '''import''' matplotlib.pyplot as plt&lt;br /&gt;
 '''from''' sklearn '''import''' cluster, datasets, mixture&lt;br /&gt;
 '''from''' sklearn.preprocessing '''import''' StandardScaler&lt;br /&gt;
 '''from''' itertools '''import''' cycle, islice&lt;br /&gt;
 np.random.seed(12)&lt;br /&gt;
 &lt;br /&gt;
 &amp;lt;font color=&amp;quot;green&amp;quot;&amp;gt;# Создаем datasets с использованием стандартных sklearn.datasets&amp;lt;/font&amp;gt;&lt;br /&gt;
 n_samples = 2000&lt;br /&gt;
 random_state = 170&lt;br /&gt;
 noisy_circles = datasets.make_circles(n_samples=n_samples, factor=.5, noise=.05)&lt;br /&gt;
 noisy_moons = datasets.make_moons(n_samples=n_samples, noise=.05)&lt;br /&gt;
 blobs = datasets.make_blobs(n_samples=n_samples, random_state=8)&lt;br /&gt;
 varied = datasets.make_blobs(n_samples=n_samples, cluster_std=[1.0, 2.5, 0.5], random_state=random_state)&lt;br /&gt;
 &lt;br /&gt;
 &amp;lt;font color=&amp;quot;green&amp;quot;&amp;gt;# Создаем анизатропно разделенные данные&amp;lt;/font&amp;gt;&lt;br /&gt;
 X, y = datasets.make_blobs(n_samples=n_samples, random_state=random_state)&lt;br /&gt;
 transformation = [[0.6, -0.6], [-0.4, 0.8]]&lt;br /&gt;
 X_aniso = np.dot(X, transformation)&lt;br /&gt;
 aniso = (X_aniso, y)&lt;br /&gt;
 &lt;br /&gt;
 &amp;lt;font color=&amp;quot;green&amp;quot;&amp;gt;# Выставляем параметры для matplotlib.pyplot&amp;lt;/font&amp;gt;&lt;br /&gt;
 plt.figure(figsize=(9 * 2 + 3, 12.5))&lt;br /&gt;
 plt.subplots_adjust(left=.02, right=.98, bottom=.001, top=.96, wspace=.05, hspace=.01)&lt;br /&gt;
 plot_num = 1&lt;br /&gt;
 defaul_n = 3&lt;br /&gt;
 &lt;br /&gt;
 &amp;lt;font color=&amp;quot;green&amp;quot;&amp;gt;# Варьируем значение количества классов в зависимости от данных, ведь для нас это гиперпараметр&amp;lt;/font&amp;gt;&lt;br /&gt;
 datasets = [&lt;br /&gt;
    (varied, defaul_n),&lt;br /&gt;
    (aniso, defaul_n),&lt;br /&gt;
    (blobs, defaul_n),&lt;br /&gt;
    (noisy_circles, 2)]&lt;br /&gt;
 for i_dataset, (dataset, n_cluster) in enumerate(datasets):&lt;br /&gt;
    X, y = dataset&lt;br /&gt;
 &lt;br /&gt;
    &amp;lt;font color=&amp;quot;green&amp;quot;&amp;gt;# Нормализация данных&amp;lt;/font&amp;gt;&lt;br /&gt;
    X = StandardScaler().fit_transform(X)&lt;br /&gt;
 &lt;br /&gt;
    &amp;lt;font color=&amp;quot;green&amp;quot;&amp;gt;# Непосредственно наш алгоритм - Gaussian Mixture&amp;lt;/font&amp;gt;&lt;br /&gt;
    gmm = mixture.GaussianMixture(n_components=n_cluster, covariance_type='full')&lt;br /&gt;
    &lt;br /&gt;
    &amp;lt;font color=&amp;quot;green&amp;quot;&amp;gt;# Для сравнения берем алгоритм - k-means&amp;lt;/font&amp;gt;&lt;br /&gt;
    two_means = cluster.KMeans(n_clusters=n_cluster)&lt;br /&gt;
    clustering_algorithms = {&lt;br /&gt;
        'Real distribution': None,&lt;br /&gt;
        'Gaussian Mixture': gmm,&lt;br /&gt;
        'k-Means': two_means&lt;br /&gt;
    }&lt;br /&gt;
    for name, algorithm in clustering_algorithms:&lt;br /&gt;
 &lt;br /&gt;
        # Этап обучения&lt;br /&gt;
        if algorithm is not None:&lt;br /&gt;
            algorithm.fit(X)&lt;br /&gt;
        &lt;br /&gt;
        # Применяем алгоритм&lt;br /&gt;
         y_pred = y if algorithm is None else algorithm.predict(X)&lt;br /&gt;
        &lt;br /&gt;
        # Рисуем результаты&lt;br /&gt;
        plt.subplot(len(datasets), len(clustering_algorithms), plot_num)&lt;br /&gt;
        if i_dataset == 0:&lt;br /&gt;
            plt.title(name, size=18)&lt;br /&gt;
        colors = np.array(list(islice(cycle(['#377eb8', '#ff7f00', '#4daf4a']), int(max(y_pred) + 1))))&lt;br /&gt;
        plt.scatter(X[:, 0], X[:, 1], s=10, color=colors[y_pred])&lt;br /&gt;
        plt.xlim(-2.5, 2.5)&lt;br /&gt;
        plt.ylim(-2.5, 2.5)&lt;br /&gt;
        plt.xticks(())&lt;br /&gt;
        plt.yticks(())&lt;br /&gt;
        plot_num += 1&lt;br /&gt;
 plt.show()&lt;br /&gt;
&lt;br /&gt;
Как и следовало ожидать, алгоритм EM работает на некоторых данных лучше чем k-means, однако есть данные, с которыми он не справляется без дополнительных преобразований.&lt;br /&gt;
&lt;br /&gt;
== См. также ==&lt;br /&gt;
*[[Кластеризация]]&lt;br /&gt;
*[[Алгоритм_k-Means|Алгоритм k-Means]]&lt;br /&gt;
&lt;br /&gt;
==Примечания==&lt;br /&gt;
&amp;lt;references /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Источники информации ==&lt;br /&gt;
&lt;br /&gt;
# Материалы лекции про кластеризацию курса &amp;quot;Машинное обучение&amp;quot; университета ИТМО, 2019 год&lt;br /&gt;
# [http://www.machinelearning.ru/wiki/images/6/6d/Voron-ML-1.pdf Математические методы обучения по прецедентам К. В. Воронцов]&lt;br /&gt;
# [http://www.machinelearning.ru/wiki/index.php?title=EM-%D0%B0%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC Статья про EM-алгоритм на machinelearning.ru]&lt;br /&gt;
# [https://machinelearningmastery.com/expectation-maximization-em-algorithm/ A Gentle Introduction to Expectation-Maximization]&lt;br /&gt;
# [http://dendroid.sk/2011/05/09/k-means-clustering/ k-means]&lt;br /&gt;
&lt;br /&gt;
[[Категория: Машинное обучение]]&lt;br /&gt;
[[Категория: Кластеризация]]&lt;/div&gt;</summary>
		<author><name>94.229.111.244</name></author>	</entry>

	<entry>
		<id>http://neerc.ifmo.ru/wiki/index.php?title=EM-%D0%B0%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC&amp;diff=73025</id>
		<title>EM-алгоритм</title>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=EM-%D0%B0%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC&amp;diff=73025"/>
				<updated>2020-03-21T11:05:28Z</updated>
		
		<summary type="html">&lt;p&gt;94.229.111.244: Исправил тире&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Определение ==&lt;br /&gt;
&lt;br /&gt;
'''Алгоритм EM''' (англ. ''expectation-maximization'') {{---}} итеративный алгоритм поиска оценок максимума правдоподобия модели, в ситуации, когда она зависит от скрытых (ненаблюдаемых) переменных.&lt;br /&gt;
&lt;br /&gt;
Алгоритм ищет параметры модели итеративно, каждая итерация состоит из двух шагов:&lt;br /&gt;
&lt;br /&gt;
'''E (Expectation)''' шаг {{---}} поиск наиболее вероятных значений скрытых переменных.&lt;br /&gt;
&lt;br /&gt;
'''M (Maximization)''' шаг {{---}} поиск наиболее вероятных значений параметров, для полученных на шаге E значений скрытых переменных.&lt;br /&gt;
&lt;br /&gt;
EM алгоритм подходит для решения задач двух типов:&lt;br /&gt;
&lt;br /&gt;
# Задачи с неполными данными.&lt;br /&gt;
# Задачи, в которых удобно вводить скрытые переменные для упрощения подсчета функции правдоподобия. Примером такой задачи может служить кластеризация.&lt;br /&gt;
&lt;br /&gt;
== Основной алгоритм == &lt;br /&gt;
&lt;br /&gt;
=== Постановка задачи ===&lt;br /&gt;
&lt;br /&gt;
Плотность распределения смеси имеет вид:&amp;lt;br/&amp;gt;&lt;br /&gt;
&amp;lt;tex&amp;gt;p(x) = \sum\limits_{j=1}^k w_j p_j(x)&amp;lt;/tex&amp;gt;&amp;lt;br/&amp;gt;&lt;br /&gt;
Где &amp;lt;tex&amp;gt; \sum\limits_{j=1}^k w_j = 1;  w_j \geq 0; p_j(x) = \phi(x;\theta_j)&amp;lt;/tex&amp;gt; {{---}} функция правдоподобия &amp;lt;tex&amp;gt;j&amp;lt;/tex&amp;gt;-ой компонеты смеси, &amp;lt;tex&amp;gt;w_j&amp;lt;/tex&amp;gt; {{---}} априорная вероятность &amp;lt;tex&amp;gt;j&amp;lt;/tex&amp;gt;-ой компоненты смеси.&amp;lt;br/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Перед нами стоит две задачи:&amp;lt;br/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
# По заданной выборке &amp;lt;tex&amp;gt;X^m&amp;lt;/tex&amp;gt; случайных и независимых наблюдений полученных из смеси &amp;lt;tex&amp;gt;p(x)&amp;lt;/tex&amp;gt;, числу &amp;lt;tex&amp;gt;k&amp;lt;/tex&amp;gt; и функции &amp;lt;tex&amp;gt;\phi&amp;lt;/tex&amp;gt;, оценить вектор параметров &amp;lt;tex&amp;gt;\Theta = (w_1,..,w_k,\theta_1,..,\theta_k)&amp;lt;/tex&amp;gt;&lt;br /&gt;
# Найти &amp;lt;tex&amp;gt;k&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Проблема === &lt;br /&gt;
&lt;br /&gt;
Задачи подобного рода мы умеем решать, максимизируя логармиф правдоподобия:&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;tex&amp;gt; L(\Theta) = ln \prod\limits_{i=1}^mp(x_i) = \sum\limits_{i=1}^m ln\sum\limits_{j=1}^k w_j p_j(x_i; \theta_j) \longrightarrow \max\limits_{\Theta}&amp;lt;/tex&amp;gt;&amp;lt;br/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Но проблeма в том, что мы не знаем как аналитически посчитать логарифм суммы. Тут нам и поможет алгоритм EM.&lt;br /&gt;
&lt;br /&gt;
=== Решение === &lt;br /&gt;
&lt;br /&gt;
Основная идея алгоритма EM заключается в том, что мы добавляем скрытые переменные такие, что:&amp;lt;br/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
# Они могут быть выражены через &amp;lt;tex&amp;gt;\Theta&amp;lt;/tex&amp;gt;&lt;br /&gt;
# Они помогают разбить сумму так: &amp;lt;tex&amp;gt;p (X, H|\Theta) = \prod\limits_{i=1}^k p (X|H, \Theta) p(H|\Theta)&amp;lt;/tex&amp;gt;, где &amp;lt;tex&amp;gt;H&amp;lt;/tex&amp;gt; {{---}} матрица скрытых переменных.&lt;br /&gt;
&lt;br /&gt;
Тогда алгоритм EM сводится к повторению шагов, указанных в [[#Определение|Определении]].&lt;br /&gt;
&lt;br /&gt;
=== E-шаг === &lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt;p(x,\theta_j) = p(x)P(\theta_j | x) = w_jp_j(x)&amp;lt;/tex&amp;gt; &amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Скрытые переменные представляют из себя матрицу &amp;lt;tex&amp;gt;H = (h_{ij})_{m \times k}&amp;lt;/tex&amp;gt;&amp;lt;br/&amp;gt;&lt;br /&gt;
где &amp;lt;tex&amp;gt;h_{ij} = P(\theta_j | x_i)&amp;lt;/tex&amp;gt; {{---}} вероятность того, что &amp;lt;tex&amp;gt;x_i&amp;lt;/tex&amp;gt; пренадлежит &amp;lt;tex&amp;gt;j&amp;lt;/tex&amp;gt;-ой компоненте.&amp;lt;br/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
По формуле Байеса справедливо равенство:&amp;lt;br /&amp;gt;&lt;br /&gt;
&amp;lt;tex&amp;gt; h_{ij} = \frac{w_jp_j(x_i)}{p (x_i)} = \frac{w_jp_j(x_i)}{\sum\limits_{s=1}^k w_s p_s(x_i)}&amp;lt;/tex&amp;gt;&amp;lt;br/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Также &amp;lt;tex&amp;gt;\sum\limits_{j=1}^k h_{ij} = 1&amp;lt;/tex&amp;gt;&amp;lt;br/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Таким образом, зная значения вектора параметров &amp;lt;tex&amp;gt;\Theta&amp;lt;/tex&amp;gt;, мы легко можем пересчитать значения скрытых переменных&amp;lt;br/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== M-шаг === &lt;br /&gt;
&lt;br /&gt;
{{Теорема&lt;br /&gt;
|statement=&lt;br /&gt;
Если известны скрытые переменные, то задача минимизации &amp;lt;tex&amp;gt;Q(\Theta)&amp;lt;/tex&amp;gt; сводится к &amp;lt;tex&amp;gt;k&amp;lt;/tex&amp;gt; независимым подзадачам:&amp;lt;br/&amp;gt;&lt;br /&gt;
&amp;lt;center&amp;gt;&amp;lt;tex&amp;gt;\theta_j = \arg\max\limits_{\theta}\sum\limits_{i=1}^m h_{ij}*\ln\phi(x_i;\theta)&amp;lt;/tex&amp;gt;&amp;lt;/center&amp;gt;&lt;br /&gt;
Оптимальные же веса считаются как:&amp;lt;br/&amp;gt;&lt;br /&gt;
&amp;lt;center&amp;gt;&amp;lt;tex&amp;gt; w_j = \frac {1} {m} \sum\limits_{i=1}^m h_{ij}&amp;lt;/tex&amp;gt;&amp;lt;/center&amp;gt;&lt;br /&gt;
|proof=&lt;br /&gt;
Посчитаем логарифм правдоподобия:&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;tex&amp;gt; Q(\Theta) = \sum\limits_{i=1}^m ln\sum\limits_{j=1}^k w_j p_j(x_i; \theta_j) \longrightarrow \max\limits_{\Theta}&amp;lt;/tex&amp;gt;&amp;lt;br/&amp;gt;&lt;br /&gt;
При условии, что&amp;lt;tex&amp;gt; \sum\limits_{j=1}^k w_j = 1; w_j \geq 0&amp;lt;/tex&amp;gt; имеет смысл рассматривать Лагранжиан задачи:&amp;lt;br/&amp;gt;&lt;br /&gt;
&amp;lt;tex&amp;gt; L(\Theta, X^m) = \sum\limits_{i=1}^m ln \biggl( \sum\limits_{j=1}^k w_j p_j(x_i) \biggr)  - \lambda \biggl(\sum\limits_{j=1}^k w_j - 1 \biggr) &amp;lt;/tex&amp;gt;&amp;lt;br/&amp;gt;&lt;br /&gt;
Приравняв нулю производную Лагранжиана по &amp;lt;tex&amp;gt;w_j&amp;lt;/tex&amp;gt;, получим:&amp;lt;br/&amp;gt;&lt;br /&gt;
&amp;lt;tex&amp;gt;\frac{\partial L} {\partial w_j} = \sum\limits_{i=1}^m \frac{p_j(x_i)}{\sum\limits_{s=1}^kw_s p_s(x_i)} - \lambda = 0, j = 1..k&amp;lt;/tex&amp;gt;&amp;lt;br /&amp;gt;&lt;br /&gt;
Умножим на &amp;lt;tex&amp;gt;w_j&amp;lt;/tex&amp;gt; и просуммируем уравнения для всех &amp;lt;tex&amp;gt;j&amp;lt;/tex&amp;gt; &amp;lt;br /&amp;gt;&lt;br /&gt;
&amp;lt;tex&amp;gt;\sum\limits_{j=1}^k \sum\limits_{i=1}^m \frac{w_jp_j(x_i)}{\sum\limits_{s=1}^kw_s p_s(x_i)} = \lambda \sum\limits_{j=1}^kw_j&amp;lt;/tex&amp;gt; &amp;lt;br /&amp;gt;&lt;br /&gt;
А так как &amp;lt;tex&amp;gt;\sum\limits_{j=1}^k \frac{w_jp_j(x_i)}{\sum\limits_{s=1}^kw_sp_s(x_i)} = 1&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;\sum\limits_{j=1}^kw_j = 1&amp;lt;/tex&amp;gt;, из чего следует &amp;lt;tex&amp;gt;\lambda = m&amp;lt;/tex&amp;gt; &amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt;w_j = \frac{1}{m}\sum\limits_{i=1}^m \frac{w_jp_j(x_i)}{\sum\limits_{s=1}^kw_sp_s(x_i)} = \frac{1}{m}\sum\limits_{i=1}^m h_{ij}&amp;lt;/tex&amp;gt;&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Приравняв к нулю производную Лагранжиана по &amp;lt;tex&amp;gt;\theta_j&amp;lt;/tex&amp;gt;, схожим способом найдем:&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt; \theta_j = \arg\max\limits_{\theta}\sum\limits_{i=1}^m h_{ij}*\ln\phi(x_i;\theta).&amp;lt;/tex&amp;gt;&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
=== Критерий остановки === &lt;br /&gt;
&lt;br /&gt;
Алгоритм EM вы полняется до сходимости, но как нам определить, что сходимость наступила? Мы можем останавливаться, когда либо &amp;lt;tex&amp;gt;Q(\Theta)&amp;lt;/tex&amp;gt;, либо &amp;lt;tex&amp;gt;H&amp;lt;/tex&amp;gt; перестают сильно меняться. Но, обычно, удобней контролировать изменения значений скрытых переменных, так как они имеют смысл вероятностей и принимают значения из отрезка &amp;lt;tex&amp;gt;[0,1]&amp;lt;/tex&amp;gt;. Поэтому один из возможных критериев остановки будет выглядеть так: &amp;lt;tex&amp;gt;\max\limits_{i,j} |h_{ij} - h_{ij}^{(0)}| &amp;gt; \delta&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Псевдокод === &lt;br /&gt;
&lt;br /&gt;
 Input:&amp;lt;tex&amp;gt;X^m, k, \Theta^{(0)}&amp;lt;/tex&amp;gt;&lt;br /&gt;
 Repeat&lt;br /&gt;
    '''E-step''': for all i = 1..m; j = 1..k:&lt;br /&gt;
        &amp;lt;tex&amp;gt;h_{ij} = \frac{w_j \phi(x_i; \theta_j)}{\sum\limits_{s=1}^k w_s \phi(x_i; \theta_j)}&amp;lt;/tex&amp;gt;&lt;br /&gt;
    '''M-step''': for all j = 1..k:&lt;br /&gt;
        &amp;lt;tex&amp;gt;\theta_j = \arg\max\limits_{\theta} \sum\limits_{i=1}^m h_{ij}*ln \phi (x_i, \theta)&amp;lt;/tex&amp;gt;&lt;br /&gt;
        &amp;lt;tex&amp;gt;w_j = \frac {1} {m} \sum\limits_{i=1}^m h_{ij}&amp;lt;/tex&amp;gt;&lt;br /&gt;
 Until a stopping criterion is satisfied&lt;br /&gt;
 Return &amp;lt;tex&amp;gt;\Theta = (\theta_j, w_j)_{j=1}^k&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Плюсы и минусы === &lt;br /&gt;
&lt;br /&gt;
Плюсы:&amp;lt;br/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Сходится в большинтсве случаев&lt;br /&gt;
* Наиболее гибкое решение&lt;br /&gt;
* Существуют простые модификации, позволяющие уменьшить чуствительность алгоритма к шуму в данных&lt;br /&gt;
&lt;br /&gt;
Минусы:&amp;lt;br/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Чуствителен к начальному приближению. Могут быть ситуации, когда сойдемся к локальному экстремуму&lt;br /&gt;
* Число компонент &amp;lt;tex&amp;gt;k&amp;lt;/tex&amp;gt; является гиперпараметром.&lt;br /&gt;
&lt;br /&gt;
== Модификации == &lt;br /&gt;
&lt;br /&gt;
Базовый алгоритм EM является очень гибким для модификаций, позволяющих улучшить его работу. В этом разделе мы приведем краткое описаниен некоторых из них.&lt;br /&gt;
&lt;br /&gt;
=== Generalized EM-algorithm === &lt;br /&gt;
&lt;br /&gt;
Осоновная идея этой модификации заключается в том, что на шаге M мы не будем пытаться найти наилучшее решение. Это применимо в случаях, когда максимизация &amp;lt;tex&amp;gt;Q(\Theta)&amp;lt;/tex&amp;gt; является сликшом дорогой, поэтому нам достаточно сделать лишь несколько итераций, для того, чтобы сместиться в сторону максимума значения &amp;lt;tex&amp;gt;Q(\Theta)&amp;lt;/tex&amp;gt;. Эта модификация имеет неплохую сходимость.&lt;br /&gt;
&lt;br /&gt;
=== Stochastic EM-algorithm ===&lt;br /&gt;
&lt;br /&gt;
Как уже было отмечено в [[#Плюсы_и_минусы|Плюсы и минусы]], базовый алгоритм чувствителен к начальному приближению и могут быть ситуации, когда алгоритм &amp;quot;застрянет&amp;quot; в лоакльном экстремуме. Для того, чтобы предотвратить это, будем на каждой итерации алгоритма случайно &amp;quot;встряхивать&amp;quot; выборку. В этой модификации у нас добавляется шаг S, на котором мы и будем &amp;quot;встряхивать&amp;quot; выборку. И на шаге M мы будем решать уже задачу максимуму невзвешенного правдоподобия. Эта модификация хороша тем, что нечуствиетльная к начальном приблежению. &lt;br /&gt;
&lt;br /&gt;
== Пример. Разделение смеси Гауссиана == &lt;br /&gt;
&lt;br /&gt;
[[Файл:Gaussians2.png|right|thumb|400px|Несколько итераций алгоритма]]&lt;br /&gt;
&lt;br /&gt;
Каноническим примером использования EM алгоритма является задача разделения смеси гауссиана. Данные у нас получены из нормального распределения. В этом случае параметрами функций ялвяются матожидание и дисперсия.&amp;lt;br/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt;\theta = (w_1,..,w_k;\;\mu_1,..,\mu_k;\;\sigma_1,..,\sigma_k)&amp;lt;/tex&amp;gt; {{---}} вектор параметров, &amp;lt;br/&amp;gt;&lt;br /&gt;
&amp;lt;tex&amp;gt;p_j(x) = N(x;\mu_j, \sigma_j) = \frac1{\sqrt{2\pi}\sigma_j} \exp \biggl(-\frac{(x - \mu_j)^2}{2\sigma_j^2}\biggr) &amp;lt;/tex&amp;gt; - плотность распределения &amp;lt;br/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Посчитаем значения для каждого шага. &amp;lt;br/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
E-шаг:&lt;br /&gt;
&lt;br /&gt;
: &amp;lt;tex&amp;gt; h_{ij} = \frac{w_j N(x_i, \mu_j, \sigma_j)}{\sum\limits_{s=1}^k w_s N(x_i, \mu_s, \sigma_s)} &amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
M-шаг:&lt;br /&gt;
&lt;br /&gt;
: &amp;lt;tex&amp;gt;w_j = \frac{1}{m} \sum\limits_{i=1}^m h_{ij}&amp;lt;/tex&amp;gt;&lt;br /&gt;
: &amp;lt;tex&amp;gt; \mu_j = \frac {1} {mw_j} \sum\limits_{i=1}^m h_{ij}x_i&amp;lt;/tex&amp;gt;&lt;br /&gt;
: &amp;lt;tex&amp;gt; \sigma_j^2 = \frac {1} {mw_j} \sum\limits_{i=1}^m h_{ij}(x_i - \mu_j)^2, j = 1..k&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Использование в задаче кластеризации ==&lt;br /&gt;
&lt;br /&gt;
[[Файл:kmeans.jpg|right|thumb|200px|Пример работы k-means]]&lt;br /&gt;
&lt;br /&gt;
Как уже упоминалось в [[#Определение|Определении]], алгоритм EM подходит для решения задачи кластеризации. И одной из его имплементаций для этой задачи является алгоритм &amp;lt;tex&amp;gt;k&amp;lt;/tex&amp;gt;-means. В этом алгоритме в качестве скрытых переменных выступают метки классов объектов. Параметрами же являются центроиды искомых классов. Тогда на шаге E мы относим объекты к какому-то одному классу на основе расстояний до центроид. А на шаге M мы пересчитываем центроиды кластеров, исходя из полученной на шаге E разметке.&amp;lt;br/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Также стоит упомянуть алгоритм &amp;lt;tex&amp;gt;c&amp;lt;/tex&amp;gt;-means. В нем качестве скрытых переменных выступают вероятности принадлежности объекта к классам. На шаге E мы пересчитывем вероятности принадлежности объектов, иходя из расстояния до центроид. Шаг M, идейно, остается без изменений.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Реализация на python ==&lt;br /&gt;
&lt;br /&gt;
В пакете sklearn алгоритм EM представлен объектом GaussianMixture. Проиллюстрируем его работу на примере задачи кластеризации и сравним его с алгоритмом &amp;lt;tex&amp;gt;k&amp;lt;/tex&amp;gt;-means:&lt;br /&gt;
 &lt;br /&gt;
 [[Файл:em_clustering.png|thumb|600px|Результат выполнения программы]]&lt;br /&gt;
 '''import''' numpy as np&lt;br /&gt;
 '''import''' matplotlib.pyplot as plt&lt;br /&gt;
 '''from''' sklearn '''import''' cluster, datasets, mixture&lt;br /&gt;
 '''from''' sklearn.preprocessing '''import''' StandardScaler&lt;br /&gt;
 '''from''' itertools '''import''' cycle, islice&lt;br /&gt;
 np.random.seed(12)&lt;br /&gt;
 &lt;br /&gt;
 &amp;lt;font color=&amp;quot;green&amp;quot;&amp;gt;# Создаем datasets с использованием стандартных sklearn.datasets&amp;lt;/font&amp;gt;&lt;br /&gt;
 n_samples = 2000&lt;br /&gt;
 random_state = 170&lt;br /&gt;
 noisy_circles = datasets.make_circles(n_samples=n_samples, factor=.5, noise=.05)&lt;br /&gt;
 noisy_moons = datasets.make_moons(n_samples=n_samples, noise=.05)&lt;br /&gt;
 blobs = datasets.make_blobs(n_samples=n_samples, random_state=8)&lt;br /&gt;
 varied = datasets.make_blobs(n_samples=n_samples, cluster_std=[1.0, 2.5, 0.5], random_state=random_state)&lt;br /&gt;
 &lt;br /&gt;
 &amp;lt;font color=&amp;quot;green&amp;quot;&amp;gt;# Создаем анизатропно разделенные данные&amp;lt;/font&amp;gt;&lt;br /&gt;
 X, y = datasets.make_blobs(n_samples=n_samples, random_state=random_state)&lt;br /&gt;
 transformation = [[0.6, -0.6], [-0.4, 0.8]]&lt;br /&gt;
 X_aniso = np.dot(X, transformation)&lt;br /&gt;
 aniso = (X_aniso, y)&lt;br /&gt;
 &lt;br /&gt;
 &amp;lt;font color=&amp;quot;green&amp;quot;&amp;gt;# Выставляем параметры для matplotlib.pyplot&amp;lt;/font&amp;gt;&lt;br /&gt;
 plt.figure(figsize=(9 * 2 + 3, 12.5))&lt;br /&gt;
 plt.subplots_adjust(left=.02, right=.98, bottom=.001, top=.96, wspace=.05, hspace=.01)&lt;br /&gt;
 plot_num = 1&lt;br /&gt;
 defaul_n = 3&lt;br /&gt;
 &lt;br /&gt;
 &amp;lt;font color=&amp;quot;green&amp;quot;&amp;gt;# Варьируем значение количества классов в зависимости от данных, ведь для нас это гиперпараметр&amp;lt;/font&amp;gt;&lt;br /&gt;
 datasets = [&lt;br /&gt;
    (varied, defaul_n),&lt;br /&gt;
    (aniso, defaul_n),&lt;br /&gt;
    (blobs, defaul_n),&lt;br /&gt;
    (noisy_circles, 2)]&lt;br /&gt;
 for i_dataset, (dataset, n_cluster) in enumerate(datasets):&lt;br /&gt;
    X, y = dataset&lt;br /&gt;
 &lt;br /&gt;
    &amp;lt;font color=&amp;quot;green&amp;quot;&amp;gt;# Нормализация данных&amp;lt;/font&amp;gt;&lt;br /&gt;
    X = StandardScaler().fit_transform(X)&lt;br /&gt;
 &lt;br /&gt;
    &amp;lt;font color=&amp;quot;green&amp;quot;&amp;gt;# Непосредственно наш алгоритм - Gaussian Mixture&amp;lt;/font&amp;gt;&lt;br /&gt;
    gmm = mixture.GaussianMixture(n_components=n_cluster, covariance_type='full')&lt;br /&gt;
    &lt;br /&gt;
    &amp;lt;font color=&amp;quot;green&amp;quot;&amp;gt;# Для сравнения берем алгоритм - k-means&amp;lt;/font&amp;gt;&lt;br /&gt;
    two_means = cluster.KMeans(n_clusters=n_cluster)&lt;br /&gt;
    clustering_algorithms = {&lt;br /&gt;
        'Real distribution': None,&lt;br /&gt;
        'Gaussian Mixture': gmm,&lt;br /&gt;
        'k-Means': two_means&lt;br /&gt;
    }&lt;br /&gt;
    for name, algorithm in clustering_algorithms:&lt;br /&gt;
 &lt;br /&gt;
        # Этап обучения&lt;br /&gt;
        if algorithm is not None:&lt;br /&gt;
            algorithm.fit(X)&lt;br /&gt;
        &lt;br /&gt;
        # Применяем алгоритм&lt;br /&gt;
         y_pred = y if algorithm is None else algorithm.predict(X)&lt;br /&gt;
        &lt;br /&gt;
        # Рисуем результаты&lt;br /&gt;
        plt.subplot(len(datasets), len(clustering_algorithms), plot_num)&lt;br /&gt;
        if i_dataset == 0:&lt;br /&gt;
            plt.title(name, size=18)&lt;br /&gt;
        colors = np.array(list(islice(cycle(['#377eb8', '#ff7f00', '#4daf4a']), int(max(y_pred) + 1))))&lt;br /&gt;
        plt.scatter(X[:, 0], X[:, 1], s=10, color=colors[y_pred])&lt;br /&gt;
        plt.xlim(-2.5, 2.5)&lt;br /&gt;
        plt.ylim(-2.5, 2.5)&lt;br /&gt;
        plt.xticks(())&lt;br /&gt;
        plt.yticks(())&lt;br /&gt;
        plot_num += 1&lt;br /&gt;
 plt.show()&lt;br /&gt;
&lt;br /&gt;
Как и следовало ожидать, алгоритм EM работает на некоторых данных лучше чем k-means, однако есть данные, с которыми он не справляется без дополнительных преобразований.&lt;br /&gt;
&lt;br /&gt;
== См. также ==&lt;br /&gt;
*[[Кластеризация]]&lt;br /&gt;
*[[Алгоритм_k-Means|Алгоритм k-Means]]&lt;br /&gt;
&lt;br /&gt;
== Источники информации ==&lt;br /&gt;
&lt;br /&gt;
# Материалы лекции про кластеризацию курса &amp;quot;Машинное обучение&amp;quot; университета ИТМО, 2019 год&lt;br /&gt;
# [http://www.machinelearning.ru/wiki/images/6/6d/Voron-ML-1.pdf Математические методы обучения по прецедентам К. В. Воронцов]&lt;br /&gt;
# [http://www.machinelearning.ru/wiki/index.php?title=EM-%D0%B0%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC Статья про EM-алгоритм на machinelearning.ru]&lt;br /&gt;
# [https://machinelearningmastery.com/expectation-maximization-em-algorithm/ A Gentle Introduction to Expectation-Maximization]&lt;br /&gt;
# [http://dendroid.sk/2011/05/09/k-means-clustering/ k-means]&lt;br /&gt;
&lt;br /&gt;
[[Категория:Машинное обучение]]&lt;/div&gt;</summary>
		<author><name>94.229.111.244</name></author>	</entry>

	<entry>
		<id>http://neerc.ifmo.ru/wiki/index.php?title=EM-%D0%B0%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC&amp;diff=73023</id>
		<title>EM-алгоритм</title>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=EM-%D0%B0%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC&amp;diff=73023"/>
				<updated>2020-03-21T11:03:54Z</updated>
		
		<summary type="html">&lt;p&gt;94.229.111.244: Поправил опечатки&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Определение ==&lt;br /&gt;
&lt;br /&gt;
'''Алгоритм EM''' (англ. ''expectation-maximization'') {{---}} итеративный алгоритм поиска оценок максимума правдоподобия модели, в ситуации, когда она зависит от скрытых (ненаблюдаемых) переменных.&lt;br /&gt;
&lt;br /&gt;
Алгоритм ищет параметры модели итеративно, каждая итерация состоит из двух шагов:&lt;br /&gt;
&lt;br /&gt;
'''E (Expectation)''' шаг {{---}} поиск наиболее вероятных значений скрытых переменных.&lt;br /&gt;
&lt;br /&gt;
'''M (Maximization)''' шаг {{---}} поиск наиболее вероятных значений параметров, для полученных на шаге E значений скрытых переменных.&lt;br /&gt;
&lt;br /&gt;
EM алгоритм подходит для решения задач двух типов:&lt;br /&gt;
&lt;br /&gt;
# Задачи с неполными данными.&lt;br /&gt;
# Задачи, в которых удобно вводить скрытые переменные для упрощения подсчета функции правдоподобия. Примером такой задачи может служить кластеризация.&lt;br /&gt;
&lt;br /&gt;
== Основной алгоритм == &lt;br /&gt;
&lt;br /&gt;
=== Постановка задачи ===&lt;br /&gt;
&lt;br /&gt;
Плотность распределения смеси имеет вид:&amp;lt;br/&amp;gt;&lt;br /&gt;
&amp;lt;tex&amp;gt;p(x) = \sum\limits_{j=1}^k w_j p_j(x)&amp;lt;/tex&amp;gt;&amp;lt;br/&amp;gt;&lt;br /&gt;
Где &amp;lt;tex&amp;gt; \sum\limits_{j=1}^k w_j = 1;  w_j \geq 0; p_j(x) = \phi(x;\theta_j)&amp;lt;/tex&amp;gt; {{---}} функция правдоподобия &amp;lt;tex&amp;gt;j&amp;lt;/tex&amp;gt;-ой компонеты смеси, &amp;lt;tex&amp;gt;w_j&amp;lt;/tex&amp;gt; {{---}} априорная вероятность &amp;lt;tex&amp;gt;j&amp;lt;/tex&amp;gt;-ой компоненты смеси.&amp;lt;br/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Перед нами стоит две задачи:&amp;lt;br/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
# По заданной выборке &amp;lt;tex&amp;gt;X^m&amp;lt;/tex&amp;gt; случайных и независимых наблюдений полученных из смеси &amp;lt;tex&amp;gt;p(x)&amp;lt;/tex&amp;gt;, числу &amp;lt;tex&amp;gt;k&amp;lt;/tex&amp;gt; и функции &amp;lt;tex&amp;gt;\phi&amp;lt;/tex&amp;gt;, оценить вектор параметров &amp;lt;tex&amp;gt;\Theta = (w_1,..,w_k,\theta_1,..,\theta_k)&amp;lt;/tex&amp;gt;&lt;br /&gt;
# Найти &amp;lt;tex&amp;gt;k&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Проблема === &lt;br /&gt;
&lt;br /&gt;
Задачи подобного рода мы умеем решать, максимизируя логармиф правдоподобия:&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;tex&amp;gt; L(\Theta) = ln \prod\limits_{i=1}^mp(x_i) = \sum\limits_{i=1}^m ln\sum\limits_{j=1}^k w_j p_j(x_i; \theta_j) \longrightarrow \max\limits_{\Theta}&amp;lt;/tex&amp;gt;&amp;lt;br/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Но проблeма в том, что мы не знаем как аналитически посчитать логарифм суммы. Тут нам и поможет алгоритм EM.&lt;br /&gt;
&lt;br /&gt;
=== Решение === &lt;br /&gt;
&lt;br /&gt;
Основная идея алгоритма EM заключается в том, что мы добавляем скрытые переменные такие, что:&amp;lt;br/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
# Они могут быть выражены через &amp;lt;tex&amp;gt;\Theta&amp;lt;/tex&amp;gt;&lt;br /&gt;
# Они помогают разбить сумму так: &amp;lt;tex&amp;gt;p (X, H|\Theta) = \prod\limits_{i=1}^k p (X|H, \Theta) p(H|\Theta)&amp;lt;/tex&amp;gt;, где &amp;lt;tex&amp;gt;H&amp;lt;/tex&amp;gt; - матрица скрытых переменных.&lt;br /&gt;
&lt;br /&gt;
Тогда алгоритм EM сводится к повторению шагов, указанных в [[#Определение|Определении]].&lt;br /&gt;
&lt;br /&gt;
=== E-шаг === &lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt;p(x,\theta_j) = p(x)P(\theta_j | x) = w_jp_j(x)&amp;lt;/tex&amp;gt; &amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Скрытые переменные представляют из себя матрицу &amp;lt;tex&amp;gt;H = (h_{ij})_{m \times k}&amp;lt;/tex&amp;gt;&amp;lt;br/&amp;gt;&lt;br /&gt;
где &amp;lt;tex&amp;gt;h_{ij} = P(\theta_j | x_i)&amp;lt;/tex&amp;gt; {{---}} вероятность того, что &amp;lt;tex&amp;gt;x_i&amp;lt;/tex&amp;gt; пренадлежит &amp;lt;tex&amp;gt;j&amp;lt;/tex&amp;gt;-ой компоненте.&amp;lt;br/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
По формуле Байеса справедливо равенство:&amp;lt;br /&amp;gt;&lt;br /&gt;
&amp;lt;tex&amp;gt; h_{ij} = \frac{w_jp_j(x_i)}{p (x_i)} = \frac{w_jp_j(x_i)}{\sum\limits_{s=1}^k w_s p_s(x_i)}&amp;lt;/tex&amp;gt;&amp;lt;br/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Также &amp;lt;tex&amp;gt;\sum\limits_{j=1}^k h_{ij} = 1&amp;lt;/tex&amp;gt;&amp;lt;br/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Таким образом, зная значения вектора параметров &amp;lt;tex&amp;gt;\Theta&amp;lt;/tex&amp;gt;, мы легко можем пересчитать значения скрытых переменных&amp;lt;br/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== M-шаг === &lt;br /&gt;
&lt;br /&gt;
{{Теорема&lt;br /&gt;
|statement=&lt;br /&gt;
Если известны скрытые переменные, то задача минимизации &amp;lt;tex&amp;gt;Q(\Theta)&amp;lt;/tex&amp;gt; сводится к &amp;lt;tex&amp;gt;k&amp;lt;/tex&amp;gt; независимым подзадачам:&amp;lt;br/&amp;gt;&lt;br /&gt;
&amp;lt;center&amp;gt;&amp;lt;tex&amp;gt;\theta_j = \arg\max\limits_{\theta}\sum\limits_{i=1}^m h_{ij}*\ln\phi(x_i;\theta)&amp;lt;/tex&amp;gt;&amp;lt;/center&amp;gt;&lt;br /&gt;
Оптимальные же веса считаются как:&amp;lt;br/&amp;gt;&lt;br /&gt;
&amp;lt;center&amp;gt;&amp;lt;tex&amp;gt; w_j = \frac {1} {m} \sum\limits_{i=1}^m h_{ij}&amp;lt;/tex&amp;gt;&amp;lt;/center&amp;gt;&lt;br /&gt;
|proof=&lt;br /&gt;
Посчитаем логарифм правдоподобия:&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;tex&amp;gt; Q(\Theta) = \sum\limits_{i=1}^m ln\sum\limits_{j=1}^k w_j p_j(x_i; \theta_j) \longrightarrow \max\limits_{\Theta}&amp;lt;/tex&amp;gt;&amp;lt;br/&amp;gt;&lt;br /&gt;
При условии, что&amp;lt;tex&amp;gt; \sum\limits_{j=1}^k w_j = 1; w_j \geq 0&amp;lt;/tex&amp;gt; имеет смысл рассматривать Лагранжиан задачи:&amp;lt;br/&amp;gt;&lt;br /&gt;
&amp;lt;tex&amp;gt; L(\Theta, X^m) = \sum\limits_{i=1}^m ln \biggl( \sum\limits_{j=1}^k w_j p_j(x_i) \biggr)  - \lambda \biggl(\sum\limits_{j=1}^k w_j - 1 \biggr) &amp;lt;/tex&amp;gt;&amp;lt;br/&amp;gt;&lt;br /&gt;
Приравняв нулю производную Лагранжиана по &amp;lt;tex&amp;gt;w_j&amp;lt;/tex&amp;gt;, получим:&amp;lt;br/&amp;gt;&lt;br /&gt;
&amp;lt;tex&amp;gt;\frac{\partial L} {\partial w_j} = \sum\limits_{i=1}^m \frac{p_j(x_i)}{\sum\limits_{s=1}^kw_s p_s(x_i)} - \lambda = 0, j = 1..k&amp;lt;/tex&amp;gt;&amp;lt;br /&amp;gt;&lt;br /&gt;
Умножим на &amp;lt;tex&amp;gt;w_j&amp;lt;/tex&amp;gt; и просуммируем уравнения для всех &amp;lt;tex&amp;gt;j&amp;lt;/tex&amp;gt; &amp;lt;br /&amp;gt;&lt;br /&gt;
&amp;lt;tex&amp;gt;\sum\limits_{j=1}^k \sum\limits_{i=1}^m \frac{w_jp_j(x_i)}{\sum\limits_{s=1}^kw_s p_s(x_i)} = \lambda \sum\limits_{j=1}^kw_j&amp;lt;/tex&amp;gt; &amp;lt;br /&amp;gt;&lt;br /&gt;
А так как &amp;lt;tex&amp;gt;\sum\limits_{j=1}^k \frac{w_jp_j(x_i)}{\sum\limits_{s=1}^kw_sp_s(x_i)} = 1&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;\sum\limits_{j=1}^kw_j = 1&amp;lt;/tex&amp;gt;, из чего следует &amp;lt;tex&amp;gt;\lambda = m&amp;lt;/tex&amp;gt; &amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt;w_j = \frac{1}{m}\sum\limits_{i=1}^m \frac{w_jp_j(x_i)}{\sum\limits_{s=1}^kw_sp_s(x_i)} = \frac{1}{m}\sum\limits_{i=1}^m h_{ij}&amp;lt;/tex&amp;gt;&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Приравняв к нулю производную Лагранжиана по &amp;lt;tex&amp;gt;\theta_j&amp;lt;/tex&amp;gt;, схожим способом найдем:&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt; \theta_j = \arg\max\limits_{\theta}\sum\limits_{i=1}^m h_{ij}*\ln\phi(x_i;\theta).&amp;lt;/tex&amp;gt;&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
=== Критерий остановки === &lt;br /&gt;
&lt;br /&gt;
Алгоритм EM вы полняется до сходимости, но как нам определить, что сходимость наступила? Мы можем останавливаться, когда либо &amp;lt;tex&amp;gt;Q(\Theta)&amp;lt;/tex&amp;gt;, либо &amp;lt;tex&amp;gt;H&amp;lt;/tex&amp;gt; перестают сильно меняться. Но, обычно, удобней контролировать изменения значений скрытых переменных, так как они имеют смысл вероятностей и принимают значения из отрезка &amp;lt;tex&amp;gt;[0,1]&amp;lt;/tex&amp;gt;. Поэтому один из возможных критериев остановки будет выглядеть так: &amp;lt;tex&amp;gt;\max\limits_{i,j} |h_{ij} - h_{ij}^{(0)}| &amp;gt; \delta&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Псевдокод === &lt;br /&gt;
&lt;br /&gt;
 Input:&amp;lt;tex&amp;gt;X^m, k, \Theta^{(0)}&amp;lt;/tex&amp;gt;&lt;br /&gt;
 Repeat&lt;br /&gt;
    '''E-step''': for all i = 1..m; j = 1..k:&lt;br /&gt;
        &amp;lt;tex&amp;gt;h_{ij} = \frac{w_j \phi(x_i; \theta_j)}{\sum\limits_{s=1}^k w_s \phi(x_i; \theta_j)}&amp;lt;/tex&amp;gt;&lt;br /&gt;
    '''M-step''': for all j = 1..k:&lt;br /&gt;
        &amp;lt;tex&amp;gt;\theta_j = \arg\max\limits_{\theta} \sum\limits_{i=1}^m h_{ij}*ln \phi (x_i, \theta)&amp;lt;/tex&amp;gt;&lt;br /&gt;
        &amp;lt;tex&amp;gt;w_j = \frac {1} {m} \sum\limits_{i=1}^m h_{ij}&amp;lt;/tex&amp;gt;&lt;br /&gt;
 Until a stopping criterion is satisfied&lt;br /&gt;
 Return &amp;lt;tex&amp;gt;\Theta = (\theta_j, w_j)_{j=1}^k&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Плюсы и минусы === &lt;br /&gt;
&lt;br /&gt;
Плюсы:&amp;lt;br/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Сходится в большинтсве случаев&lt;br /&gt;
* Наиболее гибкое решение&lt;br /&gt;
* Существуют простые модификации, позволяющие уменьшить чуствительность алгоритма к шуму в данных&lt;br /&gt;
&lt;br /&gt;
Минусы:&amp;lt;br/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Чуствителен к начальному приближению. Могут быть ситуации, когда сойдемся к локальному экстремуму&lt;br /&gt;
* Число компонент &amp;lt;tex&amp;gt;k&amp;lt;/tex&amp;gt; является гиперпараметром.&lt;br /&gt;
&lt;br /&gt;
== Модификации == &lt;br /&gt;
&lt;br /&gt;
Базовый алгоритм EM является очень гибким для модификаций, позволяющих улучшить его работу. В этом разделе мы приведем краткое описаниен некоторых из них.&lt;br /&gt;
&lt;br /&gt;
=== Generalized EM-algorithm === &lt;br /&gt;
&lt;br /&gt;
Осоновная идея этой модификации заключается в том, что на шаге M мы не будем пытаться найти наилучшее решение. Это применимо в случаях, когда максимизация &amp;lt;tex&amp;gt;Q(\Theta)&amp;lt;/tex&amp;gt; является сликшом дорогой, поэтому нам достаточно сделать лишь несколько итераций, для того, чтобы сместиться в сторону максимума значения &amp;lt;tex&amp;gt;Q(\Theta)&amp;lt;/tex&amp;gt;. Эта модификация имеет неплохую сходимость.&lt;br /&gt;
&lt;br /&gt;
=== Stochastic EM-algorithm ===&lt;br /&gt;
&lt;br /&gt;
Как уже было отмечено в [[#Плюсы_и_минусы|Плюсы и минусы]], базовый алгоритм чувствителен к начальному приближению и могут быть ситуации, когда алгоритм &amp;quot;застрянет&amp;quot; в лоакльном экстремуме. Для того, чтобы предотвратить это, будем на каждой итерации алгоритма случайно &amp;quot;встряхивать&amp;quot; выборку. В этой модификации у нас добавляется шаг S, на котором мы и будем &amp;quot;встряхивать&amp;quot; выборку. И на шаге M мы будем решать уже задачу максимуму невзвешенного правдоподобия. Эта модификация хороша тем, что нечуствиетльная к начальном приблежению. &lt;br /&gt;
&lt;br /&gt;
== Пример. Разделение смеси Гауссиана == &lt;br /&gt;
&lt;br /&gt;
[[Файл:Gaussians2.png|right|thumb|400px|Несколько итераций алгоритма]]&lt;br /&gt;
&lt;br /&gt;
Каноническим примером использования EM алгоритма является задача разделения смеси гауссиана. Данные у нас получены из нормального распределения. В этом случае параметрами функций ялвяются матожидание и дисперсия.&amp;lt;br/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt;\theta = (w_1,..,w_k;\;\mu_1,..,\mu_k;\;\sigma_1,..,\sigma_k)&amp;lt;/tex&amp;gt; {{---}} вектор параметров, &amp;lt;br/&amp;gt;&lt;br /&gt;
&amp;lt;tex&amp;gt;p_j(x) = N(x;\mu_j, \sigma_j) = \frac1{\sqrt{2\pi}\sigma_j} \exp \biggl(-\frac{(x - \mu_j)^2}{2\sigma_j^2}\biggr) &amp;lt;/tex&amp;gt; - плотность распределения &amp;lt;br/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Посчитаем значения для каждого шага. &amp;lt;br/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
E-шаг:&lt;br /&gt;
&lt;br /&gt;
: &amp;lt;tex&amp;gt; h_{ij} = \frac{w_j N(x_i, \mu_j, \sigma_j)}{\sum\limits_{s=1}^k w_s N(x_i, \mu_s, \sigma_s)} &amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
M-шаг:&lt;br /&gt;
&lt;br /&gt;
: &amp;lt;tex&amp;gt;w_j = \frac{1}{m} \sum\limits_{i=1}^m h_{ij}&amp;lt;/tex&amp;gt;&lt;br /&gt;
: &amp;lt;tex&amp;gt; \mu_j = \frac {1} {mw_j} \sum\limits_{i=1}^m h_{ij}x_i&amp;lt;/tex&amp;gt;&lt;br /&gt;
: &amp;lt;tex&amp;gt; \sigma_j^2 = \frac {1} {mw_j} \sum\limits_{i=1}^m h_{ij}(x_i - \mu_j)^2, j = 1..k&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Использование в задаче кластеризации ==&lt;br /&gt;
&lt;br /&gt;
[[Файл:kmeans.jpg|right|thumb|200px|Пример работы k-means]]&lt;br /&gt;
&lt;br /&gt;
Как уже упоминалось в [[#Определение|Определении]], алгоритм EM подходит для решения задачи кластеризации. И одной из его имплементаций для этой задачи является алгоритм &amp;lt;tex&amp;gt;k&amp;lt;/tex&amp;gt;-means. В этом алгоритме в качестве скрытых переменных выступают метки классов объектов. Параметрами же являются центроиды искомых классов. Тогда на шаге E мы относим объекты к какому-то одному классу на основе расстояний до центроид. А на шаге M мы пересчитываем центроиды кластеров, исходя из полученной на шаге E разметке.&amp;lt;br/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Также стоит упомянуть алгоритм &amp;lt;tex&amp;gt;c&amp;lt;/tex&amp;gt;-means. В нем качестве скрытых переменных выступают вероятности принадлежности объекта к классам. На шаге E мы пересчитывем вероятности принадлежности объектов, иходя из расстояния до центроид. Шаг M, идейно, остается без изменений.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Реализация на python ==&lt;br /&gt;
&lt;br /&gt;
В пакете sklearn алгоритм EM представлен объектом GaussianMixture. Проиллюстрируем его работу на примере задачи кластеризации и сравним его с алгоритмом &amp;lt;tex&amp;gt;k&amp;lt;/tex&amp;gt;-means:&lt;br /&gt;
 &lt;br /&gt;
 [[Файл:em_clustering.png|thumb|600px|Результат выполнения программы]]&lt;br /&gt;
 '''import''' numpy as np&lt;br /&gt;
 '''import''' matplotlib.pyplot as plt&lt;br /&gt;
 '''from''' sklearn '''import''' cluster, datasets, mixture&lt;br /&gt;
 '''from''' sklearn.preprocessing '''import''' StandardScaler&lt;br /&gt;
 '''from''' itertools '''import''' cycle, islice&lt;br /&gt;
 np.random.seed(12)&lt;br /&gt;
 &lt;br /&gt;
 &amp;lt;font color=&amp;quot;green&amp;quot;&amp;gt;# Создаем datasets с использованием стандартных sklearn.datasets&amp;lt;/font&amp;gt;&lt;br /&gt;
 n_samples = 2000&lt;br /&gt;
 random_state = 170&lt;br /&gt;
 noisy_circles = datasets.make_circles(n_samples=n_samples, factor=.5, noise=.05)&lt;br /&gt;
 noisy_moons = datasets.make_moons(n_samples=n_samples, noise=.05)&lt;br /&gt;
 blobs = datasets.make_blobs(n_samples=n_samples, random_state=8)&lt;br /&gt;
 varied = datasets.make_blobs(n_samples=n_samples, cluster_std=[1.0, 2.5, 0.5], random_state=random_state)&lt;br /&gt;
 &lt;br /&gt;
 &amp;lt;font color=&amp;quot;green&amp;quot;&amp;gt;# Создаем анизатропно разделенные данные&amp;lt;/font&amp;gt;&lt;br /&gt;
 X, y = datasets.make_blobs(n_samples=n_samples, random_state=random_state)&lt;br /&gt;
 transformation = [[0.6, -0.6], [-0.4, 0.8]]&lt;br /&gt;
 X_aniso = np.dot(X, transformation)&lt;br /&gt;
 aniso = (X_aniso, y)&lt;br /&gt;
 &lt;br /&gt;
 &amp;lt;font color=&amp;quot;green&amp;quot;&amp;gt;# Выставляем параметры для matplotlib.pyplot&amp;lt;/font&amp;gt;&lt;br /&gt;
 plt.figure(figsize=(9 * 2 + 3, 12.5))&lt;br /&gt;
 plt.subplots_adjust(left=.02, right=.98, bottom=.001, top=.96, wspace=.05, hspace=.01)&lt;br /&gt;
 plot_num = 1&lt;br /&gt;
 defaul_n = 3&lt;br /&gt;
 &lt;br /&gt;
 &amp;lt;font color=&amp;quot;green&amp;quot;&amp;gt;# Варьируем значение количества классов в зависимости от данных, ведь для нас это гиперпараметр&amp;lt;/font&amp;gt;&lt;br /&gt;
 datasets = [&lt;br /&gt;
    (varied, defaul_n),&lt;br /&gt;
    (aniso, defaul_n),&lt;br /&gt;
    (blobs, defaul_n),&lt;br /&gt;
    (noisy_circles, 2)]&lt;br /&gt;
 for i_dataset, (dataset, n_cluster) in enumerate(datasets):&lt;br /&gt;
    X, y = dataset&lt;br /&gt;
 &lt;br /&gt;
    &amp;lt;font color=&amp;quot;green&amp;quot;&amp;gt;# Нормализация данных&amp;lt;/font&amp;gt;&lt;br /&gt;
    X = StandardScaler().fit_transform(X)&lt;br /&gt;
 &lt;br /&gt;
    &amp;lt;font color=&amp;quot;green&amp;quot;&amp;gt;# Непосредственно наш алгоритм - Gaussian Mixture&amp;lt;/font&amp;gt;&lt;br /&gt;
    gmm = mixture.GaussianMixture(n_components=n_cluster, covariance_type='full')&lt;br /&gt;
    &lt;br /&gt;
    &amp;lt;font color=&amp;quot;green&amp;quot;&amp;gt;# Для сравнения берем алгоритм - k-means&amp;lt;/font&amp;gt;&lt;br /&gt;
    two_means = cluster.KMeans(n_clusters=n_cluster)&lt;br /&gt;
    clustering_algorithms = {&lt;br /&gt;
        'Real distribution': None,&lt;br /&gt;
        'Gaussian Mixture': gmm,&lt;br /&gt;
        'k-Means': two_means&lt;br /&gt;
    }&lt;br /&gt;
    for name, algorithm in clustering_algorithms:&lt;br /&gt;
 &lt;br /&gt;
        # Этап обучения&lt;br /&gt;
        if algorithm is not None:&lt;br /&gt;
            algorithm.fit(X)&lt;br /&gt;
        &lt;br /&gt;
        # Применяем алгоритм&lt;br /&gt;
         y_pred = y if algorithm is None else algorithm.predict(X)&lt;br /&gt;
        &lt;br /&gt;
        # Рисуем результаты&lt;br /&gt;
        plt.subplot(len(datasets), len(clustering_algorithms), plot_num)&lt;br /&gt;
        if i_dataset == 0:&lt;br /&gt;
            plt.title(name, size=18)&lt;br /&gt;
        colors = np.array(list(islice(cycle(['#377eb8', '#ff7f00', '#4daf4a']), int(max(y_pred) + 1))))&lt;br /&gt;
        plt.scatter(X[:, 0], X[:, 1], s=10, color=colors[y_pred])&lt;br /&gt;
        plt.xlim(-2.5, 2.5)&lt;br /&gt;
        plt.ylim(-2.5, 2.5)&lt;br /&gt;
        plt.xticks(())&lt;br /&gt;
        plt.yticks(())&lt;br /&gt;
        plot_num += 1&lt;br /&gt;
 plt.show()&lt;br /&gt;
&lt;br /&gt;
Как и следовало ожидать, алгоритм EM работает на некоторых данных лучше чем k-means, однако есть данные, с которыми он не справляется без дополнительных преобразований.&lt;br /&gt;
&lt;br /&gt;
== См. также ==&lt;br /&gt;
*[[Кластеризация]]&lt;br /&gt;
*[[Алгоритм_k-Means|Алгоритм k-Means]]&lt;br /&gt;
&lt;br /&gt;
== Источники информации ==&lt;br /&gt;
&lt;br /&gt;
# Материалы лекции про кластеризацию курса &amp;quot;Машинное обучение&amp;quot; университета ИТМО, 2019 год&lt;br /&gt;
# [http://www.machinelearning.ru/wiki/images/6/6d/Voron-ML-1.pdf Математические методы обучения по прецедентам К. В. Воронцов]&lt;br /&gt;
# [http://www.machinelearning.ru/wiki/index.php?title=EM-%D0%B0%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC Статья про EM-алгоритм на machinelearning.ru]&lt;br /&gt;
# [https://machinelearningmastery.com/expectation-maximization-em-algorithm/ A Gentle Introduction to Expectation-Maximization]&lt;br /&gt;
# [http://dendroid.sk/2011/05/09/k-means-clustering/ k-means]&lt;br /&gt;
&lt;br /&gt;
[[Категория:Машинное обучение]]&lt;/div&gt;</summary>
		<author><name>94.229.111.244</name></author>	</entry>

	<entry>
		<id>http://neerc.ifmo.ru/wiki/index.php?title=EM-%D0%B0%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC&amp;diff=73021</id>
		<title>EM-алгоритм</title>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=EM-%D0%B0%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC&amp;diff=73021"/>
				<updated>2020-03-21T11:00:55Z</updated>
		
		<summary type="html">&lt;p&gt;94.229.111.244: Добавил точки&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Определение ==&lt;br /&gt;
&lt;br /&gt;
'''Алгоритм EM''' (англ. ''expectation-maximization'') {{---}} итеративный алгоритм поиска оценок максимума правдоподобия модели, в ситуации, когда она зависит от скрытых (ненаблюдаемых) переменных.&lt;br /&gt;
&lt;br /&gt;
Алгоритм ищет параметры модели итеративно, каждая итерация состоит из двух шагов:&lt;br /&gt;
&lt;br /&gt;
'''E (Expectation)''' шаг {{---}} поиск наиболее вероятных значений скрытых переменных.&lt;br /&gt;
&lt;br /&gt;
'''M (Maximization)''' шаг {{---}} поиск наиболее вероятных значений параметров, для полученных на шаге E значений скрытых переменных.&lt;br /&gt;
&lt;br /&gt;
EM алгоритм подходит для решения задач двух типов:&lt;br /&gt;
&lt;br /&gt;
# Задачи с неполными данными.&lt;br /&gt;
# Задачи, в которых удобно вводить скрытые переменные для упрощения подсчета функции правдоподобия. Примером такой задачи может служить кластеризация.&lt;br /&gt;
&lt;br /&gt;
== Основной алгоритм == &lt;br /&gt;
&lt;br /&gt;
=== Постановка задачи ===&lt;br /&gt;
&lt;br /&gt;
Плотность распределения смеси имеет вид:&amp;lt;br/&amp;gt;&lt;br /&gt;
&amp;lt;tex&amp;gt;p(x) = \sum\limits_{j=1}^k w_j p_j(x)&amp;lt;/tex&amp;gt;&amp;lt;br/&amp;gt;&lt;br /&gt;
Где &amp;lt;tex&amp;gt; \sum\limits_{j=1}^k w_j = 1;  w_j \geq 0; p_j(x) = \phi(x;\theta_j)&amp;lt;/tex&amp;gt; {{---}} функция правдоподобия &amp;lt;tex&amp;gt;j&amp;lt;/tex&amp;gt;-ой компонеты смеси, &amp;lt;tex&amp;gt;w_j&amp;lt;/tex&amp;gt; {{---}} априорная вероятность &amp;lt;tex&amp;gt;j&amp;lt;/tex&amp;gt;-ой компоненты смеси.&amp;lt;br/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Перед нами стоит две задачи:&amp;lt;br/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
# По заданной выборке &amp;lt;tex&amp;gt;X^m&amp;lt;/tex&amp;gt; случайных и независимых наблюдений полученных из смеси &amp;lt;tex&amp;gt;p(x)&amp;lt;/tex&amp;gt;, числу &amp;lt;tex&amp;gt;k&amp;lt;/tex&amp;gt; и функции &amp;lt;tex&amp;gt;\phi&amp;lt;/tex&amp;gt;, оценить вектор параметров &amp;lt;tex&amp;gt;\Theta = (w_1,..,w_k,\theta_1,..,\theta_k)&amp;lt;/tex&amp;gt;&lt;br /&gt;
# Найти &amp;lt;tex&amp;gt;k&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Проблема === &lt;br /&gt;
&lt;br /&gt;
Задачи подобного рода мы умеем решать, максимизируя логармиф правдоподобия:&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;tex&amp;gt; L(\Theta) = ln \prod\limits_{i=1}^mp(x_i) = \sum\limits_{i=1}^m ln\sum\limits_{j=1}^k w_j p_j(x_i; \theta_j) \longrightarrow \max\limits_{\Theta}&amp;lt;/tex&amp;gt;&amp;lt;br/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Но пробелма в том, что мы не знаем как аналитически посчитать логарифм суммы. Тут нам и поможет алгоритм EM.&lt;br /&gt;
&lt;br /&gt;
=== Решение === &lt;br /&gt;
&lt;br /&gt;
Основная идея алгоритма EM заключается в том, что мы добавляме скрытые переменные такие, что:&amp;lt;br/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
# Они могут быть выражены через &amp;lt;tex&amp;gt;\Theta&amp;lt;/tex&amp;gt;&lt;br /&gt;
# Они помогают разбить сумму так: &amp;lt;tex&amp;gt;p (X, H|\Theta) = \prod\limits_{i=1}^k p (X|H, \Theta) p(H|\Theta)&amp;lt;/tex&amp;gt;, где &amp;lt;tex&amp;gt;H&amp;lt;/tex&amp;gt; - матрица скрытых переменных.&lt;br /&gt;
&lt;br /&gt;
Тогда алгоритм EM сводится к повторению шагов, указанных в [[#Определение|Определении]].&lt;br /&gt;
&lt;br /&gt;
=== E-шаг === &lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt;p(x,\theta_j) = p(x)P(\theta_j | x) = w_jp_j(x)&amp;lt;/tex&amp;gt; &amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Скрытые переменные представляют из себя матрицу &amp;lt;tex&amp;gt;H = (h_{ij})_{m \times k}&amp;lt;/tex&amp;gt;&amp;lt;br/&amp;gt;&lt;br /&gt;
где &amp;lt;tex&amp;gt;h_{ij} = P(\theta_j | x_i)&amp;lt;/tex&amp;gt; {{---}} вероятность того, что &amp;lt;tex&amp;gt;x_i&amp;lt;/tex&amp;gt; пренадлежит &amp;lt;tex&amp;gt;j&amp;lt;/tex&amp;gt;-ой компоненте.&amp;lt;br/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
По формуле Байеса справедливо равенство:&amp;lt;br /&amp;gt;&lt;br /&gt;
&amp;lt;tex&amp;gt; h_{ij} = \frac{w_jp_j(x_i)}{p (x_i)} = \frac{w_jp_j(x_i)}{\sum\limits_{s=1}^k w_s p_s(x_i)}&amp;lt;/tex&amp;gt;&amp;lt;br/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Также &amp;lt;tex&amp;gt;\sum\limits_{j=1}^k h_{ij} = 1&amp;lt;/tex&amp;gt;&amp;lt;br/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Таким образом, зная значения вектора параметров &amp;lt;tex&amp;gt;\Theta&amp;lt;/tex&amp;gt;, мы легко можем пересчитать значения скрытых переменных&amp;lt;br/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== M-шаг === &lt;br /&gt;
&lt;br /&gt;
{{Теорема&lt;br /&gt;
|statement=&lt;br /&gt;
Если известны скрытые переменные, то задача минимизации &amp;lt;tex&amp;gt;Q(\Theta)&amp;lt;/tex&amp;gt; сводится к &amp;lt;tex&amp;gt;k&amp;lt;/tex&amp;gt; независимым подзадачам:&amp;lt;br/&amp;gt;&lt;br /&gt;
&amp;lt;center&amp;gt;&amp;lt;tex&amp;gt;\theta_j = \arg\max\limits_{\theta}\sum\limits_{i=1}^m h_{ij}*\ln\phi(x_i;\theta)&amp;lt;/tex&amp;gt;&amp;lt;/center&amp;gt;&lt;br /&gt;
Оптимальные же веса считаются как:&amp;lt;br/&amp;gt;&lt;br /&gt;
&amp;lt;center&amp;gt;&amp;lt;tex&amp;gt; w_j = \frac {1} {m} \sum\limits_{i=1}^m h_{ij}&amp;lt;/tex&amp;gt;&amp;lt;/center&amp;gt;&lt;br /&gt;
|proof=&lt;br /&gt;
Посчитаем логарифм правдоподобия:&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;tex&amp;gt; Q(\Theta) = \sum\limits_{i=1}^m ln\sum\limits_{j=1}^k w_j p_j(x_i; \theta_j) \longrightarrow \max\limits_{\Theta}&amp;lt;/tex&amp;gt;&amp;lt;br/&amp;gt;&lt;br /&gt;
При условии, что&amp;lt;tex&amp;gt; \sum\limits_{j=1}^k w_j = 1; w_j \geq 0&amp;lt;/tex&amp;gt; имеет смысл рассматривать Лагранжиан задачи:&amp;lt;br/&amp;gt;&lt;br /&gt;
&amp;lt;tex&amp;gt; L(\Theta, X^m) = \sum\limits_{i=1}^m ln \biggl( \sum\limits_{j=1}^k w_j p_j(x_i) \biggr)  - \lambda \biggl(\sum\limits_{j=1}^k w_j - 1 \biggr) &amp;lt;/tex&amp;gt;&amp;lt;br/&amp;gt;&lt;br /&gt;
Приравняв нулю производную Лагранжиана по &amp;lt;tex&amp;gt;w_j&amp;lt;/tex&amp;gt;, получим:&amp;lt;br/&amp;gt;&lt;br /&gt;
&amp;lt;tex&amp;gt;\frac{\partial L} {\partial w_j} = \sum\limits_{i=1}^m \frac{p_j(x_i)}{\sum\limits_{s=1}^kw_s p_s(x_i)} - \lambda = 0, j = 1..k&amp;lt;/tex&amp;gt;&amp;lt;br /&amp;gt;&lt;br /&gt;
Умножим на &amp;lt;tex&amp;gt;w_j&amp;lt;/tex&amp;gt; и просуммируем уравнения для всех &amp;lt;tex&amp;gt;j&amp;lt;/tex&amp;gt; &amp;lt;br /&amp;gt;&lt;br /&gt;
&amp;lt;tex&amp;gt;\sum\limits_{j=1}^k \sum\limits_{i=1}^m \frac{w_jp_j(x_i)}{\sum\limits_{s=1}^kw_s p_s(x_i)} = \lambda \sum\limits_{j=1}^kw_j&amp;lt;/tex&amp;gt; &amp;lt;br /&amp;gt;&lt;br /&gt;
А так как &amp;lt;tex&amp;gt;\sum\limits_{j=1}^k \frac{w_jp_j(x_i)}{\sum\limits_{s=1}^kw_sp_s(x_i)} = 1&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;\sum\limits_{j=1}^kw_j = 1&amp;lt;/tex&amp;gt;, из чего следует &amp;lt;tex&amp;gt;\lambda = m&amp;lt;/tex&amp;gt; &amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt;w_j = \frac{1}{m}\sum\limits_{i=1}^m \frac{w_jp_j(x_i)}{\sum\limits_{s=1}^kw_sp_s(x_i)} = \frac{1}{m}\sum\limits_{i=1}^m h_{ij}&amp;lt;/tex&amp;gt;&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Приравняв к нулю производную Лагранжиана по &amp;lt;tex&amp;gt;\theta_j&amp;lt;/tex&amp;gt;, схожим способом найдем:&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt; \theta_j = \arg\max\limits_{\theta}\sum\limits_{i=1}^m h_{ij}*\ln\phi(x_i;\theta).&amp;lt;/tex&amp;gt;&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
=== Критерий остановки === &lt;br /&gt;
&lt;br /&gt;
Алгоритм EM вы полняется до сходимости, но как нам определить, что сходимость наступила? Мы можем останавливаться, когда либо &amp;lt;tex&amp;gt;Q(\Theta)&amp;lt;/tex&amp;gt;, либо &amp;lt;tex&amp;gt;H&amp;lt;/tex&amp;gt; перестают сильно меняться. Но, обычно, удобней контролировать изменения значений скрытых переменных, так как они имеют смысл вероятностей и принимают значения из отрезка &amp;lt;tex&amp;gt;[0,1]&amp;lt;/tex&amp;gt;. Поэтому один из возможных критериев остановки будет выглядеть так: &amp;lt;tex&amp;gt;\max\limits_{i,j} |h_{ij} - h_{ij}^{(0)}| &amp;gt; \delta&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Псевдокод === &lt;br /&gt;
&lt;br /&gt;
 Input:&amp;lt;tex&amp;gt;X^m, k, \Theta^{(0)}&amp;lt;/tex&amp;gt;&lt;br /&gt;
 Repeat&lt;br /&gt;
    '''E-step''': for all i = 1..m; j = 1..k:&lt;br /&gt;
        &amp;lt;tex&amp;gt;h_{ij} = \frac{w_j \phi(x_i; \theta_j)}{\sum\limits_{s=1}^k w_s \phi(x_i; \theta_j)}&amp;lt;/tex&amp;gt;&lt;br /&gt;
    '''M-step''': for all j = 1..k:&lt;br /&gt;
        &amp;lt;tex&amp;gt;\theta_j = \arg\max\limits_{\theta} \sum\limits_{i=1}^m h_{ij}*ln \phi (x_i, \theta)&amp;lt;/tex&amp;gt;&lt;br /&gt;
        &amp;lt;tex&amp;gt;w_j = \frac {1} {m} \sum\limits_{i=1}^m h_{ij}&amp;lt;/tex&amp;gt;&lt;br /&gt;
 Until a stopping criterion is satisfied&lt;br /&gt;
 Return &amp;lt;tex&amp;gt;\Theta = (\theta_j, w_j)_{j=1}^k&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Плюсы и минусы === &lt;br /&gt;
&lt;br /&gt;
Плюсы:&amp;lt;br/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Сходится в большинтсве случаев&lt;br /&gt;
* Наиболее гибкое решение&lt;br /&gt;
* Существуют простые модификации, позволяющие уменьшить чуствительность алгоритма к шуму в данных&lt;br /&gt;
&lt;br /&gt;
Минусы:&amp;lt;br/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Чуствителен к начальному приближению. Могут быть ситуации, когда сойдемся к локальному экстремуму&lt;br /&gt;
* Число компонент &amp;lt;tex&amp;gt;k&amp;lt;/tex&amp;gt; является гиперпараметром.&lt;br /&gt;
&lt;br /&gt;
== Модификации == &lt;br /&gt;
&lt;br /&gt;
Базовый алгоритм EM является очень гибким для модификаций, позволяющих улучшить его работу. В этом разделе мы приведем краткое описаниен некоторых из них.&lt;br /&gt;
&lt;br /&gt;
=== Generalized EM-algorithm === &lt;br /&gt;
&lt;br /&gt;
Осоновная идея этой модификации заключается в том, что на шаге M мы не будем пытаться найти наилучшее решение. Это применимо в случаях, когда максимизация &amp;lt;tex&amp;gt;Q(\Theta)&amp;lt;/tex&amp;gt; является сликшом дорогой, поэтому нам достаточно сделать лишь несколько итераций, для того, чтобы сместиться в сторону максимума значения &amp;lt;tex&amp;gt;Q(\Theta)&amp;lt;/tex&amp;gt;. Эта модификация имеет неплохую сходимость.&lt;br /&gt;
&lt;br /&gt;
=== Stochastic EM-algorithm ===&lt;br /&gt;
&lt;br /&gt;
Как уже было отмечено в [[#Плюсы_и_минусы|Плюсы и минусы]], базовый алгоритм чувствителен к начальному приближению и могут быть ситуации, когда алгоритм &amp;quot;застрянет&amp;quot; в лоакльном экстремуме. Для того, чтобы предотвратить это, будем на каждой итерации алгоритма случайно &amp;quot;встряхивать&amp;quot; выборку. В этой модификации у нас добавляется шаг S, на котором мы и будем &amp;quot;встряхивать&amp;quot; выборку. И на шаге M мы будем решать уже задачу максимуму невзвешенного правдоподобия. Эта модификация хороша тем, что нечуствиетльная к начальном приблежению. &lt;br /&gt;
&lt;br /&gt;
== Пример. Разделение смеси Гауссиана == &lt;br /&gt;
&lt;br /&gt;
[[Файл:Gaussians2.png|right|thumb|400px|Несколько итераций алгоритма]]&lt;br /&gt;
&lt;br /&gt;
Каноническим примером использования EM алгоритма является задача разделения смеси гауссиана. Данные у нас получены из нормального распределения. В этом случае параметрами функций ялвяются матожидание и дисперсия.&amp;lt;br/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt;\theta = (w_1,..,w_k;\;\mu_1,..,\mu_k;\;\sigma_1,..,\sigma_k)&amp;lt;/tex&amp;gt; {{---}} вектор параметров, &amp;lt;br/&amp;gt;&lt;br /&gt;
&amp;lt;tex&amp;gt;p_j(x) = N(x;\mu_j, \sigma_j) = \frac1{\sqrt{2\pi}\sigma_j} \exp \biggl(-\frac{(x - \mu_j)^2}{2\sigma_j^2}\biggr) &amp;lt;/tex&amp;gt; - плотность распределения &amp;lt;br/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Посчитаем значения для каждого шага. &amp;lt;br/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
E-шаг:&lt;br /&gt;
&lt;br /&gt;
: &amp;lt;tex&amp;gt; h_{ij} = \frac{w_j N(x_i, \mu_j, \sigma_j)}{\sum\limits_{s=1}^k w_s N(x_i, \mu_s, \sigma_s)} &amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
M-шаг:&lt;br /&gt;
&lt;br /&gt;
: &amp;lt;tex&amp;gt;w_j = \frac{1}{m} \sum\limits_{i=1}^m h_{ij}&amp;lt;/tex&amp;gt;&lt;br /&gt;
: &amp;lt;tex&amp;gt; \mu_j = \frac {1} {mw_j} \sum\limits_{i=1}^m h_{ij}x_i&amp;lt;/tex&amp;gt;&lt;br /&gt;
: &amp;lt;tex&amp;gt; \sigma_j^2 = \frac {1} {mw_j} \sum\limits_{i=1}^m h_{ij}(x_i - \mu_j)^2, j = 1..k&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Использование в задаче кластеризации ==&lt;br /&gt;
&lt;br /&gt;
[[Файл:kmeans.jpg|right|thumb|200px|Пример работы k-means]]&lt;br /&gt;
&lt;br /&gt;
Как уже упоминалось в [[#Определение|Определении]], алгоритм EM подходит для решения задачи кластеризации. И одной из его имплементаций для этой задачи является алгоритм &amp;lt;tex&amp;gt;k&amp;lt;/tex&amp;gt;-means. В этом алгоритме в качестве скрытых переменных выступают метки классов объектов. Параметрами же являются центроиды искомых классов. Тогда на шаге E мы относим объекты к какому-то одному классу на основе расстояний до центроид. А на шаге M мы пересчитываем центроиды кластеров, исходя из полученной на шаге E разметке.&amp;lt;br/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Также стоит упомянуть алгоритм &amp;lt;tex&amp;gt;c&amp;lt;/tex&amp;gt;-means. В нем качестве скрытых переменных выступают вероятности принадлежности объекта к классам. На шаге E мы пересчитывем вероятности принадлежности объектов, иходя из расстояния до центроид. Шаг M, идейно, остается без изменений.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Реализация на python ==&lt;br /&gt;
&lt;br /&gt;
В пакете sklearn алгоритм EM представлен объектом GaussianMixture. Проиллюстрируем его работу на примере задачи кластеризации и сравним его с алгоритмом &amp;lt;tex&amp;gt;k&amp;lt;/tex&amp;gt;-means:&lt;br /&gt;
 &lt;br /&gt;
 [[Файл:em_clustering.png|thumb|600px|Результат выполнения программы]]&lt;br /&gt;
 '''import''' numpy as np&lt;br /&gt;
 '''import''' matplotlib.pyplot as plt&lt;br /&gt;
 '''from''' sklearn '''import''' cluster, datasets, mixture&lt;br /&gt;
 '''from''' sklearn.preprocessing '''import''' StandardScaler&lt;br /&gt;
 '''from''' itertools '''import''' cycle, islice&lt;br /&gt;
 np.random.seed(12)&lt;br /&gt;
 &lt;br /&gt;
 &amp;lt;font color=&amp;quot;green&amp;quot;&amp;gt;# Создаем datasets с использованием стандартных sklearn.datasets&amp;lt;/font&amp;gt;&lt;br /&gt;
 n_samples = 2000&lt;br /&gt;
 random_state = 170&lt;br /&gt;
 noisy_circles = datasets.make_circles(n_samples=n_samples, factor=.5, noise=.05)&lt;br /&gt;
 noisy_moons = datasets.make_moons(n_samples=n_samples, noise=.05)&lt;br /&gt;
 blobs = datasets.make_blobs(n_samples=n_samples, random_state=8)&lt;br /&gt;
 varied = datasets.make_blobs(n_samples=n_samples, cluster_std=[1.0, 2.5, 0.5], random_state=random_state)&lt;br /&gt;
 &lt;br /&gt;
 &amp;lt;font color=&amp;quot;green&amp;quot;&amp;gt;# Создаем анизатропно разделенные данные&amp;lt;/font&amp;gt;&lt;br /&gt;
 X, y = datasets.make_blobs(n_samples=n_samples, random_state=random_state)&lt;br /&gt;
 transformation = [[0.6, -0.6], [-0.4, 0.8]]&lt;br /&gt;
 X_aniso = np.dot(X, transformation)&lt;br /&gt;
 aniso = (X_aniso, y)&lt;br /&gt;
 &lt;br /&gt;
 &amp;lt;font color=&amp;quot;green&amp;quot;&amp;gt;# Выставляем параметры для matplotlib.pyplot&amp;lt;/font&amp;gt;&lt;br /&gt;
 plt.figure(figsize=(9 * 2 + 3, 12.5))&lt;br /&gt;
 plt.subplots_adjust(left=.02, right=.98, bottom=.001, top=.96, wspace=.05, hspace=.01)&lt;br /&gt;
 plot_num = 1&lt;br /&gt;
 defaul_n = 3&lt;br /&gt;
 &lt;br /&gt;
 &amp;lt;font color=&amp;quot;green&amp;quot;&amp;gt;# Варьируем значение количества классов в зависимости от данных, ведь для нас это гиперпараметр&amp;lt;/font&amp;gt;&lt;br /&gt;
 datasets = [&lt;br /&gt;
    (varied, defaul_n),&lt;br /&gt;
    (aniso, defaul_n),&lt;br /&gt;
    (blobs, defaul_n),&lt;br /&gt;
    (noisy_circles, 2)]&lt;br /&gt;
 for i_dataset, (dataset, n_cluster) in enumerate(datasets):&lt;br /&gt;
    X, y = dataset&lt;br /&gt;
 &lt;br /&gt;
    &amp;lt;font color=&amp;quot;green&amp;quot;&amp;gt;# Нормализация данных&amp;lt;/font&amp;gt;&lt;br /&gt;
    X = StandardScaler().fit_transform(X)&lt;br /&gt;
 &lt;br /&gt;
    &amp;lt;font color=&amp;quot;green&amp;quot;&amp;gt;# Непосредственно наш алгоритм - Gaussian Mixture&amp;lt;/font&amp;gt;&lt;br /&gt;
    gmm = mixture.GaussianMixture(n_components=n_cluster, covariance_type='full')&lt;br /&gt;
    &lt;br /&gt;
    &amp;lt;font color=&amp;quot;green&amp;quot;&amp;gt;# Для сравнения берем алгоритм - k-means&amp;lt;/font&amp;gt;&lt;br /&gt;
    two_means = cluster.KMeans(n_clusters=n_cluster)&lt;br /&gt;
    clustering_algorithms = {&lt;br /&gt;
        'Real distribution': None,&lt;br /&gt;
        'Gaussian Mixture': gmm,&lt;br /&gt;
        'k-Means': two_means&lt;br /&gt;
    }&lt;br /&gt;
    for name, algorithm in clustering_algorithms:&lt;br /&gt;
 &lt;br /&gt;
        # Этап обучения&lt;br /&gt;
        if algorithm is not None:&lt;br /&gt;
            algorithm.fit(X)&lt;br /&gt;
        &lt;br /&gt;
        # Применяем алгоритм&lt;br /&gt;
         y_pred = y if algorithm is None else algorithm.predict(X)&lt;br /&gt;
        &lt;br /&gt;
        # Рисуем результаты&lt;br /&gt;
        plt.subplot(len(datasets), len(clustering_algorithms), plot_num)&lt;br /&gt;
        if i_dataset == 0:&lt;br /&gt;
            plt.title(name, size=18)&lt;br /&gt;
        colors = np.array(list(islice(cycle(['#377eb8', '#ff7f00', '#4daf4a']), int(max(y_pred) + 1))))&lt;br /&gt;
        plt.scatter(X[:, 0], X[:, 1], s=10, color=colors[y_pred])&lt;br /&gt;
        plt.xlim(-2.5, 2.5)&lt;br /&gt;
        plt.ylim(-2.5, 2.5)&lt;br /&gt;
        plt.xticks(())&lt;br /&gt;
        plt.yticks(())&lt;br /&gt;
        plot_num += 1&lt;br /&gt;
 plt.show()&lt;br /&gt;
&lt;br /&gt;
Как и следовало ожидать, алгоритм EM работает на некоторых данных лучше чем k-means, однако есть данные, с которыми он не справляется без дополнительных преобразований.&lt;br /&gt;
&lt;br /&gt;
== См. также ==&lt;br /&gt;
*[[Кластеризация]]&lt;br /&gt;
*[[Алгоритм_k-Means|Алгоритм k-Means]]&lt;br /&gt;
&lt;br /&gt;
== Источники информации ==&lt;br /&gt;
&lt;br /&gt;
# Материалы лекции про кластеризацию курса &amp;quot;Машинное обучение&amp;quot; университета ИТМО, 2019 год&lt;br /&gt;
# [http://www.machinelearning.ru/wiki/images/6/6d/Voron-ML-1.pdf Математические методы обучения по прецедентам К. В. Воронцов]&lt;br /&gt;
# [http://www.machinelearning.ru/wiki/index.php?title=EM-%D0%B0%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC Статья про EM-алгоритм на machinelearning.ru]&lt;br /&gt;
# [https://machinelearningmastery.com/expectation-maximization-em-algorithm/ A Gentle Introduction to Expectation-Maximization]&lt;br /&gt;
# [http://dendroid.sk/2011/05/09/k-means-clustering/ k-means]&lt;br /&gt;
&lt;br /&gt;
[[Категория:Машинное обучение]]&lt;/div&gt;</summary>
		<author><name>94.229.111.244</name></author>	</entry>

	<entry>
		<id>http://neerc.ifmo.ru/wiki/index.php?title=EM-%D0%B0%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC&amp;diff=73014</id>
		<title>EM-алгоритм</title>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=EM-%D0%B0%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC&amp;diff=73014"/>
				<updated>2020-03-20T20:45:47Z</updated>
		
		<summary type="html">&lt;p&gt;94.229.111.244: Поправил нерабочую ссылку на Определение&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Определение ==&lt;br /&gt;
&lt;br /&gt;
'''Алгоритм EM''' (англ. ''expectation-maximization'') {{---}} итеративный алгоритм поиска оценок максимума правдоподобия модели, в ситуации, когда она зависит от скрытых (ненаблюдаемых) переменных.&lt;br /&gt;
&lt;br /&gt;
Алгоритм ищет параметры модели итеративно, каждая итерация состоит из двух шагов:&lt;br /&gt;
&lt;br /&gt;
'''E (Expectation)''' шаг {{---}} поиск наиболее вероятных значений скрытых переменных.&lt;br /&gt;
&lt;br /&gt;
'''M (Maximization)''' шаг {{---}} поиск наиболее вероятных значений параметров, для полученных на шаге E значений скрытых переменных.&lt;br /&gt;
&lt;br /&gt;
EM алгоритм подходит для решения задач двух типов:&lt;br /&gt;
&lt;br /&gt;
# Задачи с неполными данными.&lt;br /&gt;
# Задачи, в которых удобно вводить скрытые переменные для упрощения подсчета функции правдоподобия. Примером такой задачи может служить кластеризация&lt;br /&gt;
&lt;br /&gt;
== Основной алгоритм == &lt;br /&gt;
&lt;br /&gt;
=== Постановка задачи ===&lt;br /&gt;
&lt;br /&gt;
Плотность распределения смеси имеет вид:&amp;lt;br/&amp;gt;&lt;br /&gt;
&amp;lt;tex&amp;gt;p(x) = \sum\limits_{j=1}^k w_j p_j(x)&amp;lt;/tex&amp;gt;&amp;lt;br/&amp;gt;&lt;br /&gt;
Где &amp;lt;tex&amp;gt; \sum\limits_{j=1}^k w_j = 1;  w_j \geq 0; p_j(x) = \phi(x;\theta_j)&amp;lt;/tex&amp;gt; {{---}} функция правдоподобия &amp;lt;tex&amp;gt;j&amp;lt;/tex&amp;gt;-ой компонеты смеси, &amp;lt;tex&amp;gt;w_j&amp;lt;/tex&amp;gt; {{---}} априорная вероятность &amp;lt;tex&amp;gt;j&amp;lt;/tex&amp;gt;-ой компоненты смеси.&amp;lt;br/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Перед нами стоит две задачи:&amp;lt;br/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
# По заданной выборке &amp;lt;tex&amp;gt;X^m&amp;lt;/tex&amp;gt; случайных и независимых наблюдений полученных из смеси &amp;lt;tex&amp;gt;p(x)&amp;lt;/tex&amp;gt;, числу &amp;lt;tex&amp;gt;k&amp;lt;/tex&amp;gt; и функции &amp;lt;tex&amp;gt;\phi&amp;lt;/tex&amp;gt;, оценить вектор параметров &amp;lt;tex&amp;gt;\Theta = (w_1,..,w_k,\theta_1,..,\theta_k)&amp;lt;/tex&amp;gt;&lt;br /&gt;
# Найти &amp;lt;tex&amp;gt;k&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Проблема === &lt;br /&gt;
&lt;br /&gt;
Задачи подобного рода мы умеем решать, максимизируя логармиф правдоподобия:&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;tex&amp;gt; L(\Theta) = ln \prod\limits_{i=1}^mp(x_i) = \sum\limits_{i=1}^m ln\sum\limits_{j=1}^k w_j p_j(x_i; \theta_j) \longrightarrow \max\limits_{\Theta}&amp;lt;/tex&amp;gt;&amp;lt;br/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Но пробелма в том, что мы не знаем как аналитически посчитать логарифм суммы. Тут нам и поможет алгоритм EM.&lt;br /&gt;
&lt;br /&gt;
=== Решение === &lt;br /&gt;
&lt;br /&gt;
Основная идея алгоритма EM заключается в том, что мы добавляме скрытые переменные такие, что:&amp;lt;br/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
# Они могут быть выражены через &amp;lt;tex&amp;gt;\Theta&amp;lt;/tex&amp;gt;&lt;br /&gt;
# Они помогают разбить сумму так: &amp;lt;tex&amp;gt;p (X, H|\Theta) = \prod\limits_{i=1}^k p (X|H, \Theta) p(H|\Theta)&amp;lt;/tex&amp;gt;, где &amp;lt;tex&amp;gt;H&amp;lt;/tex&amp;gt; - матрица скрытых переменных.&lt;br /&gt;
&lt;br /&gt;
Тогда алгоритм EM сводится к повторению шагов, указанных в [[#Определение|Определении]].&lt;br /&gt;
&lt;br /&gt;
=== E-шаг === &lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt;p(x,\theta_j) = p(x)P(\theta_j | x) = w_jp_j(x)&amp;lt;/tex&amp;gt; &amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Скрытые переменные представляют из себя матрицу &amp;lt;tex&amp;gt;H = (h_{ij})_{m \times k}&amp;lt;/tex&amp;gt;&amp;lt;br/&amp;gt;&lt;br /&gt;
где &amp;lt;tex&amp;gt;h_{ij} = P(\theta_j | x_i)&amp;lt;/tex&amp;gt; {{---}} вероятность того, что &amp;lt;tex&amp;gt;x_i&amp;lt;/tex&amp;gt; пренадлежит &amp;lt;tex&amp;gt;j&amp;lt;/tex&amp;gt;-ой компоненте.&amp;lt;br/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
По формуле Байеса справедливо равенство:&amp;lt;br /&amp;gt;&lt;br /&gt;
&amp;lt;tex&amp;gt; h_{ij} = \frac{w_jp_j(x_i)}{p (x_i)} = \frac{w_jp_j(x_i)}{\sum\limits_{s=1}^k w_s p_s(x_i)}&amp;lt;/tex&amp;gt;&amp;lt;br/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Также &amp;lt;tex&amp;gt;\sum\limits_{j=1}^k h_{ij} = 1&amp;lt;/tex&amp;gt;&amp;lt;br/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Таким образом, зная значения вектора параметров &amp;lt;tex&amp;gt;\Theta&amp;lt;/tex&amp;gt;, мы легко можем пересчитать значения скрытых переменных&amp;lt;br/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== M-шаг === &lt;br /&gt;
&lt;br /&gt;
{{Теорема&lt;br /&gt;
|statement=&lt;br /&gt;
Если известны скрытые переменные, то задача минимизации &amp;lt;tex&amp;gt;Q(\Theta)&amp;lt;/tex&amp;gt; сводится к &amp;lt;tex&amp;gt;k&amp;lt;/tex&amp;gt; независимым подзадачам:&amp;lt;br/&amp;gt;&lt;br /&gt;
&amp;lt;center&amp;gt;&amp;lt;tex&amp;gt;\theta_j = \arg\max\limits_{\theta}\sum\limits_{i=1}^m h_{ij}*\ln\phi(x_i;\theta)&amp;lt;/tex&amp;gt;&amp;lt;/center&amp;gt;&lt;br /&gt;
Оптимальные же веса считаются как:&amp;lt;br/&amp;gt;&lt;br /&gt;
&amp;lt;center&amp;gt;&amp;lt;tex&amp;gt; w_j = \frac {1} {m} \sum\limits_{i=1}^m h_{ij}&amp;lt;/tex&amp;gt;&amp;lt;/center&amp;gt;&lt;br /&gt;
|proof=&lt;br /&gt;
Посчитаем логарифм правдоподобия:&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;tex&amp;gt; Q(\Theta) = \sum\limits_{i=1}^m ln\sum\limits_{j=1}^k w_j p_j(x_i; \theta_j) \longrightarrow \max\limits_{\Theta}&amp;lt;/tex&amp;gt;&amp;lt;br/&amp;gt;&lt;br /&gt;
При условии, что&amp;lt;tex&amp;gt; \sum\limits_{j=1}^k w_j = 1; w_j \geq 0&amp;lt;/tex&amp;gt; имеет смысл рассматривать Лагранжиан задачи:&amp;lt;br/&amp;gt;&lt;br /&gt;
&amp;lt;tex&amp;gt; L(\Theta, X^m) = \sum\limits_{i=1}^m ln \biggl( \sum\limits_{j=1}^k w_j p_j(x_i) \biggr)  - \lambda \biggl(\sum\limits_{j=1}^k w_j - 1 \biggr) &amp;lt;/tex&amp;gt;&amp;lt;br/&amp;gt;&lt;br /&gt;
Приравняв нулю производную Лагранжиана по &amp;lt;tex&amp;gt;w_j&amp;lt;/tex&amp;gt;, получим:&amp;lt;br/&amp;gt;&lt;br /&gt;
&amp;lt;tex&amp;gt;\frac{\partial L} {\partial w_j} = \sum\limits_{i=1}^m \frac{p_j(x_i)}{\sum\limits_{s=1}^kw_s p_s(x_i)} - \lambda = 0, j = 1..k&amp;lt;/tex&amp;gt;&amp;lt;br /&amp;gt;&lt;br /&gt;
Умножим на &amp;lt;tex&amp;gt;w_j&amp;lt;/tex&amp;gt; и просуммируем уравнения для всех &amp;lt;tex&amp;gt;j&amp;lt;/tex&amp;gt; &amp;lt;br /&amp;gt;&lt;br /&gt;
&amp;lt;tex&amp;gt;\sum\limits_{j=1}^k \sum\limits_{i=1}^m \frac{w_jp_j(x_i)}{\sum\limits_{s=1}^kw_s p_s(x_i)} = \lambda \sum\limits_{j=1}^kw_j&amp;lt;/tex&amp;gt; &amp;lt;br /&amp;gt;&lt;br /&gt;
А так как &amp;lt;tex&amp;gt;\sum\limits_{j=1}^k \frac{w_jp_j(x_i)}{\sum\limits_{s=1}^kw_sp_s(x_i)} = 1&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;\sum\limits_{j=1}^kw_j = 1&amp;lt;/tex&amp;gt;, из чего следует &amp;lt;tex&amp;gt;\lambda = m&amp;lt;/tex&amp;gt; &amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt;w_j = \frac{1}{m}\sum\limits_{i=1}^m \frac{w_jp_j(x_i)}{\sum\limits_{s=1}^kw_sp_s(x_i)} = \frac{1}{m}\sum\limits_{i=1}^m h_{ij}&amp;lt;/tex&amp;gt;&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Приравняв к нулю производную Лагранжиана по &amp;lt;tex&amp;gt;\theta_j&amp;lt;/tex&amp;gt;, схожим способом найдем:&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt; \theta_j = \arg\max\limits_{\theta}\sum\limits_{i=1}^m h_{ij}*\ln\phi(x_i;\theta).&amp;lt;/tex&amp;gt;&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
=== Критерий остановки === &lt;br /&gt;
&lt;br /&gt;
Алгоритм EM вы полняется до сходимости, но как нам определить, что сходимость наступила? Мы можем останавливаться, когда либо &amp;lt;tex&amp;gt;Q(\Theta)&amp;lt;/tex&amp;gt;, либо &amp;lt;tex&amp;gt;H&amp;lt;/tex&amp;gt; перестают сильно меняться. Но, обычно, удобней контролировать изменения значений скрытых переменных, так как они имеют смысл вероятностей и принимают значения из отрезка &amp;lt;tex&amp;gt;[0,1]&amp;lt;/tex&amp;gt;. Поэтому один из возможных критериев остановки будет выглядеть так: &amp;lt;tex&amp;gt;\max\limits_{i,j} |h_{ij} - h_{ij}^{(0)}| &amp;gt; \delta&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Псевдокод === &lt;br /&gt;
&lt;br /&gt;
 Input:&amp;lt;tex&amp;gt;X^m, k, \Theta^{(0)}&amp;lt;/tex&amp;gt;&lt;br /&gt;
 Repeat&lt;br /&gt;
    '''E-step''': for all i = 1..m; j = 1..k:&lt;br /&gt;
        &amp;lt;tex&amp;gt;h_{ij} = \frac{w_j \phi(x_i; \theta_j)}{\sum\limits_{s=1}^k w_s \phi(x_i; \theta_j)}&amp;lt;/tex&amp;gt;&lt;br /&gt;
    '''M-step''': for all j = 1..k:&lt;br /&gt;
        &amp;lt;tex&amp;gt;\theta_j = \arg\max\limits_{\theta} \sum\limits_{i=1}^m h_{ij}*ln \phi (x_i, \theta)&amp;lt;/tex&amp;gt;&lt;br /&gt;
        &amp;lt;tex&amp;gt;w_j = \frac {1} {m} \sum\limits_{i=1}^m h_{ij}&amp;lt;/tex&amp;gt;&lt;br /&gt;
 Until a stopping criterion is satisfied&lt;br /&gt;
 Return &amp;lt;tex&amp;gt;\Theta = (\theta_j, w_j)_{j=1}^k&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Плюсы и минусы === &lt;br /&gt;
&lt;br /&gt;
Плюсы:&amp;lt;br/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Сходится в большинтсве случаев&lt;br /&gt;
* Наиболее гибкое решение&lt;br /&gt;
* Существуют простые модификации, позволяющие уменьшить чуствительность алгоритма к шуму в данных&lt;br /&gt;
&lt;br /&gt;
Минусы:&amp;lt;br/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Чуствителен к начальному приближению. Могут быть ситуации, когда сойдемся к локальному экстремуму&lt;br /&gt;
* Число компонент &amp;lt;tex&amp;gt;k&amp;lt;/tex&amp;gt; является гиперпараметром.&lt;br /&gt;
&lt;br /&gt;
== Модификации == &lt;br /&gt;
&lt;br /&gt;
Базовый алгоритм EM является очень гибким для модификаций, позволяющих улучшить его работу. В этом разделе мы приведем краткое описаниен некоторых из них.&lt;br /&gt;
&lt;br /&gt;
=== Generalized EM-algorithm === &lt;br /&gt;
&lt;br /&gt;
Осоновная идея этой модификации заключается в том, что на шаге M мы не будем пытаться найти наилучшее решение. Это применимо в случаях, когда максимизация &amp;lt;tex&amp;gt;Q(\Theta)&amp;lt;/tex&amp;gt; является сликшом дорогой, поэтому нам достаточно сделать лишь несколько итераций, для того, чтобы сместиться в сторону максимума значения &amp;lt;tex&amp;gt;Q(\Theta)&amp;lt;/tex&amp;gt;. Эта модификация имеет неплохую сходимость.&lt;br /&gt;
&lt;br /&gt;
=== Stochastic EM-algorithm ===&lt;br /&gt;
&lt;br /&gt;
Как уже было отмечено в [[#Плюсы_и_минусы|Плюсы и минусы]], базовый алгоритм чувствителен к начальному приближению и могут быть ситуации, когда алгоритм &amp;quot;застрянет&amp;quot; в лоакльном экстремуме. Для того, чтобы предотвратить это, будем на каждой итерации алгоритма случайно &amp;quot;встряхивать&amp;quot; выборку. В этой модификации у нас добавляется шаг S, на котором мы и будем &amp;quot;встряхивать&amp;quot; выборку. И на шаге M мы будем решать уже задачу максимуму невзвешенного правдоподобия. Эта модификация хороша тем, что нечуствиетльная к начальном приблежению. &lt;br /&gt;
&lt;br /&gt;
== Пример. Разделение смеси Гауссиана == &lt;br /&gt;
&lt;br /&gt;
[[Файл:Gaussians2.png|right|thumb|400px|Несколько итераций алгоритма]]&lt;br /&gt;
&lt;br /&gt;
Каноническим примером использования EM алгоритма является задача разделения смеси гауссиана. Данные у нас получены из нормального распределения. В этом случае параметрами функций ялвяются матожидание и дисперсия.&amp;lt;br/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt;\theta = (w_1,..,w_k;\;\mu_1,..,\mu_k;\;\sigma_1,..,\sigma_k)&amp;lt;/tex&amp;gt; {{---}} вектор параметров, &amp;lt;br/&amp;gt;&lt;br /&gt;
&amp;lt;tex&amp;gt;p_j(x) = N(x;\mu_j, \sigma_j) = \frac1{\sqrt{2\pi}\sigma_j} \exp \biggl(-\frac{(x - \mu_j)^2}{2\sigma_j^2}\biggr) &amp;lt;/tex&amp;gt; - плотность распределения &amp;lt;br/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Посчитаем значения для каждого шага. &amp;lt;br/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
E-шаг:&lt;br /&gt;
&lt;br /&gt;
: &amp;lt;tex&amp;gt; h_{ij} = \frac{w_j N(x_i, \mu_j, \sigma_j)}{\sum\limits_{s=1}^k w_s N(x_i, \mu_s, \sigma_s)} &amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
M-шаг:&lt;br /&gt;
&lt;br /&gt;
: &amp;lt;tex&amp;gt;w_j = \frac{1}{m} \sum\limits_{i=1}^m h_{ij}&amp;lt;/tex&amp;gt;&lt;br /&gt;
: &amp;lt;tex&amp;gt; \mu_j = \frac {1} {mw_j} \sum\limits_{i=1}^m h_{ij}x_i&amp;lt;/tex&amp;gt;&lt;br /&gt;
: &amp;lt;tex&amp;gt; \sigma_j^2 = \frac {1} {mw_j} \sum\limits_{i=1}^m h_{ij}(x_i - \mu_j)^2, j = 1..k&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Использование в задаче кластеризации ==&lt;br /&gt;
&lt;br /&gt;
[[Файл:kmeans.jpg|right|thumb|200px|Пример работы k-means]]&lt;br /&gt;
&lt;br /&gt;
Как уже упоминалось в [[#Определение|Определении]], алгоритм EM подходит для решения задачи кластеризации. И одной из его имплементаций для этой задачи является алгоритм &amp;lt;tex&amp;gt;k&amp;lt;/tex&amp;gt;-means. В этом алгоритме в качестве скрытых переменных выступают метки классов объектов. Параметрами же являются центроиды искомых классов. Тогда на шаге E мы относим объекты к какому-то одному классу на основе расстояний до центроид. А на шаге M мы пересчитываем центроиды кластеров, исходя из полученной на шаге E разметке.&amp;lt;br/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Также стоит упомянуть алгоритм &amp;lt;tex&amp;gt;c&amp;lt;/tex&amp;gt;-means. В нем качестве скрытых переменных выступают вероятности принадлежности объекта к классам. На шаге E мы пересчитывем вероятности принадлежности объектов, иходя из расстояния до центроид. Шаг M, идейно, остается без изменений.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Реализация на python ==&lt;br /&gt;
&lt;br /&gt;
В пакете sklearn алгоритм EM представлен объектом GaussianMixture. Проиллюстрируем его работу на примере задачи кластеризации и сравним его с алгоритмом &amp;lt;tex&amp;gt;k&amp;lt;/tex&amp;gt;-means:&lt;br /&gt;
 &lt;br /&gt;
 [[Файл:em_clustering.png|thumb|600px|Результат выполнения программы]]&lt;br /&gt;
 '''import''' numpy as np&lt;br /&gt;
 '''import''' matplotlib.pyplot as plt&lt;br /&gt;
 '''from''' sklearn '''import''' cluster, datasets, mixture&lt;br /&gt;
 '''from''' sklearn.preprocessing '''import''' StandardScaler&lt;br /&gt;
 '''from''' itertools '''import''' cycle, islice&lt;br /&gt;
 np.random.seed(12)&lt;br /&gt;
 &lt;br /&gt;
 &amp;lt;font color=&amp;quot;green&amp;quot;&amp;gt;# Создаем datasets с использованием стандартных sklearn.datasets&amp;lt;/font&amp;gt;&lt;br /&gt;
 n_samples = 2000&lt;br /&gt;
 random_state = 170&lt;br /&gt;
 noisy_circles = datasets.make_circles(n_samples=n_samples, factor=.5, noise=.05)&lt;br /&gt;
 noisy_moons = datasets.make_moons(n_samples=n_samples, noise=.05)&lt;br /&gt;
 blobs = datasets.make_blobs(n_samples=n_samples, random_state=8)&lt;br /&gt;
 varied = datasets.make_blobs(n_samples=n_samples, cluster_std=[1.0, 2.5, 0.5], random_state=random_state)&lt;br /&gt;
 &lt;br /&gt;
 &amp;lt;font color=&amp;quot;green&amp;quot;&amp;gt;# Создаем анизатропно разделенные данные&amp;lt;/font&amp;gt;&lt;br /&gt;
 X, y = datasets.make_blobs(n_samples=n_samples, random_state=random_state)&lt;br /&gt;
 transformation = [[0.6, -0.6], [-0.4, 0.8]]&lt;br /&gt;
 X_aniso = np.dot(X, transformation)&lt;br /&gt;
 aniso = (X_aniso, y)&lt;br /&gt;
 &lt;br /&gt;
 &amp;lt;font color=&amp;quot;green&amp;quot;&amp;gt;# Выставляем параметры для matplotlib.pyplot&amp;lt;/font&amp;gt;&lt;br /&gt;
 plt.figure(figsize=(9 * 2 + 3, 12.5))&lt;br /&gt;
 plt.subplots_adjust(left=.02, right=.98, bottom=.001, top=.96, wspace=.05, hspace=.01)&lt;br /&gt;
 plot_num = 1&lt;br /&gt;
 defaul_n = 3&lt;br /&gt;
 &lt;br /&gt;
 &amp;lt;font color=&amp;quot;green&amp;quot;&amp;gt;# Варьируем значение количества классов в зависимости от данных, ведь для нас это гиперпараметр&amp;lt;/font&amp;gt;&lt;br /&gt;
 datasets = [&lt;br /&gt;
    (varied, defaul_n),&lt;br /&gt;
    (aniso, defaul_n),&lt;br /&gt;
    (blobs, defaul_n),&lt;br /&gt;
    (noisy_circles, 2)]&lt;br /&gt;
 for i_dataset, (dataset, n_cluster) in enumerate(datasets):&lt;br /&gt;
    X, y = dataset&lt;br /&gt;
 &lt;br /&gt;
    &amp;lt;font color=&amp;quot;green&amp;quot;&amp;gt;# Нормализация данных&amp;lt;/font&amp;gt;&lt;br /&gt;
    X = StandardScaler().fit_transform(X)&lt;br /&gt;
 &lt;br /&gt;
    &amp;lt;font color=&amp;quot;green&amp;quot;&amp;gt;# Непосредственно наш алгоритм - Gaussian Mixture&amp;lt;/font&amp;gt;&lt;br /&gt;
    gmm = mixture.GaussianMixture(n_components=n_cluster, covariance_type='full')&lt;br /&gt;
    &lt;br /&gt;
    &amp;lt;font color=&amp;quot;green&amp;quot;&amp;gt;# Для сравнения берем алгоритм - k-means&amp;lt;/font&amp;gt;&lt;br /&gt;
    two_means = cluster.KMeans(n_clusters=n_cluster)&lt;br /&gt;
    clustering_algorithms = {&lt;br /&gt;
        'Real distribution': None,&lt;br /&gt;
        'Gaussian Mixture': gmm,&lt;br /&gt;
        'k-Means': two_means&lt;br /&gt;
    }&lt;br /&gt;
    for name, algorithm in clustering_algorithms:&lt;br /&gt;
 &lt;br /&gt;
        # Этап обучения&lt;br /&gt;
        if algorithm is not None:&lt;br /&gt;
            algorithm.fit(X)&lt;br /&gt;
        &lt;br /&gt;
        # Применяем алгоритм&lt;br /&gt;
         y_pred = y if algorithm is None else algorithm.predict(X)&lt;br /&gt;
        &lt;br /&gt;
        # Рисуем результаты&lt;br /&gt;
        plt.subplot(len(datasets), len(clustering_algorithms), plot_num)&lt;br /&gt;
        if i_dataset == 0:&lt;br /&gt;
            plt.title(name, size=18)&lt;br /&gt;
        colors = np.array(list(islice(cycle(['#377eb8', '#ff7f00', '#4daf4a']), int(max(y_pred) + 1))))&lt;br /&gt;
        plt.scatter(X[:, 0], X[:, 1], s=10, color=colors[y_pred])&lt;br /&gt;
        plt.xlim(-2.5, 2.5)&lt;br /&gt;
        plt.ylim(-2.5, 2.5)&lt;br /&gt;
        plt.xticks(())&lt;br /&gt;
        plt.yticks(())&lt;br /&gt;
        plot_num += 1&lt;br /&gt;
 plt.show()&lt;br /&gt;
&lt;br /&gt;
Как и следовало ожидать, алгоритм EM работает на некоторых данных лучше чем k-means, однако есть данные, с которыми он не справляется без дополнительных преобразований.&lt;br /&gt;
&lt;br /&gt;
== См. также ==&lt;br /&gt;
*[[Кластеризация]]&lt;br /&gt;
*[[Алгоритм_k-Means|Алгоритм k-Means]]&lt;br /&gt;
&lt;br /&gt;
== Источники информации ==&lt;br /&gt;
&lt;br /&gt;
# Материалы лекции про кластеризацию курса &amp;quot;Машинное обучение&amp;quot; университета ИТМО, 2019 год&lt;br /&gt;
# [http://www.machinelearning.ru/wiki/images/6/6d/Voron-ML-1.pdf Математические методы обучения по прецедентам К. В. Воронцов]&lt;br /&gt;
# [http://www.machinelearning.ru/wiki/index.php?title=EM-%D0%B0%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC Статья про EM-алгоритм на machinelearning.ru]&lt;br /&gt;
# [https://machinelearningmastery.com/expectation-maximization-em-algorithm/ A Gentle Introduction to Expectation-Maximization]&lt;br /&gt;
# [http://dendroid.sk/2011/05/09/k-means-clustering/ k-means]&lt;br /&gt;
&lt;br /&gt;
[[Категория:Машинное обучение]]&lt;/div&gt;</summary>
		<author><name>94.229.111.244</name></author>	</entry>

	<entry>
		<id>http://neerc.ifmo.ru/wiki/index.php?title=EM-%D0%B0%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC&amp;diff=72938</id>
		<title>EM-алгоритм</title>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=EM-%D0%B0%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC&amp;diff=72938"/>
				<updated>2020-03-19T19:10:53Z</updated>
		
		<summary type="html">&lt;p&gt;94.229.111.244: Поправил кучу мелких багов&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Определение ==&lt;br /&gt;
&lt;br /&gt;
'''Алгоритм EM''' (англ. ''expectation-maximization'') {{---}} итеративный алгоритм поиска оценок максимума правдоподобия модели, в ситуации, когда она зависит от скрытых (ненаблюдаемых) переменных.&lt;br /&gt;
&lt;br /&gt;
Алгоритм ищет параметры модели итеративно, каждая итерация состоит из двух шагов:&lt;br /&gt;
&lt;br /&gt;
'''E (Expectation)''' шаг {{---}} поиск наиболее вероятных значений скрытых переменных.&lt;br /&gt;
&lt;br /&gt;
'''M (Maximization)''' шаг {{---}} поиск наиболее вероятных значений параметров, для полученных на шаге E значений скрытых переменных.&lt;br /&gt;
&lt;br /&gt;
EM алгоритм подходит для решения задач двух типов:&lt;br /&gt;
&lt;br /&gt;
# Задачи с неполными данными.&lt;br /&gt;
# Задачи, в которых удобно вводить скрытые переменные для упрощения подсчета функции правдоподобия. Примером такой задачи может служить кластеризация&lt;br /&gt;
&lt;br /&gt;
== Основной алгоритм == &lt;br /&gt;
&lt;br /&gt;
=== Постановка задачи ===&lt;br /&gt;
&lt;br /&gt;
Плотность распределения смеси имеет вид:&amp;lt;br/&amp;gt;&lt;br /&gt;
&amp;lt;tex&amp;gt;p(x) = \sum\limits_{j=1}^k w_j p_j(x)&amp;lt;/tex&amp;gt;&amp;lt;br/&amp;gt;&lt;br /&gt;
Где &amp;lt;tex&amp;gt; \sum\limits_{j=1}^k w_j = 1;  w_j \geq 0; p_j(x) = \phi(x;\theta_j)&amp;lt;/tex&amp;gt; {{---}} функция правдоподобия &amp;lt;tex&amp;gt;j&amp;lt;/tex&amp;gt;-ой компонеты смеси, &amp;lt;tex&amp;gt;w_j&amp;lt;/tex&amp;gt; {{---}} априорная вероятность &amp;lt;tex&amp;gt;j&amp;lt;/tex&amp;gt;-ой компоненты смеси.&amp;lt;br/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Перед нами стоит две задачи:&amp;lt;br/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
# По заданной выборке &amp;lt;tex&amp;gt;X^m&amp;lt;/tex&amp;gt; случайных и независимых наблюдений полученных из смеси &amp;lt;tex&amp;gt;p(x)&amp;lt;/tex&amp;gt;, числу &amp;lt;tex&amp;gt;k&amp;lt;/tex&amp;gt; и функции &amp;lt;tex&amp;gt;\phi&amp;lt;/tex&amp;gt;, оценить вектор параметров &amp;lt;tex&amp;gt;\Theta = (w_1,..,w_k,\theta_1,..,\theta_k)&amp;lt;/tex&amp;gt;&lt;br /&gt;
# Найти &amp;lt;tex&amp;gt;k&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Проблема === &lt;br /&gt;
&lt;br /&gt;
Задачи подобного рода мы умеем решать, максимизируя логармиф правдоподобия:&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;tex&amp;gt; L(\Theta) = ln \prod\limits_{i=1}^mp(x_i) = \sum\limits_{i=1}^m ln\sum\limits_{j=1}^k w_j p_j(x_i; \theta_j) \longrightarrow \max\limits_{\Theta}&amp;lt;/tex&amp;gt;&amp;lt;br/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Но пробелма в том, что мы не знаем как аналитически посчитать логарифм суммы. Тут нам и поможет алгоритм EM.&lt;br /&gt;
&lt;br /&gt;
=== Решение === &lt;br /&gt;
&lt;br /&gt;
Основная идея алгоритма EM заключается в том, что мы добавляме скрытые переменные такие, что:&amp;lt;br/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
# Они могут быть выражены через &amp;lt;tex&amp;gt;\Theta&amp;lt;/tex&amp;gt;&lt;br /&gt;
# Они помогают разбить сумму так: &amp;lt;tex&amp;gt;p (X, H|\Theta) = \prod\limits_{i=1}^k p (X|H, \Theta) p(H|\Theta)&amp;lt;/tex&amp;gt;, где &amp;lt;tex&amp;gt;H&amp;lt;/tex&amp;gt; - матрица скрытых переменных.&lt;br /&gt;
&lt;br /&gt;
Тогда алгоритм EM сводится к повторению шагов, указанных в [[#Определение|Определении]].&lt;br /&gt;
&lt;br /&gt;
=== E-шаг === &lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt;p(x,\theta_j) = p(x)P(\theta_j | x) = w_jp_j(x)&amp;lt;/tex&amp;gt; &amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Скрытые переменные представляют из себя матрицу &amp;lt;tex&amp;gt;H = (h_{ij})_{m \times k}&amp;lt;/tex&amp;gt;&amp;lt;br/&amp;gt;&lt;br /&gt;
где &amp;lt;tex&amp;gt;h_{ij} = P(\theta_j | x_i)&amp;lt;/tex&amp;gt; {{---}} вероятность того, что &amp;lt;tex&amp;gt;x_i&amp;lt;/tex&amp;gt; пренадлежит &amp;lt;tex&amp;gt;j&amp;lt;/tex&amp;gt;-ой компоненте.&amp;lt;br/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
По формуле Байеса справедливо равенство:&amp;lt;br /&amp;gt;&lt;br /&gt;
&amp;lt;tex&amp;gt; h_{ij} = \frac{w_jp_j(x_i)}{p (x_i)} = \frac{w_jp_j(x_i)}{\sum\limits_{s=1}^k w_s p_s(x_i)}&amp;lt;/tex&amp;gt;&amp;lt;br/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Также &amp;lt;tex&amp;gt;\sum\limits_{j=1}^k h_{ij} = 1&amp;lt;/tex&amp;gt;&amp;lt;br/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Таким образом, зная значения вектора параметров &amp;lt;tex&amp;gt;\Theta&amp;lt;/tex&amp;gt;, мы легко можем пересчитать значения скрытых переменных&amp;lt;br/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== M-шаг === &lt;br /&gt;
&lt;br /&gt;
{{Теорема&lt;br /&gt;
|statement=&lt;br /&gt;
Если известны скрытые переменные, то задача минимизации &amp;lt;tex&amp;gt;Q(\Theta)&amp;lt;/tex&amp;gt; сводится к &amp;lt;tex&amp;gt;k&amp;lt;/tex&amp;gt; независимым подзадачам:&amp;lt;br/&amp;gt;&lt;br /&gt;
&amp;lt;center&amp;gt;&amp;lt;tex&amp;gt;\theta_j = \arg\max\limits_{\theta}\sum\limits_{i=1}^m h_{ij}*\ln\phi(x_i;\theta)&amp;lt;/tex&amp;gt;&amp;lt;/center&amp;gt;&lt;br /&gt;
Оптимальные же веса считаются как:&amp;lt;br/&amp;gt;&lt;br /&gt;
&amp;lt;center&amp;gt;&amp;lt;tex&amp;gt; w_j = \frac {1} {m} \sum\limits_{i=1}^m h_{ij}&amp;lt;/tex&amp;gt;&amp;lt;/center&amp;gt;&lt;br /&gt;
|proof=&lt;br /&gt;
Посчитаем логарифм правдоподобия:&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;tex&amp;gt; Q(\Theta) = \sum\limits_{i=1}^m ln\sum\limits_{j=1}^k w_j p_j(x_i; \theta_j) \longrightarrow \max\limits_{\Theta}&amp;lt;/tex&amp;gt;&amp;lt;br/&amp;gt;&lt;br /&gt;
При условии, что&amp;lt;tex&amp;gt; \sum\limits_{j=1}^k w_j = 1; w_j \geq 0&amp;lt;/tex&amp;gt; имеет смысл рассматривать Лагранжиан задачи:&amp;lt;br/&amp;gt;&lt;br /&gt;
&amp;lt;tex&amp;gt; L(\Theta, X^m) = \sum\limits_{i=1}^m ln \biggl( \sum\limits_{j=1}^k w_j p_j(x_i) \biggr)  - \lambda \biggl(\sum\limits_{j=1}^k w_j - 1 \biggr) &amp;lt;/tex&amp;gt;&amp;lt;br/&amp;gt;&lt;br /&gt;
Приравняв нулю производную Лагранжиана по &amp;lt;tex&amp;gt;w_j&amp;lt;/tex&amp;gt;, получим:&amp;lt;br/&amp;gt;&lt;br /&gt;
&amp;lt;tex&amp;gt;\frac{\partial L} {\partial w_j} = \sum\limits_{i=1}^m \frac{p_j(x_i)}{\sum\limits_{s=1}^kw_s p_s(x_i)} - \lambda = 0, j = 1..k&amp;lt;/tex&amp;gt;&amp;lt;br /&amp;gt;&lt;br /&gt;
Умножим на &amp;lt;tex&amp;gt;w_j&amp;lt;/tex&amp;gt; и просуммируем уравнения для всех &amp;lt;tex&amp;gt;j&amp;lt;/tex&amp;gt; &amp;lt;br /&amp;gt;&lt;br /&gt;
&amp;lt;tex&amp;gt;\sum\limits_{j=1}^k \sum\limits_{i=1}^m \frac{w_jp_j(x_i)}{\sum\limits_{s=1}^kw_s p_s(x_i)} = \lambda \sum\limits_{j=1}^kw_j&amp;lt;/tex&amp;gt; &amp;lt;br /&amp;gt;&lt;br /&gt;
А так как &amp;lt;tex&amp;gt;\sum\limits_{j=1}^k \frac{w_jp_j(x_i)}{\sum\limits_{s=1}^kw_sp_s(x_i)} = 1&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;\sum\limits_{j=1}^kw_j = 1&amp;lt;/tex&amp;gt;, из чего следует &amp;lt;tex&amp;gt;\lambda = m&amp;lt;/tex&amp;gt; &amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt;w_j = \frac{1}{m}\sum\limits_{i=1}^m \frac{w_jp_j(x_i)}{\sum\limits_{s=1}^kw_sp_s(x_i)} = \frac{1}{m}\sum\limits_{i=1}^m h_{ij}&amp;lt;/tex&amp;gt;&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Приравняв к нулю производную Лагранжиана по &amp;lt;tex&amp;gt;\theta_j&amp;lt;/tex&amp;gt;, схожим способом найдем:&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt; \theta_j = \arg\max\limits_{\theta}\sum\limits_{i=1}^m h_{ij}*\ln\phi(x_i;\theta).&amp;lt;/tex&amp;gt;&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
=== Критерий остановки === &lt;br /&gt;
&lt;br /&gt;
Алгоритм EM вы полняется до сходимости, но как нам определить, что сходимость наступила? Мы можем останавливаться, когда либо &amp;lt;tex&amp;gt;Q(\Theta)&amp;lt;/tex&amp;gt;, либо &amp;lt;tex&amp;gt;H&amp;lt;/tex&amp;gt; перестают сильно меняться. Но, обычно, удобней контролировать изменения значений скрытых переменных, так как они имеют смысл вероятностей и принимают значения из отрезка &amp;lt;tex&amp;gt;[0,1]&amp;lt;/tex&amp;gt;. Поэтому один из возможных критериев остановки будет выглядеть так: &amp;lt;tex&amp;gt;\max\limits_{i,j} |h_{ij} - h_{ij}^{(0)}| &amp;gt; \delta&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Псевдокод === &lt;br /&gt;
&lt;br /&gt;
 Input:&amp;lt;tex&amp;gt;X^m, k, \theta^{(0)}&amp;lt;/tex&amp;gt;&lt;br /&gt;
 Repeat&lt;br /&gt;
    '''E-step''': for all i = 1..m; j = 1..k:&lt;br /&gt;
        &amp;lt;tex&amp;gt;h_{ij} = \frac{w_j \phi(x_i; \theta_j)}{\sum\limits_{s=1}^k w_s \phi(x_i; \theta_j)}&amp;lt;/tex&amp;gt;&lt;br /&gt;
    '''M-step''': for all j = 1..k:&lt;br /&gt;
        &amp;lt;tex&amp;gt;\theta_j = \arg\max\limits_{\theta} \sum\limits_{i=1}^m h_{ij}*ln \phi (x_i, \theta)&amp;lt;/tex&amp;gt;&lt;br /&gt;
        &amp;lt;tex&amp;gt;w_j = \frac {1} {m} \sum\limits_{i=1}^m h_{ij}&amp;lt;/tex&amp;gt;&lt;br /&gt;
 Until a stopping criterion is satisfied&lt;br /&gt;
 Return &amp;lt;tex&amp;gt;\Theta = (\theta_j, w_j)_{j=1}^k&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Плюсы и минусы === &lt;br /&gt;
&lt;br /&gt;
Плюсы:&amp;lt;br/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Сходится в большинтсве ситуаций&lt;br /&gt;
* Наиболее гибкое решение&lt;br /&gt;
* Существуют простые модификации, позволяющие уменьшить чуствительность алгоритма к шуму в данных&lt;br /&gt;
&lt;br /&gt;
Минусы:&amp;lt;br/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Чуствителен к начальному приближению. Могут быть ситуации, когда сойдемся к локальному экстремуму&lt;br /&gt;
* Число компонент &amp;lt;tex&amp;gt;k&amp;lt;/tex&amp;gt; является гиперпараметром.&lt;br /&gt;
&lt;br /&gt;
== Модификации == &lt;br /&gt;
&lt;br /&gt;
Базовый алгоритм EM является очень гибким для модификаций, позволяющих улучшить его работу. В этом разделе мы приведем краткое описаниен некоторых из них.&lt;br /&gt;
&lt;br /&gt;
=== Generalized EM-algorithm === &lt;br /&gt;
&lt;br /&gt;
Осоновная идея этой модификации заключается в том, что на шаге M мы не будем пытаться найти наилучшее решение. Это применимо в случаях, когда максимизация &amp;lt;tex&amp;gt;Q(\Theta)&amp;lt;/tex&amp;gt; является сликшом дорогой, поэтому нам достаточно сделать лишь несколько итераций, для того, чтобы сместиться в сторону максимума значения &amp;lt;tex&amp;gt;Q(\Theta)&amp;lt;/tex&amp;gt;. Эта модификация имеет неплохую сходимость.&lt;br /&gt;
&lt;br /&gt;
=== Stochastic EM-algorithm ===&lt;br /&gt;
&lt;br /&gt;
Как уже было отмечено в [[#Плюсы_и_минусы|Плюсы и минусы]], базовый алгоритм чувствителен к начальному приближению и могут быть ситуации, когда алгоритм &amp;quot;застрянет&amp;quot; в лоакльном экстремуме. Для того, чтобы предотвратить это, будем на каждой итерации алгоритма случайно &amp;quot;встряхивать&amp;quot; выборку. В этой модификации у нас добавляется шаг S, на котором мы и будем &amp;quot;встряхивать&amp;quot; выборку. И на шаге M мы будем решать уже задачу максимуму невзвешенного правдоподобия. Эта модификация хороша тем, что нечуствиетльная к начальном приблежению. &lt;br /&gt;
&lt;br /&gt;
== Пример. Разделение смеси Гауссиана == &lt;br /&gt;
&lt;br /&gt;
[[Файл:Gaussians2.png|right|thumb|400px|Несколько итераций алгоритма]]&lt;br /&gt;
&lt;br /&gt;
Каноническим примером использования EM алгоритма является задача разделения смеси гауссиана. Данные у нас получены из нормального распределения. В этом случае параметрами функций ялвяются матожидание и дисперсия.&amp;lt;br/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt;\theta = (w_1,..,w_k;\;\mu_1,..,\mu_k;\;\sigma_1,..,\sigma_k)&amp;lt;/tex&amp;gt; {{---}} вектор параметров, &amp;lt;br/&amp;gt;&lt;br /&gt;
&amp;lt;tex&amp;gt;p_j(x) = N(x;\mu_j, \sigma_j) = \frac1{\sqrt{2\pi}\sigma_j} \exp \biggl(-\frac{(x - \mu_j)^2}{2\sigma_j^2}\biggr) &amp;lt;/tex&amp;gt; - плотность распределения &amp;lt;br/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Посчитаем значения для каждого шага. &amp;lt;br/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
E-шаг:&lt;br /&gt;
&lt;br /&gt;
: &amp;lt;tex&amp;gt; h_{ij} = \frac{w_j N(x_i, \mu_j, \sigma_j)}{\sum\limits_{s=1}^k w_s N(x_i, \mu_s, \sigma_s)} &amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
M-шаг:&lt;br /&gt;
&lt;br /&gt;
: &amp;lt;tex&amp;gt;w_j = \frac{1}{m} \sum\limits_{i=1}^m h_{ij}&amp;lt;/tex&amp;gt;&lt;br /&gt;
: &amp;lt;tex&amp;gt; \mu_j = \frac {1} {mw_j} \sum\limits_{i=1}^m h_{ij}x_i&amp;lt;/tex&amp;gt;&lt;br /&gt;
: &amp;lt;tex&amp;gt; \sigma_j^2 = \frac {1} {mw_j} \sum\limits_{i=1}^m h_{ij}(x_i - \mu_j)^2, j = 1..k&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Использование в задаче кластеризации ==&lt;br /&gt;
&lt;br /&gt;
[[Файл:kmeans.jpg|right|thumb|200px|Пример работы k-means]]&lt;br /&gt;
&lt;br /&gt;
Как уже упоминалось в [[#Опредиление|Определении]], алгоритм EM подходит для решения задачи кластеризации. И одной из его имплементаций для этой задачи является алгоритм &amp;lt;tex&amp;gt;k&amp;lt;/tex&amp;gt;-means. В этом алгоритме в качестве скрытых переменных выступают метки классов объектов. Параметрами же являются центроиды искомых классов. Тогда на шаге E мы относим объекты к какому то одному классу на основе расстояний до центроид. А на шаге M мы пересчитываем центроиды кластеров, исходя из полученной на шаге E разметке.&amp;lt;br/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Также стоит упомянуть алгоритм &amp;lt;tex&amp;gt;c&amp;lt;/tex&amp;gt;-means. В нем качестве скрытых переменных выступают вероятности принадлежности объекта к классам. На шаге E мы пересчитывем вероятности принадлежности объектов, иходя из расстояния до центроид. Шаг M, идейно, остается без изменений.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Реализация на python ==&lt;br /&gt;
&lt;br /&gt;
В пакете sklearn алгоритм EM представлен объектом GaussianMixture. Проиллюстрируем его работу на примере задачи кластеризации и сравним его с алгоритмом &amp;lt;tex&amp;gt;k&amp;lt;/tex&amp;gt;-means:&lt;br /&gt;
 &lt;br /&gt;
 [[Файл:Prog.png|thumb|400px|Результат выполнения программы]]&lt;br /&gt;
 '''import''' numpy as np&lt;br /&gt;
 '''import''' matplotlib.pyplot as plt&lt;br /&gt;
 '''from''' sklearn '''import''' cluster, datasets, mixture&lt;br /&gt;
 '''from''' sklearn.preprocessing '''import''' StandardScaler&lt;br /&gt;
 '''from''' itertools '''import''' cycle, islice&lt;br /&gt;
 np.random.seed(12)&lt;br /&gt;
 &lt;br /&gt;
 &amp;lt;font color=&amp;quot;green&amp;quot;&amp;gt;# Создаем datasets с использованием стандартных sklearn.datasets&amp;lt;/font&amp;gt;&lt;br /&gt;
 n_samples = 2000&lt;br /&gt;
 random_state = 170&lt;br /&gt;
 noisy_circles = datasets.make_circles(n_samples=n_samples, factor=.5, noise=.05)&lt;br /&gt;
 noisy_moons = datasets.make_moons(n_samples=n_samples, noise=.05)&lt;br /&gt;
 blobs = datasets.make_blobs(n_samples=n_samples, random_state=8)&lt;br /&gt;
 varied = datasets.make_blobs(n_samples=n_samples, cluster_std=[1.0, 2.5, 0.5], random_state=random_state)&lt;br /&gt;
 &lt;br /&gt;
 &amp;lt;font color=&amp;quot;green&amp;quot;&amp;gt;# Создаем анизатропно разделенные данные&amp;lt;/font&amp;gt;&lt;br /&gt;
 X, y = datasets.make_blobs(n_samples=n_samples, random_state=random_state)&lt;br /&gt;
 transformation = [[0.6, -0.6], [-0.4, 0.8]]&lt;br /&gt;
 X_aniso = np.dot(X, transformation)&lt;br /&gt;
 aniso = (X_aniso, y)&lt;br /&gt;
 &lt;br /&gt;
 &amp;lt;font color=&amp;quot;green&amp;quot;&amp;gt;# Выставляем параметры для matplotlib.pyplot&amp;lt;/font&amp;gt;&lt;br /&gt;
 plt.figure(figsize=(9 * 2 + 3, 12.5))&lt;br /&gt;
 plt.subplots_adjust(left=.02, right=.98, bottom=.001, top=.96, wspace=.05, hspace=.01)&lt;br /&gt;
 plot_num = 1&lt;br /&gt;
 defaul_n = 3&lt;br /&gt;
 &lt;br /&gt;
 &amp;lt;font color=&amp;quot;green&amp;quot;&amp;gt;# Варьируем значение количества классов в зависимости от данных, ведь для нас это гиперпараметр&amp;lt;/font&amp;gt;&lt;br /&gt;
 datasets = [&lt;br /&gt;
    (varied, defaul_n),&lt;br /&gt;
    (aniso, defaul_n),&lt;br /&gt;
    (blobs, defaul_n),&lt;br /&gt;
    (noisy_circles, 2)]&lt;br /&gt;
 for i_dataset, (dataset, n_cluster) in enumerate(datasets):&lt;br /&gt;
    X, y = dataset&lt;br /&gt;
 &lt;br /&gt;
    &amp;lt;font color=&amp;quot;green&amp;quot;&amp;gt;# Нормализация данных&amp;lt;/font&amp;gt;&lt;br /&gt;
    X = StandardScaler().fit_transform(X)&lt;br /&gt;
 &lt;br /&gt;
    &amp;lt;font color=&amp;quot;green&amp;quot;&amp;gt;# Непосредственно наш алгоритм - Gaussian Mixture&amp;lt;/font&amp;gt;&lt;br /&gt;
    gmm = mixture.GaussianMixture(n_components=n_cluster, covariance_type='full')&lt;br /&gt;
    &lt;br /&gt;
    &amp;lt;font color=&amp;quot;green&amp;quot;&amp;gt;# Для сравнения берем алгоритм - k-means&amp;lt;/font&amp;gt;&lt;br /&gt;
    two_means = cluster.KMeans(n_clusters=n_cluster)&lt;br /&gt;
    clustering_algorithms = (&lt;br /&gt;
        ('GaussianMixture', gmm),&lt;br /&gt;
        ('KMeans', two_means)&lt;br /&gt;
    )&lt;br /&gt;
    for name, algorithm in clustering_algorithms:&lt;br /&gt;
 &lt;br /&gt;
        # Этап обучения&lt;br /&gt;
        algorithm.fit(X)&lt;br /&gt;
        &lt;br /&gt;
        # Применяем алгоритм&lt;br /&gt;
        y_pred = algorithm.predict(X)&lt;br /&gt;
        &lt;br /&gt;
        # Рисуем результаты&lt;br /&gt;
        plt.subplot(len(datasets), len(clustering_algorithms), plot_num)&lt;br /&gt;
        if i_dataset == 0:&lt;br /&gt;
            plt.title(name, size=18)&lt;br /&gt;
        colors = np.array(list(islice(cycle(['#377eb8', '#ff7f00', '#4daf4a']), int(max(y_pred) + 1))))&lt;br /&gt;
        plt.scatter(X[:, 0], X[:, 1], s=10, color=colors[y_pred])&lt;br /&gt;
        plt.xlim(-2.5, 2.5)&lt;br /&gt;
        plt.ylim(-2.5, 2.5)&lt;br /&gt;
        plt.xticks(())&lt;br /&gt;
        plt.yticks(())&lt;br /&gt;
        plot_num += 1&lt;br /&gt;
 plt.show()&lt;br /&gt;
&lt;br /&gt;
Как и следовало ожидать, алгоритм EM работает на некоторых данных лучше чем k-means, однако есть данные, с которыми он не справляется без дополнительных преобразований.&lt;br /&gt;
&lt;br /&gt;
== См. также ==&lt;br /&gt;
*[[Кластеризация]]&lt;br /&gt;
*[[Алгоритм_k-Means|Алгоритм k-Means]]&lt;br /&gt;
&lt;br /&gt;
== Источники информации ==&lt;br /&gt;
&lt;br /&gt;
# Материалы лекции про кластеризацию курса &amp;quot;Машинное обучение&amp;quot; университета ИТМО, 2019 год&lt;br /&gt;
# [http://www.machinelearning.ru/wiki/images/6/6d/Voron-ML-1.pdf Математические методы обучения по прецедентам К. В. Воронцов]&lt;br /&gt;
# [http://www.machinelearning.ru/wiki/index.php?title=EM-%D0%B0%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC Статья про EM-алгоритм на machinelearning.ru]&lt;br /&gt;
# [https://machinelearningmastery.com/expectation-maximization-em-algorithm/ A Gentle Introduction to Expectation-Maximization]&lt;br /&gt;
# [http://dendroid.sk/2011/05/09/k-means-clustering/ k-means]&lt;br /&gt;
&lt;br /&gt;
[[Категория:Машинное обучение]]&lt;/div&gt;</summary>
		<author><name>94.229.111.244</name></author>	</entry>

	<entry>
		<id>http://neerc.ifmo.ru/wiki/index.php?title=EM-%D0%B0%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC&amp;diff=72914</id>
		<title>EM-алгоритм</title>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=EM-%D0%B0%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC&amp;diff=72914"/>
				<updated>2020-03-17T09:00:58Z</updated>
		
		<summary type="html">&lt;p&gt;94.229.111.244: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Определение ==&lt;br /&gt;
&lt;br /&gt;
'''Алгоритм EM''' (англ: expectation-maximization) --- итеративный алгоритм поиска оценок максимума правдоподобия модели, в ситуации, когда она зависит от скрытых(ненаблюдаемых) переменных.&lt;br /&gt;
&lt;br /&gt;
Алгоритм ищет параметры модели итеративно, каждая итерация состоит из двух шагов:&lt;br /&gt;
&lt;br /&gt;
'''E(Expectation)''' шаг --- поиск наиболее вероятных значений скрытых переменных.&lt;br /&gt;
&lt;br /&gt;
'''M(Maximisation)''' шаг --- поиск наиболее вероятных значений параметров, для полученных на шаге E значений скрытых переменных.&lt;br /&gt;
&lt;br /&gt;
EM алгоритм подходит для решения задач двух типов:&lt;br /&gt;
&lt;br /&gt;
# Задачи с неполными данными.&lt;br /&gt;
# Задачи, в которых удобно вводить скрытые переменные для упрощения подсчета функции правдоподобия. Примером такой задачи может служить кластеризация&lt;br /&gt;
&lt;br /&gt;
== Проблема восстановления распределения смеси == &lt;br /&gt;
&lt;br /&gt;
=== Постановка задачи ===&lt;br /&gt;
&lt;br /&gt;
Плотность распределения смеси имеет вид:&amp;lt;br/&amp;gt;&lt;br /&gt;
&amp;lt;tex&amp;gt;p(x) = \sum\limits_{i=1}^k \omega_j p_j(x)&amp;lt;/tex&amp;gt;&amp;lt;br/&amp;gt;&lt;br /&gt;
Где &amp;lt;tex&amp;gt; \sum\limits_{i=1}^k w_j = 1;  w_j &amp;gt;= 0; p_j(x) = \phi(x;\theta_j)&amp;lt;/tex&amp;gt; - функция правдоподобия &amp;lt;tex&amp;gt;j&amp;lt;/tex&amp;gt;-ой компонеты смеси, &amp;lt;tex&amp;gt;\omega_j&amp;lt;/tex&amp;gt; - априорная вероятность &amp;lt;tex&amp;gt;j&amp;lt;/tex&amp;gt;-ой компоненты распределения.&amp;lt;br/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Перед нами стоит две задачи:&amp;lt;br/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
# По заданной выборке &amp;lt;tex&amp;gt;X^m&amp;lt;/tex&amp;gt; случайных и независимых наблюдений полученных из смеси &amp;lt;tex&amp;gt;p(x)&amp;lt;/tex&amp;gt;, числу &amp;lt;tex&amp;gt;k&amp;lt;/tex&amp;gt; и функцию &amp;lt;tex&amp;gt;\phi&amp;lt;/tex&amp;gt;, оценить вектор параметров &amp;lt;tex&amp;gt;\Theta = (\omega_1,..,\omega_k,\theta_1,..,\theta_k)&amp;lt;/tex&amp;gt;&lt;br /&gt;
# Найти &amp;lt;tex&amp;gt;k&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Проблема === &lt;br /&gt;
&lt;br /&gt;
Задачи подобного рода мы умеем решать максимизируя логармиф правдоподобия:&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;tex&amp;gt; L(\Theta) = ln \prod\limits_{i=1}^mp(x_i) = \sum\limits_{i=1}^m ln\sum\limits_{j=1}^k w_j p_j(x_i; \theta_j) \longrightarrow max&amp;lt;/tex&amp;gt;&amp;lt;br/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Но пробелма в том, что мы не знаем как аналитически посчитать логарифм суммы. Тут нам и поможет алгоритм EM.&lt;br /&gt;
&lt;br /&gt;
=== Решение === &lt;br /&gt;
&lt;br /&gt;
Основная идея алгоритма EM заключается в том, что мы добавляме скрытые переменные такие, что:&amp;lt;br/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
# Они могут быть выражены через &amp;lt;tex&amp;gt;\Theta&amp;lt;/tex&amp;gt;&lt;br /&gt;
# Они помогают разбить сумму так: &amp;lt;tex&amp;gt;p (X, H|\Theta) = \prod\limits_{i=1}^k p (X|H, \Theta) p(H|\Theta)&amp;lt;/tex&amp;gt;, где &amp;lt;tex&amp;gt;H&amp;lt;/tex&amp;gt; - матрица скрытых переменных.&lt;br /&gt;
&lt;br /&gt;
Тогда алгоритм EM сводится к повторению шагов, указанных в [[#Определение|Определение]].&lt;br /&gt;
&lt;br /&gt;
=== E-шаг === &lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt;p(x,\theta_j) = p(x)P(\theta_j | x) = w_jp_j(x)&amp;lt;/tex&amp;gt; &amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Скрытые переменные представляют из себя матрицу &amp;lt;tex&amp;gt;H = (h_{ij})_{m \times k}&amp;lt;/tex&amp;gt;&amp;lt;br/&amp;gt;&lt;br /&gt;
где &amp;lt;tex&amp;gt;h_{ij} = P(\theta_j | x_i)&amp;lt;/tex&amp;gt; - вероятность того, что &amp;lt;tex&amp;gt;x_i&amp;lt;/tex&amp;gt; пренадлежит &amp;lt;tex&amp;gt;j&amp;lt;/tex&amp;gt;-ой компоненте.&amp;lt;br/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
По формуле Байеса справедливо равенство:&amp;lt;br /&amp;gt;&lt;br /&gt;
&amp;lt;tex&amp;gt; h_{ij} = \frac{w_jp_j(x_i)}{p (x_i)} = \frac{w_jp_j(x_i)}{\sum\limits_{s=1}^k w_s p_s(x_i)}&amp;lt;/tex&amp;gt;&amp;lt;br/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Также &amp;lt;tex&amp;gt;\sum\limits_{j=1}^k h_{ij} = 1&amp;lt;/tex&amp;gt;&amp;lt;br/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Таким образом, зная значения вектора параметров &amp;lt;tex&amp;gt;\Theta&amp;lt;/tex&amp;gt;, мы легко можем пересчитать значения скрытых переменных&amp;lt;br/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== M-шаг === &lt;br /&gt;
&lt;br /&gt;
{{Теорема&lt;br /&gt;
|statement=&lt;br /&gt;
Если известны скрытые переменные, то задача минимизации &amp;lt;tex&amp;gt;Q(\Theta)&amp;lt;/tex&amp;gt; сводится к &amp;lt;tex&amp;gt;k&amp;lt;/tex&amp;gt; независимым подзадачам:&amp;lt;br/&amp;gt;&lt;br /&gt;
&amp;lt;center&amp;gt;&amp;lt;tex&amp;gt;\theta_j = argmax_{\theta} \sum\limits_{i=1}^m h_{ij}*ln \phi (x_i, \theta)&amp;lt;/tex&amp;gt;&amp;lt;/center&amp;gt;&lt;br /&gt;
Оптимальные же веса считаются как:&amp;lt;br/&amp;gt;&lt;br /&gt;
&amp;lt;center&amp;gt;&amp;lt;tex&amp;gt; w_j = \frac {1} {m} \sum\limits_{i=1}^m h_{ij}&amp;lt;/tex&amp;gt;&amp;lt;/center&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
=== Псевдокод === &lt;br /&gt;
&lt;br /&gt;
 Input:&amp;lt;tex&amp;gt;X^m, k, \theta^{(0)}&amp;lt;/tex&amp;gt;&lt;br /&gt;
 Repeat&lt;br /&gt;
    '''E-step''': for all i = 1..m; j = 1..k:&lt;br /&gt;
        &amp;lt;tex&amp;gt;h_{ij} = \frac{w_jp_j(x_i)}{\sum\limits_{s=1}^k w_s p_s(x_i)}&amp;lt;/tex&amp;gt;&lt;br /&gt;
    '''M-step''': for all j = 1..k:&lt;br /&gt;
        &amp;lt;tex&amp;gt;\theta_j = argmax_{\theta} \sum\limits_{i=1}^m h_{ij}*ln \phi (x_i, \theta)&amp;lt;/tex&amp;gt;&lt;br /&gt;
        &amp;lt;tex&amp;gt;w_j = \frac {1} {m} \sum\limits_{i=1}^m h_{ij}&amp;lt;/tex&amp;gt;&lt;br /&gt;
 Until stopping criteria is satisfied&lt;br /&gt;
&lt;br /&gt;
=== Плюсы и минусы === &lt;br /&gt;
&lt;br /&gt;
Плюсы:&amp;lt;br/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Сходится в большинтсве ситуаций&lt;br /&gt;
* Наиболее гибкое решение&lt;br /&gt;
* Легко может добавить нечуствительность к шуму&lt;br /&gt;
&lt;br /&gt;
Минусы:&amp;lt;br/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Чуствителен к начальному приближению. Могут быть ситуации, когда сойдемся к локальному экстремуму&lt;br /&gt;
* Число компонент &amp;lt;tex&amp;gt;k&amp;lt;/tex&amp;gt; является гиперпараметром.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Модификации == &lt;br /&gt;
&lt;br /&gt;
Базовый алгоритм EM является очень гибким для модификаций, позволяющих улучшить его работу. В этом разделе мы приведем краткое описаниен некоторых из них.&lt;br /&gt;
&lt;br /&gt;
=== Generalized EM-algorithm === &lt;br /&gt;
&lt;br /&gt;
Осоновная идея этой модификации заключается в том, что на шаге M мы не будем пытаться найти наилучшее решение. Это применимо в случаях, когда максимизация &amp;lt;tex&amp;gt;Q(\Theta)&amp;lt;/tex&amp;gt; является сликшом дорогой, поэтому нам достаточно сделать лишь несколько итераций, для того, чтобы сместиться в сторону максимума значения &amp;lt;tex&amp;gt;Q(\Theta)&amp;lt;/tex&amp;gt;. Эта модификация имеет неплохую сходимость.&lt;br /&gt;
&lt;br /&gt;
=== Stochastic EM-algorithm ===&lt;br /&gt;
&lt;br /&gt;
Как уже было отмечено в [[#Плюсы_и_минусы|Плюсы и минусы]], базовый алгоритм чувствителен к начальному приближению и могут быть ситуации, когда алгоритм &amp;quot;застрянет&amp;quot; в лоакльном экстремуме. Для того, чтобы предотвратить это, будем на каждой итерации алгоритма случайно &amp;quot;встряхивать&amp;quot; выборку. В этой модификации у нас добавляется шаг S, на котором мы и будем &amp;quot;встряхивать&amp;quot; выборку. И на шаге M мы будем решать уже задачу максимуму невзвешенного правдоподобия. Эта модификация хороша тем, что нечуствиетльная к начальном приблежению. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Пример. Разделение смеси Гауссиана == &lt;br /&gt;
&lt;br /&gt;
Каноническим примером использования EM алгоритма является задача разделения смеси гауссиана. Данные у нас получены из нормального распределения. В этом лучае параметрами функций ялвяются матожидание и дисперсия.&amp;lt;br/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt;\theta = (w_1,..,w_k;\;\mu_1,..,\mu_k;\;\sigma_1,..,\sigma_k)&amp;lt;/tex&amp;gt; — вектор параметров, &amp;lt;br/&amp;gt;&lt;br /&gt;
&amp;lt;tex&amp;gt;p_j(x) = N(x;\mu_j, \sigma_j) = \frac1{\sqrt{2\pi}\sigma_j} \exp \biggl(-\frac{(x - \mu_j)^2}{2\sigma_j^2}\biggr) &amp;lt;/tex&amp;gt; - плотность распределения &amp;lt;br/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Посчитаем значения для каждого шага. &amp;lt;br/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
E-шаг:&lt;br /&gt;
&lt;br /&gt;
: &amp;lt;tex&amp;gt; h_{ij} = \frac{w_j N(x_i, \mu_j, \sigma_j)}{\sum\limits_{s=1}^k w_s N(x_i, \mu_s, \sigma_s)} &amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
M-шаг:&lt;br /&gt;
&lt;br /&gt;
: &amp;lt;tex&amp;gt;w_j = \frac{1}{m} \sum\limits_{i=1}^m h_{ij}&amp;lt;/tex&amp;gt;&lt;br /&gt;
: &amp;lt;tex&amp;gt; \mu_j = \frac {1} {mw_j} \sum\limits_{i=1}^m h_{ij}x_i&amp;lt;/tex&amp;gt;&lt;br /&gt;
: &amp;lt;tex&amp;gt; \sigma_j^2 = \frac {1} {mw_j} \sum\limits_{i=1}^m h_{ij}(x_i - \mu_j)^2, j = 1..k&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Задача разделения смеси распределений == &lt;br /&gt;
&lt;br /&gt;
=== Общий алгоритм ===&lt;br /&gt;
&lt;br /&gt;
Необходимо описать плотность распределения функции на X как сумму k функций, которые можно рассматривать как элементы параметрического семейства функций &amp;lt;tex&amp;gt; p_j(x) = \phi(x;\theta_j)&amp;lt;/tex&amp;gt;. Плотность распределения будет выглядеть как &amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;tex&amp;gt;p(x) = \sum\limits_{i=1}^k \omega_j p_j(x);   \sum\limits_{i=1}^k w_j = 1;  w_j &amp;gt;= 0 &amp;lt;/tex&amp;gt;  &lt;br /&gt;
&amp;lt;br /&amp;gt;  где &amp;lt;tex&amp;gt;\omega_j&amp;lt;/tex&amp;gt;- априорная вероятность j компоненты распределения.&lt;br /&gt;
Задача разделения смеси заключается в том, чтобы, имея выборку &amp;lt;tex&amp;gt;X^m&amp;lt;/tex&amp;gt; случайных и независимых наблюдений из смеси &amp;lt;tex&amp;gt;p(x)&amp;lt;/tex&amp;gt;, зная число &amp;lt;tex&amp;gt;k&amp;lt;/tex&amp;gt; и функцию &amp;lt;tex&amp;gt;\phi&amp;lt;/tex&amp;gt;, оценить вектор параметров &amp;lt;tex&amp;gt;\theta = (\omega_1,..,\omega_k,\theta_1,..,\theta_k)&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
E-шаг:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt;p(x,\theta_j) = p(x)P(\theta_j | x) = w_jp_j(x)&amp;lt;/tex&amp;gt; &amp;lt;br /&amp;gt;&lt;br /&gt;
Введем обозначение: &amp;lt;tex&amp;gt; g_{ij} = P(\theta_j | x_i) &amp;lt;/tex&amp;gt; это и будут скрытые параметры данной задачи - апостериорная вероятность того, что обучающий объект &amp;lt;tex&amp;gt; x_i &amp;lt;/tex&amp;gt; получен из &amp;lt;tex&amp;gt;j&amp;lt;/tex&amp;gt;-й компоненты  &lt;br /&gt;
&lt;br /&gt;
По формуле Байеса справедливо равенство:&amp;lt;br /&amp;gt;&lt;br /&gt;
&amp;lt;tex&amp;gt; g_{ij} = \frac{w_jp_j(x_i)}{\sum\limits_{t=1}^k w_t p_t(x_i)}&amp;lt;/tex&amp;gt;&amp;lt;br /&amp;gt;&lt;br /&gt;
Таким образом при зная значение параметров легко найти скрытые переменные.&lt;br /&gt;
&lt;br /&gt;
Перейдем к M-шагу.&lt;br /&gt;
&lt;br /&gt;
Посчитаем для аддитивности логарифм правдоподобия:&amp;lt;br /&amp;gt;&lt;br /&gt;
&amp;lt;tex&amp;gt; Q(\Theta) = ln \prod\limits_{i=1}^mp(x_i) = \sum\limits_{i=1}^m ln\sum\limits_{j=1}^k w_j p_j(x_i) \longrightarrow max&amp;lt;/tex&amp;gt; &amp;lt;br /&amp;gt;&lt;br /&gt;
при условии &amp;lt;tex&amp;gt;\sum\limits_{i=1}^k w_j = 1; w_j &amp;gt;= 0&amp;lt;/tex&amp;gt; имеет смысл рассматривать лагранжиан задачи:&amp;lt;br /&amp;gt;&lt;br /&gt;
&amp;lt;tex&amp;gt;\frac{\partial L} {\partial w_j} = \sum\limits_{i=1}^m \frac{p_j(x_i)}{\sum\limits_{t=1}^kw_tp_t(x_i)} - \lambda = 0.&amp;lt;/tex&amp;gt;&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Умножим на &amp;lt;tex&amp;gt;\omega_j&amp;lt;/tex&amp;gt; и просуммируем уравнения для всех &amp;lt;tex&amp;gt;j&amp;lt;/tex&amp;gt; &amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt;\sum\limits_{j=1}^k \sum\limits_{i=1}^m \frac{w_jp_j(x_i)}{\sum\limits_{t=1}^kw_tp_t(x_i)} = \lambda \sum\limits_{j=1}^kw_j&amp;lt;/tex&amp;gt; &amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Так как можно заменить порядок суммы: &amp;lt;tex&amp;gt; \sum\limits_{i=1}^m \sum\limits_{j=1}^k \frac{w_jp_j(x_i)}{\sum\limits_{t=1}^kw_tp_t(x_i)} = \lambda \sum\limits_{j=1}^kw_j&amp;lt;/tex&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
А так как &amp;lt;tex&amp;gt;\sum\limits_{j=1}^k \frac{w_jp_j(x_i)}{\sum\limits_{t=1}^kw_tp_t(x_i)} = 1&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;\sum\limits_{j=1}^kw_j = 1&amp;lt;/tex&amp;gt;, из чего следует &amp;lt;tex&amp;gt;\lambda = m&amp;lt;/tex&amp;gt; &amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt;\omega_j = \frac{1}{m}\sum\limits_{i=1}^m \frac{w_jp_j(x_i)}{\sum\limits_{t=1}^kw_tp_t(x_i)} = \frac{1}{m}\sum\limits_{i=1}^mg_{ij}&amp;lt;/tex&amp;gt;&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Приравняв к нулю лагранжиан по &amp;lt;tex&amp;gt;\theta_j&amp;lt;/tex&amp;gt; схожим способом найдем:&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt; \theta_j = \arg\max\limits{\theta}\sum\limits_{i=1}^mg_{ij}\ln(\phi(x_i;\theta)).&amp;lt;/tex&amp;gt;&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Таким образом на M-шаге необходимо взять среднее значение &amp;lt;tex&amp;gt;g_{ij}&amp;lt;/tex&amp;gt; и решить k независимых оптимизационных задач.&lt;br /&gt;
&lt;br /&gt;
=== Разделение смеси гауссиан ===&lt;br /&gt;
[[Файл:Gaussians.png|right|250px| Несколько итераций алгоритма]]&lt;br /&gt;
Важным на практике примером является случай, когда параметрическое семейство - нормальные распределения. Параметрами функций будут являться матожидание и дисперсия.&amp;lt;br /&amp;gt;&lt;br /&gt;
&amp;lt;tex&amp;gt;\theta = (w_1,..,w_k;\;\mu_1,..,\mu_k;\;\sigma_1,..,\sigma_k)&amp;lt;/tex&amp;gt; — вектор параметров, &amp;lt;br /&amp;gt;&lt;br /&gt;
&amp;lt;tex&amp;gt;p_j(x) = N(x;\mu_j, \sigma_j) = \frac1{\sqrt{2\pi}\sigma_j} \exp \biggl(-\frac{(x - \mu_j)^2}{2\sigma_j^2}\biggr) &amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== k-means как EM алгоритм ==&lt;br /&gt;
[[Файл:kmeans.jpg|right|250px|K-means]]&lt;br /&gt;
Скрытыми переменными в данной задаче являются классы, к которым относятся объекты для кластеризации. Сами же параметры это центры масс классов. На шаге E - распределяются все объекты по классам исходя из расстояния от центра, на шаге M находится оптимальное месторасположение центра.&lt;br /&gt;
&lt;br /&gt;
Аналогично рассматривается и алгоритм c-means. Скрытые переменные здесь будут вероятности принадлежности к классам, которые находятся на E-шаге по расстоянию от центра. Центр так же рассчитывается на M-шаге исходя из скрытых переменных.&lt;br /&gt;
&lt;br /&gt;
== Реализация на python ==&lt;br /&gt;
&lt;br /&gt;
 '''import''' numpy as np&lt;br /&gt;
 '''import''' matplotlib.pyplot as plt&lt;br /&gt;
 '''from''' sklearn '''import''' cluster, datasets, mixture&lt;br /&gt;
 '''from''' sklearn.preprocessing '''import''' StandardScaler&lt;br /&gt;
 '''from''' itertools '''import''' cycle, islice&lt;br /&gt;
 np.random.seed(12)&lt;br /&gt;
 &lt;br /&gt;
 # Создаем datasets с использованием стандартных sklearn.datasets&lt;br /&gt;
 n_samples = 2000&lt;br /&gt;
 random_state = 170&lt;br /&gt;
 noisy_circles = datasets.make_circles(n_samples=n_samples, factor=.5, noise=.05)&lt;br /&gt;
 noisy_moons = datasets.make_moons(n_samples=n_samples, noise=.05)&lt;br /&gt;
 blobs = datasets.make_blobs(n_samples=n_samples, random_state=8)&lt;br /&gt;
 varied = datasets.make_blobs(n_samples=n_samples, cluster_std=[1.0, 2.5, 0.5], random_state=random_state)&lt;br /&gt;
 &lt;br /&gt;
 # Создаем анизатропно разделенные данные&lt;br /&gt;
 X, y = datasets.make_blobs(n_samples=n_samples, random_state=random_state)&lt;br /&gt;
 transformation = [[0.6, -0.6], [-0.4, 0.8]]&lt;br /&gt;
 X_aniso = np.dot(X, transformation)&lt;br /&gt;
 aniso = (X_aniso, y)&lt;br /&gt;
 &lt;br /&gt;
 # Выставляем параметры для matplotlib.pyplot&lt;br /&gt;
 plt.figure(figsize=(9 * 2 + 3, 12.5))&lt;br /&gt;
 plt.subplots_adjust(left=.02, right=.98, bottom=.001, top=.96, wspace=.05, hspace=.01)&lt;br /&gt;
 plot_num = 1&lt;br /&gt;
 defaul_n = 3&lt;br /&gt;
 &lt;br /&gt;
 # Варьируем значение количества классов в зависимости от данных, ведь для нас это гиперпараметр&lt;br /&gt;
 datasets = [&lt;br /&gt;
    (varied, defaul_n),&lt;br /&gt;
    (aniso, defaul_n),&lt;br /&gt;
    (blobs, defaul_n),&lt;br /&gt;
    (noisy_circles, 2)]&lt;br /&gt;
 for i_dataset, (dataset, n_cluster) in enumerate(datasets):&lt;br /&gt;
    X, y = dataset&lt;br /&gt;
 &lt;br /&gt;
    # Нормализация данных&lt;br /&gt;
    X = StandardScaler().fit_transform(X)&lt;br /&gt;
 &lt;br /&gt;
    # Непосредственно наш алгоритм - Gaussian Mixture&lt;br /&gt;
    gmm = mixture.GaussianMixture(n_components=n_cluster, covariance_type='full')&lt;br /&gt;
    &lt;br /&gt;
    # Для сравнения берем алгоритм - K-means&lt;br /&gt;
    two_means = cluster.KMeans(n_clusters=n_cluster)&lt;br /&gt;
    clustering_algorithms = (&lt;br /&gt;
        ('GaussianMixture', gmm),&lt;br /&gt;
        ('KMeans', two_means)&lt;br /&gt;
    )&lt;br /&gt;
    for name, algorithm in clustering_algorithms:&lt;br /&gt;
 &lt;br /&gt;
        # Этап обучения&lt;br /&gt;
        algorithm.fit(X)&lt;br /&gt;
        &lt;br /&gt;
        # Применяем алгоритм&lt;br /&gt;
        y_pred = algorithm.predict(X)&lt;br /&gt;
        &lt;br /&gt;
        # Рисуем результаты&lt;br /&gt;
        plt.subplot(len(datasets), len(clustering_algorithms), plot_num)&lt;br /&gt;
        if i_dataset == 0:&lt;br /&gt;
            plt.title(name, size=18)&lt;br /&gt;
        colors = np.array(list(islice(cycle(['#377eb8', '#ff7f00', '#4daf4a']), int(max(y_pred) + 1))))&lt;br /&gt;
        plt.scatter(X[:, 0], X[:, 1], s=10, color=colors[y_pred])&lt;br /&gt;
        plt.xlim(-2.5, 2.5)&lt;br /&gt;
        plt.ylim(-2.5, 2.5)&lt;br /&gt;
        plt.xticks(())&lt;br /&gt;
        plt.yticks(())&lt;br /&gt;
        plot_num += 1&lt;br /&gt;
 plt.show()&lt;br /&gt;
&lt;br /&gt;
[[Файл:Prog.png|thumb|250px|Результат программы]]&lt;br /&gt;
&lt;br /&gt;
Как и следовало ожидать, алгоритм работает на некоторых данных лучше чем k-means, однако есть данные, с которыми он не справляется без дополнительных преобразований.&lt;br /&gt;
&lt;br /&gt;
== См. также ==&lt;br /&gt;
*[[Кластеризация]]&lt;br /&gt;
&lt;br /&gt;
== Источники информации ==&lt;br /&gt;
&lt;br /&gt;
# [http://www.machinelearning.ru/wiki/images/6/6d/Voron-ML-1.pdf Математические методы обучения по прецедентам К. В. Воронцов]&lt;br /&gt;
# [http://dendroid.sk/2011/05/09/k-means-clustering/ k-means]&lt;br /&gt;
&lt;br /&gt;
[[Категория:Машинное обучение]]&lt;/div&gt;</summary>
		<author><name>94.229.111.244</name></author>	</entry>

	</feed>