<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="ru">
	<id>https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=DennZo1993</id>
	<title>Алговики - Вклад [ru]</title>
	<link rel="self" type="application/atom+xml" href="https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=DennZo1993"/>
	<link rel="alternate" type="text/html" href="https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/ru/%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/DennZo1993"/>
	<updated>2026-10-22T20:43:32Z</updated>
	<subtitle>Вклад</subtitle>
	<generator>MediaWiki 1.43.5</generator>
	<entry>
		<id>https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:%D0%91%D1%80%D0%BE%D1%82%D0%B8%D0%BA%D0%BE%D0%B2%D1%81%D0%BA%D0%B0%D1%8F_%D0%94%D0%B0%D0%BD%D1%83%D1%82%D0%B0/%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_k-means&amp;diff=20540</id>
		<title>Участник:Бротиковская Данута/Алгоритм k-means</title>
		<link rel="alternate" type="text/html" href="https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:%D0%91%D1%80%D0%BE%D1%82%D0%B8%D0%BA%D0%BE%D0%B2%D1%81%D0%BA%D0%B0%D1%8F_%D0%94%D0%B0%D0%BD%D1%83%D1%82%D0%B0/%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_k-means&amp;diff=20540"/>
		<updated>2016-12-10T11:15:57Z</updated>

		<summary type="html">&lt;p&gt;DennZo1993: /* Масштабируемость алгоритма и его реализации */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Assignment|Zhum}}&lt;br /&gt;
&lt;br /&gt;
{{algorithm&lt;br /&gt;
| name              = Алгоритм k средних (k means)&lt;br /&gt;
| serial_complexity = &amp;lt;math&amp;gt;O(ikdn)&amp;lt;/math&amp;gt;&lt;br /&gt;
| input_data        = &amp;lt;math&amp;gt; dn &amp;lt;/math&amp;gt;&lt;br /&gt;
| output_data       = &amp;lt;math&amp;gt; n &amp;lt;/math&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
Авторы страницы &amp;lt;b&amp;gt;[[Участник:Бротиковская Данута|Данута Бротиковская]]&amp;lt;/b&amp;gt; и &amp;lt;b&amp;gt;[[Участник:DennZo1993|Денис Зобнин]]&amp;lt;/b&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
Оба автора внесли одинаковый вклад в написание статьи (поиск материалов, изучение статей, заполнение контента статьи), четких разграничений по пунктам статьи сделать невозможно. &lt;br /&gt;
&lt;br /&gt;
== Свойства и структура алгоритма ==&lt;br /&gt;
&lt;br /&gt;
=== Общее описание алгоритма ===&lt;br /&gt;
Алгоритм &amp;lt;b&amp;gt;&amp;lt;i&amp;gt;k средних&amp;lt;/i&amp;gt;&amp;lt;/b&amp;gt; (&amp;lt;b&amp;gt;&amp;lt;i&amp;gt;k means&amp;lt;/i&amp;gt;&amp;lt;/b&amp;gt;) &amp;amp;ndash; неиерархический&amp;lt;ref&amp;gt;&amp;quot;https://ru.wikipedia.org/wiki/Иерархическая_кластеризация&amp;quot;&amp;lt;/ref&amp;gt;, итерационный метод кластеризации&amp;lt;ref&amp;gt;&amp;quot;https://ru.wikipedia.org/wiki/Кластерный_анализ&amp;quot;&amp;lt;/ref&amp;gt;, получивший большую популярность благодаря своей простоте, наглядности реализации и достаточно высокому качеству работы. Был изобретен в 1950-х годах математиком &amp;lt;i&amp;gt;Гуго Штейнгаузом&amp;lt;/i&amp;gt;&amp;lt;ref&amp;gt;Steinhaus, Hugo. &amp;quot;Sur la division des corp materiels en parties.&amp;quot; Bull. Acad. Polon. Sci 1.804 (1956): 801.&amp;lt;/ref&amp;gt; и почти одновременно &amp;lt;i&amp;gt;Стюартом Ллойдом&amp;lt;/i&amp;gt;&amp;lt;ref&amp;gt;Lloyd, S. P. &amp;quot;Least square quantization in PCM. Bell Telephone Laboratories Paper. Published in journal much later: Lloyd, SP: Least squares quantization in PCM.&amp;quot; IEEE Trans. Inform. Theor.(1957/1982).&amp;lt;/ref&amp;gt;. Особую популярность приобрел после публикации работы &amp;lt;i&amp;gt;МакКуина&amp;lt;/i&amp;gt;&amp;lt;ref&amp;gt;MacQueen, James. &amp;quot;Some methods for classification and analysis of multivariate observations.&amp;quot; Proceedings of the fifth Berkeley symposium on mathematical statistics and probability. Vol. 1. No. 14. 1967.&amp;lt;/ref&amp;gt; в 1967.&lt;br /&gt;
&lt;br /&gt;
Алгоритм представляет собой версию EM-алгоритма&amp;lt;ref&amp;gt;&amp;quot;https://ru.wikipedia.org/wiki/EM-алгоритм&amp;quot;&amp;lt;/ref&amp;gt;, применяемого также для разделения смеси гауссиан. Основная идея &amp;lt;i&amp;gt;k means&amp;lt;/i&amp;gt; заключается в том, что данные произвольно разбиваются на кластеры, после чего итеративно перевычисляется центр масс для каждого кластера, полученного на предыдущем шаге, затем векторы разбиваются на кластеры вновь в соответствии с тем, какой из новых центров оказался ближе по выбранной метрике.&lt;br /&gt;
&lt;br /&gt;
Цель алгоритма заключается в разделении &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; наблюдений на &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластеров таким образом, чтобы каждое наблюдение принадлежало ровно одному кластеру, расположенному на наименьшем расстоянии от наблюдения.&lt;br /&gt;
&lt;br /&gt;
=== Математическое описание алгоритма ===&lt;br /&gt;
&amp;lt;b&amp;gt;&amp;lt;u&amp;gt;Дано:&amp;lt;/u&amp;gt;&amp;lt;/b&amp;gt;&lt;br /&gt;
* набор из &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; наблюдений &amp;lt;math&amp;gt;X=\{\mathbf{x}_1, \mathbf{x}_2, ..., \mathbf{x}_n\}, \mathbf{x}_i \in \mathbb{R}^d, i=\overline{1, n}&amp;lt;/math&amp;gt;;&lt;br /&gt;
* &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; - требуемое число кластеров, &amp;lt;math&amp;gt;k \in \mathbb{N}, k \leq n&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;&amp;lt;u&amp;gt;Требуется:&amp;lt;/u&amp;gt;&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Разделить множество наблюдений &amp;lt;math&amp;gt;X&amp;lt;/math&amp;gt; на &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластеров &amp;lt;math&amp;gt;S_1, S_2, ..., S_k&amp;lt;/math&amp;gt;:&lt;br /&gt;
*   &amp;lt;math&amp;gt;S_i \cap S_j= \varnothing, \quad i \ne j&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
*   &amp;lt;math&amp;gt;\bigcup_{i=1}^{k} S_i = X&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;&amp;lt;u&amp;gt;Действие алгоритма:&amp;lt;/u&amp;gt;&amp;lt;/b&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;Алгоритм &amp;lt;i&amp;gt;k means&amp;lt;/i&amp;gt; разбивает набор &amp;lt;math&amp;gt;X&amp;lt;/math&amp;gt; на &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; наборов &amp;lt;math&amp;gt;S_1, S_2, ..., S_k,&amp;lt;/math&amp;gt; таким образом, чтобы минимизировать сумму квадратов расстояний от каждой точки кластера до его центра (центр масс кластера). Введем обозначение, &amp;lt;math&amp;gt;S=\{S_1, S_2, ..., S_k\}&amp;lt;/math&amp;gt;. Тогда действие алгоритма &amp;lt;i&amp;gt;k means&amp;lt;/i&amp;gt; равносильно поиску:&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;table style=&amp;quot;width:100%&amp;quot;&amp;gt;&lt;br /&gt;
  &amp;lt;tr&amp;gt;&lt;br /&gt;
    &amp;lt;td align=&amp;quot;center&amp;quot; width=&amp;quot;90%&amp;quot;&amp;gt;&amp;lt;math&amp;gt;\arg\min_{S} \sum\limits_{i=1}^k \sum\limits_{\mathbf{x} \in S_i} \rho(\mathbf{x}, \mathbf{\mu}_i )^2,&amp;lt;/math&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;td align=&amp;quot;right&amp;quot;&amp;gt;&amp;lt;math&amp;gt;(1)&amp;lt;/math&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;/table&amp;gt;&lt;br /&gt;
где &amp;lt;math&amp;gt;\mathbf{\mu}_i&amp;lt;/math&amp;gt; &amp;amp;ndash; центры кластеров, &amp;lt;math&amp;gt;i=\overline{1,k}, \quad \rho(\mathbf{x}, \mathbf{\mu}_i)&amp;lt;/math&amp;gt; &amp;amp;ndash; функция расстояния между &amp;lt;math&amp;gt;\mathbf{x}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\mu_i&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;&amp;lt;u&amp;gt;Шаги алгоритма: &amp;lt;/u&amp;gt;&amp;lt;/b&amp;gt;&lt;br /&gt;
&amp;lt;ol&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&lt;br /&gt;
    &amp;lt;b&amp;gt;Начальный шаг: инициализация кластеров&amp;lt;/b&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;Выбирается произвольное множество точек &amp;lt;math&amp;gt;\mu_i, i=\overline{1,k}&amp;lt;/math&amp;gt;, рассматриваемых как начальные центры кластеров: &amp;lt;math&amp;gt;\mu_i^{(0)} = \mu_i, \quad i=\overline{1, k}&amp;lt;/math&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
  &amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&lt;br /&gt;
    &amp;lt;b&amp;gt;Распределение векторов по кластерам&amp;lt;/b&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Шаг&amp;lt;/b&amp;gt; &amp;lt;math&amp;gt;t: \forall \mathbf{x}_i \in X, i=\overline{1,n}: \mathbf{x}_i \in S_j \iff  j=\arg\min_{k}\rho(\mathbf{x}_i,\mathbf{\mu}_k^{(t-1)})^2&amp;lt;/math&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
  &amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&lt;br /&gt;
    &amp;lt;b&amp;gt;Пересчет центров кластеров&amp;lt;/b&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Шаг &amp;lt;/b&amp;gt; &amp;lt;math&amp;gt;t: \forall i=\overline{1,k}:  \mu_i^{(t)} = \cfrac{1}{|S_i|}\sum_{\mathbf{x}\in S_i}\mathbf{x}&amp;lt;/math&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
  &amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&lt;br /&gt;
    &amp;lt;b&amp;gt;Проверка условия останова:&amp;lt;/b&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
    &#039;&#039;&#039;if&#039;&#039;&#039; &amp;lt;math&amp;gt;\exist i\in \overline{1,k}: \mu_i^{(t)} \ne \mu_i^{(t-1)}&amp;lt;/math&amp;gt; &#039;&#039;&#039;then&#039;&#039;&#039;&lt;br /&gt;
        t = t + 1;&lt;br /&gt;
        goto 2;&lt;br /&gt;
    &#039;&#039;&#039;else&#039;&#039;&#039;&lt;br /&gt;
        &#039;&#039;&#039;stop&#039;&#039;&#039;&lt;br /&gt;
  &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ol&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Вычислительное ядро алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Вычислительным ядром являются шаги 2 и 3 приведенного выше алгоритма: &amp;lt;b&amp;gt;&amp;lt;i&amp;gt;распределение векторов по кластерам&amp;lt;/i&amp;gt;&amp;lt;/b&amp;gt; и &amp;lt;b&amp;gt;&amp;lt;i&amp;gt;пересчет центров кластеров&amp;lt;/i&amp;gt;&amp;lt;/b&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;&amp;lt;i&amp;gt;Распределение векторов&amp;lt;/i&amp;gt;&amp;lt;/b&amp;gt; по кластерам предполагает вычисление расстояний между каждым вектором &amp;lt;math&amp;gt;\mathbf{x}_i \in X, i= \overline{1,n}&amp;lt;/math&amp;gt; и центрами кластера &amp;lt;math&amp;gt;\mathbf{\mu}_j, j= \overline{1,k}&amp;lt;/math&amp;gt;. Таким образом, данный шаг предполагает &amp;lt;math&amp;gt;kn&amp;lt;/math&amp;gt; вычислений расстояний между d-мерными векторами. &lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;&amp;lt;i&amp;gt;Пересчет центров кластеров&amp;lt;/i&amp;gt;&amp;lt;/b&amp;gt; предполагает &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; вычислений центров масс &amp;lt;math&amp;gt;\mathbf{\mu}_i&amp;lt;/math&amp;gt; множеств &amp;lt;math&amp;gt;S_i, i=\overline{1,k}&amp;lt;/math&amp;gt; представленных выражением в шаге 3 представленного выше алгоритма.&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Макроструктура алгоритма ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Инициализация центров масс &amp;lt;math&amp;gt;\mu_1, ..., \mu_k&amp;lt;/math&amp;gt;&amp;lt;/b&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
Наиболее распространенными являются следующие стратегии:&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&lt;br /&gt;
    &amp;lt;b&amp;gt;Метод Forgy&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;В качестве начальных значений &amp;lt;math&amp;gt;\mu_1, ..., \mu_k&amp;lt;/math&amp;gt; берутся случайно выбранные векторы.&lt;br /&gt;
  &amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&lt;br /&gt;
    &amp;lt;b&amp;gt;Метод случайно разделения (Random Partitioning)&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;Для каждого вектора &amp;lt;math&amp;gt;\mathbf{x}_i \in X, i=\overline{1, n}&amp;lt;/math&amp;gt; выбирается случайным образом кластер &amp;lt;math&amp;gt;S_1, ..., S_k&amp;lt;/math&amp;gt;, после чего для каждого полученного кластера вычисляются значения &amp;lt;math&amp;gt;\mu_1, ..., \mu_k&amp;lt;/math&amp;gt;.&lt;br /&gt;
  &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Распределение векторов по кластерам&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Для этого шага алгоритма между векторами &amp;lt;math&amp;gt;\mathbf{x}_i \in X, i=\overline{1, n}&amp;lt;/math&amp;gt; и центрами кластеров &amp;lt;math&amp;gt;\mu_1, ..., \mu_k&amp;lt;/math&amp;gt; вычисляются &amp;lt;b&amp;gt;расстояния&amp;lt;/b&amp;gt; по формуле (как правило, используется Евлидово расстояние):&lt;br /&gt;
&amp;lt;table style=&amp;quot;width:100%&amp;quot;&amp;gt;&lt;br /&gt;
  &amp;lt;tr&amp;gt;&lt;br /&gt;
    &amp;lt;td align=&amp;quot;center&amp;quot; width=&amp;quot;90%&amp;quot;&amp;gt;&amp;lt;math&amp;gt; \mathbf{v}_1, \mathbf{v}_2 \in \mathbb{R}^d,  \quad \rho(\mathbf{v}_1, \mathbf{v}_2) = \lVert \mathbf{v}_1- \mathbf{v}_2 \rVert= \sqrt{\sum_{i=1}^{d}(\mathbf{v}_{1,i} - \mathbf{v}_{2,i})^2}&amp;lt;/math&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;td align=&amp;quot;right&amp;quot;&amp;gt;&amp;lt;math&amp;gt;(2)&amp;lt;/math&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;/table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Пересчет центров кластеров&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Для этого шага алгоритма производится пересчет центров кластера по &amp;lt;b&amp;gt;формуле вычисления центра масс&amp;lt;/b&amp;gt;:&lt;br /&gt;
&amp;lt;table style=&amp;quot;width:100%&amp;quot;&amp;gt;&lt;br /&gt;
  &amp;lt;tr&amp;gt;&lt;br /&gt;
    &amp;lt;td align=&amp;quot;center&amp;quot; width=&amp;quot;90%&amp;quot;&amp;gt;&amp;lt;math&amp;gt; \mu = \cfrac{1}{|S|}\sum_{\mathbf{x}\in S}\mathbf{x}&amp;lt;/math&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;td align=&amp;quot;right&amp;quot;&amp;gt;&amp;lt;math&amp;gt;(3)&amp;lt;/math&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;/table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Схема реализации последовательного алгоритма ===&lt;br /&gt;
&lt;br /&gt;
 &#039;&#039;&#039;algorithm&#039;&#039;&#039; k-means &#039;&#039;&#039;is&#039;&#039;&#039;&lt;br /&gt;
     &#039;&#039;&#039;1.&#039;&#039;&#039; Инициализировать центры кластеров &amp;lt;math&amp;gt;\mathbf{\mu}_i^{(1)}, i=\overline{1,k}&amp;lt;/math&amp;gt;&lt;br /&gt;
     &#039;&#039;&#039;2.&#039;&#039;&#039; &amp;lt;math&amp;gt;t \leftarrow 1&amp;lt;/math&amp;gt;&lt;br /&gt;
     &#039;&#039;&#039;3.&#039;&#039;&#039; &#039;&#039;&#039;Распределение по кластерам&#039;&#039;&#039;&amp;lt;br&amp;gt;&lt;br /&gt;
        &amp;lt;math&amp;gt;S_i^{(t)}=\{\mathbf{x}_p: \lVert\mathbf{x}_p-\mathbf{\mu}_i^{(t)}\rVert^2 \leq \lVert\mathbf{x}_p-\mathbf{\mu}_j^{(t)}\rVert^2 \quad \forall j=\overline{1,k}\},&amp;lt;/math&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
        где каждый вектор &amp;lt;math&amp;gt;\mathbf{x}_p&amp;lt;/math&amp;gt; соотносится единственному кластеру &amp;lt;math&amp;gt;S^{(t)}&amp;lt;/math&amp;gt;&lt;br /&gt;
     &#039;&#039;&#039;4.&#039;&#039;&#039; &#039;&#039;&#039;Обновление центров кластеров&#039;&#039;&#039;&amp;lt;br&amp;gt;&lt;br /&gt;
        &amp;lt;math&amp;gt;\mathbf{\mu}_i^{(t+1)} = \frac{1}{|S^{(t)}_i|} \sum_{\mathbf{x}_j \in S^{(t)}_i} \mathbf{x}_j &amp;lt;/math&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
     &#039;&#039;&#039;5.&#039;&#039;&#039; &#039;&#039;&#039;if&#039;&#039;&#039; &amp;lt;math&amp;gt;\exist i \in \overline{1,k}: \mathbf{\mu}_i^{(t+1)} \ne \mathbf{\mu}_i^{(t)}&amp;lt;/math&amp;gt; &#039;&#039;&#039;then&#039;&#039;&#039;&lt;br /&gt;
            t = t + 1;&lt;br /&gt;
            goto &#039;&#039;&#039;3&#039;&#039;&#039;;&lt;br /&gt;
        &#039;&#039;&#039;else&#039;&#039;&#039;&lt;br /&gt;
            &#039;&#039;&#039;stop&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
=== Последовательная сложность алгоритма===&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding-bottom: 20px&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;Обозначим &amp;lt;math&amp;gt;\Theta_{\rm centroid}^{d, m}&amp;lt;/math&amp;gt; временную сложность вычисления центорида кластера, число элементов которого равна &amp;lt;math&amp;gt;m&amp;lt;/math&amp;gt;,  в d-мерном пространстве.&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;Аналогично  &amp;lt;math&amp;gt;\Theta_{\rm distance}^d&amp;lt;/math&amp;gt; &amp;amp;ndash; временная сложность вычисления расстояния между двумя d-мерными векторами.&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding-bottom: 20px&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;Сложность шага инициализации &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластеров мощности &amp;lt;math&amp;gt;m&amp;lt;/math&amp;gt; в d-мерном пространстве &amp;amp;ndash; &amp;lt;math&amp;gt;\Theta_{\rm init}^{k, d, m}&amp;lt;/math&amp;gt;&amp;lt;/b&amp;gt;&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;i&amp;gt;Стратерия Forgy&amp;lt;/i&amp;gt;: вычисления не требуются, &amp;lt;math&amp;gt;\Theta_{\rm init}^{k, d, m} = 0&amp;lt;/math&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;i&amp;gt;Стратегия случайного разбиения&amp;lt;/i&amp;gt;: вычисление центров &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластеров,  &amp;lt;math&amp;gt;\Theta_{\rm init}^{k, d, m} = k \cdot \Theta_{\rm centroid}^{d, m}, m \le n&amp;lt;/math&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding-bottom: 20px&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Cложность шага распределения d мерных векторов по &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластерам &amp;amp;ndash; &amp;lt;math&amp;gt;\Theta_{\rm distribute}^{k, d}&amp;lt;/math&amp;gt;&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
На этом шаге для каждого вектора &amp;lt;math&amp;gt;\mathbf{x}_i \in X, i=\overline{1, n}&amp;lt;/math&amp;gt; вычисляется k расстояний до центров кластеров &amp;lt;math&amp;gt;\mathbf{\mu}_1, ...\mathbf{\mu}_k&amp;lt;/math&amp;gt;&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p align=&amp;quot;center&amp;quot;&amp;gt;&lt;br /&gt;
  &amp;lt;math&amp;gt;\Theta_{\rm distribute}^{k, d} = n \cdot k \cdot \Theta_{\rm distance}^d&amp;lt;/math&amp;gt;&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding-bottom: 20px&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;Сложность шага пересчета центров &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластеров размера &amp;lt;math&amp;gt;m&amp;lt;/math&amp;gt; в d-мерном пространстве &amp;amp;ndash; &amp;lt;math&amp;gt;\Theta_{\rm recenter}^{k, d, m}&amp;lt;/math&amp;gt;&amp;lt;/b&amp;gt;&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;На этом шаге вычисляется &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; центров кластеров &amp;lt;math&amp;gt;\mathbf{\mu}_1, ...\mathbf{\mu}_k&amp;lt;/math&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p align=&amp;quot;center&amp;quot;&amp;gt;&amp;lt;math&amp;gt;\Theta_{\rm recenter}^{k, d, m} = k \cdot \Theta_{\rm centroid}^{d, m}&amp;lt;/math&amp;gt; &amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding-bottom: 20px&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Рассчитаем &amp;lt;math&amp;gt;\Theta_{\rm centroid}^{d, m}&amp;lt;/math&amp;gt; для кластера, число элементов которого равно &amp;lt;math&amp;gt;m&amp;lt;/math&amp;gt;&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p align=&amp;quot;center&amp;quot;&amp;gt;&amp;lt;math&amp;gt;\Theta_{\rm centroid}^{d, m}&amp;lt;/math&amp;gt; = &amp;lt;math&amp;gt;m \cdot d&amp;lt;/math&amp;gt; сложений + &amp;lt;math&amp;gt;d&amp;lt;/math&amp;gt; делений &amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding-bottom: 20px&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Рассчитаем &amp;lt;math&amp;gt;\Theta_{\rm distance}^d&amp;lt;/math&amp;gt; в соответствие с формулой &amp;lt;math&amp;gt;(2)&amp;lt;/math&amp;gt;&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p align=&amp;quot;center&amp;quot;&amp;gt;&amp;lt;math&amp;gt;\Theta_{\rm distance}^d&amp;lt;/math&amp;gt; = &amp;lt;math&amp;gt;d&amp;lt;/math&amp;gt; вычитаний + &amp;lt;math&amp;gt;d&amp;lt;/math&amp;gt; умножений + &amp;lt;math&amp;gt;(d-1)&amp;lt;/math&amp;gt; сложение&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding-bottom: 20px&amp;quot;&amp;gt;&lt;br /&gt;
  &amp;lt;p&amp;gt;Предположим, что алгоритм сошелся за &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt; итераций, тогда временная сложность алгоритма &amp;lt;math&amp;gt;\Theta_{\rm k-means}^{d, n}&amp;lt;/math&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
  &amp;lt;p align=&amp;quot;center&amp;quot;&amp;gt;&amp;lt;b&amp;gt;&amp;lt;math&amp;gt;\Theta_{\rm k-means}^{d, n} \le \Theta_{\rm init}^{k, d, n} + i(\Theta_{\rm distribute}^{k, d} + \Theta_{\rm recenter}^{k, d, n})&amp;lt;/math&amp;gt;&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding-bottom: 5px&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;Операции сложения/вычитания:&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p align=&amp;quot;center&amp;quot;&amp;gt;&amp;lt;b&amp;gt;&amp;lt;math&amp;gt;\Theta_{\rm k-means}^{d, n} \le knd+ i(kn(2d-1) + knd) = knd+ i(kn(3d-1)) \thicksim O(ikdn)&amp;lt;/math&amp;gt;&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding-bottom: 20px&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;Операции умножения/деления:&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p align=&amp;quot;center&amp;quot;&amp;gt;&amp;lt;b&amp;gt;&amp;lt;math&amp;gt;\Theta_{\rm k-means}^{d, n} \le kd + i(knd + kd) = kd + ikd(n+1) \thicksim O(ikdn) &amp;lt;/math&amp;gt;&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding-bottom: 20px&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;Получаем, что &amp;lt;b&amp;gt;временная сложность&amp;lt;/b&amp;gt; алгоритма &amp;lt;b&amp;gt;k means&amp;lt;/b&amp;gt; кластеризации &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; &amp;lt;b&amp;gt;d-мерных&amp;lt;/b&amp;gt; векторов на &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластеров за &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt; итераций:&amp;lt;/p&amp;gt;&lt;br /&gt;
 &amp;lt;p align=&amp;quot;center&amp;quot;&amp;gt;&amp;lt;b&amp;gt;&amp;lt;math&amp;gt; \Theta_{\rm k-means}^{d, n} \thicksim O(ikdn) &amp;lt;/math&amp;gt;&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Информационный граф ===&lt;br /&gt;
&lt;br /&gt;
Рассмотрим информационный граф алгоритма. Алгоритм &amp;lt;i&amp;gt;k means&amp;lt;/i&amp;gt; начинается с этапа инициализации, после которого следуют итерации, на каждой из которых выполняется два последовательных шага (см. [[#Схема реализации последовательного алгоритма|&amp;quot;Схема реализации последовательного алгоритма&amp;quot;]]): &lt;br /&gt;
* распределение векторов по кластерам&lt;br /&gt;
* перерасчет центров кластеров&lt;br /&gt;
&lt;br /&gt;
Поскольку основная часть вычислений приходится на шаги итераций, распишем информационные графы данных шагов.&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Распределение векторов по кластерам&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
Информационный граф шага распределения векторов по кластерам представлен на &#039;&#039;рисунке 1&#039;&#039;. Исходами данного графа является исходные векторы &amp;lt;math&amp;gt;\mathbf{x}_1, ..., \mathbf{x}_n&amp;lt;/math&amp;gt;, а также центры кластеров &amp;lt;math&amp;gt;\mathbf{\mu}_1, ... \mathbf{\mu}_k&amp;lt;/math&amp;gt;, вычисленные ранее (на шаге инициализации, если рассматривается первая итерация алгоритма, или на шаге пересчета центров кластеров предыдущей итерации в противном случае). Каждая пара векторов данных &amp;lt;math&amp;gt;\mathbf{x}_i, i=\overline{1,n}&amp;lt;/math&amp;gt; и центров кластера &amp;lt;math&amp;gt;\mathbf{\mu}_j, j=\overline{1, k}&amp;lt;/math&amp;gt; : (&amp;lt;math&amp;gt;\mathbf{x}_i&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;\mathbf{\mu}_j&amp;lt;/math&amp;gt;) подаются на независимые узлы &amp;lt;i&amp;gt;&amp;quot;d&amp;quot;&amp;lt;/i&amp;gt; вычисления расстояния между векторами (более подробная схема вычисления расстояния представлена далее, &#039;&#039;рисунок 2&#039;&#039;). Далее узлы вычисления расстояния &amp;lt;i&amp;gt;&amp;quot;d&amp;quot;&amp;lt;/i&amp;gt;, соответствующие одному и тому же исходному вектору &amp;lt;math&amp;gt;\mathbf{x}_i&amp;lt;/math&amp;gt; передаются на один узел &amp;lt;i&amp;gt;&amp;quot;m&amp;quot;&amp;lt;/i&amp;gt;, где далее происходит вычисление новой метки кластера для каждого вектора &amp;lt;math&amp;gt;\mathbf{x}_i&amp;lt;/math&amp;gt; (берется кластер с минимальным результатом вычисления расстояния). На выходе графа выдаются метки кластеров , &amp;lt;math&amp;gt;L_1, ..., L_n&amp;lt;/math&amp;gt;, такие что &amp;lt;math&amp;gt;\forall \mathbf{x}_i, i=\overline{1, n}, \mathbf{x}_i \in S_j \Leftrightarrow L_i = j&amp;lt;/math&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
[[file:Clusterization.png|thumb|center|800px|Рис. 1. Схема распределения векторов по кластерам. &#039;&#039;d&#039;&#039; &amp;amp;ndash; вычисление расстояния между векторами; &#039;&#039;m&#039;&#039; &amp;amp;ndash; вычисление минимума.]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Вычисление расстояния между векторами&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
Подробная схема вычисления расстояния между векторами &amp;lt;math&amp;gt;\mathbf{x}_i, \mathbf{\mu}_j&amp;lt;/math&amp;gt; представлена на &#039;&#039;рисунке 2&#039;&#039;. Как показано на графе, узел вычисления расстояния между векторами &amp;lt;i&amp;gt;&amp;quot;d&amp;quot;&amp;lt;/i&amp;gt; состоит из шага взятия разности между векторами (узел &amp;quot;&amp;lt;math&amp;gt;-&amp;lt;/math&amp;gt;&amp;quot;) и взятия нормы получившегося вектора разности (узел &amp;quot;&amp;lt;math&amp;gt;||\cdot||^2&amp;lt;/math&amp;gt;&amp;quot;). Более подробно, вычисление расстояния между векторами &amp;lt;math&amp;gt;\mathbf{x}_i = {x_{i1,}, ...,{x_{in}}}, \mathbf{\mu}_j = {\mu_{j1}, ...,\mu_{jn}}&amp;lt;/math&amp;gt; может быть представлено как вычисление разности между каждой парой компонент &amp;lt;math&amp;gt;(x_{iz}, \mu_{jz}), z=\overline{1, d}&amp;lt;/math&amp;gt; (узел &amp;quot;&amp;lt;math&amp;gt;-&amp;lt;/math&amp;gt;&amp;quot;), далее возведение в квадрат для каждого узла &amp;quot;&amp;lt;math&amp;gt;-&amp;lt;/math&amp;gt;&amp;quot; (узел &amp;quot;&amp;lt;math&amp;gt;()^2&amp;lt;/math&amp;gt;&amp;quot;) и суммирования выходов всех узлов &amp;quot;&amp;lt;math&amp;gt;()^2&amp;lt;/math&amp;gt;&amp;quot; (узел &amp;quot;&amp;lt;math&amp;gt;+&amp;lt;/math&amp;gt;&amp;quot;).  &lt;br /&gt;
&lt;br /&gt;
[[file:dist_calc.png|thumb|center|800px|Рис. 2. Схема вычисления расстояния между вектором и центром кластера.]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Пересчет центров кластеров&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
Информационный граф шага пересчета центров кластеров представлен на &#039;&#039;рисунке 3&#039;&#039;. Исходами данного графа является исходные векторы &amp;lt;math&amp;gt;\mathbf{x}_1, ..., \mathbf{x}_n&amp;lt;/math&amp;gt;, а также им соответствующие метки кластера, &amp;lt;math&amp;gt;L_1, ..., L_n&amp;lt;/math&amp;gt;, такие что &amp;lt;math&amp;gt;\forall x_i, i=\overline{1, n}, \mathbf{x}_i \in S_j \Leftrightarrow L_i = j&amp;lt;/math&amp;gt;, вычисленные на этапе распределения векторов по кластерам. Все векторы &amp;lt;math&amp;gt;\mathbf{x}_1, ..., \mathbf{x}_n&amp;lt;/math&amp;gt; подаются в узлы &amp;lt;math&amp;gt;+_1, ...+_k&amp;lt;/math&amp;gt;, каждый узел &amp;lt;math&amp;gt;+_m, m = \overline{1,k}&amp;lt;/math&amp;gt; соответствует операции сложения векторов кластера с номером &amp;lt;math&amp;gt;m&amp;lt;/math&amp;gt;. Метки кластера &amp;lt;math&amp;gt;L_1, ..., L_n&amp;lt;/math&amp;gt; также совместно передаются на узлы &amp;lt;math&amp;gt;S_m, m = \overline{1,k}&amp;lt;/math&amp;gt;, на каждом из которых вычисляется количество векторов в соответствующем кластере (количество меток с соответствующим значением). Далее каждая пара выходов узлов &amp;lt;math&amp;gt;+_m&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;S_m&amp;lt;/math&amp;gt; подается на узел &amp;quot;&amp;lt;math&amp;gt;/&amp;lt;/math&amp;gt;&amp;quot;, где производится деление суммы векторов кластера на количество элементов в нем. Значения, вычисленные на узлах &amp;quot;&amp;lt;math&amp;gt;/&amp;lt;/math&amp;gt;&amp;quot;, присваиваются новым центрам кластеров (выходные значения графа).&lt;br /&gt;
&lt;br /&gt;
[[file:Recluster.png|thumb|center|800px|Рис. 3. Схема пересчета центров кластеров]]&lt;br /&gt;
&lt;br /&gt;
=== Ресурс параллелизма алгоритма ===&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
Работа алгоритма состоит из &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt; итераций, в каждой из которых происходит &amp;lt;b&amp;gt;распределение d-мерных векторов по &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластерам&amp;lt;/b&amp;gt;, а также &amp;lt;b&amp;gt;пересчет центров кластеров в d-мерном пространстве&amp;lt;/b&amp;gt;. В шаге &amp;lt;b&amp;gt;распределения d-мерных векторов по &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластерам&amp;lt;/b&amp;gt; расстояния между вектором и центрами кластеров вычисляются независимо (отсутствуют информационные зависимости). &amp;lt;b&amp;gt;Центры масс кластеров&amp;lt;/b&amp;gt; также пересчитываются независимо друг от друга. Таким образом, имеет место [[глоссарий#Массовый параллелизм|&#039;&#039;массовый параллелизм&#039;&#039;]]. Вычислим параллельную сложность &amp;lt;math&amp;gt;\Psi_*&amp;lt;/math&amp;gt; каждого из шагов, а также параллельную сложность всего алгоритма, &amp;lt;math&amp;gt;\Psi_{\rm k-means}&amp;lt;/math&amp;gt;. Будем исходить из предположения, что может быть использовано любое необходимое число потоков.&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Распределение d-мерных векторов по &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластерам&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;  &lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
Поскольку на данном шаге для каждой пары векторов &amp;lt;math&amp;gt;\mathbf{x}_i, i=\overline{1,n}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\mathbf{\mu}_j, j=\overline{1,k}&amp;lt;/math&amp;gt; операции вычисления расстояния не зависят друг от друга, они могут выполняться параллельно. Тогда, разделив все вычисление расстояний на &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; потоков, получим, что в каждом потоке будет выполняться только одна операция вычисления расстояния между векторами размерности d. При этом каждому вычислительному потоку передаются координаты центров всех кластеров &amp;lt;math&amp;gt;\mathbf{\mu}_1, ..., \mathbf{\mu}_k&amp;lt;/math&amp;gt;. Таким образом, параллельная сложность данного шага определяется &amp;lt;i&amp;gt; сложностью параллельной операции вычисления расстояния между d-мерными векторами&amp;lt;/i&amp;gt;, &amp;lt;math&amp;gt;\Psi_{\rm distance}^d&amp;lt;/math&amp;gt;  и &amp;lt;i&amp;gt;сложностью определения наиболее близкого кластера&amp;lt;/i&amp;gt; (паралельное взятие минимума по расстояниям), &amp;lt;math&amp;gt;\Psi_{\rm min}^k&amp;lt;/math&amp;gt;. Для оценки &amp;lt;math&amp;gt;\Psi_{\rm distance}^d&amp;lt;/math&amp;gt; воспользуемся  [[Нахождение_частных_сумм_элементов_массива_сдваиванием | параллельной реализацией нахождения частичной суммы элементов массива путем сдваивания]]. Аналогично, &amp;lt;math&amp;gt;\Psi_{\rm min}^k = log(k)&amp;lt;/math&amp;gt;. В результате, &amp;lt;math&amp;gt;\Psi_{\rm distance}^d = O(log(d))&amp;lt;/math&amp;gt;.   Таким образом: &lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p align=&amp;quot;center&amp;quot;&amp;gt;&amp;lt;math&amp;gt;\Psi_{\rm distribute}^{k, d}  = \Psi_{\rm distance}^d + \Psi_{\rm min}^k = O(log(d))+O(log(k)) = O(log(kd))&amp;lt;/math&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Пересчет центров кластеров в d-мерном пространстве&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
Поскольку на данном шаге для каждого из &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластеров центр масс может быть вычислен независимо, данные операции могут быть выполнены в отдельных потоках. Таким образом, параллельная сложность данного шага, &amp;lt;math&amp;gt;\Psi_{\rm recenter}^{k, d}&amp;lt;/math&amp;gt;,  будет определяться &amp;lt;i&amp;gt;параллельной сложностью вычисления одного центра масс кластера размера &amp;lt;math&amp;gt;m&amp;lt;/math&amp;gt;&amp;lt;/i&amp;gt;, &amp;lt;math&amp;gt;\Psi_{\rm recenter}^{k, d}&amp;lt;/math&amp;gt;,  а так как &amp;lt;math&amp;gt;m \le n \Rightarrow \Psi_{\rm recenter}^{d, m} \le \Psi_{\rm recenter}^{d, n}&amp;lt;/math&amp;gt;. Сложность вычисления центра масс кластера d-мерных векторов размера n аналогично предыдущим вычислениям равна &amp;lt;math&amp;gt;O(log(n))&amp;lt;/math&amp;gt;. Тогда:  &lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p align=&amp;quot;center&amp;quot;&amp;gt;&amp;lt;math&amp;gt;\Psi_{\rm recenter}^{k, d}  \le \Psi_{\rm recenter}^{d, n} = O(log(n))&amp;lt;/math&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Общая параллельная сложность алгоритма&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
На каждой итерации необходимо обновление центров кластеров, которые будут использованы на следующей итерации. Таким образом, итерационный процесс выполняется последовательно&amp;lt;ref&amp;gt;Zhao, Weizhong, Huifang Ma, and Qing He. &amp;quot;Parallel k-means clustering based on mapreduce.&amp;quot; IEEE International Conference on Cloud Computing. Springer Berlin Heidelberg, 2009.&amp;lt;/ref&amp;gt;. Тогда, поскольку сложность каждой итерации  определяется &amp;lt;math&amp;gt;\Psi_{\rm distribute}^{k, d}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\Psi_{\rm recenter}&amp;lt;/math&amp;gt;, сложность всего алгоритма, &amp;lt;math&amp;gt;\Psi_{\rm k-means}&amp;lt;/math&amp;gt; в предположении, что было сделано &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt; операций определяется выражением&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p align=&amp;quot;center&amp;quot;&amp;gt;&amp;lt;math&amp;gt;\Psi_{\rm k-means} \approx i \cdot (\Psi_{\rm distribute}^{k, d} + \Psi_{\rm recenter}^{k, d}) \le i \cdot O(log(kdn))&amp;lt;/math&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Входные и выходные данные алгоритма ===&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;Входные данные&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;Матрица из &amp;lt;math&amp;gt;n \cdot d&amp;lt;/math&amp;gt; элементов &amp;lt;math&amp;gt;x_{i, j} \in \mathbb{R}, i=\overline{1, n}, j=\overline{1, d}&amp;lt;/math&amp;gt;&amp;amp;ndash; координат векторов (наблюдений).&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;Целое положительное число &amp;lt;math&amp;gt;k, k \le n&amp;lt;/math&amp;gt; &amp;amp;ndash; количество кластеров.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;Объем входных данных&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;math&amp;gt;1&amp;lt;/math&amp;gt; целое число + &amp;lt;math&amp;gt;n \cdot d&amp;lt;/math&amp;gt; вещественных чисел (при условии, что координаты &amp;amp;ndash; вещественные числа).&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;Выходные данные&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; целых положительных чисел &amp;lt;math&amp;gt;L_1, ..., L_n&amp;lt;/math&amp;gt;&amp;amp;ndash; номера кластеров, соотвествующие каждому вектору (при условии, что нумерация кластеров начинается с &amp;lt;math&amp;gt;1&amp;lt;/math&amp;gt;).&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;Объем выходных данных&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; целых положительных чисел.&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Свойства алгоритма ===&lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;[[глоссарий#Вычислительная мощность|&#039;&#039;Вычислительная мощность&#039;&#039;]]&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
Вычислительная мощность алгоритма &amp;lt;i&amp;gt;k means&amp;lt;/i&amp;gt; равна &amp;lt;math&amp;gt;\frac{ikdn}{nd} = ki &amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; &amp;amp;ndash; число кластеров, &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt; &amp;amp;ndash; число итераций алгоритма.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;[[глоссарий#Детерминированность |&#039;&#039;Детерминированность&#039;&#039;]] и [[глоссарий#Устойчивость |&#039;&#039;Устойчивость&#039;&#039;]] &amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
Алгоритм &amp;lt;i&amp;gt;k means&amp;lt;/i&amp;gt; является итерационным. Количество итераций алгоритма в общем случае не фиксируется и зависит от начального расположения объектов в пространстве, параметра &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt;, а также от начального приближения центров кластеров, &amp;lt;math&amp;gt;\mu_1, ..., \mu_k&amp;lt;/math&amp;gt;. В результате этого может варьироваться результат работы алгоритма. При неудачном выборе начальных параметров итерационный процесс может сойтись к локальному оптимуму&amp;lt;ref&amp;gt;Von Luxburg, Ulrike. Clustering Stability. Now Publishers Inc, 2010.&amp;lt;/ref&amp;gt;. По этим причинам алгоритм не является ни &amp;lt;b&amp;gt;детермирированным&amp;lt;/b&amp;gt;, ни &amp;lt;b&amp;gt;устойчивым&amp;lt;/b&amp;gt;.&lt;br /&gt;
 &lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Соотношение последовательной и параллельной сложности алгоритма&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\frac{\Theta_{\rm k-means}}{\Psi_{\rm k-means}} = \frac{O(ikdn)}{O(i \cdot log(kdn))}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Сильные стороны алгоритма&amp;lt;/b&amp;gt;:&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;i&amp;gt;Сравнительно высокая эффективность при простоте реализации&amp;lt;/i&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;i&amp;gt;Высокое качество кластеризации&amp;lt;/i&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;i&amp;gt;Возможность распараллеливания&amp;lt;/i&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;i&amp;gt;Существование множества модификаций&amp;lt;/i&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;Недостатки алгоритма&amp;lt;/b&amp;gt;&amp;lt;ref&amp;gt;Ortega, Joaquín Pérez, Ma Del Rocío Boone Rojas, and María J. Somodevilla. &amp;quot;Research issues on K-means Algorithm: An Experimental Trial Using Matlab.&amp;quot;&amp;lt;/ref&amp;gt;:&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;i&amp;gt;Количество кластеров является параметром алгоритма&amp;lt;/i&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;&amp;lt;i&amp;gt;Чувствительность к начальным условиям&amp;lt;/i&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;Инициализация центров кластеров в значительной степени влияет на результат кластеризации.&amp;lt;/p&amp;gt;&lt;br /&gt;
  &amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;&amp;lt;i&amp;gt;Чувствительность к выбросам и шумам&amp;lt;/i&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;Выбросы, далекие от центров настоящих кластеров, все равно учитываются при вычислении их центров.&amp;lt;/p&amp;gt;&lt;br /&gt;
  &amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;&amp;lt;i&amp;gt;Возможность сходимости к локальному оптимуму&amp;lt;/i&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;Итеративный подход не дает гарантии сходимости к оптимальному решению.&amp;lt;/p&amp;gt;&lt;br /&gt;
  &amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;&amp;lt;i&amp;gt;Использование понятия &amp;quot;среднего&amp;quot;&amp;lt;/i&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;Алгоритм неприменим к данным, для которых не определено понятие &amp;quot;среднего&amp;quot;, например, категориальным данным.&amp;lt;/p&amp;gt;&lt;br /&gt;
  &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&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;
Исследование масштабируемости параллельной реализации алгоритма k means проводилось на суперкомпьютере &amp;quot;Ломоносов&amp;quot;&amp;lt;ref name=&amp;quot;Lom&amp;quot;&amp;gt;Воеводин Вл., Жуматий С., Соболев С., Антонов А., Брызгалов П., Никитенко Д., Стефанов К., Воеводин Вад. Практика суперкомпьютера «Ломоносов» // Открытые системы, 2012, N 7, С. 36-39.&amp;lt;/ref&amp;gt; [http://parallel.ru/cluster Суперкомпьютерного комплекса Московского университета]. Алгоритм реализован на языке C с использованием средств MPI.&lt;br /&gt;
Для исследования масштабируемости проводилось множество запусков программы с разным значением параметра (количество векторов для кластеризации), а также с различным числом процессоров. Фиксировались результаты запусков &amp;amp;ndash; время работы &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt; и количество произведенных итераций алгоритма &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Параметры запусков для экспериментальной оценки:&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;Значения &amp;lt;b&amp;gt;количества векторов&amp;lt;/b&amp;gt; &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;: 20&#039;000, 30&#039;000, 50&#039;000, 100&#039;000, 200&#039;000, 300&#039;000, 500&#039;000, 700&#039;000, 1&#039;000&#039;000, 1&#039;500&#039;000, 2&#039;000&#039;000.&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;Значения &amp;lt;b&amp;gt;количества процессоров&amp;lt;/b&amp;gt; &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt;: 1, 8, 16, 32, 64, 128, 160, 192, 224, 256, 288, 320, 352, 384, 416, 448, 480, 512.&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;Значение &amp;lt;b&amp;gt;количества кластеров&amp;lt;/b&amp;gt; &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt;: 100.&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;Значение &amp;lt;b&amp;gt;размерности векторов&amp;lt;/b&amp;gt; &amp;lt;math&amp;gt;d&amp;lt;/math&amp;gt;: 10.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Для проведения экспериментов были сгенерированы нормально распределенные псевдослучайные данные (с использованием Python библиотеки [http://scikit-learn.org/ scikit-learn]):&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
from sklearn.datasets import make_classification&lt;br /&gt;
X1, Y1 = make_classification(n_features=10, n_redundant=2, n_informative=8,&lt;br /&gt;
                             n_clusters_per_class=1, n_classes=100,&lt;br /&gt;
                             n_samples=2000000)&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Для заданной конфигурации эксперимента (&amp;lt;math&amp;gt;n, d, p, k&amp;lt;/math&amp;gt;) и полученных результатов (&amp;lt;math&amp;gt;t, i&amp;lt;/math&amp;gt;)  [[Глоссарий#Производительность|производительность]]  и эффективность реализации расчитывались по формулам:&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
&amp;lt;ul&amp;gt;&amp;lt;li&amp;gt;&amp;lt;math&amp;gt;Performance = \frac{N_{\rm k-means}^{d, n}}{t}\ \ (FLOPS),&amp;lt;/math&amp;gt;&amp;lt;/li&amp;gt;&amp;lt;/ul&amp;gt;&lt;br /&gt;
где &amp;lt;math&amp;gt;N_{\rm k-means}^{d, n}&amp;lt;/math&amp;gt; &amp;amp;ndash; точное число операций с плавающей точкой (операции с памятью, а также целочисленные операции не учитывались), вычисленное в соответствие с разделом [[#Последовательная сложность алгоритма| &amp;quot;Последовательная сложность алгоритма&amp;quot;]];&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
&amp;lt;ul&amp;gt;&amp;lt;li&amp;gt;&amp;lt;math&amp;gt;\rm Efficiency = \frac{100 \cdot Performance}{Performance_{\rm Peak}^{p}}\ \ (%),&amp;lt;/math&amp;gt;&amp;lt;/li&amp;gt;&amp;lt;/ul&amp;gt;&lt;br /&gt;
где &amp;lt;math&amp;gt;\rm Performance_{\rm Peak}^{p}&amp;lt;/math&amp;gt; &amp;amp;ndash; пиковая производительность суперкомпьютера при &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt; процессорах, вычисленная согласно спецификациям Intel&amp;lt;sup&amp;gt;&amp;amp;reg;&amp;lt;/sup&amp;gt; XEON&amp;lt;sup&amp;gt;&amp;amp;reg;&amp;lt;/sup&amp;gt; X5670&amp;lt;ref&amp;gt;&amp;quot;http://ark.intel.com/ru/products/47920/Intel-Xeon-Processor-X5670-12M-Cache-2_93-GHz-6_40-GTs-Intel-QPI&amp;quot;&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Графики зависимости производительности и эффективности параллельной реализации k means от числа векторов для кластеризации (&amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;) и числа процессоров (&amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt;) представлены на рисунках 4 и 5 соответственно.&lt;br /&gt;
&lt;br /&gt;
[[file:Flops.png|thumb|center|800px|Рис. 4. Параллельная реализация k means. График зависимости производительности реализации алгоритма от числа векторов для кластеризации (&amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;) и числа процессоров (&amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt;).]]&lt;br /&gt;
[[file:Efficiency.png|thumb|center|800px|Рис. 5. Параллельная реализация k means. График зависимости эффективности реализации алгоритма от числа векторов для кластеризации (&amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;) и числа процессоров (&amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt;).]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;В результате&amp;lt;/b&amp;gt; экспериментальной оценки были получены следующие оценки эффективности реализации:&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;b&amp;gt;Минимальное&amp;lt;/b&amp;gt; значение: 0.000409 % достигается при &amp;lt;math&amp;gt;n=20&#039;000, p=480&amp;lt;/math&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;b&amp;gt;Максимальное&amp;lt;/b&amp;gt; значение: 0.741119 % достигается при &amp;lt;math&amp;gt;n=300&#039;000, p=1&amp;lt;/math&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
Оценки масштабируемости реализации алгоритма k means:&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;b&amp;gt;По числу процессоров:&amp;lt;/b&amp;gt; -0.002683 &amp;amp;ndash; эффективность убывает с ростом числа процессоров. Данный результат вызван ростом накладных расходов для обеспечения параллельного выполнения алгоритма.&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;b&amp;gt;По размеру задачи:&amp;lt;/b&amp;gt; 0.002779 &amp;amp;ndash; эффективность растет с ростом числа векторов. Данный результат вызван тем, что при увеличении размера задачи, количество вычислений растет по сравнению с временем, затрачиваемым на пересылку данных.&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;b&amp;gt;Общая оценка:&amp;lt;/b&amp;gt; -0.000058 &amp;amp;ndash; можно сделать вывод, что в целом эффективность реализации незначительно уменьшается с ростом размера задачи и числа процессоров.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[https://github.com/serban/kmeans Использованная параллельная реализация алгоритма k means]&lt;br /&gt;
&lt;br /&gt;
=== Динамические характеристики и эффективность реализации алгоритма ===&lt;br /&gt;
=== Выводы для классов архитектур ===&lt;br /&gt;
=== Существующие реализации алгоритма ===&lt;br /&gt;
==== Открытое программное обеспечение ====&lt;br /&gt;
&amp;lt;ol&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;[https://www.icpsr.umich.edu/CrimeStat/ CrimeStat]&amp;lt;/li&amp;gt; Программное обеспечение, созданное для операционных систем Windows, предоставляющее инструменты статистического  и пространственного анализа для решения задачи картирования преступности.&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://juliastats.github.io Julia]&amp;lt;/li&amp;gt; Высокоуровневый высокопроизводительный свободный язык программирования с динамической типизацией, созданный для математических вычислений, содержит реализацию k-means.&lt;br /&gt;
  &amp;lt;li&amp;gt;[https://mahout.apache.org Mahout]&amp;lt;/li&amp;gt; Apache Mahout - Java библиотека для работы с алгоритмами машинного обучения с использованием MapReduce. Содержит реализацию k-means.&lt;br /&gt;
  &amp;lt;li&amp;gt;[https://www.gnu.org/software/octave/ Octave]&amp;lt;/li&amp;gt; Написанная на C++  свободная система для математических вычислений, использующая совместимый с MATLAB язык высокого уровня, содержит реализацию k-means.&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://spark.apache.org/docs/latest/mllib-clustering.html Spark]&amp;lt;/li&amp;gt; Распределенная реализация k-means содержится в библиотеке Mlib для работы с алгоритмами машинного обучения, взаимодействующая с Python библиотекой NumPy и библиотека R.&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://torch.ch Torch]&amp;lt;/li&amp;gt;  MATLAB-подобная библиотека для языка программирования Lua с открытым исходным кодом, предоставляет большое количество алгоритмов для глубинного обучения и научных расчётов. Ядро написано на Си, прикладная часть выполняется на LuaJIT, поддерживается распараллеливание вычислений средствами CUDA и OpenMP. Существуют реализации k-means.&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://www.cs.waikato.ac.nz/ml/weka/ Weka]&amp;lt;/li&amp;gt;  Cвободное программное обеспечение для анализа данных, написанное на Java. Содержит k-means и x-means.&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://accord-framework.net/docs/html/T_Accord_MachineLearning_KMeans.htm Accord.NET]&amp;lt;/li&amp;gt; C# реализация алгоритмов k-means, k-means++, k-modes.&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://docs.opencv.org/3.0-beta/doc/py_tutorials/py_ml/py_kmeans/py_kmeans_opencv/py_kmeans_opencv.html OpenCV]&amp;lt;/li&amp;gt; Написанная на С++ библиотека, направленная в основном на решение задач компьютерного зрения. Содержит реализацию k-means.&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://mlpack.org/ MLPACK]&amp;lt;/li&amp;gt; Масштабируемая С++ библиотека для работы с алгоритмами машинного обучения, содержит реализацию k-means.&lt;br /&gt;
  &amp;lt;li&amp;gt;[https://www.scipy.org/ SciPy]&amp;lt;/li&amp;gt; Библиотека Python, содержит множество реализаций k-means.&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://scikit-learn.org/ scikit-learn]&amp;lt;/li&amp;gt; Библиотека Python, содержит множество реализаций k-means.&lt;br /&gt;
  &amp;lt;li&amp;gt;[https://www.r-bloggers.com/k-means-clustering-in-r/ R]&amp;lt;/li&amp;gt; Язык программирования для статистической обработки данных и работы с графикой, а также свободная программная среда вычислений с открытым исходным кодом в рамках проекта GNU, содержит три реализации k-means.&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://elki.dbs.ifi.lmu.de ELKI]&amp;lt;/li&amp;gt; Java фреймворк, содержащий реализацию k-means, а также множество других алгоритмов кластеризации.&lt;br /&gt;
&amp;lt;/ol&amp;gt;&lt;br /&gt;
==== Проприетарное программное обеспечение  ====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ol&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;[https://www.ayasdi.com/blog/bigdata/topological-data-analysis-of-oil-and-gas-petrophysical-data/ Ayasdi]&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://www.stata.com/features/cluster-analysis/ Stata]&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://mathworld.wolfram.com/K-MeansClusteringAlgorithm.html Mathematica]&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://www.mathworks.com/help/stats/kmeans.html?requestedDomain=www.mathworks.com MATLAB]&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;[https://support.sas.com/rnd/app/stat/procedures/fastclus.html SAS]&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://docs.rapidminer.com/studio/operators/modeling/segmentation/k_means.html RapidMiner]&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;[https://blogs.sap.com/2013/03/28/sap-hana-pal-k-means-algorithm-or-how-to-do-customer-segmentation-for-the-telecommunications-industry/ SAP HANA]&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ol&amp;gt;&lt;br /&gt;
== Литература ==&lt;br /&gt;
&amp;lt;references /&amp;gt;&lt;/div&gt;</summary>
		<author><name>DennZo1993</name></author>
	</entry>
	<entry>
		<id>https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:%D0%91%D1%80%D0%BE%D1%82%D0%B8%D0%BA%D0%BE%D0%B2%D1%81%D0%BA%D0%B0%D1%8F_%D0%94%D0%B0%D0%BD%D1%83%D1%82%D0%B0/%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_k-means&amp;diff=20539</id>
		<title>Участник:Бротиковская Данута/Алгоритм k-means</title>
		<link rel="alternate" type="text/html" href="https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:%D0%91%D1%80%D0%BE%D1%82%D0%B8%D0%BA%D0%BE%D0%B2%D1%81%D0%BA%D0%B0%D1%8F_%D0%94%D0%B0%D0%BD%D1%83%D1%82%D0%B0/%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_k-means&amp;diff=20539"/>
		<updated>2016-12-10T11:14:10Z</updated>

		<summary type="html">&lt;p&gt;DennZo1993: /* Масштабируемость алгоритма и его реализации */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Assignment|Zhum}}&lt;br /&gt;
&lt;br /&gt;
{{algorithm&lt;br /&gt;
| name              = Алгоритм k средних (k means)&lt;br /&gt;
| serial_complexity = &amp;lt;math&amp;gt;O(ikdn)&amp;lt;/math&amp;gt;&lt;br /&gt;
| input_data        = &amp;lt;math&amp;gt; dn &amp;lt;/math&amp;gt;&lt;br /&gt;
| output_data       = &amp;lt;math&amp;gt; n &amp;lt;/math&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
Авторы страницы &amp;lt;b&amp;gt;[[Участник:Бротиковская Данута|Данута Бротиковская]]&amp;lt;/b&amp;gt; и &amp;lt;b&amp;gt;[[Участник:DennZo1993|Денис Зобнин]]&amp;lt;/b&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
Оба автора внесли одинаковый вклад в написание статьи (поиск материалов, изучение статей, заполнение контента статьи), четких разграничений по пунктам статьи сделать невозможно. &lt;br /&gt;
&lt;br /&gt;
== Свойства и структура алгоритма ==&lt;br /&gt;
&lt;br /&gt;
=== Общее описание алгоритма ===&lt;br /&gt;
Алгоритм &amp;lt;b&amp;gt;&amp;lt;i&amp;gt;k средних&amp;lt;/i&amp;gt;&amp;lt;/b&amp;gt; (&amp;lt;b&amp;gt;&amp;lt;i&amp;gt;k means&amp;lt;/i&amp;gt;&amp;lt;/b&amp;gt;) &amp;amp;ndash; неиерархический&amp;lt;ref&amp;gt;&amp;quot;https://ru.wikipedia.org/wiki/Иерархическая_кластеризация&amp;quot;&amp;lt;/ref&amp;gt;, итерационный метод кластеризации&amp;lt;ref&amp;gt;&amp;quot;https://ru.wikipedia.org/wiki/Кластерный_анализ&amp;quot;&amp;lt;/ref&amp;gt;, получивший большую популярность благодаря своей простоте, наглядности реализации и достаточно высокому качеству работы. Был изобретен в 1950-х годах математиком &amp;lt;i&amp;gt;Гуго Штейнгаузом&amp;lt;/i&amp;gt;&amp;lt;ref&amp;gt;Steinhaus, Hugo. &amp;quot;Sur la division des corp materiels en parties.&amp;quot; Bull. Acad. Polon. Sci 1.804 (1956): 801.&amp;lt;/ref&amp;gt; и почти одновременно &amp;lt;i&amp;gt;Стюартом Ллойдом&amp;lt;/i&amp;gt;&amp;lt;ref&amp;gt;Lloyd, S. P. &amp;quot;Least square quantization in PCM. Bell Telephone Laboratories Paper. Published in journal much later: Lloyd, SP: Least squares quantization in PCM.&amp;quot; IEEE Trans. Inform. Theor.(1957/1982).&amp;lt;/ref&amp;gt;. Особую популярность приобрел после публикации работы &amp;lt;i&amp;gt;МакКуина&amp;lt;/i&amp;gt;&amp;lt;ref&amp;gt;MacQueen, James. &amp;quot;Some methods for classification and analysis of multivariate observations.&amp;quot; Proceedings of the fifth Berkeley symposium on mathematical statistics and probability. Vol. 1. No. 14. 1967.&amp;lt;/ref&amp;gt; в 1967.&lt;br /&gt;
&lt;br /&gt;
Алгоритм представляет собой версию EM-алгоритма&amp;lt;ref&amp;gt;&amp;quot;https://ru.wikipedia.org/wiki/EM-алгоритм&amp;quot;&amp;lt;/ref&amp;gt;, применяемого также для разделения смеси гауссиан. Основная идея &amp;lt;i&amp;gt;k means&amp;lt;/i&amp;gt; заключается в том, что данные произвольно разбиваются на кластеры, после чего итеративно перевычисляется центр масс для каждого кластера, полученного на предыдущем шаге, затем векторы разбиваются на кластеры вновь в соответствии с тем, какой из новых центров оказался ближе по выбранной метрике.&lt;br /&gt;
&lt;br /&gt;
Цель алгоритма заключается в разделении &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; наблюдений на &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластеров таким образом, чтобы каждое наблюдение принадлежало ровно одному кластеру, расположенному на наименьшем расстоянии от наблюдения.&lt;br /&gt;
&lt;br /&gt;
=== Математическое описание алгоритма ===&lt;br /&gt;
&amp;lt;b&amp;gt;&amp;lt;u&amp;gt;Дано:&amp;lt;/u&amp;gt;&amp;lt;/b&amp;gt;&lt;br /&gt;
* набор из &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; наблюдений &amp;lt;math&amp;gt;X=\{\mathbf{x}_1, \mathbf{x}_2, ..., \mathbf{x}_n\}, \mathbf{x}_i \in \mathbb{R}^d, i=\overline{1, n}&amp;lt;/math&amp;gt;;&lt;br /&gt;
* &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; - требуемое число кластеров, &amp;lt;math&amp;gt;k \in \mathbb{N}, k \leq n&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;&amp;lt;u&amp;gt;Требуется:&amp;lt;/u&amp;gt;&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Разделить множество наблюдений &amp;lt;math&amp;gt;X&amp;lt;/math&amp;gt; на &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластеров &amp;lt;math&amp;gt;S_1, S_2, ..., S_k&amp;lt;/math&amp;gt;:&lt;br /&gt;
*   &amp;lt;math&amp;gt;S_i \cap S_j= \varnothing, \quad i \ne j&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
*   &amp;lt;math&amp;gt;\bigcup_{i=1}^{k} S_i = X&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;&amp;lt;u&amp;gt;Действие алгоритма:&amp;lt;/u&amp;gt;&amp;lt;/b&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;Алгоритм &amp;lt;i&amp;gt;k means&amp;lt;/i&amp;gt; разбивает набор &amp;lt;math&amp;gt;X&amp;lt;/math&amp;gt; на &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; наборов &amp;lt;math&amp;gt;S_1, S_2, ..., S_k,&amp;lt;/math&amp;gt; таким образом, чтобы минимизировать сумму квадратов расстояний от каждой точки кластера до его центра (центр масс кластера). Введем обозначение, &amp;lt;math&amp;gt;S=\{S_1, S_2, ..., S_k\}&amp;lt;/math&amp;gt;. Тогда действие алгоритма &amp;lt;i&amp;gt;k means&amp;lt;/i&amp;gt; равносильно поиску:&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;table style=&amp;quot;width:100%&amp;quot;&amp;gt;&lt;br /&gt;
  &amp;lt;tr&amp;gt;&lt;br /&gt;
    &amp;lt;td align=&amp;quot;center&amp;quot; width=&amp;quot;90%&amp;quot;&amp;gt;&amp;lt;math&amp;gt;\arg\min_{S} \sum\limits_{i=1}^k \sum\limits_{\mathbf{x} \in S_i} \rho(\mathbf{x}, \mathbf{\mu}_i )^2,&amp;lt;/math&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;td align=&amp;quot;right&amp;quot;&amp;gt;&amp;lt;math&amp;gt;(1)&amp;lt;/math&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;/table&amp;gt;&lt;br /&gt;
где &amp;lt;math&amp;gt;\mathbf{\mu}_i&amp;lt;/math&amp;gt; &amp;amp;ndash; центры кластеров, &amp;lt;math&amp;gt;i=\overline{1,k}, \quad \rho(\mathbf{x}, \mathbf{\mu}_i)&amp;lt;/math&amp;gt; &amp;amp;ndash; функция расстояния между &amp;lt;math&amp;gt;\mathbf{x}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\mu_i&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;&amp;lt;u&amp;gt;Шаги алгоритма: &amp;lt;/u&amp;gt;&amp;lt;/b&amp;gt;&lt;br /&gt;
&amp;lt;ol&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&lt;br /&gt;
    &amp;lt;b&amp;gt;Начальный шаг: инициализация кластеров&amp;lt;/b&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;Выбирается произвольное множество точек &amp;lt;math&amp;gt;\mu_i, i=\overline{1,k}&amp;lt;/math&amp;gt;, рассматриваемых как начальные центры кластеров: &amp;lt;math&amp;gt;\mu_i^{(0)} = \mu_i, \quad i=\overline{1, k}&amp;lt;/math&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
  &amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&lt;br /&gt;
    &amp;lt;b&amp;gt;Распределение векторов по кластерам&amp;lt;/b&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Шаг&amp;lt;/b&amp;gt; &amp;lt;math&amp;gt;t: \forall \mathbf{x}_i \in X, i=\overline{1,n}: \mathbf{x}_i \in S_j \iff  j=\arg\min_{k}\rho(\mathbf{x}_i,\mathbf{\mu}_k^{(t-1)})^2&amp;lt;/math&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
  &amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&lt;br /&gt;
    &amp;lt;b&amp;gt;Пересчет центров кластеров&amp;lt;/b&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Шаг &amp;lt;/b&amp;gt; &amp;lt;math&amp;gt;t: \forall i=\overline{1,k}:  \mu_i^{(t)} = \cfrac{1}{|S_i|}\sum_{\mathbf{x}\in S_i}\mathbf{x}&amp;lt;/math&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
  &amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&lt;br /&gt;
    &amp;lt;b&amp;gt;Проверка условия останова:&amp;lt;/b&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
    &#039;&#039;&#039;if&#039;&#039;&#039; &amp;lt;math&amp;gt;\exist i\in \overline{1,k}: \mu_i^{(t)} \ne \mu_i^{(t-1)}&amp;lt;/math&amp;gt; &#039;&#039;&#039;then&#039;&#039;&#039;&lt;br /&gt;
        t = t + 1;&lt;br /&gt;
        goto 2;&lt;br /&gt;
    &#039;&#039;&#039;else&#039;&#039;&#039;&lt;br /&gt;
        &#039;&#039;&#039;stop&#039;&#039;&#039;&lt;br /&gt;
  &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ol&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Вычислительное ядро алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Вычислительным ядром являются шаги 2 и 3 приведенного выше алгоритма: &amp;lt;b&amp;gt;&amp;lt;i&amp;gt;распределение векторов по кластерам&amp;lt;/i&amp;gt;&amp;lt;/b&amp;gt; и &amp;lt;b&amp;gt;&amp;lt;i&amp;gt;пересчет центров кластеров&amp;lt;/i&amp;gt;&amp;lt;/b&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;&amp;lt;i&amp;gt;Распределение векторов&amp;lt;/i&amp;gt;&amp;lt;/b&amp;gt; по кластерам предполагает вычисление расстояний между каждым вектором &amp;lt;math&amp;gt;\mathbf{x}_i \in X, i= \overline{1,n}&amp;lt;/math&amp;gt; и центрами кластера &amp;lt;math&amp;gt;\mathbf{\mu}_j, j= \overline{1,k}&amp;lt;/math&amp;gt;. Таким образом, данный шаг предполагает &amp;lt;math&amp;gt;kn&amp;lt;/math&amp;gt; вычислений расстояний между d-мерными векторами. &lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;&amp;lt;i&amp;gt;Пересчет центров кластеров&amp;lt;/i&amp;gt;&amp;lt;/b&amp;gt; предполагает &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; вычислений центров масс &amp;lt;math&amp;gt;\mathbf{\mu}_i&amp;lt;/math&amp;gt; множеств &amp;lt;math&amp;gt;S_i, i=\overline{1,k}&amp;lt;/math&amp;gt; представленных выражением в шаге 3 представленного выше алгоритма.&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Макроструктура алгоритма ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Инициализация центров масс &amp;lt;math&amp;gt;\mu_1, ..., \mu_k&amp;lt;/math&amp;gt;&amp;lt;/b&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
Наиболее распространенными являются следующие стратегии:&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&lt;br /&gt;
    &amp;lt;b&amp;gt;Метод Forgy&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;В качестве начальных значений &amp;lt;math&amp;gt;\mu_1, ..., \mu_k&amp;lt;/math&amp;gt; берутся случайно выбранные векторы.&lt;br /&gt;
  &amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&lt;br /&gt;
    &amp;lt;b&amp;gt;Метод случайно разделения (Random Partitioning)&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;Для каждого вектора &amp;lt;math&amp;gt;\mathbf{x}_i \in X, i=\overline{1, n}&amp;lt;/math&amp;gt; выбирается случайным образом кластер &amp;lt;math&amp;gt;S_1, ..., S_k&amp;lt;/math&amp;gt;, после чего для каждого полученного кластера вычисляются значения &amp;lt;math&amp;gt;\mu_1, ..., \mu_k&amp;lt;/math&amp;gt;.&lt;br /&gt;
  &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Распределение векторов по кластерам&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Для этого шага алгоритма между векторами &amp;lt;math&amp;gt;\mathbf{x}_i \in X, i=\overline{1, n}&amp;lt;/math&amp;gt; и центрами кластеров &amp;lt;math&amp;gt;\mu_1, ..., \mu_k&amp;lt;/math&amp;gt; вычисляются &amp;lt;b&amp;gt;расстояния&amp;lt;/b&amp;gt; по формуле (как правило, используется Евлидово расстояние):&lt;br /&gt;
&amp;lt;table style=&amp;quot;width:100%&amp;quot;&amp;gt;&lt;br /&gt;
  &amp;lt;tr&amp;gt;&lt;br /&gt;
    &amp;lt;td align=&amp;quot;center&amp;quot; width=&amp;quot;90%&amp;quot;&amp;gt;&amp;lt;math&amp;gt; \mathbf{v}_1, \mathbf{v}_2 \in \mathbb{R}^d,  \quad \rho(\mathbf{v}_1, \mathbf{v}_2) = \lVert \mathbf{v}_1- \mathbf{v}_2 \rVert= \sqrt{\sum_{i=1}^{d}(\mathbf{v}_{1,i} - \mathbf{v}_{2,i})^2}&amp;lt;/math&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;td align=&amp;quot;right&amp;quot;&amp;gt;&amp;lt;math&amp;gt;(2)&amp;lt;/math&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;/table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Пересчет центров кластеров&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Для этого шага алгоритма производится пересчет центров кластера по &amp;lt;b&amp;gt;формуле вычисления центра масс&amp;lt;/b&amp;gt;:&lt;br /&gt;
&amp;lt;table style=&amp;quot;width:100%&amp;quot;&amp;gt;&lt;br /&gt;
  &amp;lt;tr&amp;gt;&lt;br /&gt;
    &amp;lt;td align=&amp;quot;center&amp;quot; width=&amp;quot;90%&amp;quot;&amp;gt;&amp;lt;math&amp;gt; \mu = \cfrac{1}{|S|}\sum_{\mathbf{x}\in S}\mathbf{x}&amp;lt;/math&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;td align=&amp;quot;right&amp;quot;&amp;gt;&amp;lt;math&amp;gt;(3)&amp;lt;/math&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;/table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Схема реализации последовательного алгоритма ===&lt;br /&gt;
&lt;br /&gt;
 &#039;&#039;&#039;algorithm&#039;&#039;&#039; k-means &#039;&#039;&#039;is&#039;&#039;&#039;&lt;br /&gt;
     &#039;&#039;&#039;1.&#039;&#039;&#039; Инициализировать центры кластеров &amp;lt;math&amp;gt;\mathbf{\mu}_i^{(1)}, i=\overline{1,k}&amp;lt;/math&amp;gt;&lt;br /&gt;
     &#039;&#039;&#039;2.&#039;&#039;&#039; &amp;lt;math&amp;gt;t \leftarrow 1&amp;lt;/math&amp;gt;&lt;br /&gt;
     &#039;&#039;&#039;3.&#039;&#039;&#039; &#039;&#039;&#039;Распределение по кластерам&#039;&#039;&#039;&amp;lt;br&amp;gt;&lt;br /&gt;
        &amp;lt;math&amp;gt;S_i^{(t)}=\{\mathbf{x}_p: \lVert\mathbf{x}_p-\mathbf{\mu}_i^{(t)}\rVert^2 \leq \lVert\mathbf{x}_p-\mathbf{\mu}_j^{(t)}\rVert^2 \quad \forall j=\overline{1,k}\},&amp;lt;/math&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
        где каждый вектор &amp;lt;math&amp;gt;\mathbf{x}_p&amp;lt;/math&amp;gt; соотносится единственному кластеру &amp;lt;math&amp;gt;S^{(t)}&amp;lt;/math&amp;gt;&lt;br /&gt;
     &#039;&#039;&#039;4.&#039;&#039;&#039; &#039;&#039;&#039;Обновление центров кластеров&#039;&#039;&#039;&amp;lt;br&amp;gt;&lt;br /&gt;
        &amp;lt;math&amp;gt;\mathbf{\mu}_i^{(t+1)} = \frac{1}{|S^{(t)}_i|} \sum_{\mathbf{x}_j \in S^{(t)}_i} \mathbf{x}_j &amp;lt;/math&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
     &#039;&#039;&#039;5.&#039;&#039;&#039; &#039;&#039;&#039;if&#039;&#039;&#039; &amp;lt;math&amp;gt;\exist i \in \overline{1,k}: \mathbf{\mu}_i^{(t+1)} \ne \mathbf{\mu}_i^{(t)}&amp;lt;/math&amp;gt; &#039;&#039;&#039;then&#039;&#039;&#039;&lt;br /&gt;
            t = t + 1;&lt;br /&gt;
            goto &#039;&#039;&#039;3&#039;&#039;&#039;;&lt;br /&gt;
        &#039;&#039;&#039;else&#039;&#039;&#039;&lt;br /&gt;
            &#039;&#039;&#039;stop&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
=== Последовательная сложность алгоритма===&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding-bottom: 20px&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;Обозначим &amp;lt;math&amp;gt;\Theta_{\rm centroid}^{d, m}&amp;lt;/math&amp;gt; временную сложность вычисления центорида кластера, число элементов которого равна &amp;lt;math&amp;gt;m&amp;lt;/math&amp;gt;,  в d-мерном пространстве.&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;Аналогично  &amp;lt;math&amp;gt;\Theta_{\rm distance}^d&amp;lt;/math&amp;gt; &amp;amp;ndash; временная сложность вычисления расстояния между двумя d-мерными векторами.&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding-bottom: 20px&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;Сложность шага инициализации &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластеров мощности &amp;lt;math&amp;gt;m&amp;lt;/math&amp;gt; в d-мерном пространстве &amp;amp;ndash; &amp;lt;math&amp;gt;\Theta_{\rm init}^{k, d, m}&amp;lt;/math&amp;gt;&amp;lt;/b&amp;gt;&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;i&amp;gt;Стратерия Forgy&amp;lt;/i&amp;gt;: вычисления не требуются, &amp;lt;math&amp;gt;\Theta_{\rm init}^{k, d, m} = 0&amp;lt;/math&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;i&amp;gt;Стратегия случайного разбиения&amp;lt;/i&amp;gt;: вычисление центров &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластеров,  &amp;lt;math&amp;gt;\Theta_{\rm init}^{k, d, m} = k \cdot \Theta_{\rm centroid}^{d, m}, m \le n&amp;lt;/math&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding-bottom: 20px&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Cложность шага распределения d мерных векторов по &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластерам &amp;amp;ndash; &amp;lt;math&amp;gt;\Theta_{\rm distribute}^{k, d}&amp;lt;/math&amp;gt;&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
На этом шаге для каждого вектора &amp;lt;math&amp;gt;\mathbf{x}_i \in X, i=\overline{1, n}&amp;lt;/math&amp;gt; вычисляется k расстояний до центров кластеров &amp;lt;math&amp;gt;\mathbf{\mu}_1, ...\mathbf{\mu}_k&amp;lt;/math&amp;gt;&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p align=&amp;quot;center&amp;quot;&amp;gt;&lt;br /&gt;
  &amp;lt;math&amp;gt;\Theta_{\rm distribute}^{k, d} = n \cdot k \cdot \Theta_{\rm distance}^d&amp;lt;/math&amp;gt;&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding-bottom: 20px&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;Сложность шага пересчета центров &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластеров размера &amp;lt;math&amp;gt;m&amp;lt;/math&amp;gt; в d-мерном пространстве &amp;amp;ndash; &amp;lt;math&amp;gt;\Theta_{\rm recenter}^{k, d, m}&amp;lt;/math&amp;gt;&amp;lt;/b&amp;gt;&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;На этом шаге вычисляется &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; центров кластеров &amp;lt;math&amp;gt;\mathbf{\mu}_1, ...\mathbf{\mu}_k&amp;lt;/math&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p align=&amp;quot;center&amp;quot;&amp;gt;&amp;lt;math&amp;gt;\Theta_{\rm recenter}^{k, d, m} = k \cdot \Theta_{\rm centroid}^{d, m}&amp;lt;/math&amp;gt; &amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding-bottom: 20px&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Рассчитаем &amp;lt;math&amp;gt;\Theta_{\rm centroid}^{d, m}&amp;lt;/math&amp;gt; для кластера, число элементов которого равно &amp;lt;math&amp;gt;m&amp;lt;/math&amp;gt;&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p align=&amp;quot;center&amp;quot;&amp;gt;&amp;lt;math&amp;gt;\Theta_{\rm centroid}^{d, m}&amp;lt;/math&amp;gt; = &amp;lt;math&amp;gt;m \cdot d&amp;lt;/math&amp;gt; сложений + &amp;lt;math&amp;gt;d&amp;lt;/math&amp;gt; делений &amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding-bottom: 20px&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Рассчитаем &amp;lt;math&amp;gt;\Theta_{\rm distance}^d&amp;lt;/math&amp;gt; в соответствие с формулой &amp;lt;math&amp;gt;(2)&amp;lt;/math&amp;gt;&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p align=&amp;quot;center&amp;quot;&amp;gt;&amp;lt;math&amp;gt;\Theta_{\rm distance}^d&amp;lt;/math&amp;gt; = &amp;lt;math&amp;gt;d&amp;lt;/math&amp;gt; вычитаний + &amp;lt;math&amp;gt;d&amp;lt;/math&amp;gt; умножений + &amp;lt;math&amp;gt;(d-1)&amp;lt;/math&amp;gt; сложение&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding-bottom: 20px&amp;quot;&amp;gt;&lt;br /&gt;
  &amp;lt;p&amp;gt;Предположим, что алгоритм сошелся за &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt; итераций, тогда временная сложность алгоритма &amp;lt;math&amp;gt;\Theta_{\rm k-means}^{d, n}&amp;lt;/math&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
  &amp;lt;p align=&amp;quot;center&amp;quot;&amp;gt;&amp;lt;b&amp;gt;&amp;lt;math&amp;gt;\Theta_{\rm k-means}^{d, n} \le \Theta_{\rm init}^{k, d, n} + i(\Theta_{\rm distribute}^{k, d} + \Theta_{\rm recenter}^{k, d, n})&amp;lt;/math&amp;gt;&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding-bottom: 5px&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;Операции сложения/вычитания:&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p align=&amp;quot;center&amp;quot;&amp;gt;&amp;lt;b&amp;gt;&amp;lt;math&amp;gt;\Theta_{\rm k-means}^{d, n} \le knd+ i(kn(2d-1) + knd) = knd+ i(kn(3d-1)) \thicksim O(ikdn)&amp;lt;/math&amp;gt;&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding-bottom: 20px&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;Операции умножения/деления:&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p align=&amp;quot;center&amp;quot;&amp;gt;&amp;lt;b&amp;gt;&amp;lt;math&amp;gt;\Theta_{\rm k-means}^{d, n} \le kd + i(knd + kd) = kd + ikd(n+1) \thicksim O(ikdn) &amp;lt;/math&amp;gt;&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding-bottom: 20px&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;Получаем, что &amp;lt;b&amp;gt;временная сложность&amp;lt;/b&amp;gt; алгоритма &amp;lt;b&amp;gt;k means&amp;lt;/b&amp;gt; кластеризации &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; &amp;lt;b&amp;gt;d-мерных&amp;lt;/b&amp;gt; векторов на &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластеров за &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt; итераций:&amp;lt;/p&amp;gt;&lt;br /&gt;
 &amp;lt;p align=&amp;quot;center&amp;quot;&amp;gt;&amp;lt;b&amp;gt;&amp;lt;math&amp;gt; \Theta_{\rm k-means}^{d, n} \thicksim O(ikdn) &amp;lt;/math&amp;gt;&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Информационный граф ===&lt;br /&gt;
&lt;br /&gt;
Рассмотрим информационный граф алгоритма. Алгоритм &amp;lt;i&amp;gt;k means&amp;lt;/i&amp;gt; начинается с этапа инициализации, после которого следуют итерации, на каждой из которых выполняется два последовательных шага (см. [[#Схема реализации последовательного алгоритма|&amp;quot;Схема реализации последовательного алгоритма&amp;quot;]]): &lt;br /&gt;
* распределение векторов по кластерам&lt;br /&gt;
* перерасчет центров кластеров&lt;br /&gt;
&lt;br /&gt;
Поскольку основная часть вычислений приходится на шаги итераций, распишем информационные графы данных шагов.&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Распределение векторов по кластерам&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
Информационный граф шага распределения векторов по кластерам представлен на &#039;&#039;рисунке 1&#039;&#039;. Исходами данного графа является исходные векторы &amp;lt;math&amp;gt;\mathbf{x}_1, ..., \mathbf{x}_n&amp;lt;/math&amp;gt;, а также центры кластеров &amp;lt;math&amp;gt;\mathbf{\mu}_1, ... \mathbf{\mu}_k&amp;lt;/math&amp;gt;, вычисленные ранее (на шаге инициализации, если рассматривается первая итерация алгоритма, или на шаге пересчета центров кластеров предыдущей итерации в противном случае). Каждая пара векторов данных &amp;lt;math&amp;gt;\mathbf{x}_i, i=\overline{1,n}&amp;lt;/math&amp;gt; и центров кластера &amp;lt;math&amp;gt;\mathbf{\mu}_j, j=\overline{1, k}&amp;lt;/math&amp;gt; : (&amp;lt;math&amp;gt;\mathbf{x}_i&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;\mathbf{\mu}_j&amp;lt;/math&amp;gt;) подаются на независимые узлы &amp;lt;i&amp;gt;&amp;quot;d&amp;quot;&amp;lt;/i&amp;gt; вычисления расстояния между векторами (более подробная схема вычисления расстояния представлена далее, &#039;&#039;рисунок 2&#039;&#039;). Далее узлы вычисления расстояния &amp;lt;i&amp;gt;&amp;quot;d&amp;quot;&amp;lt;/i&amp;gt;, соответствующие одному и тому же исходному вектору &amp;lt;math&amp;gt;\mathbf{x}_i&amp;lt;/math&amp;gt; передаются на один узел &amp;lt;i&amp;gt;&amp;quot;m&amp;quot;&amp;lt;/i&amp;gt;, где далее происходит вычисление новой метки кластера для каждого вектора &amp;lt;math&amp;gt;\mathbf{x}_i&amp;lt;/math&amp;gt; (берется кластер с минимальным результатом вычисления расстояния). На выходе графа выдаются метки кластеров , &amp;lt;math&amp;gt;L_1, ..., L_n&amp;lt;/math&amp;gt;, такие что &amp;lt;math&amp;gt;\forall \mathbf{x}_i, i=\overline{1, n}, \mathbf{x}_i \in S_j \Leftrightarrow L_i = j&amp;lt;/math&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
[[file:Clusterization.png|thumb|center|800px|Рис. 1. Схема распределения векторов по кластерам. &#039;&#039;d&#039;&#039; &amp;amp;ndash; вычисление расстояния между векторами; &#039;&#039;m&#039;&#039; &amp;amp;ndash; вычисление минимума.]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Вычисление расстояния между векторами&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
Подробная схема вычисления расстояния между векторами &amp;lt;math&amp;gt;\mathbf{x}_i, \mathbf{\mu}_j&amp;lt;/math&amp;gt; представлена на &#039;&#039;рисунке 2&#039;&#039;. Как показано на графе, узел вычисления расстояния между векторами &amp;lt;i&amp;gt;&amp;quot;d&amp;quot;&amp;lt;/i&amp;gt; состоит из шага взятия разности между векторами (узел &amp;quot;&amp;lt;math&amp;gt;-&amp;lt;/math&amp;gt;&amp;quot;) и взятия нормы получившегося вектора разности (узел &amp;quot;&amp;lt;math&amp;gt;||\cdot||^2&amp;lt;/math&amp;gt;&amp;quot;). Более подробно, вычисление расстояния между векторами &amp;lt;math&amp;gt;\mathbf{x}_i = {x_{i1,}, ...,{x_{in}}}, \mathbf{\mu}_j = {\mu_{j1}, ...,\mu_{jn}}&amp;lt;/math&amp;gt; может быть представлено как вычисление разности между каждой парой компонент &amp;lt;math&amp;gt;(x_{iz}, \mu_{jz}), z=\overline{1, d}&amp;lt;/math&amp;gt; (узел &amp;quot;&amp;lt;math&amp;gt;-&amp;lt;/math&amp;gt;&amp;quot;), далее возведение в квадрат для каждого узла &amp;quot;&amp;lt;math&amp;gt;-&amp;lt;/math&amp;gt;&amp;quot; (узел &amp;quot;&amp;lt;math&amp;gt;()^2&amp;lt;/math&amp;gt;&amp;quot;) и суммирования выходов всех узлов &amp;quot;&amp;lt;math&amp;gt;()^2&amp;lt;/math&amp;gt;&amp;quot; (узел &amp;quot;&amp;lt;math&amp;gt;+&amp;lt;/math&amp;gt;&amp;quot;).  &lt;br /&gt;
&lt;br /&gt;
[[file:dist_calc.png|thumb|center|800px|Рис. 2. Схема вычисления расстояния между вектором и центром кластера.]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Пересчет центров кластеров&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
Информационный граф шага пересчета центров кластеров представлен на &#039;&#039;рисунке 3&#039;&#039;. Исходами данного графа является исходные векторы &amp;lt;math&amp;gt;\mathbf{x}_1, ..., \mathbf{x}_n&amp;lt;/math&amp;gt;, а также им соответствующие метки кластера, &amp;lt;math&amp;gt;L_1, ..., L_n&amp;lt;/math&amp;gt;, такие что &amp;lt;math&amp;gt;\forall x_i, i=\overline{1, n}, \mathbf{x}_i \in S_j \Leftrightarrow L_i = j&amp;lt;/math&amp;gt;, вычисленные на этапе распределения векторов по кластерам. Все векторы &amp;lt;math&amp;gt;\mathbf{x}_1, ..., \mathbf{x}_n&amp;lt;/math&amp;gt; подаются в узлы &amp;lt;math&amp;gt;+_1, ...+_k&amp;lt;/math&amp;gt;, каждый узел &amp;lt;math&amp;gt;+_m, m = \overline{1,k}&amp;lt;/math&amp;gt; соответствует операции сложения векторов кластера с номером &amp;lt;math&amp;gt;m&amp;lt;/math&amp;gt;. Метки кластера &amp;lt;math&amp;gt;L_1, ..., L_n&amp;lt;/math&amp;gt; также совместно передаются на узлы &amp;lt;math&amp;gt;S_m, m = \overline{1,k}&amp;lt;/math&amp;gt;, на каждом из которых вычисляется количество векторов в соответствующем кластере (количество меток с соответствующим значением). Далее каждая пара выходов узлов &amp;lt;math&amp;gt;+_m&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;S_m&amp;lt;/math&amp;gt; подается на узел &amp;quot;&amp;lt;math&amp;gt;/&amp;lt;/math&amp;gt;&amp;quot;, где производится деление суммы векторов кластера на количество элементов в нем. Значения, вычисленные на узлах &amp;quot;&amp;lt;math&amp;gt;/&amp;lt;/math&amp;gt;&amp;quot;, присваиваются новым центрам кластеров (выходные значения графа).&lt;br /&gt;
&lt;br /&gt;
[[file:Recluster.png|thumb|center|800px|Рис. 3. Схема пересчета центров кластеров]]&lt;br /&gt;
&lt;br /&gt;
=== Ресурс параллелизма алгоритма ===&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
Работа алгоритма состоит из &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt; итераций, в каждой из которых происходит &amp;lt;b&amp;gt;распределение d-мерных векторов по &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластерам&amp;lt;/b&amp;gt;, а также &amp;lt;b&amp;gt;пересчет центров кластеров в d-мерном пространстве&amp;lt;/b&amp;gt;. В шаге &amp;lt;b&amp;gt;распределения d-мерных векторов по &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластерам&amp;lt;/b&amp;gt; расстояния между вектором и центрами кластеров вычисляются независимо (отсутствуют информационные зависимости). &amp;lt;b&amp;gt;Центры масс кластеров&amp;lt;/b&amp;gt; также пересчитываются независимо друг от друга. Таким образом, имеет место [[глоссарий#Массовый параллелизм|&#039;&#039;массовый параллелизм&#039;&#039;]]. Вычислим параллельную сложность &amp;lt;math&amp;gt;\Psi_*&amp;lt;/math&amp;gt; каждого из шагов, а также параллельную сложность всего алгоритма, &amp;lt;math&amp;gt;\Psi_{\rm k-means}&amp;lt;/math&amp;gt;. Будем исходить из предположения, что может быть использовано любое необходимое число потоков.&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Распределение d-мерных векторов по &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластерам&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;  &lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
Поскольку на данном шаге для каждой пары векторов &amp;lt;math&amp;gt;\mathbf{x}_i, i=\overline{1,n}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\mathbf{\mu}_j, j=\overline{1,k}&amp;lt;/math&amp;gt; операции вычисления расстояния не зависят друг от друга, они могут выполняться параллельно. Тогда, разделив все вычисление расстояний на &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; потоков, получим, что в каждом потоке будет выполняться только одна операция вычисления расстояния между векторами размерности d. При этом каждому вычислительному потоку передаются координаты центров всех кластеров &amp;lt;math&amp;gt;\mathbf{\mu}_1, ..., \mathbf{\mu}_k&amp;lt;/math&amp;gt;. Таким образом, параллельная сложность данного шага определяется &amp;lt;i&amp;gt; сложностью параллельной операции вычисления расстояния между d-мерными векторами&amp;lt;/i&amp;gt;, &amp;lt;math&amp;gt;\Psi_{\rm distance}^d&amp;lt;/math&amp;gt;  и &amp;lt;i&amp;gt;сложностью определения наиболее близкого кластера&amp;lt;/i&amp;gt; (паралельное взятие минимума по расстояниям), &amp;lt;math&amp;gt;\Psi_{\rm min}^k&amp;lt;/math&amp;gt;. Для оценки &amp;lt;math&amp;gt;\Psi_{\rm distance}^d&amp;lt;/math&amp;gt; воспользуемся  [[Нахождение_частных_сумм_элементов_массива_сдваиванием | параллельной реализацией нахождения частичной суммы элементов массива путем сдваивания]]. Аналогично, &amp;lt;math&amp;gt;\Psi_{\rm min}^k = log(k)&amp;lt;/math&amp;gt;. В результате, &amp;lt;math&amp;gt;\Psi_{\rm distance}^d = O(log(d))&amp;lt;/math&amp;gt;.   Таким образом: &lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p align=&amp;quot;center&amp;quot;&amp;gt;&amp;lt;math&amp;gt;\Psi_{\rm distribute}^{k, d}  = \Psi_{\rm distance}^d + \Psi_{\rm min}^k = O(log(d))+O(log(k)) = O(log(kd))&amp;lt;/math&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Пересчет центров кластеров в d-мерном пространстве&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
Поскольку на данном шаге для каждого из &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластеров центр масс может быть вычислен независимо, данные операции могут быть выполнены в отдельных потоках. Таким образом, параллельная сложность данного шага, &amp;lt;math&amp;gt;\Psi_{\rm recenter}^{k, d}&amp;lt;/math&amp;gt;,  будет определяться &amp;lt;i&amp;gt;параллельной сложностью вычисления одного центра масс кластера размера &amp;lt;math&amp;gt;m&amp;lt;/math&amp;gt;&amp;lt;/i&amp;gt;, &amp;lt;math&amp;gt;\Psi_{\rm recenter}^{k, d}&amp;lt;/math&amp;gt;,  а так как &amp;lt;math&amp;gt;m \le n \Rightarrow \Psi_{\rm recenter}^{d, m} \le \Psi_{\rm recenter}^{d, n}&amp;lt;/math&amp;gt;. Сложность вычисления центра масс кластера d-мерных векторов размера n аналогично предыдущим вычислениям равна &amp;lt;math&amp;gt;O(log(n))&amp;lt;/math&amp;gt;. Тогда:  &lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p align=&amp;quot;center&amp;quot;&amp;gt;&amp;lt;math&amp;gt;\Psi_{\rm recenter}^{k, d}  \le \Psi_{\rm recenter}^{d, n} = O(log(n))&amp;lt;/math&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Общая параллельная сложность алгоритма&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
На каждой итерации необходимо обновление центров кластеров, которые будут использованы на следующей итерации. Таким образом, итерационный процесс выполняется последовательно&amp;lt;ref&amp;gt;Zhao, Weizhong, Huifang Ma, and Qing He. &amp;quot;Parallel k-means clustering based on mapreduce.&amp;quot; IEEE International Conference on Cloud Computing. Springer Berlin Heidelberg, 2009.&amp;lt;/ref&amp;gt;. Тогда, поскольку сложность каждой итерации  определяется &amp;lt;math&amp;gt;\Psi_{\rm distribute}^{k, d}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\Psi_{\rm recenter}&amp;lt;/math&amp;gt;, сложность всего алгоритма, &amp;lt;math&amp;gt;\Psi_{\rm k-means}&amp;lt;/math&amp;gt; в предположении, что было сделано &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt; операций определяется выражением&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p align=&amp;quot;center&amp;quot;&amp;gt;&amp;lt;math&amp;gt;\Psi_{\rm k-means} \approx i \cdot (\Psi_{\rm distribute}^{k, d} + \Psi_{\rm recenter}^{k, d}) \le i \cdot O(log(kdn))&amp;lt;/math&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Входные и выходные данные алгоритма ===&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;Входные данные&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;Матрица из &amp;lt;math&amp;gt;n \cdot d&amp;lt;/math&amp;gt; элементов &amp;lt;math&amp;gt;x_{i, j} \in \mathbb{R}, i=\overline{1, n}, j=\overline{1, d}&amp;lt;/math&amp;gt;&amp;amp;ndash; координат векторов (наблюдений).&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;Целое положительное число &amp;lt;math&amp;gt;k, k \le n&amp;lt;/math&amp;gt; &amp;amp;ndash; количество кластеров.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;Объем входных данных&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;math&amp;gt;1&amp;lt;/math&amp;gt; целое число + &amp;lt;math&amp;gt;n \cdot d&amp;lt;/math&amp;gt; вещественных чисел (при условии, что координаты &amp;amp;ndash; вещественные числа).&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;Выходные данные&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; целых положительных чисел &amp;lt;math&amp;gt;L_1, ..., L_n&amp;lt;/math&amp;gt;&amp;amp;ndash; номера кластеров, соотвествующие каждому вектору (при условии, что нумерация кластеров начинается с &amp;lt;math&amp;gt;1&amp;lt;/math&amp;gt;).&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;Объем выходных данных&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; целых положительных чисел.&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Свойства алгоритма ===&lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;[[глоссарий#Вычислительная мощность|&#039;&#039;Вычислительная мощность&#039;&#039;]]&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
Вычислительная мощность алгоритма &amp;lt;i&amp;gt;k means&amp;lt;/i&amp;gt; равна &amp;lt;math&amp;gt;\frac{ikdn}{nd} = ki &amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; &amp;amp;ndash; число кластеров, &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt; &amp;amp;ndash; число итераций алгоритма.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;[[глоссарий#Детерминированность |&#039;&#039;Детерминированность&#039;&#039;]] и [[глоссарий#Устойчивость |&#039;&#039;Устойчивость&#039;&#039;]] &amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
Алгоритм &amp;lt;i&amp;gt;k means&amp;lt;/i&amp;gt; является итерационным. Количество итераций алгоритма в общем случае не фиксируется и зависит от начального расположения объектов в пространстве, параметра &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt;, а также от начального приближения центров кластеров, &amp;lt;math&amp;gt;\mu_1, ..., \mu_k&amp;lt;/math&amp;gt;. В результате этого может варьироваться результат работы алгоритма. При неудачном выборе начальных параметров итерационный процесс может сойтись к локальному оптимуму&amp;lt;ref&amp;gt;Von Luxburg, Ulrike. Clustering Stability. Now Publishers Inc, 2010.&amp;lt;/ref&amp;gt;. По этим причинам алгоритм не является ни &amp;lt;b&amp;gt;детермирированным&amp;lt;/b&amp;gt;, ни &amp;lt;b&amp;gt;устойчивым&amp;lt;/b&amp;gt;.&lt;br /&gt;
 &lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Соотношение последовательной и параллельной сложности алгоритма&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\frac{\Theta_{\rm k-means}}{\Psi_{\rm k-means}} = \frac{O(ikdn)}{O(i \cdot log(kdn))}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Сильные стороны алгоритма&amp;lt;/b&amp;gt;:&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;i&amp;gt;Сравнительно высокая эффективность при простоте реализации&amp;lt;/i&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;i&amp;gt;Высокое качество кластеризации&amp;lt;/i&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;i&amp;gt;Возможность распараллеливания&amp;lt;/i&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;i&amp;gt;Существование множества модификаций&amp;lt;/i&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;Недостатки алгоритма&amp;lt;/b&amp;gt;&amp;lt;ref&amp;gt;Ortega, Joaquín Pérez, Ma Del Rocío Boone Rojas, and María J. Somodevilla. &amp;quot;Research issues on K-means Algorithm: An Experimental Trial Using Matlab.&amp;quot;&amp;lt;/ref&amp;gt;:&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;i&amp;gt;Количество кластеров является параметром алгоритма&amp;lt;/i&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;&amp;lt;i&amp;gt;Чувствительность к начальным условиям&amp;lt;/i&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;Инициализация центров кластеров в значительной степени влияет на результат кластеризации.&amp;lt;/p&amp;gt;&lt;br /&gt;
  &amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;&amp;lt;i&amp;gt;Чувствительность к выбросам и шумам&amp;lt;/i&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;Выбросы, далекие от центров настоящих кластеров, все равно учитываются при вычислении их центров.&amp;lt;/p&amp;gt;&lt;br /&gt;
  &amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;&amp;lt;i&amp;gt;Возможность сходимости к локальному оптимуму&amp;lt;/i&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;Итеративный подход не дает гарантии сходимости к оптимальному решению.&amp;lt;/p&amp;gt;&lt;br /&gt;
  &amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;&amp;lt;i&amp;gt;Использование понятия &amp;quot;среднего&amp;quot;&amp;lt;/i&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;Алгоритм неприменим к данным, для которых не определено понятие &amp;quot;среднего&amp;quot;, например, категориальным данным.&amp;lt;/p&amp;gt;&lt;br /&gt;
  &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&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;
Исследование масштабируемости параллельной реализации алгоритма k means проводилось на суперкомпьютере &amp;quot;Ломоносов&amp;quot;&amp;lt;ref name=&amp;quot;Lom&amp;quot;&amp;gt;Воеводин Вл., Жуматий С., Соболев С., Антонов А., Брызгалов П., Никитенко Д., Стефанов К., Воеводин Вад. Практика суперкомпьютера «Ломоносов» // Открытые системы, 2012, N 7, С. 36-39.&amp;lt;/ref&amp;gt; [http://parallel.ru/cluster Суперкомпьютерного комплекса Московского университета]. Алгоритм реализован на языке C с использованием средств MPI.&lt;br /&gt;
Для исследования масштабируемости проводилось множество запусков программы с разным значением параметра (количество векторов для кластеризации), а также с различным числом процессоров. Фиксировались результаты запусков &amp;amp;ndash; время работы &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt; и количество произведенных итераций алгоритма &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Параметры запусков для экспериментальной оценки:&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;Значения &amp;lt;b&amp;gt;количества векторов&amp;lt;/b&amp;gt; &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;: 20&#039;000, 30&#039;000, 50&#039;000, 100&#039;000, 200&#039;000, 300&#039;000, 500&#039;000, 700&#039;000, 1&#039;000&#039;000, 1&#039;500&#039;000, 2&#039;000&#039;000.&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;Значения &amp;lt;b&amp;gt;количества процессоров&amp;lt;/b&amp;gt; &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt;: 1, 8, 16, 32, 64, 128, 160, 192, 224, 256, 288, 320, 352, 384, 416, 448, 480, 512.&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;Значение &amp;lt;b&amp;gt;количества кластеров&amp;lt;/b&amp;gt; &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt;: 100.&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;Значение &amp;lt;b&amp;gt;размерности векторов&amp;lt;/b&amp;gt; &amp;lt;math&amp;gt;d&amp;lt;/math&amp;gt;: 10.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Для проведения экспериментов были сгенерированы нормально распределенные псевдослучайные данные (с использованием Python библиотеки [http://scikit-learn.org/ scikit-learn]):&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
from sklearn.datasets import make_classification&lt;br /&gt;
X1, Y1 = make_classification(n_features=10, n_redundant=2, n_informative=8,&lt;br /&gt;
                             n_clusters_per_class=1, n_classes=100,&lt;br /&gt;
                             n_samples=2000000)&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Для заданной конфигурации эксперимента (&amp;lt;math&amp;gt;n, d, p, k&amp;lt;/math&amp;gt;) и полученных результатов (&amp;lt;math&amp;gt;t, i&amp;lt;/math&amp;gt;)  [[Глоссарий#Производительность|производительность]]  и эффективность реализации расчитывались по формулам:&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
&amp;lt;ul&amp;gt;&amp;lt;li&amp;gt;&amp;lt;math&amp;gt;\rm Performance = \frac{N_{\rm k-means}^{d, n}}{t}\ \ (FLOPS),&amp;lt;/math&amp;gt;&amp;lt;/li&amp;gt;&amp;lt;/ul&amp;gt;&lt;br /&gt;
где &amp;lt;math&amp;gt;N_{\rm k-means}^{d, n}&amp;lt;/math&amp;gt; &amp;amp;ndash; точное число операций с плавающей точкой (операции с памятью, а также целочисленные операции не учитывались), вычисленное в соответствие с разделом [[#Последовательная сложность алгоритма| &amp;quot;Последовательная сложность алгоритма&amp;quot;]];&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
&amp;lt;ul&amp;gt;&amp;lt;li&amp;gt;&amp;lt;math&amp;gt;\rm Efficiency = \frac{100 \cdot Performance}{Performance_{\rm Peak}^{p}}\ \ (%),&amp;lt;/math&amp;gt;&amp;lt;/li&amp;gt;&amp;lt;/ul&amp;gt;&lt;br /&gt;
где &amp;lt;math&amp;gt;\rm Performance_{\rm Peak}^{p}&amp;lt;/math&amp;gt; &amp;amp;ndash; пиковая производительность суперкомпьютера при &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt; процессорах, вычисленная согласно спецификациям Intel&amp;lt;sup&amp;gt;&amp;amp;reg;&amp;lt;/sup&amp;gt; XEON&amp;lt;sup&amp;gt;&amp;amp;reg;&amp;lt;/sup&amp;gt; X5670&amp;lt;ref&amp;gt;&amp;quot;http://ark.intel.com/ru/products/47920/Intel-Xeon-Processor-X5670-12M-Cache-2_93-GHz-6_40-GTs-Intel-QPI&amp;quot;&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Графики зависимости производительности и эффективности параллельной реализации k means от числа векторов для кластеризации (&amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;) и числа процессоров (&amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt;) представлены на рисунках 4 и 5 соответственно.&lt;br /&gt;
&lt;br /&gt;
[[file:Flops.png|thumb|center|800px|Рис. 4. Параллельная реализация k means. График зависимости производительности реализации алгоритма от числа векторов для кластеризации (&amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;) и числа процессоров (&amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt;).]]&lt;br /&gt;
[[file:Efficiency.png|thumb|center|800px|Рис. 5. Параллельная реализация k means. График зависимости эффективности реализации алгоритма от числа векторов для кластеризации (&amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;) и числа процессоров (&amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt;).]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;В результате&amp;lt;/b&amp;gt; экспериментальной оценки были получены следующие оценки эффективности реализации:&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;b&amp;gt;Минимальное&amp;lt;/b&amp;gt; значение: 0.000409 % достигается при &amp;lt;math&amp;gt;n=20&#039;000, p=480&amp;lt;/math&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;b&amp;gt;Максимальное&amp;lt;/b&amp;gt; значение: 0.741119 % достигается при &amp;lt;math&amp;gt;n=300&#039;000, p=1&amp;lt;/math&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
Оценки масштабируемости реализации алгоритма k means:&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;b&amp;gt;По числу процессоров:&amp;lt;/b&amp;gt; -0.002683 &amp;amp;ndash; эффективность убывает с ростом числа процессоров. Данный результат вызван ростом накладных расходов для обеспечения параллельного выполнения алгоритма.&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;b&amp;gt;По размеру задачи:&amp;lt;/b&amp;gt; 0.002779 &amp;amp;ndash; эффективность растет с ростом числа векторов. Данный результат вызван тем, что при увеличении размера задачи, количество вычислений растет по сравнению с временем, затрачиваемым на пересылку данных.&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;b&amp;gt;Общая оценка:&amp;lt;/b&amp;gt; -0.000058 &amp;amp;ndash; можно сделать вывод, что в целом эффективность реализации незначительно уменьшается с ростом размера задачи и числа процессоров.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[https://github.com/serban/kmeans Использованная параллельная реализация алгоритма k means]&lt;br /&gt;
&lt;br /&gt;
=== Динамические характеристики и эффективность реализации алгоритма ===&lt;br /&gt;
=== Выводы для классов архитектур ===&lt;br /&gt;
=== Существующие реализации алгоритма ===&lt;br /&gt;
==== Открытое программное обеспечение ====&lt;br /&gt;
&amp;lt;ol&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;[https://www.icpsr.umich.edu/CrimeStat/ CrimeStat]&amp;lt;/li&amp;gt; Программное обеспечение, созданное для операционных систем Windows, предоставляющее инструменты статистического  и пространственного анализа для решения задачи картирования преступности.&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://juliastats.github.io Julia]&amp;lt;/li&amp;gt; Высокоуровневый высокопроизводительный свободный язык программирования с динамической типизацией, созданный для математических вычислений, содержит реализацию k-means.&lt;br /&gt;
  &amp;lt;li&amp;gt;[https://mahout.apache.org Mahout]&amp;lt;/li&amp;gt; Apache Mahout - Java библиотека для работы с алгоритмами машинного обучения с использованием MapReduce. Содержит реализацию k-means.&lt;br /&gt;
  &amp;lt;li&amp;gt;[https://www.gnu.org/software/octave/ Octave]&amp;lt;/li&amp;gt; Написанная на C++  свободная система для математических вычислений, использующая совместимый с MATLAB язык высокого уровня, содержит реализацию k-means.&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://spark.apache.org/docs/latest/mllib-clustering.html Spark]&amp;lt;/li&amp;gt; Распределенная реализация k-means содержится в библиотеке Mlib для работы с алгоритмами машинного обучения, взаимодействующая с Python библиотекой NumPy и библиотека R.&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://torch.ch Torch]&amp;lt;/li&amp;gt;  MATLAB-подобная библиотека для языка программирования Lua с открытым исходным кодом, предоставляет большое количество алгоритмов для глубинного обучения и научных расчётов. Ядро написано на Си, прикладная часть выполняется на LuaJIT, поддерживается распараллеливание вычислений средствами CUDA и OpenMP. Существуют реализации k-means.&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://www.cs.waikato.ac.nz/ml/weka/ Weka]&amp;lt;/li&amp;gt;  Cвободное программное обеспечение для анализа данных, написанное на Java. Содержит k-means и x-means.&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://accord-framework.net/docs/html/T_Accord_MachineLearning_KMeans.htm Accord.NET]&amp;lt;/li&amp;gt; C# реализация алгоритмов k-means, k-means++, k-modes.&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://docs.opencv.org/3.0-beta/doc/py_tutorials/py_ml/py_kmeans/py_kmeans_opencv/py_kmeans_opencv.html OpenCV]&amp;lt;/li&amp;gt; Написанная на С++ библиотека, направленная в основном на решение задач компьютерного зрения. Содержит реализацию k-means.&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://mlpack.org/ MLPACK]&amp;lt;/li&amp;gt; Масштабируемая С++ библиотека для работы с алгоритмами машинного обучения, содержит реализацию k-means.&lt;br /&gt;
  &amp;lt;li&amp;gt;[https://www.scipy.org/ SciPy]&amp;lt;/li&amp;gt; Библиотека Python, содержит множество реализаций k-means.&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://scikit-learn.org/ scikit-learn]&amp;lt;/li&amp;gt; Библиотека Python, содержит множество реализаций k-means.&lt;br /&gt;
  &amp;lt;li&amp;gt;[https://www.r-bloggers.com/k-means-clustering-in-r/ R]&amp;lt;/li&amp;gt; Язык программирования для статистической обработки данных и работы с графикой, а также свободная программная среда вычислений с открытым исходным кодом в рамках проекта GNU, содержит три реализации k-means.&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://elki.dbs.ifi.lmu.de ELKI]&amp;lt;/li&amp;gt; Java фреймворк, содержащий реализацию k-means, а также множество других алгоритмов кластеризации.&lt;br /&gt;
&amp;lt;/ol&amp;gt;&lt;br /&gt;
==== Проприетарное программное обеспечение  ====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ol&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;[https://www.ayasdi.com/blog/bigdata/topological-data-analysis-of-oil-and-gas-petrophysical-data/ Ayasdi]&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://www.stata.com/features/cluster-analysis/ Stata]&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://mathworld.wolfram.com/K-MeansClusteringAlgorithm.html Mathematica]&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://www.mathworks.com/help/stats/kmeans.html?requestedDomain=www.mathworks.com MATLAB]&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;[https://support.sas.com/rnd/app/stat/procedures/fastclus.html SAS]&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://docs.rapidminer.com/studio/operators/modeling/segmentation/k_means.html RapidMiner]&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;[https://blogs.sap.com/2013/03/28/sap-hana-pal-k-means-algorithm-or-how-to-do-customer-segmentation-for-the-telecommunications-industry/ SAP HANA]&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ol&amp;gt;&lt;br /&gt;
== Литература ==&lt;br /&gt;
&amp;lt;references /&amp;gt;&lt;/div&gt;</summary>
		<author><name>DennZo1993</name></author>
	</entry>
	<entry>
		<id>https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:%D0%91%D1%80%D0%BE%D1%82%D0%B8%D0%BA%D0%BE%D0%B2%D1%81%D0%BA%D0%B0%D1%8F_%D0%94%D0%B0%D0%BD%D1%83%D1%82%D0%B0/%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_k-means&amp;diff=20538</id>
		<title>Участник:Бротиковская Данута/Алгоритм k-means</title>
		<link rel="alternate" type="text/html" href="https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:%D0%91%D1%80%D0%BE%D1%82%D0%B8%D0%BA%D0%BE%D0%B2%D1%81%D0%BA%D0%B0%D1%8F_%D0%94%D0%B0%D0%BD%D1%83%D1%82%D0%B0/%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_k-means&amp;diff=20538"/>
		<updated>2016-12-10T11:13:34Z</updated>

		<summary type="html">&lt;p&gt;DennZo1993: /* Масштабируемость алгоритма и его реализации */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Assignment|Zhum}}&lt;br /&gt;
&lt;br /&gt;
{{algorithm&lt;br /&gt;
| name              = Алгоритм k средних (k means)&lt;br /&gt;
| serial_complexity = &amp;lt;math&amp;gt;O(ikdn)&amp;lt;/math&amp;gt;&lt;br /&gt;
| input_data        = &amp;lt;math&amp;gt; dn &amp;lt;/math&amp;gt;&lt;br /&gt;
| output_data       = &amp;lt;math&amp;gt; n &amp;lt;/math&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
Авторы страницы &amp;lt;b&amp;gt;[[Участник:Бротиковская Данута|Данута Бротиковская]]&amp;lt;/b&amp;gt; и &amp;lt;b&amp;gt;[[Участник:DennZo1993|Денис Зобнин]]&amp;lt;/b&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
Оба автора внесли одинаковый вклад в написание статьи (поиск материалов, изучение статей, заполнение контента статьи), четких разграничений по пунктам статьи сделать невозможно. &lt;br /&gt;
&lt;br /&gt;
== Свойства и структура алгоритма ==&lt;br /&gt;
&lt;br /&gt;
=== Общее описание алгоритма ===&lt;br /&gt;
Алгоритм &amp;lt;b&amp;gt;&amp;lt;i&amp;gt;k средних&amp;lt;/i&amp;gt;&amp;lt;/b&amp;gt; (&amp;lt;b&amp;gt;&amp;lt;i&amp;gt;k means&amp;lt;/i&amp;gt;&amp;lt;/b&amp;gt;) &amp;amp;ndash; неиерархический&amp;lt;ref&amp;gt;&amp;quot;https://ru.wikipedia.org/wiki/Иерархическая_кластеризация&amp;quot;&amp;lt;/ref&amp;gt;, итерационный метод кластеризации&amp;lt;ref&amp;gt;&amp;quot;https://ru.wikipedia.org/wiki/Кластерный_анализ&amp;quot;&amp;lt;/ref&amp;gt;, получивший большую популярность благодаря своей простоте, наглядности реализации и достаточно высокому качеству работы. Был изобретен в 1950-х годах математиком &amp;lt;i&amp;gt;Гуго Штейнгаузом&amp;lt;/i&amp;gt;&amp;lt;ref&amp;gt;Steinhaus, Hugo. &amp;quot;Sur la division des corp materiels en parties.&amp;quot; Bull. Acad. Polon. Sci 1.804 (1956): 801.&amp;lt;/ref&amp;gt; и почти одновременно &amp;lt;i&amp;gt;Стюартом Ллойдом&amp;lt;/i&amp;gt;&amp;lt;ref&amp;gt;Lloyd, S. P. &amp;quot;Least square quantization in PCM. Bell Telephone Laboratories Paper. Published in journal much later: Lloyd, SP: Least squares quantization in PCM.&amp;quot; IEEE Trans. Inform. Theor.(1957/1982).&amp;lt;/ref&amp;gt;. Особую популярность приобрел после публикации работы &amp;lt;i&amp;gt;МакКуина&amp;lt;/i&amp;gt;&amp;lt;ref&amp;gt;MacQueen, James. &amp;quot;Some methods for classification and analysis of multivariate observations.&amp;quot; Proceedings of the fifth Berkeley symposium on mathematical statistics and probability. Vol. 1. No. 14. 1967.&amp;lt;/ref&amp;gt; в 1967.&lt;br /&gt;
&lt;br /&gt;
Алгоритм представляет собой версию EM-алгоритма&amp;lt;ref&amp;gt;&amp;quot;https://ru.wikipedia.org/wiki/EM-алгоритм&amp;quot;&amp;lt;/ref&amp;gt;, применяемого также для разделения смеси гауссиан. Основная идея &amp;lt;i&amp;gt;k means&amp;lt;/i&amp;gt; заключается в том, что данные произвольно разбиваются на кластеры, после чего итеративно перевычисляется центр масс для каждого кластера, полученного на предыдущем шаге, затем векторы разбиваются на кластеры вновь в соответствии с тем, какой из новых центров оказался ближе по выбранной метрике.&lt;br /&gt;
&lt;br /&gt;
Цель алгоритма заключается в разделении &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; наблюдений на &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластеров таким образом, чтобы каждое наблюдение принадлежало ровно одному кластеру, расположенному на наименьшем расстоянии от наблюдения.&lt;br /&gt;
&lt;br /&gt;
=== Математическое описание алгоритма ===&lt;br /&gt;
&amp;lt;b&amp;gt;&amp;lt;u&amp;gt;Дано:&amp;lt;/u&amp;gt;&amp;lt;/b&amp;gt;&lt;br /&gt;
* набор из &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; наблюдений &amp;lt;math&amp;gt;X=\{\mathbf{x}_1, \mathbf{x}_2, ..., \mathbf{x}_n\}, \mathbf{x}_i \in \mathbb{R}^d, i=\overline{1, n}&amp;lt;/math&amp;gt;;&lt;br /&gt;
* &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; - требуемое число кластеров, &amp;lt;math&amp;gt;k \in \mathbb{N}, k \leq n&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;&amp;lt;u&amp;gt;Требуется:&amp;lt;/u&amp;gt;&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Разделить множество наблюдений &amp;lt;math&amp;gt;X&amp;lt;/math&amp;gt; на &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластеров &amp;lt;math&amp;gt;S_1, S_2, ..., S_k&amp;lt;/math&amp;gt;:&lt;br /&gt;
*   &amp;lt;math&amp;gt;S_i \cap S_j= \varnothing, \quad i \ne j&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
*   &amp;lt;math&amp;gt;\bigcup_{i=1}^{k} S_i = X&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;&amp;lt;u&amp;gt;Действие алгоритма:&amp;lt;/u&amp;gt;&amp;lt;/b&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;Алгоритм &amp;lt;i&amp;gt;k means&amp;lt;/i&amp;gt; разбивает набор &amp;lt;math&amp;gt;X&amp;lt;/math&amp;gt; на &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; наборов &amp;lt;math&amp;gt;S_1, S_2, ..., S_k,&amp;lt;/math&amp;gt; таким образом, чтобы минимизировать сумму квадратов расстояний от каждой точки кластера до его центра (центр масс кластера). Введем обозначение, &amp;lt;math&amp;gt;S=\{S_1, S_2, ..., S_k\}&amp;lt;/math&amp;gt;. Тогда действие алгоритма &amp;lt;i&amp;gt;k means&amp;lt;/i&amp;gt; равносильно поиску:&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;table style=&amp;quot;width:100%&amp;quot;&amp;gt;&lt;br /&gt;
  &amp;lt;tr&amp;gt;&lt;br /&gt;
    &amp;lt;td align=&amp;quot;center&amp;quot; width=&amp;quot;90%&amp;quot;&amp;gt;&amp;lt;math&amp;gt;\arg\min_{S} \sum\limits_{i=1}^k \sum\limits_{\mathbf{x} \in S_i} \rho(\mathbf{x}, \mathbf{\mu}_i )^2,&amp;lt;/math&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;td align=&amp;quot;right&amp;quot;&amp;gt;&amp;lt;math&amp;gt;(1)&amp;lt;/math&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;/table&amp;gt;&lt;br /&gt;
где &amp;lt;math&amp;gt;\mathbf{\mu}_i&amp;lt;/math&amp;gt; &amp;amp;ndash; центры кластеров, &amp;lt;math&amp;gt;i=\overline{1,k}, \quad \rho(\mathbf{x}, \mathbf{\mu}_i)&amp;lt;/math&amp;gt; &amp;amp;ndash; функция расстояния между &amp;lt;math&amp;gt;\mathbf{x}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\mu_i&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;&amp;lt;u&amp;gt;Шаги алгоритма: &amp;lt;/u&amp;gt;&amp;lt;/b&amp;gt;&lt;br /&gt;
&amp;lt;ol&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&lt;br /&gt;
    &amp;lt;b&amp;gt;Начальный шаг: инициализация кластеров&amp;lt;/b&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;Выбирается произвольное множество точек &amp;lt;math&amp;gt;\mu_i, i=\overline{1,k}&amp;lt;/math&amp;gt;, рассматриваемых как начальные центры кластеров: &amp;lt;math&amp;gt;\mu_i^{(0)} = \mu_i, \quad i=\overline{1, k}&amp;lt;/math&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
  &amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&lt;br /&gt;
    &amp;lt;b&amp;gt;Распределение векторов по кластерам&amp;lt;/b&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Шаг&amp;lt;/b&amp;gt; &amp;lt;math&amp;gt;t: \forall \mathbf{x}_i \in X, i=\overline{1,n}: \mathbf{x}_i \in S_j \iff  j=\arg\min_{k}\rho(\mathbf{x}_i,\mathbf{\mu}_k^{(t-1)})^2&amp;lt;/math&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
  &amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&lt;br /&gt;
    &amp;lt;b&amp;gt;Пересчет центров кластеров&amp;lt;/b&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Шаг &amp;lt;/b&amp;gt; &amp;lt;math&amp;gt;t: \forall i=\overline{1,k}:  \mu_i^{(t)} = \cfrac{1}{|S_i|}\sum_{\mathbf{x}\in S_i}\mathbf{x}&amp;lt;/math&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
  &amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&lt;br /&gt;
    &amp;lt;b&amp;gt;Проверка условия останова:&amp;lt;/b&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
    &#039;&#039;&#039;if&#039;&#039;&#039; &amp;lt;math&amp;gt;\exist i\in \overline{1,k}: \mu_i^{(t)} \ne \mu_i^{(t-1)}&amp;lt;/math&amp;gt; &#039;&#039;&#039;then&#039;&#039;&#039;&lt;br /&gt;
        t = t + 1;&lt;br /&gt;
        goto 2;&lt;br /&gt;
    &#039;&#039;&#039;else&#039;&#039;&#039;&lt;br /&gt;
        &#039;&#039;&#039;stop&#039;&#039;&#039;&lt;br /&gt;
  &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ol&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Вычислительное ядро алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Вычислительным ядром являются шаги 2 и 3 приведенного выше алгоритма: &amp;lt;b&amp;gt;&amp;lt;i&amp;gt;распределение векторов по кластерам&amp;lt;/i&amp;gt;&amp;lt;/b&amp;gt; и &amp;lt;b&amp;gt;&amp;lt;i&amp;gt;пересчет центров кластеров&amp;lt;/i&amp;gt;&amp;lt;/b&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;&amp;lt;i&amp;gt;Распределение векторов&amp;lt;/i&amp;gt;&amp;lt;/b&amp;gt; по кластерам предполагает вычисление расстояний между каждым вектором &amp;lt;math&amp;gt;\mathbf{x}_i \in X, i= \overline{1,n}&amp;lt;/math&amp;gt; и центрами кластера &amp;lt;math&amp;gt;\mathbf{\mu}_j, j= \overline{1,k}&amp;lt;/math&amp;gt;. Таким образом, данный шаг предполагает &amp;lt;math&amp;gt;kn&amp;lt;/math&amp;gt; вычислений расстояний между d-мерными векторами. &lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;&amp;lt;i&amp;gt;Пересчет центров кластеров&amp;lt;/i&amp;gt;&amp;lt;/b&amp;gt; предполагает &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; вычислений центров масс &amp;lt;math&amp;gt;\mathbf{\mu}_i&amp;lt;/math&amp;gt; множеств &amp;lt;math&amp;gt;S_i, i=\overline{1,k}&amp;lt;/math&amp;gt; представленных выражением в шаге 3 представленного выше алгоритма.&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Макроструктура алгоритма ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Инициализация центров масс &amp;lt;math&amp;gt;\mu_1, ..., \mu_k&amp;lt;/math&amp;gt;&amp;lt;/b&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
Наиболее распространенными являются следующие стратегии:&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&lt;br /&gt;
    &amp;lt;b&amp;gt;Метод Forgy&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;В качестве начальных значений &amp;lt;math&amp;gt;\mu_1, ..., \mu_k&amp;lt;/math&amp;gt; берутся случайно выбранные векторы.&lt;br /&gt;
  &amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&lt;br /&gt;
    &amp;lt;b&amp;gt;Метод случайно разделения (Random Partitioning)&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;Для каждого вектора &amp;lt;math&amp;gt;\mathbf{x}_i \in X, i=\overline{1, n}&amp;lt;/math&amp;gt; выбирается случайным образом кластер &amp;lt;math&amp;gt;S_1, ..., S_k&amp;lt;/math&amp;gt;, после чего для каждого полученного кластера вычисляются значения &amp;lt;math&amp;gt;\mu_1, ..., \mu_k&amp;lt;/math&amp;gt;.&lt;br /&gt;
  &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Распределение векторов по кластерам&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Для этого шага алгоритма между векторами &amp;lt;math&amp;gt;\mathbf{x}_i \in X, i=\overline{1, n}&amp;lt;/math&amp;gt; и центрами кластеров &amp;lt;math&amp;gt;\mu_1, ..., \mu_k&amp;lt;/math&amp;gt; вычисляются &amp;lt;b&amp;gt;расстояния&amp;lt;/b&amp;gt; по формуле (как правило, используется Евлидово расстояние):&lt;br /&gt;
&amp;lt;table style=&amp;quot;width:100%&amp;quot;&amp;gt;&lt;br /&gt;
  &amp;lt;tr&amp;gt;&lt;br /&gt;
    &amp;lt;td align=&amp;quot;center&amp;quot; width=&amp;quot;90%&amp;quot;&amp;gt;&amp;lt;math&amp;gt; \mathbf{v}_1, \mathbf{v}_2 \in \mathbb{R}^d,  \quad \rho(\mathbf{v}_1, \mathbf{v}_2) = \lVert \mathbf{v}_1- \mathbf{v}_2 \rVert= \sqrt{\sum_{i=1}^{d}(\mathbf{v}_{1,i} - \mathbf{v}_{2,i})^2}&amp;lt;/math&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;td align=&amp;quot;right&amp;quot;&amp;gt;&amp;lt;math&amp;gt;(2)&amp;lt;/math&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;/table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Пересчет центров кластеров&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Для этого шага алгоритма производится пересчет центров кластера по &amp;lt;b&amp;gt;формуле вычисления центра масс&amp;lt;/b&amp;gt;:&lt;br /&gt;
&amp;lt;table style=&amp;quot;width:100%&amp;quot;&amp;gt;&lt;br /&gt;
  &amp;lt;tr&amp;gt;&lt;br /&gt;
    &amp;lt;td align=&amp;quot;center&amp;quot; width=&amp;quot;90%&amp;quot;&amp;gt;&amp;lt;math&amp;gt; \mu = \cfrac{1}{|S|}\sum_{\mathbf{x}\in S}\mathbf{x}&amp;lt;/math&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;td align=&amp;quot;right&amp;quot;&amp;gt;&amp;lt;math&amp;gt;(3)&amp;lt;/math&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;/table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Схема реализации последовательного алгоритма ===&lt;br /&gt;
&lt;br /&gt;
 &#039;&#039;&#039;algorithm&#039;&#039;&#039; k-means &#039;&#039;&#039;is&#039;&#039;&#039;&lt;br /&gt;
     &#039;&#039;&#039;1.&#039;&#039;&#039; Инициализировать центры кластеров &amp;lt;math&amp;gt;\mathbf{\mu}_i^{(1)}, i=\overline{1,k}&amp;lt;/math&amp;gt;&lt;br /&gt;
     &#039;&#039;&#039;2.&#039;&#039;&#039; &amp;lt;math&amp;gt;t \leftarrow 1&amp;lt;/math&amp;gt;&lt;br /&gt;
     &#039;&#039;&#039;3.&#039;&#039;&#039; &#039;&#039;&#039;Распределение по кластерам&#039;&#039;&#039;&amp;lt;br&amp;gt;&lt;br /&gt;
        &amp;lt;math&amp;gt;S_i^{(t)}=\{\mathbf{x}_p: \lVert\mathbf{x}_p-\mathbf{\mu}_i^{(t)}\rVert^2 \leq \lVert\mathbf{x}_p-\mathbf{\mu}_j^{(t)}\rVert^2 \quad \forall j=\overline{1,k}\},&amp;lt;/math&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
        где каждый вектор &amp;lt;math&amp;gt;\mathbf{x}_p&amp;lt;/math&amp;gt; соотносится единственному кластеру &amp;lt;math&amp;gt;S^{(t)}&amp;lt;/math&amp;gt;&lt;br /&gt;
     &#039;&#039;&#039;4.&#039;&#039;&#039; &#039;&#039;&#039;Обновление центров кластеров&#039;&#039;&#039;&amp;lt;br&amp;gt;&lt;br /&gt;
        &amp;lt;math&amp;gt;\mathbf{\mu}_i^{(t+1)} = \frac{1}{|S^{(t)}_i|} \sum_{\mathbf{x}_j \in S^{(t)}_i} \mathbf{x}_j &amp;lt;/math&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
     &#039;&#039;&#039;5.&#039;&#039;&#039; &#039;&#039;&#039;if&#039;&#039;&#039; &amp;lt;math&amp;gt;\exist i \in \overline{1,k}: \mathbf{\mu}_i^{(t+1)} \ne \mathbf{\mu}_i^{(t)}&amp;lt;/math&amp;gt; &#039;&#039;&#039;then&#039;&#039;&#039;&lt;br /&gt;
            t = t + 1;&lt;br /&gt;
            goto &#039;&#039;&#039;3&#039;&#039;&#039;;&lt;br /&gt;
        &#039;&#039;&#039;else&#039;&#039;&#039;&lt;br /&gt;
            &#039;&#039;&#039;stop&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
=== Последовательная сложность алгоритма===&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding-bottom: 20px&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;Обозначим &amp;lt;math&amp;gt;\Theta_{\rm centroid}^{d, m}&amp;lt;/math&amp;gt; временную сложность вычисления центорида кластера, число элементов которого равна &amp;lt;math&amp;gt;m&amp;lt;/math&amp;gt;,  в d-мерном пространстве.&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;Аналогично  &amp;lt;math&amp;gt;\Theta_{\rm distance}^d&amp;lt;/math&amp;gt; &amp;amp;ndash; временная сложность вычисления расстояния между двумя d-мерными векторами.&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding-bottom: 20px&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;Сложность шага инициализации &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластеров мощности &amp;lt;math&amp;gt;m&amp;lt;/math&amp;gt; в d-мерном пространстве &amp;amp;ndash; &amp;lt;math&amp;gt;\Theta_{\rm init}^{k, d, m}&amp;lt;/math&amp;gt;&amp;lt;/b&amp;gt;&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;i&amp;gt;Стратерия Forgy&amp;lt;/i&amp;gt;: вычисления не требуются, &amp;lt;math&amp;gt;\Theta_{\rm init}^{k, d, m} = 0&amp;lt;/math&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;i&amp;gt;Стратегия случайного разбиения&amp;lt;/i&amp;gt;: вычисление центров &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластеров,  &amp;lt;math&amp;gt;\Theta_{\rm init}^{k, d, m} = k \cdot \Theta_{\rm centroid}^{d, m}, m \le n&amp;lt;/math&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding-bottom: 20px&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Cложность шага распределения d мерных векторов по &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластерам &amp;amp;ndash; &amp;lt;math&amp;gt;\Theta_{\rm distribute}^{k, d}&amp;lt;/math&amp;gt;&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
На этом шаге для каждого вектора &amp;lt;math&amp;gt;\mathbf{x}_i \in X, i=\overline{1, n}&amp;lt;/math&amp;gt; вычисляется k расстояний до центров кластеров &amp;lt;math&amp;gt;\mathbf{\mu}_1, ...\mathbf{\mu}_k&amp;lt;/math&amp;gt;&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p align=&amp;quot;center&amp;quot;&amp;gt;&lt;br /&gt;
  &amp;lt;math&amp;gt;\Theta_{\rm distribute}^{k, d} = n \cdot k \cdot \Theta_{\rm distance}^d&amp;lt;/math&amp;gt;&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding-bottom: 20px&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;Сложность шага пересчета центров &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластеров размера &amp;lt;math&amp;gt;m&amp;lt;/math&amp;gt; в d-мерном пространстве &amp;amp;ndash; &amp;lt;math&amp;gt;\Theta_{\rm recenter}^{k, d, m}&amp;lt;/math&amp;gt;&amp;lt;/b&amp;gt;&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;На этом шаге вычисляется &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; центров кластеров &amp;lt;math&amp;gt;\mathbf{\mu}_1, ...\mathbf{\mu}_k&amp;lt;/math&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p align=&amp;quot;center&amp;quot;&amp;gt;&amp;lt;math&amp;gt;\Theta_{\rm recenter}^{k, d, m} = k \cdot \Theta_{\rm centroid}^{d, m}&amp;lt;/math&amp;gt; &amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding-bottom: 20px&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Рассчитаем &amp;lt;math&amp;gt;\Theta_{\rm centroid}^{d, m}&amp;lt;/math&amp;gt; для кластера, число элементов которого равно &amp;lt;math&amp;gt;m&amp;lt;/math&amp;gt;&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p align=&amp;quot;center&amp;quot;&amp;gt;&amp;lt;math&amp;gt;\Theta_{\rm centroid}^{d, m}&amp;lt;/math&amp;gt; = &amp;lt;math&amp;gt;m \cdot d&amp;lt;/math&amp;gt; сложений + &amp;lt;math&amp;gt;d&amp;lt;/math&amp;gt; делений &amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding-bottom: 20px&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Рассчитаем &amp;lt;math&amp;gt;\Theta_{\rm distance}^d&amp;lt;/math&amp;gt; в соответствие с формулой &amp;lt;math&amp;gt;(2)&amp;lt;/math&amp;gt;&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p align=&amp;quot;center&amp;quot;&amp;gt;&amp;lt;math&amp;gt;\Theta_{\rm distance}^d&amp;lt;/math&amp;gt; = &amp;lt;math&amp;gt;d&amp;lt;/math&amp;gt; вычитаний + &amp;lt;math&amp;gt;d&amp;lt;/math&amp;gt; умножений + &amp;lt;math&amp;gt;(d-1)&amp;lt;/math&amp;gt; сложение&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding-bottom: 20px&amp;quot;&amp;gt;&lt;br /&gt;
  &amp;lt;p&amp;gt;Предположим, что алгоритм сошелся за &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt; итераций, тогда временная сложность алгоритма &amp;lt;math&amp;gt;\Theta_{\rm k-means}^{d, n}&amp;lt;/math&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
  &amp;lt;p align=&amp;quot;center&amp;quot;&amp;gt;&amp;lt;b&amp;gt;&amp;lt;math&amp;gt;\Theta_{\rm k-means}^{d, n} \le \Theta_{\rm init}^{k, d, n} + i(\Theta_{\rm distribute}^{k, d} + \Theta_{\rm recenter}^{k, d, n})&amp;lt;/math&amp;gt;&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding-bottom: 5px&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;Операции сложения/вычитания:&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p align=&amp;quot;center&amp;quot;&amp;gt;&amp;lt;b&amp;gt;&amp;lt;math&amp;gt;\Theta_{\rm k-means}^{d, n} \le knd+ i(kn(2d-1) + knd) = knd+ i(kn(3d-1)) \thicksim O(ikdn)&amp;lt;/math&amp;gt;&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding-bottom: 20px&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;Операции умножения/деления:&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p align=&amp;quot;center&amp;quot;&amp;gt;&amp;lt;b&amp;gt;&amp;lt;math&amp;gt;\Theta_{\rm k-means}^{d, n} \le kd + i(knd + kd) = kd + ikd(n+1) \thicksim O(ikdn) &amp;lt;/math&amp;gt;&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding-bottom: 20px&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;Получаем, что &amp;lt;b&amp;gt;временная сложность&amp;lt;/b&amp;gt; алгоритма &amp;lt;b&amp;gt;k means&amp;lt;/b&amp;gt; кластеризации &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; &amp;lt;b&amp;gt;d-мерных&amp;lt;/b&amp;gt; векторов на &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластеров за &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt; итераций:&amp;lt;/p&amp;gt;&lt;br /&gt;
 &amp;lt;p align=&amp;quot;center&amp;quot;&amp;gt;&amp;lt;b&amp;gt;&amp;lt;math&amp;gt; \Theta_{\rm k-means}^{d, n} \thicksim O(ikdn) &amp;lt;/math&amp;gt;&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Информационный граф ===&lt;br /&gt;
&lt;br /&gt;
Рассмотрим информационный граф алгоритма. Алгоритм &amp;lt;i&amp;gt;k means&amp;lt;/i&amp;gt; начинается с этапа инициализации, после которого следуют итерации, на каждой из которых выполняется два последовательных шага (см. [[#Схема реализации последовательного алгоритма|&amp;quot;Схема реализации последовательного алгоритма&amp;quot;]]): &lt;br /&gt;
* распределение векторов по кластерам&lt;br /&gt;
* перерасчет центров кластеров&lt;br /&gt;
&lt;br /&gt;
Поскольку основная часть вычислений приходится на шаги итераций, распишем информационные графы данных шагов.&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Распределение векторов по кластерам&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
Информационный граф шага распределения векторов по кластерам представлен на &#039;&#039;рисунке 1&#039;&#039;. Исходами данного графа является исходные векторы &amp;lt;math&amp;gt;\mathbf{x}_1, ..., \mathbf{x}_n&amp;lt;/math&amp;gt;, а также центры кластеров &amp;lt;math&amp;gt;\mathbf{\mu}_1, ... \mathbf{\mu}_k&amp;lt;/math&amp;gt;, вычисленные ранее (на шаге инициализации, если рассматривается первая итерация алгоритма, или на шаге пересчета центров кластеров предыдущей итерации в противном случае). Каждая пара векторов данных &amp;lt;math&amp;gt;\mathbf{x}_i, i=\overline{1,n}&amp;lt;/math&amp;gt; и центров кластера &amp;lt;math&amp;gt;\mathbf{\mu}_j, j=\overline{1, k}&amp;lt;/math&amp;gt; : (&amp;lt;math&amp;gt;\mathbf{x}_i&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;\mathbf{\mu}_j&amp;lt;/math&amp;gt;) подаются на независимые узлы &amp;lt;i&amp;gt;&amp;quot;d&amp;quot;&amp;lt;/i&amp;gt; вычисления расстояния между векторами (более подробная схема вычисления расстояния представлена далее, &#039;&#039;рисунок 2&#039;&#039;). Далее узлы вычисления расстояния &amp;lt;i&amp;gt;&amp;quot;d&amp;quot;&amp;lt;/i&amp;gt;, соответствующие одному и тому же исходному вектору &amp;lt;math&amp;gt;\mathbf{x}_i&amp;lt;/math&amp;gt; передаются на один узел &amp;lt;i&amp;gt;&amp;quot;m&amp;quot;&amp;lt;/i&amp;gt;, где далее происходит вычисление новой метки кластера для каждого вектора &amp;lt;math&amp;gt;\mathbf{x}_i&amp;lt;/math&amp;gt; (берется кластер с минимальным результатом вычисления расстояния). На выходе графа выдаются метки кластеров , &amp;lt;math&amp;gt;L_1, ..., L_n&amp;lt;/math&amp;gt;, такие что &amp;lt;math&amp;gt;\forall \mathbf{x}_i, i=\overline{1, n}, \mathbf{x}_i \in S_j \Leftrightarrow L_i = j&amp;lt;/math&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
[[file:Clusterization.png|thumb|center|800px|Рис. 1. Схема распределения векторов по кластерам. &#039;&#039;d&#039;&#039; &amp;amp;ndash; вычисление расстояния между векторами; &#039;&#039;m&#039;&#039; &amp;amp;ndash; вычисление минимума.]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Вычисление расстояния между векторами&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
Подробная схема вычисления расстояния между векторами &amp;lt;math&amp;gt;\mathbf{x}_i, \mathbf{\mu}_j&amp;lt;/math&amp;gt; представлена на &#039;&#039;рисунке 2&#039;&#039;. Как показано на графе, узел вычисления расстояния между векторами &amp;lt;i&amp;gt;&amp;quot;d&amp;quot;&amp;lt;/i&amp;gt; состоит из шага взятия разности между векторами (узел &amp;quot;&amp;lt;math&amp;gt;-&amp;lt;/math&amp;gt;&amp;quot;) и взятия нормы получившегося вектора разности (узел &amp;quot;&amp;lt;math&amp;gt;||\cdot||^2&amp;lt;/math&amp;gt;&amp;quot;). Более подробно, вычисление расстояния между векторами &amp;lt;math&amp;gt;\mathbf{x}_i = {x_{i1,}, ...,{x_{in}}}, \mathbf{\mu}_j = {\mu_{j1}, ...,\mu_{jn}}&amp;lt;/math&amp;gt; может быть представлено как вычисление разности между каждой парой компонент &amp;lt;math&amp;gt;(x_{iz}, \mu_{jz}), z=\overline{1, d}&amp;lt;/math&amp;gt; (узел &amp;quot;&amp;lt;math&amp;gt;-&amp;lt;/math&amp;gt;&amp;quot;), далее возведение в квадрат для каждого узла &amp;quot;&amp;lt;math&amp;gt;-&amp;lt;/math&amp;gt;&amp;quot; (узел &amp;quot;&amp;lt;math&amp;gt;()^2&amp;lt;/math&amp;gt;&amp;quot;) и суммирования выходов всех узлов &amp;quot;&amp;lt;math&amp;gt;()^2&amp;lt;/math&amp;gt;&amp;quot; (узел &amp;quot;&amp;lt;math&amp;gt;+&amp;lt;/math&amp;gt;&amp;quot;).  &lt;br /&gt;
&lt;br /&gt;
[[file:dist_calc.png|thumb|center|800px|Рис. 2. Схема вычисления расстояния между вектором и центром кластера.]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Пересчет центров кластеров&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
Информационный граф шага пересчета центров кластеров представлен на &#039;&#039;рисунке 3&#039;&#039;. Исходами данного графа является исходные векторы &amp;lt;math&amp;gt;\mathbf{x}_1, ..., \mathbf{x}_n&amp;lt;/math&amp;gt;, а также им соответствующие метки кластера, &amp;lt;math&amp;gt;L_1, ..., L_n&amp;lt;/math&amp;gt;, такие что &amp;lt;math&amp;gt;\forall x_i, i=\overline{1, n}, \mathbf{x}_i \in S_j \Leftrightarrow L_i = j&amp;lt;/math&amp;gt;, вычисленные на этапе распределения векторов по кластерам. Все векторы &amp;lt;math&amp;gt;\mathbf{x}_1, ..., \mathbf{x}_n&amp;lt;/math&amp;gt; подаются в узлы &amp;lt;math&amp;gt;+_1, ...+_k&amp;lt;/math&amp;gt;, каждый узел &amp;lt;math&amp;gt;+_m, m = \overline{1,k}&amp;lt;/math&amp;gt; соответствует операции сложения векторов кластера с номером &amp;lt;math&amp;gt;m&amp;lt;/math&amp;gt;. Метки кластера &amp;lt;math&amp;gt;L_1, ..., L_n&amp;lt;/math&amp;gt; также совместно передаются на узлы &amp;lt;math&amp;gt;S_m, m = \overline{1,k}&amp;lt;/math&amp;gt;, на каждом из которых вычисляется количество векторов в соответствующем кластере (количество меток с соответствующим значением). Далее каждая пара выходов узлов &amp;lt;math&amp;gt;+_m&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;S_m&amp;lt;/math&amp;gt; подается на узел &amp;quot;&amp;lt;math&amp;gt;/&amp;lt;/math&amp;gt;&amp;quot;, где производится деление суммы векторов кластера на количество элементов в нем. Значения, вычисленные на узлах &amp;quot;&amp;lt;math&amp;gt;/&amp;lt;/math&amp;gt;&amp;quot;, присваиваются новым центрам кластеров (выходные значения графа).&lt;br /&gt;
&lt;br /&gt;
[[file:Recluster.png|thumb|center|800px|Рис. 3. Схема пересчета центров кластеров]]&lt;br /&gt;
&lt;br /&gt;
=== Ресурс параллелизма алгоритма ===&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
Работа алгоритма состоит из &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt; итераций, в каждой из которых происходит &amp;lt;b&amp;gt;распределение d-мерных векторов по &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластерам&amp;lt;/b&amp;gt;, а также &amp;lt;b&amp;gt;пересчет центров кластеров в d-мерном пространстве&amp;lt;/b&amp;gt;. В шаге &amp;lt;b&amp;gt;распределения d-мерных векторов по &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластерам&amp;lt;/b&amp;gt; расстояния между вектором и центрами кластеров вычисляются независимо (отсутствуют информационные зависимости). &amp;lt;b&amp;gt;Центры масс кластеров&amp;lt;/b&amp;gt; также пересчитываются независимо друг от друга. Таким образом, имеет место [[глоссарий#Массовый параллелизм|&#039;&#039;массовый параллелизм&#039;&#039;]]. Вычислим параллельную сложность &amp;lt;math&amp;gt;\Psi_*&amp;lt;/math&amp;gt; каждого из шагов, а также параллельную сложность всего алгоритма, &amp;lt;math&amp;gt;\Psi_{\rm k-means}&amp;lt;/math&amp;gt;. Будем исходить из предположения, что может быть использовано любое необходимое число потоков.&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Распределение d-мерных векторов по &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластерам&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;  &lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
Поскольку на данном шаге для каждой пары векторов &amp;lt;math&amp;gt;\mathbf{x}_i, i=\overline{1,n}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\mathbf{\mu}_j, j=\overline{1,k}&amp;lt;/math&amp;gt; операции вычисления расстояния не зависят друг от друга, они могут выполняться параллельно. Тогда, разделив все вычисление расстояний на &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; потоков, получим, что в каждом потоке будет выполняться только одна операция вычисления расстояния между векторами размерности d. При этом каждому вычислительному потоку передаются координаты центров всех кластеров &amp;lt;math&amp;gt;\mathbf{\mu}_1, ..., \mathbf{\mu}_k&amp;lt;/math&amp;gt;. Таким образом, параллельная сложность данного шага определяется &amp;lt;i&amp;gt; сложностью параллельной операции вычисления расстояния между d-мерными векторами&amp;lt;/i&amp;gt;, &amp;lt;math&amp;gt;\Psi_{\rm distance}^d&amp;lt;/math&amp;gt;  и &amp;lt;i&amp;gt;сложностью определения наиболее близкого кластера&amp;lt;/i&amp;gt; (паралельное взятие минимума по расстояниям), &amp;lt;math&amp;gt;\Psi_{\rm min}^k&amp;lt;/math&amp;gt;. Для оценки &amp;lt;math&amp;gt;\Psi_{\rm distance}^d&amp;lt;/math&amp;gt; воспользуемся  [[Нахождение_частных_сумм_элементов_массива_сдваиванием | параллельной реализацией нахождения частичной суммы элементов массива путем сдваивания]]. Аналогично, &amp;lt;math&amp;gt;\Psi_{\rm min}^k = log(k)&amp;lt;/math&amp;gt;. В результате, &amp;lt;math&amp;gt;\Psi_{\rm distance}^d = O(log(d))&amp;lt;/math&amp;gt;.   Таким образом: &lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p align=&amp;quot;center&amp;quot;&amp;gt;&amp;lt;math&amp;gt;\Psi_{\rm distribute}^{k, d}  = \Psi_{\rm distance}^d + \Psi_{\rm min}^k = O(log(d))+O(log(k)) = O(log(kd))&amp;lt;/math&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Пересчет центров кластеров в d-мерном пространстве&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
Поскольку на данном шаге для каждого из &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластеров центр масс может быть вычислен независимо, данные операции могут быть выполнены в отдельных потоках. Таким образом, параллельная сложность данного шага, &amp;lt;math&amp;gt;\Psi_{\rm recenter}^{k, d}&amp;lt;/math&amp;gt;,  будет определяться &amp;lt;i&amp;gt;параллельной сложностью вычисления одного центра масс кластера размера &amp;lt;math&amp;gt;m&amp;lt;/math&amp;gt;&amp;lt;/i&amp;gt;, &amp;lt;math&amp;gt;\Psi_{\rm recenter}^{k, d}&amp;lt;/math&amp;gt;,  а так как &amp;lt;math&amp;gt;m \le n \Rightarrow \Psi_{\rm recenter}^{d, m} \le \Psi_{\rm recenter}^{d, n}&amp;lt;/math&amp;gt;. Сложность вычисления центра масс кластера d-мерных векторов размера n аналогично предыдущим вычислениям равна &amp;lt;math&amp;gt;O(log(n))&amp;lt;/math&amp;gt;. Тогда:  &lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p align=&amp;quot;center&amp;quot;&amp;gt;&amp;lt;math&amp;gt;\Psi_{\rm recenter}^{k, d}  \le \Psi_{\rm recenter}^{d, n} = O(log(n))&amp;lt;/math&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Общая параллельная сложность алгоритма&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
На каждой итерации необходимо обновление центров кластеров, которые будут использованы на следующей итерации. Таким образом, итерационный процесс выполняется последовательно&amp;lt;ref&amp;gt;Zhao, Weizhong, Huifang Ma, and Qing He. &amp;quot;Parallel k-means clustering based on mapreduce.&amp;quot; IEEE International Conference on Cloud Computing. Springer Berlin Heidelberg, 2009.&amp;lt;/ref&amp;gt;. Тогда, поскольку сложность каждой итерации  определяется &amp;lt;math&amp;gt;\Psi_{\rm distribute}^{k, d}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\Psi_{\rm recenter}&amp;lt;/math&amp;gt;, сложность всего алгоритма, &amp;lt;math&amp;gt;\Psi_{\rm k-means}&amp;lt;/math&amp;gt; в предположении, что было сделано &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt; операций определяется выражением&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p align=&amp;quot;center&amp;quot;&amp;gt;&amp;lt;math&amp;gt;\Psi_{\rm k-means} \approx i \cdot (\Psi_{\rm distribute}^{k, d} + \Psi_{\rm recenter}^{k, d}) \le i \cdot O(log(kdn))&amp;lt;/math&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Входные и выходные данные алгоритма ===&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;Входные данные&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;Матрица из &amp;lt;math&amp;gt;n \cdot d&amp;lt;/math&amp;gt; элементов &amp;lt;math&amp;gt;x_{i, j} \in \mathbb{R}, i=\overline{1, n}, j=\overline{1, d}&amp;lt;/math&amp;gt;&amp;amp;ndash; координат векторов (наблюдений).&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;Целое положительное число &amp;lt;math&amp;gt;k, k \le n&amp;lt;/math&amp;gt; &amp;amp;ndash; количество кластеров.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;Объем входных данных&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;math&amp;gt;1&amp;lt;/math&amp;gt; целое число + &amp;lt;math&amp;gt;n \cdot d&amp;lt;/math&amp;gt; вещественных чисел (при условии, что координаты &amp;amp;ndash; вещественные числа).&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;Выходные данные&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; целых положительных чисел &amp;lt;math&amp;gt;L_1, ..., L_n&amp;lt;/math&amp;gt;&amp;amp;ndash; номера кластеров, соотвествующие каждому вектору (при условии, что нумерация кластеров начинается с &amp;lt;math&amp;gt;1&amp;lt;/math&amp;gt;).&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;Объем выходных данных&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; целых положительных чисел.&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Свойства алгоритма ===&lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;[[глоссарий#Вычислительная мощность|&#039;&#039;Вычислительная мощность&#039;&#039;]]&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
Вычислительная мощность алгоритма &amp;lt;i&amp;gt;k means&amp;lt;/i&amp;gt; равна &amp;lt;math&amp;gt;\frac{ikdn}{nd} = ki &amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; &amp;amp;ndash; число кластеров, &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt; &amp;amp;ndash; число итераций алгоритма.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;[[глоссарий#Детерминированность |&#039;&#039;Детерминированность&#039;&#039;]] и [[глоссарий#Устойчивость |&#039;&#039;Устойчивость&#039;&#039;]] &amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
Алгоритм &amp;lt;i&amp;gt;k means&amp;lt;/i&amp;gt; является итерационным. Количество итераций алгоритма в общем случае не фиксируется и зависит от начального расположения объектов в пространстве, параметра &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt;, а также от начального приближения центров кластеров, &amp;lt;math&amp;gt;\mu_1, ..., \mu_k&amp;lt;/math&amp;gt;. В результате этого может варьироваться результат работы алгоритма. При неудачном выборе начальных параметров итерационный процесс может сойтись к локальному оптимуму&amp;lt;ref&amp;gt;Von Luxburg, Ulrike. Clustering Stability. Now Publishers Inc, 2010.&amp;lt;/ref&amp;gt;. По этим причинам алгоритм не является ни &amp;lt;b&amp;gt;детермирированным&amp;lt;/b&amp;gt;, ни &amp;lt;b&amp;gt;устойчивым&amp;lt;/b&amp;gt;.&lt;br /&gt;
 &lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Соотношение последовательной и параллельной сложности алгоритма&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\frac{\Theta_{\rm k-means}}{\Psi_{\rm k-means}} = \frac{O(ikdn)}{O(i \cdot log(kdn))}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Сильные стороны алгоритма&amp;lt;/b&amp;gt;:&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;i&amp;gt;Сравнительно высокая эффективность при простоте реализации&amp;lt;/i&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;i&amp;gt;Высокое качество кластеризации&amp;lt;/i&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;i&amp;gt;Возможность распараллеливания&amp;lt;/i&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;i&amp;gt;Существование множества модификаций&amp;lt;/i&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;Недостатки алгоритма&amp;lt;/b&amp;gt;&amp;lt;ref&amp;gt;Ortega, Joaquín Pérez, Ma Del Rocío Boone Rojas, and María J. Somodevilla. &amp;quot;Research issues on K-means Algorithm: An Experimental Trial Using Matlab.&amp;quot;&amp;lt;/ref&amp;gt;:&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;i&amp;gt;Количество кластеров является параметром алгоритма&amp;lt;/i&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;&amp;lt;i&amp;gt;Чувствительность к начальным условиям&amp;lt;/i&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;Инициализация центров кластеров в значительной степени влияет на результат кластеризации.&amp;lt;/p&amp;gt;&lt;br /&gt;
  &amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;&amp;lt;i&amp;gt;Чувствительность к выбросам и шумам&amp;lt;/i&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;Выбросы, далекие от центров настоящих кластеров, все равно учитываются при вычислении их центров.&amp;lt;/p&amp;gt;&lt;br /&gt;
  &amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;&amp;lt;i&amp;gt;Возможность сходимости к локальному оптимуму&amp;lt;/i&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;Итеративный подход не дает гарантии сходимости к оптимальному решению.&amp;lt;/p&amp;gt;&lt;br /&gt;
  &amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;&amp;lt;i&amp;gt;Использование понятия &amp;quot;среднего&amp;quot;&amp;lt;/i&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;Алгоритм неприменим к данным, для которых не определено понятие &amp;quot;среднего&amp;quot;, например, категориальным данным.&amp;lt;/p&amp;gt;&lt;br /&gt;
  &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&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;
Исследование масштабируемости параллельной реализации алгоритма k means проводилось на суперкомпьютере &amp;quot;Ломоносов&amp;quot;&amp;lt;ref name=&amp;quot;Lom&amp;quot;&amp;gt;Воеводин Вл., Жуматий С., Соболев С., Антонов А., Брызгалов П., Никитенко Д., Стефанов К., Воеводин Вад. Практика суперкомпьютера «Ломоносов» // Открытые системы, 2012, N 7, С. 36-39.&amp;lt;/ref&amp;gt; [http://parallel.ru/cluster Суперкомпьютерного комплекса Московского университета]. Алгоритм реализован на языке C с использованием средств MPI.&lt;br /&gt;
Для исследования масштабируемости проводилось множество запусков программы с разным значением параметра (количество векторов для кластеризации), а также с различным числом процессоров. Фиксировались результаты запусков &amp;amp;ndash; время работы &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt; и количество произведенных итераций алгоритма &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Параметры запусков для экспериментальной оценки:&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;Значения &amp;lt;b&amp;gt;количества векторов&amp;lt;/b&amp;gt; &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;: 20&#039;000, 30&#039;000, 50&#039;000, 100&#039;000, 200&#039;000, 300&#039;000, 500&#039;000, 700&#039;000, 1&#039;000&#039;000, 1&#039;500&#039;000, 2&#039;000&#039;000.&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;Значения &amp;lt;b&amp;gt;количества процессоров&amp;lt;/b&amp;gt; &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt;: 1, 8, 16, 32, 64, 128, 160, 192, 224, 256, 288, 320, 352, 384, 416, 448, 480, 512.&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;Значение &amp;lt;b&amp;gt;количества кластеров&amp;lt;/b&amp;gt; &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt;: 100.&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;Значение &amp;lt;b&amp;gt;размерности векторов&amp;lt;/b&amp;gt; &amp;lt;math&amp;gt;d&amp;lt;/math&amp;gt;: 10.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Для проведения экспериментов были сгенерированы нормально распределенные псевдослучайные данные (с использованием Python библиотеки [http://scikit-learn.org/ scikit-learn]):&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
from sklearn.datasets import make_classification&lt;br /&gt;
X1, Y1 = make_classification(n_features=10, n_redundant=2, n_informative=8,&lt;br /&gt;
                             n_clusters_per_class=1, n_classes=100,&lt;br /&gt;
                             n_samples=2000000)&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Для заданной конфигурации эксперимента (&amp;lt;math&amp;gt;n, d, p, k&amp;lt;/math&amp;gt;) и полученных результатов (&amp;lt;math&amp;gt;t, i&amp;lt;/math&amp;gt;)  [[Глоссарий#Производительность|производительность]]  и эффективность реализации расчитывались по формулам:&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
&amp;lt;ul&amp;gt;&amp;lt;li&amp;gt;&amp;lt;math&amp;gt;\rm Performance = \frac{N_{\rm k-means}^{d, n}}{t}\ \ (FLOPS),&amp;lt;/math&amp;gt;&amp;lt;/li&amp;gt;&amp;lt;/ul&amp;gt;&lt;br /&gt;
где &amp;lt;math&amp;gt;N_{\rm k-means}^{d, n}&amp;lt;/math&amp;gt; &amp;amp;ndash; точное число операций с плавающей точкой (операции с памятью, а также целочисленные операции не учитывались), вычисленное в соответствие с разделом [[#Последовательная сложность алгоритма| &amp;quot;Последовательная сложность алгоритма&amp;quot;]];&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
&amp;lt;ul&amp;gt;&amp;lt;li&amp;gt;&amp;lt;math&amp;gt;\rm Efficiency = \frac{100 \cdot Performance}{Performance_{\rm Peak}^{p}}\ \ (%),&amp;lt;/math&amp;gt;&amp;lt;/li&amp;gt;&amp;lt;/ul&amp;gt;&lt;br /&gt;
где &amp;lt;math&amp;gt;Performance_{Peak}^{p}&amp;lt;/math&amp;gt; &amp;amp;ndash; пиковая производительность суперкомпьютера при &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt; процессорах, вычисленная согласно спецификациям Intel&amp;lt;sup&amp;gt;&amp;amp;reg;&amp;lt;/sup&amp;gt; XEON&amp;lt;sup&amp;gt;&amp;amp;reg;&amp;lt;/sup&amp;gt; X5670&amp;lt;ref&amp;gt;&amp;quot;http://ark.intel.com/ru/products/47920/Intel-Xeon-Processor-X5670-12M-Cache-2_93-GHz-6_40-GTs-Intel-QPI&amp;quot;&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Графики зависимости производительности и эффективности параллельной реализации k means от числа векторов для кластеризации (&amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;) и числа процессоров (&amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt;) представлены на рисунках 4 и 5 соответственно.&lt;br /&gt;
&lt;br /&gt;
[[file:Flops.png|thumb|center|800px|Рис. 4. Параллельная реализация k means. График зависимости производительности реализации алгоритма от числа векторов для кластеризации (&amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;) и числа процессоров (&amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt;).]]&lt;br /&gt;
[[file:Efficiency.png|thumb|center|800px|Рис. 5. Параллельная реализация k means. График зависимости эффективности реализации алгоритма от числа векторов для кластеризации (&amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;) и числа процессоров (&amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt;).]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;В результате&amp;lt;/b&amp;gt; экспериментальной оценки были получены следующие оценки эффективности реализации:&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;b&amp;gt;Минимальное&amp;lt;/b&amp;gt; значение: 0.000409 % достигается при &amp;lt;math&amp;gt;n=20&#039;000, p=480&amp;lt;/math&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;b&amp;gt;Максимальное&amp;lt;/b&amp;gt; значение: 0.741119 % достигается при &amp;lt;math&amp;gt;n=300&#039;000, p=1&amp;lt;/math&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
Оценки масштабируемости реализации алгоритма k means:&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;b&amp;gt;По числу процессоров:&amp;lt;/b&amp;gt; -0.002683 &amp;amp;ndash; эффективность убывает с ростом числа процессоров. Данный результат вызван ростом накладных расходов для обеспечения параллельного выполнения алгоритма.&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;b&amp;gt;По размеру задачи:&amp;lt;/b&amp;gt; 0.002779 &amp;amp;ndash; эффективность растет с ростом числа векторов. Данный результат вызван тем, что при увеличении размера задачи, количество вычислений растет по сравнению с временем, затрачиваемым на пересылку данных.&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;b&amp;gt;Общая оценка:&amp;lt;/b&amp;gt; -0.000058 &amp;amp;ndash; можно сделать вывод, что в целом эффективность реализации незначительно уменьшается с ростом размера задачи и числа процессоров.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[https://github.com/serban/kmeans Использованная параллельная реализация алгоритма k means]&lt;br /&gt;
&lt;br /&gt;
=== Динамические характеристики и эффективность реализации алгоритма ===&lt;br /&gt;
=== Выводы для классов архитектур ===&lt;br /&gt;
=== Существующие реализации алгоритма ===&lt;br /&gt;
==== Открытое программное обеспечение ====&lt;br /&gt;
&amp;lt;ol&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;[https://www.icpsr.umich.edu/CrimeStat/ CrimeStat]&amp;lt;/li&amp;gt; Программное обеспечение, созданное для операционных систем Windows, предоставляющее инструменты статистического  и пространственного анализа для решения задачи картирования преступности.&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://juliastats.github.io Julia]&amp;lt;/li&amp;gt; Высокоуровневый высокопроизводительный свободный язык программирования с динамической типизацией, созданный для математических вычислений, содержит реализацию k-means.&lt;br /&gt;
  &amp;lt;li&amp;gt;[https://mahout.apache.org Mahout]&amp;lt;/li&amp;gt; Apache Mahout - Java библиотека для работы с алгоритмами машинного обучения с использованием MapReduce. Содержит реализацию k-means.&lt;br /&gt;
  &amp;lt;li&amp;gt;[https://www.gnu.org/software/octave/ Octave]&amp;lt;/li&amp;gt; Написанная на C++  свободная система для математических вычислений, использующая совместимый с MATLAB язык высокого уровня, содержит реализацию k-means.&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://spark.apache.org/docs/latest/mllib-clustering.html Spark]&amp;lt;/li&amp;gt; Распределенная реализация k-means содержится в библиотеке Mlib для работы с алгоритмами машинного обучения, взаимодействующая с Python библиотекой NumPy и библиотека R.&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://torch.ch Torch]&amp;lt;/li&amp;gt;  MATLAB-подобная библиотека для языка программирования Lua с открытым исходным кодом, предоставляет большое количество алгоритмов для глубинного обучения и научных расчётов. Ядро написано на Си, прикладная часть выполняется на LuaJIT, поддерживается распараллеливание вычислений средствами CUDA и OpenMP. Существуют реализации k-means.&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://www.cs.waikato.ac.nz/ml/weka/ Weka]&amp;lt;/li&amp;gt;  Cвободное программное обеспечение для анализа данных, написанное на Java. Содержит k-means и x-means.&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://accord-framework.net/docs/html/T_Accord_MachineLearning_KMeans.htm Accord.NET]&amp;lt;/li&amp;gt; C# реализация алгоритмов k-means, k-means++, k-modes.&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://docs.opencv.org/3.0-beta/doc/py_tutorials/py_ml/py_kmeans/py_kmeans_opencv/py_kmeans_opencv.html OpenCV]&amp;lt;/li&amp;gt; Написанная на С++ библиотека, направленная в основном на решение задач компьютерного зрения. Содержит реализацию k-means.&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://mlpack.org/ MLPACK]&amp;lt;/li&amp;gt; Масштабируемая С++ библиотека для работы с алгоритмами машинного обучения, содержит реализацию k-means.&lt;br /&gt;
  &amp;lt;li&amp;gt;[https://www.scipy.org/ SciPy]&amp;lt;/li&amp;gt; Библиотека Python, содержит множество реализаций k-means.&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://scikit-learn.org/ scikit-learn]&amp;lt;/li&amp;gt; Библиотека Python, содержит множество реализаций k-means.&lt;br /&gt;
  &amp;lt;li&amp;gt;[https://www.r-bloggers.com/k-means-clustering-in-r/ R]&amp;lt;/li&amp;gt; Язык программирования для статистической обработки данных и работы с графикой, а также свободная программная среда вычислений с открытым исходным кодом в рамках проекта GNU, содержит три реализации k-means.&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://elki.dbs.ifi.lmu.de ELKI]&amp;lt;/li&amp;gt; Java фреймворк, содержащий реализацию k-means, а также множество других алгоритмов кластеризации.&lt;br /&gt;
&amp;lt;/ol&amp;gt;&lt;br /&gt;
==== Проприетарное программное обеспечение  ====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ol&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;[https://www.ayasdi.com/blog/bigdata/topological-data-analysis-of-oil-and-gas-petrophysical-data/ Ayasdi]&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://www.stata.com/features/cluster-analysis/ Stata]&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://mathworld.wolfram.com/K-MeansClusteringAlgorithm.html Mathematica]&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://www.mathworks.com/help/stats/kmeans.html?requestedDomain=www.mathworks.com MATLAB]&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;[https://support.sas.com/rnd/app/stat/procedures/fastclus.html SAS]&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://docs.rapidminer.com/studio/operators/modeling/segmentation/k_means.html RapidMiner]&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;[https://blogs.sap.com/2013/03/28/sap-hana-pal-k-means-algorithm-or-how-to-do-customer-segmentation-for-the-telecommunications-industry/ SAP HANA]&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ol&amp;gt;&lt;br /&gt;
== Литература ==&lt;br /&gt;
&amp;lt;references /&amp;gt;&lt;/div&gt;</summary>
		<author><name>DennZo1993</name></author>
	</entry>
	<entry>
		<id>https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:%D0%91%D1%80%D0%BE%D1%82%D0%B8%D0%BA%D0%BE%D0%B2%D1%81%D0%BA%D0%B0%D1%8F_%D0%94%D0%B0%D0%BD%D1%83%D1%82%D0%B0/%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_k-means&amp;diff=20537</id>
		<title>Участник:Бротиковская Данута/Алгоритм k-means</title>
		<link rel="alternate" type="text/html" href="https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:%D0%91%D1%80%D0%BE%D1%82%D0%B8%D0%BA%D0%BE%D0%B2%D1%81%D0%BA%D0%B0%D1%8F_%D0%94%D0%B0%D0%BD%D1%83%D1%82%D0%B0/%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_k-means&amp;diff=20537"/>
		<updated>2016-12-10T11:13:02Z</updated>

		<summary type="html">&lt;p&gt;DennZo1993: /* Масштабируемость алгоритма и его реализации */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Assignment|Zhum}}&lt;br /&gt;
&lt;br /&gt;
{{algorithm&lt;br /&gt;
| name              = Алгоритм k средних (k means)&lt;br /&gt;
| serial_complexity = &amp;lt;math&amp;gt;O(ikdn)&amp;lt;/math&amp;gt;&lt;br /&gt;
| input_data        = &amp;lt;math&amp;gt; dn &amp;lt;/math&amp;gt;&lt;br /&gt;
| output_data       = &amp;lt;math&amp;gt; n &amp;lt;/math&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
Авторы страницы &amp;lt;b&amp;gt;[[Участник:Бротиковская Данута|Данута Бротиковская]]&amp;lt;/b&amp;gt; и &amp;lt;b&amp;gt;[[Участник:DennZo1993|Денис Зобнин]]&amp;lt;/b&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
Оба автора внесли одинаковый вклад в написание статьи (поиск материалов, изучение статей, заполнение контента статьи), четких разграничений по пунктам статьи сделать невозможно. &lt;br /&gt;
&lt;br /&gt;
== Свойства и структура алгоритма ==&lt;br /&gt;
&lt;br /&gt;
=== Общее описание алгоритма ===&lt;br /&gt;
Алгоритм &amp;lt;b&amp;gt;&amp;lt;i&amp;gt;k средних&amp;lt;/i&amp;gt;&amp;lt;/b&amp;gt; (&amp;lt;b&amp;gt;&amp;lt;i&amp;gt;k means&amp;lt;/i&amp;gt;&amp;lt;/b&amp;gt;) &amp;amp;ndash; неиерархический&amp;lt;ref&amp;gt;&amp;quot;https://ru.wikipedia.org/wiki/Иерархическая_кластеризация&amp;quot;&amp;lt;/ref&amp;gt;, итерационный метод кластеризации&amp;lt;ref&amp;gt;&amp;quot;https://ru.wikipedia.org/wiki/Кластерный_анализ&amp;quot;&amp;lt;/ref&amp;gt;, получивший большую популярность благодаря своей простоте, наглядности реализации и достаточно высокому качеству работы. Был изобретен в 1950-х годах математиком &amp;lt;i&amp;gt;Гуго Штейнгаузом&amp;lt;/i&amp;gt;&amp;lt;ref&amp;gt;Steinhaus, Hugo. &amp;quot;Sur la division des corp materiels en parties.&amp;quot; Bull. Acad. Polon. Sci 1.804 (1956): 801.&amp;lt;/ref&amp;gt; и почти одновременно &amp;lt;i&amp;gt;Стюартом Ллойдом&amp;lt;/i&amp;gt;&amp;lt;ref&amp;gt;Lloyd, S. P. &amp;quot;Least square quantization in PCM. Bell Telephone Laboratories Paper. Published in journal much later: Lloyd, SP: Least squares quantization in PCM.&amp;quot; IEEE Trans. Inform. Theor.(1957/1982).&amp;lt;/ref&amp;gt;. Особую популярность приобрел после публикации работы &amp;lt;i&amp;gt;МакКуина&amp;lt;/i&amp;gt;&amp;lt;ref&amp;gt;MacQueen, James. &amp;quot;Some methods for classification and analysis of multivariate observations.&amp;quot; Proceedings of the fifth Berkeley symposium on mathematical statistics and probability. Vol. 1. No. 14. 1967.&amp;lt;/ref&amp;gt; в 1967.&lt;br /&gt;
&lt;br /&gt;
Алгоритм представляет собой версию EM-алгоритма&amp;lt;ref&amp;gt;&amp;quot;https://ru.wikipedia.org/wiki/EM-алгоритм&amp;quot;&amp;lt;/ref&amp;gt;, применяемого также для разделения смеси гауссиан. Основная идея &amp;lt;i&amp;gt;k means&amp;lt;/i&amp;gt; заключается в том, что данные произвольно разбиваются на кластеры, после чего итеративно перевычисляется центр масс для каждого кластера, полученного на предыдущем шаге, затем векторы разбиваются на кластеры вновь в соответствии с тем, какой из новых центров оказался ближе по выбранной метрике.&lt;br /&gt;
&lt;br /&gt;
Цель алгоритма заключается в разделении &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; наблюдений на &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластеров таким образом, чтобы каждое наблюдение принадлежало ровно одному кластеру, расположенному на наименьшем расстоянии от наблюдения.&lt;br /&gt;
&lt;br /&gt;
=== Математическое описание алгоритма ===&lt;br /&gt;
&amp;lt;b&amp;gt;&amp;lt;u&amp;gt;Дано:&amp;lt;/u&amp;gt;&amp;lt;/b&amp;gt;&lt;br /&gt;
* набор из &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; наблюдений &amp;lt;math&amp;gt;X=\{\mathbf{x}_1, \mathbf{x}_2, ..., \mathbf{x}_n\}, \mathbf{x}_i \in \mathbb{R}^d, i=\overline{1, n}&amp;lt;/math&amp;gt;;&lt;br /&gt;
* &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; - требуемое число кластеров, &amp;lt;math&amp;gt;k \in \mathbb{N}, k \leq n&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;&amp;lt;u&amp;gt;Требуется:&amp;lt;/u&amp;gt;&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Разделить множество наблюдений &amp;lt;math&amp;gt;X&amp;lt;/math&amp;gt; на &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластеров &amp;lt;math&amp;gt;S_1, S_2, ..., S_k&amp;lt;/math&amp;gt;:&lt;br /&gt;
*   &amp;lt;math&amp;gt;S_i \cap S_j= \varnothing, \quad i \ne j&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
*   &amp;lt;math&amp;gt;\bigcup_{i=1}^{k} S_i = X&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;&amp;lt;u&amp;gt;Действие алгоритма:&amp;lt;/u&amp;gt;&amp;lt;/b&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;Алгоритм &amp;lt;i&amp;gt;k means&amp;lt;/i&amp;gt; разбивает набор &amp;lt;math&amp;gt;X&amp;lt;/math&amp;gt; на &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; наборов &amp;lt;math&amp;gt;S_1, S_2, ..., S_k,&amp;lt;/math&amp;gt; таким образом, чтобы минимизировать сумму квадратов расстояний от каждой точки кластера до его центра (центр масс кластера). Введем обозначение, &amp;lt;math&amp;gt;S=\{S_1, S_2, ..., S_k\}&amp;lt;/math&amp;gt;. Тогда действие алгоритма &amp;lt;i&amp;gt;k means&amp;lt;/i&amp;gt; равносильно поиску:&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;table style=&amp;quot;width:100%&amp;quot;&amp;gt;&lt;br /&gt;
  &amp;lt;tr&amp;gt;&lt;br /&gt;
    &amp;lt;td align=&amp;quot;center&amp;quot; width=&amp;quot;90%&amp;quot;&amp;gt;&amp;lt;math&amp;gt;\arg\min_{S} \sum\limits_{i=1}^k \sum\limits_{\mathbf{x} \in S_i} \rho(\mathbf{x}, \mathbf{\mu}_i )^2,&amp;lt;/math&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;td align=&amp;quot;right&amp;quot;&amp;gt;&amp;lt;math&amp;gt;(1)&amp;lt;/math&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;/table&amp;gt;&lt;br /&gt;
где &amp;lt;math&amp;gt;\mathbf{\mu}_i&amp;lt;/math&amp;gt; &amp;amp;ndash; центры кластеров, &amp;lt;math&amp;gt;i=\overline{1,k}, \quad \rho(\mathbf{x}, \mathbf{\mu}_i)&amp;lt;/math&amp;gt; &amp;amp;ndash; функция расстояния между &amp;lt;math&amp;gt;\mathbf{x}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\mu_i&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;&amp;lt;u&amp;gt;Шаги алгоритма: &amp;lt;/u&amp;gt;&amp;lt;/b&amp;gt;&lt;br /&gt;
&amp;lt;ol&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&lt;br /&gt;
    &amp;lt;b&amp;gt;Начальный шаг: инициализация кластеров&amp;lt;/b&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;Выбирается произвольное множество точек &amp;lt;math&amp;gt;\mu_i, i=\overline{1,k}&amp;lt;/math&amp;gt;, рассматриваемых как начальные центры кластеров: &amp;lt;math&amp;gt;\mu_i^{(0)} = \mu_i, \quad i=\overline{1, k}&amp;lt;/math&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
  &amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&lt;br /&gt;
    &amp;lt;b&amp;gt;Распределение векторов по кластерам&amp;lt;/b&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Шаг&amp;lt;/b&amp;gt; &amp;lt;math&amp;gt;t: \forall \mathbf{x}_i \in X, i=\overline{1,n}: \mathbf{x}_i \in S_j \iff  j=\arg\min_{k}\rho(\mathbf{x}_i,\mathbf{\mu}_k^{(t-1)})^2&amp;lt;/math&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
  &amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&lt;br /&gt;
    &amp;lt;b&amp;gt;Пересчет центров кластеров&amp;lt;/b&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Шаг &amp;lt;/b&amp;gt; &amp;lt;math&amp;gt;t: \forall i=\overline{1,k}:  \mu_i^{(t)} = \cfrac{1}{|S_i|}\sum_{\mathbf{x}\in S_i}\mathbf{x}&amp;lt;/math&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
  &amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&lt;br /&gt;
    &amp;lt;b&amp;gt;Проверка условия останова:&amp;lt;/b&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
    &#039;&#039;&#039;if&#039;&#039;&#039; &amp;lt;math&amp;gt;\exist i\in \overline{1,k}: \mu_i^{(t)} \ne \mu_i^{(t-1)}&amp;lt;/math&amp;gt; &#039;&#039;&#039;then&#039;&#039;&#039;&lt;br /&gt;
        t = t + 1;&lt;br /&gt;
        goto 2;&lt;br /&gt;
    &#039;&#039;&#039;else&#039;&#039;&#039;&lt;br /&gt;
        &#039;&#039;&#039;stop&#039;&#039;&#039;&lt;br /&gt;
  &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ol&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Вычислительное ядро алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Вычислительным ядром являются шаги 2 и 3 приведенного выше алгоритма: &amp;lt;b&amp;gt;&amp;lt;i&amp;gt;распределение векторов по кластерам&amp;lt;/i&amp;gt;&amp;lt;/b&amp;gt; и &amp;lt;b&amp;gt;&amp;lt;i&amp;gt;пересчет центров кластеров&amp;lt;/i&amp;gt;&amp;lt;/b&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;&amp;lt;i&amp;gt;Распределение векторов&amp;lt;/i&amp;gt;&amp;lt;/b&amp;gt; по кластерам предполагает вычисление расстояний между каждым вектором &amp;lt;math&amp;gt;\mathbf{x}_i \in X, i= \overline{1,n}&amp;lt;/math&amp;gt; и центрами кластера &amp;lt;math&amp;gt;\mathbf{\mu}_j, j= \overline{1,k}&amp;lt;/math&amp;gt;. Таким образом, данный шаг предполагает &amp;lt;math&amp;gt;kn&amp;lt;/math&amp;gt; вычислений расстояний между d-мерными векторами. &lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;&amp;lt;i&amp;gt;Пересчет центров кластеров&amp;lt;/i&amp;gt;&amp;lt;/b&amp;gt; предполагает &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; вычислений центров масс &amp;lt;math&amp;gt;\mathbf{\mu}_i&amp;lt;/math&amp;gt; множеств &amp;lt;math&amp;gt;S_i, i=\overline{1,k}&amp;lt;/math&amp;gt; представленных выражением в шаге 3 представленного выше алгоритма.&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Макроструктура алгоритма ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Инициализация центров масс &amp;lt;math&amp;gt;\mu_1, ..., \mu_k&amp;lt;/math&amp;gt;&amp;lt;/b&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
Наиболее распространенными являются следующие стратегии:&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&lt;br /&gt;
    &amp;lt;b&amp;gt;Метод Forgy&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;В качестве начальных значений &amp;lt;math&amp;gt;\mu_1, ..., \mu_k&amp;lt;/math&amp;gt; берутся случайно выбранные векторы.&lt;br /&gt;
  &amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&lt;br /&gt;
    &amp;lt;b&amp;gt;Метод случайно разделения (Random Partitioning)&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;Для каждого вектора &amp;lt;math&amp;gt;\mathbf{x}_i \in X, i=\overline{1, n}&amp;lt;/math&amp;gt; выбирается случайным образом кластер &amp;lt;math&amp;gt;S_1, ..., S_k&amp;lt;/math&amp;gt;, после чего для каждого полученного кластера вычисляются значения &amp;lt;math&amp;gt;\mu_1, ..., \mu_k&amp;lt;/math&amp;gt;.&lt;br /&gt;
  &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Распределение векторов по кластерам&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Для этого шага алгоритма между векторами &amp;lt;math&amp;gt;\mathbf{x}_i \in X, i=\overline{1, n}&amp;lt;/math&amp;gt; и центрами кластеров &amp;lt;math&amp;gt;\mu_1, ..., \mu_k&amp;lt;/math&amp;gt; вычисляются &amp;lt;b&amp;gt;расстояния&amp;lt;/b&amp;gt; по формуле (как правило, используется Евлидово расстояние):&lt;br /&gt;
&amp;lt;table style=&amp;quot;width:100%&amp;quot;&amp;gt;&lt;br /&gt;
  &amp;lt;tr&amp;gt;&lt;br /&gt;
    &amp;lt;td align=&amp;quot;center&amp;quot; width=&amp;quot;90%&amp;quot;&amp;gt;&amp;lt;math&amp;gt; \mathbf{v}_1, \mathbf{v}_2 \in \mathbb{R}^d,  \quad \rho(\mathbf{v}_1, \mathbf{v}_2) = \lVert \mathbf{v}_1- \mathbf{v}_2 \rVert= \sqrt{\sum_{i=1}^{d}(\mathbf{v}_{1,i} - \mathbf{v}_{2,i})^2}&amp;lt;/math&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;td align=&amp;quot;right&amp;quot;&amp;gt;&amp;lt;math&amp;gt;(2)&amp;lt;/math&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;/table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Пересчет центров кластеров&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Для этого шага алгоритма производится пересчет центров кластера по &amp;lt;b&amp;gt;формуле вычисления центра масс&amp;lt;/b&amp;gt;:&lt;br /&gt;
&amp;lt;table style=&amp;quot;width:100%&amp;quot;&amp;gt;&lt;br /&gt;
  &amp;lt;tr&amp;gt;&lt;br /&gt;
    &amp;lt;td align=&amp;quot;center&amp;quot; width=&amp;quot;90%&amp;quot;&amp;gt;&amp;lt;math&amp;gt; \mu = \cfrac{1}{|S|}\sum_{\mathbf{x}\in S}\mathbf{x}&amp;lt;/math&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;td align=&amp;quot;right&amp;quot;&amp;gt;&amp;lt;math&amp;gt;(3)&amp;lt;/math&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;/table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Схема реализации последовательного алгоритма ===&lt;br /&gt;
&lt;br /&gt;
 &#039;&#039;&#039;algorithm&#039;&#039;&#039; k-means &#039;&#039;&#039;is&#039;&#039;&#039;&lt;br /&gt;
     &#039;&#039;&#039;1.&#039;&#039;&#039; Инициализировать центры кластеров &amp;lt;math&amp;gt;\mathbf{\mu}_i^{(1)}, i=\overline{1,k}&amp;lt;/math&amp;gt;&lt;br /&gt;
     &#039;&#039;&#039;2.&#039;&#039;&#039; &amp;lt;math&amp;gt;t \leftarrow 1&amp;lt;/math&amp;gt;&lt;br /&gt;
     &#039;&#039;&#039;3.&#039;&#039;&#039; &#039;&#039;&#039;Распределение по кластерам&#039;&#039;&#039;&amp;lt;br&amp;gt;&lt;br /&gt;
        &amp;lt;math&amp;gt;S_i^{(t)}=\{\mathbf{x}_p: \lVert\mathbf{x}_p-\mathbf{\mu}_i^{(t)}\rVert^2 \leq \lVert\mathbf{x}_p-\mathbf{\mu}_j^{(t)}\rVert^2 \quad \forall j=\overline{1,k}\},&amp;lt;/math&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
        где каждый вектор &amp;lt;math&amp;gt;\mathbf{x}_p&amp;lt;/math&amp;gt; соотносится единственному кластеру &amp;lt;math&amp;gt;S^{(t)}&amp;lt;/math&amp;gt;&lt;br /&gt;
     &#039;&#039;&#039;4.&#039;&#039;&#039; &#039;&#039;&#039;Обновление центров кластеров&#039;&#039;&#039;&amp;lt;br&amp;gt;&lt;br /&gt;
        &amp;lt;math&amp;gt;\mathbf{\mu}_i^{(t+1)} = \frac{1}{|S^{(t)}_i|} \sum_{\mathbf{x}_j \in S^{(t)}_i} \mathbf{x}_j &amp;lt;/math&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
     &#039;&#039;&#039;5.&#039;&#039;&#039; &#039;&#039;&#039;if&#039;&#039;&#039; &amp;lt;math&amp;gt;\exist i \in \overline{1,k}: \mathbf{\mu}_i^{(t+1)} \ne \mathbf{\mu}_i^{(t)}&amp;lt;/math&amp;gt; &#039;&#039;&#039;then&#039;&#039;&#039;&lt;br /&gt;
            t = t + 1;&lt;br /&gt;
            goto &#039;&#039;&#039;3&#039;&#039;&#039;;&lt;br /&gt;
        &#039;&#039;&#039;else&#039;&#039;&#039;&lt;br /&gt;
            &#039;&#039;&#039;stop&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
=== Последовательная сложность алгоритма===&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding-bottom: 20px&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;Обозначим &amp;lt;math&amp;gt;\Theta_{\rm centroid}^{d, m}&amp;lt;/math&amp;gt; временную сложность вычисления центорида кластера, число элементов которого равна &amp;lt;math&amp;gt;m&amp;lt;/math&amp;gt;,  в d-мерном пространстве.&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;Аналогично  &amp;lt;math&amp;gt;\Theta_{\rm distance}^d&amp;lt;/math&amp;gt; &amp;amp;ndash; временная сложность вычисления расстояния между двумя d-мерными векторами.&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding-bottom: 20px&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;Сложность шага инициализации &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластеров мощности &amp;lt;math&amp;gt;m&amp;lt;/math&amp;gt; в d-мерном пространстве &amp;amp;ndash; &amp;lt;math&amp;gt;\Theta_{\rm init}^{k, d, m}&amp;lt;/math&amp;gt;&amp;lt;/b&amp;gt;&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;i&amp;gt;Стратерия Forgy&amp;lt;/i&amp;gt;: вычисления не требуются, &amp;lt;math&amp;gt;\Theta_{\rm init}^{k, d, m} = 0&amp;lt;/math&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;i&amp;gt;Стратегия случайного разбиения&amp;lt;/i&amp;gt;: вычисление центров &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластеров,  &amp;lt;math&amp;gt;\Theta_{\rm init}^{k, d, m} = k \cdot \Theta_{\rm centroid}^{d, m}, m \le n&amp;lt;/math&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding-bottom: 20px&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Cложность шага распределения d мерных векторов по &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластерам &amp;amp;ndash; &amp;lt;math&amp;gt;\Theta_{\rm distribute}^{k, d}&amp;lt;/math&amp;gt;&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
На этом шаге для каждого вектора &amp;lt;math&amp;gt;\mathbf{x}_i \in X, i=\overline{1, n}&amp;lt;/math&amp;gt; вычисляется k расстояний до центров кластеров &amp;lt;math&amp;gt;\mathbf{\mu}_1, ...\mathbf{\mu}_k&amp;lt;/math&amp;gt;&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p align=&amp;quot;center&amp;quot;&amp;gt;&lt;br /&gt;
  &amp;lt;math&amp;gt;\Theta_{\rm distribute}^{k, d} = n \cdot k \cdot \Theta_{\rm distance}^d&amp;lt;/math&amp;gt;&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding-bottom: 20px&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;Сложность шага пересчета центров &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластеров размера &amp;lt;math&amp;gt;m&amp;lt;/math&amp;gt; в d-мерном пространстве &amp;amp;ndash; &amp;lt;math&amp;gt;\Theta_{\rm recenter}^{k, d, m}&amp;lt;/math&amp;gt;&amp;lt;/b&amp;gt;&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;На этом шаге вычисляется &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; центров кластеров &amp;lt;math&amp;gt;\mathbf{\mu}_1, ...\mathbf{\mu}_k&amp;lt;/math&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p align=&amp;quot;center&amp;quot;&amp;gt;&amp;lt;math&amp;gt;\Theta_{\rm recenter}^{k, d, m} = k \cdot \Theta_{\rm centroid}^{d, m}&amp;lt;/math&amp;gt; &amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding-bottom: 20px&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Рассчитаем &amp;lt;math&amp;gt;\Theta_{\rm centroid}^{d, m}&amp;lt;/math&amp;gt; для кластера, число элементов которого равно &amp;lt;math&amp;gt;m&amp;lt;/math&amp;gt;&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p align=&amp;quot;center&amp;quot;&amp;gt;&amp;lt;math&amp;gt;\Theta_{\rm centroid}^{d, m}&amp;lt;/math&amp;gt; = &amp;lt;math&amp;gt;m \cdot d&amp;lt;/math&amp;gt; сложений + &amp;lt;math&amp;gt;d&amp;lt;/math&amp;gt; делений &amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding-bottom: 20px&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Рассчитаем &amp;lt;math&amp;gt;\Theta_{\rm distance}^d&amp;lt;/math&amp;gt; в соответствие с формулой &amp;lt;math&amp;gt;(2)&amp;lt;/math&amp;gt;&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p align=&amp;quot;center&amp;quot;&amp;gt;&amp;lt;math&amp;gt;\Theta_{\rm distance}^d&amp;lt;/math&amp;gt; = &amp;lt;math&amp;gt;d&amp;lt;/math&amp;gt; вычитаний + &amp;lt;math&amp;gt;d&amp;lt;/math&amp;gt; умножений + &amp;lt;math&amp;gt;(d-1)&amp;lt;/math&amp;gt; сложение&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding-bottom: 20px&amp;quot;&amp;gt;&lt;br /&gt;
  &amp;lt;p&amp;gt;Предположим, что алгоритм сошелся за &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt; итераций, тогда временная сложность алгоритма &amp;lt;math&amp;gt;\Theta_{\rm k-means}^{d, n}&amp;lt;/math&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
  &amp;lt;p align=&amp;quot;center&amp;quot;&amp;gt;&amp;lt;b&amp;gt;&amp;lt;math&amp;gt;\Theta_{\rm k-means}^{d, n} \le \Theta_{\rm init}^{k, d, n} + i(\Theta_{\rm distribute}^{k, d} + \Theta_{\rm recenter}^{k, d, n})&amp;lt;/math&amp;gt;&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding-bottom: 5px&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;Операции сложения/вычитания:&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p align=&amp;quot;center&amp;quot;&amp;gt;&amp;lt;b&amp;gt;&amp;lt;math&amp;gt;\Theta_{\rm k-means}^{d, n} \le knd+ i(kn(2d-1) + knd) = knd+ i(kn(3d-1)) \thicksim O(ikdn)&amp;lt;/math&amp;gt;&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding-bottom: 20px&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;Операции умножения/деления:&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p align=&amp;quot;center&amp;quot;&amp;gt;&amp;lt;b&amp;gt;&amp;lt;math&amp;gt;\Theta_{\rm k-means}^{d, n} \le kd + i(knd + kd) = kd + ikd(n+1) \thicksim O(ikdn) &amp;lt;/math&amp;gt;&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding-bottom: 20px&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;Получаем, что &amp;lt;b&amp;gt;временная сложность&amp;lt;/b&amp;gt; алгоритма &amp;lt;b&amp;gt;k means&amp;lt;/b&amp;gt; кластеризации &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; &amp;lt;b&amp;gt;d-мерных&amp;lt;/b&amp;gt; векторов на &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластеров за &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt; итераций:&amp;lt;/p&amp;gt;&lt;br /&gt;
 &amp;lt;p align=&amp;quot;center&amp;quot;&amp;gt;&amp;lt;b&amp;gt;&amp;lt;math&amp;gt; \Theta_{\rm k-means}^{d, n} \thicksim O(ikdn) &amp;lt;/math&amp;gt;&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Информационный граф ===&lt;br /&gt;
&lt;br /&gt;
Рассмотрим информационный граф алгоритма. Алгоритм &amp;lt;i&amp;gt;k means&amp;lt;/i&amp;gt; начинается с этапа инициализации, после которого следуют итерации, на каждой из которых выполняется два последовательных шага (см. [[#Схема реализации последовательного алгоритма|&amp;quot;Схема реализации последовательного алгоритма&amp;quot;]]): &lt;br /&gt;
* распределение векторов по кластерам&lt;br /&gt;
* перерасчет центров кластеров&lt;br /&gt;
&lt;br /&gt;
Поскольку основная часть вычислений приходится на шаги итераций, распишем информационные графы данных шагов.&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Распределение векторов по кластерам&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
Информационный граф шага распределения векторов по кластерам представлен на &#039;&#039;рисунке 1&#039;&#039;. Исходами данного графа является исходные векторы &amp;lt;math&amp;gt;\mathbf{x}_1, ..., \mathbf{x}_n&amp;lt;/math&amp;gt;, а также центры кластеров &amp;lt;math&amp;gt;\mathbf{\mu}_1, ... \mathbf{\mu}_k&amp;lt;/math&amp;gt;, вычисленные ранее (на шаге инициализации, если рассматривается первая итерация алгоритма, или на шаге пересчета центров кластеров предыдущей итерации в противном случае). Каждая пара векторов данных &amp;lt;math&amp;gt;\mathbf{x}_i, i=\overline{1,n}&amp;lt;/math&amp;gt; и центров кластера &amp;lt;math&amp;gt;\mathbf{\mu}_j, j=\overline{1, k}&amp;lt;/math&amp;gt; : (&amp;lt;math&amp;gt;\mathbf{x}_i&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;\mathbf{\mu}_j&amp;lt;/math&amp;gt;) подаются на независимые узлы &amp;lt;i&amp;gt;&amp;quot;d&amp;quot;&amp;lt;/i&amp;gt; вычисления расстояния между векторами (более подробная схема вычисления расстояния представлена далее, &#039;&#039;рисунок 2&#039;&#039;). Далее узлы вычисления расстояния &amp;lt;i&amp;gt;&amp;quot;d&amp;quot;&amp;lt;/i&amp;gt;, соответствующие одному и тому же исходному вектору &amp;lt;math&amp;gt;\mathbf{x}_i&amp;lt;/math&amp;gt; передаются на один узел &amp;lt;i&amp;gt;&amp;quot;m&amp;quot;&amp;lt;/i&amp;gt;, где далее происходит вычисление новой метки кластера для каждого вектора &amp;lt;math&amp;gt;\mathbf{x}_i&amp;lt;/math&amp;gt; (берется кластер с минимальным результатом вычисления расстояния). На выходе графа выдаются метки кластеров , &amp;lt;math&amp;gt;L_1, ..., L_n&amp;lt;/math&amp;gt;, такие что &amp;lt;math&amp;gt;\forall \mathbf{x}_i, i=\overline{1, n}, \mathbf{x}_i \in S_j \Leftrightarrow L_i = j&amp;lt;/math&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
[[file:Clusterization.png|thumb|center|800px|Рис. 1. Схема распределения векторов по кластерам. &#039;&#039;d&#039;&#039; &amp;amp;ndash; вычисление расстояния между векторами; &#039;&#039;m&#039;&#039; &amp;amp;ndash; вычисление минимума.]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Вычисление расстояния между векторами&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
Подробная схема вычисления расстояния между векторами &amp;lt;math&amp;gt;\mathbf{x}_i, \mathbf{\mu}_j&amp;lt;/math&amp;gt; представлена на &#039;&#039;рисунке 2&#039;&#039;. Как показано на графе, узел вычисления расстояния между векторами &amp;lt;i&amp;gt;&amp;quot;d&amp;quot;&amp;lt;/i&amp;gt; состоит из шага взятия разности между векторами (узел &amp;quot;&amp;lt;math&amp;gt;-&amp;lt;/math&amp;gt;&amp;quot;) и взятия нормы получившегося вектора разности (узел &amp;quot;&amp;lt;math&amp;gt;||\cdot||^2&amp;lt;/math&amp;gt;&amp;quot;). Более подробно, вычисление расстояния между векторами &amp;lt;math&amp;gt;\mathbf{x}_i = {x_{i1,}, ...,{x_{in}}}, \mathbf{\mu}_j = {\mu_{j1}, ...,\mu_{jn}}&amp;lt;/math&amp;gt; может быть представлено как вычисление разности между каждой парой компонент &amp;lt;math&amp;gt;(x_{iz}, \mu_{jz}), z=\overline{1, d}&amp;lt;/math&amp;gt; (узел &amp;quot;&amp;lt;math&amp;gt;-&amp;lt;/math&amp;gt;&amp;quot;), далее возведение в квадрат для каждого узла &amp;quot;&amp;lt;math&amp;gt;-&amp;lt;/math&amp;gt;&amp;quot; (узел &amp;quot;&amp;lt;math&amp;gt;()^2&amp;lt;/math&amp;gt;&amp;quot;) и суммирования выходов всех узлов &amp;quot;&amp;lt;math&amp;gt;()^2&amp;lt;/math&amp;gt;&amp;quot; (узел &amp;quot;&amp;lt;math&amp;gt;+&amp;lt;/math&amp;gt;&amp;quot;).  &lt;br /&gt;
&lt;br /&gt;
[[file:dist_calc.png|thumb|center|800px|Рис. 2. Схема вычисления расстояния между вектором и центром кластера.]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Пересчет центров кластеров&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
Информационный граф шага пересчета центров кластеров представлен на &#039;&#039;рисунке 3&#039;&#039;. Исходами данного графа является исходные векторы &amp;lt;math&amp;gt;\mathbf{x}_1, ..., \mathbf{x}_n&amp;lt;/math&amp;gt;, а также им соответствующие метки кластера, &amp;lt;math&amp;gt;L_1, ..., L_n&amp;lt;/math&amp;gt;, такие что &amp;lt;math&amp;gt;\forall x_i, i=\overline{1, n}, \mathbf{x}_i \in S_j \Leftrightarrow L_i = j&amp;lt;/math&amp;gt;, вычисленные на этапе распределения векторов по кластерам. Все векторы &amp;lt;math&amp;gt;\mathbf{x}_1, ..., \mathbf{x}_n&amp;lt;/math&amp;gt; подаются в узлы &amp;lt;math&amp;gt;+_1, ...+_k&amp;lt;/math&amp;gt;, каждый узел &amp;lt;math&amp;gt;+_m, m = \overline{1,k}&amp;lt;/math&amp;gt; соответствует операции сложения векторов кластера с номером &amp;lt;math&amp;gt;m&amp;lt;/math&amp;gt;. Метки кластера &amp;lt;math&amp;gt;L_1, ..., L_n&amp;lt;/math&amp;gt; также совместно передаются на узлы &amp;lt;math&amp;gt;S_m, m = \overline{1,k}&amp;lt;/math&amp;gt;, на каждом из которых вычисляется количество векторов в соответствующем кластере (количество меток с соответствующим значением). Далее каждая пара выходов узлов &amp;lt;math&amp;gt;+_m&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;S_m&amp;lt;/math&amp;gt; подается на узел &amp;quot;&amp;lt;math&amp;gt;/&amp;lt;/math&amp;gt;&amp;quot;, где производится деление суммы векторов кластера на количество элементов в нем. Значения, вычисленные на узлах &amp;quot;&amp;lt;math&amp;gt;/&amp;lt;/math&amp;gt;&amp;quot;, присваиваются новым центрам кластеров (выходные значения графа).&lt;br /&gt;
&lt;br /&gt;
[[file:Recluster.png|thumb|center|800px|Рис. 3. Схема пересчета центров кластеров]]&lt;br /&gt;
&lt;br /&gt;
=== Ресурс параллелизма алгоритма ===&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
Работа алгоритма состоит из &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt; итераций, в каждой из которых происходит &amp;lt;b&amp;gt;распределение d-мерных векторов по &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластерам&amp;lt;/b&amp;gt;, а также &amp;lt;b&amp;gt;пересчет центров кластеров в d-мерном пространстве&amp;lt;/b&amp;gt;. В шаге &amp;lt;b&amp;gt;распределения d-мерных векторов по &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластерам&amp;lt;/b&amp;gt; расстояния между вектором и центрами кластеров вычисляются независимо (отсутствуют информационные зависимости). &amp;lt;b&amp;gt;Центры масс кластеров&amp;lt;/b&amp;gt; также пересчитываются независимо друг от друга. Таким образом, имеет место [[глоссарий#Массовый параллелизм|&#039;&#039;массовый параллелизм&#039;&#039;]]. Вычислим параллельную сложность &amp;lt;math&amp;gt;\Psi_*&amp;lt;/math&amp;gt; каждого из шагов, а также параллельную сложность всего алгоритма, &amp;lt;math&amp;gt;\Psi_{\rm k-means}&amp;lt;/math&amp;gt;. Будем исходить из предположения, что может быть использовано любое необходимое число потоков.&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Распределение d-мерных векторов по &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластерам&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;  &lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
Поскольку на данном шаге для каждой пары векторов &amp;lt;math&amp;gt;\mathbf{x}_i, i=\overline{1,n}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\mathbf{\mu}_j, j=\overline{1,k}&amp;lt;/math&amp;gt; операции вычисления расстояния не зависят друг от друга, они могут выполняться параллельно. Тогда, разделив все вычисление расстояний на &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; потоков, получим, что в каждом потоке будет выполняться только одна операция вычисления расстояния между векторами размерности d. При этом каждому вычислительному потоку передаются координаты центров всех кластеров &amp;lt;math&amp;gt;\mathbf{\mu}_1, ..., \mathbf{\mu}_k&amp;lt;/math&amp;gt;. Таким образом, параллельная сложность данного шага определяется &amp;lt;i&amp;gt; сложностью параллельной операции вычисления расстояния между d-мерными векторами&amp;lt;/i&amp;gt;, &amp;lt;math&amp;gt;\Psi_{\rm distance}^d&amp;lt;/math&amp;gt;  и &amp;lt;i&amp;gt;сложностью определения наиболее близкого кластера&amp;lt;/i&amp;gt; (паралельное взятие минимума по расстояниям), &amp;lt;math&amp;gt;\Psi_{\rm min}^k&amp;lt;/math&amp;gt;. Для оценки &amp;lt;math&amp;gt;\Psi_{\rm distance}^d&amp;lt;/math&amp;gt; воспользуемся  [[Нахождение_частных_сумм_элементов_массива_сдваиванием | параллельной реализацией нахождения частичной суммы элементов массива путем сдваивания]]. Аналогично, &amp;lt;math&amp;gt;\Psi_{\rm min}^k = log(k)&amp;lt;/math&amp;gt;. В результате, &amp;lt;math&amp;gt;\Psi_{\rm distance}^d = O(log(d))&amp;lt;/math&amp;gt;.   Таким образом: &lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p align=&amp;quot;center&amp;quot;&amp;gt;&amp;lt;math&amp;gt;\Psi_{\rm distribute}^{k, d}  = \Psi_{\rm distance}^d + \Psi_{\rm min}^k = O(log(d))+O(log(k)) = O(log(kd))&amp;lt;/math&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Пересчет центров кластеров в d-мерном пространстве&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
Поскольку на данном шаге для каждого из &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластеров центр масс может быть вычислен независимо, данные операции могут быть выполнены в отдельных потоках. Таким образом, параллельная сложность данного шага, &amp;lt;math&amp;gt;\Psi_{\rm recenter}^{k, d}&amp;lt;/math&amp;gt;,  будет определяться &amp;lt;i&amp;gt;параллельной сложностью вычисления одного центра масс кластера размера &amp;lt;math&amp;gt;m&amp;lt;/math&amp;gt;&amp;lt;/i&amp;gt;, &amp;lt;math&amp;gt;\Psi_{\rm recenter}^{k, d}&amp;lt;/math&amp;gt;,  а так как &amp;lt;math&amp;gt;m \le n \Rightarrow \Psi_{\rm recenter}^{d, m} \le \Psi_{\rm recenter}^{d, n}&amp;lt;/math&amp;gt;. Сложность вычисления центра масс кластера d-мерных векторов размера n аналогично предыдущим вычислениям равна &amp;lt;math&amp;gt;O(log(n))&amp;lt;/math&amp;gt;. Тогда:  &lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p align=&amp;quot;center&amp;quot;&amp;gt;&amp;lt;math&amp;gt;\Psi_{\rm recenter}^{k, d}  \le \Psi_{\rm recenter}^{d, n} = O(log(n))&amp;lt;/math&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Общая параллельная сложность алгоритма&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
На каждой итерации необходимо обновление центров кластеров, которые будут использованы на следующей итерации. Таким образом, итерационный процесс выполняется последовательно&amp;lt;ref&amp;gt;Zhao, Weizhong, Huifang Ma, and Qing He. &amp;quot;Parallel k-means clustering based on mapreduce.&amp;quot; IEEE International Conference on Cloud Computing. Springer Berlin Heidelberg, 2009.&amp;lt;/ref&amp;gt;. Тогда, поскольку сложность каждой итерации  определяется &amp;lt;math&amp;gt;\Psi_{\rm distribute}^{k, d}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\Psi_{\rm recenter}&amp;lt;/math&amp;gt;, сложность всего алгоритма, &amp;lt;math&amp;gt;\Psi_{\rm k-means}&amp;lt;/math&amp;gt; в предположении, что было сделано &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt; операций определяется выражением&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p align=&amp;quot;center&amp;quot;&amp;gt;&amp;lt;math&amp;gt;\Psi_{\rm k-means} \approx i \cdot (\Psi_{\rm distribute}^{k, d} + \Psi_{\rm recenter}^{k, d}) \le i \cdot O(log(kdn))&amp;lt;/math&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Входные и выходные данные алгоритма ===&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;Входные данные&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;Матрица из &amp;lt;math&amp;gt;n \cdot d&amp;lt;/math&amp;gt; элементов &amp;lt;math&amp;gt;x_{i, j} \in \mathbb{R}, i=\overline{1, n}, j=\overline{1, d}&amp;lt;/math&amp;gt;&amp;amp;ndash; координат векторов (наблюдений).&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;Целое положительное число &amp;lt;math&amp;gt;k, k \le n&amp;lt;/math&amp;gt; &amp;amp;ndash; количество кластеров.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;Объем входных данных&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;math&amp;gt;1&amp;lt;/math&amp;gt; целое число + &amp;lt;math&amp;gt;n \cdot d&amp;lt;/math&amp;gt; вещественных чисел (при условии, что координаты &amp;amp;ndash; вещественные числа).&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;Выходные данные&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; целых положительных чисел &amp;lt;math&amp;gt;L_1, ..., L_n&amp;lt;/math&amp;gt;&amp;amp;ndash; номера кластеров, соотвествующие каждому вектору (при условии, что нумерация кластеров начинается с &amp;lt;math&amp;gt;1&amp;lt;/math&amp;gt;).&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;Объем выходных данных&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; целых положительных чисел.&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Свойства алгоритма ===&lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;[[глоссарий#Вычислительная мощность|&#039;&#039;Вычислительная мощность&#039;&#039;]]&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
Вычислительная мощность алгоритма &amp;lt;i&amp;gt;k means&amp;lt;/i&amp;gt; равна &amp;lt;math&amp;gt;\frac{ikdn}{nd} = ki &amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; &amp;amp;ndash; число кластеров, &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt; &amp;amp;ndash; число итераций алгоритма.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;[[глоссарий#Детерминированность |&#039;&#039;Детерминированность&#039;&#039;]] и [[глоссарий#Устойчивость |&#039;&#039;Устойчивость&#039;&#039;]] &amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
Алгоритм &amp;lt;i&amp;gt;k means&amp;lt;/i&amp;gt; является итерационным. Количество итераций алгоритма в общем случае не фиксируется и зависит от начального расположения объектов в пространстве, параметра &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt;, а также от начального приближения центров кластеров, &amp;lt;math&amp;gt;\mu_1, ..., \mu_k&amp;lt;/math&amp;gt;. В результате этого может варьироваться результат работы алгоритма. При неудачном выборе начальных параметров итерационный процесс может сойтись к локальному оптимуму&amp;lt;ref&amp;gt;Von Luxburg, Ulrike. Clustering Stability. Now Publishers Inc, 2010.&amp;lt;/ref&amp;gt;. По этим причинам алгоритм не является ни &amp;lt;b&amp;gt;детермирированным&amp;lt;/b&amp;gt;, ни &amp;lt;b&amp;gt;устойчивым&amp;lt;/b&amp;gt;.&lt;br /&gt;
 &lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Соотношение последовательной и параллельной сложности алгоритма&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\frac{\Theta_{\rm k-means}}{\Psi_{\rm k-means}} = \frac{O(ikdn)}{O(i \cdot log(kdn))}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Сильные стороны алгоритма&amp;lt;/b&amp;gt;:&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;i&amp;gt;Сравнительно высокая эффективность при простоте реализации&amp;lt;/i&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;i&amp;gt;Высокое качество кластеризации&amp;lt;/i&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;i&amp;gt;Возможность распараллеливания&amp;lt;/i&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;i&amp;gt;Существование множества модификаций&amp;lt;/i&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;Недостатки алгоритма&amp;lt;/b&amp;gt;&amp;lt;ref&amp;gt;Ortega, Joaquín Pérez, Ma Del Rocío Boone Rojas, and María J. Somodevilla. &amp;quot;Research issues on K-means Algorithm: An Experimental Trial Using Matlab.&amp;quot;&amp;lt;/ref&amp;gt;:&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;i&amp;gt;Количество кластеров является параметром алгоритма&amp;lt;/i&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;&amp;lt;i&amp;gt;Чувствительность к начальным условиям&amp;lt;/i&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;Инициализация центров кластеров в значительной степени влияет на результат кластеризации.&amp;lt;/p&amp;gt;&lt;br /&gt;
  &amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;&amp;lt;i&amp;gt;Чувствительность к выбросам и шумам&amp;lt;/i&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;Выбросы, далекие от центров настоящих кластеров, все равно учитываются при вычислении их центров.&amp;lt;/p&amp;gt;&lt;br /&gt;
  &amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;&amp;lt;i&amp;gt;Возможность сходимости к локальному оптимуму&amp;lt;/i&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;Итеративный подход не дает гарантии сходимости к оптимальному решению.&amp;lt;/p&amp;gt;&lt;br /&gt;
  &amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;&amp;lt;i&amp;gt;Использование понятия &amp;quot;среднего&amp;quot;&amp;lt;/i&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;Алгоритм неприменим к данным, для которых не определено понятие &amp;quot;среднего&amp;quot;, например, категориальным данным.&amp;lt;/p&amp;gt;&lt;br /&gt;
  &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&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;
Исследование масштабируемости параллельной реализации алгоритма k means проводилось на суперкомпьютере &amp;quot;Ломоносов&amp;quot;&amp;lt;ref name=&amp;quot;Lom&amp;quot;&amp;gt;Воеводин Вл., Жуматий С., Соболев С., Антонов А., Брызгалов П., Никитенко Д., Стефанов К., Воеводин Вад. Практика суперкомпьютера «Ломоносов» // Открытые системы, 2012, N 7, С. 36-39.&amp;lt;/ref&amp;gt; [http://parallel.ru/cluster Суперкомпьютерного комплекса Московского университета]. Алгоритм реализован на языке C с использованием средств MPI.&lt;br /&gt;
Для исследования масштабируемости проводилось множество запусков программы с разным значением параметра (количество векторов для кластеризации), а также с различным числом процессоров. Фиксировались результаты запусков &amp;amp;ndash; время работы &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt; и количество произведенных итераций алгоритма &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Параметры запусков для экспериментальной оценки:&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;Значения &amp;lt;b&amp;gt;количества векторов&amp;lt;/b&amp;gt; &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;: 20&#039;000, 30&#039;000, 50&#039;000, 100&#039;000, 200&#039;000, 300&#039;000, 500&#039;000, 700&#039;000, 1&#039;000&#039;000, 1&#039;500&#039;000, 2&#039;000&#039;000.&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;Значения &amp;lt;b&amp;gt;количества процессоров&amp;lt;/b&amp;gt; &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt;: 1, 8, 16, 32, 64, 128, 160, 192, 224, 256, 288, 320, 352, 384, 416, 448, 480, 512.&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;Значение &amp;lt;b&amp;gt;количества кластеров&amp;lt;/b&amp;gt; &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt;: 100.&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;Значение &amp;lt;b&amp;gt;размерности векторов&amp;lt;/b&amp;gt; &amp;lt;math&amp;gt;d&amp;lt;/math&amp;gt;: 10.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Для проведения экспериментов были сгенерированы нормально распределенные псевдослучайные данные (с использованием Python библиотеки [http://scikit-learn.org/ scikit-learn]):&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
from sklearn.datasets import make_classification&lt;br /&gt;
X1, Y1 = make_classification(n_features=10, n_redundant=2, n_informative=8,&lt;br /&gt;
                             n_clusters_per_class=1, n_classes=100,&lt;br /&gt;
                             n_samples=2000000)&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Для заданной конфигурации эксперимента (&amp;lt;math&amp;gt;n, d, p, k&amp;lt;/math&amp;gt;) и полученных результатов (&amp;lt;math&amp;gt;t, i&amp;lt;/math&amp;gt;)  [[Глоссарий#Производительность|производительность]]  и эффективность реализации расчитывались по формулам:&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
&amp;lt;ul&amp;gt;&amp;lt;li&amp;gt;&amp;lt;math&amp;gt;Performance = \frac{N_{\rm k-means}^{d, n}}{t}\ \ (FLOPS),&amp;lt;/math&amp;gt;&amp;lt;/li&amp;gt;&amp;lt;/ul&amp;gt;&lt;br /&gt;
где &amp;lt;math&amp;gt;N_{k-means}^{d, n}&amp;lt;/math&amp;gt; &amp;amp;ndash; точное число операций с плавающей точкой (операции с памятью, а также целочисленные операции не учитывались), вычисленное в соответствие с разделом [[#Последовательная сложность алгоритма| &amp;quot;Последовательная сложность алгоритма&amp;quot;]];&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
&amp;lt;ul&amp;gt;&amp;lt;li&amp;gt;&amp;lt;math&amp;gt;Efficiency = \frac{100 \cdot Performance}{Performance_{\rm Peak}^{p}}\ \ (%),&amp;lt;/math&amp;gt;&amp;lt;/li&amp;gt;&amp;lt;/ul&amp;gt;&lt;br /&gt;
где &amp;lt;math&amp;gt;Performance_{Peak}^{p}&amp;lt;/math&amp;gt; &amp;amp;ndash; пиковая производительность суперкомпьютера при &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt; процессорах, вычисленная согласно спецификациям Intel&amp;lt;sup&amp;gt;&amp;amp;reg;&amp;lt;/sup&amp;gt; XEON&amp;lt;sup&amp;gt;&amp;amp;reg;&amp;lt;/sup&amp;gt; X5670&amp;lt;ref&amp;gt;&amp;quot;http://ark.intel.com/ru/products/47920/Intel-Xeon-Processor-X5670-12M-Cache-2_93-GHz-6_40-GTs-Intel-QPI&amp;quot;&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Графики зависимости производительности и эффективности параллельной реализации k means от числа векторов для кластеризации (&amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;) и числа процессоров (&amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt;) представлены на рисунках 4 и 5 соответственно.&lt;br /&gt;
&lt;br /&gt;
[[file:Flops.png|thumb|center|800px|Рис. 4. Параллельная реализация k means. График зависимости производительности реализации алгоритма от числа векторов для кластеризации (&amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;) и числа процессоров (&amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt;).]]&lt;br /&gt;
[[file:Efficiency.png|thumb|center|800px|Рис. 5. Параллельная реализация k means. График зависимости эффективности реализации алгоритма от числа векторов для кластеризации (&amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;) и числа процессоров (&amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt;).]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;В результате&amp;lt;/b&amp;gt; экспериментальной оценки были получены следующие оценки эффективности реализации:&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;b&amp;gt;Минимальное&amp;lt;/b&amp;gt; значение: 0.000409 % достигается при &amp;lt;math&amp;gt;n=20&#039;000, p=480&amp;lt;/math&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;b&amp;gt;Максимальное&amp;lt;/b&amp;gt; значение: 0.741119 % достигается при &amp;lt;math&amp;gt;n=300&#039;000, p=1&amp;lt;/math&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
Оценки масштабируемости реализации алгоритма k means:&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;b&amp;gt;По числу процессоров:&amp;lt;/b&amp;gt; -0.002683 &amp;amp;ndash; эффективность убывает с ростом числа процессоров. Данный результат вызван ростом накладных расходов для обеспечения параллельного выполнения алгоритма.&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;b&amp;gt;По размеру задачи:&amp;lt;/b&amp;gt; 0.002779 &amp;amp;ndash; эффективность растет с ростом числа векторов. Данный результат вызван тем, что при увеличении размера задачи, количество вычислений растет по сравнению с временем, затрачиваемым на пересылку данных.&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;b&amp;gt;Общая оценка:&amp;lt;/b&amp;gt; -0.000058 &amp;amp;ndash; можно сделать вывод, что в целом эффективность реализации незначительно уменьшается с ростом размера задачи и числа процессоров.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[https://github.com/serban/kmeans Использованная параллельная реализация алгоритма k means]&lt;br /&gt;
&lt;br /&gt;
=== Динамические характеристики и эффективность реализации алгоритма ===&lt;br /&gt;
=== Выводы для классов архитектур ===&lt;br /&gt;
=== Существующие реализации алгоритма ===&lt;br /&gt;
==== Открытое программное обеспечение ====&lt;br /&gt;
&amp;lt;ol&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;[https://www.icpsr.umich.edu/CrimeStat/ CrimeStat]&amp;lt;/li&amp;gt; Программное обеспечение, созданное для операционных систем Windows, предоставляющее инструменты статистического  и пространственного анализа для решения задачи картирования преступности.&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://juliastats.github.io Julia]&amp;lt;/li&amp;gt; Высокоуровневый высокопроизводительный свободный язык программирования с динамической типизацией, созданный для математических вычислений, содержит реализацию k-means.&lt;br /&gt;
  &amp;lt;li&amp;gt;[https://mahout.apache.org Mahout]&amp;lt;/li&amp;gt; Apache Mahout - Java библиотека для работы с алгоритмами машинного обучения с использованием MapReduce. Содержит реализацию k-means.&lt;br /&gt;
  &amp;lt;li&amp;gt;[https://www.gnu.org/software/octave/ Octave]&amp;lt;/li&amp;gt; Написанная на C++  свободная система для математических вычислений, использующая совместимый с MATLAB язык высокого уровня, содержит реализацию k-means.&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://spark.apache.org/docs/latest/mllib-clustering.html Spark]&amp;lt;/li&amp;gt; Распределенная реализация k-means содержится в библиотеке Mlib для работы с алгоритмами машинного обучения, взаимодействующая с Python библиотекой NumPy и библиотека R.&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://torch.ch Torch]&amp;lt;/li&amp;gt;  MATLAB-подобная библиотека для языка программирования Lua с открытым исходным кодом, предоставляет большое количество алгоритмов для глубинного обучения и научных расчётов. Ядро написано на Си, прикладная часть выполняется на LuaJIT, поддерживается распараллеливание вычислений средствами CUDA и OpenMP. Существуют реализации k-means.&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://www.cs.waikato.ac.nz/ml/weka/ Weka]&amp;lt;/li&amp;gt;  Cвободное программное обеспечение для анализа данных, написанное на Java. Содержит k-means и x-means.&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://accord-framework.net/docs/html/T_Accord_MachineLearning_KMeans.htm Accord.NET]&amp;lt;/li&amp;gt; C# реализация алгоритмов k-means, k-means++, k-modes.&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://docs.opencv.org/3.0-beta/doc/py_tutorials/py_ml/py_kmeans/py_kmeans_opencv/py_kmeans_opencv.html OpenCV]&amp;lt;/li&amp;gt; Написанная на С++ библиотека, направленная в основном на решение задач компьютерного зрения. Содержит реализацию k-means.&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://mlpack.org/ MLPACK]&amp;lt;/li&amp;gt; Масштабируемая С++ библиотека для работы с алгоритмами машинного обучения, содержит реализацию k-means.&lt;br /&gt;
  &amp;lt;li&amp;gt;[https://www.scipy.org/ SciPy]&amp;lt;/li&amp;gt; Библиотека Python, содержит множество реализаций k-means.&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://scikit-learn.org/ scikit-learn]&amp;lt;/li&amp;gt; Библиотека Python, содержит множество реализаций k-means.&lt;br /&gt;
  &amp;lt;li&amp;gt;[https://www.r-bloggers.com/k-means-clustering-in-r/ R]&amp;lt;/li&amp;gt; Язык программирования для статистической обработки данных и работы с графикой, а также свободная программная среда вычислений с открытым исходным кодом в рамках проекта GNU, содержит три реализации k-means.&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://elki.dbs.ifi.lmu.de ELKI]&amp;lt;/li&amp;gt; Java фреймворк, содержащий реализацию k-means, а также множество других алгоритмов кластеризации.&lt;br /&gt;
&amp;lt;/ol&amp;gt;&lt;br /&gt;
==== Проприетарное программное обеспечение  ====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ol&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;[https://www.ayasdi.com/blog/bigdata/topological-data-analysis-of-oil-and-gas-petrophysical-data/ Ayasdi]&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://www.stata.com/features/cluster-analysis/ Stata]&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://mathworld.wolfram.com/K-MeansClusteringAlgorithm.html Mathematica]&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://www.mathworks.com/help/stats/kmeans.html?requestedDomain=www.mathworks.com MATLAB]&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;[https://support.sas.com/rnd/app/stat/procedures/fastclus.html SAS]&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://docs.rapidminer.com/studio/operators/modeling/segmentation/k_means.html RapidMiner]&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;[https://blogs.sap.com/2013/03/28/sap-hana-pal-k-means-algorithm-or-how-to-do-customer-segmentation-for-the-telecommunications-industry/ SAP HANA]&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ol&amp;gt;&lt;br /&gt;
== Литература ==&lt;br /&gt;
&amp;lt;references /&amp;gt;&lt;/div&gt;</summary>
		<author><name>DennZo1993</name></author>
	</entry>
	<entry>
		<id>https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:%D0%91%D1%80%D0%BE%D1%82%D0%B8%D0%BA%D0%BE%D0%B2%D1%81%D0%BA%D0%B0%D1%8F_%D0%94%D0%B0%D0%BD%D1%83%D1%82%D0%B0/%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_k-means&amp;diff=20536</id>
		<title>Участник:Бротиковская Данута/Алгоритм k-means</title>
		<link rel="alternate" type="text/html" href="https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:%D0%91%D1%80%D0%BE%D1%82%D0%B8%D0%BA%D0%BE%D0%B2%D1%81%D0%BA%D0%B0%D1%8F_%D0%94%D0%B0%D0%BD%D1%83%D1%82%D0%B0/%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_k-means&amp;diff=20536"/>
		<updated>2016-12-10T11:12:22Z</updated>

		<summary type="html">&lt;p&gt;DennZo1993: /* Свойства алгоритма */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Assignment|Zhum}}&lt;br /&gt;
&lt;br /&gt;
{{algorithm&lt;br /&gt;
| name              = Алгоритм k средних (k means)&lt;br /&gt;
| serial_complexity = &amp;lt;math&amp;gt;O(ikdn)&amp;lt;/math&amp;gt;&lt;br /&gt;
| input_data        = &amp;lt;math&amp;gt; dn &amp;lt;/math&amp;gt;&lt;br /&gt;
| output_data       = &amp;lt;math&amp;gt; n &amp;lt;/math&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
Авторы страницы &amp;lt;b&amp;gt;[[Участник:Бротиковская Данута|Данута Бротиковская]]&amp;lt;/b&amp;gt; и &amp;lt;b&amp;gt;[[Участник:DennZo1993|Денис Зобнин]]&amp;lt;/b&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
Оба автора внесли одинаковый вклад в написание статьи (поиск материалов, изучение статей, заполнение контента статьи), четких разграничений по пунктам статьи сделать невозможно. &lt;br /&gt;
&lt;br /&gt;
== Свойства и структура алгоритма ==&lt;br /&gt;
&lt;br /&gt;
=== Общее описание алгоритма ===&lt;br /&gt;
Алгоритм &amp;lt;b&amp;gt;&amp;lt;i&amp;gt;k средних&amp;lt;/i&amp;gt;&amp;lt;/b&amp;gt; (&amp;lt;b&amp;gt;&amp;lt;i&amp;gt;k means&amp;lt;/i&amp;gt;&amp;lt;/b&amp;gt;) &amp;amp;ndash; неиерархический&amp;lt;ref&amp;gt;&amp;quot;https://ru.wikipedia.org/wiki/Иерархическая_кластеризация&amp;quot;&amp;lt;/ref&amp;gt;, итерационный метод кластеризации&amp;lt;ref&amp;gt;&amp;quot;https://ru.wikipedia.org/wiki/Кластерный_анализ&amp;quot;&amp;lt;/ref&amp;gt;, получивший большую популярность благодаря своей простоте, наглядности реализации и достаточно высокому качеству работы. Был изобретен в 1950-х годах математиком &amp;lt;i&amp;gt;Гуго Штейнгаузом&amp;lt;/i&amp;gt;&amp;lt;ref&amp;gt;Steinhaus, Hugo. &amp;quot;Sur la division des corp materiels en parties.&amp;quot; Bull. Acad. Polon. Sci 1.804 (1956): 801.&amp;lt;/ref&amp;gt; и почти одновременно &amp;lt;i&amp;gt;Стюартом Ллойдом&amp;lt;/i&amp;gt;&amp;lt;ref&amp;gt;Lloyd, S. P. &amp;quot;Least square quantization in PCM. Bell Telephone Laboratories Paper. Published in journal much later: Lloyd, SP: Least squares quantization in PCM.&amp;quot; IEEE Trans. Inform. Theor.(1957/1982).&amp;lt;/ref&amp;gt;. Особую популярность приобрел после публикации работы &amp;lt;i&amp;gt;МакКуина&amp;lt;/i&amp;gt;&amp;lt;ref&amp;gt;MacQueen, James. &amp;quot;Some methods for classification and analysis of multivariate observations.&amp;quot; Proceedings of the fifth Berkeley symposium on mathematical statistics and probability. Vol. 1. No. 14. 1967.&amp;lt;/ref&amp;gt; в 1967.&lt;br /&gt;
&lt;br /&gt;
Алгоритм представляет собой версию EM-алгоритма&amp;lt;ref&amp;gt;&amp;quot;https://ru.wikipedia.org/wiki/EM-алгоритм&amp;quot;&amp;lt;/ref&amp;gt;, применяемого также для разделения смеси гауссиан. Основная идея &amp;lt;i&amp;gt;k means&amp;lt;/i&amp;gt; заключается в том, что данные произвольно разбиваются на кластеры, после чего итеративно перевычисляется центр масс для каждого кластера, полученного на предыдущем шаге, затем векторы разбиваются на кластеры вновь в соответствии с тем, какой из новых центров оказался ближе по выбранной метрике.&lt;br /&gt;
&lt;br /&gt;
Цель алгоритма заключается в разделении &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; наблюдений на &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластеров таким образом, чтобы каждое наблюдение принадлежало ровно одному кластеру, расположенному на наименьшем расстоянии от наблюдения.&lt;br /&gt;
&lt;br /&gt;
=== Математическое описание алгоритма ===&lt;br /&gt;
&amp;lt;b&amp;gt;&amp;lt;u&amp;gt;Дано:&amp;lt;/u&amp;gt;&amp;lt;/b&amp;gt;&lt;br /&gt;
* набор из &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; наблюдений &amp;lt;math&amp;gt;X=\{\mathbf{x}_1, \mathbf{x}_2, ..., \mathbf{x}_n\}, \mathbf{x}_i \in \mathbb{R}^d, i=\overline{1, n}&amp;lt;/math&amp;gt;;&lt;br /&gt;
* &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; - требуемое число кластеров, &amp;lt;math&amp;gt;k \in \mathbb{N}, k \leq n&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;&amp;lt;u&amp;gt;Требуется:&amp;lt;/u&amp;gt;&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Разделить множество наблюдений &amp;lt;math&amp;gt;X&amp;lt;/math&amp;gt; на &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластеров &amp;lt;math&amp;gt;S_1, S_2, ..., S_k&amp;lt;/math&amp;gt;:&lt;br /&gt;
*   &amp;lt;math&amp;gt;S_i \cap S_j= \varnothing, \quad i \ne j&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
*   &amp;lt;math&amp;gt;\bigcup_{i=1}^{k} S_i = X&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;&amp;lt;u&amp;gt;Действие алгоритма:&amp;lt;/u&amp;gt;&amp;lt;/b&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;Алгоритм &amp;lt;i&amp;gt;k means&amp;lt;/i&amp;gt; разбивает набор &amp;lt;math&amp;gt;X&amp;lt;/math&amp;gt; на &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; наборов &amp;lt;math&amp;gt;S_1, S_2, ..., S_k,&amp;lt;/math&amp;gt; таким образом, чтобы минимизировать сумму квадратов расстояний от каждой точки кластера до его центра (центр масс кластера). Введем обозначение, &amp;lt;math&amp;gt;S=\{S_1, S_2, ..., S_k\}&amp;lt;/math&amp;gt;. Тогда действие алгоритма &amp;lt;i&amp;gt;k means&amp;lt;/i&amp;gt; равносильно поиску:&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;table style=&amp;quot;width:100%&amp;quot;&amp;gt;&lt;br /&gt;
  &amp;lt;tr&amp;gt;&lt;br /&gt;
    &amp;lt;td align=&amp;quot;center&amp;quot; width=&amp;quot;90%&amp;quot;&amp;gt;&amp;lt;math&amp;gt;\arg\min_{S} \sum\limits_{i=1}^k \sum\limits_{\mathbf{x} \in S_i} \rho(\mathbf{x}, \mathbf{\mu}_i )^2,&amp;lt;/math&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;td align=&amp;quot;right&amp;quot;&amp;gt;&amp;lt;math&amp;gt;(1)&amp;lt;/math&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;/table&amp;gt;&lt;br /&gt;
где &amp;lt;math&amp;gt;\mathbf{\mu}_i&amp;lt;/math&amp;gt; &amp;amp;ndash; центры кластеров, &amp;lt;math&amp;gt;i=\overline{1,k}, \quad \rho(\mathbf{x}, \mathbf{\mu}_i)&amp;lt;/math&amp;gt; &amp;amp;ndash; функция расстояния между &amp;lt;math&amp;gt;\mathbf{x}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\mu_i&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;&amp;lt;u&amp;gt;Шаги алгоритма: &amp;lt;/u&amp;gt;&amp;lt;/b&amp;gt;&lt;br /&gt;
&amp;lt;ol&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&lt;br /&gt;
    &amp;lt;b&amp;gt;Начальный шаг: инициализация кластеров&amp;lt;/b&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;Выбирается произвольное множество точек &amp;lt;math&amp;gt;\mu_i, i=\overline{1,k}&amp;lt;/math&amp;gt;, рассматриваемых как начальные центры кластеров: &amp;lt;math&amp;gt;\mu_i^{(0)} = \mu_i, \quad i=\overline{1, k}&amp;lt;/math&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
  &amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&lt;br /&gt;
    &amp;lt;b&amp;gt;Распределение векторов по кластерам&amp;lt;/b&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Шаг&amp;lt;/b&amp;gt; &amp;lt;math&amp;gt;t: \forall \mathbf{x}_i \in X, i=\overline{1,n}: \mathbf{x}_i \in S_j \iff  j=\arg\min_{k}\rho(\mathbf{x}_i,\mathbf{\mu}_k^{(t-1)})^2&amp;lt;/math&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
  &amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&lt;br /&gt;
    &amp;lt;b&amp;gt;Пересчет центров кластеров&amp;lt;/b&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Шаг &amp;lt;/b&amp;gt; &amp;lt;math&amp;gt;t: \forall i=\overline{1,k}:  \mu_i^{(t)} = \cfrac{1}{|S_i|}\sum_{\mathbf{x}\in S_i}\mathbf{x}&amp;lt;/math&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
  &amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&lt;br /&gt;
    &amp;lt;b&amp;gt;Проверка условия останова:&amp;lt;/b&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
    &#039;&#039;&#039;if&#039;&#039;&#039; &amp;lt;math&amp;gt;\exist i\in \overline{1,k}: \mu_i^{(t)} \ne \mu_i^{(t-1)}&amp;lt;/math&amp;gt; &#039;&#039;&#039;then&#039;&#039;&#039;&lt;br /&gt;
        t = t + 1;&lt;br /&gt;
        goto 2;&lt;br /&gt;
    &#039;&#039;&#039;else&#039;&#039;&#039;&lt;br /&gt;
        &#039;&#039;&#039;stop&#039;&#039;&#039;&lt;br /&gt;
  &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ol&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Вычислительное ядро алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Вычислительным ядром являются шаги 2 и 3 приведенного выше алгоритма: &amp;lt;b&amp;gt;&amp;lt;i&amp;gt;распределение векторов по кластерам&amp;lt;/i&amp;gt;&amp;lt;/b&amp;gt; и &amp;lt;b&amp;gt;&amp;lt;i&amp;gt;пересчет центров кластеров&amp;lt;/i&amp;gt;&amp;lt;/b&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;&amp;lt;i&amp;gt;Распределение векторов&amp;lt;/i&amp;gt;&amp;lt;/b&amp;gt; по кластерам предполагает вычисление расстояний между каждым вектором &amp;lt;math&amp;gt;\mathbf{x}_i \in X, i= \overline{1,n}&amp;lt;/math&amp;gt; и центрами кластера &amp;lt;math&amp;gt;\mathbf{\mu}_j, j= \overline{1,k}&amp;lt;/math&amp;gt;. Таким образом, данный шаг предполагает &amp;lt;math&amp;gt;kn&amp;lt;/math&amp;gt; вычислений расстояний между d-мерными векторами. &lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;&amp;lt;i&amp;gt;Пересчет центров кластеров&amp;lt;/i&amp;gt;&amp;lt;/b&amp;gt; предполагает &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; вычислений центров масс &amp;lt;math&amp;gt;\mathbf{\mu}_i&amp;lt;/math&amp;gt; множеств &amp;lt;math&amp;gt;S_i, i=\overline{1,k}&amp;lt;/math&amp;gt; представленных выражением в шаге 3 представленного выше алгоритма.&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Макроструктура алгоритма ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Инициализация центров масс &amp;lt;math&amp;gt;\mu_1, ..., \mu_k&amp;lt;/math&amp;gt;&amp;lt;/b&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
Наиболее распространенными являются следующие стратегии:&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&lt;br /&gt;
    &amp;lt;b&amp;gt;Метод Forgy&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;В качестве начальных значений &amp;lt;math&amp;gt;\mu_1, ..., \mu_k&amp;lt;/math&amp;gt; берутся случайно выбранные векторы.&lt;br /&gt;
  &amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&lt;br /&gt;
    &amp;lt;b&amp;gt;Метод случайно разделения (Random Partitioning)&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;Для каждого вектора &amp;lt;math&amp;gt;\mathbf{x}_i \in X, i=\overline{1, n}&amp;lt;/math&amp;gt; выбирается случайным образом кластер &amp;lt;math&amp;gt;S_1, ..., S_k&amp;lt;/math&amp;gt;, после чего для каждого полученного кластера вычисляются значения &amp;lt;math&amp;gt;\mu_1, ..., \mu_k&amp;lt;/math&amp;gt;.&lt;br /&gt;
  &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Распределение векторов по кластерам&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Для этого шага алгоритма между векторами &amp;lt;math&amp;gt;\mathbf{x}_i \in X, i=\overline{1, n}&amp;lt;/math&amp;gt; и центрами кластеров &amp;lt;math&amp;gt;\mu_1, ..., \mu_k&amp;lt;/math&amp;gt; вычисляются &amp;lt;b&amp;gt;расстояния&amp;lt;/b&amp;gt; по формуле (как правило, используется Евлидово расстояние):&lt;br /&gt;
&amp;lt;table style=&amp;quot;width:100%&amp;quot;&amp;gt;&lt;br /&gt;
  &amp;lt;tr&amp;gt;&lt;br /&gt;
    &amp;lt;td align=&amp;quot;center&amp;quot; width=&amp;quot;90%&amp;quot;&amp;gt;&amp;lt;math&amp;gt; \mathbf{v}_1, \mathbf{v}_2 \in \mathbb{R}^d,  \quad \rho(\mathbf{v}_1, \mathbf{v}_2) = \lVert \mathbf{v}_1- \mathbf{v}_2 \rVert= \sqrt{\sum_{i=1}^{d}(\mathbf{v}_{1,i} - \mathbf{v}_{2,i})^2}&amp;lt;/math&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;td align=&amp;quot;right&amp;quot;&amp;gt;&amp;lt;math&amp;gt;(2)&amp;lt;/math&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;/table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Пересчет центров кластеров&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Для этого шага алгоритма производится пересчет центров кластера по &amp;lt;b&amp;gt;формуле вычисления центра масс&amp;lt;/b&amp;gt;:&lt;br /&gt;
&amp;lt;table style=&amp;quot;width:100%&amp;quot;&amp;gt;&lt;br /&gt;
  &amp;lt;tr&amp;gt;&lt;br /&gt;
    &amp;lt;td align=&amp;quot;center&amp;quot; width=&amp;quot;90%&amp;quot;&amp;gt;&amp;lt;math&amp;gt; \mu = \cfrac{1}{|S|}\sum_{\mathbf{x}\in S}\mathbf{x}&amp;lt;/math&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;td align=&amp;quot;right&amp;quot;&amp;gt;&amp;lt;math&amp;gt;(3)&amp;lt;/math&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;/table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Схема реализации последовательного алгоритма ===&lt;br /&gt;
&lt;br /&gt;
 &#039;&#039;&#039;algorithm&#039;&#039;&#039; k-means &#039;&#039;&#039;is&#039;&#039;&#039;&lt;br /&gt;
     &#039;&#039;&#039;1.&#039;&#039;&#039; Инициализировать центры кластеров &amp;lt;math&amp;gt;\mathbf{\mu}_i^{(1)}, i=\overline{1,k}&amp;lt;/math&amp;gt;&lt;br /&gt;
     &#039;&#039;&#039;2.&#039;&#039;&#039; &amp;lt;math&amp;gt;t \leftarrow 1&amp;lt;/math&amp;gt;&lt;br /&gt;
     &#039;&#039;&#039;3.&#039;&#039;&#039; &#039;&#039;&#039;Распределение по кластерам&#039;&#039;&#039;&amp;lt;br&amp;gt;&lt;br /&gt;
        &amp;lt;math&amp;gt;S_i^{(t)}=\{\mathbf{x}_p: \lVert\mathbf{x}_p-\mathbf{\mu}_i^{(t)}\rVert^2 \leq \lVert\mathbf{x}_p-\mathbf{\mu}_j^{(t)}\rVert^2 \quad \forall j=\overline{1,k}\},&amp;lt;/math&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
        где каждый вектор &amp;lt;math&amp;gt;\mathbf{x}_p&amp;lt;/math&amp;gt; соотносится единственному кластеру &amp;lt;math&amp;gt;S^{(t)}&amp;lt;/math&amp;gt;&lt;br /&gt;
     &#039;&#039;&#039;4.&#039;&#039;&#039; &#039;&#039;&#039;Обновление центров кластеров&#039;&#039;&#039;&amp;lt;br&amp;gt;&lt;br /&gt;
        &amp;lt;math&amp;gt;\mathbf{\mu}_i^{(t+1)} = \frac{1}{|S^{(t)}_i|} \sum_{\mathbf{x}_j \in S^{(t)}_i} \mathbf{x}_j &amp;lt;/math&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
     &#039;&#039;&#039;5.&#039;&#039;&#039; &#039;&#039;&#039;if&#039;&#039;&#039; &amp;lt;math&amp;gt;\exist i \in \overline{1,k}: \mathbf{\mu}_i^{(t+1)} \ne \mathbf{\mu}_i^{(t)}&amp;lt;/math&amp;gt; &#039;&#039;&#039;then&#039;&#039;&#039;&lt;br /&gt;
            t = t + 1;&lt;br /&gt;
            goto &#039;&#039;&#039;3&#039;&#039;&#039;;&lt;br /&gt;
        &#039;&#039;&#039;else&#039;&#039;&#039;&lt;br /&gt;
            &#039;&#039;&#039;stop&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
=== Последовательная сложность алгоритма===&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding-bottom: 20px&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;Обозначим &amp;lt;math&amp;gt;\Theta_{\rm centroid}^{d, m}&amp;lt;/math&amp;gt; временную сложность вычисления центорида кластера, число элементов которого равна &amp;lt;math&amp;gt;m&amp;lt;/math&amp;gt;,  в d-мерном пространстве.&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;Аналогично  &amp;lt;math&amp;gt;\Theta_{\rm distance}^d&amp;lt;/math&amp;gt; &amp;amp;ndash; временная сложность вычисления расстояния между двумя d-мерными векторами.&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding-bottom: 20px&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;Сложность шага инициализации &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластеров мощности &amp;lt;math&amp;gt;m&amp;lt;/math&amp;gt; в d-мерном пространстве &amp;amp;ndash; &amp;lt;math&amp;gt;\Theta_{\rm init}^{k, d, m}&amp;lt;/math&amp;gt;&amp;lt;/b&amp;gt;&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;i&amp;gt;Стратерия Forgy&amp;lt;/i&amp;gt;: вычисления не требуются, &amp;lt;math&amp;gt;\Theta_{\rm init}^{k, d, m} = 0&amp;lt;/math&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;i&amp;gt;Стратегия случайного разбиения&amp;lt;/i&amp;gt;: вычисление центров &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластеров,  &amp;lt;math&amp;gt;\Theta_{\rm init}^{k, d, m} = k \cdot \Theta_{\rm centroid}^{d, m}, m \le n&amp;lt;/math&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding-bottom: 20px&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Cложность шага распределения d мерных векторов по &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластерам &amp;amp;ndash; &amp;lt;math&amp;gt;\Theta_{\rm distribute}^{k, d}&amp;lt;/math&amp;gt;&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
На этом шаге для каждого вектора &amp;lt;math&amp;gt;\mathbf{x}_i \in X, i=\overline{1, n}&amp;lt;/math&amp;gt; вычисляется k расстояний до центров кластеров &amp;lt;math&amp;gt;\mathbf{\mu}_1, ...\mathbf{\mu}_k&amp;lt;/math&amp;gt;&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p align=&amp;quot;center&amp;quot;&amp;gt;&lt;br /&gt;
  &amp;lt;math&amp;gt;\Theta_{\rm distribute}^{k, d} = n \cdot k \cdot \Theta_{\rm distance}^d&amp;lt;/math&amp;gt;&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding-bottom: 20px&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;Сложность шага пересчета центров &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластеров размера &amp;lt;math&amp;gt;m&amp;lt;/math&amp;gt; в d-мерном пространстве &amp;amp;ndash; &amp;lt;math&amp;gt;\Theta_{\rm recenter}^{k, d, m}&amp;lt;/math&amp;gt;&amp;lt;/b&amp;gt;&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;На этом шаге вычисляется &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; центров кластеров &amp;lt;math&amp;gt;\mathbf{\mu}_1, ...\mathbf{\mu}_k&amp;lt;/math&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p align=&amp;quot;center&amp;quot;&amp;gt;&amp;lt;math&amp;gt;\Theta_{\rm recenter}^{k, d, m} = k \cdot \Theta_{\rm centroid}^{d, m}&amp;lt;/math&amp;gt; &amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding-bottom: 20px&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Рассчитаем &amp;lt;math&amp;gt;\Theta_{\rm centroid}^{d, m}&amp;lt;/math&amp;gt; для кластера, число элементов которого равно &amp;lt;math&amp;gt;m&amp;lt;/math&amp;gt;&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p align=&amp;quot;center&amp;quot;&amp;gt;&amp;lt;math&amp;gt;\Theta_{\rm centroid}^{d, m}&amp;lt;/math&amp;gt; = &amp;lt;math&amp;gt;m \cdot d&amp;lt;/math&amp;gt; сложений + &amp;lt;math&amp;gt;d&amp;lt;/math&amp;gt; делений &amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding-bottom: 20px&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Рассчитаем &amp;lt;math&amp;gt;\Theta_{\rm distance}^d&amp;lt;/math&amp;gt; в соответствие с формулой &amp;lt;math&amp;gt;(2)&amp;lt;/math&amp;gt;&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p align=&amp;quot;center&amp;quot;&amp;gt;&amp;lt;math&amp;gt;\Theta_{\rm distance}^d&amp;lt;/math&amp;gt; = &amp;lt;math&amp;gt;d&amp;lt;/math&amp;gt; вычитаний + &amp;lt;math&amp;gt;d&amp;lt;/math&amp;gt; умножений + &amp;lt;math&amp;gt;(d-1)&amp;lt;/math&amp;gt; сложение&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding-bottom: 20px&amp;quot;&amp;gt;&lt;br /&gt;
  &amp;lt;p&amp;gt;Предположим, что алгоритм сошелся за &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt; итераций, тогда временная сложность алгоритма &amp;lt;math&amp;gt;\Theta_{\rm k-means}^{d, n}&amp;lt;/math&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
  &amp;lt;p align=&amp;quot;center&amp;quot;&amp;gt;&amp;lt;b&amp;gt;&amp;lt;math&amp;gt;\Theta_{\rm k-means}^{d, n} \le \Theta_{\rm init}^{k, d, n} + i(\Theta_{\rm distribute}^{k, d} + \Theta_{\rm recenter}^{k, d, n})&amp;lt;/math&amp;gt;&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding-bottom: 5px&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;Операции сложения/вычитания:&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p align=&amp;quot;center&amp;quot;&amp;gt;&amp;lt;b&amp;gt;&amp;lt;math&amp;gt;\Theta_{\rm k-means}^{d, n} \le knd+ i(kn(2d-1) + knd) = knd+ i(kn(3d-1)) \thicksim O(ikdn)&amp;lt;/math&amp;gt;&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding-bottom: 20px&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;Операции умножения/деления:&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p align=&amp;quot;center&amp;quot;&amp;gt;&amp;lt;b&amp;gt;&amp;lt;math&amp;gt;\Theta_{\rm k-means}^{d, n} \le kd + i(knd + kd) = kd + ikd(n+1) \thicksim O(ikdn) &amp;lt;/math&amp;gt;&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding-bottom: 20px&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;Получаем, что &amp;lt;b&amp;gt;временная сложность&amp;lt;/b&amp;gt; алгоритма &amp;lt;b&amp;gt;k means&amp;lt;/b&amp;gt; кластеризации &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; &amp;lt;b&amp;gt;d-мерных&amp;lt;/b&amp;gt; векторов на &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластеров за &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt; итераций:&amp;lt;/p&amp;gt;&lt;br /&gt;
 &amp;lt;p align=&amp;quot;center&amp;quot;&amp;gt;&amp;lt;b&amp;gt;&amp;lt;math&amp;gt; \Theta_{\rm k-means}^{d, n} \thicksim O(ikdn) &amp;lt;/math&amp;gt;&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Информационный граф ===&lt;br /&gt;
&lt;br /&gt;
Рассмотрим информационный граф алгоритма. Алгоритм &amp;lt;i&amp;gt;k means&amp;lt;/i&amp;gt; начинается с этапа инициализации, после которого следуют итерации, на каждой из которых выполняется два последовательных шага (см. [[#Схема реализации последовательного алгоритма|&amp;quot;Схема реализации последовательного алгоритма&amp;quot;]]): &lt;br /&gt;
* распределение векторов по кластерам&lt;br /&gt;
* перерасчет центров кластеров&lt;br /&gt;
&lt;br /&gt;
Поскольку основная часть вычислений приходится на шаги итераций, распишем информационные графы данных шагов.&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Распределение векторов по кластерам&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
Информационный граф шага распределения векторов по кластерам представлен на &#039;&#039;рисунке 1&#039;&#039;. Исходами данного графа является исходные векторы &amp;lt;math&amp;gt;\mathbf{x}_1, ..., \mathbf{x}_n&amp;lt;/math&amp;gt;, а также центры кластеров &amp;lt;math&amp;gt;\mathbf{\mu}_1, ... \mathbf{\mu}_k&amp;lt;/math&amp;gt;, вычисленные ранее (на шаге инициализации, если рассматривается первая итерация алгоритма, или на шаге пересчета центров кластеров предыдущей итерации в противном случае). Каждая пара векторов данных &amp;lt;math&amp;gt;\mathbf{x}_i, i=\overline{1,n}&amp;lt;/math&amp;gt; и центров кластера &amp;lt;math&amp;gt;\mathbf{\mu}_j, j=\overline{1, k}&amp;lt;/math&amp;gt; : (&amp;lt;math&amp;gt;\mathbf{x}_i&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;\mathbf{\mu}_j&amp;lt;/math&amp;gt;) подаются на независимые узлы &amp;lt;i&amp;gt;&amp;quot;d&amp;quot;&amp;lt;/i&amp;gt; вычисления расстояния между векторами (более подробная схема вычисления расстояния представлена далее, &#039;&#039;рисунок 2&#039;&#039;). Далее узлы вычисления расстояния &amp;lt;i&amp;gt;&amp;quot;d&amp;quot;&amp;lt;/i&amp;gt;, соответствующие одному и тому же исходному вектору &amp;lt;math&amp;gt;\mathbf{x}_i&amp;lt;/math&amp;gt; передаются на один узел &amp;lt;i&amp;gt;&amp;quot;m&amp;quot;&amp;lt;/i&amp;gt;, где далее происходит вычисление новой метки кластера для каждого вектора &amp;lt;math&amp;gt;\mathbf{x}_i&amp;lt;/math&amp;gt; (берется кластер с минимальным результатом вычисления расстояния). На выходе графа выдаются метки кластеров , &amp;lt;math&amp;gt;L_1, ..., L_n&amp;lt;/math&amp;gt;, такие что &amp;lt;math&amp;gt;\forall \mathbf{x}_i, i=\overline{1, n}, \mathbf{x}_i \in S_j \Leftrightarrow L_i = j&amp;lt;/math&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
[[file:Clusterization.png|thumb|center|800px|Рис. 1. Схема распределения векторов по кластерам. &#039;&#039;d&#039;&#039; &amp;amp;ndash; вычисление расстояния между векторами; &#039;&#039;m&#039;&#039; &amp;amp;ndash; вычисление минимума.]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Вычисление расстояния между векторами&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
Подробная схема вычисления расстояния между векторами &amp;lt;math&amp;gt;\mathbf{x}_i, \mathbf{\mu}_j&amp;lt;/math&amp;gt; представлена на &#039;&#039;рисунке 2&#039;&#039;. Как показано на графе, узел вычисления расстояния между векторами &amp;lt;i&amp;gt;&amp;quot;d&amp;quot;&amp;lt;/i&amp;gt; состоит из шага взятия разности между векторами (узел &amp;quot;&amp;lt;math&amp;gt;-&amp;lt;/math&amp;gt;&amp;quot;) и взятия нормы получившегося вектора разности (узел &amp;quot;&amp;lt;math&amp;gt;||\cdot||^2&amp;lt;/math&amp;gt;&amp;quot;). Более подробно, вычисление расстояния между векторами &amp;lt;math&amp;gt;\mathbf{x}_i = {x_{i1,}, ...,{x_{in}}}, \mathbf{\mu}_j = {\mu_{j1}, ...,\mu_{jn}}&amp;lt;/math&amp;gt; может быть представлено как вычисление разности между каждой парой компонент &amp;lt;math&amp;gt;(x_{iz}, \mu_{jz}), z=\overline{1, d}&amp;lt;/math&amp;gt; (узел &amp;quot;&amp;lt;math&amp;gt;-&amp;lt;/math&amp;gt;&amp;quot;), далее возведение в квадрат для каждого узла &amp;quot;&amp;lt;math&amp;gt;-&amp;lt;/math&amp;gt;&amp;quot; (узел &amp;quot;&amp;lt;math&amp;gt;()^2&amp;lt;/math&amp;gt;&amp;quot;) и суммирования выходов всех узлов &amp;quot;&amp;lt;math&amp;gt;()^2&amp;lt;/math&amp;gt;&amp;quot; (узел &amp;quot;&amp;lt;math&amp;gt;+&amp;lt;/math&amp;gt;&amp;quot;).  &lt;br /&gt;
&lt;br /&gt;
[[file:dist_calc.png|thumb|center|800px|Рис. 2. Схема вычисления расстояния между вектором и центром кластера.]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Пересчет центров кластеров&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
Информационный граф шага пересчета центров кластеров представлен на &#039;&#039;рисунке 3&#039;&#039;. Исходами данного графа является исходные векторы &amp;lt;math&amp;gt;\mathbf{x}_1, ..., \mathbf{x}_n&amp;lt;/math&amp;gt;, а также им соответствующие метки кластера, &amp;lt;math&amp;gt;L_1, ..., L_n&amp;lt;/math&amp;gt;, такие что &amp;lt;math&amp;gt;\forall x_i, i=\overline{1, n}, \mathbf{x}_i \in S_j \Leftrightarrow L_i = j&amp;lt;/math&amp;gt;, вычисленные на этапе распределения векторов по кластерам. Все векторы &amp;lt;math&amp;gt;\mathbf{x}_1, ..., \mathbf{x}_n&amp;lt;/math&amp;gt; подаются в узлы &amp;lt;math&amp;gt;+_1, ...+_k&amp;lt;/math&amp;gt;, каждый узел &amp;lt;math&amp;gt;+_m, m = \overline{1,k}&amp;lt;/math&amp;gt; соответствует операции сложения векторов кластера с номером &amp;lt;math&amp;gt;m&amp;lt;/math&amp;gt;. Метки кластера &amp;lt;math&amp;gt;L_1, ..., L_n&amp;lt;/math&amp;gt; также совместно передаются на узлы &amp;lt;math&amp;gt;S_m, m = \overline{1,k}&amp;lt;/math&amp;gt;, на каждом из которых вычисляется количество векторов в соответствующем кластере (количество меток с соответствующим значением). Далее каждая пара выходов узлов &amp;lt;math&amp;gt;+_m&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;S_m&amp;lt;/math&amp;gt; подается на узел &amp;quot;&amp;lt;math&amp;gt;/&amp;lt;/math&amp;gt;&amp;quot;, где производится деление суммы векторов кластера на количество элементов в нем. Значения, вычисленные на узлах &amp;quot;&amp;lt;math&amp;gt;/&amp;lt;/math&amp;gt;&amp;quot;, присваиваются новым центрам кластеров (выходные значения графа).&lt;br /&gt;
&lt;br /&gt;
[[file:Recluster.png|thumb|center|800px|Рис. 3. Схема пересчета центров кластеров]]&lt;br /&gt;
&lt;br /&gt;
=== Ресурс параллелизма алгоритма ===&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
Работа алгоритма состоит из &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt; итераций, в каждой из которых происходит &amp;lt;b&amp;gt;распределение d-мерных векторов по &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластерам&amp;lt;/b&amp;gt;, а также &amp;lt;b&amp;gt;пересчет центров кластеров в d-мерном пространстве&amp;lt;/b&amp;gt;. В шаге &amp;lt;b&amp;gt;распределения d-мерных векторов по &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластерам&amp;lt;/b&amp;gt; расстояния между вектором и центрами кластеров вычисляются независимо (отсутствуют информационные зависимости). &amp;lt;b&amp;gt;Центры масс кластеров&amp;lt;/b&amp;gt; также пересчитываются независимо друг от друга. Таким образом, имеет место [[глоссарий#Массовый параллелизм|&#039;&#039;массовый параллелизм&#039;&#039;]]. Вычислим параллельную сложность &amp;lt;math&amp;gt;\Psi_*&amp;lt;/math&amp;gt; каждого из шагов, а также параллельную сложность всего алгоритма, &amp;lt;math&amp;gt;\Psi_{\rm k-means}&amp;lt;/math&amp;gt;. Будем исходить из предположения, что может быть использовано любое необходимое число потоков.&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Распределение d-мерных векторов по &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластерам&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;  &lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
Поскольку на данном шаге для каждой пары векторов &amp;lt;math&amp;gt;\mathbf{x}_i, i=\overline{1,n}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\mathbf{\mu}_j, j=\overline{1,k}&amp;lt;/math&amp;gt; операции вычисления расстояния не зависят друг от друга, они могут выполняться параллельно. Тогда, разделив все вычисление расстояний на &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; потоков, получим, что в каждом потоке будет выполняться только одна операция вычисления расстояния между векторами размерности d. При этом каждому вычислительному потоку передаются координаты центров всех кластеров &amp;lt;math&amp;gt;\mathbf{\mu}_1, ..., \mathbf{\mu}_k&amp;lt;/math&amp;gt;. Таким образом, параллельная сложность данного шага определяется &amp;lt;i&amp;gt; сложностью параллельной операции вычисления расстояния между d-мерными векторами&amp;lt;/i&amp;gt;, &amp;lt;math&amp;gt;\Psi_{\rm distance}^d&amp;lt;/math&amp;gt;  и &amp;lt;i&amp;gt;сложностью определения наиболее близкого кластера&amp;lt;/i&amp;gt; (паралельное взятие минимума по расстояниям), &amp;lt;math&amp;gt;\Psi_{\rm min}^k&amp;lt;/math&amp;gt;. Для оценки &amp;lt;math&amp;gt;\Psi_{\rm distance}^d&amp;lt;/math&amp;gt; воспользуемся  [[Нахождение_частных_сумм_элементов_массива_сдваиванием | параллельной реализацией нахождения частичной суммы элементов массива путем сдваивания]]. Аналогично, &amp;lt;math&amp;gt;\Psi_{\rm min}^k = log(k)&amp;lt;/math&amp;gt;. В результате, &amp;lt;math&amp;gt;\Psi_{\rm distance}^d = O(log(d))&amp;lt;/math&amp;gt;.   Таким образом: &lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p align=&amp;quot;center&amp;quot;&amp;gt;&amp;lt;math&amp;gt;\Psi_{\rm distribute}^{k, d}  = \Psi_{\rm distance}^d + \Psi_{\rm min}^k = O(log(d))+O(log(k)) = O(log(kd))&amp;lt;/math&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Пересчет центров кластеров в d-мерном пространстве&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
Поскольку на данном шаге для каждого из &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластеров центр масс может быть вычислен независимо, данные операции могут быть выполнены в отдельных потоках. Таким образом, параллельная сложность данного шага, &amp;lt;math&amp;gt;\Psi_{\rm recenter}^{k, d}&amp;lt;/math&amp;gt;,  будет определяться &amp;lt;i&amp;gt;параллельной сложностью вычисления одного центра масс кластера размера &amp;lt;math&amp;gt;m&amp;lt;/math&amp;gt;&amp;lt;/i&amp;gt;, &amp;lt;math&amp;gt;\Psi_{\rm recenter}^{k, d}&amp;lt;/math&amp;gt;,  а так как &amp;lt;math&amp;gt;m \le n \Rightarrow \Psi_{\rm recenter}^{d, m} \le \Psi_{\rm recenter}^{d, n}&amp;lt;/math&amp;gt;. Сложность вычисления центра масс кластера d-мерных векторов размера n аналогично предыдущим вычислениям равна &amp;lt;math&amp;gt;O(log(n))&amp;lt;/math&amp;gt;. Тогда:  &lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p align=&amp;quot;center&amp;quot;&amp;gt;&amp;lt;math&amp;gt;\Psi_{\rm recenter}^{k, d}  \le \Psi_{\rm recenter}^{d, n} = O(log(n))&amp;lt;/math&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Общая параллельная сложность алгоритма&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
На каждой итерации необходимо обновление центров кластеров, которые будут использованы на следующей итерации. Таким образом, итерационный процесс выполняется последовательно&amp;lt;ref&amp;gt;Zhao, Weizhong, Huifang Ma, and Qing He. &amp;quot;Parallel k-means clustering based on mapreduce.&amp;quot; IEEE International Conference on Cloud Computing. Springer Berlin Heidelberg, 2009.&amp;lt;/ref&amp;gt;. Тогда, поскольку сложность каждой итерации  определяется &amp;lt;math&amp;gt;\Psi_{\rm distribute}^{k, d}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\Psi_{\rm recenter}&amp;lt;/math&amp;gt;, сложность всего алгоритма, &amp;lt;math&amp;gt;\Psi_{\rm k-means}&amp;lt;/math&amp;gt; в предположении, что было сделано &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt; операций определяется выражением&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p align=&amp;quot;center&amp;quot;&amp;gt;&amp;lt;math&amp;gt;\Psi_{\rm k-means} \approx i \cdot (\Psi_{\rm distribute}^{k, d} + \Psi_{\rm recenter}^{k, d}) \le i \cdot O(log(kdn))&amp;lt;/math&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Входные и выходные данные алгоритма ===&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;Входные данные&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;Матрица из &amp;lt;math&amp;gt;n \cdot d&amp;lt;/math&amp;gt; элементов &amp;lt;math&amp;gt;x_{i, j} \in \mathbb{R}, i=\overline{1, n}, j=\overline{1, d}&amp;lt;/math&amp;gt;&amp;amp;ndash; координат векторов (наблюдений).&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;Целое положительное число &amp;lt;math&amp;gt;k, k \le n&amp;lt;/math&amp;gt; &amp;amp;ndash; количество кластеров.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;Объем входных данных&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;math&amp;gt;1&amp;lt;/math&amp;gt; целое число + &amp;lt;math&amp;gt;n \cdot d&amp;lt;/math&amp;gt; вещественных чисел (при условии, что координаты &amp;amp;ndash; вещественные числа).&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;Выходные данные&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; целых положительных чисел &amp;lt;math&amp;gt;L_1, ..., L_n&amp;lt;/math&amp;gt;&amp;amp;ndash; номера кластеров, соотвествующие каждому вектору (при условии, что нумерация кластеров начинается с &amp;lt;math&amp;gt;1&amp;lt;/math&amp;gt;).&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;Объем выходных данных&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; целых положительных чисел.&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Свойства алгоритма ===&lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;[[глоссарий#Вычислительная мощность|&#039;&#039;Вычислительная мощность&#039;&#039;]]&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
Вычислительная мощность алгоритма &amp;lt;i&amp;gt;k means&amp;lt;/i&amp;gt; равна &amp;lt;math&amp;gt;\frac{ikdn}{nd} = ki &amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; &amp;amp;ndash; число кластеров, &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt; &amp;amp;ndash; число итераций алгоритма.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;[[глоссарий#Детерминированность |&#039;&#039;Детерминированность&#039;&#039;]] и [[глоссарий#Устойчивость |&#039;&#039;Устойчивость&#039;&#039;]] &amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
Алгоритм &amp;lt;i&amp;gt;k means&amp;lt;/i&amp;gt; является итерационным. Количество итераций алгоритма в общем случае не фиксируется и зависит от начального расположения объектов в пространстве, параметра &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt;, а также от начального приближения центров кластеров, &amp;lt;math&amp;gt;\mu_1, ..., \mu_k&amp;lt;/math&amp;gt;. В результате этого может варьироваться результат работы алгоритма. При неудачном выборе начальных параметров итерационный процесс может сойтись к локальному оптимуму&amp;lt;ref&amp;gt;Von Luxburg, Ulrike. Clustering Stability. Now Publishers Inc, 2010.&amp;lt;/ref&amp;gt;. По этим причинам алгоритм не является ни &amp;lt;b&amp;gt;детермирированным&amp;lt;/b&amp;gt;, ни &amp;lt;b&amp;gt;устойчивым&amp;lt;/b&amp;gt;.&lt;br /&gt;
 &lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Соотношение последовательной и параллельной сложности алгоритма&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\frac{\Theta_{\rm k-means}}{\Psi_{\rm k-means}} = \frac{O(ikdn)}{O(i \cdot log(kdn))}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Сильные стороны алгоритма&amp;lt;/b&amp;gt;:&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;i&amp;gt;Сравнительно высокая эффективность при простоте реализации&amp;lt;/i&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;i&amp;gt;Высокое качество кластеризации&amp;lt;/i&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;i&amp;gt;Возможность распараллеливания&amp;lt;/i&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;i&amp;gt;Существование множества модификаций&amp;lt;/i&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;Недостатки алгоритма&amp;lt;/b&amp;gt;&amp;lt;ref&amp;gt;Ortega, Joaquín Pérez, Ma Del Rocío Boone Rojas, and María J. Somodevilla. &amp;quot;Research issues on K-means Algorithm: An Experimental Trial Using Matlab.&amp;quot;&amp;lt;/ref&amp;gt;:&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;i&amp;gt;Количество кластеров является параметром алгоритма&amp;lt;/i&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;&amp;lt;i&amp;gt;Чувствительность к начальным условиям&amp;lt;/i&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;Инициализация центров кластеров в значительной степени влияет на результат кластеризации.&amp;lt;/p&amp;gt;&lt;br /&gt;
  &amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;&amp;lt;i&amp;gt;Чувствительность к выбросам и шумам&amp;lt;/i&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;Выбросы, далекие от центров настоящих кластеров, все равно учитываются при вычислении их центров.&amp;lt;/p&amp;gt;&lt;br /&gt;
  &amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;&amp;lt;i&amp;gt;Возможность сходимости к локальному оптимуму&amp;lt;/i&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;Итеративный подход не дает гарантии сходимости к оптимальному решению.&amp;lt;/p&amp;gt;&lt;br /&gt;
  &amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;&amp;lt;i&amp;gt;Использование понятия &amp;quot;среднего&amp;quot;&amp;lt;/i&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;Алгоритм неприменим к данным, для которых не определено понятие &amp;quot;среднего&amp;quot;, например, категориальным данным.&amp;lt;/p&amp;gt;&lt;br /&gt;
  &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&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;
Исследование масштабируемости параллельной реализации алгоритма k means проводилось на суперкомпьютере &amp;quot;Ломоносов&amp;quot;&amp;lt;ref name=&amp;quot;Lom&amp;quot;&amp;gt;Воеводин Вл., Жуматий С., Соболев С., Антонов А., Брызгалов П., Никитенко Д., Стефанов К., Воеводин Вад. Практика суперкомпьютера «Ломоносов» // Открытые системы, 2012, N 7, С. 36-39.&amp;lt;/ref&amp;gt; [http://parallel.ru/cluster Суперкомпьютерного комплекса Московского университета]. Алгоритм реализован на языке C с использованием средств MPI.&lt;br /&gt;
Для исследования масштабируемости проводилось множество запусков программы с разным значением параметра (количество векторов для кластеризации), а также с различным числом процессоров. Фиксировались результаты запусков &amp;amp;ndash; время работы &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt; и количество произведенных итераций алгоритма &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Параметры запусков для экспериментальной оценки:&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;Значения &amp;lt;b&amp;gt;количества векторов&amp;lt;/b&amp;gt; &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;: 20&#039;000, 30&#039;000, 50&#039;000, 100&#039;000, 200&#039;000, 300&#039;000, 500&#039;000, 700&#039;000, 1&#039;000&#039;000, 1&#039;500&#039;000, 2&#039;000&#039;000.&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;Значения &amp;lt;b&amp;gt;количества процессоров&amp;lt;/b&amp;gt; &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt;: 1, 8, 16, 32, 64, 128, 160, 192, 224, 256, 288, 320, 352, 384, 416, 448, 480, 512.&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;Значение &amp;lt;b&amp;gt;количества кластеров&amp;lt;/b&amp;gt; &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt;: 100.&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;Значение &amp;lt;b&amp;gt;размерности векторов&amp;lt;/b&amp;gt; &amp;lt;math&amp;gt;d&amp;lt;/math&amp;gt;: 10.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Для проведения экспериментов были сгенерированы нормально распределенные псевдослучайные данные (с использованием Python библиотеки [http://scikit-learn.org/ scikit-learn]):&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
from sklearn.datasets import make_classification&lt;br /&gt;
X1, Y1 = make_classification(n_features=10, n_redundant=2, n_informative=8,&lt;br /&gt;
                             n_clusters_per_class=1, n_classes=100,&lt;br /&gt;
                             n_samples=2000000)&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Для заданной конфигурации эксперимента (&amp;lt;math&amp;gt;n, d, p, k&amp;lt;/math&amp;gt;) и полученных результатов (&amp;lt;math&amp;gt;t, i&amp;lt;/math&amp;gt;)  [[Глоссарий#Производительность|производительность]]  и эффективность реализации расчитывались по формулам:&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
&amp;lt;ul&amp;gt;&amp;lt;li&amp;gt;&amp;lt;math&amp;gt;Performance = \frac{N_{k-means}^{d, n}}{t}\ \ (FLOPS),&amp;lt;/math&amp;gt;&amp;lt;/li&amp;gt;&amp;lt;/ul&amp;gt;&lt;br /&gt;
где &amp;lt;math&amp;gt;N_{k-means}^{d, n}&amp;lt;/math&amp;gt; &amp;amp;ndash; точное число операций с плавающей точкой (операции с памятью, а также целочисленные операции не учитывались), вычисленное в соответствие с разделом [[#Последовательная сложность алгоритма| &amp;quot;Последовательная сложность алгоритма&amp;quot;]];&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
&amp;lt;ul&amp;gt;&amp;lt;li&amp;gt;&amp;lt;math&amp;gt;Efficiency = \frac{100 \cdot Performance}{Performance_{Peak}^{p}}\ \ (%),&amp;lt;/math&amp;gt;&amp;lt;/li&amp;gt;&amp;lt;/ul&amp;gt;&lt;br /&gt;
где &amp;lt;math&amp;gt;Performance_{Peak}^{p}&amp;lt;/math&amp;gt; &amp;amp;ndash; пиковая производительность суперкомпьютера при &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt; процессорах, вычисленная согласно спецификациям Intel&amp;lt;sup&amp;gt;&amp;amp;reg;&amp;lt;/sup&amp;gt; XEON&amp;lt;sup&amp;gt;&amp;amp;reg;&amp;lt;/sup&amp;gt; X5670&amp;lt;ref&amp;gt;&amp;quot;http://ark.intel.com/ru/products/47920/Intel-Xeon-Processor-X5670-12M-Cache-2_93-GHz-6_40-GTs-Intel-QPI&amp;quot;&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Графики зависимости производительности и эффективности параллельной реализации k means от числа векторов для кластеризации (&amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;) и числа процессоров (&amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt;) представлены на рисунках 4 и 5 соответственно.&lt;br /&gt;
&lt;br /&gt;
[[file:Flops.png|thumb|center|800px|Рис. 4. Параллельная реализация k means. График зависимости производительности реализации алгоритма от числа векторов для кластеризации (&amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;) и числа процессоров (&amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt;).]]&lt;br /&gt;
[[file:Efficiency.png|thumb|center|800px|Рис. 5. Параллельная реализация k means. График зависимости эффективности реализации алгоритма от числа векторов для кластеризации (&amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;) и числа процессоров (&amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt;).]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;В результате&amp;lt;/b&amp;gt; экспериментальной оценки были получены следующие оценки эффективности реализации:&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;b&amp;gt;Минимальное&amp;lt;/b&amp;gt; значение: 0.000409 % достигается при &amp;lt;math&amp;gt;n=20&#039;000, p=480&amp;lt;/math&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;b&amp;gt;Максимальное&amp;lt;/b&amp;gt; значение: 0.741119 % достигается при &amp;lt;math&amp;gt;n=300&#039;000, p=1&amp;lt;/math&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
Оценки масштабируемости реализации алгоритма k means:&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;b&amp;gt;По числу процессоров:&amp;lt;/b&amp;gt; -0.002683 &amp;amp;ndash; эффективность убывает с ростом числа процессоров. Данный результат вызван ростом накладных расходов для обеспечения параллельного выполнения алгоритма.&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;b&amp;gt;По размеру задачи:&amp;lt;/b&amp;gt; 0.002779 &amp;amp;ndash; эффективность растет с ростом числа векторов. Данный результат вызван тем, что при увеличении размера задачи, количество вычислений растет по сравнению с временем, затрачиваемым на пересылку данных.&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;b&amp;gt;Общая оценка:&amp;lt;/b&amp;gt; -0.000058 &amp;amp;ndash; можно сделать вывод, что в целом эффективность реализации незначительно уменьшается с ростом размера задачи и числа процессоров.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[https://github.com/serban/kmeans Использованная параллельная реализация алгоритма k means]&lt;br /&gt;
&lt;br /&gt;
=== Динамические характеристики и эффективность реализации алгоритма ===&lt;br /&gt;
=== Выводы для классов архитектур ===&lt;br /&gt;
=== Существующие реализации алгоритма ===&lt;br /&gt;
==== Открытое программное обеспечение ====&lt;br /&gt;
&amp;lt;ol&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;[https://www.icpsr.umich.edu/CrimeStat/ CrimeStat]&amp;lt;/li&amp;gt; Программное обеспечение, созданное для операционных систем Windows, предоставляющее инструменты статистического  и пространственного анализа для решения задачи картирования преступности.&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://juliastats.github.io Julia]&amp;lt;/li&amp;gt; Высокоуровневый высокопроизводительный свободный язык программирования с динамической типизацией, созданный для математических вычислений, содержит реализацию k-means.&lt;br /&gt;
  &amp;lt;li&amp;gt;[https://mahout.apache.org Mahout]&amp;lt;/li&amp;gt; Apache Mahout - Java библиотека для работы с алгоритмами машинного обучения с использованием MapReduce. Содержит реализацию k-means.&lt;br /&gt;
  &amp;lt;li&amp;gt;[https://www.gnu.org/software/octave/ Octave]&amp;lt;/li&amp;gt; Написанная на C++  свободная система для математических вычислений, использующая совместимый с MATLAB язык высокого уровня, содержит реализацию k-means.&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://spark.apache.org/docs/latest/mllib-clustering.html Spark]&amp;lt;/li&amp;gt; Распределенная реализация k-means содержится в библиотеке Mlib для работы с алгоритмами машинного обучения, взаимодействующая с Python библиотекой NumPy и библиотека R.&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://torch.ch Torch]&amp;lt;/li&amp;gt;  MATLAB-подобная библиотека для языка программирования Lua с открытым исходным кодом, предоставляет большое количество алгоритмов для глубинного обучения и научных расчётов. Ядро написано на Си, прикладная часть выполняется на LuaJIT, поддерживается распараллеливание вычислений средствами CUDA и OpenMP. Существуют реализации k-means.&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://www.cs.waikato.ac.nz/ml/weka/ Weka]&amp;lt;/li&amp;gt;  Cвободное программное обеспечение для анализа данных, написанное на Java. Содержит k-means и x-means.&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://accord-framework.net/docs/html/T_Accord_MachineLearning_KMeans.htm Accord.NET]&amp;lt;/li&amp;gt; C# реализация алгоритмов k-means, k-means++, k-modes.&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://docs.opencv.org/3.0-beta/doc/py_tutorials/py_ml/py_kmeans/py_kmeans_opencv/py_kmeans_opencv.html OpenCV]&amp;lt;/li&amp;gt; Написанная на С++ библиотека, направленная в основном на решение задач компьютерного зрения. Содержит реализацию k-means.&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://mlpack.org/ MLPACK]&amp;lt;/li&amp;gt; Масштабируемая С++ библиотека для работы с алгоритмами машинного обучения, содержит реализацию k-means.&lt;br /&gt;
  &amp;lt;li&amp;gt;[https://www.scipy.org/ SciPy]&amp;lt;/li&amp;gt; Библиотека Python, содержит множество реализаций k-means.&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://scikit-learn.org/ scikit-learn]&amp;lt;/li&amp;gt; Библиотека Python, содержит множество реализаций k-means.&lt;br /&gt;
  &amp;lt;li&amp;gt;[https://www.r-bloggers.com/k-means-clustering-in-r/ R]&amp;lt;/li&amp;gt; Язык программирования для статистической обработки данных и работы с графикой, а также свободная программная среда вычислений с открытым исходным кодом в рамках проекта GNU, содержит три реализации k-means.&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://elki.dbs.ifi.lmu.de ELKI]&amp;lt;/li&amp;gt; Java фреймворк, содержащий реализацию k-means, а также множество других алгоритмов кластеризации.&lt;br /&gt;
&amp;lt;/ol&amp;gt;&lt;br /&gt;
==== Проприетарное программное обеспечение  ====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ol&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;[https://www.ayasdi.com/blog/bigdata/topological-data-analysis-of-oil-and-gas-petrophysical-data/ Ayasdi]&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://www.stata.com/features/cluster-analysis/ Stata]&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://mathworld.wolfram.com/K-MeansClusteringAlgorithm.html Mathematica]&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://www.mathworks.com/help/stats/kmeans.html?requestedDomain=www.mathworks.com MATLAB]&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;[https://support.sas.com/rnd/app/stat/procedures/fastclus.html SAS]&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://docs.rapidminer.com/studio/operators/modeling/segmentation/k_means.html RapidMiner]&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;[https://blogs.sap.com/2013/03/28/sap-hana-pal-k-means-algorithm-or-how-to-do-customer-segmentation-for-the-telecommunications-industry/ SAP HANA]&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ol&amp;gt;&lt;br /&gt;
== Литература ==&lt;br /&gt;
&amp;lt;references /&amp;gt;&lt;/div&gt;</summary>
		<author><name>DennZo1993</name></author>
	</entry>
	<entry>
		<id>https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:%D0%91%D1%80%D0%BE%D1%82%D0%B8%D0%BA%D0%BE%D0%B2%D1%81%D0%BA%D0%B0%D1%8F_%D0%94%D0%B0%D0%BD%D1%83%D1%82%D0%B0/%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_k-means&amp;diff=20535</id>
		<title>Участник:Бротиковская Данута/Алгоритм k-means</title>
		<link rel="alternate" type="text/html" href="https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:%D0%91%D1%80%D0%BE%D1%82%D0%B8%D0%BA%D0%BE%D0%B2%D1%81%D0%BA%D0%B0%D1%8F_%D0%94%D0%B0%D0%BD%D1%83%D1%82%D0%B0/%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_k-means&amp;diff=20535"/>
		<updated>2016-12-10T11:11:47Z</updated>

		<summary type="html">&lt;p&gt;DennZo1993: /* Ресурс параллелизма алгоритма */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Assignment|Zhum}}&lt;br /&gt;
&lt;br /&gt;
{{algorithm&lt;br /&gt;
| name              = Алгоритм k средних (k means)&lt;br /&gt;
| serial_complexity = &amp;lt;math&amp;gt;O(ikdn)&amp;lt;/math&amp;gt;&lt;br /&gt;
| input_data        = &amp;lt;math&amp;gt; dn &amp;lt;/math&amp;gt;&lt;br /&gt;
| output_data       = &amp;lt;math&amp;gt; n &amp;lt;/math&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
Авторы страницы &amp;lt;b&amp;gt;[[Участник:Бротиковская Данута|Данута Бротиковская]]&amp;lt;/b&amp;gt; и &amp;lt;b&amp;gt;[[Участник:DennZo1993|Денис Зобнин]]&amp;lt;/b&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
Оба автора внесли одинаковый вклад в написание статьи (поиск материалов, изучение статей, заполнение контента статьи), четких разграничений по пунктам статьи сделать невозможно. &lt;br /&gt;
&lt;br /&gt;
== Свойства и структура алгоритма ==&lt;br /&gt;
&lt;br /&gt;
=== Общее описание алгоритма ===&lt;br /&gt;
Алгоритм &amp;lt;b&amp;gt;&amp;lt;i&amp;gt;k средних&amp;lt;/i&amp;gt;&amp;lt;/b&amp;gt; (&amp;lt;b&amp;gt;&amp;lt;i&amp;gt;k means&amp;lt;/i&amp;gt;&amp;lt;/b&amp;gt;) &amp;amp;ndash; неиерархический&amp;lt;ref&amp;gt;&amp;quot;https://ru.wikipedia.org/wiki/Иерархическая_кластеризация&amp;quot;&amp;lt;/ref&amp;gt;, итерационный метод кластеризации&amp;lt;ref&amp;gt;&amp;quot;https://ru.wikipedia.org/wiki/Кластерный_анализ&amp;quot;&amp;lt;/ref&amp;gt;, получивший большую популярность благодаря своей простоте, наглядности реализации и достаточно высокому качеству работы. Был изобретен в 1950-х годах математиком &amp;lt;i&amp;gt;Гуго Штейнгаузом&amp;lt;/i&amp;gt;&amp;lt;ref&amp;gt;Steinhaus, Hugo. &amp;quot;Sur la division des corp materiels en parties.&amp;quot; Bull. Acad. Polon. Sci 1.804 (1956): 801.&amp;lt;/ref&amp;gt; и почти одновременно &amp;lt;i&amp;gt;Стюартом Ллойдом&amp;lt;/i&amp;gt;&amp;lt;ref&amp;gt;Lloyd, S. P. &amp;quot;Least square quantization in PCM. Bell Telephone Laboratories Paper. Published in journal much later: Lloyd, SP: Least squares quantization in PCM.&amp;quot; IEEE Trans. Inform. Theor.(1957/1982).&amp;lt;/ref&amp;gt;. Особую популярность приобрел после публикации работы &amp;lt;i&amp;gt;МакКуина&amp;lt;/i&amp;gt;&amp;lt;ref&amp;gt;MacQueen, James. &amp;quot;Some methods for classification and analysis of multivariate observations.&amp;quot; Proceedings of the fifth Berkeley symposium on mathematical statistics and probability. Vol. 1. No. 14. 1967.&amp;lt;/ref&amp;gt; в 1967.&lt;br /&gt;
&lt;br /&gt;
Алгоритм представляет собой версию EM-алгоритма&amp;lt;ref&amp;gt;&amp;quot;https://ru.wikipedia.org/wiki/EM-алгоритм&amp;quot;&amp;lt;/ref&amp;gt;, применяемого также для разделения смеси гауссиан. Основная идея &amp;lt;i&amp;gt;k means&amp;lt;/i&amp;gt; заключается в том, что данные произвольно разбиваются на кластеры, после чего итеративно перевычисляется центр масс для каждого кластера, полученного на предыдущем шаге, затем векторы разбиваются на кластеры вновь в соответствии с тем, какой из новых центров оказался ближе по выбранной метрике.&lt;br /&gt;
&lt;br /&gt;
Цель алгоритма заключается в разделении &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; наблюдений на &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластеров таким образом, чтобы каждое наблюдение принадлежало ровно одному кластеру, расположенному на наименьшем расстоянии от наблюдения.&lt;br /&gt;
&lt;br /&gt;
=== Математическое описание алгоритма ===&lt;br /&gt;
&amp;lt;b&amp;gt;&amp;lt;u&amp;gt;Дано:&amp;lt;/u&amp;gt;&amp;lt;/b&amp;gt;&lt;br /&gt;
* набор из &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; наблюдений &amp;lt;math&amp;gt;X=\{\mathbf{x}_1, \mathbf{x}_2, ..., \mathbf{x}_n\}, \mathbf{x}_i \in \mathbb{R}^d, i=\overline{1, n}&amp;lt;/math&amp;gt;;&lt;br /&gt;
* &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; - требуемое число кластеров, &amp;lt;math&amp;gt;k \in \mathbb{N}, k \leq n&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;&amp;lt;u&amp;gt;Требуется:&amp;lt;/u&amp;gt;&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Разделить множество наблюдений &amp;lt;math&amp;gt;X&amp;lt;/math&amp;gt; на &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластеров &amp;lt;math&amp;gt;S_1, S_2, ..., S_k&amp;lt;/math&amp;gt;:&lt;br /&gt;
*   &amp;lt;math&amp;gt;S_i \cap S_j= \varnothing, \quad i \ne j&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
*   &amp;lt;math&amp;gt;\bigcup_{i=1}^{k} S_i = X&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;&amp;lt;u&amp;gt;Действие алгоритма:&amp;lt;/u&amp;gt;&amp;lt;/b&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;Алгоритм &amp;lt;i&amp;gt;k means&amp;lt;/i&amp;gt; разбивает набор &amp;lt;math&amp;gt;X&amp;lt;/math&amp;gt; на &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; наборов &amp;lt;math&amp;gt;S_1, S_2, ..., S_k,&amp;lt;/math&amp;gt; таким образом, чтобы минимизировать сумму квадратов расстояний от каждой точки кластера до его центра (центр масс кластера). Введем обозначение, &amp;lt;math&amp;gt;S=\{S_1, S_2, ..., S_k\}&amp;lt;/math&amp;gt;. Тогда действие алгоритма &amp;lt;i&amp;gt;k means&amp;lt;/i&amp;gt; равносильно поиску:&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;table style=&amp;quot;width:100%&amp;quot;&amp;gt;&lt;br /&gt;
  &amp;lt;tr&amp;gt;&lt;br /&gt;
    &amp;lt;td align=&amp;quot;center&amp;quot; width=&amp;quot;90%&amp;quot;&amp;gt;&amp;lt;math&amp;gt;\arg\min_{S} \sum\limits_{i=1}^k \sum\limits_{\mathbf{x} \in S_i} \rho(\mathbf{x}, \mathbf{\mu}_i )^2,&amp;lt;/math&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;td align=&amp;quot;right&amp;quot;&amp;gt;&amp;lt;math&amp;gt;(1)&amp;lt;/math&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;/table&amp;gt;&lt;br /&gt;
где &amp;lt;math&amp;gt;\mathbf{\mu}_i&amp;lt;/math&amp;gt; &amp;amp;ndash; центры кластеров, &amp;lt;math&amp;gt;i=\overline{1,k}, \quad \rho(\mathbf{x}, \mathbf{\mu}_i)&amp;lt;/math&amp;gt; &amp;amp;ndash; функция расстояния между &amp;lt;math&amp;gt;\mathbf{x}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\mu_i&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;&amp;lt;u&amp;gt;Шаги алгоритма: &amp;lt;/u&amp;gt;&amp;lt;/b&amp;gt;&lt;br /&gt;
&amp;lt;ol&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&lt;br /&gt;
    &amp;lt;b&amp;gt;Начальный шаг: инициализация кластеров&amp;lt;/b&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;Выбирается произвольное множество точек &amp;lt;math&amp;gt;\mu_i, i=\overline{1,k}&amp;lt;/math&amp;gt;, рассматриваемых как начальные центры кластеров: &amp;lt;math&amp;gt;\mu_i^{(0)} = \mu_i, \quad i=\overline{1, k}&amp;lt;/math&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
  &amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&lt;br /&gt;
    &amp;lt;b&amp;gt;Распределение векторов по кластерам&amp;lt;/b&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Шаг&amp;lt;/b&amp;gt; &amp;lt;math&amp;gt;t: \forall \mathbf{x}_i \in X, i=\overline{1,n}: \mathbf{x}_i \in S_j \iff  j=\arg\min_{k}\rho(\mathbf{x}_i,\mathbf{\mu}_k^{(t-1)})^2&amp;lt;/math&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
  &amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&lt;br /&gt;
    &amp;lt;b&amp;gt;Пересчет центров кластеров&amp;lt;/b&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Шаг &amp;lt;/b&amp;gt; &amp;lt;math&amp;gt;t: \forall i=\overline{1,k}:  \mu_i^{(t)} = \cfrac{1}{|S_i|}\sum_{\mathbf{x}\in S_i}\mathbf{x}&amp;lt;/math&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
  &amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&lt;br /&gt;
    &amp;lt;b&amp;gt;Проверка условия останова:&amp;lt;/b&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
    &#039;&#039;&#039;if&#039;&#039;&#039; &amp;lt;math&amp;gt;\exist i\in \overline{1,k}: \mu_i^{(t)} \ne \mu_i^{(t-1)}&amp;lt;/math&amp;gt; &#039;&#039;&#039;then&#039;&#039;&#039;&lt;br /&gt;
        t = t + 1;&lt;br /&gt;
        goto 2;&lt;br /&gt;
    &#039;&#039;&#039;else&#039;&#039;&#039;&lt;br /&gt;
        &#039;&#039;&#039;stop&#039;&#039;&#039;&lt;br /&gt;
  &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ol&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Вычислительное ядро алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Вычислительным ядром являются шаги 2 и 3 приведенного выше алгоритма: &amp;lt;b&amp;gt;&amp;lt;i&amp;gt;распределение векторов по кластерам&amp;lt;/i&amp;gt;&amp;lt;/b&amp;gt; и &amp;lt;b&amp;gt;&amp;lt;i&amp;gt;пересчет центров кластеров&amp;lt;/i&amp;gt;&amp;lt;/b&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;&amp;lt;i&amp;gt;Распределение векторов&amp;lt;/i&amp;gt;&amp;lt;/b&amp;gt; по кластерам предполагает вычисление расстояний между каждым вектором &amp;lt;math&amp;gt;\mathbf{x}_i \in X, i= \overline{1,n}&amp;lt;/math&amp;gt; и центрами кластера &amp;lt;math&amp;gt;\mathbf{\mu}_j, j= \overline{1,k}&amp;lt;/math&amp;gt;. Таким образом, данный шаг предполагает &amp;lt;math&amp;gt;kn&amp;lt;/math&amp;gt; вычислений расстояний между d-мерными векторами. &lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;&amp;lt;i&amp;gt;Пересчет центров кластеров&amp;lt;/i&amp;gt;&amp;lt;/b&amp;gt; предполагает &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; вычислений центров масс &amp;lt;math&amp;gt;\mathbf{\mu}_i&amp;lt;/math&amp;gt; множеств &amp;lt;math&amp;gt;S_i, i=\overline{1,k}&amp;lt;/math&amp;gt; представленных выражением в шаге 3 представленного выше алгоритма.&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Макроструктура алгоритма ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Инициализация центров масс &amp;lt;math&amp;gt;\mu_1, ..., \mu_k&amp;lt;/math&amp;gt;&amp;lt;/b&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
Наиболее распространенными являются следующие стратегии:&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&lt;br /&gt;
    &amp;lt;b&amp;gt;Метод Forgy&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;В качестве начальных значений &amp;lt;math&amp;gt;\mu_1, ..., \mu_k&amp;lt;/math&amp;gt; берутся случайно выбранные векторы.&lt;br /&gt;
  &amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&lt;br /&gt;
    &amp;lt;b&amp;gt;Метод случайно разделения (Random Partitioning)&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;Для каждого вектора &amp;lt;math&amp;gt;\mathbf{x}_i \in X, i=\overline{1, n}&amp;lt;/math&amp;gt; выбирается случайным образом кластер &amp;lt;math&amp;gt;S_1, ..., S_k&amp;lt;/math&amp;gt;, после чего для каждого полученного кластера вычисляются значения &amp;lt;math&amp;gt;\mu_1, ..., \mu_k&amp;lt;/math&amp;gt;.&lt;br /&gt;
  &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Распределение векторов по кластерам&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Для этого шага алгоритма между векторами &amp;lt;math&amp;gt;\mathbf{x}_i \in X, i=\overline{1, n}&amp;lt;/math&amp;gt; и центрами кластеров &amp;lt;math&amp;gt;\mu_1, ..., \mu_k&amp;lt;/math&amp;gt; вычисляются &amp;lt;b&amp;gt;расстояния&amp;lt;/b&amp;gt; по формуле (как правило, используется Евлидово расстояние):&lt;br /&gt;
&amp;lt;table style=&amp;quot;width:100%&amp;quot;&amp;gt;&lt;br /&gt;
  &amp;lt;tr&amp;gt;&lt;br /&gt;
    &amp;lt;td align=&amp;quot;center&amp;quot; width=&amp;quot;90%&amp;quot;&amp;gt;&amp;lt;math&amp;gt; \mathbf{v}_1, \mathbf{v}_2 \in \mathbb{R}^d,  \quad \rho(\mathbf{v}_1, \mathbf{v}_2) = \lVert \mathbf{v}_1- \mathbf{v}_2 \rVert= \sqrt{\sum_{i=1}^{d}(\mathbf{v}_{1,i} - \mathbf{v}_{2,i})^2}&amp;lt;/math&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;td align=&amp;quot;right&amp;quot;&amp;gt;&amp;lt;math&amp;gt;(2)&amp;lt;/math&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;/table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Пересчет центров кластеров&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Для этого шага алгоритма производится пересчет центров кластера по &amp;lt;b&amp;gt;формуле вычисления центра масс&amp;lt;/b&amp;gt;:&lt;br /&gt;
&amp;lt;table style=&amp;quot;width:100%&amp;quot;&amp;gt;&lt;br /&gt;
  &amp;lt;tr&amp;gt;&lt;br /&gt;
    &amp;lt;td align=&amp;quot;center&amp;quot; width=&amp;quot;90%&amp;quot;&amp;gt;&amp;lt;math&amp;gt; \mu = \cfrac{1}{|S|}\sum_{\mathbf{x}\in S}\mathbf{x}&amp;lt;/math&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;td align=&amp;quot;right&amp;quot;&amp;gt;&amp;lt;math&amp;gt;(3)&amp;lt;/math&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;/table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Схема реализации последовательного алгоритма ===&lt;br /&gt;
&lt;br /&gt;
 &#039;&#039;&#039;algorithm&#039;&#039;&#039; k-means &#039;&#039;&#039;is&#039;&#039;&#039;&lt;br /&gt;
     &#039;&#039;&#039;1.&#039;&#039;&#039; Инициализировать центры кластеров &amp;lt;math&amp;gt;\mathbf{\mu}_i^{(1)}, i=\overline{1,k}&amp;lt;/math&amp;gt;&lt;br /&gt;
     &#039;&#039;&#039;2.&#039;&#039;&#039; &amp;lt;math&amp;gt;t \leftarrow 1&amp;lt;/math&amp;gt;&lt;br /&gt;
     &#039;&#039;&#039;3.&#039;&#039;&#039; &#039;&#039;&#039;Распределение по кластерам&#039;&#039;&#039;&amp;lt;br&amp;gt;&lt;br /&gt;
        &amp;lt;math&amp;gt;S_i^{(t)}=\{\mathbf{x}_p: \lVert\mathbf{x}_p-\mathbf{\mu}_i^{(t)}\rVert^2 \leq \lVert\mathbf{x}_p-\mathbf{\mu}_j^{(t)}\rVert^2 \quad \forall j=\overline{1,k}\},&amp;lt;/math&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
        где каждый вектор &amp;lt;math&amp;gt;\mathbf{x}_p&amp;lt;/math&amp;gt; соотносится единственному кластеру &amp;lt;math&amp;gt;S^{(t)}&amp;lt;/math&amp;gt;&lt;br /&gt;
     &#039;&#039;&#039;4.&#039;&#039;&#039; &#039;&#039;&#039;Обновление центров кластеров&#039;&#039;&#039;&amp;lt;br&amp;gt;&lt;br /&gt;
        &amp;lt;math&amp;gt;\mathbf{\mu}_i^{(t+1)} = \frac{1}{|S^{(t)}_i|} \sum_{\mathbf{x}_j \in S^{(t)}_i} \mathbf{x}_j &amp;lt;/math&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
     &#039;&#039;&#039;5.&#039;&#039;&#039; &#039;&#039;&#039;if&#039;&#039;&#039; &amp;lt;math&amp;gt;\exist i \in \overline{1,k}: \mathbf{\mu}_i^{(t+1)} \ne \mathbf{\mu}_i^{(t)}&amp;lt;/math&amp;gt; &#039;&#039;&#039;then&#039;&#039;&#039;&lt;br /&gt;
            t = t + 1;&lt;br /&gt;
            goto &#039;&#039;&#039;3&#039;&#039;&#039;;&lt;br /&gt;
        &#039;&#039;&#039;else&#039;&#039;&#039;&lt;br /&gt;
            &#039;&#039;&#039;stop&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
=== Последовательная сложность алгоритма===&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding-bottom: 20px&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;Обозначим &amp;lt;math&amp;gt;\Theta_{\rm centroid}^{d, m}&amp;lt;/math&amp;gt; временную сложность вычисления центорида кластера, число элементов которого равна &amp;lt;math&amp;gt;m&amp;lt;/math&amp;gt;,  в d-мерном пространстве.&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;Аналогично  &amp;lt;math&amp;gt;\Theta_{\rm distance}^d&amp;lt;/math&amp;gt; &amp;amp;ndash; временная сложность вычисления расстояния между двумя d-мерными векторами.&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding-bottom: 20px&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;Сложность шага инициализации &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластеров мощности &amp;lt;math&amp;gt;m&amp;lt;/math&amp;gt; в d-мерном пространстве &amp;amp;ndash; &amp;lt;math&amp;gt;\Theta_{\rm init}^{k, d, m}&amp;lt;/math&amp;gt;&amp;lt;/b&amp;gt;&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;i&amp;gt;Стратерия Forgy&amp;lt;/i&amp;gt;: вычисления не требуются, &amp;lt;math&amp;gt;\Theta_{\rm init}^{k, d, m} = 0&amp;lt;/math&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;i&amp;gt;Стратегия случайного разбиения&amp;lt;/i&amp;gt;: вычисление центров &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластеров,  &amp;lt;math&amp;gt;\Theta_{\rm init}^{k, d, m} = k \cdot \Theta_{\rm centroid}^{d, m}, m \le n&amp;lt;/math&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding-bottom: 20px&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Cложность шага распределения d мерных векторов по &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластерам &amp;amp;ndash; &amp;lt;math&amp;gt;\Theta_{\rm distribute}^{k, d}&amp;lt;/math&amp;gt;&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
На этом шаге для каждого вектора &amp;lt;math&amp;gt;\mathbf{x}_i \in X, i=\overline{1, n}&amp;lt;/math&amp;gt; вычисляется k расстояний до центров кластеров &amp;lt;math&amp;gt;\mathbf{\mu}_1, ...\mathbf{\mu}_k&amp;lt;/math&amp;gt;&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p align=&amp;quot;center&amp;quot;&amp;gt;&lt;br /&gt;
  &amp;lt;math&amp;gt;\Theta_{\rm distribute}^{k, d} = n \cdot k \cdot \Theta_{\rm distance}^d&amp;lt;/math&amp;gt;&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding-bottom: 20px&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;Сложность шага пересчета центров &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластеров размера &amp;lt;math&amp;gt;m&amp;lt;/math&amp;gt; в d-мерном пространстве &amp;amp;ndash; &amp;lt;math&amp;gt;\Theta_{\rm recenter}^{k, d, m}&amp;lt;/math&amp;gt;&amp;lt;/b&amp;gt;&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;На этом шаге вычисляется &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; центров кластеров &amp;lt;math&amp;gt;\mathbf{\mu}_1, ...\mathbf{\mu}_k&amp;lt;/math&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p align=&amp;quot;center&amp;quot;&amp;gt;&amp;lt;math&amp;gt;\Theta_{\rm recenter}^{k, d, m} = k \cdot \Theta_{\rm centroid}^{d, m}&amp;lt;/math&amp;gt; &amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding-bottom: 20px&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Рассчитаем &amp;lt;math&amp;gt;\Theta_{\rm centroid}^{d, m}&amp;lt;/math&amp;gt; для кластера, число элементов которого равно &amp;lt;math&amp;gt;m&amp;lt;/math&amp;gt;&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p align=&amp;quot;center&amp;quot;&amp;gt;&amp;lt;math&amp;gt;\Theta_{\rm centroid}^{d, m}&amp;lt;/math&amp;gt; = &amp;lt;math&amp;gt;m \cdot d&amp;lt;/math&amp;gt; сложений + &amp;lt;math&amp;gt;d&amp;lt;/math&amp;gt; делений &amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding-bottom: 20px&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Рассчитаем &amp;lt;math&amp;gt;\Theta_{\rm distance}^d&amp;lt;/math&amp;gt; в соответствие с формулой &amp;lt;math&amp;gt;(2)&amp;lt;/math&amp;gt;&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p align=&amp;quot;center&amp;quot;&amp;gt;&amp;lt;math&amp;gt;\Theta_{\rm distance}^d&amp;lt;/math&amp;gt; = &amp;lt;math&amp;gt;d&amp;lt;/math&amp;gt; вычитаний + &amp;lt;math&amp;gt;d&amp;lt;/math&amp;gt; умножений + &amp;lt;math&amp;gt;(d-1)&amp;lt;/math&amp;gt; сложение&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding-bottom: 20px&amp;quot;&amp;gt;&lt;br /&gt;
  &amp;lt;p&amp;gt;Предположим, что алгоритм сошелся за &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt; итераций, тогда временная сложность алгоритма &amp;lt;math&amp;gt;\Theta_{\rm k-means}^{d, n}&amp;lt;/math&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
  &amp;lt;p align=&amp;quot;center&amp;quot;&amp;gt;&amp;lt;b&amp;gt;&amp;lt;math&amp;gt;\Theta_{\rm k-means}^{d, n} \le \Theta_{\rm init}^{k, d, n} + i(\Theta_{\rm distribute}^{k, d} + \Theta_{\rm recenter}^{k, d, n})&amp;lt;/math&amp;gt;&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding-bottom: 5px&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;Операции сложения/вычитания:&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p align=&amp;quot;center&amp;quot;&amp;gt;&amp;lt;b&amp;gt;&amp;lt;math&amp;gt;\Theta_{\rm k-means}^{d, n} \le knd+ i(kn(2d-1) + knd) = knd+ i(kn(3d-1)) \thicksim O(ikdn)&amp;lt;/math&amp;gt;&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding-bottom: 20px&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;Операции умножения/деления:&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p align=&amp;quot;center&amp;quot;&amp;gt;&amp;lt;b&amp;gt;&amp;lt;math&amp;gt;\Theta_{\rm k-means}^{d, n} \le kd + i(knd + kd) = kd + ikd(n+1) \thicksim O(ikdn) &amp;lt;/math&amp;gt;&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding-bottom: 20px&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;Получаем, что &amp;lt;b&amp;gt;временная сложность&amp;lt;/b&amp;gt; алгоритма &amp;lt;b&amp;gt;k means&amp;lt;/b&amp;gt; кластеризации &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; &amp;lt;b&amp;gt;d-мерных&amp;lt;/b&amp;gt; векторов на &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластеров за &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt; итераций:&amp;lt;/p&amp;gt;&lt;br /&gt;
 &amp;lt;p align=&amp;quot;center&amp;quot;&amp;gt;&amp;lt;b&amp;gt;&amp;lt;math&amp;gt; \Theta_{\rm k-means}^{d, n} \thicksim O(ikdn) &amp;lt;/math&amp;gt;&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Информационный граф ===&lt;br /&gt;
&lt;br /&gt;
Рассмотрим информационный граф алгоритма. Алгоритм &amp;lt;i&amp;gt;k means&amp;lt;/i&amp;gt; начинается с этапа инициализации, после которого следуют итерации, на каждой из которых выполняется два последовательных шага (см. [[#Схема реализации последовательного алгоритма|&amp;quot;Схема реализации последовательного алгоритма&amp;quot;]]): &lt;br /&gt;
* распределение векторов по кластерам&lt;br /&gt;
* перерасчет центров кластеров&lt;br /&gt;
&lt;br /&gt;
Поскольку основная часть вычислений приходится на шаги итераций, распишем информационные графы данных шагов.&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Распределение векторов по кластерам&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
Информационный граф шага распределения векторов по кластерам представлен на &#039;&#039;рисунке 1&#039;&#039;. Исходами данного графа является исходные векторы &amp;lt;math&amp;gt;\mathbf{x}_1, ..., \mathbf{x}_n&amp;lt;/math&amp;gt;, а также центры кластеров &amp;lt;math&amp;gt;\mathbf{\mu}_1, ... \mathbf{\mu}_k&amp;lt;/math&amp;gt;, вычисленные ранее (на шаге инициализации, если рассматривается первая итерация алгоритма, или на шаге пересчета центров кластеров предыдущей итерации в противном случае). Каждая пара векторов данных &amp;lt;math&amp;gt;\mathbf{x}_i, i=\overline{1,n}&amp;lt;/math&amp;gt; и центров кластера &amp;lt;math&amp;gt;\mathbf{\mu}_j, j=\overline{1, k}&amp;lt;/math&amp;gt; : (&amp;lt;math&amp;gt;\mathbf{x}_i&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;\mathbf{\mu}_j&amp;lt;/math&amp;gt;) подаются на независимые узлы &amp;lt;i&amp;gt;&amp;quot;d&amp;quot;&amp;lt;/i&amp;gt; вычисления расстояния между векторами (более подробная схема вычисления расстояния представлена далее, &#039;&#039;рисунок 2&#039;&#039;). Далее узлы вычисления расстояния &amp;lt;i&amp;gt;&amp;quot;d&amp;quot;&amp;lt;/i&amp;gt;, соответствующие одному и тому же исходному вектору &amp;lt;math&amp;gt;\mathbf{x}_i&amp;lt;/math&amp;gt; передаются на один узел &amp;lt;i&amp;gt;&amp;quot;m&amp;quot;&amp;lt;/i&amp;gt;, где далее происходит вычисление новой метки кластера для каждого вектора &amp;lt;math&amp;gt;\mathbf{x}_i&amp;lt;/math&amp;gt; (берется кластер с минимальным результатом вычисления расстояния). На выходе графа выдаются метки кластеров , &amp;lt;math&amp;gt;L_1, ..., L_n&amp;lt;/math&amp;gt;, такие что &amp;lt;math&amp;gt;\forall \mathbf{x}_i, i=\overline{1, n}, \mathbf{x}_i \in S_j \Leftrightarrow L_i = j&amp;lt;/math&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
[[file:Clusterization.png|thumb|center|800px|Рис. 1. Схема распределения векторов по кластерам. &#039;&#039;d&#039;&#039; &amp;amp;ndash; вычисление расстояния между векторами; &#039;&#039;m&#039;&#039; &amp;amp;ndash; вычисление минимума.]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Вычисление расстояния между векторами&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
Подробная схема вычисления расстояния между векторами &amp;lt;math&amp;gt;\mathbf{x}_i, \mathbf{\mu}_j&amp;lt;/math&amp;gt; представлена на &#039;&#039;рисунке 2&#039;&#039;. Как показано на графе, узел вычисления расстояния между векторами &amp;lt;i&amp;gt;&amp;quot;d&amp;quot;&amp;lt;/i&amp;gt; состоит из шага взятия разности между векторами (узел &amp;quot;&amp;lt;math&amp;gt;-&amp;lt;/math&amp;gt;&amp;quot;) и взятия нормы получившегося вектора разности (узел &amp;quot;&amp;lt;math&amp;gt;||\cdot||^2&amp;lt;/math&amp;gt;&amp;quot;). Более подробно, вычисление расстояния между векторами &amp;lt;math&amp;gt;\mathbf{x}_i = {x_{i1,}, ...,{x_{in}}}, \mathbf{\mu}_j = {\mu_{j1}, ...,\mu_{jn}}&amp;lt;/math&amp;gt; может быть представлено как вычисление разности между каждой парой компонент &amp;lt;math&amp;gt;(x_{iz}, \mu_{jz}), z=\overline{1, d}&amp;lt;/math&amp;gt; (узел &amp;quot;&amp;lt;math&amp;gt;-&amp;lt;/math&amp;gt;&amp;quot;), далее возведение в квадрат для каждого узла &amp;quot;&amp;lt;math&amp;gt;-&amp;lt;/math&amp;gt;&amp;quot; (узел &amp;quot;&amp;lt;math&amp;gt;()^2&amp;lt;/math&amp;gt;&amp;quot;) и суммирования выходов всех узлов &amp;quot;&amp;lt;math&amp;gt;()^2&amp;lt;/math&amp;gt;&amp;quot; (узел &amp;quot;&amp;lt;math&amp;gt;+&amp;lt;/math&amp;gt;&amp;quot;).  &lt;br /&gt;
&lt;br /&gt;
[[file:dist_calc.png|thumb|center|800px|Рис. 2. Схема вычисления расстояния между вектором и центром кластера.]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Пересчет центров кластеров&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
Информационный граф шага пересчета центров кластеров представлен на &#039;&#039;рисунке 3&#039;&#039;. Исходами данного графа является исходные векторы &amp;lt;math&amp;gt;\mathbf{x}_1, ..., \mathbf{x}_n&amp;lt;/math&amp;gt;, а также им соответствующие метки кластера, &amp;lt;math&amp;gt;L_1, ..., L_n&amp;lt;/math&amp;gt;, такие что &amp;lt;math&amp;gt;\forall x_i, i=\overline{1, n}, \mathbf{x}_i \in S_j \Leftrightarrow L_i = j&amp;lt;/math&amp;gt;, вычисленные на этапе распределения векторов по кластерам. Все векторы &amp;lt;math&amp;gt;\mathbf{x}_1, ..., \mathbf{x}_n&amp;lt;/math&amp;gt; подаются в узлы &amp;lt;math&amp;gt;+_1, ...+_k&amp;lt;/math&amp;gt;, каждый узел &amp;lt;math&amp;gt;+_m, m = \overline{1,k}&amp;lt;/math&amp;gt; соответствует операции сложения векторов кластера с номером &amp;lt;math&amp;gt;m&amp;lt;/math&amp;gt;. Метки кластера &amp;lt;math&amp;gt;L_1, ..., L_n&amp;lt;/math&amp;gt; также совместно передаются на узлы &amp;lt;math&amp;gt;S_m, m = \overline{1,k}&amp;lt;/math&amp;gt;, на каждом из которых вычисляется количество векторов в соответствующем кластере (количество меток с соответствующим значением). Далее каждая пара выходов узлов &amp;lt;math&amp;gt;+_m&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;S_m&amp;lt;/math&amp;gt; подается на узел &amp;quot;&amp;lt;math&amp;gt;/&amp;lt;/math&amp;gt;&amp;quot;, где производится деление суммы векторов кластера на количество элементов в нем. Значения, вычисленные на узлах &amp;quot;&amp;lt;math&amp;gt;/&amp;lt;/math&amp;gt;&amp;quot;, присваиваются новым центрам кластеров (выходные значения графа).&lt;br /&gt;
&lt;br /&gt;
[[file:Recluster.png|thumb|center|800px|Рис. 3. Схема пересчета центров кластеров]]&lt;br /&gt;
&lt;br /&gt;
=== Ресурс параллелизма алгоритма ===&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
Работа алгоритма состоит из &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt; итераций, в каждой из которых происходит &amp;lt;b&amp;gt;распределение d-мерных векторов по &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластерам&amp;lt;/b&amp;gt;, а также &amp;lt;b&amp;gt;пересчет центров кластеров в d-мерном пространстве&amp;lt;/b&amp;gt;. В шаге &amp;lt;b&amp;gt;распределения d-мерных векторов по &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластерам&amp;lt;/b&amp;gt; расстояния между вектором и центрами кластеров вычисляются независимо (отсутствуют информационные зависимости). &amp;lt;b&amp;gt;Центры масс кластеров&amp;lt;/b&amp;gt; также пересчитываются независимо друг от друга. Таким образом, имеет место [[глоссарий#Массовый параллелизм|&#039;&#039;массовый параллелизм&#039;&#039;]]. Вычислим параллельную сложность &amp;lt;math&amp;gt;\Psi_*&amp;lt;/math&amp;gt; каждого из шагов, а также параллельную сложность всего алгоритма, &amp;lt;math&amp;gt;\Psi_{\rm k-means}&amp;lt;/math&amp;gt;. Будем исходить из предположения, что может быть использовано любое необходимое число потоков.&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Распределение d-мерных векторов по &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластерам&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;  &lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
Поскольку на данном шаге для каждой пары векторов &amp;lt;math&amp;gt;\mathbf{x}_i, i=\overline{1,n}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\mathbf{\mu}_j, j=\overline{1,k}&amp;lt;/math&amp;gt; операции вычисления расстояния не зависят друг от друга, они могут выполняться параллельно. Тогда, разделив все вычисление расстояний на &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; потоков, получим, что в каждом потоке будет выполняться только одна операция вычисления расстояния между векторами размерности d. При этом каждому вычислительному потоку передаются координаты центров всех кластеров &amp;lt;math&amp;gt;\mathbf{\mu}_1, ..., \mathbf{\mu}_k&amp;lt;/math&amp;gt;. Таким образом, параллельная сложность данного шага определяется &amp;lt;i&amp;gt; сложностью параллельной операции вычисления расстояния между d-мерными векторами&amp;lt;/i&amp;gt;, &amp;lt;math&amp;gt;\Psi_{\rm distance}^d&amp;lt;/math&amp;gt;  и &amp;lt;i&amp;gt;сложностью определения наиболее близкого кластера&amp;lt;/i&amp;gt; (паралельное взятие минимума по расстояниям), &amp;lt;math&amp;gt;\Psi_{\rm min}^k&amp;lt;/math&amp;gt;. Для оценки &amp;lt;math&amp;gt;\Psi_{\rm distance}^d&amp;lt;/math&amp;gt; воспользуемся  [[Нахождение_частных_сумм_элементов_массива_сдваиванием | параллельной реализацией нахождения частичной суммы элементов массива путем сдваивания]]. Аналогично, &amp;lt;math&amp;gt;\Psi_{\rm min}^k = log(k)&amp;lt;/math&amp;gt;. В результате, &amp;lt;math&amp;gt;\Psi_{\rm distance}^d = O(log(d))&amp;lt;/math&amp;gt;.   Таким образом: &lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p align=&amp;quot;center&amp;quot;&amp;gt;&amp;lt;math&amp;gt;\Psi_{\rm distribute}^{k, d}  = \Psi_{\rm distance}^d + \Psi_{\rm min}^k = O(log(d))+O(log(k)) = O(log(kd))&amp;lt;/math&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Пересчет центров кластеров в d-мерном пространстве&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
Поскольку на данном шаге для каждого из &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластеров центр масс может быть вычислен независимо, данные операции могут быть выполнены в отдельных потоках. Таким образом, параллельная сложность данного шага, &amp;lt;math&amp;gt;\Psi_{\rm recenter}^{k, d}&amp;lt;/math&amp;gt;,  будет определяться &amp;lt;i&amp;gt;параллельной сложностью вычисления одного центра масс кластера размера &amp;lt;math&amp;gt;m&amp;lt;/math&amp;gt;&amp;lt;/i&amp;gt;, &amp;lt;math&amp;gt;\Psi_{\rm recenter}^{k, d}&amp;lt;/math&amp;gt;,  а так как &amp;lt;math&amp;gt;m \le n \Rightarrow \Psi_{\rm recenter}^{d, m} \le \Psi_{\rm recenter}^{d, n}&amp;lt;/math&amp;gt;. Сложность вычисления центра масс кластера d-мерных векторов размера n аналогично предыдущим вычислениям равна &amp;lt;math&amp;gt;O(log(n))&amp;lt;/math&amp;gt;. Тогда:  &lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p align=&amp;quot;center&amp;quot;&amp;gt;&amp;lt;math&amp;gt;\Psi_{\rm recenter}^{k, d}  \le \Psi_{\rm recenter}^{d, n} = O(log(n))&amp;lt;/math&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Общая параллельная сложность алгоритма&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
На каждой итерации необходимо обновление центров кластеров, которые будут использованы на следующей итерации. Таким образом, итерационный процесс выполняется последовательно&amp;lt;ref&amp;gt;Zhao, Weizhong, Huifang Ma, and Qing He. &amp;quot;Parallel k-means clustering based on mapreduce.&amp;quot; IEEE International Conference on Cloud Computing. Springer Berlin Heidelberg, 2009.&amp;lt;/ref&amp;gt;. Тогда, поскольку сложность каждой итерации  определяется &amp;lt;math&amp;gt;\Psi_{\rm distribute}^{k, d}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\Psi_{\rm recenter}&amp;lt;/math&amp;gt;, сложность всего алгоритма, &amp;lt;math&amp;gt;\Psi_{\rm k-means}&amp;lt;/math&amp;gt; в предположении, что было сделано &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt; операций определяется выражением&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p align=&amp;quot;center&amp;quot;&amp;gt;&amp;lt;math&amp;gt;\Psi_{\rm k-means} \approx i \cdot (\Psi_{\rm distribute}^{k, d} + \Psi_{\rm recenter}^{k, d}) \le i \cdot O(log(kdn))&amp;lt;/math&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Входные и выходные данные алгоритма ===&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;Входные данные&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;Матрица из &amp;lt;math&amp;gt;n \cdot d&amp;lt;/math&amp;gt; элементов &amp;lt;math&amp;gt;x_{i, j} \in \mathbb{R}, i=\overline{1, n}, j=\overline{1, d}&amp;lt;/math&amp;gt;&amp;amp;ndash; координат векторов (наблюдений).&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;Целое положительное число &amp;lt;math&amp;gt;k, k \le n&amp;lt;/math&amp;gt; &amp;amp;ndash; количество кластеров.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;Объем входных данных&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;math&amp;gt;1&amp;lt;/math&amp;gt; целое число + &amp;lt;math&amp;gt;n \cdot d&amp;lt;/math&amp;gt; вещественных чисел (при условии, что координаты &amp;amp;ndash; вещественные числа).&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;Выходные данные&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; целых положительных чисел &amp;lt;math&amp;gt;L_1, ..., L_n&amp;lt;/math&amp;gt;&amp;amp;ndash; номера кластеров, соотвествующие каждому вектору (при условии, что нумерация кластеров начинается с &amp;lt;math&amp;gt;1&amp;lt;/math&amp;gt;).&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;Объем выходных данных&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; целых положительных чисел.&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Свойства алгоритма ===&lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;[[глоссарий#Вычислительная мощность|&#039;&#039;Вычислительная мощность&#039;&#039;]]&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
Вычислительная мощность алгоритма &amp;lt;i&amp;gt;k means&amp;lt;/i&amp;gt; равна &amp;lt;math&amp;gt;\frac{ikdn}{nd} = ki &amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; &amp;amp;ndash; число кластеров, &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt; &amp;amp;ndash; число итераций алгоритма.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;[[глоссарий#Детерминированность |&#039;&#039;Детерминированность&#039;&#039;]] и [[глоссарий#Устойчивость |&#039;&#039;Устойчивость&#039;&#039;]] &amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
Алгоритм &amp;lt;i&amp;gt;k means&amp;lt;/i&amp;gt; является итерационным. Количество итераций алгоритма в общем случае не фиксируется и зависит от начального расположения объектов в пространстве, параметра &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt;, а также от начального приближения центров кластеров, &amp;lt;math&amp;gt;\mu_1, ..., \mu_k&amp;lt;/math&amp;gt;. В результате этого может варьироваться результат работы алгоритма. При неудачном выборе начальных параметров итерационный процесс может сойтись к локальному оптимуму&amp;lt;ref&amp;gt;Von Luxburg, Ulrike. Clustering Stability. Now Publishers Inc, 2010.&amp;lt;/ref&amp;gt;. По этим причинам алгоритм не является ни &amp;lt;b&amp;gt;детермирированным&amp;lt;/b&amp;gt;, ни &amp;lt;b&amp;gt;устойчивым&amp;lt;/b&amp;gt;.&lt;br /&gt;
 &lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Соотношение последовательной и параллельной сложности алгоритма&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\frac{\Theta_{k-means}}{\Psi_{k-means}} = \frac{O(ikdn)}{O(i \cdot log(kdn))}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Сильные стороны алгоритма&amp;lt;/b&amp;gt;:&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;i&amp;gt;Сравнительно высокая эффективность при простоте реализации&amp;lt;/i&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;i&amp;gt;Высокое качество кластеризации&amp;lt;/i&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;i&amp;gt;Возможность распараллеливания&amp;lt;/i&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;i&amp;gt;Существование множества модификаций&amp;lt;/i&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;Недостатки алгоритма&amp;lt;/b&amp;gt;&amp;lt;ref&amp;gt;Ortega, Joaquín Pérez, Ma Del Rocío Boone Rojas, and María J. Somodevilla. &amp;quot;Research issues on K-means Algorithm: An Experimental Trial Using Matlab.&amp;quot;&amp;lt;/ref&amp;gt;:&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;i&amp;gt;Количество кластеров является параметром алгоритма&amp;lt;/i&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;&amp;lt;i&amp;gt;Чувствительность к начальным условиям&amp;lt;/i&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;Инициализация центров кластеров в значительной степени влияет на результат кластеризации.&amp;lt;/p&amp;gt;&lt;br /&gt;
  &amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;&amp;lt;i&amp;gt;Чувствительность к выбросам и шумам&amp;lt;/i&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;Выбросы, далекие от центров настоящих кластеров, все равно учитываются при вычислении их центров.&amp;lt;/p&amp;gt;&lt;br /&gt;
  &amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;&amp;lt;i&amp;gt;Возможность сходимости к локальному оптимуму&amp;lt;/i&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;Итеративный подход не дает гарантии сходимости к оптимальному решению.&amp;lt;/p&amp;gt;&lt;br /&gt;
  &amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;&amp;lt;i&amp;gt;Использование понятия &amp;quot;среднего&amp;quot;&amp;lt;/i&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;Алгоритм неприменим к данным, для которых не определено понятие &amp;quot;среднего&amp;quot;, например, категориальным данным.&amp;lt;/p&amp;gt;&lt;br /&gt;
  &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&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;
Исследование масштабируемости параллельной реализации алгоритма k means проводилось на суперкомпьютере &amp;quot;Ломоносов&amp;quot;&amp;lt;ref name=&amp;quot;Lom&amp;quot;&amp;gt;Воеводин Вл., Жуматий С., Соболев С., Антонов А., Брызгалов П., Никитенко Д., Стефанов К., Воеводин Вад. Практика суперкомпьютера «Ломоносов» // Открытые системы, 2012, N 7, С. 36-39.&amp;lt;/ref&amp;gt; [http://parallel.ru/cluster Суперкомпьютерного комплекса Московского университета]. Алгоритм реализован на языке C с использованием средств MPI.&lt;br /&gt;
Для исследования масштабируемости проводилось множество запусков программы с разным значением параметра (количество векторов для кластеризации), а также с различным числом процессоров. Фиксировались результаты запусков &amp;amp;ndash; время работы &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt; и количество произведенных итераций алгоритма &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Параметры запусков для экспериментальной оценки:&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;Значения &amp;lt;b&amp;gt;количества векторов&amp;lt;/b&amp;gt; &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;: 20&#039;000, 30&#039;000, 50&#039;000, 100&#039;000, 200&#039;000, 300&#039;000, 500&#039;000, 700&#039;000, 1&#039;000&#039;000, 1&#039;500&#039;000, 2&#039;000&#039;000.&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;Значения &amp;lt;b&amp;gt;количества процессоров&amp;lt;/b&amp;gt; &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt;: 1, 8, 16, 32, 64, 128, 160, 192, 224, 256, 288, 320, 352, 384, 416, 448, 480, 512.&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;Значение &amp;lt;b&amp;gt;количества кластеров&amp;lt;/b&amp;gt; &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt;: 100.&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;Значение &amp;lt;b&amp;gt;размерности векторов&amp;lt;/b&amp;gt; &amp;lt;math&amp;gt;d&amp;lt;/math&amp;gt;: 10.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Для проведения экспериментов были сгенерированы нормально распределенные псевдослучайные данные (с использованием Python библиотеки [http://scikit-learn.org/ scikit-learn]):&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
from sklearn.datasets import make_classification&lt;br /&gt;
X1, Y1 = make_classification(n_features=10, n_redundant=2, n_informative=8,&lt;br /&gt;
                             n_clusters_per_class=1, n_classes=100,&lt;br /&gt;
                             n_samples=2000000)&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Для заданной конфигурации эксперимента (&amp;lt;math&amp;gt;n, d, p, k&amp;lt;/math&amp;gt;) и полученных результатов (&amp;lt;math&amp;gt;t, i&amp;lt;/math&amp;gt;)  [[Глоссарий#Производительность|производительность]]  и эффективность реализации расчитывались по формулам:&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
&amp;lt;ul&amp;gt;&amp;lt;li&amp;gt;&amp;lt;math&amp;gt;Performance = \frac{N_{k-means}^{d, n}}{t}\ \ (FLOPS),&amp;lt;/math&amp;gt;&amp;lt;/li&amp;gt;&amp;lt;/ul&amp;gt;&lt;br /&gt;
где &amp;lt;math&amp;gt;N_{k-means}^{d, n}&amp;lt;/math&amp;gt; &amp;amp;ndash; точное число операций с плавающей точкой (операции с памятью, а также целочисленные операции не учитывались), вычисленное в соответствие с разделом [[#Последовательная сложность алгоритма| &amp;quot;Последовательная сложность алгоритма&amp;quot;]];&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
&amp;lt;ul&amp;gt;&amp;lt;li&amp;gt;&amp;lt;math&amp;gt;Efficiency = \frac{100 \cdot Performance}{Performance_{Peak}^{p}}\ \ (%),&amp;lt;/math&amp;gt;&amp;lt;/li&amp;gt;&amp;lt;/ul&amp;gt;&lt;br /&gt;
где &amp;lt;math&amp;gt;Performance_{Peak}^{p}&amp;lt;/math&amp;gt; &amp;amp;ndash; пиковая производительность суперкомпьютера при &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt; процессорах, вычисленная согласно спецификациям Intel&amp;lt;sup&amp;gt;&amp;amp;reg;&amp;lt;/sup&amp;gt; XEON&amp;lt;sup&amp;gt;&amp;amp;reg;&amp;lt;/sup&amp;gt; X5670&amp;lt;ref&amp;gt;&amp;quot;http://ark.intel.com/ru/products/47920/Intel-Xeon-Processor-X5670-12M-Cache-2_93-GHz-6_40-GTs-Intel-QPI&amp;quot;&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Графики зависимости производительности и эффективности параллельной реализации k means от числа векторов для кластеризации (&amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;) и числа процессоров (&amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt;) представлены на рисунках 4 и 5 соответственно.&lt;br /&gt;
&lt;br /&gt;
[[file:Flops.png|thumb|center|800px|Рис. 4. Параллельная реализация k means. График зависимости производительности реализации алгоритма от числа векторов для кластеризации (&amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;) и числа процессоров (&amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt;).]]&lt;br /&gt;
[[file:Efficiency.png|thumb|center|800px|Рис. 5. Параллельная реализация k means. График зависимости эффективности реализации алгоритма от числа векторов для кластеризации (&amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;) и числа процессоров (&amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt;).]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;В результате&amp;lt;/b&amp;gt; экспериментальной оценки были получены следующие оценки эффективности реализации:&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;b&amp;gt;Минимальное&amp;lt;/b&amp;gt; значение: 0.000409 % достигается при &amp;lt;math&amp;gt;n=20&#039;000, p=480&amp;lt;/math&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;b&amp;gt;Максимальное&amp;lt;/b&amp;gt; значение: 0.741119 % достигается при &amp;lt;math&amp;gt;n=300&#039;000, p=1&amp;lt;/math&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
Оценки масштабируемости реализации алгоритма k means:&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;b&amp;gt;По числу процессоров:&amp;lt;/b&amp;gt; -0.002683 &amp;amp;ndash; эффективность убывает с ростом числа процессоров. Данный результат вызван ростом накладных расходов для обеспечения параллельного выполнения алгоритма.&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;b&amp;gt;По размеру задачи:&amp;lt;/b&amp;gt; 0.002779 &amp;amp;ndash; эффективность растет с ростом числа векторов. Данный результат вызван тем, что при увеличении размера задачи, количество вычислений растет по сравнению с временем, затрачиваемым на пересылку данных.&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;b&amp;gt;Общая оценка:&amp;lt;/b&amp;gt; -0.000058 &amp;amp;ndash; можно сделать вывод, что в целом эффективность реализации незначительно уменьшается с ростом размера задачи и числа процессоров.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[https://github.com/serban/kmeans Использованная параллельная реализация алгоритма k means]&lt;br /&gt;
&lt;br /&gt;
=== Динамические характеристики и эффективность реализации алгоритма ===&lt;br /&gt;
=== Выводы для классов архитектур ===&lt;br /&gt;
=== Существующие реализации алгоритма ===&lt;br /&gt;
==== Открытое программное обеспечение ====&lt;br /&gt;
&amp;lt;ol&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;[https://www.icpsr.umich.edu/CrimeStat/ CrimeStat]&amp;lt;/li&amp;gt; Программное обеспечение, созданное для операционных систем Windows, предоставляющее инструменты статистического  и пространственного анализа для решения задачи картирования преступности.&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://juliastats.github.io Julia]&amp;lt;/li&amp;gt; Высокоуровневый высокопроизводительный свободный язык программирования с динамической типизацией, созданный для математических вычислений, содержит реализацию k-means.&lt;br /&gt;
  &amp;lt;li&amp;gt;[https://mahout.apache.org Mahout]&amp;lt;/li&amp;gt; Apache Mahout - Java библиотека для работы с алгоритмами машинного обучения с использованием MapReduce. Содержит реализацию k-means.&lt;br /&gt;
  &amp;lt;li&amp;gt;[https://www.gnu.org/software/octave/ Octave]&amp;lt;/li&amp;gt; Написанная на C++  свободная система для математических вычислений, использующая совместимый с MATLAB язык высокого уровня, содержит реализацию k-means.&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://spark.apache.org/docs/latest/mllib-clustering.html Spark]&amp;lt;/li&amp;gt; Распределенная реализация k-means содержится в библиотеке Mlib для работы с алгоритмами машинного обучения, взаимодействующая с Python библиотекой NumPy и библиотека R.&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://torch.ch Torch]&amp;lt;/li&amp;gt;  MATLAB-подобная библиотека для языка программирования Lua с открытым исходным кодом, предоставляет большое количество алгоритмов для глубинного обучения и научных расчётов. Ядро написано на Си, прикладная часть выполняется на LuaJIT, поддерживается распараллеливание вычислений средствами CUDA и OpenMP. Существуют реализации k-means.&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://www.cs.waikato.ac.nz/ml/weka/ Weka]&amp;lt;/li&amp;gt;  Cвободное программное обеспечение для анализа данных, написанное на Java. Содержит k-means и x-means.&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://accord-framework.net/docs/html/T_Accord_MachineLearning_KMeans.htm Accord.NET]&amp;lt;/li&amp;gt; C# реализация алгоритмов k-means, k-means++, k-modes.&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://docs.opencv.org/3.0-beta/doc/py_tutorials/py_ml/py_kmeans/py_kmeans_opencv/py_kmeans_opencv.html OpenCV]&amp;lt;/li&amp;gt; Написанная на С++ библиотека, направленная в основном на решение задач компьютерного зрения. Содержит реализацию k-means.&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://mlpack.org/ MLPACK]&amp;lt;/li&amp;gt; Масштабируемая С++ библиотека для работы с алгоритмами машинного обучения, содержит реализацию k-means.&lt;br /&gt;
  &amp;lt;li&amp;gt;[https://www.scipy.org/ SciPy]&amp;lt;/li&amp;gt; Библиотека Python, содержит множество реализаций k-means.&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://scikit-learn.org/ scikit-learn]&amp;lt;/li&amp;gt; Библиотека Python, содержит множество реализаций k-means.&lt;br /&gt;
  &amp;lt;li&amp;gt;[https://www.r-bloggers.com/k-means-clustering-in-r/ R]&amp;lt;/li&amp;gt; Язык программирования для статистической обработки данных и работы с графикой, а также свободная программная среда вычислений с открытым исходным кодом в рамках проекта GNU, содержит три реализации k-means.&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://elki.dbs.ifi.lmu.de ELKI]&amp;lt;/li&amp;gt; Java фреймворк, содержащий реализацию k-means, а также множество других алгоритмов кластеризации.&lt;br /&gt;
&amp;lt;/ol&amp;gt;&lt;br /&gt;
==== Проприетарное программное обеспечение  ====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ol&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;[https://www.ayasdi.com/blog/bigdata/topological-data-analysis-of-oil-and-gas-petrophysical-data/ Ayasdi]&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://www.stata.com/features/cluster-analysis/ Stata]&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://mathworld.wolfram.com/K-MeansClusteringAlgorithm.html Mathematica]&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://www.mathworks.com/help/stats/kmeans.html?requestedDomain=www.mathworks.com MATLAB]&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;[https://support.sas.com/rnd/app/stat/procedures/fastclus.html SAS]&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://docs.rapidminer.com/studio/operators/modeling/segmentation/k_means.html RapidMiner]&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;[https://blogs.sap.com/2013/03/28/sap-hana-pal-k-means-algorithm-or-how-to-do-customer-segmentation-for-the-telecommunications-industry/ SAP HANA]&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ol&amp;gt;&lt;br /&gt;
== Литература ==&lt;br /&gt;
&amp;lt;references /&amp;gt;&lt;/div&gt;</summary>
		<author><name>DennZo1993</name></author>
	</entry>
	<entry>
		<id>https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:%D0%91%D1%80%D0%BE%D1%82%D0%B8%D0%BA%D0%BE%D0%B2%D1%81%D0%BA%D0%B0%D1%8F_%D0%94%D0%B0%D0%BD%D1%83%D1%82%D0%B0/%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_k-means&amp;diff=20534</id>
		<title>Участник:Бротиковская Данута/Алгоритм k-means</title>
		<link rel="alternate" type="text/html" href="https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:%D0%91%D1%80%D0%BE%D1%82%D0%B8%D0%BA%D0%BE%D0%B2%D1%81%D0%BA%D0%B0%D1%8F_%D0%94%D0%B0%D0%BD%D1%83%D1%82%D0%B0/%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_k-means&amp;diff=20534"/>
		<updated>2016-12-10T11:11:27Z</updated>

		<summary type="html">&lt;p&gt;DennZo1993: /* Ресурс параллелизма алгоритма */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Assignment|Zhum}}&lt;br /&gt;
&lt;br /&gt;
{{algorithm&lt;br /&gt;
| name              = Алгоритм k средних (k means)&lt;br /&gt;
| serial_complexity = &amp;lt;math&amp;gt;O(ikdn)&amp;lt;/math&amp;gt;&lt;br /&gt;
| input_data        = &amp;lt;math&amp;gt; dn &amp;lt;/math&amp;gt;&lt;br /&gt;
| output_data       = &amp;lt;math&amp;gt; n &amp;lt;/math&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
Авторы страницы &amp;lt;b&amp;gt;[[Участник:Бротиковская Данута|Данута Бротиковская]]&amp;lt;/b&amp;gt; и &amp;lt;b&amp;gt;[[Участник:DennZo1993|Денис Зобнин]]&amp;lt;/b&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
Оба автора внесли одинаковый вклад в написание статьи (поиск материалов, изучение статей, заполнение контента статьи), четких разграничений по пунктам статьи сделать невозможно. &lt;br /&gt;
&lt;br /&gt;
== Свойства и структура алгоритма ==&lt;br /&gt;
&lt;br /&gt;
=== Общее описание алгоритма ===&lt;br /&gt;
Алгоритм &amp;lt;b&amp;gt;&amp;lt;i&amp;gt;k средних&amp;lt;/i&amp;gt;&amp;lt;/b&amp;gt; (&amp;lt;b&amp;gt;&amp;lt;i&amp;gt;k means&amp;lt;/i&amp;gt;&amp;lt;/b&amp;gt;) &amp;amp;ndash; неиерархический&amp;lt;ref&amp;gt;&amp;quot;https://ru.wikipedia.org/wiki/Иерархическая_кластеризация&amp;quot;&amp;lt;/ref&amp;gt;, итерационный метод кластеризации&amp;lt;ref&amp;gt;&amp;quot;https://ru.wikipedia.org/wiki/Кластерный_анализ&amp;quot;&amp;lt;/ref&amp;gt;, получивший большую популярность благодаря своей простоте, наглядности реализации и достаточно высокому качеству работы. Был изобретен в 1950-х годах математиком &amp;lt;i&amp;gt;Гуго Штейнгаузом&amp;lt;/i&amp;gt;&amp;lt;ref&amp;gt;Steinhaus, Hugo. &amp;quot;Sur la division des corp materiels en parties.&amp;quot; Bull. Acad. Polon. Sci 1.804 (1956): 801.&amp;lt;/ref&amp;gt; и почти одновременно &amp;lt;i&amp;gt;Стюартом Ллойдом&amp;lt;/i&amp;gt;&amp;lt;ref&amp;gt;Lloyd, S. P. &amp;quot;Least square quantization in PCM. Bell Telephone Laboratories Paper. Published in journal much later: Lloyd, SP: Least squares quantization in PCM.&amp;quot; IEEE Trans. Inform. Theor.(1957/1982).&amp;lt;/ref&amp;gt;. Особую популярность приобрел после публикации работы &amp;lt;i&amp;gt;МакКуина&amp;lt;/i&amp;gt;&amp;lt;ref&amp;gt;MacQueen, James. &amp;quot;Some methods for classification and analysis of multivariate observations.&amp;quot; Proceedings of the fifth Berkeley symposium on mathematical statistics and probability. Vol. 1. No. 14. 1967.&amp;lt;/ref&amp;gt; в 1967.&lt;br /&gt;
&lt;br /&gt;
Алгоритм представляет собой версию EM-алгоритма&amp;lt;ref&amp;gt;&amp;quot;https://ru.wikipedia.org/wiki/EM-алгоритм&amp;quot;&amp;lt;/ref&amp;gt;, применяемого также для разделения смеси гауссиан. Основная идея &amp;lt;i&amp;gt;k means&amp;lt;/i&amp;gt; заключается в том, что данные произвольно разбиваются на кластеры, после чего итеративно перевычисляется центр масс для каждого кластера, полученного на предыдущем шаге, затем векторы разбиваются на кластеры вновь в соответствии с тем, какой из новых центров оказался ближе по выбранной метрике.&lt;br /&gt;
&lt;br /&gt;
Цель алгоритма заключается в разделении &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; наблюдений на &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластеров таким образом, чтобы каждое наблюдение принадлежало ровно одному кластеру, расположенному на наименьшем расстоянии от наблюдения.&lt;br /&gt;
&lt;br /&gt;
=== Математическое описание алгоритма ===&lt;br /&gt;
&amp;lt;b&amp;gt;&amp;lt;u&amp;gt;Дано:&amp;lt;/u&amp;gt;&amp;lt;/b&amp;gt;&lt;br /&gt;
* набор из &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; наблюдений &amp;lt;math&amp;gt;X=\{\mathbf{x}_1, \mathbf{x}_2, ..., \mathbf{x}_n\}, \mathbf{x}_i \in \mathbb{R}^d, i=\overline{1, n}&amp;lt;/math&amp;gt;;&lt;br /&gt;
* &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; - требуемое число кластеров, &amp;lt;math&amp;gt;k \in \mathbb{N}, k \leq n&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;&amp;lt;u&amp;gt;Требуется:&amp;lt;/u&amp;gt;&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Разделить множество наблюдений &amp;lt;math&amp;gt;X&amp;lt;/math&amp;gt; на &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластеров &amp;lt;math&amp;gt;S_1, S_2, ..., S_k&amp;lt;/math&amp;gt;:&lt;br /&gt;
*   &amp;lt;math&amp;gt;S_i \cap S_j= \varnothing, \quad i \ne j&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
*   &amp;lt;math&amp;gt;\bigcup_{i=1}^{k} S_i = X&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;&amp;lt;u&amp;gt;Действие алгоритма:&amp;lt;/u&amp;gt;&amp;lt;/b&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;Алгоритм &amp;lt;i&amp;gt;k means&amp;lt;/i&amp;gt; разбивает набор &amp;lt;math&amp;gt;X&amp;lt;/math&amp;gt; на &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; наборов &amp;lt;math&amp;gt;S_1, S_2, ..., S_k,&amp;lt;/math&amp;gt; таким образом, чтобы минимизировать сумму квадратов расстояний от каждой точки кластера до его центра (центр масс кластера). Введем обозначение, &amp;lt;math&amp;gt;S=\{S_1, S_2, ..., S_k\}&amp;lt;/math&amp;gt;. Тогда действие алгоритма &amp;lt;i&amp;gt;k means&amp;lt;/i&amp;gt; равносильно поиску:&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;table style=&amp;quot;width:100%&amp;quot;&amp;gt;&lt;br /&gt;
  &amp;lt;tr&amp;gt;&lt;br /&gt;
    &amp;lt;td align=&amp;quot;center&amp;quot; width=&amp;quot;90%&amp;quot;&amp;gt;&amp;lt;math&amp;gt;\arg\min_{S} \sum\limits_{i=1}^k \sum\limits_{\mathbf{x} \in S_i} \rho(\mathbf{x}, \mathbf{\mu}_i )^2,&amp;lt;/math&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;td align=&amp;quot;right&amp;quot;&amp;gt;&amp;lt;math&amp;gt;(1)&amp;lt;/math&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;/table&amp;gt;&lt;br /&gt;
где &amp;lt;math&amp;gt;\mathbf{\mu}_i&amp;lt;/math&amp;gt; &amp;amp;ndash; центры кластеров, &amp;lt;math&amp;gt;i=\overline{1,k}, \quad \rho(\mathbf{x}, \mathbf{\mu}_i)&amp;lt;/math&amp;gt; &amp;amp;ndash; функция расстояния между &amp;lt;math&amp;gt;\mathbf{x}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\mu_i&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;&amp;lt;u&amp;gt;Шаги алгоритма: &amp;lt;/u&amp;gt;&amp;lt;/b&amp;gt;&lt;br /&gt;
&amp;lt;ol&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&lt;br /&gt;
    &amp;lt;b&amp;gt;Начальный шаг: инициализация кластеров&amp;lt;/b&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;Выбирается произвольное множество точек &amp;lt;math&amp;gt;\mu_i, i=\overline{1,k}&amp;lt;/math&amp;gt;, рассматриваемых как начальные центры кластеров: &amp;lt;math&amp;gt;\mu_i^{(0)} = \mu_i, \quad i=\overline{1, k}&amp;lt;/math&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
  &amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&lt;br /&gt;
    &amp;lt;b&amp;gt;Распределение векторов по кластерам&amp;lt;/b&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Шаг&amp;lt;/b&amp;gt; &amp;lt;math&amp;gt;t: \forall \mathbf{x}_i \in X, i=\overline{1,n}: \mathbf{x}_i \in S_j \iff  j=\arg\min_{k}\rho(\mathbf{x}_i,\mathbf{\mu}_k^{(t-1)})^2&amp;lt;/math&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
  &amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&lt;br /&gt;
    &amp;lt;b&amp;gt;Пересчет центров кластеров&amp;lt;/b&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Шаг &amp;lt;/b&amp;gt; &amp;lt;math&amp;gt;t: \forall i=\overline{1,k}:  \mu_i^{(t)} = \cfrac{1}{|S_i|}\sum_{\mathbf{x}\in S_i}\mathbf{x}&amp;lt;/math&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
  &amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&lt;br /&gt;
    &amp;lt;b&amp;gt;Проверка условия останова:&amp;lt;/b&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
    &#039;&#039;&#039;if&#039;&#039;&#039; &amp;lt;math&amp;gt;\exist i\in \overline{1,k}: \mu_i^{(t)} \ne \mu_i^{(t-1)}&amp;lt;/math&amp;gt; &#039;&#039;&#039;then&#039;&#039;&#039;&lt;br /&gt;
        t = t + 1;&lt;br /&gt;
        goto 2;&lt;br /&gt;
    &#039;&#039;&#039;else&#039;&#039;&#039;&lt;br /&gt;
        &#039;&#039;&#039;stop&#039;&#039;&#039;&lt;br /&gt;
  &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ol&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Вычислительное ядро алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Вычислительным ядром являются шаги 2 и 3 приведенного выше алгоритма: &amp;lt;b&amp;gt;&amp;lt;i&amp;gt;распределение векторов по кластерам&amp;lt;/i&amp;gt;&amp;lt;/b&amp;gt; и &amp;lt;b&amp;gt;&amp;lt;i&amp;gt;пересчет центров кластеров&amp;lt;/i&amp;gt;&amp;lt;/b&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;&amp;lt;i&amp;gt;Распределение векторов&amp;lt;/i&amp;gt;&amp;lt;/b&amp;gt; по кластерам предполагает вычисление расстояний между каждым вектором &amp;lt;math&amp;gt;\mathbf{x}_i \in X, i= \overline{1,n}&amp;lt;/math&amp;gt; и центрами кластера &amp;lt;math&amp;gt;\mathbf{\mu}_j, j= \overline{1,k}&amp;lt;/math&amp;gt;. Таким образом, данный шаг предполагает &amp;lt;math&amp;gt;kn&amp;lt;/math&amp;gt; вычислений расстояний между d-мерными векторами. &lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;&amp;lt;i&amp;gt;Пересчет центров кластеров&amp;lt;/i&amp;gt;&amp;lt;/b&amp;gt; предполагает &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; вычислений центров масс &amp;lt;math&amp;gt;\mathbf{\mu}_i&amp;lt;/math&amp;gt; множеств &amp;lt;math&amp;gt;S_i, i=\overline{1,k}&amp;lt;/math&amp;gt; представленных выражением в шаге 3 представленного выше алгоритма.&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Макроструктура алгоритма ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Инициализация центров масс &amp;lt;math&amp;gt;\mu_1, ..., \mu_k&amp;lt;/math&amp;gt;&amp;lt;/b&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
Наиболее распространенными являются следующие стратегии:&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&lt;br /&gt;
    &amp;lt;b&amp;gt;Метод Forgy&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;В качестве начальных значений &amp;lt;math&amp;gt;\mu_1, ..., \mu_k&amp;lt;/math&amp;gt; берутся случайно выбранные векторы.&lt;br /&gt;
  &amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&lt;br /&gt;
    &amp;lt;b&amp;gt;Метод случайно разделения (Random Partitioning)&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;Для каждого вектора &amp;lt;math&amp;gt;\mathbf{x}_i \in X, i=\overline{1, n}&amp;lt;/math&amp;gt; выбирается случайным образом кластер &amp;lt;math&amp;gt;S_1, ..., S_k&amp;lt;/math&amp;gt;, после чего для каждого полученного кластера вычисляются значения &amp;lt;math&amp;gt;\mu_1, ..., \mu_k&amp;lt;/math&amp;gt;.&lt;br /&gt;
  &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Распределение векторов по кластерам&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Для этого шага алгоритма между векторами &amp;lt;math&amp;gt;\mathbf{x}_i \in X, i=\overline{1, n}&amp;lt;/math&amp;gt; и центрами кластеров &amp;lt;math&amp;gt;\mu_1, ..., \mu_k&amp;lt;/math&amp;gt; вычисляются &amp;lt;b&amp;gt;расстояния&amp;lt;/b&amp;gt; по формуле (как правило, используется Евлидово расстояние):&lt;br /&gt;
&amp;lt;table style=&amp;quot;width:100%&amp;quot;&amp;gt;&lt;br /&gt;
  &amp;lt;tr&amp;gt;&lt;br /&gt;
    &amp;lt;td align=&amp;quot;center&amp;quot; width=&amp;quot;90%&amp;quot;&amp;gt;&amp;lt;math&amp;gt; \mathbf{v}_1, \mathbf{v}_2 \in \mathbb{R}^d,  \quad \rho(\mathbf{v}_1, \mathbf{v}_2) = \lVert \mathbf{v}_1- \mathbf{v}_2 \rVert= \sqrt{\sum_{i=1}^{d}(\mathbf{v}_{1,i} - \mathbf{v}_{2,i})^2}&amp;lt;/math&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;td align=&amp;quot;right&amp;quot;&amp;gt;&amp;lt;math&amp;gt;(2)&amp;lt;/math&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;/table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Пересчет центров кластеров&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Для этого шага алгоритма производится пересчет центров кластера по &amp;lt;b&amp;gt;формуле вычисления центра масс&amp;lt;/b&amp;gt;:&lt;br /&gt;
&amp;lt;table style=&amp;quot;width:100%&amp;quot;&amp;gt;&lt;br /&gt;
  &amp;lt;tr&amp;gt;&lt;br /&gt;
    &amp;lt;td align=&amp;quot;center&amp;quot; width=&amp;quot;90%&amp;quot;&amp;gt;&amp;lt;math&amp;gt; \mu = \cfrac{1}{|S|}\sum_{\mathbf{x}\in S}\mathbf{x}&amp;lt;/math&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;td align=&amp;quot;right&amp;quot;&amp;gt;&amp;lt;math&amp;gt;(3)&amp;lt;/math&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;/table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Схема реализации последовательного алгоритма ===&lt;br /&gt;
&lt;br /&gt;
 &#039;&#039;&#039;algorithm&#039;&#039;&#039; k-means &#039;&#039;&#039;is&#039;&#039;&#039;&lt;br /&gt;
     &#039;&#039;&#039;1.&#039;&#039;&#039; Инициализировать центры кластеров &amp;lt;math&amp;gt;\mathbf{\mu}_i^{(1)}, i=\overline{1,k}&amp;lt;/math&amp;gt;&lt;br /&gt;
     &#039;&#039;&#039;2.&#039;&#039;&#039; &amp;lt;math&amp;gt;t \leftarrow 1&amp;lt;/math&amp;gt;&lt;br /&gt;
     &#039;&#039;&#039;3.&#039;&#039;&#039; &#039;&#039;&#039;Распределение по кластерам&#039;&#039;&#039;&amp;lt;br&amp;gt;&lt;br /&gt;
        &amp;lt;math&amp;gt;S_i^{(t)}=\{\mathbf{x}_p: \lVert\mathbf{x}_p-\mathbf{\mu}_i^{(t)}\rVert^2 \leq \lVert\mathbf{x}_p-\mathbf{\mu}_j^{(t)}\rVert^2 \quad \forall j=\overline{1,k}\},&amp;lt;/math&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
        где каждый вектор &amp;lt;math&amp;gt;\mathbf{x}_p&amp;lt;/math&amp;gt; соотносится единственному кластеру &amp;lt;math&amp;gt;S^{(t)}&amp;lt;/math&amp;gt;&lt;br /&gt;
     &#039;&#039;&#039;4.&#039;&#039;&#039; &#039;&#039;&#039;Обновление центров кластеров&#039;&#039;&#039;&amp;lt;br&amp;gt;&lt;br /&gt;
        &amp;lt;math&amp;gt;\mathbf{\mu}_i^{(t+1)} = \frac{1}{|S^{(t)}_i|} \sum_{\mathbf{x}_j \in S^{(t)}_i} \mathbf{x}_j &amp;lt;/math&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
     &#039;&#039;&#039;5.&#039;&#039;&#039; &#039;&#039;&#039;if&#039;&#039;&#039; &amp;lt;math&amp;gt;\exist i \in \overline{1,k}: \mathbf{\mu}_i^{(t+1)} \ne \mathbf{\mu}_i^{(t)}&amp;lt;/math&amp;gt; &#039;&#039;&#039;then&#039;&#039;&#039;&lt;br /&gt;
            t = t + 1;&lt;br /&gt;
            goto &#039;&#039;&#039;3&#039;&#039;&#039;;&lt;br /&gt;
        &#039;&#039;&#039;else&#039;&#039;&#039;&lt;br /&gt;
            &#039;&#039;&#039;stop&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
=== Последовательная сложность алгоритма===&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding-bottom: 20px&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;Обозначим &amp;lt;math&amp;gt;\Theta_{\rm centroid}^{d, m}&amp;lt;/math&amp;gt; временную сложность вычисления центорида кластера, число элементов которого равна &amp;lt;math&amp;gt;m&amp;lt;/math&amp;gt;,  в d-мерном пространстве.&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;Аналогично  &amp;lt;math&amp;gt;\Theta_{\rm distance}^d&amp;lt;/math&amp;gt; &amp;amp;ndash; временная сложность вычисления расстояния между двумя d-мерными векторами.&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding-bottom: 20px&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;Сложность шага инициализации &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластеров мощности &amp;lt;math&amp;gt;m&amp;lt;/math&amp;gt; в d-мерном пространстве &amp;amp;ndash; &amp;lt;math&amp;gt;\Theta_{\rm init}^{k, d, m}&amp;lt;/math&amp;gt;&amp;lt;/b&amp;gt;&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;i&amp;gt;Стратерия Forgy&amp;lt;/i&amp;gt;: вычисления не требуются, &amp;lt;math&amp;gt;\Theta_{\rm init}^{k, d, m} = 0&amp;lt;/math&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;i&amp;gt;Стратегия случайного разбиения&amp;lt;/i&amp;gt;: вычисление центров &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластеров,  &amp;lt;math&amp;gt;\Theta_{\rm init}^{k, d, m} = k \cdot \Theta_{\rm centroid}^{d, m}, m \le n&amp;lt;/math&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding-bottom: 20px&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Cложность шага распределения d мерных векторов по &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластерам &amp;amp;ndash; &amp;lt;math&amp;gt;\Theta_{\rm distribute}^{k, d}&amp;lt;/math&amp;gt;&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
На этом шаге для каждого вектора &amp;lt;math&amp;gt;\mathbf{x}_i \in X, i=\overline{1, n}&amp;lt;/math&amp;gt; вычисляется k расстояний до центров кластеров &amp;lt;math&amp;gt;\mathbf{\mu}_1, ...\mathbf{\mu}_k&amp;lt;/math&amp;gt;&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p align=&amp;quot;center&amp;quot;&amp;gt;&lt;br /&gt;
  &amp;lt;math&amp;gt;\Theta_{\rm distribute}^{k, d} = n \cdot k \cdot \Theta_{\rm distance}^d&amp;lt;/math&amp;gt;&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding-bottom: 20px&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;Сложность шага пересчета центров &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластеров размера &amp;lt;math&amp;gt;m&amp;lt;/math&amp;gt; в d-мерном пространстве &amp;amp;ndash; &amp;lt;math&amp;gt;\Theta_{\rm recenter}^{k, d, m}&amp;lt;/math&amp;gt;&amp;lt;/b&amp;gt;&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;На этом шаге вычисляется &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; центров кластеров &amp;lt;math&amp;gt;\mathbf{\mu}_1, ...\mathbf{\mu}_k&amp;lt;/math&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p align=&amp;quot;center&amp;quot;&amp;gt;&amp;lt;math&amp;gt;\Theta_{\rm recenter}^{k, d, m} = k \cdot \Theta_{\rm centroid}^{d, m}&amp;lt;/math&amp;gt; &amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding-bottom: 20px&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Рассчитаем &amp;lt;math&amp;gt;\Theta_{\rm centroid}^{d, m}&amp;lt;/math&amp;gt; для кластера, число элементов которого равно &amp;lt;math&amp;gt;m&amp;lt;/math&amp;gt;&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p align=&amp;quot;center&amp;quot;&amp;gt;&amp;lt;math&amp;gt;\Theta_{\rm centroid}^{d, m}&amp;lt;/math&amp;gt; = &amp;lt;math&amp;gt;m \cdot d&amp;lt;/math&amp;gt; сложений + &amp;lt;math&amp;gt;d&amp;lt;/math&amp;gt; делений &amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding-bottom: 20px&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Рассчитаем &amp;lt;math&amp;gt;\Theta_{\rm distance}^d&amp;lt;/math&amp;gt; в соответствие с формулой &amp;lt;math&amp;gt;(2)&amp;lt;/math&amp;gt;&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p align=&amp;quot;center&amp;quot;&amp;gt;&amp;lt;math&amp;gt;\Theta_{\rm distance}^d&amp;lt;/math&amp;gt; = &amp;lt;math&amp;gt;d&amp;lt;/math&amp;gt; вычитаний + &amp;lt;math&amp;gt;d&amp;lt;/math&amp;gt; умножений + &amp;lt;math&amp;gt;(d-1)&amp;lt;/math&amp;gt; сложение&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding-bottom: 20px&amp;quot;&amp;gt;&lt;br /&gt;
  &amp;lt;p&amp;gt;Предположим, что алгоритм сошелся за &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt; итераций, тогда временная сложность алгоритма &amp;lt;math&amp;gt;\Theta_{\rm k-means}^{d, n}&amp;lt;/math&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
  &amp;lt;p align=&amp;quot;center&amp;quot;&amp;gt;&amp;lt;b&amp;gt;&amp;lt;math&amp;gt;\Theta_{\rm k-means}^{d, n} \le \Theta_{\rm init}^{k, d, n} + i(\Theta_{\rm distribute}^{k, d} + \Theta_{\rm recenter}^{k, d, n})&amp;lt;/math&amp;gt;&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding-bottom: 5px&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;Операции сложения/вычитания:&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p align=&amp;quot;center&amp;quot;&amp;gt;&amp;lt;b&amp;gt;&amp;lt;math&amp;gt;\Theta_{\rm k-means}^{d, n} \le knd+ i(kn(2d-1) + knd) = knd+ i(kn(3d-1)) \thicksim O(ikdn)&amp;lt;/math&amp;gt;&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding-bottom: 20px&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;Операции умножения/деления:&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p align=&amp;quot;center&amp;quot;&amp;gt;&amp;lt;b&amp;gt;&amp;lt;math&amp;gt;\Theta_{\rm k-means}^{d, n} \le kd + i(knd + kd) = kd + ikd(n+1) \thicksim O(ikdn) &amp;lt;/math&amp;gt;&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding-bottom: 20px&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;Получаем, что &amp;lt;b&amp;gt;временная сложность&amp;lt;/b&amp;gt; алгоритма &amp;lt;b&amp;gt;k means&amp;lt;/b&amp;gt; кластеризации &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; &amp;lt;b&amp;gt;d-мерных&amp;lt;/b&amp;gt; векторов на &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластеров за &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt; итераций:&amp;lt;/p&amp;gt;&lt;br /&gt;
 &amp;lt;p align=&amp;quot;center&amp;quot;&amp;gt;&amp;lt;b&amp;gt;&amp;lt;math&amp;gt; \Theta_{\rm k-means}^{d, n} \thicksim O(ikdn) &amp;lt;/math&amp;gt;&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Информационный граф ===&lt;br /&gt;
&lt;br /&gt;
Рассмотрим информационный граф алгоритма. Алгоритм &amp;lt;i&amp;gt;k means&amp;lt;/i&amp;gt; начинается с этапа инициализации, после которого следуют итерации, на каждой из которых выполняется два последовательных шага (см. [[#Схема реализации последовательного алгоритма|&amp;quot;Схема реализации последовательного алгоритма&amp;quot;]]): &lt;br /&gt;
* распределение векторов по кластерам&lt;br /&gt;
* перерасчет центров кластеров&lt;br /&gt;
&lt;br /&gt;
Поскольку основная часть вычислений приходится на шаги итераций, распишем информационные графы данных шагов.&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Распределение векторов по кластерам&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
Информационный граф шага распределения векторов по кластерам представлен на &#039;&#039;рисунке 1&#039;&#039;. Исходами данного графа является исходные векторы &amp;lt;math&amp;gt;\mathbf{x}_1, ..., \mathbf{x}_n&amp;lt;/math&amp;gt;, а также центры кластеров &amp;lt;math&amp;gt;\mathbf{\mu}_1, ... \mathbf{\mu}_k&amp;lt;/math&amp;gt;, вычисленные ранее (на шаге инициализации, если рассматривается первая итерация алгоритма, или на шаге пересчета центров кластеров предыдущей итерации в противном случае). Каждая пара векторов данных &amp;lt;math&amp;gt;\mathbf{x}_i, i=\overline{1,n}&amp;lt;/math&amp;gt; и центров кластера &amp;lt;math&amp;gt;\mathbf{\mu}_j, j=\overline{1, k}&amp;lt;/math&amp;gt; : (&amp;lt;math&amp;gt;\mathbf{x}_i&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;\mathbf{\mu}_j&amp;lt;/math&amp;gt;) подаются на независимые узлы &amp;lt;i&amp;gt;&amp;quot;d&amp;quot;&amp;lt;/i&amp;gt; вычисления расстояния между векторами (более подробная схема вычисления расстояния представлена далее, &#039;&#039;рисунок 2&#039;&#039;). Далее узлы вычисления расстояния &amp;lt;i&amp;gt;&amp;quot;d&amp;quot;&amp;lt;/i&amp;gt;, соответствующие одному и тому же исходному вектору &amp;lt;math&amp;gt;\mathbf{x}_i&amp;lt;/math&amp;gt; передаются на один узел &amp;lt;i&amp;gt;&amp;quot;m&amp;quot;&amp;lt;/i&amp;gt;, где далее происходит вычисление новой метки кластера для каждого вектора &amp;lt;math&amp;gt;\mathbf{x}_i&amp;lt;/math&amp;gt; (берется кластер с минимальным результатом вычисления расстояния). На выходе графа выдаются метки кластеров , &amp;lt;math&amp;gt;L_1, ..., L_n&amp;lt;/math&amp;gt;, такие что &amp;lt;math&amp;gt;\forall \mathbf{x}_i, i=\overline{1, n}, \mathbf{x}_i \in S_j \Leftrightarrow L_i = j&amp;lt;/math&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
[[file:Clusterization.png|thumb|center|800px|Рис. 1. Схема распределения векторов по кластерам. &#039;&#039;d&#039;&#039; &amp;amp;ndash; вычисление расстояния между векторами; &#039;&#039;m&#039;&#039; &amp;amp;ndash; вычисление минимума.]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Вычисление расстояния между векторами&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
Подробная схема вычисления расстояния между векторами &amp;lt;math&amp;gt;\mathbf{x}_i, \mathbf{\mu}_j&amp;lt;/math&amp;gt; представлена на &#039;&#039;рисунке 2&#039;&#039;. Как показано на графе, узел вычисления расстояния между векторами &amp;lt;i&amp;gt;&amp;quot;d&amp;quot;&amp;lt;/i&amp;gt; состоит из шага взятия разности между векторами (узел &amp;quot;&amp;lt;math&amp;gt;-&amp;lt;/math&amp;gt;&amp;quot;) и взятия нормы получившегося вектора разности (узел &amp;quot;&amp;lt;math&amp;gt;||\cdot||^2&amp;lt;/math&amp;gt;&amp;quot;). Более подробно, вычисление расстояния между векторами &amp;lt;math&amp;gt;\mathbf{x}_i = {x_{i1,}, ...,{x_{in}}}, \mathbf{\mu}_j = {\mu_{j1}, ...,\mu_{jn}}&amp;lt;/math&amp;gt; может быть представлено как вычисление разности между каждой парой компонент &amp;lt;math&amp;gt;(x_{iz}, \mu_{jz}), z=\overline{1, d}&amp;lt;/math&amp;gt; (узел &amp;quot;&amp;lt;math&amp;gt;-&amp;lt;/math&amp;gt;&amp;quot;), далее возведение в квадрат для каждого узла &amp;quot;&amp;lt;math&amp;gt;-&amp;lt;/math&amp;gt;&amp;quot; (узел &amp;quot;&amp;lt;math&amp;gt;()^2&amp;lt;/math&amp;gt;&amp;quot;) и суммирования выходов всех узлов &amp;quot;&amp;lt;math&amp;gt;()^2&amp;lt;/math&amp;gt;&amp;quot; (узел &amp;quot;&amp;lt;math&amp;gt;+&amp;lt;/math&amp;gt;&amp;quot;).  &lt;br /&gt;
&lt;br /&gt;
[[file:dist_calc.png|thumb|center|800px|Рис. 2. Схема вычисления расстояния между вектором и центром кластера.]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Пересчет центров кластеров&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
Информационный граф шага пересчета центров кластеров представлен на &#039;&#039;рисунке 3&#039;&#039;. Исходами данного графа является исходные векторы &amp;lt;math&amp;gt;\mathbf{x}_1, ..., \mathbf{x}_n&amp;lt;/math&amp;gt;, а также им соответствующие метки кластера, &amp;lt;math&amp;gt;L_1, ..., L_n&amp;lt;/math&amp;gt;, такие что &amp;lt;math&amp;gt;\forall x_i, i=\overline{1, n}, \mathbf{x}_i \in S_j \Leftrightarrow L_i = j&amp;lt;/math&amp;gt;, вычисленные на этапе распределения векторов по кластерам. Все векторы &amp;lt;math&amp;gt;\mathbf{x}_1, ..., \mathbf{x}_n&amp;lt;/math&amp;gt; подаются в узлы &amp;lt;math&amp;gt;+_1, ...+_k&amp;lt;/math&amp;gt;, каждый узел &amp;lt;math&amp;gt;+_m, m = \overline{1,k}&amp;lt;/math&amp;gt; соответствует операции сложения векторов кластера с номером &amp;lt;math&amp;gt;m&amp;lt;/math&amp;gt;. Метки кластера &amp;lt;math&amp;gt;L_1, ..., L_n&amp;lt;/math&amp;gt; также совместно передаются на узлы &amp;lt;math&amp;gt;S_m, m = \overline{1,k}&amp;lt;/math&amp;gt;, на каждом из которых вычисляется количество векторов в соответствующем кластере (количество меток с соответствующим значением). Далее каждая пара выходов узлов &amp;lt;math&amp;gt;+_m&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;S_m&amp;lt;/math&amp;gt; подается на узел &amp;quot;&amp;lt;math&amp;gt;/&amp;lt;/math&amp;gt;&amp;quot;, где производится деление суммы векторов кластера на количество элементов в нем. Значения, вычисленные на узлах &amp;quot;&amp;lt;math&amp;gt;/&amp;lt;/math&amp;gt;&amp;quot;, присваиваются новым центрам кластеров (выходные значения графа).&lt;br /&gt;
&lt;br /&gt;
[[file:Recluster.png|thumb|center|800px|Рис. 3. Схема пересчета центров кластеров]]&lt;br /&gt;
&lt;br /&gt;
=== Ресурс параллелизма алгоритма ===&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
Работа алгоритма состоит из &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt; итераций, в каждой из которых происходит &amp;lt;b&amp;gt;распределение d-мерных векторов по &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластерам&amp;lt;/b&amp;gt;, а также &amp;lt;b&amp;gt;пересчет центров кластеров в d-мерном пространстве&amp;lt;/b&amp;gt;. В шаге &amp;lt;b&amp;gt;распределения d-мерных векторов по &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластерам&amp;lt;/b&amp;gt; расстояния между вектором и центрами кластеров вычисляются независимо (отсутствуют информационные зависимости). &amp;lt;b&amp;gt;Центры масс кластеров&amp;lt;/b&amp;gt; также пересчитываются независимо друг от друга. Таким образом, имеет место [[глоссарий#Массовый параллелизм|&#039;&#039;массовый параллелизм&#039;&#039;]]. Вычислим параллельную сложность &amp;lt;math&amp;gt;\Psi_*&amp;lt;/math&amp;gt; каждого из шагов, а также параллельную сложность всего алгоритма, &amp;lt;math&amp;gt;\Psi_{\rm k-means}&amp;lt;/math&amp;gt;. Будем исходить из предположения, что может быть использовано любое необходимое число потоков.&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Распределение d-мерных векторов по &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластерам&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;  &lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
Поскольку на данном шаге для каждой пары векторов &amp;lt;math&amp;gt;\mathbf{x}_i, i=\overline{1,n}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\mathbf{\mu}_j, j=\overline{1,k}&amp;lt;/math&amp;gt; операции вычисления расстояния не зависят друг от друга, они могут выполняться параллельно. Тогда, разделив все вычисление расстояний на &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; потоков, получим, что в каждом потоке будет выполняться только одна операция вычисления расстояния между векторами размерности d. При этом каждому вычислительному потоку передаются координаты центров всех кластеров &amp;lt;math&amp;gt;\mathbf{\mu}_1, ..., \mathbf{\mu}_k&amp;lt;/math&amp;gt;. Таким образом, параллельная сложность данного шага определяется &amp;lt;i&amp;gt; сложностью параллельной операции вычисления расстояния между d-мерными векторами&amp;lt;/i&amp;gt;, &amp;lt;math&amp;gt;\Psi_{\rm distance}^d&amp;lt;/math&amp;gt;  и &amp;lt;i&amp;gt;сложностью определения наиболее близкого кластера&amp;lt;/i&amp;gt; (паралельное взятие минимума по расстояниям), &amp;lt;math&amp;gt;\Psi_{\rm min}^k&amp;lt;/math&amp;gt;. Для оценки &amp;lt;math&amp;gt;\Psi_{\rm distance}^d&amp;lt;/math&amp;gt; воспользуемся  [[Нахождение_частных_сумм_элементов_массива_сдваиванием | параллельной реализацией нахождения частичной суммы элементов массива путем сдваивания]]. Аналогично, &amp;lt;math&amp;gt;\Psi_{\rm min}^k = log(k)&amp;lt;/math&amp;gt;. В результате, &amp;lt;math&amp;gt;\Psi_{\rm distance}^d = O(log(d))&amp;lt;/math&amp;gt;.   Таким образом: &lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p align=&amp;quot;center&amp;quot;&amp;gt;&amp;lt;math&amp;gt;\Psi_{\rm distribute}^{k, d}  = \Psi_{\rm distance}^d + \Psi_{\rm min}^k = O(log(d))+O(log(k)) = O(log(kd))&amp;lt;/math&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Пересчет центров кластеров в d-мерном пространстве&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
Поскольку на данном шаге для каждого из &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластеров центр масс может быть вычислен независимо, данные операции могут быть выполнены в отдельных потоках. Таким образом, параллельная сложность данного шага, &amp;lt;math&amp;gt;\Psi_{\rm recenter}^{k, d}&amp;lt;/math&amp;gt;,  будет определяться &amp;lt;i&amp;gt;параллельной сложностью вычисления одного центра масс кластера размера &amp;lt;math&amp;gt;m&amp;lt;/math&amp;gt;&amp;lt;/i&amp;gt;, &amp;lt;math&amp;gt;\Psi_{\rm recenter}^{k, d}&amp;lt;/math&amp;gt;,  а так как &amp;lt;math&amp;gt;m \le n \Rightarrow \Psi_{\rm recenter}^{d, m} \le \Psi_{\rm recenter}^{d, n}&amp;lt;/math&amp;gt;. Сложность вычисления центра масс кластера d-мерных векторов размера n аналогично предыдущим вычислениям равна &amp;lt;math&amp;gt;O(log(n))&amp;lt;/math&amp;gt;. Тогда:  &lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p align=&amp;quot;center&amp;quot;&amp;gt;&amp;lt;math&amp;gt;\Psi_{\rm recenter}^{k, d}  \le \Psi_{\rm recenter}^{d, n} = O(log(n))&amp;lt;/math&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Общая параллельная сложность алгоритма&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
На каждой итерации необходимо обновление центров кластеров, которые будут использованы на следующей итерации. Таким образом, итерационный процесс выполняется последовательно&amp;lt;ref&amp;gt;Zhao, Weizhong, Huifang Ma, and Qing He. &amp;quot;Parallel k-means clustering based on mapreduce.&amp;quot; IEEE International Conference on Cloud Computing. Springer Berlin Heidelberg, 2009.&amp;lt;/ref&amp;gt;. Тогда, поскольку сложность каждой итерации  определяется &amp;lt;math&amp;gt;\Psi_{distribute}^{k, d}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\Psi_{\rm recenter}&amp;lt;/math&amp;gt;, сложность всего алгоритма, &amp;lt;math&amp;gt;\Psi_{\rm k-means}&amp;lt;/math&amp;gt; в предположении, что было сделано &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt; операций определяется выражением&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p align=&amp;quot;center&amp;quot;&amp;gt;&amp;lt;math&amp;gt;\Psi_{\rm k-means} \approx i \cdot (\Psi_{\rm distribute}^{k, d} + \Psi_{\rm recenter}^{k, d}) \le i \cdot O(log(kdn))&amp;lt;/math&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Входные и выходные данные алгоритма ===&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;Входные данные&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;Матрица из &amp;lt;math&amp;gt;n \cdot d&amp;lt;/math&amp;gt; элементов &amp;lt;math&amp;gt;x_{i, j} \in \mathbb{R}, i=\overline{1, n}, j=\overline{1, d}&amp;lt;/math&amp;gt;&amp;amp;ndash; координат векторов (наблюдений).&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;Целое положительное число &amp;lt;math&amp;gt;k, k \le n&amp;lt;/math&amp;gt; &amp;amp;ndash; количество кластеров.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;Объем входных данных&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;math&amp;gt;1&amp;lt;/math&amp;gt; целое число + &amp;lt;math&amp;gt;n \cdot d&amp;lt;/math&amp;gt; вещественных чисел (при условии, что координаты &amp;amp;ndash; вещественные числа).&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;Выходные данные&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; целых положительных чисел &amp;lt;math&amp;gt;L_1, ..., L_n&amp;lt;/math&amp;gt;&amp;amp;ndash; номера кластеров, соотвествующие каждому вектору (при условии, что нумерация кластеров начинается с &amp;lt;math&amp;gt;1&amp;lt;/math&amp;gt;).&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;Объем выходных данных&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; целых положительных чисел.&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Свойства алгоритма ===&lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;[[глоссарий#Вычислительная мощность|&#039;&#039;Вычислительная мощность&#039;&#039;]]&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
Вычислительная мощность алгоритма &amp;lt;i&amp;gt;k means&amp;lt;/i&amp;gt; равна &amp;lt;math&amp;gt;\frac{ikdn}{nd} = ki &amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; &amp;amp;ndash; число кластеров, &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt; &amp;amp;ndash; число итераций алгоритма.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;[[глоссарий#Детерминированность |&#039;&#039;Детерминированность&#039;&#039;]] и [[глоссарий#Устойчивость |&#039;&#039;Устойчивость&#039;&#039;]] &amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
Алгоритм &amp;lt;i&amp;gt;k means&amp;lt;/i&amp;gt; является итерационным. Количество итераций алгоритма в общем случае не фиксируется и зависит от начального расположения объектов в пространстве, параметра &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt;, а также от начального приближения центров кластеров, &amp;lt;math&amp;gt;\mu_1, ..., \mu_k&amp;lt;/math&amp;gt;. В результате этого может варьироваться результат работы алгоритма. При неудачном выборе начальных параметров итерационный процесс может сойтись к локальному оптимуму&amp;lt;ref&amp;gt;Von Luxburg, Ulrike. Clustering Stability. Now Publishers Inc, 2010.&amp;lt;/ref&amp;gt;. По этим причинам алгоритм не является ни &amp;lt;b&amp;gt;детермирированным&amp;lt;/b&amp;gt;, ни &amp;lt;b&amp;gt;устойчивым&amp;lt;/b&amp;gt;.&lt;br /&gt;
 &lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Соотношение последовательной и параллельной сложности алгоритма&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\frac{\Theta_{k-means}}{\Psi_{k-means}} = \frac{O(ikdn)}{O(i \cdot log(kdn))}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Сильные стороны алгоритма&amp;lt;/b&amp;gt;:&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;i&amp;gt;Сравнительно высокая эффективность при простоте реализации&amp;lt;/i&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;i&amp;gt;Высокое качество кластеризации&amp;lt;/i&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;i&amp;gt;Возможность распараллеливания&amp;lt;/i&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;i&amp;gt;Существование множества модификаций&amp;lt;/i&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;Недостатки алгоритма&amp;lt;/b&amp;gt;&amp;lt;ref&amp;gt;Ortega, Joaquín Pérez, Ma Del Rocío Boone Rojas, and María J. Somodevilla. &amp;quot;Research issues on K-means Algorithm: An Experimental Trial Using Matlab.&amp;quot;&amp;lt;/ref&amp;gt;:&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;i&amp;gt;Количество кластеров является параметром алгоритма&amp;lt;/i&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;&amp;lt;i&amp;gt;Чувствительность к начальным условиям&amp;lt;/i&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;Инициализация центров кластеров в значительной степени влияет на результат кластеризации.&amp;lt;/p&amp;gt;&lt;br /&gt;
  &amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;&amp;lt;i&amp;gt;Чувствительность к выбросам и шумам&amp;lt;/i&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;Выбросы, далекие от центров настоящих кластеров, все равно учитываются при вычислении их центров.&amp;lt;/p&amp;gt;&lt;br /&gt;
  &amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;&amp;lt;i&amp;gt;Возможность сходимости к локальному оптимуму&amp;lt;/i&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;Итеративный подход не дает гарантии сходимости к оптимальному решению.&amp;lt;/p&amp;gt;&lt;br /&gt;
  &amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;&amp;lt;i&amp;gt;Использование понятия &amp;quot;среднего&amp;quot;&amp;lt;/i&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;Алгоритм неприменим к данным, для которых не определено понятие &amp;quot;среднего&amp;quot;, например, категориальным данным.&amp;lt;/p&amp;gt;&lt;br /&gt;
  &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&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;
Исследование масштабируемости параллельной реализации алгоритма k means проводилось на суперкомпьютере &amp;quot;Ломоносов&amp;quot;&amp;lt;ref name=&amp;quot;Lom&amp;quot;&amp;gt;Воеводин Вл., Жуматий С., Соболев С., Антонов А., Брызгалов П., Никитенко Д., Стефанов К., Воеводин Вад. Практика суперкомпьютера «Ломоносов» // Открытые системы, 2012, N 7, С. 36-39.&amp;lt;/ref&amp;gt; [http://parallel.ru/cluster Суперкомпьютерного комплекса Московского университета]. Алгоритм реализован на языке C с использованием средств MPI.&lt;br /&gt;
Для исследования масштабируемости проводилось множество запусков программы с разным значением параметра (количество векторов для кластеризации), а также с различным числом процессоров. Фиксировались результаты запусков &amp;amp;ndash; время работы &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt; и количество произведенных итераций алгоритма &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Параметры запусков для экспериментальной оценки:&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;Значения &amp;lt;b&amp;gt;количества векторов&amp;lt;/b&amp;gt; &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;: 20&#039;000, 30&#039;000, 50&#039;000, 100&#039;000, 200&#039;000, 300&#039;000, 500&#039;000, 700&#039;000, 1&#039;000&#039;000, 1&#039;500&#039;000, 2&#039;000&#039;000.&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;Значения &amp;lt;b&amp;gt;количества процессоров&amp;lt;/b&amp;gt; &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt;: 1, 8, 16, 32, 64, 128, 160, 192, 224, 256, 288, 320, 352, 384, 416, 448, 480, 512.&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;Значение &amp;lt;b&amp;gt;количества кластеров&amp;lt;/b&amp;gt; &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt;: 100.&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;Значение &amp;lt;b&amp;gt;размерности векторов&amp;lt;/b&amp;gt; &amp;lt;math&amp;gt;d&amp;lt;/math&amp;gt;: 10.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Для проведения экспериментов были сгенерированы нормально распределенные псевдослучайные данные (с использованием Python библиотеки [http://scikit-learn.org/ scikit-learn]):&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
from sklearn.datasets import make_classification&lt;br /&gt;
X1, Y1 = make_classification(n_features=10, n_redundant=2, n_informative=8,&lt;br /&gt;
                             n_clusters_per_class=1, n_classes=100,&lt;br /&gt;
                             n_samples=2000000)&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Для заданной конфигурации эксперимента (&amp;lt;math&amp;gt;n, d, p, k&amp;lt;/math&amp;gt;) и полученных результатов (&amp;lt;math&amp;gt;t, i&amp;lt;/math&amp;gt;)  [[Глоссарий#Производительность|производительность]]  и эффективность реализации расчитывались по формулам:&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
&amp;lt;ul&amp;gt;&amp;lt;li&amp;gt;&amp;lt;math&amp;gt;Performance = \frac{N_{k-means}^{d, n}}{t}\ \ (FLOPS),&amp;lt;/math&amp;gt;&amp;lt;/li&amp;gt;&amp;lt;/ul&amp;gt;&lt;br /&gt;
где &amp;lt;math&amp;gt;N_{k-means}^{d, n}&amp;lt;/math&amp;gt; &amp;amp;ndash; точное число операций с плавающей точкой (операции с памятью, а также целочисленные операции не учитывались), вычисленное в соответствие с разделом [[#Последовательная сложность алгоритма| &amp;quot;Последовательная сложность алгоритма&amp;quot;]];&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
&amp;lt;ul&amp;gt;&amp;lt;li&amp;gt;&amp;lt;math&amp;gt;Efficiency = \frac{100 \cdot Performance}{Performance_{Peak}^{p}}\ \ (%),&amp;lt;/math&amp;gt;&amp;lt;/li&amp;gt;&amp;lt;/ul&amp;gt;&lt;br /&gt;
где &amp;lt;math&amp;gt;Performance_{Peak}^{p}&amp;lt;/math&amp;gt; &amp;amp;ndash; пиковая производительность суперкомпьютера при &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt; процессорах, вычисленная согласно спецификациям Intel&amp;lt;sup&amp;gt;&amp;amp;reg;&amp;lt;/sup&amp;gt; XEON&amp;lt;sup&amp;gt;&amp;amp;reg;&amp;lt;/sup&amp;gt; X5670&amp;lt;ref&amp;gt;&amp;quot;http://ark.intel.com/ru/products/47920/Intel-Xeon-Processor-X5670-12M-Cache-2_93-GHz-6_40-GTs-Intel-QPI&amp;quot;&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Графики зависимости производительности и эффективности параллельной реализации k means от числа векторов для кластеризации (&amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;) и числа процессоров (&amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt;) представлены на рисунках 4 и 5 соответственно.&lt;br /&gt;
&lt;br /&gt;
[[file:Flops.png|thumb|center|800px|Рис. 4. Параллельная реализация k means. График зависимости производительности реализации алгоритма от числа векторов для кластеризации (&amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;) и числа процессоров (&amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt;).]]&lt;br /&gt;
[[file:Efficiency.png|thumb|center|800px|Рис. 5. Параллельная реализация k means. График зависимости эффективности реализации алгоритма от числа векторов для кластеризации (&amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;) и числа процессоров (&amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt;).]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;В результате&amp;lt;/b&amp;gt; экспериментальной оценки были получены следующие оценки эффективности реализации:&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;b&amp;gt;Минимальное&amp;lt;/b&amp;gt; значение: 0.000409 % достигается при &amp;lt;math&amp;gt;n=20&#039;000, p=480&amp;lt;/math&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;b&amp;gt;Максимальное&amp;lt;/b&amp;gt; значение: 0.741119 % достигается при &amp;lt;math&amp;gt;n=300&#039;000, p=1&amp;lt;/math&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
Оценки масштабируемости реализации алгоритма k means:&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;b&amp;gt;По числу процессоров:&amp;lt;/b&amp;gt; -0.002683 &amp;amp;ndash; эффективность убывает с ростом числа процессоров. Данный результат вызван ростом накладных расходов для обеспечения параллельного выполнения алгоритма.&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;b&amp;gt;По размеру задачи:&amp;lt;/b&amp;gt; 0.002779 &amp;amp;ndash; эффективность растет с ростом числа векторов. Данный результат вызван тем, что при увеличении размера задачи, количество вычислений растет по сравнению с временем, затрачиваемым на пересылку данных.&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;b&amp;gt;Общая оценка:&amp;lt;/b&amp;gt; -0.000058 &amp;amp;ndash; можно сделать вывод, что в целом эффективность реализации незначительно уменьшается с ростом размера задачи и числа процессоров.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[https://github.com/serban/kmeans Использованная параллельная реализация алгоритма k means]&lt;br /&gt;
&lt;br /&gt;
=== Динамические характеристики и эффективность реализации алгоритма ===&lt;br /&gt;
=== Выводы для классов архитектур ===&lt;br /&gt;
=== Существующие реализации алгоритма ===&lt;br /&gt;
==== Открытое программное обеспечение ====&lt;br /&gt;
&amp;lt;ol&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;[https://www.icpsr.umich.edu/CrimeStat/ CrimeStat]&amp;lt;/li&amp;gt; Программное обеспечение, созданное для операционных систем Windows, предоставляющее инструменты статистического  и пространственного анализа для решения задачи картирования преступности.&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://juliastats.github.io Julia]&amp;lt;/li&amp;gt; Высокоуровневый высокопроизводительный свободный язык программирования с динамической типизацией, созданный для математических вычислений, содержит реализацию k-means.&lt;br /&gt;
  &amp;lt;li&amp;gt;[https://mahout.apache.org Mahout]&amp;lt;/li&amp;gt; Apache Mahout - Java библиотека для работы с алгоритмами машинного обучения с использованием MapReduce. Содержит реализацию k-means.&lt;br /&gt;
  &amp;lt;li&amp;gt;[https://www.gnu.org/software/octave/ Octave]&amp;lt;/li&amp;gt; Написанная на C++  свободная система для математических вычислений, использующая совместимый с MATLAB язык высокого уровня, содержит реализацию k-means.&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://spark.apache.org/docs/latest/mllib-clustering.html Spark]&amp;lt;/li&amp;gt; Распределенная реализация k-means содержится в библиотеке Mlib для работы с алгоритмами машинного обучения, взаимодействующая с Python библиотекой NumPy и библиотека R.&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://torch.ch Torch]&amp;lt;/li&amp;gt;  MATLAB-подобная библиотека для языка программирования Lua с открытым исходным кодом, предоставляет большое количество алгоритмов для глубинного обучения и научных расчётов. Ядро написано на Си, прикладная часть выполняется на LuaJIT, поддерживается распараллеливание вычислений средствами CUDA и OpenMP. Существуют реализации k-means.&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://www.cs.waikato.ac.nz/ml/weka/ Weka]&amp;lt;/li&amp;gt;  Cвободное программное обеспечение для анализа данных, написанное на Java. Содержит k-means и x-means.&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://accord-framework.net/docs/html/T_Accord_MachineLearning_KMeans.htm Accord.NET]&amp;lt;/li&amp;gt; C# реализация алгоритмов k-means, k-means++, k-modes.&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://docs.opencv.org/3.0-beta/doc/py_tutorials/py_ml/py_kmeans/py_kmeans_opencv/py_kmeans_opencv.html OpenCV]&amp;lt;/li&amp;gt; Написанная на С++ библиотека, направленная в основном на решение задач компьютерного зрения. Содержит реализацию k-means.&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://mlpack.org/ MLPACK]&amp;lt;/li&amp;gt; Масштабируемая С++ библиотека для работы с алгоритмами машинного обучения, содержит реализацию k-means.&lt;br /&gt;
  &amp;lt;li&amp;gt;[https://www.scipy.org/ SciPy]&amp;lt;/li&amp;gt; Библиотека Python, содержит множество реализаций k-means.&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://scikit-learn.org/ scikit-learn]&amp;lt;/li&amp;gt; Библиотека Python, содержит множество реализаций k-means.&lt;br /&gt;
  &amp;lt;li&amp;gt;[https://www.r-bloggers.com/k-means-clustering-in-r/ R]&amp;lt;/li&amp;gt; Язык программирования для статистической обработки данных и работы с графикой, а также свободная программная среда вычислений с открытым исходным кодом в рамках проекта GNU, содержит три реализации k-means.&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://elki.dbs.ifi.lmu.de ELKI]&amp;lt;/li&amp;gt; Java фреймворк, содержащий реализацию k-means, а также множество других алгоритмов кластеризации.&lt;br /&gt;
&amp;lt;/ol&amp;gt;&lt;br /&gt;
==== Проприетарное программное обеспечение  ====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ol&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;[https://www.ayasdi.com/blog/bigdata/topological-data-analysis-of-oil-and-gas-petrophysical-data/ Ayasdi]&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://www.stata.com/features/cluster-analysis/ Stata]&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://mathworld.wolfram.com/K-MeansClusteringAlgorithm.html Mathematica]&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://www.mathworks.com/help/stats/kmeans.html?requestedDomain=www.mathworks.com MATLAB]&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;[https://support.sas.com/rnd/app/stat/procedures/fastclus.html SAS]&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://docs.rapidminer.com/studio/operators/modeling/segmentation/k_means.html RapidMiner]&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;[https://blogs.sap.com/2013/03/28/sap-hana-pal-k-means-algorithm-or-how-to-do-customer-segmentation-for-the-telecommunications-industry/ SAP HANA]&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ol&amp;gt;&lt;br /&gt;
== Литература ==&lt;br /&gt;
&amp;lt;references /&amp;gt;&lt;/div&gt;</summary>
		<author><name>DennZo1993</name></author>
	</entry>
	<entry>
		<id>https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:%D0%91%D1%80%D0%BE%D1%82%D0%B8%D0%BA%D0%BE%D0%B2%D1%81%D0%BA%D0%B0%D1%8F_%D0%94%D0%B0%D0%BD%D1%83%D1%82%D0%B0/%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_k-means&amp;diff=20533</id>
		<title>Участник:Бротиковская Данута/Алгоритм k-means</title>
		<link rel="alternate" type="text/html" href="https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:%D0%91%D1%80%D0%BE%D1%82%D0%B8%D0%BA%D0%BE%D0%B2%D1%81%D0%BA%D0%B0%D1%8F_%D0%94%D0%B0%D0%BD%D1%83%D1%82%D0%B0/%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_k-means&amp;diff=20533"/>
		<updated>2016-12-10T11:10:15Z</updated>

		<summary type="html">&lt;p&gt;DennZo1993: /* Ресурс параллелизма алгоритма */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Assignment|Zhum}}&lt;br /&gt;
&lt;br /&gt;
{{algorithm&lt;br /&gt;
| name              = Алгоритм k средних (k means)&lt;br /&gt;
| serial_complexity = &amp;lt;math&amp;gt;O(ikdn)&amp;lt;/math&amp;gt;&lt;br /&gt;
| input_data        = &amp;lt;math&amp;gt; dn &amp;lt;/math&amp;gt;&lt;br /&gt;
| output_data       = &amp;lt;math&amp;gt; n &amp;lt;/math&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
Авторы страницы &amp;lt;b&amp;gt;[[Участник:Бротиковская Данута|Данута Бротиковская]]&amp;lt;/b&amp;gt; и &amp;lt;b&amp;gt;[[Участник:DennZo1993|Денис Зобнин]]&amp;lt;/b&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
Оба автора внесли одинаковый вклад в написание статьи (поиск материалов, изучение статей, заполнение контента статьи), четких разграничений по пунктам статьи сделать невозможно. &lt;br /&gt;
&lt;br /&gt;
== Свойства и структура алгоритма ==&lt;br /&gt;
&lt;br /&gt;
=== Общее описание алгоритма ===&lt;br /&gt;
Алгоритм &amp;lt;b&amp;gt;&amp;lt;i&amp;gt;k средних&amp;lt;/i&amp;gt;&amp;lt;/b&amp;gt; (&amp;lt;b&amp;gt;&amp;lt;i&amp;gt;k means&amp;lt;/i&amp;gt;&amp;lt;/b&amp;gt;) &amp;amp;ndash; неиерархический&amp;lt;ref&amp;gt;&amp;quot;https://ru.wikipedia.org/wiki/Иерархическая_кластеризация&amp;quot;&amp;lt;/ref&amp;gt;, итерационный метод кластеризации&amp;lt;ref&amp;gt;&amp;quot;https://ru.wikipedia.org/wiki/Кластерный_анализ&amp;quot;&amp;lt;/ref&amp;gt;, получивший большую популярность благодаря своей простоте, наглядности реализации и достаточно высокому качеству работы. Был изобретен в 1950-х годах математиком &amp;lt;i&amp;gt;Гуго Штейнгаузом&amp;lt;/i&amp;gt;&amp;lt;ref&amp;gt;Steinhaus, Hugo. &amp;quot;Sur la division des corp materiels en parties.&amp;quot; Bull. Acad. Polon. Sci 1.804 (1956): 801.&amp;lt;/ref&amp;gt; и почти одновременно &amp;lt;i&amp;gt;Стюартом Ллойдом&amp;lt;/i&amp;gt;&amp;lt;ref&amp;gt;Lloyd, S. P. &amp;quot;Least square quantization in PCM. Bell Telephone Laboratories Paper. Published in journal much later: Lloyd, SP: Least squares quantization in PCM.&amp;quot; IEEE Trans. Inform. Theor.(1957/1982).&amp;lt;/ref&amp;gt;. Особую популярность приобрел после публикации работы &amp;lt;i&amp;gt;МакКуина&amp;lt;/i&amp;gt;&amp;lt;ref&amp;gt;MacQueen, James. &amp;quot;Some methods for classification and analysis of multivariate observations.&amp;quot; Proceedings of the fifth Berkeley symposium on mathematical statistics and probability. Vol. 1. No. 14. 1967.&amp;lt;/ref&amp;gt; в 1967.&lt;br /&gt;
&lt;br /&gt;
Алгоритм представляет собой версию EM-алгоритма&amp;lt;ref&amp;gt;&amp;quot;https://ru.wikipedia.org/wiki/EM-алгоритм&amp;quot;&amp;lt;/ref&amp;gt;, применяемого также для разделения смеси гауссиан. Основная идея &amp;lt;i&amp;gt;k means&amp;lt;/i&amp;gt; заключается в том, что данные произвольно разбиваются на кластеры, после чего итеративно перевычисляется центр масс для каждого кластера, полученного на предыдущем шаге, затем векторы разбиваются на кластеры вновь в соответствии с тем, какой из новых центров оказался ближе по выбранной метрике.&lt;br /&gt;
&lt;br /&gt;
Цель алгоритма заключается в разделении &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; наблюдений на &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластеров таким образом, чтобы каждое наблюдение принадлежало ровно одному кластеру, расположенному на наименьшем расстоянии от наблюдения.&lt;br /&gt;
&lt;br /&gt;
=== Математическое описание алгоритма ===&lt;br /&gt;
&amp;lt;b&amp;gt;&amp;lt;u&amp;gt;Дано:&amp;lt;/u&amp;gt;&amp;lt;/b&amp;gt;&lt;br /&gt;
* набор из &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; наблюдений &amp;lt;math&amp;gt;X=\{\mathbf{x}_1, \mathbf{x}_2, ..., \mathbf{x}_n\}, \mathbf{x}_i \in \mathbb{R}^d, i=\overline{1, n}&amp;lt;/math&amp;gt;;&lt;br /&gt;
* &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; - требуемое число кластеров, &amp;lt;math&amp;gt;k \in \mathbb{N}, k \leq n&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;&amp;lt;u&amp;gt;Требуется:&amp;lt;/u&amp;gt;&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Разделить множество наблюдений &amp;lt;math&amp;gt;X&amp;lt;/math&amp;gt; на &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластеров &amp;lt;math&amp;gt;S_1, S_2, ..., S_k&amp;lt;/math&amp;gt;:&lt;br /&gt;
*   &amp;lt;math&amp;gt;S_i \cap S_j= \varnothing, \quad i \ne j&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
*   &amp;lt;math&amp;gt;\bigcup_{i=1}^{k} S_i = X&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;&amp;lt;u&amp;gt;Действие алгоритма:&amp;lt;/u&amp;gt;&amp;lt;/b&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;Алгоритм &amp;lt;i&amp;gt;k means&amp;lt;/i&amp;gt; разбивает набор &amp;lt;math&amp;gt;X&amp;lt;/math&amp;gt; на &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; наборов &amp;lt;math&amp;gt;S_1, S_2, ..., S_k,&amp;lt;/math&amp;gt; таким образом, чтобы минимизировать сумму квадратов расстояний от каждой точки кластера до его центра (центр масс кластера). Введем обозначение, &amp;lt;math&amp;gt;S=\{S_1, S_2, ..., S_k\}&amp;lt;/math&amp;gt;. Тогда действие алгоритма &amp;lt;i&amp;gt;k means&amp;lt;/i&amp;gt; равносильно поиску:&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;table style=&amp;quot;width:100%&amp;quot;&amp;gt;&lt;br /&gt;
  &amp;lt;tr&amp;gt;&lt;br /&gt;
    &amp;lt;td align=&amp;quot;center&amp;quot; width=&amp;quot;90%&amp;quot;&amp;gt;&amp;lt;math&amp;gt;\arg\min_{S} \sum\limits_{i=1}^k \sum\limits_{\mathbf{x} \in S_i} \rho(\mathbf{x}, \mathbf{\mu}_i )^2,&amp;lt;/math&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;td align=&amp;quot;right&amp;quot;&amp;gt;&amp;lt;math&amp;gt;(1)&amp;lt;/math&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;/table&amp;gt;&lt;br /&gt;
где &amp;lt;math&amp;gt;\mathbf{\mu}_i&amp;lt;/math&amp;gt; &amp;amp;ndash; центры кластеров, &amp;lt;math&amp;gt;i=\overline{1,k}, \quad \rho(\mathbf{x}, \mathbf{\mu}_i)&amp;lt;/math&amp;gt; &amp;amp;ndash; функция расстояния между &amp;lt;math&amp;gt;\mathbf{x}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\mu_i&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;&amp;lt;u&amp;gt;Шаги алгоритма: &amp;lt;/u&amp;gt;&amp;lt;/b&amp;gt;&lt;br /&gt;
&amp;lt;ol&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&lt;br /&gt;
    &amp;lt;b&amp;gt;Начальный шаг: инициализация кластеров&amp;lt;/b&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;Выбирается произвольное множество точек &amp;lt;math&amp;gt;\mu_i, i=\overline{1,k}&amp;lt;/math&amp;gt;, рассматриваемых как начальные центры кластеров: &amp;lt;math&amp;gt;\mu_i^{(0)} = \mu_i, \quad i=\overline{1, k}&amp;lt;/math&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
  &amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&lt;br /&gt;
    &amp;lt;b&amp;gt;Распределение векторов по кластерам&amp;lt;/b&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Шаг&amp;lt;/b&amp;gt; &amp;lt;math&amp;gt;t: \forall \mathbf{x}_i \in X, i=\overline{1,n}: \mathbf{x}_i \in S_j \iff  j=\arg\min_{k}\rho(\mathbf{x}_i,\mathbf{\mu}_k^{(t-1)})^2&amp;lt;/math&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
  &amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&lt;br /&gt;
    &amp;lt;b&amp;gt;Пересчет центров кластеров&amp;lt;/b&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Шаг &amp;lt;/b&amp;gt; &amp;lt;math&amp;gt;t: \forall i=\overline{1,k}:  \mu_i^{(t)} = \cfrac{1}{|S_i|}\sum_{\mathbf{x}\in S_i}\mathbf{x}&amp;lt;/math&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
  &amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&lt;br /&gt;
    &amp;lt;b&amp;gt;Проверка условия останова:&amp;lt;/b&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
    &#039;&#039;&#039;if&#039;&#039;&#039; &amp;lt;math&amp;gt;\exist i\in \overline{1,k}: \mu_i^{(t)} \ne \mu_i^{(t-1)}&amp;lt;/math&amp;gt; &#039;&#039;&#039;then&#039;&#039;&#039;&lt;br /&gt;
        t = t + 1;&lt;br /&gt;
        goto 2;&lt;br /&gt;
    &#039;&#039;&#039;else&#039;&#039;&#039;&lt;br /&gt;
        &#039;&#039;&#039;stop&#039;&#039;&#039;&lt;br /&gt;
  &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ol&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Вычислительное ядро алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Вычислительным ядром являются шаги 2 и 3 приведенного выше алгоритма: &amp;lt;b&amp;gt;&amp;lt;i&amp;gt;распределение векторов по кластерам&amp;lt;/i&amp;gt;&amp;lt;/b&amp;gt; и &amp;lt;b&amp;gt;&amp;lt;i&amp;gt;пересчет центров кластеров&amp;lt;/i&amp;gt;&amp;lt;/b&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;&amp;lt;i&amp;gt;Распределение векторов&amp;lt;/i&amp;gt;&amp;lt;/b&amp;gt; по кластерам предполагает вычисление расстояний между каждым вектором &amp;lt;math&amp;gt;\mathbf{x}_i \in X, i= \overline{1,n}&amp;lt;/math&amp;gt; и центрами кластера &amp;lt;math&amp;gt;\mathbf{\mu}_j, j= \overline{1,k}&amp;lt;/math&amp;gt;. Таким образом, данный шаг предполагает &amp;lt;math&amp;gt;kn&amp;lt;/math&amp;gt; вычислений расстояний между d-мерными векторами. &lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;&amp;lt;i&amp;gt;Пересчет центров кластеров&amp;lt;/i&amp;gt;&amp;lt;/b&amp;gt; предполагает &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; вычислений центров масс &amp;lt;math&amp;gt;\mathbf{\mu}_i&amp;lt;/math&amp;gt; множеств &amp;lt;math&amp;gt;S_i, i=\overline{1,k}&amp;lt;/math&amp;gt; представленных выражением в шаге 3 представленного выше алгоритма.&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Макроструктура алгоритма ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Инициализация центров масс &amp;lt;math&amp;gt;\mu_1, ..., \mu_k&amp;lt;/math&amp;gt;&amp;lt;/b&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
Наиболее распространенными являются следующие стратегии:&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&lt;br /&gt;
    &amp;lt;b&amp;gt;Метод Forgy&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;В качестве начальных значений &amp;lt;math&amp;gt;\mu_1, ..., \mu_k&amp;lt;/math&amp;gt; берутся случайно выбранные векторы.&lt;br /&gt;
  &amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&lt;br /&gt;
    &amp;lt;b&amp;gt;Метод случайно разделения (Random Partitioning)&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;Для каждого вектора &amp;lt;math&amp;gt;\mathbf{x}_i \in X, i=\overline{1, n}&amp;lt;/math&amp;gt; выбирается случайным образом кластер &amp;lt;math&amp;gt;S_1, ..., S_k&amp;lt;/math&amp;gt;, после чего для каждого полученного кластера вычисляются значения &amp;lt;math&amp;gt;\mu_1, ..., \mu_k&amp;lt;/math&amp;gt;.&lt;br /&gt;
  &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Распределение векторов по кластерам&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Для этого шага алгоритма между векторами &amp;lt;math&amp;gt;\mathbf{x}_i \in X, i=\overline{1, n}&amp;lt;/math&amp;gt; и центрами кластеров &amp;lt;math&amp;gt;\mu_1, ..., \mu_k&amp;lt;/math&amp;gt; вычисляются &amp;lt;b&amp;gt;расстояния&amp;lt;/b&amp;gt; по формуле (как правило, используется Евлидово расстояние):&lt;br /&gt;
&amp;lt;table style=&amp;quot;width:100%&amp;quot;&amp;gt;&lt;br /&gt;
  &amp;lt;tr&amp;gt;&lt;br /&gt;
    &amp;lt;td align=&amp;quot;center&amp;quot; width=&amp;quot;90%&amp;quot;&amp;gt;&amp;lt;math&amp;gt; \mathbf{v}_1, \mathbf{v}_2 \in \mathbb{R}^d,  \quad \rho(\mathbf{v}_1, \mathbf{v}_2) = \lVert \mathbf{v}_1- \mathbf{v}_2 \rVert= \sqrt{\sum_{i=1}^{d}(\mathbf{v}_{1,i} - \mathbf{v}_{2,i})^2}&amp;lt;/math&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;td align=&amp;quot;right&amp;quot;&amp;gt;&amp;lt;math&amp;gt;(2)&amp;lt;/math&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;/table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Пересчет центров кластеров&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Для этого шага алгоритма производится пересчет центров кластера по &amp;lt;b&amp;gt;формуле вычисления центра масс&amp;lt;/b&amp;gt;:&lt;br /&gt;
&amp;lt;table style=&amp;quot;width:100%&amp;quot;&amp;gt;&lt;br /&gt;
  &amp;lt;tr&amp;gt;&lt;br /&gt;
    &amp;lt;td align=&amp;quot;center&amp;quot; width=&amp;quot;90%&amp;quot;&amp;gt;&amp;lt;math&amp;gt; \mu = \cfrac{1}{|S|}\sum_{\mathbf{x}\in S}\mathbf{x}&amp;lt;/math&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;td align=&amp;quot;right&amp;quot;&amp;gt;&amp;lt;math&amp;gt;(3)&amp;lt;/math&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;/table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Схема реализации последовательного алгоритма ===&lt;br /&gt;
&lt;br /&gt;
 &#039;&#039;&#039;algorithm&#039;&#039;&#039; k-means &#039;&#039;&#039;is&#039;&#039;&#039;&lt;br /&gt;
     &#039;&#039;&#039;1.&#039;&#039;&#039; Инициализировать центры кластеров &amp;lt;math&amp;gt;\mathbf{\mu}_i^{(1)}, i=\overline{1,k}&amp;lt;/math&amp;gt;&lt;br /&gt;
     &#039;&#039;&#039;2.&#039;&#039;&#039; &amp;lt;math&amp;gt;t \leftarrow 1&amp;lt;/math&amp;gt;&lt;br /&gt;
     &#039;&#039;&#039;3.&#039;&#039;&#039; &#039;&#039;&#039;Распределение по кластерам&#039;&#039;&#039;&amp;lt;br&amp;gt;&lt;br /&gt;
        &amp;lt;math&amp;gt;S_i^{(t)}=\{\mathbf{x}_p: \lVert\mathbf{x}_p-\mathbf{\mu}_i^{(t)}\rVert^2 \leq \lVert\mathbf{x}_p-\mathbf{\mu}_j^{(t)}\rVert^2 \quad \forall j=\overline{1,k}\},&amp;lt;/math&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
        где каждый вектор &amp;lt;math&amp;gt;\mathbf{x}_p&amp;lt;/math&amp;gt; соотносится единственному кластеру &amp;lt;math&amp;gt;S^{(t)}&amp;lt;/math&amp;gt;&lt;br /&gt;
     &#039;&#039;&#039;4.&#039;&#039;&#039; &#039;&#039;&#039;Обновление центров кластеров&#039;&#039;&#039;&amp;lt;br&amp;gt;&lt;br /&gt;
        &amp;lt;math&amp;gt;\mathbf{\mu}_i^{(t+1)} = \frac{1}{|S^{(t)}_i|} \sum_{\mathbf{x}_j \in S^{(t)}_i} \mathbf{x}_j &amp;lt;/math&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
     &#039;&#039;&#039;5.&#039;&#039;&#039; &#039;&#039;&#039;if&#039;&#039;&#039; &amp;lt;math&amp;gt;\exist i \in \overline{1,k}: \mathbf{\mu}_i^{(t+1)} \ne \mathbf{\mu}_i^{(t)}&amp;lt;/math&amp;gt; &#039;&#039;&#039;then&#039;&#039;&#039;&lt;br /&gt;
            t = t + 1;&lt;br /&gt;
            goto &#039;&#039;&#039;3&#039;&#039;&#039;;&lt;br /&gt;
        &#039;&#039;&#039;else&#039;&#039;&#039;&lt;br /&gt;
            &#039;&#039;&#039;stop&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
=== Последовательная сложность алгоритма===&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding-bottom: 20px&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;Обозначим &amp;lt;math&amp;gt;\Theta_{\rm centroid}^{d, m}&amp;lt;/math&amp;gt; временную сложность вычисления центорида кластера, число элементов которого равна &amp;lt;math&amp;gt;m&amp;lt;/math&amp;gt;,  в d-мерном пространстве.&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;Аналогично  &amp;lt;math&amp;gt;\Theta_{\rm distance}^d&amp;lt;/math&amp;gt; &amp;amp;ndash; временная сложность вычисления расстояния между двумя d-мерными векторами.&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding-bottom: 20px&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;Сложность шага инициализации &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластеров мощности &amp;lt;math&amp;gt;m&amp;lt;/math&amp;gt; в d-мерном пространстве &amp;amp;ndash; &amp;lt;math&amp;gt;\Theta_{\rm init}^{k, d, m}&amp;lt;/math&amp;gt;&amp;lt;/b&amp;gt;&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;i&amp;gt;Стратерия Forgy&amp;lt;/i&amp;gt;: вычисления не требуются, &amp;lt;math&amp;gt;\Theta_{\rm init}^{k, d, m} = 0&amp;lt;/math&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;i&amp;gt;Стратегия случайного разбиения&amp;lt;/i&amp;gt;: вычисление центров &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластеров,  &amp;lt;math&amp;gt;\Theta_{\rm init}^{k, d, m} = k \cdot \Theta_{\rm centroid}^{d, m}, m \le n&amp;lt;/math&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding-bottom: 20px&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Cложность шага распределения d мерных векторов по &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластерам &amp;amp;ndash; &amp;lt;math&amp;gt;\Theta_{\rm distribute}^{k, d}&amp;lt;/math&amp;gt;&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
На этом шаге для каждого вектора &amp;lt;math&amp;gt;\mathbf{x}_i \in X, i=\overline{1, n}&amp;lt;/math&amp;gt; вычисляется k расстояний до центров кластеров &amp;lt;math&amp;gt;\mathbf{\mu}_1, ...\mathbf{\mu}_k&amp;lt;/math&amp;gt;&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p align=&amp;quot;center&amp;quot;&amp;gt;&lt;br /&gt;
  &amp;lt;math&amp;gt;\Theta_{\rm distribute}^{k, d} = n \cdot k \cdot \Theta_{\rm distance}^d&amp;lt;/math&amp;gt;&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding-bottom: 20px&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;Сложность шага пересчета центров &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластеров размера &amp;lt;math&amp;gt;m&amp;lt;/math&amp;gt; в d-мерном пространстве &amp;amp;ndash; &amp;lt;math&amp;gt;\Theta_{\rm recenter}^{k, d, m}&amp;lt;/math&amp;gt;&amp;lt;/b&amp;gt;&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;На этом шаге вычисляется &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; центров кластеров &amp;lt;math&amp;gt;\mathbf{\mu}_1, ...\mathbf{\mu}_k&amp;lt;/math&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p align=&amp;quot;center&amp;quot;&amp;gt;&amp;lt;math&amp;gt;\Theta_{\rm recenter}^{k, d, m} = k \cdot \Theta_{\rm centroid}^{d, m}&amp;lt;/math&amp;gt; &amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding-bottom: 20px&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Рассчитаем &amp;lt;math&amp;gt;\Theta_{\rm centroid}^{d, m}&amp;lt;/math&amp;gt; для кластера, число элементов которого равно &amp;lt;math&amp;gt;m&amp;lt;/math&amp;gt;&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p align=&amp;quot;center&amp;quot;&amp;gt;&amp;lt;math&amp;gt;\Theta_{\rm centroid}^{d, m}&amp;lt;/math&amp;gt; = &amp;lt;math&amp;gt;m \cdot d&amp;lt;/math&amp;gt; сложений + &amp;lt;math&amp;gt;d&amp;lt;/math&amp;gt; делений &amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding-bottom: 20px&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Рассчитаем &amp;lt;math&amp;gt;\Theta_{\rm distance}^d&amp;lt;/math&amp;gt; в соответствие с формулой &amp;lt;math&amp;gt;(2)&amp;lt;/math&amp;gt;&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p align=&amp;quot;center&amp;quot;&amp;gt;&amp;lt;math&amp;gt;\Theta_{\rm distance}^d&amp;lt;/math&amp;gt; = &amp;lt;math&amp;gt;d&amp;lt;/math&amp;gt; вычитаний + &amp;lt;math&amp;gt;d&amp;lt;/math&amp;gt; умножений + &amp;lt;math&amp;gt;(d-1)&amp;lt;/math&amp;gt; сложение&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding-bottom: 20px&amp;quot;&amp;gt;&lt;br /&gt;
  &amp;lt;p&amp;gt;Предположим, что алгоритм сошелся за &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt; итераций, тогда временная сложность алгоритма &amp;lt;math&amp;gt;\Theta_{\rm k-means}^{d, n}&amp;lt;/math&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
  &amp;lt;p align=&amp;quot;center&amp;quot;&amp;gt;&amp;lt;b&amp;gt;&amp;lt;math&amp;gt;\Theta_{\rm k-means}^{d, n} \le \Theta_{\rm init}^{k, d, n} + i(\Theta_{\rm distribute}^{k, d} + \Theta_{\rm recenter}^{k, d, n})&amp;lt;/math&amp;gt;&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding-bottom: 5px&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;Операции сложения/вычитания:&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p align=&amp;quot;center&amp;quot;&amp;gt;&amp;lt;b&amp;gt;&amp;lt;math&amp;gt;\Theta_{\rm k-means}^{d, n} \le knd+ i(kn(2d-1) + knd) = knd+ i(kn(3d-1)) \thicksim O(ikdn)&amp;lt;/math&amp;gt;&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding-bottom: 20px&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;Операции умножения/деления:&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p align=&amp;quot;center&amp;quot;&amp;gt;&amp;lt;b&amp;gt;&amp;lt;math&amp;gt;\Theta_{\rm k-means}^{d, n} \le kd + i(knd + kd) = kd + ikd(n+1) \thicksim O(ikdn) &amp;lt;/math&amp;gt;&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding-bottom: 20px&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;Получаем, что &amp;lt;b&amp;gt;временная сложность&amp;lt;/b&amp;gt; алгоритма &amp;lt;b&amp;gt;k means&amp;lt;/b&amp;gt; кластеризации &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; &amp;lt;b&amp;gt;d-мерных&amp;lt;/b&amp;gt; векторов на &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластеров за &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt; итераций:&amp;lt;/p&amp;gt;&lt;br /&gt;
 &amp;lt;p align=&amp;quot;center&amp;quot;&amp;gt;&amp;lt;b&amp;gt;&amp;lt;math&amp;gt; \Theta_{\rm k-means}^{d, n} \thicksim O(ikdn) &amp;lt;/math&amp;gt;&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Информационный граф ===&lt;br /&gt;
&lt;br /&gt;
Рассмотрим информационный граф алгоритма. Алгоритм &amp;lt;i&amp;gt;k means&amp;lt;/i&amp;gt; начинается с этапа инициализации, после которого следуют итерации, на каждой из которых выполняется два последовательных шага (см. [[#Схема реализации последовательного алгоритма|&amp;quot;Схема реализации последовательного алгоритма&amp;quot;]]): &lt;br /&gt;
* распределение векторов по кластерам&lt;br /&gt;
* перерасчет центров кластеров&lt;br /&gt;
&lt;br /&gt;
Поскольку основная часть вычислений приходится на шаги итераций, распишем информационные графы данных шагов.&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Распределение векторов по кластерам&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
Информационный граф шага распределения векторов по кластерам представлен на &#039;&#039;рисунке 1&#039;&#039;. Исходами данного графа является исходные векторы &amp;lt;math&amp;gt;\mathbf{x}_1, ..., \mathbf{x}_n&amp;lt;/math&amp;gt;, а также центры кластеров &amp;lt;math&amp;gt;\mathbf{\mu}_1, ... \mathbf{\mu}_k&amp;lt;/math&amp;gt;, вычисленные ранее (на шаге инициализации, если рассматривается первая итерация алгоритма, или на шаге пересчета центров кластеров предыдущей итерации в противном случае). Каждая пара векторов данных &amp;lt;math&amp;gt;\mathbf{x}_i, i=\overline{1,n}&amp;lt;/math&amp;gt; и центров кластера &amp;lt;math&amp;gt;\mathbf{\mu}_j, j=\overline{1, k}&amp;lt;/math&amp;gt; : (&amp;lt;math&amp;gt;\mathbf{x}_i&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;\mathbf{\mu}_j&amp;lt;/math&amp;gt;) подаются на независимые узлы &amp;lt;i&amp;gt;&amp;quot;d&amp;quot;&amp;lt;/i&amp;gt; вычисления расстояния между векторами (более подробная схема вычисления расстояния представлена далее, &#039;&#039;рисунок 2&#039;&#039;). Далее узлы вычисления расстояния &amp;lt;i&amp;gt;&amp;quot;d&amp;quot;&amp;lt;/i&amp;gt;, соответствующие одному и тому же исходному вектору &amp;lt;math&amp;gt;\mathbf{x}_i&amp;lt;/math&amp;gt; передаются на один узел &amp;lt;i&amp;gt;&amp;quot;m&amp;quot;&amp;lt;/i&amp;gt;, где далее происходит вычисление новой метки кластера для каждого вектора &amp;lt;math&amp;gt;\mathbf{x}_i&amp;lt;/math&amp;gt; (берется кластер с минимальным результатом вычисления расстояния). На выходе графа выдаются метки кластеров , &amp;lt;math&amp;gt;L_1, ..., L_n&amp;lt;/math&amp;gt;, такие что &amp;lt;math&amp;gt;\forall \mathbf{x}_i, i=\overline{1, n}, \mathbf{x}_i \in S_j \Leftrightarrow L_i = j&amp;lt;/math&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
[[file:Clusterization.png|thumb|center|800px|Рис. 1. Схема распределения векторов по кластерам. &#039;&#039;d&#039;&#039; &amp;amp;ndash; вычисление расстояния между векторами; &#039;&#039;m&#039;&#039; &amp;amp;ndash; вычисление минимума.]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Вычисление расстояния между векторами&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
Подробная схема вычисления расстояния между векторами &amp;lt;math&amp;gt;\mathbf{x}_i, \mathbf{\mu}_j&amp;lt;/math&amp;gt; представлена на &#039;&#039;рисунке 2&#039;&#039;. Как показано на графе, узел вычисления расстояния между векторами &amp;lt;i&amp;gt;&amp;quot;d&amp;quot;&amp;lt;/i&amp;gt; состоит из шага взятия разности между векторами (узел &amp;quot;&amp;lt;math&amp;gt;-&amp;lt;/math&amp;gt;&amp;quot;) и взятия нормы получившегося вектора разности (узел &amp;quot;&amp;lt;math&amp;gt;||\cdot||^2&amp;lt;/math&amp;gt;&amp;quot;). Более подробно, вычисление расстояния между векторами &amp;lt;math&amp;gt;\mathbf{x}_i = {x_{i1,}, ...,{x_{in}}}, \mathbf{\mu}_j = {\mu_{j1}, ...,\mu_{jn}}&amp;lt;/math&amp;gt; может быть представлено как вычисление разности между каждой парой компонент &amp;lt;math&amp;gt;(x_{iz}, \mu_{jz}), z=\overline{1, d}&amp;lt;/math&amp;gt; (узел &amp;quot;&amp;lt;math&amp;gt;-&amp;lt;/math&amp;gt;&amp;quot;), далее возведение в квадрат для каждого узла &amp;quot;&amp;lt;math&amp;gt;-&amp;lt;/math&amp;gt;&amp;quot; (узел &amp;quot;&amp;lt;math&amp;gt;()^2&amp;lt;/math&amp;gt;&amp;quot;) и суммирования выходов всех узлов &amp;quot;&amp;lt;math&amp;gt;()^2&amp;lt;/math&amp;gt;&amp;quot; (узел &amp;quot;&amp;lt;math&amp;gt;+&amp;lt;/math&amp;gt;&amp;quot;).  &lt;br /&gt;
&lt;br /&gt;
[[file:dist_calc.png|thumb|center|800px|Рис. 2. Схема вычисления расстояния между вектором и центром кластера.]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Пересчет центров кластеров&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
Информационный граф шага пересчета центров кластеров представлен на &#039;&#039;рисунке 3&#039;&#039;. Исходами данного графа является исходные векторы &amp;lt;math&amp;gt;\mathbf{x}_1, ..., \mathbf{x}_n&amp;lt;/math&amp;gt;, а также им соответствующие метки кластера, &amp;lt;math&amp;gt;L_1, ..., L_n&amp;lt;/math&amp;gt;, такие что &amp;lt;math&amp;gt;\forall x_i, i=\overline{1, n}, \mathbf{x}_i \in S_j \Leftrightarrow L_i = j&amp;lt;/math&amp;gt;, вычисленные на этапе распределения векторов по кластерам. Все векторы &amp;lt;math&amp;gt;\mathbf{x}_1, ..., \mathbf{x}_n&amp;lt;/math&amp;gt; подаются в узлы &amp;lt;math&amp;gt;+_1, ...+_k&amp;lt;/math&amp;gt;, каждый узел &amp;lt;math&amp;gt;+_m, m = \overline{1,k}&amp;lt;/math&amp;gt; соответствует операции сложения векторов кластера с номером &amp;lt;math&amp;gt;m&amp;lt;/math&amp;gt;. Метки кластера &amp;lt;math&amp;gt;L_1, ..., L_n&amp;lt;/math&amp;gt; также совместно передаются на узлы &amp;lt;math&amp;gt;S_m, m = \overline{1,k}&amp;lt;/math&amp;gt;, на каждом из которых вычисляется количество векторов в соответствующем кластере (количество меток с соответствующим значением). Далее каждая пара выходов узлов &amp;lt;math&amp;gt;+_m&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;S_m&amp;lt;/math&amp;gt; подается на узел &amp;quot;&amp;lt;math&amp;gt;/&amp;lt;/math&amp;gt;&amp;quot;, где производится деление суммы векторов кластера на количество элементов в нем. Значения, вычисленные на узлах &amp;quot;&amp;lt;math&amp;gt;/&amp;lt;/math&amp;gt;&amp;quot;, присваиваются новым центрам кластеров (выходные значения графа).&lt;br /&gt;
&lt;br /&gt;
[[file:Recluster.png|thumb|center|800px|Рис. 3. Схема пересчета центров кластеров]]&lt;br /&gt;
&lt;br /&gt;
=== Ресурс параллелизма алгоритма ===&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
Работа алгоритма состоит из &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt; итераций, в каждой из которых происходит &amp;lt;b&amp;gt;распределение d-мерных векторов по &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластерам&amp;lt;/b&amp;gt;, а также &amp;lt;b&amp;gt;пересчет центров кластеров в d-мерном пространстве&amp;lt;/b&amp;gt;. В шаге &amp;lt;b&amp;gt;распределения d-мерных векторов по &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластерам&amp;lt;/b&amp;gt; расстояния между вектором и центрами кластеров вычисляются независимо (отсутствуют информационные зависимости). &amp;lt;b&amp;gt;Центры масс кластеров&amp;lt;/b&amp;gt; также пересчитываются независимо друг от друга. Таким образом, имеет место [[глоссарий#Массовый параллелизм|&#039;&#039;массовый параллелизм&#039;&#039;]]. Вычислим параллельную сложность &amp;lt;math&amp;gt;\Psi_*&amp;lt;/math&amp;gt; каждого из шагов, а также параллельную сложность всего алгоритма, &amp;lt;math&amp;gt;\Psi_{\rm k-means}&amp;lt;/math&amp;gt;. Будем исходить из предположения, что может быть использовано любое необходимое число потоков.&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Распределение d-мерных векторов по &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластерам&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;  &lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
Поскольку на данном шаге для каждой пары векторов &amp;lt;math&amp;gt;\mathbf{x}_i, i=\overline{1,n}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\mathbf{\mu}_j, j=\overline{1,k}&amp;lt;/math&amp;gt; операции вычисления расстояния не зависят друг от друга, они могут выполняться параллельно. Тогда, разделив все вычисление расстояний на &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; потоков, получим, что в каждом потоке будет выполняться только одна операция вычисления расстояния между векторами размерности d. При этом каждому вычислительному потоку передаются координаты центров всех кластеров &amp;lt;math&amp;gt;\mathbf{\mu}_1, ..., \mathbf{\mu}_k&amp;lt;/math&amp;gt;. Таким образом, параллельная сложность данного шага определяется &amp;lt;i&amp;gt; сложностью параллельной операции вычисления расстояния между d-мерными векторами&amp;lt;/i&amp;gt;, &amp;lt;math&amp;gt;\Psi_{\rm distance}^d&amp;lt;/math&amp;gt;  и &amp;lt;i&amp;gt;сложностью определения наиболее близкого кластера&amp;lt;/i&amp;gt; (паралельное взятие минимума по расстояниям), &amp;lt;math&amp;gt;\Psi_{min}^k&amp;lt;/math&amp;gt;. Для оценки &amp;lt;math&amp;gt;\Psi_{\rm distance}^d&amp;lt;/math&amp;gt; воспользуемся  [[Нахождение_частных_сумм_элементов_массива_сдваиванием | параллельной реализацией нахождения частичной суммы элементов массива путем сдваивания]]. Аналогично, &amp;lt;math&amp;gt;\Psi_{\rm min}^k = log(k)&amp;lt;/math&amp;gt;. В результате, &amp;lt;math&amp;gt;\Psi_{\rm distance}^d = O(log(d))&amp;lt;/math&amp;gt;.   Таким образом: &lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p align=&amp;quot;center&amp;quot;&amp;gt;&amp;lt;math&amp;gt;\Psi_{\rm distribute}^{k, d}  = \Psi_{\rm distance}^d + \Psi_{\rm min}^k = O(log(d))+O(log(k)) = O(log(kd))&amp;lt;/math&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Пересчет центров кластеров в d-мерном пространстве&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
Поскольку на данном шаге для каждого из &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластеров центр масс может быть вычислен независимо, данные операции могут быть выполнены в отдельных потоках. Таким образом, параллельная сложность данного шага, &amp;lt;math&amp;gt;\Psi_{\rm recenter}^{k, d}&amp;lt;/math&amp;gt;,  будет определяться &amp;lt;i&amp;gt;параллельной сложностью вычисления одного центра масс кластера размера &amp;lt;math&amp;gt;m&amp;lt;/math&amp;gt;&amp;lt;/i&amp;gt;, &amp;lt;math&amp;gt;\Psi_{\rm recenter}^{k, d}&amp;lt;/math&amp;gt;,  а так как &amp;lt;math&amp;gt;m \le n \Rightarrow \Psi_{\rm recenter}^{d, m} \le \Psi_{\rm recenter}^{d, n}&amp;lt;/math&amp;gt;. Сложность вычисления центра масс кластера d-мерных векторов размера n аналогично предыдущим вычислениям равна &amp;lt;math&amp;gt;O(log(n))&amp;lt;/math&amp;gt;. Тогда:  &lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p align=&amp;quot;center&amp;quot;&amp;gt;&amp;lt;math&amp;gt;\Psi_{\rm recenter}^{k, d}  \le \Psi_{\rm recenter}^{d, n} = O(log(n))&amp;lt;/math&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Общая параллельная сложность алгоритма&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
На каждой итерации необходимо обновление центров кластеров, которые будут использованы на следующей итерации. Таким образом, итерационный процесс выполняется последовательно&amp;lt;ref&amp;gt;Zhao, Weizhong, Huifang Ma, and Qing He. &amp;quot;Parallel k-means clustering based on mapreduce.&amp;quot; IEEE International Conference on Cloud Computing. Springer Berlin Heidelberg, 2009.&amp;lt;/ref&amp;gt;. Тогда, поскольку сложность каждой итерации  определяется &amp;lt;math&amp;gt;\Psi_{distribute}^{k, d}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\Psi_{\rm recenter}&amp;lt;/math&amp;gt;, сложность всего алгоритма, &amp;lt;math&amp;gt;\Psi_{\rm k-means}&amp;lt;/math&amp;gt; в предположении, что было сделано &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt; операций определяется выражением&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p align=&amp;quot;center&amp;quot;&amp;gt;&amp;lt;math&amp;gt;\Psi_{\rm k-means} \approx i \cdot (\Psi_{\rm distribute}^{k, d} + \Psi_{\rm recenter}^{k, d}) \le i \cdot O(log(kdn))&amp;lt;/math&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Входные и выходные данные алгоритма ===&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;Входные данные&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;Матрица из &amp;lt;math&amp;gt;n \cdot d&amp;lt;/math&amp;gt; элементов &amp;lt;math&amp;gt;x_{i, j} \in \mathbb{R}, i=\overline{1, n}, j=\overline{1, d}&amp;lt;/math&amp;gt;&amp;amp;ndash; координат векторов (наблюдений).&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;Целое положительное число &amp;lt;math&amp;gt;k, k \le n&amp;lt;/math&amp;gt; &amp;amp;ndash; количество кластеров.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;Объем входных данных&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;math&amp;gt;1&amp;lt;/math&amp;gt; целое число + &amp;lt;math&amp;gt;n \cdot d&amp;lt;/math&amp;gt; вещественных чисел (при условии, что координаты &amp;amp;ndash; вещественные числа).&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;Выходные данные&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; целых положительных чисел &amp;lt;math&amp;gt;L_1, ..., L_n&amp;lt;/math&amp;gt;&amp;amp;ndash; номера кластеров, соотвествующие каждому вектору (при условии, что нумерация кластеров начинается с &amp;lt;math&amp;gt;1&amp;lt;/math&amp;gt;).&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;Объем выходных данных&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; целых положительных чисел.&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Свойства алгоритма ===&lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;[[глоссарий#Вычислительная мощность|&#039;&#039;Вычислительная мощность&#039;&#039;]]&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
Вычислительная мощность алгоритма &amp;lt;i&amp;gt;k means&amp;lt;/i&amp;gt; равна &amp;lt;math&amp;gt;\frac{ikdn}{nd} = ki &amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; &amp;amp;ndash; число кластеров, &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt; &amp;amp;ndash; число итераций алгоритма.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;[[глоссарий#Детерминированность |&#039;&#039;Детерминированность&#039;&#039;]] и [[глоссарий#Устойчивость |&#039;&#039;Устойчивость&#039;&#039;]] &amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
Алгоритм &amp;lt;i&amp;gt;k means&amp;lt;/i&amp;gt; является итерационным. Количество итераций алгоритма в общем случае не фиксируется и зависит от начального расположения объектов в пространстве, параметра &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt;, а также от начального приближения центров кластеров, &amp;lt;math&amp;gt;\mu_1, ..., \mu_k&amp;lt;/math&amp;gt;. В результате этого может варьироваться результат работы алгоритма. При неудачном выборе начальных параметров итерационный процесс может сойтись к локальному оптимуму&amp;lt;ref&amp;gt;Von Luxburg, Ulrike. Clustering Stability. Now Publishers Inc, 2010.&amp;lt;/ref&amp;gt;. По этим причинам алгоритм не является ни &amp;lt;b&amp;gt;детермирированным&amp;lt;/b&amp;gt;, ни &amp;lt;b&amp;gt;устойчивым&amp;lt;/b&amp;gt;.&lt;br /&gt;
 &lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Соотношение последовательной и параллельной сложности алгоритма&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\frac{\Theta_{k-means}}{\Psi_{k-means}} = \frac{O(ikdn)}{O(i \cdot log(kdn))}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Сильные стороны алгоритма&amp;lt;/b&amp;gt;:&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;i&amp;gt;Сравнительно высокая эффективность при простоте реализации&amp;lt;/i&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;i&amp;gt;Высокое качество кластеризации&amp;lt;/i&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;i&amp;gt;Возможность распараллеливания&amp;lt;/i&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;i&amp;gt;Существование множества модификаций&amp;lt;/i&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;Недостатки алгоритма&amp;lt;/b&amp;gt;&amp;lt;ref&amp;gt;Ortega, Joaquín Pérez, Ma Del Rocío Boone Rojas, and María J. Somodevilla. &amp;quot;Research issues on K-means Algorithm: An Experimental Trial Using Matlab.&amp;quot;&amp;lt;/ref&amp;gt;:&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;i&amp;gt;Количество кластеров является параметром алгоритма&amp;lt;/i&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;&amp;lt;i&amp;gt;Чувствительность к начальным условиям&amp;lt;/i&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;Инициализация центров кластеров в значительной степени влияет на результат кластеризации.&amp;lt;/p&amp;gt;&lt;br /&gt;
  &amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;&amp;lt;i&amp;gt;Чувствительность к выбросам и шумам&amp;lt;/i&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;Выбросы, далекие от центров настоящих кластеров, все равно учитываются при вычислении их центров.&amp;lt;/p&amp;gt;&lt;br /&gt;
  &amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;&amp;lt;i&amp;gt;Возможность сходимости к локальному оптимуму&amp;lt;/i&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;Итеративный подход не дает гарантии сходимости к оптимальному решению.&amp;lt;/p&amp;gt;&lt;br /&gt;
  &amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;&amp;lt;i&amp;gt;Использование понятия &amp;quot;среднего&amp;quot;&amp;lt;/i&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;Алгоритм неприменим к данным, для которых не определено понятие &amp;quot;среднего&amp;quot;, например, категориальным данным.&amp;lt;/p&amp;gt;&lt;br /&gt;
  &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&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;
Исследование масштабируемости параллельной реализации алгоритма k means проводилось на суперкомпьютере &amp;quot;Ломоносов&amp;quot;&amp;lt;ref name=&amp;quot;Lom&amp;quot;&amp;gt;Воеводин Вл., Жуматий С., Соболев С., Антонов А., Брызгалов П., Никитенко Д., Стефанов К., Воеводин Вад. Практика суперкомпьютера «Ломоносов» // Открытые системы, 2012, N 7, С. 36-39.&amp;lt;/ref&amp;gt; [http://parallel.ru/cluster Суперкомпьютерного комплекса Московского университета]. Алгоритм реализован на языке C с использованием средств MPI.&lt;br /&gt;
Для исследования масштабируемости проводилось множество запусков программы с разным значением параметра (количество векторов для кластеризации), а также с различным числом процессоров. Фиксировались результаты запусков &amp;amp;ndash; время работы &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt; и количество произведенных итераций алгоритма &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Параметры запусков для экспериментальной оценки:&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;Значения &amp;lt;b&amp;gt;количества векторов&amp;lt;/b&amp;gt; &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;: 20&#039;000, 30&#039;000, 50&#039;000, 100&#039;000, 200&#039;000, 300&#039;000, 500&#039;000, 700&#039;000, 1&#039;000&#039;000, 1&#039;500&#039;000, 2&#039;000&#039;000.&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;Значения &amp;lt;b&amp;gt;количества процессоров&amp;lt;/b&amp;gt; &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt;: 1, 8, 16, 32, 64, 128, 160, 192, 224, 256, 288, 320, 352, 384, 416, 448, 480, 512.&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;Значение &amp;lt;b&amp;gt;количества кластеров&amp;lt;/b&amp;gt; &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt;: 100.&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;Значение &amp;lt;b&amp;gt;размерности векторов&amp;lt;/b&amp;gt; &amp;lt;math&amp;gt;d&amp;lt;/math&amp;gt;: 10.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Для проведения экспериментов были сгенерированы нормально распределенные псевдослучайные данные (с использованием Python библиотеки [http://scikit-learn.org/ scikit-learn]):&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
from sklearn.datasets import make_classification&lt;br /&gt;
X1, Y1 = make_classification(n_features=10, n_redundant=2, n_informative=8,&lt;br /&gt;
                             n_clusters_per_class=1, n_classes=100,&lt;br /&gt;
                             n_samples=2000000)&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Для заданной конфигурации эксперимента (&amp;lt;math&amp;gt;n, d, p, k&amp;lt;/math&amp;gt;) и полученных результатов (&amp;lt;math&amp;gt;t, i&amp;lt;/math&amp;gt;)  [[Глоссарий#Производительность|производительность]]  и эффективность реализации расчитывались по формулам:&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
&amp;lt;ul&amp;gt;&amp;lt;li&amp;gt;&amp;lt;math&amp;gt;Performance = \frac{N_{k-means}^{d, n}}{t}\ \ (FLOPS),&amp;lt;/math&amp;gt;&amp;lt;/li&amp;gt;&amp;lt;/ul&amp;gt;&lt;br /&gt;
где &amp;lt;math&amp;gt;N_{k-means}^{d, n}&amp;lt;/math&amp;gt; &amp;amp;ndash; точное число операций с плавающей точкой (операции с памятью, а также целочисленные операции не учитывались), вычисленное в соответствие с разделом [[#Последовательная сложность алгоритма| &amp;quot;Последовательная сложность алгоритма&amp;quot;]];&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
&amp;lt;ul&amp;gt;&amp;lt;li&amp;gt;&amp;lt;math&amp;gt;Efficiency = \frac{100 \cdot Performance}{Performance_{Peak}^{p}}\ \ (%),&amp;lt;/math&amp;gt;&amp;lt;/li&amp;gt;&amp;lt;/ul&amp;gt;&lt;br /&gt;
где &amp;lt;math&amp;gt;Performance_{Peak}^{p}&amp;lt;/math&amp;gt; &amp;amp;ndash; пиковая производительность суперкомпьютера при &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt; процессорах, вычисленная согласно спецификациям Intel&amp;lt;sup&amp;gt;&amp;amp;reg;&amp;lt;/sup&amp;gt; XEON&amp;lt;sup&amp;gt;&amp;amp;reg;&amp;lt;/sup&amp;gt; X5670&amp;lt;ref&amp;gt;&amp;quot;http://ark.intel.com/ru/products/47920/Intel-Xeon-Processor-X5670-12M-Cache-2_93-GHz-6_40-GTs-Intel-QPI&amp;quot;&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Графики зависимости производительности и эффективности параллельной реализации k means от числа векторов для кластеризации (&amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;) и числа процессоров (&amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt;) представлены на рисунках 4 и 5 соответственно.&lt;br /&gt;
&lt;br /&gt;
[[file:Flops.png|thumb|center|800px|Рис. 4. Параллельная реализация k means. График зависимости производительности реализации алгоритма от числа векторов для кластеризации (&amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;) и числа процессоров (&amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt;).]]&lt;br /&gt;
[[file:Efficiency.png|thumb|center|800px|Рис. 5. Параллельная реализация k means. График зависимости эффективности реализации алгоритма от числа векторов для кластеризации (&amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;) и числа процессоров (&amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt;).]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;В результате&amp;lt;/b&amp;gt; экспериментальной оценки были получены следующие оценки эффективности реализации:&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;b&amp;gt;Минимальное&amp;lt;/b&amp;gt; значение: 0.000409 % достигается при &amp;lt;math&amp;gt;n=20&#039;000, p=480&amp;lt;/math&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;b&amp;gt;Максимальное&amp;lt;/b&amp;gt; значение: 0.741119 % достигается при &amp;lt;math&amp;gt;n=300&#039;000, p=1&amp;lt;/math&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
Оценки масштабируемости реализации алгоритма k means:&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;b&amp;gt;По числу процессоров:&amp;lt;/b&amp;gt; -0.002683 &amp;amp;ndash; эффективность убывает с ростом числа процессоров. Данный результат вызван ростом накладных расходов для обеспечения параллельного выполнения алгоритма.&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;b&amp;gt;По размеру задачи:&amp;lt;/b&amp;gt; 0.002779 &amp;amp;ndash; эффективность растет с ростом числа векторов. Данный результат вызван тем, что при увеличении размера задачи, количество вычислений растет по сравнению с временем, затрачиваемым на пересылку данных.&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;b&amp;gt;Общая оценка:&amp;lt;/b&amp;gt; -0.000058 &amp;amp;ndash; можно сделать вывод, что в целом эффективность реализации незначительно уменьшается с ростом размера задачи и числа процессоров.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[https://github.com/serban/kmeans Использованная параллельная реализация алгоритма k means]&lt;br /&gt;
&lt;br /&gt;
=== Динамические характеристики и эффективность реализации алгоритма ===&lt;br /&gt;
=== Выводы для классов архитектур ===&lt;br /&gt;
=== Существующие реализации алгоритма ===&lt;br /&gt;
==== Открытое программное обеспечение ====&lt;br /&gt;
&amp;lt;ol&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;[https://www.icpsr.umich.edu/CrimeStat/ CrimeStat]&amp;lt;/li&amp;gt; Программное обеспечение, созданное для операционных систем Windows, предоставляющее инструменты статистического  и пространственного анализа для решения задачи картирования преступности.&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://juliastats.github.io Julia]&amp;lt;/li&amp;gt; Высокоуровневый высокопроизводительный свободный язык программирования с динамической типизацией, созданный для математических вычислений, содержит реализацию k-means.&lt;br /&gt;
  &amp;lt;li&amp;gt;[https://mahout.apache.org Mahout]&amp;lt;/li&amp;gt; Apache Mahout - Java библиотека для работы с алгоритмами машинного обучения с использованием MapReduce. Содержит реализацию k-means.&lt;br /&gt;
  &amp;lt;li&amp;gt;[https://www.gnu.org/software/octave/ Octave]&amp;lt;/li&amp;gt; Написанная на C++  свободная система для математических вычислений, использующая совместимый с MATLAB язык высокого уровня, содержит реализацию k-means.&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://spark.apache.org/docs/latest/mllib-clustering.html Spark]&amp;lt;/li&amp;gt; Распределенная реализация k-means содержится в библиотеке Mlib для работы с алгоритмами машинного обучения, взаимодействующая с Python библиотекой NumPy и библиотека R.&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://torch.ch Torch]&amp;lt;/li&amp;gt;  MATLAB-подобная библиотека для языка программирования Lua с открытым исходным кодом, предоставляет большое количество алгоритмов для глубинного обучения и научных расчётов. Ядро написано на Си, прикладная часть выполняется на LuaJIT, поддерживается распараллеливание вычислений средствами CUDA и OpenMP. Существуют реализации k-means.&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://www.cs.waikato.ac.nz/ml/weka/ Weka]&amp;lt;/li&amp;gt;  Cвободное программное обеспечение для анализа данных, написанное на Java. Содержит k-means и x-means.&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://accord-framework.net/docs/html/T_Accord_MachineLearning_KMeans.htm Accord.NET]&amp;lt;/li&amp;gt; C# реализация алгоритмов k-means, k-means++, k-modes.&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://docs.opencv.org/3.0-beta/doc/py_tutorials/py_ml/py_kmeans/py_kmeans_opencv/py_kmeans_opencv.html OpenCV]&amp;lt;/li&amp;gt; Написанная на С++ библиотека, направленная в основном на решение задач компьютерного зрения. Содержит реализацию k-means.&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://mlpack.org/ MLPACK]&amp;lt;/li&amp;gt; Масштабируемая С++ библиотека для работы с алгоритмами машинного обучения, содержит реализацию k-means.&lt;br /&gt;
  &amp;lt;li&amp;gt;[https://www.scipy.org/ SciPy]&amp;lt;/li&amp;gt; Библиотека Python, содержит множество реализаций k-means.&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://scikit-learn.org/ scikit-learn]&amp;lt;/li&amp;gt; Библиотека Python, содержит множество реализаций k-means.&lt;br /&gt;
  &amp;lt;li&amp;gt;[https://www.r-bloggers.com/k-means-clustering-in-r/ R]&amp;lt;/li&amp;gt; Язык программирования для статистической обработки данных и работы с графикой, а также свободная программная среда вычислений с открытым исходным кодом в рамках проекта GNU, содержит три реализации k-means.&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://elki.dbs.ifi.lmu.de ELKI]&amp;lt;/li&amp;gt; Java фреймворк, содержащий реализацию k-means, а также множество других алгоритмов кластеризации.&lt;br /&gt;
&amp;lt;/ol&amp;gt;&lt;br /&gt;
==== Проприетарное программное обеспечение  ====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ol&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;[https://www.ayasdi.com/blog/bigdata/topological-data-analysis-of-oil-and-gas-petrophysical-data/ Ayasdi]&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://www.stata.com/features/cluster-analysis/ Stata]&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://mathworld.wolfram.com/K-MeansClusteringAlgorithm.html Mathematica]&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://www.mathworks.com/help/stats/kmeans.html?requestedDomain=www.mathworks.com MATLAB]&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;[https://support.sas.com/rnd/app/stat/procedures/fastclus.html SAS]&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://docs.rapidminer.com/studio/operators/modeling/segmentation/k_means.html RapidMiner]&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;[https://blogs.sap.com/2013/03/28/sap-hana-pal-k-means-algorithm-or-how-to-do-customer-segmentation-for-the-telecommunications-industry/ SAP HANA]&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ol&amp;gt;&lt;br /&gt;
== Литература ==&lt;br /&gt;
&amp;lt;references /&amp;gt;&lt;/div&gt;</summary>
		<author><name>DennZo1993</name></author>
	</entry>
	<entry>
		<id>https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:%D0%91%D1%80%D0%BE%D1%82%D0%B8%D0%BA%D0%BE%D0%B2%D1%81%D0%BA%D0%B0%D1%8F_%D0%94%D0%B0%D0%BD%D1%83%D1%82%D0%B0/%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_k-means&amp;diff=20532</id>
		<title>Участник:Бротиковская Данута/Алгоритм k-means</title>
		<link rel="alternate" type="text/html" href="https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:%D0%91%D1%80%D0%BE%D1%82%D0%B8%D0%BA%D0%BE%D0%B2%D1%81%D0%BA%D0%B0%D1%8F_%D0%94%D0%B0%D0%BD%D1%83%D1%82%D0%B0/%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_k-means&amp;diff=20532"/>
		<updated>2016-12-10T11:05:34Z</updated>

		<summary type="html">&lt;p&gt;DennZo1993: /* Последовательная сложность алгоритма */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Assignment|Zhum}}&lt;br /&gt;
&lt;br /&gt;
{{algorithm&lt;br /&gt;
| name              = Алгоритм k средних (k means)&lt;br /&gt;
| serial_complexity = &amp;lt;math&amp;gt;O(ikdn)&amp;lt;/math&amp;gt;&lt;br /&gt;
| input_data        = &amp;lt;math&amp;gt; dn &amp;lt;/math&amp;gt;&lt;br /&gt;
| output_data       = &amp;lt;math&amp;gt; n &amp;lt;/math&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
Авторы страницы &amp;lt;b&amp;gt;[[Участник:Бротиковская Данута|Данута Бротиковская]]&amp;lt;/b&amp;gt; и &amp;lt;b&amp;gt;[[Участник:DennZo1993|Денис Зобнин]]&amp;lt;/b&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
Оба автора внесли одинаковый вклад в написание статьи (поиск материалов, изучение статей, заполнение контента статьи), четких разграничений по пунктам статьи сделать невозможно. &lt;br /&gt;
&lt;br /&gt;
== Свойства и структура алгоритма ==&lt;br /&gt;
&lt;br /&gt;
=== Общее описание алгоритма ===&lt;br /&gt;
Алгоритм &amp;lt;b&amp;gt;&amp;lt;i&amp;gt;k средних&amp;lt;/i&amp;gt;&amp;lt;/b&amp;gt; (&amp;lt;b&amp;gt;&amp;lt;i&amp;gt;k means&amp;lt;/i&amp;gt;&amp;lt;/b&amp;gt;) &amp;amp;ndash; неиерархический&amp;lt;ref&amp;gt;&amp;quot;https://ru.wikipedia.org/wiki/Иерархическая_кластеризация&amp;quot;&amp;lt;/ref&amp;gt;, итерационный метод кластеризации&amp;lt;ref&amp;gt;&amp;quot;https://ru.wikipedia.org/wiki/Кластерный_анализ&amp;quot;&amp;lt;/ref&amp;gt;, получивший большую популярность благодаря своей простоте, наглядности реализации и достаточно высокому качеству работы. Был изобретен в 1950-х годах математиком &amp;lt;i&amp;gt;Гуго Штейнгаузом&amp;lt;/i&amp;gt;&amp;lt;ref&amp;gt;Steinhaus, Hugo. &amp;quot;Sur la division des corp materiels en parties.&amp;quot; Bull. Acad. Polon. Sci 1.804 (1956): 801.&amp;lt;/ref&amp;gt; и почти одновременно &amp;lt;i&amp;gt;Стюартом Ллойдом&amp;lt;/i&amp;gt;&amp;lt;ref&amp;gt;Lloyd, S. P. &amp;quot;Least square quantization in PCM. Bell Telephone Laboratories Paper. Published in journal much later: Lloyd, SP: Least squares quantization in PCM.&amp;quot; IEEE Trans. Inform. Theor.(1957/1982).&amp;lt;/ref&amp;gt;. Особую популярность приобрел после публикации работы &amp;lt;i&amp;gt;МакКуина&amp;lt;/i&amp;gt;&amp;lt;ref&amp;gt;MacQueen, James. &amp;quot;Some methods for classification and analysis of multivariate observations.&amp;quot; Proceedings of the fifth Berkeley symposium on mathematical statistics and probability. Vol. 1. No. 14. 1967.&amp;lt;/ref&amp;gt; в 1967.&lt;br /&gt;
&lt;br /&gt;
Алгоритм представляет собой версию EM-алгоритма&amp;lt;ref&amp;gt;&amp;quot;https://ru.wikipedia.org/wiki/EM-алгоритм&amp;quot;&amp;lt;/ref&amp;gt;, применяемого также для разделения смеси гауссиан. Основная идея &amp;lt;i&amp;gt;k means&amp;lt;/i&amp;gt; заключается в том, что данные произвольно разбиваются на кластеры, после чего итеративно перевычисляется центр масс для каждого кластера, полученного на предыдущем шаге, затем векторы разбиваются на кластеры вновь в соответствии с тем, какой из новых центров оказался ближе по выбранной метрике.&lt;br /&gt;
&lt;br /&gt;
Цель алгоритма заключается в разделении &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; наблюдений на &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластеров таким образом, чтобы каждое наблюдение принадлежало ровно одному кластеру, расположенному на наименьшем расстоянии от наблюдения.&lt;br /&gt;
&lt;br /&gt;
=== Математическое описание алгоритма ===&lt;br /&gt;
&amp;lt;b&amp;gt;&amp;lt;u&amp;gt;Дано:&amp;lt;/u&amp;gt;&amp;lt;/b&amp;gt;&lt;br /&gt;
* набор из &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; наблюдений &amp;lt;math&amp;gt;X=\{\mathbf{x}_1, \mathbf{x}_2, ..., \mathbf{x}_n\}, \mathbf{x}_i \in \mathbb{R}^d, i=\overline{1, n}&amp;lt;/math&amp;gt;;&lt;br /&gt;
* &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; - требуемое число кластеров, &amp;lt;math&amp;gt;k \in \mathbb{N}, k \leq n&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;&amp;lt;u&amp;gt;Требуется:&amp;lt;/u&amp;gt;&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Разделить множество наблюдений &amp;lt;math&amp;gt;X&amp;lt;/math&amp;gt; на &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластеров &amp;lt;math&amp;gt;S_1, S_2, ..., S_k&amp;lt;/math&amp;gt;:&lt;br /&gt;
*   &amp;lt;math&amp;gt;S_i \cap S_j= \varnothing, \quad i \ne j&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
*   &amp;lt;math&amp;gt;\bigcup_{i=1}^{k} S_i = X&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;&amp;lt;u&amp;gt;Действие алгоритма:&amp;lt;/u&amp;gt;&amp;lt;/b&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;Алгоритм &amp;lt;i&amp;gt;k means&amp;lt;/i&amp;gt; разбивает набор &amp;lt;math&amp;gt;X&amp;lt;/math&amp;gt; на &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; наборов &amp;lt;math&amp;gt;S_1, S_2, ..., S_k,&amp;lt;/math&amp;gt; таким образом, чтобы минимизировать сумму квадратов расстояний от каждой точки кластера до его центра (центр масс кластера). Введем обозначение, &amp;lt;math&amp;gt;S=\{S_1, S_2, ..., S_k\}&amp;lt;/math&amp;gt;. Тогда действие алгоритма &amp;lt;i&amp;gt;k means&amp;lt;/i&amp;gt; равносильно поиску:&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;table style=&amp;quot;width:100%&amp;quot;&amp;gt;&lt;br /&gt;
  &amp;lt;tr&amp;gt;&lt;br /&gt;
    &amp;lt;td align=&amp;quot;center&amp;quot; width=&amp;quot;90%&amp;quot;&amp;gt;&amp;lt;math&amp;gt;\arg\min_{S} \sum\limits_{i=1}^k \sum\limits_{\mathbf{x} \in S_i} \rho(\mathbf{x}, \mathbf{\mu}_i )^2,&amp;lt;/math&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;td align=&amp;quot;right&amp;quot;&amp;gt;&amp;lt;math&amp;gt;(1)&amp;lt;/math&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;/table&amp;gt;&lt;br /&gt;
где &amp;lt;math&amp;gt;\mathbf{\mu}_i&amp;lt;/math&amp;gt; &amp;amp;ndash; центры кластеров, &amp;lt;math&amp;gt;i=\overline{1,k}, \quad \rho(\mathbf{x}, \mathbf{\mu}_i)&amp;lt;/math&amp;gt; &amp;amp;ndash; функция расстояния между &amp;lt;math&amp;gt;\mathbf{x}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\mu_i&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;&amp;lt;u&amp;gt;Шаги алгоритма: &amp;lt;/u&amp;gt;&amp;lt;/b&amp;gt;&lt;br /&gt;
&amp;lt;ol&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&lt;br /&gt;
    &amp;lt;b&amp;gt;Начальный шаг: инициализация кластеров&amp;lt;/b&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;Выбирается произвольное множество точек &amp;lt;math&amp;gt;\mu_i, i=\overline{1,k}&amp;lt;/math&amp;gt;, рассматриваемых как начальные центры кластеров: &amp;lt;math&amp;gt;\mu_i^{(0)} = \mu_i, \quad i=\overline{1, k}&amp;lt;/math&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
  &amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&lt;br /&gt;
    &amp;lt;b&amp;gt;Распределение векторов по кластерам&amp;lt;/b&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Шаг&amp;lt;/b&amp;gt; &amp;lt;math&amp;gt;t: \forall \mathbf{x}_i \in X, i=\overline{1,n}: \mathbf{x}_i \in S_j \iff  j=\arg\min_{k}\rho(\mathbf{x}_i,\mathbf{\mu}_k^{(t-1)})^2&amp;lt;/math&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
  &amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&lt;br /&gt;
    &amp;lt;b&amp;gt;Пересчет центров кластеров&amp;lt;/b&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Шаг &amp;lt;/b&amp;gt; &amp;lt;math&amp;gt;t: \forall i=\overline{1,k}:  \mu_i^{(t)} = \cfrac{1}{|S_i|}\sum_{\mathbf{x}\in S_i}\mathbf{x}&amp;lt;/math&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
  &amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&lt;br /&gt;
    &amp;lt;b&amp;gt;Проверка условия останова:&amp;lt;/b&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
    &#039;&#039;&#039;if&#039;&#039;&#039; &amp;lt;math&amp;gt;\exist i\in \overline{1,k}: \mu_i^{(t)} \ne \mu_i^{(t-1)}&amp;lt;/math&amp;gt; &#039;&#039;&#039;then&#039;&#039;&#039;&lt;br /&gt;
        t = t + 1;&lt;br /&gt;
        goto 2;&lt;br /&gt;
    &#039;&#039;&#039;else&#039;&#039;&#039;&lt;br /&gt;
        &#039;&#039;&#039;stop&#039;&#039;&#039;&lt;br /&gt;
  &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ol&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Вычислительное ядро алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Вычислительным ядром являются шаги 2 и 3 приведенного выше алгоритма: &amp;lt;b&amp;gt;&amp;lt;i&amp;gt;распределение векторов по кластерам&amp;lt;/i&amp;gt;&amp;lt;/b&amp;gt; и &amp;lt;b&amp;gt;&amp;lt;i&amp;gt;пересчет центров кластеров&amp;lt;/i&amp;gt;&amp;lt;/b&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;&amp;lt;i&amp;gt;Распределение векторов&amp;lt;/i&amp;gt;&amp;lt;/b&amp;gt; по кластерам предполагает вычисление расстояний между каждым вектором &amp;lt;math&amp;gt;\mathbf{x}_i \in X, i= \overline{1,n}&amp;lt;/math&amp;gt; и центрами кластера &amp;lt;math&amp;gt;\mathbf{\mu}_j, j= \overline{1,k}&amp;lt;/math&amp;gt;. Таким образом, данный шаг предполагает &amp;lt;math&amp;gt;kn&amp;lt;/math&amp;gt; вычислений расстояний между d-мерными векторами. &lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;&amp;lt;i&amp;gt;Пересчет центров кластеров&amp;lt;/i&amp;gt;&amp;lt;/b&amp;gt; предполагает &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; вычислений центров масс &amp;lt;math&amp;gt;\mathbf{\mu}_i&amp;lt;/math&amp;gt; множеств &amp;lt;math&amp;gt;S_i, i=\overline{1,k}&amp;lt;/math&amp;gt; представленных выражением в шаге 3 представленного выше алгоритма.&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Макроструктура алгоритма ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Инициализация центров масс &amp;lt;math&amp;gt;\mu_1, ..., \mu_k&amp;lt;/math&amp;gt;&amp;lt;/b&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
Наиболее распространенными являются следующие стратегии:&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&lt;br /&gt;
    &amp;lt;b&amp;gt;Метод Forgy&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;В качестве начальных значений &amp;lt;math&amp;gt;\mu_1, ..., \mu_k&amp;lt;/math&amp;gt; берутся случайно выбранные векторы.&lt;br /&gt;
  &amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&lt;br /&gt;
    &amp;lt;b&amp;gt;Метод случайно разделения (Random Partitioning)&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;Для каждого вектора &amp;lt;math&amp;gt;\mathbf{x}_i \in X, i=\overline{1, n}&amp;lt;/math&amp;gt; выбирается случайным образом кластер &amp;lt;math&amp;gt;S_1, ..., S_k&amp;lt;/math&amp;gt;, после чего для каждого полученного кластера вычисляются значения &amp;lt;math&amp;gt;\mu_1, ..., \mu_k&amp;lt;/math&amp;gt;.&lt;br /&gt;
  &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Распределение векторов по кластерам&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Для этого шага алгоритма между векторами &amp;lt;math&amp;gt;\mathbf{x}_i \in X, i=\overline{1, n}&amp;lt;/math&amp;gt; и центрами кластеров &amp;lt;math&amp;gt;\mu_1, ..., \mu_k&amp;lt;/math&amp;gt; вычисляются &amp;lt;b&amp;gt;расстояния&amp;lt;/b&amp;gt; по формуле (как правило, используется Евлидово расстояние):&lt;br /&gt;
&amp;lt;table style=&amp;quot;width:100%&amp;quot;&amp;gt;&lt;br /&gt;
  &amp;lt;tr&amp;gt;&lt;br /&gt;
    &amp;lt;td align=&amp;quot;center&amp;quot; width=&amp;quot;90%&amp;quot;&amp;gt;&amp;lt;math&amp;gt; \mathbf{v}_1, \mathbf{v}_2 \in \mathbb{R}^d,  \quad \rho(\mathbf{v}_1, \mathbf{v}_2) = \lVert \mathbf{v}_1- \mathbf{v}_2 \rVert= \sqrt{\sum_{i=1}^{d}(\mathbf{v}_{1,i} - \mathbf{v}_{2,i})^2}&amp;lt;/math&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;td align=&amp;quot;right&amp;quot;&amp;gt;&amp;lt;math&amp;gt;(2)&amp;lt;/math&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;/table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Пересчет центров кластеров&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Для этого шага алгоритма производится пересчет центров кластера по &amp;lt;b&amp;gt;формуле вычисления центра масс&amp;lt;/b&amp;gt;:&lt;br /&gt;
&amp;lt;table style=&amp;quot;width:100%&amp;quot;&amp;gt;&lt;br /&gt;
  &amp;lt;tr&amp;gt;&lt;br /&gt;
    &amp;lt;td align=&amp;quot;center&amp;quot; width=&amp;quot;90%&amp;quot;&amp;gt;&amp;lt;math&amp;gt; \mu = \cfrac{1}{|S|}\sum_{\mathbf{x}\in S}\mathbf{x}&amp;lt;/math&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;td align=&amp;quot;right&amp;quot;&amp;gt;&amp;lt;math&amp;gt;(3)&amp;lt;/math&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;/table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Схема реализации последовательного алгоритма ===&lt;br /&gt;
&lt;br /&gt;
 &#039;&#039;&#039;algorithm&#039;&#039;&#039; k-means &#039;&#039;&#039;is&#039;&#039;&#039;&lt;br /&gt;
     &#039;&#039;&#039;1.&#039;&#039;&#039; Инициализировать центры кластеров &amp;lt;math&amp;gt;\mathbf{\mu}_i^{(1)}, i=\overline{1,k}&amp;lt;/math&amp;gt;&lt;br /&gt;
     &#039;&#039;&#039;2.&#039;&#039;&#039; &amp;lt;math&amp;gt;t \leftarrow 1&amp;lt;/math&amp;gt;&lt;br /&gt;
     &#039;&#039;&#039;3.&#039;&#039;&#039; &#039;&#039;&#039;Распределение по кластерам&#039;&#039;&#039;&amp;lt;br&amp;gt;&lt;br /&gt;
        &amp;lt;math&amp;gt;S_i^{(t)}=\{\mathbf{x}_p: \lVert\mathbf{x}_p-\mathbf{\mu}_i^{(t)}\rVert^2 \leq \lVert\mathbf{x}_p-\mathbf{\mu}_j^{(t)}\rVert^2 \quad \forall j=\overline{1,k}\},&amp;lt;/math&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
        где каждый вектор &amp;lt;math&amp;gt;\mathbf{x}_p&amp;lt;/math&amp;gt; соотносится единственному кластеру &amp;lt;math&amp;gt;S^{(t)}&amp;lt;/math&amp;gt;&lt;br /&gt;
     &#039;&#039;&#039;4.&#039;&#039;&#039; &#039;&#039;&#039;Обновление центров кластеров&#039;&#039;&#039;&amp;lt;br&amp;gt;&lt;br /&gt;
        &amp;lt;math&amp;gt;\mathbf{\mu}_i^{(t+1)} = \frac{1}{|S^{(t)}_i|} \sum_{\mathbf{x}_j \in S^{(t)}_i} \mathbf{x}_j &amp;lt;/math&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
     &#039;&#039;&#039;5.&#039;&#039;&#039; &#039;&#039;&#039;if&#039;&#039;&#039; &amp;lt;math&amp;gt;\exist i \in \overline{1,k}: \mathbf{\mu}_i^{(t+1)} \ne \mathbf{\mu}_i^{(t)}&amp;lt;/math&amp;gt; &#039;&#039;&#039;then&#039;&#039;&#039;&lt;br /&gt;
            t = t + 1;&lt;br /&gt;
            goto &#039;&#039;&#039;3&#039;&#039;&#039;;&lt;br /&gt;
        &#039;&#039;&#039;else&#039;&#039;&#039;&lt;br /&gt;
            &#039;&#039;&#039;stop&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
=== Последовательная сложность алгоритма===&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding-bottom: 20px&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;Обозначим &amp;lt;math&amp;gt;\Theta_{\rm centroid}^{d, m}&amp;lt;/math&amp;gt; временную сложность вычисления центорида кластера, число элементов которого равна &amp;lt;math&amp;gt;m&amp;lt;/math&amp;gt;,  в d-мерном пространстве.&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;Аналогично  &amp;lt;math&amp;gt;\Theta_{\rm distance}^d&amp;lt;/math&amp;gt; &amp;amp;ndash; временная сложность вычисления расстояния между двумя d-мерными векторами.&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding-bottom: 20px&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;Сложность шага инициализации &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластеров мощности &amp;lt;math&amp;gt;m&amp;lt;/math&amp;gt; в d-мерном пространстве &amp;amp;ndash; &amp;lt;math&amp;gt;\Theta_{\rm init}^{k, d, m}&amp;lt;/math&amp;gt;&amp;lt;/b&amp;gt;&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;i&amp;gt;Стратерия Forgy&amp;lt;/i&amp;gt;: вычисления не требуются, &amp;lt;math&amp;gt;\Theta_{\rm init}^{k, d, m} = 0&amp;lt;/math&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;i&amp;gt;Стратегия случайного разбиения&amp;lt;/i&amp;gt;: вычисление центров &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластеров,  &amp;lt;math&amp;gt;\Theta_{\rm init}^{k, d, m} = k \cdot \Theta_{\rm centroid}^{d, m}, m \le n&amp;lt;/math&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding-bottom: 20px&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Cложность шага распределения d мерных векторов по &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластерам &amp;amp;ndash; &amp;lt;math&amp;gt;\Theta_{\rm distribute}^{k, d}&amp;lt;/math&amp;gt;&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
На этом шаге для каждого вектора &amp;lt;math&amp;gt;\mathbf{x}_i \in X, i=\overline{1, n}&amp;lt;/math&amp;gt; вычисляется k расстояний до центров кластеров &amp;lt;math&amp;gt;\mathbf{\mu}_1, ...\mathbf{\mu}_k&amp;lt;/math&amp;gt;&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p align=&amp;quot;center&amp;quot;&amp;gt;&lt;br /&gt;
  &amp;lt;math&amp;gt;\Theta_{\rm distribute}^{k, d} = n \cdot k \cdot \Theta_{\rm distance}^d&amp;lt;/math&amp;gt;&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding-bottom: 20px&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;Сложность шага пересчета центров &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластеров размера &amp;lt;math&amp;gt;m&amp;lt;/math&amp;gt; в d-мерном пространстве &amp;amp;ndash; &amp;lt;math&amp;gt;\Theta_{\rm recenter}^{k, d, m}&amp;lt;/math&amp;gt;&amp;lt;/b&amp;gt;&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;На этом шаге вычисляется &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; центров кластеров &amp;lt;math&amp;gt;\mathbf{\mu}_1, ...\mathbf{\mu}_k&amp;lt;/math&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p align=&amp;quot;center&amp;quot;&amp;gt;&amp;lt;math&amp;gt;\Theta_{\rm recenter}^{k, d, m} = k \cdot \Theta_{\rm centroid}^{d, m}&amp;lt;/math&amp;gt; &amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding-bottom: 20px&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Рассчитаем &amp;lt;math&amp;gt;\Theta_{\rm centroid}^{d, m}&amp;lt;/math&amp;gt; для кластера, число элементов которого равно &amp;lt;math&amp;gt;m&amp;lt;/math&amp;gt;&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p align=&amp;quot;center&amp;quot;&amp;gt;&amp;lt;math&amp;gt;\Theta_{\rm centroid}^{d, m}&amp;lt;/math&amp;gt; = &amp;lt;math&amp;gt;m \cdot d&amp;lt;/math&amp;gt; сложений + &amp;lt;math&amp;gt;d&amp;lt;/math&amp;gt; делений &amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding-bottom: 20px&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Рассчитаем &amp;lt;math&amp;gt;\Theta_{\rm distance}^d&amp;lt;/math&amp;gt; в соответствие с формулой &amp;lt;math&amp;gt;(2)&amp;lt;/math&amp;gt;&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p align=&amp;quot;center&amp;quot;&amp;gt;&amp;lt;math&amp;gt;\Theta_{\rm distance}^d&amp;lt;/math&amp;gt; = &amp;lt;math&amp;gt;d&amp;lt;/math&amp;gt; вычитаний + &amp;lt;math&amp;gt;d&amp;lt;/math&amp;gt; умножений + &amp;lt;math&amp;gt;(d-1)&amp;lt;/math&amp;gt; сложение&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding-bottom: 20px&amp;quot;&amp;gt;&lt;br /&gt;
  &amp;lt;p&amp;gt;Предположим, что алгоритм сошелся за &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt; итераций, тогда временная сложность алгоритма &amp;lt;math&amp;gt;\Theta_{\rm k-means}^{d, n}&amp;lt;/math&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
  &amp;lt;p align=&amp;quot;center&amp;quot;&amp;gt;&amp;lt;b&amp;gt;&amp;lt;math&amp;gt;\Theta_{\rm k-means}^{d, n} \le \Theta_{\rm init}^{k, d, n} + i(\Theta_{\rm distribute}^{k, d} + \Theta_{\rm recenter}^{k, d, n})&amp;lt;/math&amp;gt;&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding-bottom: 5px&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;Операции сложения/вычитания:&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p align=&amp;quot;center&amp;quot;&amp;gt;&amp;lt;b&amp;gt;&amp;lt;math&amp;gt;\Theta_{\rm k-means}^{d, n} \le knd+ i(kn(2d-1) + knd) = knd+ i(kn(3d-1)) \thicksim O(ikdn)&amp;lt;/math&amp;gt;&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding-bottom: 20px&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;Операции умножения/деления:&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p align=&amp;quot;center&amp;quot;&amp;gt;&amp;lt;b&amp;gt;&amp;lt;math&amp;gt;\Theta_{\rm k-means}^{d, n} \le kd + i(knd + kd) = kd + ikd(n+1) \thicksim O(ikdn) &amp;lt;/math&amp;gt;&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding-bottom: 20px&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;Получаем, что &amp;lt;b&amp;gt;временная сложность&amp;lt;/b&amp;gt; алгоритма &amp;lt;b&amp;gt;k means&amp;lt;/b&amp;gt; кластеризации &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; &amp;lt;b&amp;gt;d-мерных&amp;lt;/b&amp;gt; векторов на &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластеров за &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt; итераций:&amp;lt;/p&amp;gt;&lt;br /&gt;
 &amp;lt;p align=&amp;quot;center&amp;quot;&amp;gt;&amp;lt;b&amp;gt;&amp;lt;math&amp;gt; \Theta_{\rm k-means}^{d, n} \thicksim O(ikdn) &amp;lt;/math&amp;gt;&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Информационный граф ===&lt;br /&gt;
&lt;br /&gt;
Рассмотрим информационный граф алгоритма. Алгоритм &amp;lt;i&amp;gt;k means&amp;lt;/i&amp;gt; начинается с этапа инициализации, после которого следуют итерации, на каждой из которых выполняется два последовательных шага (см. [[#Схема реализации последовательного алгоритма|&amp;quot;Схема реализации последовательного алгоритма&amp;quot;]]): &lt;br /&gt;
* распределение векторов по кластерам&lt;br /&gt;
* перерасчет центров кластеров&lt;br /&gt;
&lt;br /&gt;
Поскольку основная часть вычислений приходится на шаги итераций, распишем информационные графы данных шагов.&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Распределение векторов по кластерам&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
Информационный граф шага распределения векторов по кластерам представлен на &#039;&#039;рисунке 1&#039;&#039;. Исходами данного графа является исходные векторы &amp;lt;math&amp;gt;\mathbf{x}_1, ..., \mathbf{x}_n&amp;lt;/math&amp;gt;, а также центры кластеров &amp;lt;math&amp;gt;\mathbf{\mu}_1, ... \mathbf{\mu}_k&amp;lt;/math&amp;gt;, вычисленные ранее (на шаге инициализации, если рассматривается первая итерация алгоритма, или на шаге пересчета центров кластеров предыдущей итерации в противном случае). Каждая пара векторов данных &amp;lt;math&amp;gt;\mathbf{x}_i, i=\overline{1,n}&amp;lt;/math&amp;gt; и центров кластера &amp;lt;math&amp;gt;\mathbf{\mu}_j, j=\overline{1, k}&amp;lt;/math&amp;gt; : (&amp;lt;math&amp;gt;\mathbf{x}_i&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;\mathbf{\mu}_j&amp;lt;/math&amp;gt;) подаются на независимые узлы &amp;lt;i&amp;gt;&amp;quot;d&amp;quot;&amp;lt;/i&amp;gt; вычисления расстояния между векторами (более подробная схема вычисления расстояния представлена далее, &#039;&#039;рисунок 2&#039;&#039;). Далее узлы вычисления расстояния &amp;lt;i&amp;gt;&amp;quot;d&amp;quot;&amp;lt;/i&amp;gt;, соответствующие одному и тому же исходному вектору &amp;lt;math&amp;gt;\mathbf{x}_i&amp;lt;/math&amp;gt; передаются на один узел &amp;lt;i&amp;gt;&amp;quot;m&amp;quot;&amp;lt;/i&amp;gt;, где далее происходит вычисление новой метки кластера для каждого вектора &amp;lt;math&amp;gt;\mathbf{x}_i&amp;lt;/math&amp;gt; (берется кластер с минимальным результатом вычисления расстояния). На выходе графа выдаются метки кластеров , &amp;lt;math&amp;gt;L_1, ..., L_n&amp;lt;/math&amp;gt;, такие что &amp;lt;math&amp;gt;\forall \mathbf{x}_i, i=\overline{1, n}, \mathbf{x}_i \in S_j \Leftrightarrow L_i = j&amp;lt;/math&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
[[file:Clusterization.png|thumb|center|800px|Рис. 1. Схема распределения векторов по кластерам. &#039;&#039;d&#039;&#039; &amp;amp;ndash; вычисление расстояния между векторами; &#039;&#039;m&#039;&#039; &amp;amp;ndash; вычисление минимума.]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Вычисление расстояния между векторами&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
Подробная схема вычисления расстояния между векторами &amp;lt;math&amp;gt;\mathbf{x}_i, \mathbf{\mu}_j&amp;lt;/math&amp;gt; представлена на &#039;&#039;рисунке 2&#039;&#039;. Как показано на графе, узел вычисления расстояния между векторами &amp;lt;i&amp;gt;&amp;quot;d&amp;quot;&amp;lt;/i&amp;gt; состоит из шага взятия разности между векторами (узел &amp;quot;&amp;lt;math&amp;gt;-&amp;lt;/math&amp;gt;&amp;quot;) и взятия нормы получившегося вектора разности (узел &amp;quot;&amp;lt;math&amp;gt;||\cdot||^2&amp;lt;/math&amp;gt;&amp;quot;). Более подробно, вычисление расстояния между векторами &amp;lt;math&amp;gt;\mathbf{x}_i = {x_{i1,}, ...,{x_{in}}}, \mathbf{\mu}_j = {\mu_{j1}, ...,\mu_{jn}}&amp;lt;/math&amp;gt; может быть представлено как вычисление разности между каждой парой компонент &amp;lt;math&amp;gt;(x_{iz}, \mu_{jz}), z=\overline{1, d}&amp;lt;/math&amp;gt; (узел &amp;quot;&amp;lt;math&amp;gt;-&amp;lt;/math&amp;gt;&amp;quot;), далее возведение в квадрат для каждого узла &amp;quot;&amp;lt;math&amp;gt;-&amp;lt;/math&amp;gt;&amp;quot; (узел &amp;quot;&amp;lt;math&amp;gt;()^2&amp;lt;/math&amp;gt;&amp;quot;) и суммирования выходов всех узлов &amp;quot;&amp;lt;math&amp;gt;()^2&amp;lt;/math&amp;gt;&amp;quot; (узел &amp;quot;&amp;lt;math&amp;gt;+&amp;lt;/math&amp;gt;&amp;quot;).  &lt;br /&gt;
&lt;br /&gt;
[[file:dist_calc.png|thumb|center|800px|Рис. 2. Схема вычисления расстояния между вектором и центром кластера.]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Пересчет центров кластеров&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
Информационный граф шага пересчета центров кластеров представлен на &#039;&#039;рисунке 3&#039;&#039;. Исходами данного графа является исходные векторы &amp;lt;math&amp;gt;\mathbf{x}_1, ..., \mathbf{x}_n&amp;lt;/math&amp;gt;, а также им соответствующие метки кластера, &amp;lt;math&amp;gt;L_1, ..., L_n&amp;lt;/math&amp;gt;, такие что &amp;lt;math&amp;gt;\forall x_i, i=\overline{1, n}, \mathbf{x}_i \in S_j \Leftrightarrow L_i = j&amp;lt;/math&amp;gt;, вычисленные на этапе распределения векторов по кластерам. Все векторы &amp;lt;math&amp;gt;\mathbf{x}_1, ..., \mathbf{x}_n&amp;lt;/math&amp;gt; подаются в узлы &amp;lt;math&amp;gt;+_1, ...+_k&amp;lt;/math&amp;gt;, каждый узел &amp;lt;math&amp;gt;+_m, m = \overline{1,k}&amp;lt;/math&amp;gt; соответствует операции сложения векторов кластера с номером &amp;lt;math&amp;gt;m&amp;lt;/math&amp;gt;. Метки кластера &amp;lt;math&amp;gt;L_1, ..., L_n&amp;lt;/math&amp;gt; также совместно передаются на узлы &amp;lt;math&amp;gt;S_m, m = \overline{1,k}&amp;lt;/math&amp;gt;, на каждом из которых вычисляется количество векторов в соответствующем кластере (количество меток с соответствующим значением). Далее каждая пара выходов узлов &amp;lt;math&amp;gt;+_m&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;S_m&amp;lt;/math&amp;gt; подается на узел &amp;quot;&amp;lt;math&amp;gt;/&amp;lt;/math&amp;gt;&amp;quot;, где производится деление суммы векторов кластера на количество элементов в нем. Значения, вычисленные на узлах &amp;quot;&amp;lt;math&amp;gt;/&amp;lt;/math&amp;gt;&amp;quot;, присваиваются новым центрам кластеров (выходные значения графа).&lt;br /&gt;
&lt;br /&gt;
[[file:Recluster.png|thumb|center|800px|Рис. 3. Схема пересчета центров кластеров]]&lt;br /&gt;
&lt;br /&gt;
=== Ресурс параллелизма алгоритма ===&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
Работа алгоритма состоит из &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt; итераций, в каждой из которых происходит &amp;lt;b&amp;gt;распределение d-мерных векторов по &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластерам&amp;lt;/b&amp;gt;, а также &amp;lt;b&amp;gt;пересчет центров кластеров в d-мерном пространстве&amp;lt;/b&amp;gt;. В шаге &amp;lt;b&amp;gt;распределения d-мерных векторов по &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластерам&amp;lt;/b&amp;gt; расстояния между вектором и центрами кластеров вычисляются независимо (отсутствуют информационные зависимости). &amp;lt;b&amp;gt;Центры масс кластеров&amp;lt;/b&amp;gt; также пересчитываются независимо друг от друга. Таким образом, имеет место [[глоссарий#Массовый параллелизм|&#039;&#039;массовый параллелизм&#039;&#039;]]. Вычислим параллельную сложность &amp;lt;math&amp;gt;\Psi_*&amp;lt;/math&amp;gt; каждого из шагов, а также параллельную сложность всего алгоритма, &amp;lt;math&amp;gt;\Psi_{k-means}&amp;lt;/math&amp;gt;. Будем исходить из предположения, что может быть использовано любое необходимое число потоков.&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Распределение d-мерных векторов по &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластерам&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;  &lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
Поскольку на данном шаге для каждой пары векторов &amp;lt;math&amp;gt;\mathbf{x}_i, i=\overline{1,n}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\mathbf{\mu}_j, j=\overline{1,k}&amp;lt;/math&amp;gt; операции вычисления расстояния не зависят друг от друга, они могут выполняться параллельно. Тогда, разделив все вычисление расстояний на &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; потоков, получим, что в каждом потоке будет выполняться только одна операция вычисления расстояния между векторами размерности d. При этом каждому вычислительному потоку передаются координаты центров всех кластеров &amp;lt;math&amp;gt;\mathbf{\mu}_1, ..., \mathbf{\mu}_k&amp;lt;/math&amp;gt;. Таким образом, параллельная сложность данного шага определяется &amp;lt;i&amp;gt; сложностью параллельной операции вычисления расстояния между d-мерными векторами&amp;lt;/i&amp;gt;, &amp;lt;math&amp;gt;\Psi_{distance}^d&amp;lt;/math&amp;gt;  и &amp;lt;i&amp;gt;сложностью определения наиболее близкого кластера&amp;lt;/i&amp;gt; (паралельное взятие минимума по расстояниям), &amp;lt;math&amp;gt;\Psi_{min}^k&amp;lt;/math&amp;gt;. Для оценки &amp;lt;math&amp;gt;\Psi_{distance}^d&amp;lt;/math&amp;gt; воспользуемся  [[Нахождение_частных_сумм_элементов_массива_сдваиванием | параллельной реализацией нахождения частичной суммы элементов массива путем сдваивания]]. Аналогично, &amp;lt;math&amp;gt;\Psi_{min}^k = log(k)&amp;lt;/math&amp;gt;. В результате, &amp;lt;math&amp;gt;\Psi_{distance}^d = O(log(d))&amp;lt;/math&amp;gt;.   Таким образом: &lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p align=&amp;quot;center&amp;quot;&amp;gt;&amp;lt;math&amp;gt;\Psi_{distribute}^{k, d}  = \Psi_{distance}^d + \Psi_{min}^k = O(log(d))+O(log(k)) = O(log(kd))&amp;lt;/math&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Пересчет центров кластеров в d-мерном пространстве&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
Поскольку на данном шаге для каждого из &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластеров центр масс может быть вычислен независимо, данные операции могут быть выполнены в отдельных потоках. Таким образом, параллельная сложность данного шага, &amp;lt;math&amp;gt;\Psi_{recenter}^{k, d}&amp;lt;/math&amp;gt;,  будет определяться &amp;lt;i&amp;gt;параллельной сложностью вычисления одного центра масс кластера размера &amp;lt;math&amp;gt;m&amp;lt;/math&amp;gt;&amp;lt;/i&amp;gt;, &amp;lt;math&amp;gt;\Psi_{recenter}^{k, d}&amp;lt;/math&amp;gt;,  а так как &amp;lt;math&amp;gt;m \le n \Rightarrow \Psi_{recenter}^{d, m} \le \Psi_{recenter}^{d, n}&amp;lt;/math&amp;gt;. Сложность вычисления центра масс кластера d-мерных векторов размера n аналогично предыдущим вычислениям равна &amp;lt;math&amp;gt;O(log(n))&amp;lt;/math&amp;gt;. Тогда:  &lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p align=&amp;quot;center&amp;quot;&amp;gt;&amp;lt;math&amp;gt;\Psi_{recenter}^{k, d}  \le \Psi_{recenter}^{d, n} = O(log(n))&amp;lt;/math&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Общая параллельная сложность алгоритма&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
На каждой итерации необходимо обновление центров кластеров, которые будут использованы на следующей итерации. Таким образом, итерационный процесс выполняется последовательно&amp;lt;ref&amp;gt;Zhao, Weizhong, Huifang Ma, and Qing He. &amp;quot;Parallel k-means clustering based on mapreduce.&amp;quot; IEEE International Conference on Cloud Computing. Springer Berlin Heidelberg, 2009.&amp;lt;/ref&amp;gt;. Тогда, поскольку сложность каждой итерации  определяется &amp;lt;math&amp;gt;\Psi_{distribute}^{k, d}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\Psi_{recenter}&amp;lt;/math&amp;gt;, сложность всего алгоритма, &amp;lt;math&amp;gt;\Psi_{k-means}&amp;lt;/math&amp;gt; в предположении, что было сделано &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt; операций определяется выражением&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p align=&amp;quot;center&amp;quot;&amp;gt;&amp;lt;math&amp;gt;\Psi_{k-means} \approx i \cdot (\Psi_{distribute}^{k, d} + \Psi_{recenter}^{k, d}) \le i \cdot O(log(kdn))&amp;lt;/math&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Входные и выходные данные алгоритма ===&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;Входные данные&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;Матрица из &amp;lt;math&amp;gt;n \cdot d&amp;lt;/math&amp;gt; элементов &amp;lt;math&amp;gt;x_{i, j} \in \mathbb{R}, i=\overline{1, n}, j=\overline{1, d}&amp;lt;/math&amp;gt;&amp;amp;ndash; координат векторов (наблюдений).&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;Целое положительное число &amp;lt;math&amp;gt;k, k \le n&amp;lt;/math&amp;gt; &amp;amp;ndash; количество кластеров.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;Объем входных данных&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;math&amp;gt;1&amp;lt;/math&amp;gt; целое число + &amp;lt;math&amp;gt;n \cdot d&amp;lt;/math&amp;gt; вещественных чисел (при условии, что координаты &amp;amp;ndash; вещественные числа).&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;Выходные данные&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; целых положительных чисел &amp;lt;math&amp;gt;L_1, ..., L_n&amp;lt;/math&amp;gt;&amp;amp;ndash; номера кластеров, соотвествующие каждому вектору (при условии, что нумерация кластеров начинается с &amp;lt;math&amp;gt;1&amp;lt;/math&amp;gt;).&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;Объем выходных данных&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; целых положительных чисел.&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Свойства алгоритма ===&lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;[[глоссарий#Вычислительная мощность|&#039;&#039;Вычислительная мощность&#039;&#039;]]&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
Вычислительная мощность алгоритма &amp;lt;i&amp;gt;k means&amp;lt;/i&amp;gt; равна &amp;lt;math&amp;gt;\frac{ikdn}{nd} = ki &amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; &amp;amp;ndash; число кластеров, &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt; &amp;amp;ndash; число итераций алгоритма.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;[[глоссарий#Детерминированность |&#039;&#039;Детерминированность&#039;&#039;]] и [[глоссарий#Устойчивость |&#039;&#039;Устойчивость&#039;&#039;]] &amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
Алгоритм &amp;lt;i&amp;gt;k means&amp;lt;/i&amp;gt; является итерационным. Количество итераций алгоритма в общем случае не фиксируется и зависит от начального расположения объектов в пространстве, параметра &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt;, а также от начального приближения центров кластеров, &amp;lt;math&amp;gt;\mu_1, ..., \mu_k&amp;lt;/math&amp;gt;. В результате этого может варьироваться результат работы алгоритма. При неудачном выборе начальных параметров итерационный процесс может сойтись к локальному оптимуму&amp;lt;ref&amp;gt;Von Luxburg, Ulrike. Clustering Stability. Now Publishers Inc, 2010.&amp;lt;/ref&amp;gt;. По этим причинам алгоритм не является ни &amp;lt;b&amp;gt;детермирированным&amp;lt;/b&amp;gt;, ни &amp;lt;b&amp;gt;устойчивым&amp;lt;/b&amp;gt;.&lt;br /&gt;
 &lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Соотношение последовательной и параллельной сложности алгоритма&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\frac{\Theta_{k-means}}{\Psi_{k-means}} = \frac{O(ikdn)}{O(i \cdot log(kdn))}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Сильные стороны алгоритма&amp;lt;/b&amp;gt;:&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;i&amp;gt;Сравнительно высокая эффективность при простоте реализации&amp;lt;/i&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;i&amp;gt;Высокое качество кластеризации&amp;lt;/i&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;i&amp;gt;Возможность распараллеливания&amp;lt;/i&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;i&amp;gt;Существование множества модификаций&amp;lt;/i&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;Недостатки алгоритма&amp;lt;/b&amp;gt;&amp;lt;ref&amp;gt;Ortega, Joaquín Pérez, Ma Del Rocío Boone Rojas, and María J. Somodevilla. &amp;quot;Research issues on K-means Algorithm: An Experimental Trial Using Matlab.&amp;quot;&amp;lt;/ref&amp;gt;:&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;i&amp;gt;Количество кластеров является параметром алгоритма&amp;lt;/i&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;&amp;lt;i&amp;gt;Чувствительность к начальным условиям&amp;lt;/i&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;Инициализация центров кластеров в значительной степени влияет на результат кластеризации.&amp;lt;/p&amp;gt;&lt;br /&gt;
  &amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;&amp;lt;i&amp;gt;Чувствительность к выбросам и шумам&amp;lt;/i&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;Выбросы, далекие от центров настоящих кластеров, все равно учитываются при вычислении их центров.&amp;lt;/p&amp;gt;&lt;br /&gt;
  &amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;&amp;lt;i&amp;gt;Возможность сходимости к локальному оптимуму&amp;lt;/i&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;Итеративный подход не дает гарантии сходимости к оптимальному решению.&amp;lt;/p&amp;gt;&lt;br /&gt;
  &amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;&amp;lt;i&amp;gt;Использование понятия &amp;quot;среднего&amp;quot;&amp;lt;/i&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;Алгоритм неприменим к данным, для которых не определено понятие &amp;quot;среднего&amp;quot;, например, категориальным данным.&amp;lt;/p&amp;gt;&lt;br /&gt;
  &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&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;
Исследование масштабируемости параллельной реализации алгоритма k means проводилось на суперкомпьютере &amp;quot;Ломоносов&amp;quot;&amp;lt;ref name=&amp;quot;Lom&amp;quot;&amp;gt;Воеводин Вл., Жуматий С., Соболев С., Антонов А., Брызгалов П., Никитенко Д., Стефанов К., Воеводин Вад. Практика суперкомпьютера «Ломоносов» // Открытые системы, 2012, N 7, С. 36-39.&amp;lt;/ref&amp;gt; [http://parallel.ru/cluster Суперкомпьютерного комплекса Московского университета]. Алгоритм реализован на языке C с использованием средств MPI.&lt;br /&gt;
Для исследования масштабируемости проводилось множество запусков программы с разным значением параметра (количество векторов для кластеризации), а также с различным числом процессоров. Фиксировались результаты запусков &amp;amp;ndash; время работы &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt; и количество произведенных итераций алгоритма &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Параметры запусков для экспериментальной оценки:&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;Значения &amp;lt;b&amp;gt;количества векторов&amp;lt;/b&amp;gt; &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;: 20&#039;000, 30&#039;000, 50&#039;000, 100&#039;000, 200&#039;000, 300&#039;000, 500&#039;000, 700&#039;000, 1&#039;000&#039;000, 1&#039;500&#039;000, 2&#039;000&#039;000.&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;Значения &amp;lt;b&amp;gt;количества процессоров&amp;lt;/b&amp;gt; &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt;: 1, 8, 16, 32, 64, 128, 160, 192, 224, 256, 288, 320, 352, 384, 416, 448, 480, 512.&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;Значение &amp;lt;b&amp;gt;количества кластеров&amp;lt;/b&amp;gt; &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt;: 100.&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;Значение &amp;lt;b&amp;gt;размерности векторов&amp;lt;/b&amp;gt; &amp;lt;math&amp;gt;d&amp;lt;/math&amp;gt;: 10.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Для проведения экспериментов были сгенерированы нормально распределенные псевдослучайные данные (с использованием Python библиотеки [http://scikit-learn.org/ scikit-learn]):&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
from sklearn.datasets import make_classification&lt;br /&gt;
X1, Y1 = make_classification(n_features=10, n_redundant=2, n_informative=8,&lt;br /&gt;
                             n_clusters_per_class=1, n_classes=100,&lt;br /&gt;
                             n_samples=2000000)&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Для заданной конфигурации эксперимента (&amp;lt;math&amp;gt;n, d, p, k&amp;lt;/math&amp;gt;) и полученных результатов (&amp;lt;math&amp;gt;t, i&amp;lt;/math&amp;gt;)  [[Глоссарий#Производительность|производительность]]  и эффективность реализации расчитывались по формулам:&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
&amp;lt;ul&amp;gt;&amp;lt;li&amp;gt;&amp;lt;math&amp;gt;Performance = \frac{N_{k-means}^{d, n}}{t}\ \ (FLOPS),&amp;lt;/math&amp;gt;&amp;lt;/li&amp;gt;&amp;lt;/ul&amp;gt;&lt;br /&gt;
где &amp;lt;math&amp;gt;N_{k-means}^{d, n}&amp;lt;/math&amp;gt; &amp;amp;ndash; точное число операций с плавающей точкой (операции с памятью, а также целочисленные операции не учитывались), вычисленное в соответствие с разделом [[#Последовательная сложность алгоритма| &amp;quot;Последовательная сложность алгоритма&amp;quot;]];&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
&amp;lt;ul&amp;gt;&amp;lt;li&amp;gt;&amp;lt;math&amp;gt;Efficiency = \frac{100 \cdot Performance}{Performance_{Peak}^{p}}\ \ (%),&amp;lt;/math&amp;gt;&amp;lt;/li&amp;gt;&amp;lt;/ul&amp;gt;&lt;br /&gt;
где &amp;lt;math&amp;gt;Performance_{Peak}^{p}&amp;lt;/math&amp;gt; &amp;amp;ndash; пиковая производительность суперкомпьютера при &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt; процессорах, вычисленная согласно спецификациям Intel&amp;lt;sup&amp;gt;&amp;amp;reg;&amp;lt;/sup&amp;gt; XEON&amp;lt;sup&amp;gt;&amp;amp;reg;&amp;lt;/sup&amp;gt; X5670&amp;lt;ref&amp;gt;&amp;quot;http://ark.intel.com/ru/products/47920/Intel-Xeon-Processor-X5670-12M-Cache-2_93-GHz-6_40-GTs-Intel-QPI&amp;quot;&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Графики зависимости производительности и эффективности параллельной реализации k means от числа векторов для кластеризации (&amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;) и числа процессоров (&amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt;) представлены на рисунках 4 и 5 соответственно.&lt;br /&gt;
&lt;br /&gt;
[[file:Flops.png|thumb|center|800px|Рис. 4. Параллельная реализация k means. График зависимости производительности реализации алгоритма от числа векторов для кластеризации (&amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;) и числа процессоров (&amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt;).]]&lt;br /&gt;
[[file:Efficiency.png|thumb|center|800px|Рис. 5. Параллельная реализация k means. График зависимости эффективности реализации алгоритма от числа векторов для кластеризации (&amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;) и числа процессоров (&amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt;).]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;В результате&amp;lt;/b&amp;gt; экспериментальной оценки были получены следующие оценки эффективности реализации:&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;b&amp;gt;Минимальное&amp;lt;/b&amp;gt; значение: 0.000409 % достигается при &amp;lt;math&amp;gt;n=20&#039;000, p=480&amp;lt;/math&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;b&amp;gt;Максимальное&amp;lt;/b&amp;gt; значение: 0.741119 % достигается при &amp;lt;math&amp;gt;n=300&#039;000, p=1&amp;lt;/math&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
Оценки масштабируемости реализации алгоритма k means:&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;b&amp;gt;По числу процессоров:&amp;lt;/b&amp;gt; -0.002683 &amp;amp;ndash; эффективность убывает с ростом числа процессоров. Данный результат вызван ростом накладных расходов для обеспечения параллельного выполнения алгоритма.&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;b&amp;gt;По размеру задачи:&amp;lt;/b&amp;gt; 0.002779 &amp;amp;ndash; эффективность растет с ростом числа векторов. Данный результат вызван тем, что при увеличении размера задачи, количество вычислений растет по сравнению с временем, затрачиваемым на пересылку данных.&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;b&amp;gt;Общая оценка:&amp;lt;/b&amp;gt; -0.000058 &amp;amp;ndash; можно сделать вывод, что в целом эффективность реализации незначительно уменьшается с ростом размера задачи и числа процессоров.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[https://github.com/serban/kmeans Использованная параллельная реализация алгоритма k means]&lt;br /&gt;
&lt;br /&gt;
=== Динамические характеристики и эффективность реализации алгоритма ===&lt;br /&gt;
=== Выводы для классов архитектур ===&lt;br /&gt;
=== Существующие реализации алгоритма ===&lt;br /&gt;
==== Открытое программное обеспечение ====&lt;br /&gt;
&amp;lt;ol&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;[https://www.icpsr.umich.edu/CrimeStat/ CrimeStat]&amp;lt;/li&amp;gt; Программное обеспечение, созданное для операционных систем Windows, предоставляющее инструменты статистического  и пространственного анализа для решения задачи картирования преступности.&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://juliastats.github.io Julia]&amp;lt;/li&amp;gt; Высокоуровневый высокопроизводительный свободный язык программирования с динамической типизацией, созданный для математических вычислений, содержит реализацию k-means.&lt;br /&gt;
  &amp;lt;li&amp;gt;[https://mahout.apache.org Mahout]&amp;lt;/li&amp;gt; Apache Mahout - Java библиотека для работы с алгоритмами машинного обучения с использованием MapReduce. Содержит реализацию k-means.&lt;br /&gt;
  &amp;lt;li&amp;gt;[https://www.gnu.org/software/octave/ Octave]&amp;lt;/li&amp;gt; Написанная на C++  свободная система для математических вычислений, использующая совместимый с MATLAB язык высокого уровня, содержит реализацию k-means.&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://spark.apache.org/docs/latest/mllib-clustering.html Spark]&amp;lt;/li&amp;gt; Распределенная реализация k-means содержится в библиотеке Mlib для работы с алгоритмами машинного обучения, взаимодействующая с Python библиотекой NumPy и библиотека R.&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://torch.ch Torch]&amp;lt;/li&amp;gt;  MATLAB-подобная библиотека для языка программирования Lua с открытым исходным кодом, предоставляет большое количество алгоритмов для глубинного обучения и научных расчётов. Ядро написано на Си, прикладная часть выполняется на LuaJIT, поддерживается распараллеливание вычислений средствами CUDA и OpenMP. Существуют реализации k-means.&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://www.cs.waikato.ac.nz/ml/weka/ Weka]&amp;lt;/li&amp;gt;  Cвободное программное обеспечение для анализа данных, написанное на Java. Содержит k-means и x-means.&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://accord-framework.net/docs/html/T_Accord_MachineLearning_KMeans.htm Accord.NET]&amp;lt;/li&amp;gt; C# реализация алгоритмов k-means, k-means++, k-modes.&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://docs.opencv.org/3.0-beta/doc/py_tutorials/py_ml/py_kmeans/py_kmeans_opencv/py_kmeans_opencv.html OpenCV]&amp;lt;/li&amp;gt; Написанная на С++ библиотека, направленная в основном на решение задач компьютерного зрения. Содержит реализацию k-means.&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://mlpack.org/ MLPACK]&amp;lt;/li&amp;gt; Масштабируемая С++ библиотека для работы с алгоритмами машинного обучения, содержит реализацию k-means.&lt;br /&gt;
  &amp;lt;li&amp;gt;[https://www.scipy.org/ SciPy]&amp;lt;/li&amp;gt; Библиотека Python, содержит множество реализаций k-means.&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://scikit-learn.org/ scikit-learn]&amp;lt;/li&amp;gt; Библиотека Python, содержит множество реализаций k-means.&lt;br /&gt;
  &amp;lt;li&amp;gt;[https://www.r-bloggers.com/k-means-clustering-in-r/ R]&amp;lt;/li&amp;gt; Язык программирования для статистической обработки данных и работы с графикой, а также свободная программная среда вычислений с открытым исходным кодом в рамках проекта GNU, содержит три реализации k-means.&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://elki.dbs.ifi.lmu.de ELKI]&amp;lt;/li&amp;gt; Java фреймворк, содержащий реализацию k-means, а также множество других алгоритмов кластеризации.&lt;br /&gt;
&amp;lt;/ol&amp;gt;&lt;br /&gt;
==== Проприетарное программное обеспечение  ====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ol&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;[https://www.ayasdi.com/blog/bigdata/topological-data-analysis-of-oil-and-gas-petrophysical-data/ Ayasdi]&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://www.stata.com/features/cluster-analysis/ Stata]&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://mathworld.wolfram.com/K-MeansClusteringAlgorithm.html Mathematica]&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://www.mathworks.com/help/stats/kmeans.html?requestedDomain=www.mathworks.com MATLAB]&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;[https://support.sas.com/rnd/app/stat/procedures/fastclus.html SAS]&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://docs.rapidminer.com/studio/operators/modeling/segmentation/k_means.html RapidMiner]&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;[https://blogs.sap.com/2013/03/28/sap-hana-pal-k-means-algorithm-or-how-to-do-customer-segmentation-for-the-telecommunications-industry/ SAP HANA]&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ol&amp;gt;&lt;br /&gt;
== Литература ==&lt;br /&gt;
&amp;lt;references /&amp;gt;&lt;/div&gt;</summary>
		<author><name>DennZo1993</name></author>
	</entry>
	<entry>
		<id>https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:%D0%91%D1%80%D0%BE%D1%82%D0%B8%D0%BA%D0%BE%D0%B2%D1%81%D0%BA%D0%B0%D1%8F_%D0%94%D0%B0%D0%BD%D1%83%D1%82%D0%B0/%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_k-means&amp;diff=20531</id>
		<title>Участник:Бротиковская Данута/Алгоритм k-means</title>
		<link rel="alternate" type="text/html" href="https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:%D0%91%D1%80%D0%BE%D1%82%D0%B8%D0%BA%D0%BE%D0%B2%D1%81%D0%BA%D0%B0%D1%8F_%D0%94%D0%B0%D0%BD%D1%83%D1%82%D0%B0/%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_k-means&amp;diff=20531"/>
		<updated>2016-12-10T11:02:01Z</updated>

		<summary type="html">&lt;p&gt;DennZo1993: /* Последовательная сложность алгоритма */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Assignment|Zhum}}&lt;br /&gt;
&lt;br /&gt;
{{algorithm&lt;br /&gt;
| name              = Алгоритм k средних (k means)&lt;br /&gt;
| serial_complexity = &amp;lt;math&amp;gt;O(ikdn)&amp;lt;/math&amp;gt;&lt;br /&gt;
| input_data        = &amp;lt;math&amp;gt; dn &amp;lt;/math&amp;gt;&lt;br /&gt;
| output_data       = &amp;lt;math&amp;gt; n &amp;lt;/math&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
Авторы страницы &amp;lt;b&amp;gt;[[Участник:Бротиковская Данута|Данута Бротиковская]]&amp;lt;/b&amp;gt; и &amp;lt;b&amp;gt;[[Участник:DennZo1993|Денис Зобнин]]&amp;lt;/b&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
Оба автора внесли одинаковый вклад в написание статьи (поиск материалов, изучение статей, заполнение контента статьи), четких разграничений по пунктам статьи сделать невозможно. &lt;br /&gt;
&lt;br /&gt;
== Свойства и структура алгоритма ==&lt;br /&gt;
&lt;br /&gt;
=== Общее описание алгоритма ===&lt;br /&gt;
Алгоритм &amp;lt;b&amp;gt;&amp;lt;i&amp;gt;k средних&amp;lt;/i&amp;gt;&amp;lt;/b&amp;gt; (&amp;lt;b&amp;gt;&amp;lt;i&amp;gt;k means&amp;lt;/i&amp;gt;&amp;lt;/b&amp;gt;) &amp;amp;ndash; неиерархический&amp;lt;ref&amp;gt;&amp;quot;https://ru.wikipedia.org/wiki/Иерархическая_кластеризация&amp;quot;&amp;lt;/ref&amp;gt;, итерационный метод кластеризации&amp;lt;ref&amp;gt;&amp;quot;https://ru.wikipedia.org/wiki/Кластерный_анализ&amp;quot;&amp;lt;/ref&amp;gt;, получивший большую популярность благодаря своей простоте, наглядности реализации и достаточно высокому качеству работы. Был изобретен в 1950-х годах математиком &amp;lt;i&amp;gt;Гуго Штейнгаузом&amp;lt;/i&amp;gt;&amp;lt;ref&amp;gt;Steinhaus, Hugo. &amp;quot;Sur la division des corp materiels en parties.&amp;quot; Bull. Acad. Polon. Sci 1.804 (1956): 801.&amp;lt;/ref&amp;gt; и почти одновременно &amp;lt;i&amp;gt;Стюартом Ллойдом&amp;lt;/i&amp;gt;&amp;lt;ref&amp;gt;Lloyd, S. P. &amp;quot;Least square quantization in PCM. Bell Telephone Laboratories Paper. Published in journal much later: Lloyd, SP: Least squares quantization in PCM.&amp;quot; IEEE Trans. Inform. Theor.(1957/1982).&amp;lt;/ref&amp;gt;. Особую популярность приобрел после публикации работы &amp;lt;i&amp;gt;МакКуина&amp;lt;/i&amp;gt;&amp;lt;ref&amp;gt;MacQueen, James. &amp;quot;Some methods for classification and analysis of multivariate observations.&amp;quot; Proceedings of the fifth Berkeley symposium on mathematical statistics and probability. Vol. 1. No. 14. 1967.&amp;lt;/ref&amp;gt; в 1967.&lt;br /&gt;
&lt;br /&gt;
Алгоритм представляет собой версию EM-алгоритма&amp;lt;ref&amp;gt;&amp;quot;https://ru.wikipedia.org/wiki/EM-алгоритм&amp;quot;&amp;lt;/ref&amp;gt;, применяемого также для разделения смеси гауссиан. Основная идея &amp;lt;i&amp;gt;k means&amp;lt;/i&amp;gt; заключается в том, что данные произвольно разбиваются на кластеры, после чего итеративно перевычисляется центр масс для каждого кластера, полученного на предыдущем шаге, затем векторы разбиваются на кластеры вновь в соответствии с тем, какой из новых центров оказался ближе по выбранной метрике.&lt;br /&gt;
&lt;br /&gt;
Цель алгоритма заключается в разделении &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; наблюдений на &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластеров таким образом, чтобы каждое наблюдение принадлежало ровно одному кластеру, расположенному на наименьшем расстоянии от наблюдения.&lt;br /&gt;
&lt;br /&gt;
=== Математическое описание алгоритма ===&lt;br /&gt;
&amp;lt;b&amp;gt;&amp;lt;u&amp;gt;Дано:&amp;lt;/u&amp;gt;&amp;lt;/b&amp;gt;&lt;br /&gt;
* набор из &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; наблюдений &amp;lt;math&amp;gt;X=\{\mathbf{x}_1, \mathbf{x}_2, ..., \mathbf{x}_n\}, \mathbf{x}_i \in \mathbb{R}^d, i=\overline{1, n}&amp;lt;/math&amp;gt;;&lt;br /&gt;
* &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; - требуемое число кластеров, &amp;lt;math&amp;gt;k \in \mathbb{N}, k \leq n&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;&amp;lt;u&amp;gt;Требуется:&amp;lt;/u&amp;gt;&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Разделить множество наблюдений &amp;lt;math&amp;gt;X&amp;lt;/math&amp;gt; на &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластеров &amp;lt;math&amp;gt;S_1, S_2, ..., S_k&amp;lt;/math&amp;gt;:&lt;br /&gt;
*   &amp;lt;math&amp;gt;S_i \cap S_j= \varnothing, \quad i \ne j&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
*   &amp;lt;math&amp;gt;\bigcup_{i=1}^{k} S_i = X&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;&amp;lt;u&amp;gt;Действие алгоритма:&amp;lt;/u&amp;gt;&amp;lt;/b&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;Алгоритм &amp;lt;i&amp;gt;k means&amp;lt;/i&amp;gt; разбивает набор &amp;lt;math&amp;gt;X&amp;lt;/math&amp;gt; на &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; наборов &amp;lt;math&amp;gt;S_1, S_2, ..., S_k,&amp;lt;/math&amp;gt; таким образом, чтобы минимизировать сумму квадратов расстояний от каждой точки кластера до его центра (центр масс кластера). Введем обозначение, &amp;lt;math&amp;gt;S=\{S_1, S_2, ..., S_k\}&amp;lt;/math&amp;gt;. Тогда действие алгоритма &amp;lt;i&amp;gt;k means&amp;lt;/i&amp;gt; равносильно поиску:&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;table style=&amp;quot;width:100%&amp;quot;&amp;gt;&lt;br /&gt;
  &amp;lt;tr&amp;gt;&lt;br /&gt;
    &amp;lt;td align=&amp;quot;center&amp;quot; width=&amp;quot;90%&amp;quot;&amp;gt;&amp;lt;math&amp;gt;\arg\min_{S} \sum\limits_{i=1}^k \sum\limits_{\mathbf{x} \in S_i} \rho(\mathbf{x}, \mathbf{\mu}_i )^2,&amp;lt;/math&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;td align=&amp;quot;right&amp;quot;&amp;gt;&amp;lt;math&amp;gt;(1)&amp;lt;/math&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;/table&amp;gt;&lt;br /&gt;
где &amp;lt;math&amp;gt;\mathbf{\mu}_i&amp;lt;/math&amp;gt; &amp;amp;ndash; центры кластеров, &amp;lt;math&amp;gt;i=\overline{1,k}, \quad \rho(\mathbf{x}, \mathbf{\mu}_i)&amp;lt;/math&amp;gt; &amp;amp;ndash; функция расстояния между &amp;lt;math&amp;gt;\mathbf{x}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\mu_i&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;&amp;lt;u&amp;gt;Шаги алгоритма: &amp;lt;/u&amp;gt;&amp;lt;/b&amp;gt;&lt;br /&gt;
&amp;lt;ol&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&lt;br /&gt;
    &amp;lt;b&amp;gt;Начальный шаг: инициализация кластеров&amp;lt;/b&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;Выбирается произвольное множество точек &amp;lt;math&amp;gt;\mu_i, i=\overline{1,k}&amp;lt;/math&amp;gt;, рассматриваемых как начальные центры кластеров: &amp;lt;math&amp;gt;\mu_i^{(0)} = \mu_i, \quad i=\overline{1, k}&amp;lt;/math&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
  &amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&lt;br /&gt;
    &amp;lt;b&amp;gt;Распределение векторов по кластерам&amp;lt;/b&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Шаг&amp;lt;/b&amp;gt; &amp;lt;math&amp;gt;t: \forall \mathbf{x}_i \in X, i=\overline{1,n}: \mathbf{x}_i \in S_j \iff  j=\arg\min_{k}\rho(\mathbf{x}_i,\mathbf{\mu}_k^{(t-1)})^2&amp;lt;/math&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
  &amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&lt;br /&gt;
    &amp;lt;b&amp;gt;Пересчет центров кластеров&amp;lt;/b&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Шаг &amp;lt;/b&amp;gt; &amp;lt;math&amp;gt;t: \forall i=\overline{1,k}:  \mu_i^{(t)} = \cfrac{1}{|S_i|}\sum_{\mathbf{x}\in S_i}\mathbf{x}&amp;lt;/math&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
  &amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&lt;br /&gt;
    &amp;lt;b&amp;gt;Проверка условия останова:&amp;lt;/b&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
    &#039;&#039;&#039;if&#039;&#039;&#039; &amp;lt;math&amp;gt;\exist i\in \overline{1,k}: \mu_i^{(t)} \ne \mu_i^{(t-1)}&amp;lt;/math&amp;gt; &#039;&#039;&#039;then&#039;&#039;&#039;&lt;br /&gt;
        t = t + 1;&lt;br /&gt;
        goto 2;&lt;br /&gt;
    &#039;&#039;&#039;else&#039;&#039;&#039;&lt;br /&gt;
        &#039;&#039;&#039;stop&#039;&#039;&#039;&lt;br /&gt;
  &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ol&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Вычислительное ядро алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Вычислительным ядром являются шаги 2 и 3 приведенного выше алгоритма: &amp;lt;b&amp;gt;&amp;lt;i&amp;gt;распределение векторов по кластерам&amp;lt;/i&amp;gt;&amp;lt;/b&amp;gt; и &amp;lt;b&amp;gt;&amp;lt;i&amp;gt;пересчет центров кластеров&amp;lt;/i&amp;gt;&amp;lt;/b&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;&amp;lt;i&amp;gt;Распределение векторов&amp;lt;/i&amp;gt;&amp;lt;/b&amp;gt; по кластерам предполагает вычисление расстояний между каждым вектором &amp;lt;math&amp;gt;\mathbf{x}_i \in X, i= \overline{1,n}&amp;lt;/math&amp;gt; и центрами кластера &amp;lt;math&amp;gt;\mathbf{\mu}_j, j= \overline{1,k}&amp;lt;/math&amp;gt;. Таким образом, данный шаг предполагает &amp;lt;math&amp;gt;kn&amp;lt;/math&amp;gt; вычислений расстояний между d-мерными векторами. &lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;&amp;lt;i&amp;gt;Пересчет центров кластеров&amp;lt;/i&amp;gt;&amp;lt;/b&amp;gt; предполагает &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; вычислений центров масс &amp;lt;math&amp;gt;\mathbf{\mu}_i&amp;lt;/math&amp;gt; множеств &amp;lt;math&amp;gt;S_i, i=\overline{1,k}&amp;lt;/math&amp;gt; представленных выражением в шаге 3 представленного выше алгоритма.&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Макроструктура алгоритма ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Инициализация центров масс &amp;lt;math&amp;gt;\mu_1, ..., \mu_k&amp;lt;/math&amp;gt;&amp;lt;/b&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
Наиболее распространенными являются следующие стратегии:&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&lt;br /&gt;
    &amp;lt;b&amp;gt;Метод Forgy&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;В качестве начальных значений &amp;lt;math&amp;gt;\mu_1, ..., \mu_k&amp;lt;/math&amp;gt; берутся случайно выбранные векторы.&lt;br /&gt;
  &amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&lt;br /&gt;
    &amp;lt;b&amp;gt;Метод случайно разделения (Random Partitioning)&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;Для каждого вектора &amp;lt;math&amp;gt;\mathbf{x}_i \in X, i=\overline{1, n}&amp;lt;/math&amp;gt; выбирается случайным образом кластер &amp;lt;math&amp;gt;S_1, ..., S_k&amp;lt;/math&amp;gt;, после чего для каждого полученного кластера вычисляются значения &amp;lt;math&amp;gt;\mu_1, ..., \mu_k&amp;lt;/math&amp;gt;.&lt;br /&gt;
  &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Распределение векторов по кластерам&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Для этого шага алгоритма между векторами &amp;lt;math&amp;gt;\mathbf{x}_i \in X, i=\overline{1, n}&amp;lt;/math&amp;gt; и центрами кластеров &amp;lt;math&amp;gt;\mu_1, ..., \mu_k&amp;lt;/math&amp;gt; вычисляются &amp;lt;b&amp;gt;расстояния&amp;lt;/b&amp;gt; по формуле (как правило, используется Евлидово расстояние):&lt;br /&gt;
&amp;lt;table style=&amp;quot;width:100%&amp;quot;&amp;gt;&lt;br /&gt;
  &amp;lt;tr&amp;gt;&lt;br /&gt;
    &amp;lt;td align=&amp;quot;center&amp;quot; width=&amp;quot;90%&amp;quot;&amp;gt;&amp;lt;math&amp;gt; \mathbf{v}_1, \mathbf{v}_2 \in \mathbb{R}^d,  \quad \rho(\mathbf{v}_1, \mathbf{v}_2) = \lVert \mathbf{v}_1- \mathbf{v}_2 \rVert= \sqrt{\sum_{i=1}^{d}(\mathbf{v}_{1,i} - \mathbf{v}_{2,i})^2}&amp;lt;/math&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;td align=&amp;quot;right&amp;quot;&amp;gt;&amp;lt;math&amp;gt;(2)&amp;lt;/math&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;/table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Пересчет центров кластеров&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Для этого шага алгоритма производится пересчет центров кластера по &amp;lt;b&amp;gt;формуле вычисления центра масс&amp;lt;/b&amp;gt;:&lt;br /&gt;
&amp;lt;table style=&amp;quot;width:100%&amp;quot;&amp;gt;&lt;br /&gt;
  &amp;lt;tr&amp;gt;&lt;br /&gt;
    &amp;lt;td align=&amp;quot;center&amp;quot; width=&amp;quot;90%&amp;quot;&amp;gt;&amp;lt;math&amp;gt; \mu = \cfrac{1}{|S|}\sum_{\mathbf{x}\in S}\mathbf{x}&amp;lt;/math&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;td align=&amp;quot;right&amp;quot;&amp;gt;&amp;lt;math&amp;gt;(3)&amp;lt;/math&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;/table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Схема реализации последовательного алгоритма ===&lt;br /&gt;
&lt;br /&gt;
 &#039;&#039;&#039;algorithm&#039;&#039;&#039; k-means &#039;&#039;&#039;is&#039;&#039;&#039;&lt;br /&gt;
     &#039;&#039;&#039;1.&#039;&#039;&#039; Инициализировать центры кластеров &amp;lt;math&amp;gt;\mathbf{\mu}_i^{(1)}, i=\overline{1,k}&amp;lt;/math&amp;gt;&lt;br /&gt;
     &#039;&#039;&#039;2.&#039;&#039;&#039; &amp;lt;math&amp;gt;t \leftarrow 1&amp;lt;/math&amp;gt;&lt;br /&gt;
     &#039;&#039;&#039;3.&#039;&#039;&#039; &#039;&#039;&#039;Распределение по кластерам&#039;&#039;&#039;&amp;lt;br&amp;gt;&lt;br /&gt;
        &amp;lt;math&amp;gt;S_i^{(t)}=\{\mathbf{x}_p: \lVert\mathbf{x}_p-\mathbf{\mu}_i^{(t)}\rVert^2 \leq \lVert\mathbf{x}_p-\mathbf{\mu}_j^{(t)}\rVert^2 \quad \forall j=\overline{1,k}\},&amp;lt;/math&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
        где каждый вектор &amp;lt;math&amp;gt;\mathbf{x}_p&amp;lt;/math&amp;gt; соотносится единственному кластеру &amp;lt;math&amp;gt;S^{(t)}&amp;lt;/math&amp;gt;&lt;br /&gt;
     &#039;&#039;&#039;4.&#039;&#039;&#039; &#039;&#039;&#039;Обновление центров кластеров&#039;&#039;&#039;&amp;lt;br&amp;gt;&lt;br /&gt;
        &amp;lt;math&amp;gt;\mathbf{\mu}_i^{(t+1)} = \frac{1}{|S^{(t)}_i|} \sum_{\mathbf{x}_j \in S^{(t)}_i} \mathbf{x}_j &amp;lt;/math&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
     &#039;&#039;&#039;5.&#039;&#039;&#039; &#039;&#039;&#039;if&#039;&#039;&#039; &amp;lt;math&amp;gt;\exist i \in \overline{1,k}: \mathbf{\mu}_i^{(t+1)} \ne \mathbf{\mu}_i^{(t)}&amp;lt;/math&amp;gt; &#039;&#039;&#039;then&#039;&#039;&#039;&lt;br /&gt;
            t = t + 1;&lt;br /&gt;
            goto &#039;&#039;&#039;3&#039;&#039;&#039;;&lt;br /&gt;
        &#039;&#039;&#039;else&#039;&#039;&#039;&lt;br /&gt;
            &#039;&#039;&#039;stop&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
=== Последовательная сложность алгоритма===&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding-bottom: 20px&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;Обозначим &amp;lt;math&amp;gt;\Theta_{\rm centroid}^{d, m}&amp;lt;/math&amp;gt; временную сложность вычисления центорида кластера, число элементов которого равна &amp;lt;math&amp;gt;m&amp;lt;/math&amp;gt;,  в d-мерном пространстве.&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;Аналогично  &amp;lt;math&amp;gt;\Theta_{\rm distance}^d&amp;lt;/math&amp;gt; &amp;amp;ndash; временная сложность вычисления расстояния между двумя d-мерными векторами.&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding-bottom: 20px&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;Сложность шага инициализации &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластеров мощности &amp;lt;math&amp;gt;m&amp;lt;/math&amp;gt; в d-мерном пространстве &amp;amp;ndash; &amp;lt;math&amp;gt;\Theta_{init}^{k, d, m}&amp;lt;/math&amp;gt;&amp;lt;/b&amp;gt;&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;i&amp;gt;Стратерия Forgy&amp;lt;/i&amp;gt;: вычисления не требуются, &amp;lt;math&amp;gt;\Theta_{init}^{k, d, m} = 0&amp;lt;/math&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;i&amp;gt;Стратегия случайного разбиения&amp;lt;/i&amp;gt;: вычисление центров &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластеров,  &amp;lt;math&amp;gt;\Theta_{init}^{k, d, m} = k \cdot \Theta_{centroid}^{d, m}, m \le n&amp;lt;/math&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding-bottom: 20px&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Cложность шага распределения d мерных векторов по &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластерам &amp;amp;ndash; &amp;lt;math&amp;gt;\Theta_{distribute}^{k, d}&amp;lt;/math&amp;gt;&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
На этом шаге для каждого вектора &amp;lt;math&amp;gt;\mathbf{x}_i \in X, i=\overline{1, n}&amp;lt;/math&amp;gt; вычисляется k расстояний до центров кластеров &amp;lt;math&amp;gt;\mathbf{\mu}_1, ...\mathbf{\mu}_k&amp;lt;/math&amp;gt;&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p align=&amp;quot;center&amp;quot;&amp;gt;&lt;br /&gt;
  &amp;lt;math&amp;gt;\Theta_{distribute}^{k, d} = n \cdot k \cdot \Theta_{distance}^d&amp;lt;/math&amp;gt;&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding-bottom: 20px&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;Сложность шага пересчета центров &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластеров размера &amp;lt;math&amp;gt;m&amp;lt;/math&amp;gt; в d-мерном пространстве &amp;amp;ndash; &amp;lt;math&amp;gt;\Theta_{recenter}^{k, d, m}&amp;lt;/math&amp;gt;&amp;lt;/b&amp;gt;&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;На этом шаге вычисляется &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; центров кластеров &amp;lt;math&amp;gt;\mathbf{\mu}_1, ...\mathbf{\mu}_k&amp;lt;/math&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p align=&amp;quot;center&amp;quot;&amp;gt;&amp;lt;math&amp;gt;\Theta_{recenter}^{k, d, m} = k \cdot \Theta_{centroid}^{d, m}&amp;lt;/math&amp;gt; &amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding-bottom: 20px&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Рассчитаем &amp;lt;math&amp;gt;\Theta_{centroid}^{d, m}&amp;lt;/math&amp;gt; для кластера, число элементов которого равно &amp;lt;math&amp;gt;m&amp;lt;/math&amp;gt;&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p align=&amp;quot;center&amp;quot;&amp;gt;&amp;lt;math&amp;gt;\Theta_{centroid}^{d, m}&amp;lt;/math&amp;gt; = &amp;lt;math&amp;gt;m \cdot d&amp;lt;/math&amp;gt; сложений + &amp;lt;math&amp;gt;d&amp;lt;/math&amp;gt; делений &amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding-bottom: 20px&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Рассчитаем &amp;lt;math&amp;gt;\Theta_{distance}^d&amp;lt;/math&amp;gt; в соответствие с формулой &amp;lt;math&amp;gt;(2)&amp;lt;/math&amp;gt;&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p align=&amp;quot;center&amp;quot;&amp;gt;&amp;lt;math&amp;gt;\Theta_{distance}^d&amp;lt;/math&amp;gt; = &amp;lt;math&amp;gt;d&amp;lt;/math&amp;gt; вычитаний + &amp;lt;math&amp;gt;d&amp;lt;/math&amp;gt; умножений + &amp;lt;math&amp;gt;(d-1)&amp;lt;/math&amp;gt; сложение&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding-bottom: 20px&amp;quot;&amp;gt;&lt;br /&gt;
  &amp;lt;p&amp;gt;Предположим, что алгоритм сошелся за &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt; итераций, тогда временная сложность алгоритма &amp;lt;math&amp;gt;\Theta_{k-means}^{d, n}&amp;lt;/math&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
  &amp;lt;p align=&amp;quot;center&amp;quot;&amp;gt;&amp;lt;b&amp;gt;&amp;lt;math&amp;gt;\Theta_{k-means}^{d, n} \le \Theta_{init}^{k, d, n} + i(\Theta_{distribute}^{k, d} + \Theta_{recenter}^{k, d, n})&amp;lt;/math&amp;gt;&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding-bottom: 5px&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;Операции сложения/вычитания:&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p align=&amp;quot;center&amp;quot;&amp;gt;&amp;lt;b&amp;gt;&amp;lt;math&amp;gt;\Theta_{k-means}^{d, n} \le knd+ i(kn(2d-1) + knd) = knd+ i(kn(3d-1)) \thicksim O(ikdn)&amp;lt;/math&amp;gt;&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding-bottom: 20px&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;Операции умножения/деления:&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p align=&amp;quot;center&amp;quot;&amp;gt;&amp;lt;b&amp;gt;&amp;lt;math&amp;gt;\Theta_{k-means}^{d, n} \le kd + i(knd + kd) = kd + ikd(n+1) \thicksim O(ikdn) &amp;lt;/math&amp;gt;&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding-bottom: 20px&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;Получаем, что &amp;lt;b&amp;gt;временная сложность&amp;lt;/b&amp;gt; алгоритма &amp;lt;b&amp;gt;k means&amp;lt;/b&amp;gt; кластеризации &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; &amp;lt;b&amp;gt;d-мерных&amp;lt;/b&amp;gt; векторов на &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластеров за &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt; итераций:&amp;lt;/p&amp;gt;&lt;br /&gt;
 &amp;lt;p align=&amp;quot;center&amp;quot;&amp;gt;&amp;lt;b&amp;gt;&amp;lt;math&amp;gt; \Theta_{k-means}^{d, n} \thicksim O(ikdn) &amp;lt;/math&amp;gt;&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Информационный граф ===&lt;br /&gt;
&lt;br /&gt;
Рассмотрим информационный граф алгоритма. Алгоритм &amp;lt;i&amp;gt;k means&amp;lt;/i&amp;gt; начинается с этапа инициализации, после которого следуют итерации, на каждой из которых выполняется два последовательных шага (см. [[#Схема реализации последовательного алгоритма|&amp;quot;Схема реализации последовательного алгоритма&amp;quot;]]): &lt;br /&gt;
* распределение векторов по кластерам&lt;br /&gt;
* перерасчет центров кластеров&lt;br /&gt;
&lt;br /&gt;
Поскольку основная часть вычислений приходится на шаги итераций, распишем информационные графы данных шагов.&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Распределение векторов по кластерам&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
Информационный граф шага распределения векторов по кластерам представлен на &#039;&#039;рисунке 1&#039;&#039;. Исходами данного графа является исходные векторы &amp;lt;math&amp;gt;\mathbf{x}_1, ..., \mathbf{x}_n&amp;lt;/math&amp;gt;, а также центры кластеров &amp;lt;math&amp;gt;\mathbf{\mu}_1, ... \mathbf{\mu}_k&amp;lt;/math&amp;gt;, вычисленные ранее (на шаге инициализации, если рассматривается первая итерация алгоритма, или на шаге пересчета центров кластеров предыдущей итерации в противном случае). Каждая пара векторов данных &amp;lt;math&amp;gt;\mathbf{x}_i, i=\overline{1,n}&amp;lt;/math&amp;gt; и центров кластера &amp;lt;math&amp;gt;\mathbf{\mu}_j, j=\overline{1, k}&amp;lt;/math&amp;gt; : (&amp;lt;math&amp;gt;\mathbf{x}_i&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;\mathbf{\mu}_j&amp;lt;/math&amp;gt;) подаются на независимые узлы &amp;lt;i&amp;gt;&amp;quot;d&amp;quot;&amp;lt;/i&amp;gt; вычисления расстояния между векторами (более подробная схема вычисления расстояния представлена далее, &#039;&#039;рисунок 2&#039;&#039;). Далее узлы вычисления расстояния &amp;lt;i&amp;gt;&amp;quot;d&amp;quot;&amp;lt;/i&amp;gt;, соответствующие одному и тому же исходному вектору &amp;lt;math&amp;gt;\mathbf{x}_i&amp;lt;/math&amp;gt; передаются на один узел &amp;lt;i&amp;gt;&amp;quot;m&amp;quot;&amp;lt;/i&amp;gt;, где далее происходит вычисление новой метки кластера для каждого вектора &amp;lt;math&amp;gt;\mathbf{x}_i&amp;lt;/math&amp;gt; (берется кластер с минимальным результатом вычисления расстояния). На выходе графа выдаются метки кластеров , &amp;lt;math&amp;gt;L_1, ..., L_n&amp;lt;/math&amp;gt;, такие что &amp;lt;math&amp;gt;\forall \mathbf{x}_i, i=\overline{1, n}, \mathbf{x}_i \in S_j \Leftrightarrow L_i = j&amp;lt;/math&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
[[file:Clusterization.png|thumb|center|800px|Рис. 1. Схема распределения векторов по кластерам. &#039;&#039;d&#039;&#039; &amp;amp;ndash; вычисление расстояния между векторами; &#039;&#039;m&#039;&#039; &amp;amp;ndash; вычисление минимума.]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Вычисление расстояния между векторами&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
Подробная схема вычисления расстояния между векторами &amp;lt;math&amp;gt;\mathbf{x}_i, \mathbf{\mu}_j&amp;lt;/math&amp;gt; представлена на &#039;&#039;рисунке 2&#039;&#039;. Как показано на графе, узел вычисления расстояния между векторами &amp;lt;i&amp;gt;&amp;quot;d&amp;quot;&amp;lt;/i&amp;gt; состоит из шага взятия разности между векторами (узел &amp;quot;&amp;lt;math&amp;gt;-&amp;lt;/math&amp;gt;&amp;quot;) и взятия нормы получившегося вектора разности (узел &amp;quot;&amp;lt;math&amp;gt;||\cdot||^2&amp;lt;/math&amp;gt;&amp;quot;). Более подробно, вычисление расстояния между векторами &amp;lt;math&amp;gt;\mathbf{x}_i = {x_{i1,}, ...,{x_{in}}}, \mathbf{\mu}_j = {\mu_{j1}, ...,\mu_{jn}}&amp;lt;/math&amp;gt; может быть представлено как вычисление разности между каждой парой компонент &amp;lt;math&amp;gt;(x_{iz}, \mu_{jz}), z=\overline{1, d}&amp;lt;/math&amp;gt; (узел &amp;quot;&amp;lt;math&amp;gt;-&amp;lt;/math&amp;gt;&amp;quot;), далее возведение в квадрат для каждого узла &amp;quot;&amp;lt;math&amp;gt;-&amp;lt;/math&amp;gt;&amp;quot; (узел &amp;quot;&amp;lt;math&amp;gt;()^2&amp;lt;/math&amp;gt;&amp;quot;) и суммирования выходов всех узлов &amp;quot;&amp;lt;math&amp;gt;()^2&amp;lt;/math&amp;gt;&amp;quot; (узел &amp;quot;&amp;lt;math&amp;gt;+&amp;lt;/math&amp;gt;&amp;quot;).  &lt;br /&gt;
&lt;br /&gt;
[[file:dist_calc.png|thumb|center|800px|Рис. 2. Схема вычисления расстояния между вектором и центром кластера.]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Пересчет центров кластеров&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
Информационный граф шага пересчета центров кластеров представлен на &#039;&#039;рисунке 3&#039;&#039;. Исходами данного графа является исходные векторы &amp;lt;math&amp;gt;\mathbf{x}_1, ..., \mathbf{x}_n&amp;lt;/math&amp;gt;, а также им соответствующие метки кластера, &amp;lt;math&amp;gt;L_1, ..., L_n&amp;lt;/math&amp;gt;, такие что &amp;lt;math&amp;gt;\forall x_i, i=\overline{1, n}, \mathbf{x}_i \in S_j \Leftrightarrow L_i = j&amp;lt;/math&amp;gt;, вычисленные на этапе распределения векторов по кластерам. Все векторы &amp;lt;math&amp;gt;\mathbf{x}_1, ..., \mathbf{x}_n&amp;lt;/math&amp;gt; подаются в узлы &amp;lt;math&amp;gt;+_1, ...+_k&amp;lt;/math&amp;gt;, каждый узел &amp;lt;math&amp;gt;+_m, m = \overline{1,k}&amp;lt;/math&amp;gt; соответствует операции сложения векторов кластера с номером &amp;lt;math&amp;gt;m&amp;lt;/math&amp;gt;. Метки кластера &amp;lt;math&amp;gt;L_1, ..., L_n&amp;lt;/math&amp;gt; также совместно передаются на узлы &amp;lt;math&amp;gt;S_m, m = \overline{1,k}&amp;lt;/math&amp;gt;, на каждом из которых вычисляется количество векторов в соответствующем кластере (количество меток с соответствующим значением). Далее каждая пара выходов узлов &amp;lt;math&amp;gt;+_m&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;S_m&amp;lt;/math&amp;gt; подается на узел &amp;quot;&amp;lt;math&amp;gt;/&amp;lt;/math&amp;gt;&amp;quot;, где производится деление суммы векторов кластера на количество элементов в нем. Значения, вычисленные на узлах &amp;quot;&amp;lt;math&amp;gt;/&amp;lt;/math&amp;gt;&amp;quot;, присваиваются новым центрам кластеров (выходные значения графа).&lt;br /&gt;
&lt;br /&gt;
[[file:Recluster.png|thumb|center|800px|Рис. 3. Схема пересчета центров кластеров]]&lt;br /&gt;
&lt;br /&gt;
=== Ресурс параллелизма алгоритма ===&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
Работа алгоритма состоит из &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt; итераций, в каждой из которых происходит &amp;lt;b&amp;gt;распределение d-мерных векторов по &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластерам&amp;lt;/b&amp;gt;, а также &amp;lt;b&amp;gt;пересчет центров кластеров в d-мерном пространстве&amp;lt;/b&amp;gt;. В шаге &amp;lt;b&amp;gt;распределения d-мерных векторов по &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластерам&amp;lt;/b&amp;gt; расстояния между вектором и центрами кластеров вычисляются независимо (отсутствуют информационные зависимости). &amp;lt;b&amp;gt;Центры масс кластеров&amp;lt;/b&amp;gt; также пересчитываются независимо друг от друга. Таким образом, имеет место [[глоссарий#Массовый параллелизм|&#039;&#039;массовый параллелизм&#039;&#039;]]. Вычислим параллельную сложность &amp;lt;math&amp;gt;\Psi_*&amp;lt;/math&amp;gt; каждого из шагов, а также параллельную сложность всего алгоритма, &amp;lt;math&amp;gt;\Psi_{k-means}&amp;lt;/math&amp;gt;. Будем исходить из предположения, что может быть использовано любое необходимое число потоков.&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Распределение d-мерных векторов по &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластерам&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;  &lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
Поскольку на данном шаге для каждой пары векторов &amp;lt;math&amp;gt;\mathbf{x}_i, i=\overline{1,n}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\mathbf{\mu}_j, j=\overline{1,k}&amp;lt;/math&amp;gt; операции вычисления расстояния не зависят друг от друга, они могут выполняться параллельно. Тогда, разделив все вычисление расстояний на &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; потоков, получим, что в каждом потоке будет выполняться только одна операция вычисления расстояния между векторами размерности d. При этом каждому вычислительному потоку передаются координаты центров всех кластеров &amp;lt;math&amp;gt;\mathbf{\mu}_1, ..., \mathbf{\mu}_k&amp;lt;/math&amp;gt;. Таким образом, параллельная сложность данного шага определяется &amp;lt;i&amp;gt; сложностью параллельной операции вычисления расстояния между d-мерными векторами&amp;lt;/i&amp;gt;, &amp;lt;math&amp;gt;\Psi_{distance}^d&amp;lt;/math&amp;gt;  и &amp;lt;i&amp;gt;сложностью определения наиболее близкого кластера&amp;lt;/i&amp;gt; (паралельное взятие минимума по расстояниям), &amp;lt;math&amp;gt;\Psi_{min}^k&amp;lt;/math&amp;gt;. Для оценки &amp;lt;math&amp;gt;\Psi_{distance}^d&amp;lt;/math&amp;gt; воспользуемся  [[Нахождение_частных_сумм_элементов_массива_сдваиванием | параллельной реализацией нахождения частичной суммы элементов массива путем сдваивания]]. Аналогично, &amp;lt;math&amp;gt;\Psi_{min}^k = log(k)&amp;lt;/math&amp;gt;. В результате, &amp;lt;math&amp;gt;\Psi_{distance}^d = O(log(d))&amp;lt;/math&amp;gt;.   Таким образом: &lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p align=&amp;quot;center&amp;quot;&amp;gt;&amp;lt;math&amp;gt;\Psi_{distribute}^{k, d}  = \Psi_{distance}^d + \Psi_{min}^k = O(log(d))+O(log(k)) = O(log(kd))&amp;lt;/math&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Пересчет центров кластеров в d-мерном пространстве&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
Поскольку на данном шаге для каждого из &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластеров центр масс может быть вычислен независимо, данные операции могут быть выполнены в отдельных потоках. Таким образом, параллельная сложность данного шага, &amp;lt;math&amp;gt;\Psi_{recenter}^{k, d}&amp;lt;/math&amp;gt;,  будет определяться &amp;lt;i&amp;gt;параллельной сложностью вычисления одного центра масс кластера размера &amp;lt;math&amp;gt;m&amp;lt;/math&amp;gt;&amp;lt;/i&amp;gt;, &amp;lt;math&amp;gt;\Psi_{recenter}^{k, d}&amp;lt;/math&amp;gt;,  а так как &amp;lt;math&amp;gt;m \le n \Rightarrow \Psi_{recenter}^{d, m} \le \Psi_{recenter}^{d, n}&amp;lt;/math&amp;gt;. Сложность вычисления центра масс кластера d-мерных векторов размера n аналогично предыдущим вычислениям равна &amp;lt;math&amp;gt;O(log(n))&amp;lt;/math&amp;gt;. Тогда:  &lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p align=&amp;quot;center&amp;quot;&amp;gt;&amp;lt;math&amp;gt;\Psi_{recenter}^{k, d}  \le \Psi_{recenter}^{d, n} = O(log(n))&amp;lt;/math&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Общая параллельная сложность алгоритма&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
На каждой итерации необходимо обновление центров кластеров, которые будут использованы на следующей итерации. Таким образом, итерационный процесс выполняется последовательно&amp;lt;ref&amp;gt;Zhao, Weizhong, Huifang Ma, and Qing He. &amp;quot;Parallel k-means clustering based on mapreduce.&amp;quot; IEEE International Conference on Cloud Computing. Springer Berlin Heidelberg, 2009.&amp;lt;/ref&amp;gt;. Тогда, поскольку сложность каждой итерации  определяется &amp;lt;math&amp;gt;\Psi_{distribute}^{k, d}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\Psi_{recenter}&amp;lt;/math&amp;gt;, сложность всего алгоритма, &amp;lt;math&amp;gt;\Psi_{k-means}&amp;lt;/math&amp;gt; в предположении, что было сделано &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt; операций определяется выражением&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p align=&amp;quot;center&amp;quot;&amp;gt;&amp;lt;math&amp;gt;\Psi_{k-means} \approx i \cdot (\Psi_{distribute}^{k, d} + \Psi_{recenter}^{k, d}) \le i \cdot O(log(kdn))&amp;lt;/math&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Входные и выходные данные алгоритма ===&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;Входные данные&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;Матрица из &amp;lt;math&amp;gt;n \cdot d&amp;lt;/math&amp;gt; элементов &amp;lt;math&amp;gt;x_{i, j} \in \mathbb{R}, i=\overline{1, n}, j=\overline{1, d}&amp;lt;/math&amp;gt;&amp;amp;ndash; координат векторов (наблюдений).&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;Целое положительное число &amp;lt;math&amp;gt;k, k \le n&amp;lt;/math&amp;gt; &amp;amp;ndash; количество кластеров.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;Объем входных данных&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;math&amp;gt;1&amp;lt;/math&amp;gt; целое число + &amp;lt;math&amp;gt;n \cdot d&amp;lt;/math&amp;gt; вещественных чисел (при условии, что координаты &amp;amp;ndash; вещественные числа).&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;Выходные данные&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; целых положительных чисел &amp;lt;math&amp;gt;L_1, ..., L_n&amp;lt;/math&amp;gt;&amp;amp;ndash; номера кластеров, соотвествующие каждому вектору (при условии, что нумерация кластеров начинается с &amp;lt;math&amp;gt;1&amp;lt;/math&amp;gt;).&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;Объем выходных данных&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; целых положительных чисел.&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Свойства алгоритма ===&lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;[[глоссарий#Вычислительная мощность|&#039;&#039;Вычислительная мощность&#039;&#039;]]&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
Вычислительная мощность алгоритма &amp;lt;i&amp;gt;k means&amp;lt;/i&amp;gt; равна &amp;lt;math&amp;gt;\frac{ikdn}{nd} = ki &amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; &amp;amp;ndash; число кластеров, &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt; &amp;amp;ndash; число итераций алгоритма.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;[[глоссарий#Детерминированность |&#039;&#039;Детерминированность&#039;&#039;]] и [[глоссарий#Устойчивость |&#039;&#039;Устойчивость&#039;&#039;]] &amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
Алгоритм &amp;lt;i&amp;gt;k means&amp;lt;/i&amp;gt; является итерационным. Количество итераций алгоритма в общем случае не фиксируется и зависит от начального расположения объектов в пространстве, параметра &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt;, а также от начального приближения центров кластеров, &amp;lt;math&amp;gt;\mu_1, ..., \mu_k&amp;lt;/math&amp;gt;. В результате этого может варьироваться результат работы алгоритма. При неудачном выборе начальных параметров итерационный процесс может сойтись к локальному оптимуму&amp;lt;ref&amp;gt;Von Luxburg, Ulrike. Clustering Stability. Now Publishers Inc, 2010.&amp;lt;/ref&amp;gt;. По этим причинам алгоритм не является ни &amp;lt;b&amp;gt;детермирированным&amp;lt;/b&amp;gt;, ни &amp;lt;b&amp;gt;устойчивым&amp;lt;/b&amp;gt;.&lt;br /&gt;
 &lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Соотношение последовательной и параллельной сложности алгоритма&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\frac{\Theta_{k-means}}{\Psi_{k-means}} = \frac{O(ikdn)}{O(i \cdot log(kdn))}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Сильные стороны алгоритма&amp;lt;/b&amp;gt;:&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;i&amp;gt;Сравнительно высокая эффективность при простоте реализации&amp;lt;/i&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;i&amp;gt;Высокое качество кластеризации&amp;lt;/i&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;i&amp;gt;Возможность распараллеливания&amp;lt;/i&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;i&amp;gt;Существование множества модификаций&amp;lt;/i&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;Недостатки алгоритма&amp;lt;/b&amp;gt;&amp;lt;ref&amp;gt;Ortega, Joaquín Pérez, Ma Del Rocío Boone Rojas, and María J. Somodevilla. &amp;quot;Research issues on K-means Algorithm: An Experimental Trial Using Matlab.&amp;quot;&amp;lt;/ref&amp;gt;:&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;i&amp;gt;Количество кластеров является параметром алгоритма&amp;lt;/i&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;&amp;lt;i&amp;gt;Чувствительность к начальным условиям&amp;lt;/i&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;Инициализация центров кластеров в значительной степени влияет на результат кластеризации.&amp;lt;/p&amp;gt;&lt;br /&gt;
  &amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;&amp;lt;i&amp;gt;Чувствительность к выбросам и шумам&amp;lt;/i&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;Выбросы, далекие от центров настоящих кластеров, все равно учитываются при вычислении их центров.&amp;lt;/p&amp;gt;&lt;br /&gt;
  &amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;&amp;lt;i&amp;gt;Возможность сходимости к локальному оптимуму&amp;lt;/i&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;Итеративный подход не дает гарантии сходимости к оптимальному решению.&amp;lt;/p&amp;gt;&lt;br /&gt;
  &amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;&amp;lt;i&amp;gt;Использование понятия &amp;quot;среднего&amp;quot;&amp;lt;/i&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;Алгоритм неприменим к данным, для которых не определено понятие &amp;quot;среднего&amp;quot;, например, категориальным данным.&amp;lt;/p&amp;gt;&lt;br /&gt;
  &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&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;
Исследование масштабируемости параллельной реализации алгоритма k means проводилось на суперкомпьютере &amp;quot;Ломоносов&amp;quot;&amp;lt;ref name=&amp;quot;Lom&amp;quot;&amp;gt;Воеводин Вл., Жуматий С., Соболев С., Антонов А., Брызгалов П., Никитенко Д., Стефанов К., Воеводин Вад. Практика суперкомпьютера «Ломоносов» // Открытые системы, 2012, N 7, С. 36-39.&amp;lt;/ref&amp;gt; [http://parallel.ru/cluster Суперкомпьютерного комплекса Московского университета]. Алгоритм реализован на языке C с использованием средств MPI.&lt;br /&gt;
Для исследования масштабируемости проводилось множество запусков программы с разным значением параметра (количество векторов для кластеризации), а также с различным числом процессоров. Фиксировались результаты запусков &amp;amp;ndash; время работы &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt; и количество произведенных итераций алгоритма &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Параметры запусков для экспериментальной оценки:&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;Значения &amp;lt;b&amp;gt;количества векторов&amp;lt;/b&amp;gt; &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;: 20&#039;000, 30&#039;000, 50&#039;000, 100&#039;000, 200&#039;000, 300&#039;000, 500&#039;000, 700&#039;000, 1&#039;000&#039;000, 1&#039;500&#039;000, 2&#039;000&#039;000.&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;Значения &amp;lt;b&amp;gt;количества процессоров&amp;lt;/b&amp;gt; &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt;: 1, 8, 16, 32, 64, 128, 160, 192, 224, 256, 288, 320, 352, 384, 416, 448, 480, 512.&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;Значение &amp;lt;b&amp;gt;количества кластеров&amp;lt;/b&amp;gt; &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt;: 100.&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;Значение &amp;lt;b&amp;gt;размерности векторов&amp;lt;/b&amp;gt; &amp;lt;math&amp;gt;d&amp;lt;/math&amp;gt;: 10.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Для проведения экспериментов были сгенерированы нормально распределенные псевдослучайные данные (с использованием Python библиотеки [http://scikit-learn.org/ scikit-learn]):&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
from sklearn.datasets import make_classification&lt;br /&gt;
X1, Y1 = make_classification(n_features=10, n_redundant=2, n_informative=8,&lt;br /&gt;
                             n_clusters_per_class=1, n_classes=100,&lt;br /&gt;
                             n_samples=2000000)&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Для заданной конфигурации эксперимента (&amp;lt;math&amp;gt;n, d, p, k&amp;lt;/math&amp;gt;) и полученных результатов (&amp;lt;math&amp;gt;t, i&amp;lt;/math&amp;gt;)  [[Глоссарий#Производительность|производительность]]  и эффективность реализации расчитывались по формулам:&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
&amp;lt;ul&amp;gt;&amp;lt;li&amp;gt;&amp;lt;math&amp;gt;Performance = \frac{N_{k-means}^{d, n}}{t}\ \ (FLOPS),&amp;lt;/math&amp;gt;&amp;lt;/li&amp;gt;&amp;lt;/ul&amp;gt;&lt;br /&gt;
где &amp;lt;math&amp;gt;N_{k-means}^{d, n}&amp;lt;/math&amp;gt; &amp;amp;ndash; точное число операций с плавающей точкой (операции с памятью, а также целочисленные операции не учитывались), вычисленное в соответствие с разделом [[#Последовательная сложность алгоритма| &amp;quot;Последовательная сложность алгоритма&amp;quot;]];&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
&amp;lt;ul&amp;gt;&amp;lt;li&amp;gt;&amp;lt;math&amp;gt;Efficiency = \frac{100 \cdot Performance}{Performance_{Peak}^{p}}\ \ (%),&amp;lt;/math&amp;gt;&amp;lt;/li&amp;gt;&amp;lt;/ul&amp;gt;&lt;br /&gt;
где &amp;lt;math&amp;gt;Performance_{Peak}^{p}&amp;lt;/math&amp;gt; &amp;amp;ndash; пиковая производительность суперкомпьютера при &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt; процессорах, вычисленная согласно спецификациям Intel&amp;lt;sup&amp;gt;&amp;amp;reg;&amp;lt;/sup&amp;gt; XEON&amp;lt;sup&amp;gt;&amp;amp;reg;&amp;lt;/sup&amp;gt; X5670&amp;lt;ref&amp;gt;&amp;quot;http://ark.intel.com/ru/products/47920/Intel-Xeon-Processor-X5670-12M-Cache-2_93-GHz-6_40-GTs-Intel-QPI&amp;quot;&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Графики зависимости производительности и эффективности параллельной реализации k means от числа векторов для кластеризации (&amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;) и числа процессоров (&amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt;) представлены на рисунках 4 и 5 соответственно.&lt;br /&gt;
&lt;br /&gt;
[[file:Flops.png|thumb|center|800px|Рис. 4. Параллельная реализация k means. График зависимости производительности реализации алгоритма от числа векторов для кластеризации (&amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;) и числа процессоров (&amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt;).]]&lt;br /&gt;
[[file:Efficiency.png|thumb|center|800px|Рис. 5. Параллельная реализация k means. График зависимости эффективности реализации алгоритма от числа векторов для кластеризации (&amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;) и числа процессоров (&amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt;).]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;В результате&amp;lt;/b&amp;gt; экспериментальной оценки были получены следующие оценки эффективности реализации:&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;b&amp;gt;Минимальное&amp;lt;/b&amp;gt; значение: 0.000409 % достигается при &amp;lt;math&amp;gt;n=20&#039;000, p=480&amp;lt;/math&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;b&amp;gt;Максимальное&amp;lt;/b&amp;gt; значение: 0.741119 % достигается при &amp;lt;math&amp;gt;n=300&#039;000, p=1&amp;lt;/math&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
Оценки масштабируемости реализации алгоритма k means:&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;b&amp;gt;По числу процессоров:&amp;lt;/b&amp;gt; -0.002683 &amp;amp;ndash; эффективность убывает с ростом числа процессоров. Данный результат вызван ростом накладных расходов для обеспечения параллельного выполнения алгоритма.&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;b&amp;gt;По размеру задачи:&amp;lt;/b&amp;gt; 0.002779 &amp;amp;ndash; эффективность растет с ростом числа векторов. Данный результат вызван тем, что при увеличении размера задачи, количество вычислений растет по сравнению с временем, затрачиваемым на пересылку данных.&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;b&amp;gt;Общая оценка:&amp;lt;/b&amp;gt; -0.000058 &amp;amp;ndash; можно сделать вывод, что в целом эффективность реализации незначительно уменьшается с ростом размера задачи и числа процессоров.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[https://github.com/serban/kmeans Использованная параллельная реализация алгоритма k means]&lt;br /&gt;
&lt;br /&gt;
=== Динамические характеристики и эффективность реализации алгоритма ===&lt;br /&gt;
=== Выводы для классов архитектур ===&lt;br /&gt;
=== Существующие реализации алгоритма ===&lt;br /&gt;
==== Открытое программное обеспечение ====&lt;br /&gt;
&amp;lt;ol&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;[https://www.icpsr.umich.edu/CrimeStat/ CrimeStat]&amp;lt;/li&amp;gt; Программное обеспечение, созданное для операционных систем Windows, предоставляющее инструменты статистического  и пространственного анализа для решения задачи картирования преступности.&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://juliastats.github.io Julia]&amp;lt;/li&amp;gt; Высокоуровневый высокопроизводительный свободный язык программирования с динамической типизацией, созданный для математических вычислений, содержит реализацию k-means.&lt;br /&gt;
  &amp;lt;li&amp;gt;[https://mahout.apache.org Mahout]&amp;lt;/li&amp;gt; Apache Mahout - Java библиотека для работы с алгоритмами машинного обучения с использованием MapReduce. Содержит реализацию k-means.&lt;br /&gt;
  &amp;lt;li&amp;gt;[https://www.gnu.org/software/octave/ Octave]&amp;lt;/li&amp;gt; Написанная на C++  свободная система для математических вычислений, использующая совместимый с MATLAB язык высокого уровня, содержит реализацию k-means.&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://spark.apache.org/docs/latest/mllib-clustering.html Spark]&amp;lt;/li&amp;gt; Распределенная реализация k-means содержится в библиотеке Mlib для работы с алгоритмами машинного обучения, взаимодействующая с Python библиотекой NumPy и библиотека R.&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://torch.ch Torch]&amp;lt;/li&amp;gt;  MATLAB-подобная библиотека для языка программирования Lua с открытым исходным кодом, предоставляет большое количество алгоритмов для глубинного обучения и научных расчётов. Ядро написано на Си, прикладная часть выполняется на LuaJIT, поддерживается распараллеливание вычислений средствами CUDA и OpenMP. Существуют реализации k-means.&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://www.cs.waikato.ac.nz/ml/weka/ Weka]&amp;lt;/li&amp;gt;  Cвободное программное обеспечение для анализа данных, написанное на Java. Содержит k-means и x-means.&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://accord-framework.net/docs/html/T_Accord_MachineLearning_KMeans.htm Accord.NET]&amp;lt;/li&amp;gt; C# реализация алгоритмов k-means, k-means++, k-modes.&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://docs.opencv.org/3.0-beta/doc/py_tutorials/py_ml/py_kmeans/py_kmeans_opencv/py_kmeans_opencv.html OpenCV]&amp;lt;/li&amp;gt; Написанная на С++ библиотека, направленная в основном на решение задач компьютерного зрения. Содержит реализацию k-means.&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://mlpack.org/ MLPACK]&amp;lt;/li&amp;gt; Масштабируемая С++ библиотека для работы с алгоритмами машинного обучения, содержит реализацию k-means.&lt;br /&gt;
  &amp;lt;li&amp;gt;[https://www.scipy.org/ SciPy]&amp;lt;/li&amp;gt; Библиотека Python, содержит множество реализаций k-means.&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://scikit-learn.org/ scikit-learn]&amp;lt;/li&amp;gt; Библиотека Python, содержит множество реализаций k-means.&lt;br /&gt;
  &amp;lt;li&amp;gt;[https://www.r-bloggers.com/k-means-clustering-in-r/ R]&amp;lt;/li&amp;gt; Язык программирования для статистической обработки данных и работы с графикой, а также свободная программная среда вычислений с открытым исходным кодом в рамках проекта GNU, содержит три реализации k-means.&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://elki.dbs.ifi.lmu.de ELKI]&amp;lt;/li&amp;gt; Java фреймворк, содержащий реализацию k-means, а также множество других алгоритмов кластеризации.&lt;br /&gt;
&amp;lt;/ol&amp;gt;&lt;br /&gt;
==== Проприетарное программное обеспечение  ====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ol&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;[https://www.ayasdi.com/blog/bigdata/topological-data-analysis-of-oil-and-gas-petrophysical-data/ Ayasdi]&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://www.stata.com/features/cluster-analysis/ Stata]&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://mathworld.wolfram.com/K-MeansClusteringAlgorithm.html Mathematica]&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://www.mathworks.com/help/stats/kmeans.html?requestedDomain=www.mathworks.com MATLAB]&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;[https://support.sas.com/rnd/app/stat/procedures/fastclus.html SAS]&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://docs.rapidminer.com/studio/operators/modeling/segmentation/k_means.html RapidMiner]&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;[https://blogs.sap.com/2013/03/28/sap-hana-pal-k-means-algorithm-or-how-to-do-customer-segmentation-for-the-telecommunications-industry/ SAP HANA]&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ol&amp;gt;&lt;br /&gt;
== Литература ==&lt;br /&gt;
&amp;lt;references /&amp;gt;&lt;/div&gt;</summary>
		<author><name>DennZo1993</name></author>
	</entry>
	<entry>
		<id>https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:%D0%91%D1%80%D0%BE%D1%82%D0%B8%D0%BA%D0%BE%D0%B2%D1%81%D0%BA%D0%B0%D1%8F_%D0%94%D0%B0%D0%BD%D1%83%D1%82%D0%B0/%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_k-means&amp;diff=20530</id>
		<title>Участник:Бротиковская Данута/Алгоритм k-means</title>
		<link rel="alternate" type="text/html" href="https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:%D0%91%D1%80%D0%BE%D1%82%D0%B8%D0%BA%D0%BE%D0%B2%D1%81%D0%BA%D0%B0%D1%8F_%D0%94%D0%B0%D0%BD%D1%83%D1%82%D0%B0/%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_k-means&amp;diff=20530"/>
		<updated>2016-12-10T10:55:06Z</updated>

		<summary type="html">&lt;p&gt;DennZo1993: /* Свойства алгоритма */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Assignment|Zhum}}&lt;br /&gt;
&lt;br /&gt;
{{algorithm&lt;br /&gt;
| name              = Алгоритм k средних (k means)&lt;br /&gt;
| serial_complexity = &amp;lt;math&amp;gt;O(ikdn)&amp;lt;/math&amp;gt;&lt;br /&gt;
| input_data        = &amp;lt;math&amp;gt; dn &amp;lt;/math&amp;gt;&lt;br /&gt;
| output_data       = &amp;lt;math&amp;gt; n &amp;lt;/math&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
Авторы страницы &amp;lt;b&amp;gt;[[Участник:Бротиковская Данута|Данута Бротиковская]]&amp;lt;/b&amp;gt; и &amp;lt;b&amp;gt;[[Участник:DennZo1993|Денис Зобнин]]&amp;lt;/b&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
Оба автора внесли одинаковый вклад в написание статьи (поиск материалов, изучение статей, заполнение контента статьи), четких разграничений по пунктам статьи сделать невозможно. &lt;br /&gt;
&lt;br /&gt;
== Свойства и структура алгоритма ==&lt;br /&gt;
&lt;br /&gt;
=== Общее описание алгоритма ===&lt;br /&gt;
Алгоритм &amp;lt;b&amp;gt;&amp;lt;i&amp;gt;k средних&amp;lt;/i&amp;gt;&amp;lt;/b&amp;gt; (&amp;lt;b&amp;gt;&amp;lt;i&amp;gt;k means&amp;lt;/i&amp;gt;&amp;lt;/b&amp;gt;) &amp;amp;ndash; неиерархический&amp;lt;ref&amp;gt;&amp;quot;https://ru.wikipedia.org/wiki/Иерархическая_кластеризация&amp;quot;&amp;lt;/ref&amp;gt;, итерационный метод кластеризации&amp;lt;ref&amp;gt;&amp;quot;https://ru.wikipedia.org/wiki/Кластерный_анализ&amp;quot;&amp;lt;/ref&amp;gt;, получивший большую популярность благодаря своей простоте, наглядности реализации и достаточно высокому качеству работы. Был изобретен в 1950-х годах математиком &amp;lt;i&amp;gt;Гуго Штейнгаузом&amp;lt;/i&amp;gt;&amp;lt;ref&amp;gt;Steinhaus, Hugo. &amp;quot;Sur la division des corp materiels en parties.&amp;quot; Bull. Acad. Polon. Sci 1.804 (1956): 801.&amp;lt;/ref&amp;gt; и почти одновременно &amp;lt;i&amp;gt;Стюартом Ллойдом&amp;lt;/i&amp;gt;&amp;lt;ref&amp;gt;Lloyd, S. P. &amp;quot;Least square quantization in PCM. Bell Telephone Laboratories Paper. Published in journal much later: Lloyd, SP: Least squares quantization in PCM.&amp;quot; IEEE Trans. Inform. Theor.(1957/1982).&amp;lt;/ref&amp;gt;. Особую популярность приобрел после публикации работы &amp;lt;i&amp;gt;МакКуина&amp;lt;/i&amp;gt;&amp;lt;ref&amp;gt;MacQueen, James. &amp;quot;Some methods for classification and analysis of multivariate observations.&amp;quot; Proceedings of the fifth Berkeley symposium on mathematical statistics and probability. Vol. 1. No. 14. 1967.&amp;lt;/ref&amp;gt; в 1967.&lt;br /&gt;
&lt;br /&gt;
Алгоритм представляет собой версию EM-алгоритма&amp;lt;ref&amp;gt;&amp;quot;https://ru.wikipedia.org/wiki/EM-алгоритм&amp;quot;&amp;lt;/ref&amp;gt;, применяемого также для разделения смеси гауссиан. Основная идея &amp;lt;i&amp;gt;k means&amp;lt;/i&amp;gt; заключается в том, что данные произвольно разбиваются на кластеры, после чего итеративно перевычисляется центр масс для каждого кластера, полученного на предыдущем шаге, затем векторы разбиваются на кластеры вновь в соответствии с тем, какой из новых центров оказался ближе по выбранной метрике.&lt;br /&gt;
&lt;br /&gt;
Цель алгоритма заключается в разделении &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; наблюдений на &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластеров таким образом, чтобы каждое наблюдение принадлежало ровно одному кластеру, расположенному на наименьшем расстоянии от наблюдения.&lt;br /&gt;
&lt;br /&gt;
=== Математическое описание алгоритма ===&lt;br /&gt;
&amp;lt;b&amp;gt;&amp;lt;u&amp;gt;Дано:&amp;lt;/u&amp;gt;&amp;lt;/b&amp;gt;&lt;br /&gt;
* набор из &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; наблюдений &amp;lt;math&amp;gt;X=\{\mathbf{x}_1, \mathbf{x}_2, ..., \mathbf{x}_n\}, \mathbf{x}_i \in \mathbb{R}^d, i=\overline{1, n}&amp;lt;/math&amp;gt;;&lt;br /&gt;
* &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; - требуемое число кластеров, &amp;lt;math&amp;gt;k \in \mathbb{N}, k \leq n&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;&amp;lt;u&amp;gt;Требуется:&amp;lt;/u&amp;gt;&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Разделить множество наблюдений &amp;lt;math&amp;gt;X&amp;lt;/math&amp;gt; на &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластеров &amp;lt;math&amp;gt;S_1, S_2, ..., S_k&amp;lt;/math&amp;gt;:&lt;br /&gt;
*   &amp;lt;math&amp;gt;S_i \cap S_j= \varnothing, \quad i \ne j&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
*   &amp;lt;math&amp;gt;\bigcup_{i=1}^{k} S_i = X&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;&amp;lt;u&amp;gt;Действие алгоритма:&amp;lt;/u&amp;gt;&amp;lt;/b&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;Алгоритм &amp;lt;i&amp;gt;k means&amp;lt;/i&amp;gt; разбивает набор &amp;lt;math&amp;gt;X&amp;lt;/math&amp;gt; на &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; наборов &amp;lt;math&amp;gt;S_1, S_2, ..., S_k,&amp;lt;/math&amp;gt; таким образом, чтобы минимизировать сумму квадратов расстояний от каждой точки кластера до его центра (центр масс кластера). Введем обозначение, &amp;lt;math&amp;gt;S=\{S_1, S_2, ..., S_k\}&amp;lt;/math&amp;gt;. Тогда действие алгоритма &amp;lt;i&amp;gt;k means&amp;lt;/i&amp;gt; равносильно поиску:&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;table style=&amp;quot;width:100%&amp;quot;&amp;gt;&lt;br /&gt;
  &amp;lt;tr&amp;gt;&lt;br /&gt;
    &amp;lt;td align=&amp;quot;center&amp;quot; width=&amp;quot;90%&amp;quot;&amp;gt;&amp;lt;math&amp;gt;\arg\min_{S} \sum\limits_{i=1}^k \sum\limits_{\mathbf{x} \in S_i} \rho(\mathbf{x}, \mathbf{\mu}_i )^2,&amp;lt;/math&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;td align=&amp;quot;right&amp;quot;&amp;gt;&amp;lt;math&amp;gt;(1)&amp;lt;/math&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;/table&amp;gt;&lt;br /&gt;
где &amp;lt;math&amp;gt;\mathbf{\mu}_i&amp;lt;/math&amp;gt; &amp;amp;ndash; центры кластеров, &amp;lt;math&amp;gt;i=\overline{1,k}, \quad \rho(\mathbf{x}, \mathbf{\mu}_i)&amp;lt;/math&amp;gt; &amp;amp;ndash; функция расстояния между &amp;lt;math&amp;gt;\mathbf{x}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\mu_i&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;&amp;lt;u&amp;gt;Шаги алгоритма: &amp;lt;/u&amp;gt;&amp;lt;/b&amp;gt;&lt;br /&gt;
&amp;lt;ol&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&lt;br /&gt;
    &amp;lt;b&amp;gt;Начальный шаг: инициализация кластеров&amp;lt;/b&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;Выбирается произвольное множество точек &amp;lt;math&amp;gt;\mu_i, i=\overline{1,k}&amp;lt;/math&amp;gt;, рассматриваемых как начальные центры кластеров: &amp;lt;math&amp;gt;\mu_i^{(0)} = \mu_i, \quad i=\overline{1, k}&amp;lt;/math&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
  &amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&lt;br /&gt;
    &amp;lt;b&amp;gt;Распределение векторов по кластерам&amp;lt;/b&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Шаг&amp;lt;/b&amp;gt; &amp;lt;math&amp;gt;t: \forall \mathbf{x}_i \in X, i=\overline{1,n}: \mathbf{x}_i \in S_j \iff  j=\arg\min_{k}\rho(\mathbf{x}_i,\mathbf{\mu}_k^{(t-1)})^2&amp;lt;/math&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
  &amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&lt;br /&gt;
    &amp;lt;b&amp;gt;Пересчет центров кластеров&amp;lt;/b&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Шаг &amp;lt;/b&amp;gt; &amp;lt;math&amp;gt;t: \forall i=\overline{1,k}:  \mu_i^{(t)} = \cfrac{1}{|S_i|}\sum_{\mathbf{x}\in S_i}\mathbf{x}&amp;lt;/math&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
  &amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&lt;br /&gt;
    &amp;lt;b&amp;gt;Проверка условия останова:&amp;lt;/b&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
    &#039;&#039;&#039;if&#039;&#039;&#039; &amp;lt;math&amp;gt;\exist i\in \overline{1,k}: \mu_i^{(t)} \ne \mu_i^{(t-1)}&amp;lt;/math&amp;gt; &#039;&#039;&#039;then&#039;&#039;&#039;&lt;br /&gt;
        t = t + 1;&lt;br /&gt;
        goto 2;&lt;br /&gt;
    &#039;&#039;&#039;else&#039;&#039;&#039;&lt;br /&gt;
        &#039;&#039;&#039;stop&#039;&#039;&#039;&lt;br /&gt;
  &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ol&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Вычислительное ядро алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Вычислительным ядром являются шаги 2 и 3 приведенного выше алгоритма: &amp;lt;b&amp;gt;&amp;lt;i&amp;gt;распределение векторов по кластерам&amp;lt;/i&amp;gt;&amp;lt;/b&amp;gt; и &amp;lt;b&amp;gt;&amp;lt;i&amp;gt;пересчет центров кластеров&amp;lt;/i&amp;gt;&amp;lt;/b&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;&amp;lt;i&amp;gt;Распределение векторов&amp;lt;/i&amp;gt;&amp;lt;/b&amp;gt; по кластерам предполагает вычисление расстояний между каждым вектором &amp;lt;math&amp;gt;\mathbf{x}_i \in X, i= \overline{1,n}&amp;lt;/math&amp;gt; и центрами кластера &amp;lt;math&amp;gt;\mathbf{\mu}_j, j= \overline{1,k}&amp;lt;/math&amp;gt;. Таким образом, данный шаг предполагает &amp;lt;math&amp;gt;kn&amp;lt;/math&amp;gt; вычислений расстояний между d-мерными векторами. &lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;&amp;lt;i&amp;gt;Пересчет центров кластеров&amp;lt;/i&amp;gt;&amp;lt;/b&amp;gt; предполагает &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; вычислений центров масс &amp;lt;math&amp;gt;\mathbf{\mu}_i&amp;lt;/math&amp;gt; множеств &amp;lt;math&amp;gt;S_i, i=\overline{1,k}&amp;lt;/math&amp;gt; представленных выражением в шаге 3 представленного выше алгоритма.&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Макроструктура алгоритма ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Инициализация центров масс &amp;lt;math&amp;gt;\mu_1, ..., \mu_k&amp;lt;/math&amp;gt;&amp;lt;/b&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
Наиболее распространенными являются следующие стратегии:&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&lt;br /&gt;
    &amp;lt;b&amp;gt;Метод Forgy&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;В качестве начальных значений &amp;lt;math&amp;gt;\mu_1, ..., \mu_k&amp;lt;/math&amp;gt; берутся случайно выбранные векторы.&lt;br /&gt;
  &amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&lt;br /&gt;
    &amp;lt;b&amp;gt;Метод случайно разделения (Random Partitioning)&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;Для каждого вектора &amp;lt;math&amp;gt;\mathbf{x}_i \in X, i=\overline{1, n}&amp;lt;/math&amp;gt; выбирается случайным образом кластер &amp;lt;math&amp;gt;S_1, ..., S_k&amp;lt;/math&amp;gt;, после чего для каждого полученного кластера вычисляются значения &amp;lt;math&amp;gt;\mu_1, ..., \mu_k&amp;lt;/math&amp;gt;.&lt;br /&gt;
  &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Распределение векторов по кластерам&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Для этого шага алгоритма между векторами &amp;lt;math&amp;gt;\mathbf{x}_i \in X, i=\overline{1, n}&amp;lt;/math&amp;gt; и центрами кластеров &amp;lt;math&amp;gt;\mu_1, ..., \mu_k&amp;lt;/math&amp;gt; вычисляются &amp;lt;b&amp;gt;расстояния&amp;lt;/b&amp;gt; по формуле (как правило, используется Евлидово расстояние):&lt;br /&gt;
&amp;lt;table style=&amp;quot;width:100%&amp;quot;&amp;gt;&lt;br /&gt;
  &amp;lt;tr&amp;gt;&lt;br /&gt;
    &amp;lt;td align=&amp;quot;center&amp;quot; width=&amp;quot;90%&amp;quot;&amp;gt;&amp;lt;math&amp;gt; \mathbf{v}_1, \mathbf{v}_2 \in \mathbb{R}^d,  \quad \rho(\mathbf{v}_1, \mathbf{v}_2) = \lVert \mathbf{v}_1- \mathbf{v}_2 \rVert= \sqrt{\sum_{i=1}^{d}(\mathbf{v}_{1,i} - \mathbf{v}_{2,i})^2}&amp;lt;/math&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;td align=&amp;quot;right&amp;quot;&amp;gt;&amp;lt;math&amp;gt;(2)&amp;lt;/math&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;/table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Пересчет центров кластеров&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Для этого шага алгоритма производится пересчет центров кластера по &amp;lt;b&amp;gt;формуле вычисления центра масс&amp;lt;/b&amp;gt;:&lt;br /&gt;
&amp;lt;table style=&amp;quot;width:100%&amp;quot;&amp;gt;&lt;br /&gt;
  &amp;lt;tr&amp;gt;&lt;br /&gt;
    &amp;lt;td align=&amp;quot;center&amp;quot; width=&amp;quot;90%&amp;quot;&amp;gt;&amp;lt;math&amp;gt; \mu = \cfrac{1}{|S|}\sum_{\mathbf{x}\in S}\mathbf{x}&amp;lt;/math&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;td align=&amp;quot;right&amp;quot;&amp;gt;&amp;lt;math&amp;gt;(3)&amp;lt;/math&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;/table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Схема реализации последовательного алгоритма ===&lt;br /&gt;
&lt;br /&gt;
 &#039;&#039;&#039;algorithm&#039;&#039;&#039; k-means &#039;&#039;&#039;is&#039;&#039;&#039;&lt;br /&gt;
     &#039;&#039;&#039;1.&#039;&#039;&#039; Инициализировать центры кластеров &amp;lt;math&amp;gt;\mathbf{\mu}_i^{(1)}, i=\overline{1,k}&amp;lt;/math&amp;gt;&lt;br /&gt;
     &#039;&#039;&#039;2.&#039;&#039;&#039; &amp;lt;math&amp;gt;t \leftarrow 1&amp;lt;/math&amp;gt;&lt;br /&gt;
     &#039;&#039;&#039;3.&#039;&#039;&#039; &#039;&#039;&#039;Распределение по кластерам&#039;&#039;&#039;&amp;lt;br&amp;gt;&lt;br /&gt;
        &amp;lt;math&amp;gt;S_i^{(t)}=\{\mathbf{x}_p: \lVert\mathbf{x}_p-\mathbf{\mu}_i^{(t)}\rVert^2 \leq \lVert\mathbf{x}_p-\mathbf{\mu}_j^{(t)}\rVert^2 \quad \forall j=\overline{1,k}\},&amp;lt;/math&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
        где каждый вектор &amp;lt;math&amp;gt;\mathbf{x}_p&amp;lt;/math&amp;gt; соотносится единственному кластеру &amp;lt;math&amp;gt;S^{(t)}&amp;lt;/math&amp;gt;&lt;br /&gt;
     &#039;&#039;&#039;4.&#039;&#039;&#039; &#039;&#039;&#039;Обновление центров кластеров&#039;&#039;&#039;&amp;lt;br&amp;gt;&lt;br /&gt;
        &amp;lt;math&amp;gt;\mathbf{\mu}_i^{(t+1)} = \frac{1}{|S^{(t)}_i|} \sum_{\mathbf{x}_j \in S^{(t)}_i} \mathbf{x}_j &amp;lt;/math&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
     &#039;&#039;&#039;5.&#039;&#039;&#039; &#039;&#039;&#039;if&#039;&#039;&#039; &amp;lt;math&amp;gt;\exist i \in \overline{1,k}: \mathbf{\mu}_i^{(t+1)} \ne \mathbf{\mu}_i^{(t)}&amp;lt;/math&amp;gt; &#039;&#039;&#039;then&#039;&#039;&#039;&lt;br /&gt;
            t = t + 1;&lt;br /&gt;
            goto &#039;&#039;&#039;3&#039;&#039;&#039;;&lt;br /&gt;
        &#039;&#039;&#039;else&#039;&#039;&#039;&lt;br /&gt;
            &#039;&#039;&#039;stop&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
=== Последовательная сложность алгоритма===&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding-bottom: 20px&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;Обозначим &amp;lt;math&amp;gt;\Theta_{centroid}^{d, m}&amp;lt;/math&amp;gt; временную сложность вычисления центорида кластера, число элементов которого равна &amp;lt;math&amp;gt;m&amp;lt;/math&amp;gt;,  в d-мерном пространстве.&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;Аналогично  &amp;lt;math&amp;gt;\Theta_{distance}^d&amp;lt;/math&amp;gt; &amp;amp;ndash; временная сложность вычисления расстояния между двумя d-мерными векторами.&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding-bottom: 20px&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;Сложность шага инициализации &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластеров мощности &amp;lt;math&amp;gt;m&amp;lt;/math&amp;gt; в d-мерном пространстве &amp;amp;ndash; &amp;lt;math&amp;gt;\Theta_{init}^{k, d, m}&amp;lt;/math&amp;gt;&amp;lt;/b&amp;gt;&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;i&amp;gt;Стратерия Forgy&amp;lt;/i&amp;gt;: вычисления не требуются, &amp;lt;math&amp;gt;\Theta_{init}^{k, d, m} = 0&amp;lt;/math&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;i&amp;gt;Стратегия случайного разбиения&amp;lt;/i&amp;gt;: вычисление центров &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластеров,  &amp;lt;math&amp;gt;\Theta_{init}^{k, d, m} = k \cdot \Theta_{centroid}^{d, m}, m \le n&amp;lt;/math&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding-bottom: 20px&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Cложность шага распределения d мерных векторов по &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластерам &amp;amp;ndash; &amp;lt;math&amp;gt;\Theta_{distribute}^{k, d}&amp;lt;/math&amp;gt;&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
На этом шаге для каждого вектора &amp;lt;math&amp;gt;\mathbf{x}_i \in X, i=\overline{1, n}&amp;lt;/math&amp;gt; вычисляется k расстояний до центров кластеров &amp;lt;math&amp;gt;\mathbf{\mu}_1, ...\mathbf{\mu}_k&amp;lt;/math&amp;gt;&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p align=&amp;quot;center&amp;quot;&amp;gt;&lt;br /&gt;
  &amp;lt;math&amp;gt;\Theta_{distribute}^{k, d} = n \cdot k \cdot \Theta_{distance}^d&amp;lt;/math&amp;gt;&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding-bottom: 20px&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;Сложность шага пересчета центров &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластеров размера &amp;lt;math&amp;gt;m&amp;lt;/math&amp;gt; в d-мерном пространстве &amp;amp;ndash; &amp;lt;math&amp;gt;\Theta_{recenter}^{k, d, m}&amp;lt;/math&amp;gt;&amp;lt;/b&amp;gt;&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;На этом шаге вычисляется &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; центров кластеров &amp;lt;math&amp;gt;\mathbf{\mu}_1, ...\mathbf{\mu}_k&amp;lt;/math&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p align=&amp;quot;center&amp;quot;&amp;gt;&amp;lt;math&amp;gt;\Theta_{recenter}^{k, d, m} = k \cdot \Theta_{centroid}^{d, m}&amp;lt;/math&amp;gt; &amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding-bottom: 20px&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Рассчитаем &amp;lt;math&amp;gt;\Theta_{centroid}^{d, m}&amp;lt;/math&amp;gt; для кластера, число элементов которого равно &amp;lt;math&amp;gt;m&amp;lt;/math&amp;gt;&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p align=&amp;quot;center&amp;quot;&amp;gt;&amp;lt;math&amp;gt;\Theta_{centroid}^{d, m}&amp;lt;/math&amp;gt; = &amp;lt;math&amp;gt;m \cdot d&amp;lt;/math&amp;gt; сложений + &amp;lt;math&amp;gt;d&amp;lt;/math&amp;gt; делений &amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding-bottom: 20px&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Рассчитаем &amp;lt;math&amp;gt;\Theta_{distance}^d&amp;lt;/math&amp;gt; в соответствие с формулой &amp;lt;math&amp;gt;(2)&amp;lt;/math&amp;gt;&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p align=&amp;quot;center&amp;quot;&amp;gt;&amp;lt;math&amp;gt;\Theta_{distance}^d&amp;lt;/math&amp;gt; = &amp;lt;math&amp;gt;d&amp;lt;/math&amp;gt; вычитаний + &amp;lt;math&amp;gt;d&amp;lt;/math&amp;gt; умножений + &amp;lt;math&amp;gt;(d-1)&amp;lt;/math&amp;gt; сложение&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding-bottom: 20px&amp;quot;&amp;gt;&lt;br /&gt;
  &amp;lt;p&amp;gt;Предположим, что алгоритм сошелся за &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt; итераций, тогда временная сложность алгоритма &amp;lt;math&amp;gt;\Theta_{k-means}^{d, n}&amp;lt;/math&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
  &amp;lt;p align=&amp;quot;center&amp;quot;&amp;gt;&amp;lt;b&amp;gt;&amp;lt;math&amp;gt;\Theta_{k-means}^{d, n} \le \Theta_{init}^{k, d, n} + i(\Theta_{distribute}^{k, d} + \Theta_{recenter}^{k, d, n})&amp;lt;/math&amp;gt;&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding-bottom: 5px&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;Операции сложения/вычитания:&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p align=&amp;quot;center&amp;quot;&amp;gt;&amp;lt;b&amp;gt;&amp;lt;math&amp;gt;\Theta_{k-means}^{d, n} \le knd+ i(kn(2d-1) + knd) = knd+ i(kn(3d-1)) \thicksim O(ikdn)&amp;lt;/math&amp;gt;&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding-bottom: 20px&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;Операции умножения/деления:&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p align=&amp;quot;center&amp;quot;&amp;gt;&amp;lt;b&amp;gt;&amp;lt;math&amp;gt;\Theta_{k-means}^{d, n} \le kd + i(knd + kd) = kd + ikd(n+1) \thicksim O(ikdn) &amp;lt;/math&amp;gt;&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding-bottom: 20px&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;Получаем, что &amp;lt;b&amp;gt;временная сложность&amp;lt;/b&amp;gt; алгоритма &amp;lt;b&amp;gt;k means&amp;lt;/b&amp;gt; кластеризации &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; &amp;lt;b&amp;gt;d-мерных&amp;lt;/b&amp;gt; векторов на &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластеров за &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt; итераций:&amp;lt;/p&amp;gt;&lt;br /&gt;
 &amp;lt;p align=&amp;quot;center&amp;quot;&amp;gt;&amp;lt;b&amp;gt;&amp;lt;math&amp;gt; \Theta_{k-means}^{d, n} \thicksim O(ikdn) &amp;lt;/math&amp;gt;&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Информационный граф ===&lt;br /&gt;
&lt;br /&gt;
Рассмотрим информационный граф алгоритма. Алгоритм &amp;lt;i&amp;gt;k means&amp;lt;/i&amp;gt; начинается с этапа инициализации, после которого следуют итерации, на каждой из которых выполняется два последовательных шага (см. [[#Схема реализации последовательного алгоритма|&amp;quot;Схема реализации последовательного алгоритма&amp;quot;]]): &lt;br /&gt;
* распределение векторов по кластерам&lt;br /&gt;
* перерасчет центров кластеров&lt;br /&gt;
&lt;br /&gt;
Поскольку основная часть вычислений приходится на шаги итераций, распишем информационные графы данных шагов.&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Распределение векторов по кластерам&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
Информационный граф шага распределения векторов по кластерам представлен на &#039;&#039;рисунке 1&#039;&#039;. Исходами данного графа является исходные векторы &amp;lt;math&amp;gt;\mathbf{x}_1, ..., \mathbf{x}_n&amp;lt;/math&amp;gt;, а также центры кластеров &amp;lt;math&amp;gt;\mathbf{\mu}_1, ... \mathbf{\mu}_k&amp;lt;/math&amp;gt;, вычисленные ранее (на шаге инициализации, если рассматривается первая итерация алгоритма, или на шаге пересчета центров кластеров предыдущей итерации в противном случае). Каждая пара векторов данных &amp;lt;math&amp;gt;\mathbf{x}_i, i=\overline{1,n}&amp;lt;/math&amp;gt; и центров кластера &amp;lt;math&amp;gt;\mathbf{\mu}_j, j=\overline{1, k}&amp;lt;/math&amp;gt; : (&amp;lt;math&amp;gt;\mathbf{x}_i&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;\mathbf{\mu}_j&amp;lt;/math&amp;gt;) подаются на независимые узлы &amp;lt;i&amp;gt;&amp;quot;d&amp;quot;&amp;lt;/i&amp;gt; вычисления расстояния между векторами (более подробная схема вычисления расстояния представлена далее, &#039;&#039;рисунок 2&#039;&#039;). Далее узлы вычисления расстояния &amp;lt;i&amp;gt;&amp;quot;d&amp;quot;&amp;lt;/i&amp;gt;, соответствующие одному и тому же исходному вектору &amp;lt;math&amp;gt;\mathbf{x}_i&amp;lt;/math&amp;gt; передаются на один узел &amp;lt;i&amp;gt;&amp;quot;m&amp;quot;&amp;lt;/i&amp;gt;, где далее происходит вычисление новой метки кластера для каждого вектора &amp;lt;math&amp;gt;\mathbf{x}_i&amp;lt;/math&amp;gt; (берется кластер с минимальным результатом вычисления расстояния). На выходе графа выдаются метки кластеров , &amp;lt;math&amp;gt;L_1, ..., L_n&amp;lt;/math&amp;gt;, такие что &amp;lt;math&amp;gt;\forall \mathbf{x}_i, i=\overline{1, n}, \mathbf{x}_i \in S_j \Leftrightarrow L_i = j&amp;lt;/math&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
[[file:Clusterization.png|thumb|center|800px|Рис. 1. Схема распределения векторов по кластерам. &#039;&#039;d&#039;&#039; &amp;amp;ndash; вычисление расстояния между векторами; &#039;&#039;m&#039;&#039; &amp;amp;ndash; вычисление минимума.]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Вычисление расстояния между векторами&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
Подробная схема вычисления расстояния между векторами &amp;lt;math&amp;gt;\mathbf{x}_i, \mathbf{\mu}_j&amp;lt;/math&amp;gt; представлена на &#039;&#039;рисунке 2&#039;&#039;. Как показано на графе, узел вычисления расстояния между векторами &amp;lt;i&amp;gt;&amp;quot;d&amp;quot;&amp;lt;/i&amp;gt; состоит из шага взятия разности между векторами (узел &amp;quot;&amp;lt;math&amp;gt;-&amp;lt;/math&amp;gt;&amp;quot;) и взятия нормы получившегося вектора разности (узел &amp;quot;&amp;lt;math&amp;gt;||\cdot||^2&amp;lt;/math&amp;gt;&amp;quot;). Более подробно, вычисление расстояния между векторами &amp;lt;math&amp;gt;\mathbf{x}_i = {x_{i1,}, ...,{x_{in}}}, \mathbf{\mu}_j = {\mu_{j1}, ...,\mu_{jn}}&amp;lt;/math&amp;gt; может быть представлено как вычисление разности между каждой парой компонент &amp;lt;math&amp;gt;(x_{iz}, \mu_{jz}), z=\overline{1, d}&amp;lt;/math&amp;gt; (узел &amp;quot;&amp;lt;math&amp;gt;-&amp;lt;/math&amp;gt;&amp;quot;), далее возведение в квадрат для каждого узла &amp;quot;&amp;lt;math&amp;gt;-&amp;lt;/math&amp;gt;&amp;quot; (узел &amp;quot;&amp;lt;math&amp;gt;()^2&amp;lt;/math&amp;gt;&amp;quot;) и суммирования выходов всех узлов &amp;quot;&amp;lt;math&amp;gt;()^2&amp;lt;/math&amp;gt;&amp;quot; (узел &amp;quot;&amp;lt;math&amp;gt;+&amp;lt;/math&amp;gt;&amp;quot;).  &lt;br /&gt;
&lt;br /&gt;
[[file:dist_calc.png|thumb|center|800px|Рис. 2. Схема вычисления расстояния между вектором и центром кластера.]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Пересчет центров кластеров&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
Информационный граф шага пересчета центров кластеров представлен на &#039;&#039;рисунке 3&#039;&#039;. Исходами данного графа является исходные векторы &amp;lt;math&amp;gt;\mathbf{x}_1, ..., \mathbf{x}_n&amp;lt;/math&amp;gt;, а также им соответствующие метки кластера, &amp;lt;math&amp;gt;L_1, ..., L_n&amp;lt;/math&amp;gt;, такие что &amp;lt;math&amp;gt;\forall x_i, i=\overline{1, n}, \mathbf{x}_i \in S_j \Leftrightarrow L_i = j&amp;lt;/math&amp;gt;, вычисленные на этапе распределения векторов по кластерам. Все векторы &amp;lt;math&amp;gt;\mathbf{x}_1, ..., \mathbf{x}_n&amp;lt;/math&amp;gt; подаются в узлы &amp;lt;math&amp;gt;+_1, ...+_k&amp;lt;/math&amp;gt;, каждый узел &amp;lt;math&amp;gt;+_m, m = \overline{1,k}&amp;lt;/math&amp;gt; соответствует операции сложения векторов кластера с номером &amp;lt;math&amp;gt;m&amp;lt;/math&amp;gt;. Метки кластера &amp;lt;math&amp;gt;L_1, ..., L_n&amp;lt;/math&amp;gt; также совместно передаются на узлы &amp;lt;math&amp;gt;S_m, m = \overline{1,k}&amp;lt;/math&amp;gt;, на каждом из которых вычисляется количество векторов в соответствующем кластере (количество меток с соответствующим значением). Далее каждая пара выходов узлов &amp;lt;math&amp;gt;+_m&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;S_m&amp;lt;/math&amp;gt; подается на узел &amp;quot;&amp;lt;math&amp;gt;/&amp;lt;/math&amp;gt;&amp;quot;, где производится деление суммы векторов кластера на количество элементов в нем. Значения, вычисленные на узлах &amp;quot;&amp;lt;math&amp;gt;/&amp;lt;/math&amp;gt;&amp;quot;, присваиваются новым центрам кластеров (выходные значения графа).&lt;br /&gt;
&lt;br /&gt;
[[file:Recluster.png|thumb|center|800px|Рис. 3. Схема пересчета центров кластеров]]&lt;br /&gt;
&lt;br /&gt;
=== Ресурс параллелизма алгоритма ===&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
Работа алгоритма состоит из &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt; итераций, в каждой из которых происходит &amp;lt;b&amp;gt;распределение d-мерных векторов по &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластерам&amp;lt;/b&amp;gt;, а также &amp;lt;b&amp;gt;пересчет центров кластеров в d-мерном пространстве&amp;lt;/b&amp;gt;. В шаге &amp;lt;b&amp;gt;распределения d-мерных векторов по &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластерам&amp;lt;/b&amp;gt; расстояния между вектором и центрами кластеров вычисляются независимо (отсутствуют информационные зависимости). &amp;lt;b&amp;gt;Центры масс кластеров&amp;lt;/b&amp;gt; также пересчитываются независимо друг от друга. Таким образом, имеет место [[глоссарий#Массовый параллелизм|&#039;&#039;массовый параллелизм&#039;&#039;]]. Вычислим параллельную сложность &amp;lt;math&amp;gt;\Psi_*&amp;lt;/math&amp;gt; каждого из шагов, а также параллельную сложность всего алгоритма, &amp;lt;math&amp;gt;\Psi_{k-means}&amp;lt;/math&amp;gt;. Будем исходить из предположения, что может быть использовано любое необходимое число потоков.&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Распределение d-мерных векторов по &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластерам&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;  &lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
Поскольку на данном шаге для каждой пары векторов &amp;lt;math&amp;gt;\mathbf{x}_i, i=\overline{1,n}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\mathbf{\mu}_j, j=\overline{1,k}&amp;lt;/math&amp;gt; операции вычисления расстояния не зависят друг от друга, они могут выполняться параллельно. Тогда, разделив все вычисление расстояний на &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; потоков, получим, что в каждом потоке будет выполняться только одна операция вычисления расстояния между векторами размерности d. При этом каждому вычислительному потоку передаются координаты центров всех кластеров &amp;lt;math&amp;gt;\mathbf{\mu}_1, ..., \mathbf{\mu}_k&amp;lt;/math&amp;gt;. Таким образом, параллельная сложность данного шага определяется &amp;lt;i&amp;gt; сложностью параллельной операции вычисления расстояния между d-мерными векторами&amp;lt;/i&amp;gt;, &amp;lt;math&amp;gt;\Psi_{distance}^d&amp;lt;/math&amp;gt;  и &amp;lt;i&amp;gt;сложностью определения наиболее близкого кластера&amp;lt;/i&amp;gt; (паралельное взятие минимума по расстояниям), &amp;lt;math&amp;gt;\Psi_{min}^k&amp;lt;/math&amp;gt;. Для оценки &amp;lt;math&amp;gt;\Psi_{distance}^d&amp;lt;/math&amp;gt; воспользуемся  [[Нахождение_частных_сумм_элементов_массива_сдваиванием | параллельной реализацией нахождения частичной суммы элементов массива путем сдваивания]]. Аналогично, &amp;lt;math&amp;gt;\Psi_{min}^k = log(k)&amp;lt;/math&amp;gt;. В результате, &amp;lt;math&amp;gt;\Psi_{distance}^d = O(log(d))&amp;lt;/math&amp;gt;.   Таким образом: &lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p align=&amp;quot;center&amp;quot;&amp;gt;&amp;lt;math&amp;gt;\Psi_{distribute}^{k, d}  = \Psi_{distance}^d + \Psi_{min}^k = O(log(d))+O(log(k)) = O(log(kd))&amp;lt;/math&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Пересчет центров кластеров в d-мерном пространстве&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
Поскольку на данном шаге для каждого из &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластеров центр масс может быть вычислен независимо, данные операции могут быть выполнены в отдельных потоках. Таким образом, параллельная сложность данного шага, &amp;lt;math&amp;gt;\Psi_{recenter}^{k, d}&amp;lt;/math&amp;gt;,  будет определяться &amp;lt;i&amp;gt;параллельной сложностью вычисления одного центра масс кластера размера &amp;lt;math&amp;gt;m&amp;lt;/math&amp;gt;&amp;lt;/i&amp;gt;, &amp;lt;math&amp;gt;\Psi_{recenter}^{k, d}&amp;lt;/math&amp;gt;,  а так как &amp;lt;math&amp;gt;m \le n \Rightarrow \Psi_{recenter}^{d, m} \le \Psi_{recenter}^{d, n}&amp;lt;/math&amp;gt;. Сложность вычисления центра масс кластера d-мерных векторов размера n аналогично предыдущим вычислениям равна &amp;lt;math&amp;gt;O(log(n))&amp;lt;/math&amp;gt;. Тогда:  &lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p align=&amp;quot;center&amp;quot;&amp;gt;&amp;lt;math&amp;gt;\Psi_{recenter}^{k, d}  \le \Psi_{recenter}^{d, n} = O(log(n))&amp;lt;/math&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Общая параллельная сложность алгоритма&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
На каждой итерации необходимо обновление центров кластеров, которые будут использованы на следующей итерации. Таким образом, итерационный процесс выполняется последовательно&amp;lt;ref&amp;gt;Zhao, Weizhong, Huifang Ma, and Qing He. &amp;quot;Parallel k-means clustering based on mapreduce.&amp;quot; IEEE International Conference on Cloud Computing. Springer Berlin Heidelberg, 2009.&amp;lt;/ref&amp;gt;. Тогда, поскольку сложность каждой итерации  определяется &amp;lt;math&amp;gt;\Psi_{distribute}^{k, d}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\Psi_{recenter}&amp;lt;/math&amp;gt;, сложность всего алгоритма, &amp;lt;math&amp;gt;\Psi_{k-means}&amp;lt;/math&amp;gt; в предположении, что было сделано &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt; операций определяется выражением&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p align=&amp;quot;center&amp;quot;&amp;gt;&amp;lt;math&amp;gt;\Psi_{k-means} \approx i \cdot (\Psi_{distribute}^{k, d} + \Psi_{recenter}^{k, d}) \le i \cdot O(log(kdn))&amp;lt;/math&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Входные и выходные данные алгоритма ===&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;Входные данные&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;Матрица из &amp;lt;math&amp;gt;n \cdot d&amp;lt;/math&amp;gt; элементов &amp;lt;math&amp;gt;x_{i, j} \in \mathbb{R}, i=\overline{1, n}, j=\overline{1, d}&amp;lt;/math&amp;gt;&amp;amp;ndash; координат векторов (наблюдений).&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;Целое положительное число &amp;lt;math&amp;gt;k, k \le n&amp;lt;/math&amp;gt; &amp;amp;ndash; количество кластеров.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;Объем входных данных&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;math&amp;gt;1&amp;lt;/math&amp;gt; целое число + &amp;lt;math&amp;gt;n \cdot d&amp;lt;/math&amp;gt; вещественных чисел (при условии, что координаты &amp;amp;ndash; вещественные числа).&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;Выходные данные&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; целых положительных чисел &amp;lt;math&amp;gt;L_1, ..., L_n&amp;lt;/math&amp;gt;&amp;amp;ndash; номера кластеров, соотвествующие каждому вектору (при условии, что нумерация кластеров начинается с &amp;lt;math&amp;gt;1&amp;lt;/math&amp;gt;).&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;Объем выходных данных&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; целых положительных чисел.&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Свойства алгоритма ===&lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;[[глоссарий#Вычислительная мощность|&#039;&#039;Вычислительная мощность&#039;&#039;]]&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
Вычислительная мощность алгоритма &amp;lt;i&amp;gt;k means&amp;lt;/i&amp;gt; равна &amp;lt;math&amp;gt;\frac{ikdn}{nd} = ki &amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; &amp;amp;ndash; число кластеров, &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt; &amp;amp;ndash; число итераций алгоритма.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;[[глоссарий#Детерминированность |&#039;&#039;Детерминированность&#039;&#039;]] и [[глоссарий#Устойчивость |&#039;&#039;Устойчивость&#039;&#039;]] &amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
Алгоритм &amp;lt;i&amp;gt;k means&amp;lt;/i&amp;gt; является итерационным. Количество итераций алгоритма в общем случае не фиксируется и зависит от начального расположения объектов в пространстве, параметра &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt;, а также от начального приближения центров кластеров, &amp;lt;math&amp;gt;\mu_1, ..., \mu_k&amp;lt;/math&amp;gt;. В результате этого может варьироваться результат работы алгоритма. При неудачном выборе начальных параметров итерационный процесс может сойтись к локальному оптимуму&amp;lt;ref&amp;gt;Von Luxburg, Ulrike. Clustering Stability. Now Publishers Inc, 2010.&amp;lt;/ref&amp;gt;. По этим причинам алгоритм не является ни &amp;lt;b&amp;gt;детермирированным&amp;lt;/b&amp;gt;, ни &amp;lt;b&amp;gt;устойчивым&amp;lt;/b&amp;gt;.&lt;br /&gt;
 &lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Соотношение последовательной и параллельной сложности алгоритма&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\frac{\Theta_{k-means}}{\Psi_{k-means}} = \frac{O(ikdn)}{O(i \cdot log(kdn))}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Сильные стороны алгоритма&amp;lt;/b&amp;gt;:&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;i&amp;gt;Сравнительно высокая эффективность при простоте реализации&amp;lt;/i&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;i&amp;gt;Высокое качество кластеризации&amp;lt;/i&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;i&amp;gt;Возможность распараллеливания&amp;lt;/i&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;i&amp;gt;Существование множества модификаций&amp;lt;/i&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;Недостатки алгоритма&amp;lt;/b&amp;gt;&amp;lt;ref&amp;gt;Ortega, Joaquín Pérez, Ma Del Rocío Boone Rojas, and María J. Somodevilla. &amp;quot;Research issues on K-means Algorithm: An Experimental Trial Using Matlab.&amp;quot;&amp;lt;/ref&amp;gt;:&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;i&amp;gt;Количество кластеров является параметром алгоритма&amp;lt;/i&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;&amp;lt;i&amp;gt;Чувствительность к начальным условиям&amp;lt;/i&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;Инициализация центров кластеров в значительной степени влияет на результат кластеризации.&amp;lt;/p&amp;gt;&lt;br /&gt;
  &amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;&amp;lt;i&amp;gt;Чувствительность к выбросам и шумам&amp;lt;/i&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;Выбросы, далекие от центров настоящих кластеров, все равно учитываются при вычислении их центров.&amp;lt;/p&amp;gt;&lt;br /&gt;
  &amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;&amp;lt;i&amp;gt;Возможность сходимости к локальному оптимуму&amp;lt;/i&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;Итеративный подход не дает гарантии сходимости к оптимальному решению.&amp;lt;/p&amp;gt;&lt;br /&gt;
  &amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;&amp;lt;i&amp;gt;Использование понятия &amp;quot;среднего&amp;quot;&amp;lt;/i&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;Алгоритм неприменим к данным, для которых не определено понятие &amp;quot;среднего&amp;quot;, например, категориальным данным.&amp;lt;/p&amp;gt;&lt;br /&gt;
  &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&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;
Исследование масштабируемости параллельной реализации алгоритма k means проводилось на суперкомпьютере &amp;quot;Ломоносов&amp;quot;&amp;lt;ref name=&amp;quot;Lom&amp;quot;&amp;gt;Воеводин Вл., Жуматий С., Соболев С., Антонов А., Брызгалов П., Никитенко Д., Стефанов К., Воеводин Вад. Практика суперкомпьютера «Ломоносов» // Открытые системы, 2012, N 7, С. 36-39.&amp;lt;/ref&amp;gt; [http://parallel.ru/cluster Суперкомпьютерного комплекса Московского университета]. Алгоритм реализован на языке C с использованием средств MPI.&lt;br /&gt;
Для исследования масштабируемости проводилось множество запусков программы с разным значением параметра (количество векторов для кластеризации), а также с различным числом процессоров. Фиксировались результаты запусков &amp;amp;ndash; время работы &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt; и количество произведенных итераций алгоритма &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Параметры запусков для экспериментальной оценки:&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;Значения &amp;lt;b&amp;gt;количества векторов&amp;lt;/b&amp;gt; &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;: 20&#039;000, 30&#039;000, 50&#039;000, 100&#039;000, 200&#039;000, 300&#039;000, 500&#039;000, 700&#039;000, 1&#039;000&#039;000, 1&#039;500&#039;000, 2&#039;000&#039;000.&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;Значения &amp;lt;b&amp;gt;количества процессоров&amp;lt;/b&amp;gt; &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt;: 1, 8, 16, 32, 64, 128, 160, 192, 224, 256, 288, 320, 352, 384, 416, 448, 480, 512.&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;Значение &amp;lt;b&amp;gt;количества кластеров&amp;lt;/b&amp;gt; &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt;: 100.&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;Значение &amp;lt;b&amp;gt;размерности векторов&amp;lt;/b&amp;gt; &amp;lt;math&amp;gt;d&amp;lt;/math&amp;gt;: 10.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Для проведения экспериментов были сгенерированы нормально распределенные псевдослучайные данные (с использованием Python библиотеки [http://scikit-learn.org/ scikit-learn]):&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
from sklearn.datasets import make_classification&lt;br /&gt;
X1, Y1 = make_classification(n_features=10, n_redundant=2, n_informative=8,&lt;br /&gt;
                             n_clusters_per_class=1, n_classes=100,&lt;br /&gt;
                             n_samples=2000000)&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Для заданной конфигурации эксперимента (&amp;lt;math&amp;gt;n, d, p, k&amp;lt;/math&amp;gt;) и полученных результатов (&amp;lt;math&amp;gt;t, i&amp;lt;/math&amp;gt;)  [[Глоссарий#Производительность|производительность]]  и эффективность реализации расчитывались по формулам:&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
&amp;lt;ul&amp;gt;&amp;lt;li&amp;gt;&amp;lt;math&amp;gt;Performance = \frac{N_{k-means}^{d, n}}{t}\ \ (FLOPS),&amp;lt;/math&amp;gt;&amp;lt;/li&amp;gt;&amp;lt;/ul&amp;gt;&lt;br /&gt;
где &amp;lt;math&amp;gt;N_{k-means}^{d, n}&amp;lt;/math&amp;gt; &amp;amp;ndash; точное число операций с плавающей точкой (операции с памятью, а также целочисленные операции не учитывались), вычисленное в соответствие с разделом [[#Последовательная сложность алгоритма| &amp;quot;Последовательная сложность алгоритма&amp;quot;]];&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
&amp;lt;ul&amp;gt;&amp;lt;li&amp;gt;&amp;lt;math&amp;gt;Efficiency = \frac{100 \cdot Performance}{Performance_{Peak}^{p}}\ \ (%),&amp;lt;/math&amp;gt;&amp;lt;/li&amp;gt;&amp;lt;/ul&amp;gt;&lt;br /&gt;
где &amp;lt;math&amp;gt;Performance_{Peak}^{p}&amp;lt;/math&amp;gt; &amp;amp;ndash; пиковая производительность суперкомпьютера при &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt; процессорах, вычисленная согласно спецификациям Intel&amp;lt;sup&amp;gt;&amp;amp;reg;&amp;lt;/sup&amp;gt; XEON&amp;lt;sup&amp;gt;&amp;amp;reg;&amp;lt;/sup&amp;gt; X5670&amp;lt;ref&amp;gt;&amp;quot;http://ark.intel.com/ru/products/47920/Intel-Xeon-Processor-X5670-12M-Cache-2_93-GHz-6_40-GTs-Intel-QPI&amp;quot;&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Графики зависимости производительности и эффективности параллельной реализации k means от числа векторов для кластеризации (&amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;) и числа процессоров (&amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt;) представлены на рисунках 4 и 5 соответственно.&lt;br /&gt;
&lt;br /&gt;
[[file:Flops.png|thumb|center|800px|Рис. 4. Параллельная реализация k means. График зависимости производительности реализации алгоритма от числа векторов для кластеризации (&amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;) и числа процессоров (&amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt;).]]&lt;br /&gt;
[[file:Efficiency.png|thumb|center|800px|Рис. 5. Параллельная реализация k means. График зависимости эффективности реализации алгоритма от числа векторов для кластеризации (&amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;) и числа процессоров (&amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt;).]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;В результате&amp;lt;/b&amp;gt; экспериментальной оценки были получены следующие оценки эффективности реализации:&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;b&amp;gt;Минимальное&amp;lt;/b&amp;gt; значение: 0.000409 % достигается при &amp;lt;math&amp;gt;n=20&#039;000, p=480&amp;lt;/math&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;b&amp;gt;Максимальное&amp;lt;/b&amp;gt; значение: 0.741119 % достигается при &amp;lt;math&amp;gt;n=300&#039;000, p=1&amp;lt;/math&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
Оценки масштабируемости реализации алгоритма k means:&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;b&amp;gt;По числу процессоров:&amp;lt;/b&amp;gt; -0.002683 &amp;amp;ndash; эффективность убывает с ростом числа процессоров. Данный результат вызван ростом накладных расходов для обеспечения параллельного выполнения алгоритма.&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;b&amp;gt;По размеру задачи:&amp;lt;/b&amp;gt; 0.002779 &amp;amp;ndash; эффективность растет с ростом числа векторов. Данный результат вызван тем, что при увеличении размера задачи, количество вычислений растет по сравнению с временем, затрачиваемым на пересылку данных.&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;b&amp;gt;Общая оценка:&amp;lt;/b&amp;gt; -0.000058 &amp;amp;ndash; можно сделать вывод, что в целом эффективность реализации незначительно уменьшается с ростом размера задачи и числа процессоров.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[https://github.com/serban/kmeans Использованная параллельная реализация алгоритма k means]&lt;br /&gt;
&lt;br /&gt;
=== Динамические характеристики и эффективность реализации алгоритма ===&lt;br /&gt;
=== Выводы для классов архитектур ===&lt;br /&gt;
=== Существующие реализации алгоритма ===&lt;br /&gt;
==== Открытое программное обеспечение ====&lt;br /&gt;
&amp;lt;ol&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;[https://www.icpsr.umich.edu/CrimeStat/ CrimeStat]&amp;lt;/li&amp;gt; Программное обеспечение, созданное для операционных систем Windows, предоставляющее инструменты статистического  и пространственного анализа для решения задачи картирования преступности.&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://juliastats.github.io Julia]&amp;lt;/li&amp;gt; Высокоуровневый высокопроизводительный свободный язык программирования с динамической типизацией, созданный для математических вычислений, содержит реализацию k-means.&lt;br /&gt;
  &amp;lt;li&amp;gt;[https://mahout.apache.org Mahout]&amp;lt;/li&amp;gt; Apache Mahout - Java библиотека для работы с алгоритмами машинного обучения с использованием MapReduce. Содержит реализацию k-means.&lt;br /&gt;
  &amp;lt;li&amp;gt;[https://www.gnu.org/software/octave/ Octave]&amp;lt;/li&amp;gt; Написанная на C++  свободная система для математических вычислений, использующая совместимый с MATLAB язык высокого уровня, содержит реализацию k-means.&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://spark.apache.org/docs/latest/mllib-clustering.html Spark]&amp;lt;/li&amp;gt; Распределенная реализация k-means содержится в библиотеке Mlib для работы с алгоритмами машинного обучения, взаимодействующая с Python библиотекой NumPy и библиотека R.&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://torch.ch Torch]&amp;lt;/li&amp;gt;  MATLAB-подобная библиотека для языка программирования Lua с открытым исходным кодом, предоставляет большое количество алгоритмов для глубинного обучения и научных расчётов. Ядро написано на Си, прикладная часть выполняется на LuaJIT, поддерживается распараллеливание вычислений средствами CUDA и OpenMP. Существуют реализации k-means.&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://www.cs.waikato.ac.nz/ml/weka/ Weka]&amp;lt;/li&amp;gt;  Cвободное программное обеспечение для анализа данных, написанное на Java. Содержит k-means и x-means.&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://accord-framework.net/docs/html/T_Accord_MachineLearning_KMeans.htm Accord.NET]&amp;lt;/li&amp;gt; C# реализация алгоритмов k-means, k-means++, k-modes.&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://docs.opencv.org/3.0-beta/doc/py_tutorials/py_ml/py_kmeans/py_kmeans_opencv/py_kmeans_opencv.html OpenCV]&amp;lt;/li&amp;gt; Написанная на С++ библиотека, направленная в основном на решение задач компьютерного зрения. Содержит реализацию k-means.&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://mlpack.org/ MLPACK]&amp;lt;/li&amp;gt; Масштабируемая С++ библиотека для работы с алгоритмами машинного обучения, содержит реализацию k-means.&lt;br /&gt;
  &amp;lt;li&amp;gt;[https://www.scipy.org/ SciPy]&amp;lt;/li&amp;gt; Библиотека Python, содержит множество реализаций k-means.&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://scikit-learn.org/ scikit-learn]&amp;lt;/li&amp;gt; Библиотека Python, содержит множество реализаций k-means.&lt;br /&gt;
  &amp;lt;li&amp;gt;[https://www.r-bloggers.com/k-means-clustering-in-r/ R]&amp;lt;/li&amp;gt; Язык программирования для статистической обработки данных и работы с графикой, а также свободная программная среда вычислений с открытым исходным кодом в рамках проекта GNU, содержит три реализации k-means.&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://elki.dbs.ifi.lmu.de ELKI]&amp;lt;/li&amp;gt; Java фреймворк, содержащий реализацию k-means, а также множество других алгоритмов кластеризации.&lt;br /&gt;
&amp;lt;/ol&amp;gt;&lt;br /&gt;
==== Проприетарное программное обеспечение  ====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ol&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;[https://www.ayasdi.com/blog/bigdata/topological-data-analysis-of-oil-and-gas-petrophysical-data/ Ayasdi]&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://www.stata.com/features/cluster-analysis/ Stata]&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://mathworld.wolfram.com/K-MeansClusteringAlgorithm.html Mathematica]&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://www.mathworks.com/help/stats/kmeans.html?requestedDomain=www.mathworks.com MATLAB]&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;[https://support.sas.com/rnd/app/stat/procedures/fastclus.html SAS]&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://docs.rapidminer.com/studio/operators/modeling/segmentation/k_means.html RapidMiner]&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;[https://blogs.sap.com/2013/03/28/sap-hana-pal-k-means-algorithm-or-how-to-do-customer-segmentation-for-the-telecommunications-industry/ SAP HANA]&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ol&amp;gt;&lt;br /&gt;
== Литература ==&lt;br /&gt;
&amp;lt;references /&amp;gt;&lt;/div&gt;</summary>
		<author><name>DennZo1993</name></author>
	</entry>
	<entry>
		<id>https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:%D0%91%D1%80%D0%BE%D1%82%D0%B8%D0%BA%D0%BE%D0%B2%D1%81%D0%BA%D0%B0%D1%8F_%D0%94%D0%B0%D0%BD%D1%83%D1%82%D0%B0/%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_k-means&amp;diff=20529</id>
		<title>Участник:Бротиковская Данута/Алгоритм k-means</title>
		<link rel="alternate" type="text/html" href="https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:%D0%91%D1%80%D0%BE%D1%82%D0%B8%D0%BA%D0%BE%D0%B2%D1%81%D0%BA%D0%B0%D1%8F_%D0%94%D0%B0%D0%BD%D1%83%D1%82%D0%B0/%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_k-means&amp;diff=20529"/>
		<updated>2016-12-10T10:54:12Z</updated>

		<summary type="html">&lt;p&gt;DennZo1993: /* Ресурс параллелизма алгоритма */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Assignment|Zhum}}&lt;br /&gt;
&lt;br /&gt;
{{algorithm&lt;br /&gt;
| name              = Алгоритм k средних (k means)&lt;br /&gt;
| serial_complexity = &amp;lt;math&amp;gt;O(ikdn)&amp;lt;/math&amp;gt;&lt;br /&gt;
| input_data        = &amp;lt;math&amp;gt; dn &amp;lt;/math&amp;gt;&lt;br /&gt;
| output_data       = &amp;lt;math&amp;gt; n &amp;lt;/math&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
Авторы страницы &amp;lt;b&amp;gt;[[Участник:Бротиковская Данута|Данута Бротиковская]]&amp;lt;/b&amp;gt; и &amp;lt;b&amp;gt;[[Участник:DennZo1993|Денис Зобнин]]&amp;lt;/b&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
Оба автора внесли одинаковый вклад в написание статьи (поиск материалов, изучение статей, заполнение контента статьи), четких разграничений по пунктам статьи сделать невозможно. &lt;br /&gt;
&lt;br /&gt;
== Свойства и структура алгоритма ==&lt;br /&gt;
&lt;br /&gt;
=== Общее описание алгоритма ===&lt;br /&gt;
Алгоритм &amp;lt;b&amp;gt;&amp;lt;i&amp;gt;k средних&amp;lt;/i&amp;gt;&amp;lt;/b&amp;gt; (&amp;lt;b&amp;gt;&amp;lt;i&amp;gt;k means&amp;lt;/i&amp;gt;&amp;lt;/b&amp;gt;) &amp;amp;ndash; неиерархический&amp;lt;ref&amp;gt;&amp;quot;https://ru.wikipedia.org/wiki/Иерархическая_кластеризация&amp;quot;&amp;lt;/ref&amp;gt;, итерационный метод кластеризации&amp;lt;ref&amp;gt;&amp;quot;https://ru.wikipedia.org/wiki/Кластерный_анализ&amp;quot;&amp;lt;/ref&amp;gt;, получивший большую популярность благодаря своей простоте, наглядности реализации и достаточно высокому качеству работы. Был изобретен в 1950-х годах математиком &amp;lt;i&amp;gt;Гуго Штейнгаузом&amp;lt;/i&amp;gt;&amp;lt;ref&amp;gt;Steinhaus, Hugo. &amp;quot;Sur la division des corp materiels en parties.&amp;quot; Bull. Acad. Polon. Sci 1.804 (1956): 801.&amp;lt;/ref&amp;gt; и почти одновременно &amp;lt;i&amp;gt;Стюартом Ллойдом&amp;lt;/i&amp;gt;&amp;lt;ref&amp;gt;Lloyd, S. P. &amp;quot;Least square quantization in PCM. Bell Telephone Laboratories Paper. Published in journal much later: Lloyd, SP: Least squares quantization in PCM.&amp;quot; IEEE Trans. Inform. Theor.(1957/1982).&amp;lt;/ref&amp;gt;. Особую популярность приобрел после публикации работы &amp;lt;i&amp;gt;МакКуина&amp;lt;/i&amp;gt;&amp;lt;ref&amp;gt;MacQueen, James. &amp;quot;Some methods for classification and analysis of multivariate observations.&amp;quot; Proceedings of the fifth Berkeley symposium on mathematical statistics and probability. Vol. 1. No. 14. 1967.&amp;lt;/ref&amp;gt; в 1967.&lt;br /&gt;
&lt;br /&gt;
Алгоритм представляет собой версию EM-алгоритма&amp;lt;ref&amp;gt;&amp;quot;https://ru.wikipedia.org/wiki/EM-алгоритм&amp;quot;&amp;lt;/ref&amp;gt;, применяемого также для разделения смеси гауссиан. Основная идея &amp;lt;i&amp;gt;k means&amp;lt;/i&amp;gt; заключается в том, что данные произвольно разбиваются на кластеры, после чего итеративно перевычисляется центр масс для каждого кластера, полученного на предыдущем шаге, затем векторы разбиваются на кластеры вновь в соответствии с тем, какой из новых центров оказался ближе по выбранной метрике.&lt;br /&gt;
&lt;br /&gt;
Цель алгоритма заключается в разделении &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; наблюдений на &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластеров таким образом, чтобы каждое наблюдение принадлежало ровно одному кластеру, расположенному на наименьшем расстоянии от наблюдения.&lt;br /&gt;
&lt;br /&gt;
=== Математическое описание алгоритма ===&lt;br /&gt;
&amp;lt;b&amp;gt;&amp;lt;u&amp;gt;Дано:&amp;lt;/u&amp;gt;&amp;lt;/b&amp;gt;&lt;br /&gt;
* набор из &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; наблюдений &amp;lt;math&amp;gt;X=\{\mathbf{x}_1, \mathbf{x}_2, ..., \mathbf{x}_n\}, \mathbf{x}_i \in \mathbb{R}^d, i=\overline{1, n}&amp;lt;/math&amp;gt;;&lt;br /&gt;
* &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; - требуемое число кластеров, &amp;lt;math&amp;gt;k \in \mathbb{N}, k \leq n&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;&amp;lt;u&amp;gt;Требуется:&amp;lt;/u&amp;gt;&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Разделить множество наблюдений &amp;lt;math&amp;gt;X&amp;lt;/math&amp;gt; на &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластеров &amp;lt;math&amp;gt;S_1, S_2, ..., S_k&amp;lt;/math&amp;gt;:&lt;br /&gt;
*   &amp;lt;math&amp;gt;S_i \cap S_j= \varnothing, \quad i \ne j&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
*   &amp;lt;math&amp;gt;\bigcup_{i=1}^{k} S_i = X&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;&amp;lt;u&amp;gt;Действие алгоритма:&amp;lt;/u&amp;gt;&amp;lt;/b&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;Алгоритм &amp;lt;i&amp;gt;k means&amp;lt;/i&amp;gt; разбивает набор &amp;lt;math&amp;gt;X&amp;lt;/math&amp;gt; на &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; наборов &amp;lt;math&amp;gt;S_1, S_2, ..., S_k,&amp;lt;/math&amp;gt; таким образом, чтобы минимизировать сумму квадратов расстояний от каждой точки кластера до его центра (центр масс кластера). Введем обозначение, &amp;lt;math&amp;gt;S=\{S_1, S_2, ..., S_k\}&amp;lt;/math&amp;gt;. Тогда действие алгоритма &amp;lt;i&amp;gt;k means&amp;lt;/i&amp;gt; равносильно поиску:&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;table style=&amp;quot;width:100%&amp;quot;&amp;gt;&lt;br /&gt;
  &amp;lt;tr&amp;gt;&lt;br /&gt;
    &amp;lt;td align=&amp;quot;center&amp;quot; width=&amp;quot;90%&amp;quot;&amp;gt;&amp;lt;math&amp;gt;\arg\min_{S} \sum\limits_{i=1}^k \sum\limits_{\mathbf{x} \in S_i} \rho(\mathbf{x}, \mathbf{\mu}_i )^2,&amp;lt;/math&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;td align=&amp;quot;right&amp;quot;&amp;gt;&amp;lt;math&amp;gt;(1)&amp;lt;/math&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;/table&amp;gt;&lt;br /&gt;
где &amp;lt;math&amp;gt;\mathbf{\mu}_i&amp;lt;/math&amp;gt; &amp;amp;ndash; центры кластеров, &amp;lt;math&amp;gt;i=\overline{1,k}, \quad \rho(\mathbf{x}, \mathbf{\mu}_i)&amp;lt;/math&amp;gt; &amp;amp;ndash; функция расстояния между &amp;lt;math&amp;gt;\mathbf{x}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\mu_i&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;&amp;lt;u&amp;gt;Шаги алгоритма: &amp;lt;/u&amp;gt;&amp;lt;/b&amp;gt;&lt;br /&gt;
&amp;lt;ol&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&lt;br /&gt;
    &amp;lt;b&amp;gt;Начальный шаг: инициализация кластеров&amp;lt;/b&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;Выбирается произвольное множество точек &amp;lt;math&amp;gt;\mu_i, i=\overline{1,k}&amp;lt;/math&amp;gt;, рассматриваемых как начальные центры кластеров: &amp;lt;math&amp;gt;\mu_i^{(0)} = \mu_i, \quad i=\overline{1, k}&amp;lt;/math&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
  &amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&lt;br /&gt;
    &amp;lt;b&amp;gt;Распределение векторов по кластерам&amp;lt;/b&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Шаг&amp;lt;/b&amp;gt; &amp;lt;math&amp;gt;t: \forall \mathbf{x}_i \in X, i=\overline{1,n}: \mathbf{x}_i \in S_j \iff  j=\arg\min_{k}\rho(\mathbf{x}_i,\mathbf{\mu}_k^{(t-1)})^2&amp;lt;/math&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
  &amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&lt;br /&gt;
    &amp;lt;b&amp;gt;Пересчет центров кластеров&amp;lt;/b&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Шаг &amp;lt;/b&amp;gt; &amp;lt;math&amp;gt;t: \forall i=\overline{1,k}:  \mu_i^{(t)} = \cfrac{1}{|S_i|}\sum_{\mathbf{x}\in S_i}\mathbf{x}&amp;lt;/math&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
  &amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&lt;br /&gt;
    &amp;lt;b&amp;gt;Проверка условия останова:&amp;lt;/b&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
    &#039;&#039;&#039;if&#039;&#039;&#039; &amp;lt;math&amp;gt;\exist i\in \overline{1,k}: \mu_i^{(t)} \ne \mu_i^{(t-1)}&amp;lt;/math&amp;gt; &#039;&#039;&#039;then&#039;&#039;&#039;&lt;br /&gt;
        t = t + 1;&lt;br /&gt;
        goto 2;&lt;br /&gt;
    &#039;&#039;&#039;else&#039;&#039;&#039;&lt;br /&gt;
        &#039;&#039;&#039;stop&#039;&#039;&#039;&lt;br /&gt;
  &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ol&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Вычислительное ядро алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Вычислительным ядром являются шаги 2 и 3 приведенного выше алгоритма: &amp;lt;b&amp;gt;&amp;lt;i&amp;gt;распределение векторов по кластерам&amp;lt;/i&amp;gt;&amp;lt;/b&amp;gt; и &amp;lt;b&amp;gt;&amp;lt;i&amp;gt;пересчет центров кластеров&amp;lt;/i&amp;gt;&amp;lt;/b&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;&amp;lt;i&amp;gt;Распределение векторов&amp;lt;/i&amp;gt;&amp;lt;/b&amp;gt; по кластерам предполагает вычисление расстояний между каждым вектором &amp;lt;math&amp;gt;\mathbf{x}_i \in X, i= \overline{1,n}&amp;lt;/math&amp;gt; и центрами кластера &amp;lt;math&amp;gt;\mathbf{\mu}_j, j= \overline{1,k}&amp;lt;/math&amp;gt;. Таким образом, данный шаг предполагает &amp;lt;math&amp;gt;kn&amp;lt;/math&amp;gt; вычислений расстояний между d-мерными векторами. &lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;&amp;lt;i&amp;gt;Пересчет центров кластеров&amp;lt;/i&amp;gt;&amp;lt;/b&amp;gt; предполагает &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; вычислений центров масс &amp;lt;math&amp;gt;\mathbf{\mu}_i&amp;lt;/math&amp;gt; множеств &amp;lt;math&amp;gt;S_i, i=\overline{1,k}&amp;lt;/math&amp;gt; представленных выражением в шаге 3 представленного выше алгоритма.&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Макроструктура алгоритма ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Инициализация центров масс &amp;lt;math&amp;gt;\mu_1, ..., \mu_k&amp;lt;/math&amp;gt;&amp;lt;/b&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
Наиболее распространенными являются следующие стратегии:&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&lt;br /&gt;
    &amp;lt;b&amp;gt;Метод Forgy&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;В качестве начальных значений &amp;lt;math&amp;gt;\mu_1, ..., \mu_k&amp;lt;/math&amp;gt; берутся случайно выбранные векторы.&lt;br /&gt;
  &amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&lt;br /&gt;
    &amp;lt;b&amp;gt;Метод случайно разделения (Random Partitioning)&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;Для каждого вектора &amp;lt;math&amp;gt;\mathbf{x}_i \in X, i=\overline{1, n}&amp;lt;/math&amp;gt; выбирается случайным образом кластер &amp;lt;math&amp;gt;S_1, ..., S_k&amp;lt;/math&amp;gt;, после чего для каждого полученного кластера вычисляются значения &amp;lt;math&amp;gt;\mu_1, ..., \mu_k&amp;lt;/math&amp;gt;.&lt;br /&gt;
  &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Распределение векторов по кластерам&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Для этого шага алгоритма между векторами &amp;lt;math&amp;gt;\mathbf{x}_i \in X, i=\overline{1, n}&amp;lt;/math&amp;gt; и центрами кластеров &amp;lt;math&amp;gt;\mu_1, ..., \mu_k&amp;lt;/math&amp;gt; вычисляются &amp;lt;b&amp;gt;расстояния&amp;lt;/b&amp;gt; по формуле (как правило, используется Евлидово расстояние):&lt;br /&gt;
&amp;lt;table style=&amp;quot;width:100%&amp;quot;&amp;gt;&lt;br /&gt;
  &amp;lt;tr&amp;gt;&lt;br /&gt;
    &amp;lt;td align=&amp;quot;center&amp;quot; width=&amp;quot;90%&amp;quot;&amp;gt;&amp;lt;math&amp;gt; \mathbf{v}_1, \mathbf{v}_2 \in \mathbb{R}^d,  \quad \rho(\mathbf{v}_1, \mathbf{v}_2) = \lVert \mathbf{v}_1- \mathbf{v}_2 \rVert= \sqrt{\sum_{i=1}^{d}(\mathbf{v}_{1,i} - \mathbf{v}_{2,i})^2}&amp;lt;/math&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;td align=&amp;quot;right&amp;quot;&amp;gt;&amp;lt;math&amp;gt;(2)&amp;lt;/math&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;/table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Пересчет центров кластеров&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Для этого шага алгоритма производится пересчет центров кластера по &amp;lt;b&amp;gt;формуле вычисления центра масс&amp;lt;/b&amp;gt;:&lt;br /&gt;
&amp;lt;table style=&amp;quot;width:100%&amp;quot;&amp;gt;&lt;br /&gt;
  &amp;lt;tr&amp;gt;&lt;br /&gt;
    &amp;lt;td align=&amp;quot;center&amp;quot; width=&amp;quot;90%&amp;quot;&amp;gt;&amp;lt;math&amp;gt; \mu = \cfrac{1}{|S|}\sum_{\mathbf{x}\in S}\mathbf{x}&amp;lt;/math&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;td align=&amp;quot;right&amp;quot;&amp;gt;&amp;lt;math&amp;gt;(3)&amp;lt;/math&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;/table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Схема реализации последовательного алгоритма ===&lt;br /&gt;
&lt;br /&gt;
 &#039;&#039;&#039;algorithm&#039;&#039;&#039; k-means &#039;&#039;&#039;is&#039;&#039;&#039;&lt;br /&gt;
     &#039;&#039;&#039;1.&#039;&#039;&#039; Инициализировать центры кластеров &amp;lt;math&amp;gt;\mathbf{\mu}_i^{(1)}, i=\overline{1,k}&amp;lt;/math&amp;gt;&lt;br /&gt;
     &#039;&#039;&#039;2.&#039;&#039;&#039; &amp;lt;math&amp;gt;t \leftarrow 1&amp;lt;/math&amp;gt;&lt;br /&gt;
     &#039;&#039;&#039;3.&#039;&#039;&#039; &#039;&#039;&#039;Распределение по кластерам&#039;&#039;&#039;&amp;lt;br&amp;gt;&lt;br /&gt;
        &amp;lt;math&amp;gt;S_i^{(t)}=\{\mathbf{x}_p: \lVert\mathbf{x}_p-\mathbf{\mu}_i^{(t)}\rVert^2 \leq \lVert\mathbf{x}_p-\mathbf{\mu}_j^{(t)}\rVert^2 \quad \forall j=\overline{1,k}\},&amp;lt;/math&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
        где каждый вектор &amp;lt;math&amp;gt;\mathbf{x}_p&amp;lt;/math&amp;gt; соотносится единственному кластеру &amp;lt;math&amp;gt;S^{(t)}&amp;lt;/math&amp;gt;&lt;br /&gt;
     &#039;&#039;&#039;4.&#039;&#039;&#039; &#039;&#039;&#039;Обновление центров кластеров&#039;&#039;&#039;&amp;lt;br&amp;gt;&lt;br /&gt;
        &amp;lt;math&amp;gt;\mathbf{\mu}_i^{(t+1)} = \frac{1}{|S^{(t)}_i|} \sum_{\mathbf{x}_j \in S^{(t)}_i} \mathbf{x}_j &amp;lt;/math&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
     &#039;&#039;&#039;5.&#039;&#039;&#039; &#039;&#039;&#039;if&#039;&#039;&#039; &amp;lt;math&amp;gt;\exist i \in \overline{1,k}: \mathbf{\mu}_i^{(t+1)} \ne \mathbf{\mu}_i^{(t)}&amp;lt;/math&amp;gt; &#039;&#039;&#039;then&#039;&#039;&#039;&lt;br /&gt;
            t = t + 1;&lt;br /&gt;
            goto &#039;&#039;&#039;3&#039;&#039;&#039;;&lt;br /&gt;
        &#039;&#039;&#039;else&#039;&#039;&#039;&lt;br /&gt;
            &#039;&#039;&#039;stop&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
=== Последовательная сложность алгоритма===&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding-bottom: 20px&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;Обозначим &amp;lt;math&amp;gt;\Theta_{centroid}^{d, m}&amp;lt;/math&amp;gt; временную сложность вычисления центорида кластера, число элементов которого равна &amp;lt;math&amp;gt;m&amp;lt;/math&amp;gt;,  в d-мерном пространстве.&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;Аналогично  &amp;lt;math&amp;gt;\Theta_{distance}^d&amp;lt;/math&amp;gt; &amp;amp;ndash; временная сложность вычисления расстояния между двумя d-мерными векторами.&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding-bottom: 20px&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;Сложность шага инициализации &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластеров мощности &amp;lt;math&amp;gt;m&amp;lt;/math&amp;gt; в d-мерном пространстве &amp;amp;ndash; &amp;lt;math&amp;gt;\Theta_{init}^{k, d, m}&amp;lt;/math&amp;gt;&amp;lt;/b&amp;gt;&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;i&amp;gt;Стратерия Forgy&amp;lt;/i&amp;gt;: вычисления не требуются, &amp;lt;math&amp;gt;\Theta_{init}^{k, d, m} = 0&amp;lt;/math&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;i&amp;gt;Стратегия случайного разбиения&amp;lt;/i&amp;gt;: вычисление центров &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластеров,  &amp;lt;math&amp;gt;\Theta_{init}^{k, d, m} = k \cdot \Theta_{centroid}^{d, m}, m \le n&amp;lt;/math&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding-bottom: 20px&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Cложность шага распределения d мерных векторов по &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластерам &amp;amp;ndash; &amp;lt;math&amp;gt;\Theta_{distribute}^{k, d}&amp;lt;/math&amp;gt;&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
На этом шаге для каждого вектора &amp;lt;math&amp;gt;\mathbf{x}_i \in X, i=\overline{1, n}&amp;lt;/math&amp;gt; вычисляется k расстояний до центров кластеров &amp;lt;math&amp;gt;\mathbf{\mu}_1, ...\mathbf{\mu}_k&amp;lt;/math&amp;gt;&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p align=&amp;quot;center&amp;quot;&amp;gt;&lt;br /&gt;
  &amp;lt;math&amp;gt;\Theta_{distribute}^{k, d} = n \cdot k \cdot \Theta_{distance}^d&amp;lt;/math&amp;gt;&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding-bottom: 20px&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;Сложность шага пересчета центров &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластеров размера &amp;lt;math&amp;gt;m&amp;lt;/math&amp;gt; в d-мерном пространстве &amp;amp;ndash; &amp;lt;math&amp;gt;\Theta_{recenter}^{k, d, m}&amp;lt;/math&amp;gt;&amp;lt;/b&amp;gt;&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;На этом шаге вычисляется &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; центров кластеров &amp;lt;math&amp;gt;\mathbf{\mu}_1, ...\mathbf{\mu}_k&amp;lt;/math&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p align=&amp;quot;center&amp;quot;&amp;gt;&amp;lt;math&amp;gt;\Theta_{recenter}^{k, d, m} = k \cdot \Theta_{centroid}^{d, m}&amp;lt;/math&amp;gt; &amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding-bottom: 20px&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Рассчитаем &amp;lt;math&amp;gt;\Theta_{centroid}^{d, m}&amp;lt;/math&amp;gt; для кластера, число элементов которого равно &amp;lt;math&amp;gt;m&amp;lt;/math&amp;gt;&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p align=&amp;quot;center&amp;quot;&amp;gt;&amp;lt;math&amp;gt;\Theta_{centroid}^{d, m}&amp;lt;/math&amp;gt; = &amp;lt;math&amp;gt;m \cdot d&amp;lt;/math&amp;gt; сложений + &amp;lt;math&amp;gt;d&amp;lt;/math&amp;gt; делений &amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding-bottom: 20px&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Рассчитаем &amp;lt;math&amp;gt;\Theta_{distance}^d&amp;lt;/math&amp;gt; в соответствие с формулой &amp;lt;math&amp;gt;(2)&amp;lt;/math&amp;gt;&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p align=&amp;quot;center&amp;quot;&amp;gt;&amp;lt;math&amp;gt;\Theta_{distance}^d&amp;lt;/math&amp;gt; = &amp;lt;math&amp;gt;d&amp;lt;/math&amp;gt; вычитаний + &amp;lt;math&amp;gt;d&amp;lt;/math&amp;gt; умножений + &amp;lt;math&amp;gt;(d-1)&amp;lt;/math&amp;gt; сложение&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding-bottom: 20px&amp;quot;&amp;gt;&lt;br /&gt;
  &amp;lt;p&amp;gt;Предположим, что алгоритм сошелся за &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt; итераций, тогда временная сложность алгоритма &amp;lt;math&amp;gt;\Theta_{k-means}^{d, n}&amp;lt;/math&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
  &amp;lt;p align=&amp;quot;center&amp;quot;&amp;gt;&amp;lt;b&amp;gt;&amp;lt;math&amp;gt;\Theta_{k-means}^{d, n} \le \Theta_{init}^{k, d, n} + i(\Theta_{distribute}^{k, d} + \Theta_{recenter}^{k, d, n})&amp;lt;/math&amp;gt;&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding-bottom: 5px&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;Операции сложения/вычитания:&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p align=&amp;quot;center&amp;quot;&amp;gt;&amp;lt;b&amp;gt;&amp;lt;math&amp;gt;\Theta_{k-means}^{d, n} \le knd+ i(kn(2d-1) + knd) = knd+ i(kn(3d-1)) \thicksim O(ikdn)&amp;lt;/math&amp;gt;&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding-bottom: 20px&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;Операции умножения/деления:&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p align=&amp;quot;center&amp;quot;&amp;gt;&amp;lt;b&amp;gt;&amp;lt;math&amp;gt;\Theta_{k-means}^{d, n} \le kd + i(knd + kd) = kd + ikd(n+1) \thicksim O(ikdn) &amp;lt;/math&amp;gt;&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding-bottom: 20px&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;Получаем, что &amp;lt;b&amp;gt;временная сложность&amp;lt;/b&amp;gt; алгоритма &amp;lt;b&amp;gt;k means&amp;lt;/b&amp;gt; кластеризации &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; &amp;lt;b&amp;gt;d-мерных&amp;lt;/b&amp;gt; векторов на &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластеров за &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt; итераций:&amp;lt;/p&amp;gt;&lt;br /&gt;
 &amp;lt;p align=&amp;quot;center&amp;quot;&amp;gt;&amp;lt;b&amp;gt;&amp;lt;math&amp;gt; \Theta_{k-means}^{d, n} \thicksim O(ikdn) &amp;lt;/math&amp;gt;&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Информационный граф ===&lt;br /&gt;
&lt;br /&gt;
Рассмотрим информационный граф алгоритма. Алгоритм &amp;lt;i&amp;gt;k means&amp;lt;/i&amp;gt; начинается с этапа инициализации, после которого следуют итерации, на каждой из которых выполняется два последовательных шага (см. [[#Схема реализации последовательного алгоритма|&amp;quot;Схема реализации последовательного алгоритма&amp;quot;]]): &lt;br /&gt;
* распределение векторов по кластерам&lt;br /&gt;
* перерасчет центров кластеров&lt;br /&gt;
&lt;br /&gt;
Поскольку основная часть вычислений приходится на шаги итераций, распишем информационные графы данных шагов.&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Распределение векторов по кластерам&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
Информационный граф шага распределения векторов по кластерам представлен на &#039;&#039;рисунке 1&#039;&#039;. Исходами данного графа является исходные векторы &amp;lt;math&amp;gt;\mathbf{x}_1, ..., \mathbf{x}_n&amp;lt;/math&amp;gt;, а также центры кластеров &amp;lt;math&amp;gt;\mathbf{\mu}_1, ... \mathbf{\mu}_k&amp;lt;/math&amp;gt;, вычисленные ранее (на шаге инициализации, если рассматривается первая итерация алгоритма, или на шаге пересчета центров кластеров предыдущей итерации в противном случае). Каждая пара векторов данных &amp;lt;math&amp;gt;\mathbf{x}_i, i=\overline{1,n}&amp;lt;/math&amp;gt; и центров кластера &amp;lt;math&amp;gt;\mathbf{\mu}_j, j=\overline{1, k}&amp;lt;/math&amp;gt; : (&amp;lt;math&amp;gt;\mathbf{x}_i&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;\mathbf{\mu}_j&amp;lt;/math&amp;gt;) подаются на независимые узлы &amp;lt;i&amp;gt;&amp;quot;d&amp;quot;&amp;lt;/i&amp;gt; вычисления расстояния между векторами (более подробная схема вычисления расстояния представлена далее, &#039;&#039;рисунок 2&#039;&#039;). Далее узлы вычисления расстояния &amp;lt;i&amp;gt;&amp;quot;d&amp;quot;&amp;lt;/i&amp;gt;, соответствующие одному и тому же исходному вектору &amp;lt;math&amp;gt;\mathbf{x}_i&amp;lt;/math&amp;gt; передаются на один узел &amp;lt;i&amp;gt;&amp;quot;m&amp;quot;&amp;lt;/i&amp;gt;, где далее происходит вычисление новой метки кластера для каждого вектора &amp;lt;math&amp;gt;\mathbf{x}_i&amp;lt;/math&amp;gt; (берется кластер с минимальным результатом вычисления расстояния). На выходе графа выдаются метки кластеров , &amp;lt;math&amp;gt;L_1, ..., L_n&amp;lt;/math&amp;gt;, такие что &amp;lt;math&amp;gt;\forall \mathbf{x}_i, i=\overline{1, n}, \mathbf{x}_i \in S_j \Leftrightarrow L_i = j&amp;lt;/math&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
[[file:Clusterization.png|thumb|center|800px|Рис. 1. Схема распределения векторов по кластерам. &#039;&#039;d&#039;&#039; &amp;amp;ndash; вычисление расстояния между векторами; &#039;&#039;m&#039;&#039; &amp;amp;ndash; вычисление минимума.]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Вычисление расстояния между векторами&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
Подробная схема вычисления расстояния между векторами &amp;lt;math&amp;gt;\mathbf{x}_i, \mathbf{\mu}_j&amp;lt;/math&amp;gt; представлена на &#039;&#039;рисунке 2&#039;&#039;. Как показано на графе, узел вычисления расстояния между векторами &amp;lt;i&amp;gt;&amp;quot;d&amp;quot;&amp;lt;/i&amp;gt; состоит из шага взятия разности между векторами (узел &amp;quot;&amp;lt;math&amp;gt;-&amp;lt;/math&amp;gt;&amp;quot;) и взятия нормы получившегося вектора разности (узел &amp;quot;&amp;lt;math&amp;gt;||\cdot||^2&amp;lt;/math&amp;gt;&amp;quot;). Более подробно, вычисление расстояния между векторами &amp;lt;math&amp;gt;\mathbf{x}_i = {x_{i1,}, ...,{x_{in}}}, \mathbf{\mu}_j = {\mu_{j1}, ...,\mu_{jn}}&amp;lt;/math&amp;gt; может быть представлено как вычисление разности между каждой парой компонент &amp;lt;math&amp;gt;(x_{iz}, \mu_{jz}), z=\overline{1, d}&amp;lt;/math&amp;gt; (узел &amp;quot;&amp;lt;math&amp;gt;-&amp;lt;/math&amp;gt;&amp;quot;), далее возведение в квадрат для каждого узла &amp;quot;&amp;lt;math&amp;gt;-&amp;lt;/math&amp;gt;&amp;quot; (узел &amp;quot;&amp;lt;math&amp;gt;()^2&amp;lt;/math&amp;gt;&amp;quot;) и суммирования выходов всех узлов &amp;quot;&amp;lt;math&amp;gt;()^2&amp;lt;/math&amp;gt;&amp;quot; (узел &amp;quot;&amp;lt;math&amp;gt;+&amp;lt;/math&amp;gt;&amp;quot;).  &lt;br /&gt;
&lt;br /&gt;
[[file:dist_calc.png|thumb|center|800px|Рис. 2. Схема вычисления расстояния между вектором и центром кластера.]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Пересчет центров кластеров&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
Информационный граф шага пересчета центров кластеров представлен на &#039;&#039;рисунке 3&#039;&#039;. Исходами данного графа является исходные векторы &amp;lt;math&amp;gt;\mathbf{x}_1, ..., \mathbf{x}_n&amp;lt;/math&amp;gt;, а также им соответствующие метки кластера, &amp;lt;math&amp;gt;L_1, ..., L_n&amp;lt;/math&amp;gt;, такие что &amp;lt;math&amp;gt;\forall x_i, i=\overline{1, n}, \mathbf{x}_i \in S_j \Leftrightarrow L_i = j&amp;lt;/math&amp;gt;, вычисленные на этапе распределения векторов по кластерам. Все векторы &amp;lt;math&amp;gt;\mathbf{x}_1, ..., \mathbf{x}_n&amp;lt;/math&amp;gt; подаются в узлы &amp;lt;math&amp;gt;+_1, ...+_k&amp;lt;/math&amp;gt;, каждый узел &amp;lt;math&amp;gt;+_m, m = \overline{1,k}&amp;lt;/math&amp;gt; соответствует операции сложения векторов кластера с номером &amp;lt;math&amp;gt;m&amp;lt;/math&amp;gt;. Метки кластера &amp;lt;math&amp;gt;L_1, ..., L_n&amp;lt;/math&amp;gt; также совместно передаются на узлы &amp;lt;math&amp;gt;S_m, m = \overline{1,k}&amp;lt;/math&amp;gt;, на каждом из которых вычисляется количество векторов в соответствующем кластере (количество меток с соответствующим значением). Далее каждая пара выходов узлов &amp;lt;math&amp;gt;+_m&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;S_m&amp;lt;/math&amp;gt; подается на узел &amp;quot;&amp;lt;math&amp;gt;/&amp;lt;/math&amp;gt;&amp;quot;, где производится деление суммы векторов кластера на количество элементов в нем. Значения, вычисленные на узлах &amp;quot;&amp;lt;math&amp;gt;/&amp;lt;/math&amp;gt;&amp;quot;, присваиваются новым центрам кластеров (выходные значения графа).&lt;br /&gt;
&lt;br /&gt;
[[file:Recluster.png|thumb|center|800px|Рис. 3. Схема пересчета центров кластеров]]&lt;br /&gt;
&lt;br /&gt;
=== Ресурс параллелизма алгоритма ===&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
Работа алгоритма состоит из &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt; итераций, в каждой из которых происходит &amp;lt;b&amp;gt;распределение d-мерных векторов по &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластерам&amp;lt;/b&amp;gt;, а также &amp;lt;b&amp;gt;пересчет центров кластеров в d-мерном пространстве&amp;lt;/b&amp;gt;. В шаге &amp;lt;b&amp;gt;распределения d-мерных векторов по &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластерам&amp;lt;/b&amp;gt; расстояния между вектором и центрами кластеров вычисляются независимо (отсутствуют информационные зависимости). &amp;lt;b&amp;gt;Центры масс кластеров&amp;lt;/b&amp;gt; также пересчитываются независимо друг от друга. Таким образом, имеет место [[глоссарий#Массовый параллелизм|&#039;&#039;массовый параллелизм&#039;&#039;]]. Вычислим параллельную сложность &amp;lt;math&amp;gt;\Psi_*&amp;lt;/math&amp;gt; каждого из шагов, а также параллельную сложность всего алгоритма, &amp;lt;math&amp;gt;\Psi_{k-means}&amp;lt;/math&amp;gt;. Будем исходить из предположения, что может быть использовано любое необходимое число потоков.&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Распределение d-мерных векторов по &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластерам&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;  &lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
Поскольку на данном шаге для каждой пары векторов &amp;lt;math&amp;gt;\mathbf{x}_i, i=\overline{1,n}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\mathbf{\mu}_j, j=\overline{1,k}&amp;lt;/math&amp;gt; операции вычисления расстояния не зависят друг от друга, они могут выполняться параллельно. Тогда, разделив все вычисление расстояний на &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; потоков, получим, что в каждом потоке будет выполняться только одна операция вычисления расстояния между векторами размерности d. При этом каждому вычислительному потоку передаются координаты центров всех кластеров &amp;lt;math&amp;gt;\mathbf{\mu}_1, ..., \mathbf{\mu}_k&amp;lt;/math&amp;gt;. Таким образом, параллельная сложность данного шага определяется &amp;lt;i&amp;gt; сложностью параллельной операции вычисления расстояния между d-мерными векторами&amp;lt;/i&amp;gt;, &amp;lt;math&amp;gt;\Psi_{distance}^d&amp;lt;/math&amp;gt;  и &amp;lt;i&amp;gt;сложностью определения наиболее близкого кластера&amp;lt;/i&amp;gt; (паралельное взятие минимума по расстояниям), &amp;lt;math&amp;gt;\Psi_{min}^k&amp;lt;/math&amp;gt;. Для оценки &amp;lt;math&amp;gt;\Psi_{distance}^d&amp;lt;/math&amp;gt; воспользуемся  [[Нахождение_частных_сумм_элементов_массива_сдваиванием | параллельной реализацией нахождения частичной суммы элементов массива путем сдваивания]]. Аналогично, &amp;lt;math&amp;gt;\Psi_{min}^k = log(k)&amp;lt;/math&amp;gt;. В результате, &amp;lt;math&amp;gt;\Psi_{distance}^d = O(log(d))&amp;lt;/math&amp;gt;.   Таким образом: &lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p align=&amp;quot;center&amp;quot;&amp;gt;&amp;lt;math&amp;gt;\Psi_{distribute}^{k, d}  = \Psi_{distance}^d + \Psi_{min}^k = O(log(d))+O(log(k)) = O(log(kd))&amp;lt;/math&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Пересчет центров кластеров в d-мерном пространстве&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
Поскольку на данном шаге для каждого из &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластеров центр масс может быть вычислен независимо, данные операции могут быть выполнены в отдельных потоках. Таким образом, параллельная сложность данного шага, &amp;lt;math&amp;gt;\Psi_{recenter}^{k, d}&amp;lt;/math&amp;gt;,  будет определяться &amp;lt;i&amp;gt;параллельной сложностью вычисления одного центра масс кластера размера &amp;lt;math&amp;gt;m&amp;lt;/math&amp;gt;&amp;lt;/i&amp;gt;, &amp;lt;math&amp;gt;\Psi_{recenter}^{k, d}&amp;lt;/math&amp;gt;,  а так как &amp;lt;math&amp;gt;m \le n \Rightarrow \Psi_{recenter}^{d, m} \le \Psi_{recenter}^{d, n}&amp;lt;/math&amp;gt;. Сложность вычисления центра масс кластера d-мерных векторов размера n аналогично предыдущим вычислениям равна &amp;lt;math&amp;gt;O(log(n))&amp;lt;/math&amp;gt;. Тогда:  &lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p align=&amp;quot;center&amp;quot;&amp;gt;&amp;lt;math&amp;gt;\Psi_{recenter}^{k, d}  \le \Psi_{recenter}^{d, n} = O(log(n))&amp;lt;/math&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Общая параллельная сложность алгоритма&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
На каждой итерации необходимо обновление центров кластеров, которые будут использованы на следующей итерации. Таким образом, итерационный процесс выполняется последовательно&amp;lt;ref&amp;gt;Zhao, Weizhong, Huifang Ma, and Qing He. &amp;quot;Parallel k-means clustering based on mapreduce.&amp;quot; IEEE International Conference on Cloud Computing. Springer Berlin Heidelberg, 2009.&amp;lt;/ref&amp;gt;. Тогда, поскольку сложность каждой итерации  определяется &amp;lt;math&amp;gt;\Psi_{distribute}^{k, d}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\Psi_{recenter}&amp;lt;/math&amp;gt;, сложность всего алгоритма, &amp;lt;math&amp;gt;\Psi_{k-means}&amp;lt;/math&amp;gt; в предположении, что было сделано &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt; операций определяется выражением&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p align=&amp;quot;center&amp;quot;&amp;gt;&amp;lt;math&amp;gt;\Psi_{k-means} \approx i \cdot (\Psi_{distribute}^{k, d} + \Psi_{recenter}^{k, d}) \le i \cdot O(log(kdn))&amp;lt;/math&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Входные и выходные данные алгоритма ===&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;Входные данные&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;Матрица из &amp;lt;math&amp;gt;n \cdot d&amp;lt;/math&amp;gt; элементов &amp;lt;math&amp;gt;x_{i, j} \in \mathbb{R}, i=\overline{1, n}, j=\overline{1, d}&amp;lt;/math&amp;gt;&amp;amp;ndash; координат векторов (наблюдений).&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;Целое положительное число &amp;lt;math&amp;gt;k, k \le n&amp;lt;/math&amp;gt; &amp;amp;ndash; количество кластеров.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;Объем входных данных&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;math&amp;gt;1&amp;lt;/math&amp;gt; целое число + &amp;lt;math&amp;gt;n \cdot d&amp;lt;/math&amp;gt; вещественных чисел (при условии, что координаты &amp;amp;ndash; вещественные числа).&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;Выходные данные&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; целых положительных чисел &amp;lt;math&amp;gt;L_1, ..., L_n&amp;lt;/math&amp;gt;&amp;amp;ndash; номера кластеров, соотвествующие каждому вектору (при условии, что нумерация кластеров начинается с &amp;lt;math&amp;gt;1&amp;lt;/math&amp;gt;).&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;Объем выходных данных&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; целых положительных чисел.&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Свойства алгоритма ===&lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;[[глоссарий#Вычислительная мощность|&#039;&#039;Вычислительная мощность&#039;&#039;]]&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
Вычислительная мощность алгоритма &amp;lt;i&amp;gt;k means&amp;lt;/i&amp;gt; равна &amp;lt;math&amp;gt;\frac{ikdn}{n \cdot d} = k \cdot i &amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; &amp;amp;ndash; число кластеров, &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt; &amp;amp;ndash; число итераций алгоритма.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;[[глоссарий#Детерминированность |&#039;&#039;Детерминированность&#039;&#039;]] и [[глоссарий#Устойчивость |&#039;&#039;Устойчивость&#039;&#039;]] &amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
Алгоритм &amp;lt;i&amp;gt;k means&amp;lt;/i&amp;gt; является итерационным. Количество итераций алгоритма в общем случае не фиксируется и зависит от начального расположения объектов в пространстве, параметра &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt;, а также от начального приближения центров кластеров, &amp;lt;math&amp;gt;\mu_1, ..., \mu_k&amp;lt;/math&amp;gt;. В результате этого может варьироваться результат работы алгоритма. При неудачном выборе начальных параметров итерационный процесс может сойтись к локальному оптимуму&amp;lt;ref&amp;gt;Von Luxburg, Ulrike. Clustering Stability. Now Publishers Inc, 2010.&amp;lt;/ref&amp;gt;. По этим причинам алгоритм не является ни &amp;lt;b&amp;gt;детермирированным&amp;lt;/b&amp;gt;, ни &amp;lt;b&amp;gt;устойчивым&amp;lt;/b&amp;gt;.&lt;br /&gt;
 &lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Соотношение последовательной и параллельной сложности алгоритма&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\frac{\Theta_{k-means}}{\Psi_{k-means}} = \frac{O(ikdn)}{O(i \cdot log(kdn))}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Сильные стороны алгоритма&amp;lt;/b&amp;gt;:&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;i&amp;gt;Сравнительно высокая эффективность при простоте реализации&amp;lt;/i&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;i&amp;gt;Высокое качество кластеризации&amp;lt;/i&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;i&amp;gt;Возможность распараллеливания&amp;lt;/i&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;i&amp;gt;Существование множества модификаций&amp;lt;/i&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;Недостатки алгоритма&amp;lt;/b&amp;gt;&amp;lt;ref&amp;gt;Ortega, Joaquín Pérez, Ma Del Rocío Boone Rojas, and María J. Somodevilla. &amp;quot;Research issues on K-means Algorithm: An Experimental Trial Using Matlab.&amp;quot;&amp;lt;/ref&amp;gt;:&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;i&amp;gt;Количество кластеров является параметром алгоритма&amp;lt;/i&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;&amp;lt;i&amp;gt;Чувствительность к начальным условиям&amp;lt;/i&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;Инициализация центров кластеров в значительной степени влияет на результат кластеризации.&amp;lt;/p&amp;gt;&lt;br /&gt;
  &amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;&amp;lt;i&amp;gt;Чувствительность к выбросам и шумам&amp;lt;/i&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;Выбросы, далекие от центров настоящих кластеров, все равно учитываются при вычислении их центров.&amp;lt;/p&amp;gt;&lt;br /&gt;
  &amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;&amp;lt;i&amp;gt;Возможность сходимости к локальному оптимуму&amp;lt;/i&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;Итеративный подход не дает гарантии сходимости к оптимальному решению.&amp;lt;/p&amp;gt;&lt;br /&gt;
  &amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;&amp;lt;i&amp;gt;Использование понятия &amp;quot;среднего&amp;quot;&amp;lt;/i&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;Алгоритм неприменим к данным, для которых не определено понятие &amp;quot;среднего&amp;quot;, например, категориальным данным.&amp;lt;/p&amp;gt;&lt;br /&gt;
  &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&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;
Исследование масштабируемости параллельной реализации алгоритма k means проводилось на суперкомпьютере &amp;quot;Ломоносов&amp;quot;&amp;lt;ref name=&amp;quot;Lom&amp;quot;&amp;gt;Воеводин Вл., Жуматий С., Соболев С., Антонов А., Брызгалов П., Никитенко Д., Стефанов К., Воеводин Вад. Практика суперкомпьютера «Ломоносов» // Открытые системы, 2012, N 7, С. 36-39.&amp;lt;/ref&amp;gt; [http://parallel.ru/cluster Суперкомпьютерного комплекса Московского университета]. Алгоритм реализован на языке C с использованием средств MPI.&lt;br /&gt;
Для исследования масштабируемости проводилось множество запусков программы с разным значением параметра (количество векторов для кластеризации), а также с различным числом процессоров. Фиксировались результаты запусков &amp;amp;ndash; время работы &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt; и количество произведенных итераций алгоритма &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Параметры запусков для экспериментальной оценки:&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;Значения &amp;lt;b&amp;gt;количества векторов&amp;lt;/b&amp;gt; &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;: 20&#039;000, 30&#039;000, 50&#039;000, 100&#039;000, 200&#039;000, 300&#039;000, 500&#039;000, 700&#039;000, 1&#039;000&#039;000, 1&#039;500&#039;000, 2&#039;000&#039;000.&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;Значения &amp;lt;b&amp;gt;количества процессоров&amp;lt;/b&amp;gt; &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt;: 1, 8, 16, 32, 64, 128, 160, 192, 224, 256, 288, 320, 352, 384, 416, 448, 480, 512.&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;Значение &amp;lt;b&amp;gt;количества кластеров&amp;lt;/b&amp;gt; &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt;: 100.&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;Значение &amp;lt;b&amp;gt;размерности векторов&amp;lt;/b&amp;gt; &amp;lt;math&amp;gt;d&amp;lt;/math&amp;gt;: 10.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Для проведения экспериментов были сгенерированы нормально распределенные псевдослучайные данные (с использованием Python библиотеки [http://scikit-learn.org/ scikit-learn]):&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
from sklearn.datasets import make_classification&lt;br /&gt;
X1, Y1 = make_classification(n_features=10, n_redundant=2, n_informative=8,&lt;br /&gt;
                             n_clusters_per_class=1, n_classes=100,&lt;br /&gt;
                             n_samples=2000000)&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Для заданной конфигурации эксперимента (&amp;lt;math&amp;gt;n, d, p, k&amp;lt;/math&amp;gt;) и полученных результатов (&amp;lt;math&amp;gt;t, i&amp;lt;/math&amp;gt;)  [[Глоссарий#Производительность|производительность]]  и эффективность реализации расчитывались по формулам:&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
&amp;lt;ul&amp;gt;&amp;lt;li&amp;gt;&amp;lt;math&amp;gt;Performance = \frac{N_{k-means}^{d, n}}{t}\ \ (FLOPS),&amp;lt;/math&amp;gt;&amp;lt;/li&amp;gt;&amp;lt;/ul&amp;gt;&lt;br /&gt;
где &amp;lt;math&amp;gt;N_{k-means}^{d, n}&amp;lt;/math&amp;gt; &amp;amp;ndash; точное число операций с плавающей точкой (операции с памятью, а также целочисленные операции не учитывались), вычисленное в соответствие с разделом [[#Последовательная сложность алгоритма| &amp;quot;Последовательная сложность алгоритма&amp;quot;]];&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
&amp;lt;ul&amp;gt;&amp;lt;li&amp;gt;&amp;lt;math&amp;gt;Efficiency = \frac{100 \cdot Performance}{Performance_{Peak}^{p}}\ \ (%),&amp;lt;/math&amp;gt;&amp;lt;/li&amp;gt;&amp;lt;/ul&amp;gt;&lt;br /&gt;
где &amp;lt;math&amp;gt;Performance_{Peak}^{p}&amp;lt;/math&amp;gt; &amp;amp;ndash; пиковая производительность суперкомпьютера при &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt; процессорах, вычисленная согласно спецификациям Intel&amp;lt;sup&amp;gt;&amp;amp;reg;&amp;lt;/sup&amp;gt; XEON&amp;lt;sup&amp;gt;&amp;amp;reg;&amp;lt;/sup&amp;gt; X5670&amp;lt;ref&amp;gt;&amp;quot;http://ark.intel.com/ru/products/47920/Intel-Xeon-Processor-X5670-12M-Cache-2_93-GHz-6_40-GTs-Intel-QPI&amp;quot;&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Графики зависимости производительности и эффективности параллельной реализации k means от числа векторов для кластеризации (&amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;) и числа процессоров (&amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt;) представлены на рисунках 4 и 5 соответственно.&lt;br /&gt;
&lt;br /&gt;
[[file:Flops.png|thumb|center|800px|Рис. 4. Параллельная реализация k means. График зависимости производительности реализации алгоритма от числа векторов для кластеризации (&amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;) и числа процессоров (&amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt;).]]&lt;br /&gt;
[[file:Efficiency.png|thumb|center|800px|Рис. 5. Параллельная реализация k means. График зависимости эффективности реализации алгоритма от числа векторов для кластеризации (&amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;) и числа процессоров (&amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt;).]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;В результате&amp;lt;/b&amp;gt; экспериментальной оценки были получены следующие оценки эффективности реализации:&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;b&amp;gt;Минимальное&amp;lt;/b&amp;gt; значение: 0.000409 % достигается при &amp;lt;math&amp;gt;n=20&#039;000, p=480&amp;lt;/math&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;b&amp;gt;Максимальное&amp;lt;/b&amp;gt; значение: 0.741119 % достигается при &amp;lt;math&amp;gt;n=300&#039;000, p=1&amp;lt;/math&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
Оценки масштабируемости реализации алгоритма k means:&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;b&amp;gt;По числу процессоров:&amp;lt;/b&amp;gt; -0.002683 &amp;amp;ndash; эффективность убывает с ростом числа процессоров. Данный результат вызван ростом накладных расходов для обеспечения параллельного выполнения алгоритма.&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;b&amp;gt;По размеру задачи:&amp;lt;/b&amp;gt; 0.002779 &amp;amp;ndash; эффективность растет с ростом числа векторов. Данный результат вызван тем, что при увеличении размера задачи, количество вычислений растет по сравнению с временем, затрачиваемым на пересылку данных.&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;b&amp;gt;Общая оценка:&amp;lt;/b&amp;gt; -0.000058 &amp;amp;ndash; можно сделать вывод, что в целом эффективность реализации незначительно уменьшается с ростом размера задачи и числа процессоров.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[https://github.com/serban/kmeans Использованная параллельная реализация алгоритма k means]&lt;br /&gt;
&lt;br /&gt;
=== Динамические характеристики и эффективность реализации алгоритма ===&lt;br /&gt;
=== Выводы для классов архитектур ===&lt;br /&gt;
=== Существующие реализации алгоритма ===&lt;br /&gt;
==== Открытое программное обеспечение ====&lt;br /&gt;
&amp;lt;ol&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;[https://www.icpsr.umich.edu/CrimeStat/ CrimeStat]&amp;lt;/li&amp;gt; Программное обеспечение, созданное для операционных систем Windows, предоставляющее инструменты статистического  и пространственного анализа для решения задачи картирования преступности.&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://juliastats.github.io Julia]&amp;lt;/li&amp;gt; Высокоуровневый высокопроизводительный свободный язык программирования с динамической типизацией, созданный для математических вычислений, содержит реализацию k-means.&lt;br /&gt;
  &amp;lt;li&amp;gt;[https://mahout.apache.org Mahout]&amp;lt;/li&amp;gt; Apache Mahout - Java библиотека для работы с алгоритмами машинного обучения с использованием MapReduce. Содержит реализацию k-means.&lt;br /&gt;
  &amp;lt;li&amp;gt;[https://www.gnu.org/software/octave/ Octave]&amp;lt;/li&amp;gt; Написанная на C++  свободная система для математических вычислений, использующая совместимый с MATLAB язык высокого уровня, содержит реализацию k-means.&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://spark.apache.org/docs/latest/mllib-clustering.html Spark]&amp;lt;/li&amp;gt; Распределенная реализация k-means содержится в библиотеке Mlib для работы с алгоритмами машинного обучения, взаимодействующая с Python библиотекой NumPy и библиотека R.&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://torch.ch Torch]&amp;lt;/li&amp;gt;  MATLAB-подобная библиотека для языка программирования Lua с открытым исходным кодом, предоставляет большое количество алгоритмов для глубинного обучения и научных расчётов. Ядро написано на Си, прикладная часть выполняется на LuaJIT, поддерживается распараллеливание вычислений средствами CUDA и OpenMP. Существуют реализации k-means.&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://www.cs.waikato.ac.nz/ml/weka/ Weka]&amp;lt;/li&amp;gt;  Cвободное программное обеспечение для анализа данных, написанное на Java. Содержит k-means и x-means.&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://accord-framework.net/docs/html/T_Accord_MachineLearning_KMeans.htm Accord.NET]&amp;lt;/li&amp;gt; C# реализация алгоритмов k-means, k-means++, k-modes.&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://docs.opencv.org/3.0-beta/doc/py_tutorials/py_ml/py_kmeans/py_kmeans_opencv/py_kmeans_opencv.html OpenCV]&amp;lt;/li&amp;gt; Написанная на С++ библиотека, направленная в основном на решение задач компьютерного зрения. Содержит реализацию k-means.&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://mlpack.org/ MLPACK]&amp;lt;/li&amp;gt; Масштабируемая С++ библиотека для работы с алгоритмами машинного обучения, содержит реализацию k-means.&lt;br /&gt;
  &amp;lt;li&amp;gt;[https://www.scipy.org/ SciPy]&amp;lt;/li&amp;gt; Библиотека Python, содержит множество реализаций k-means.&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://scikit-learn.org/ scikit-learn]&amp;lt;/li&amp;gt; Библиотека Python, содержит множество реализаций k-means.&lt;br /&gt;
  &amp;lt;li&amp;gt;[https://www.r-bloggers.com/k-means-clustering-in-r/ R]&amp;lt;/li&amp;gt; Язык программирования для статистической обработки данных и работы с графикой, а также свободная программная среда вычислений с открытым исходным кодом в рамках проекта GNU, содержит три реализации k-means.&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://elki.dbs.ifi.lmu.de ELKI]&amp;lt;/li&amp;gt; Java фреймворк, содержащий реализацию k-means, а также множество других алгоритмов кластеризации.&lt;br /&gt;
&amp;lt;/ol&amp;gt;&lt;br /&gt;
==== Проприетарное программное обеспечение  ====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ol&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;[https://www.ayasdi.com/blog/bigdata/topological-data-analysis-of-oil-and-gas-petrophysical-data/ Ayasdi]&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://www.stata.com/features/cluster-analysis/ Stata]&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://mathworld.wolfram.com/K-MeansClusteringAlgorithm.html Mathematica]&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://www.mathworks.com/help/stats/kmeans.html?requestedDomain=www.mathworks.com MATLAB]&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;[https://support.sas.com/rnd/app/stat/procedures/fastclus.html SAS]&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://docs.rapidminer.com/studio/operators/modeling/segmentation/k_means.html RapidMiner]&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;[https://blogs.sap.com/2013/03/28/sap-hana-pal-k-means-algorithm-or-how-to-do-customer-segmentation-for-the-telecommunications-industry/ SAP HANA]&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ol&amp;gt;&lt;br /&gt;
== Литература ==&lt;br /&gt;
&amp;lt;references /&amp;gt;&lt;/div&gt;</summary>
		<author><name>DennZo1993</name></author>
	</entry>
	<entry>
		<id>https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:%D0%91%D1%80%D0%BE%D1%82%D0%B8%D0%BA%D0%BE%D0%B2%D1%81%D0%BA%D0%B0%D1%8F_%D0%94%D0%B0%D0%BD%D1%83%D1%82%D0%B0/%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_k-means&amp;diff=20528</id>
		<title>Участник:Бротиковская Данута/Алгоритм k-means</title>
		<link rel="alternate" type="text/html" href="https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:%D0%91%D1%80%D0%BE%D1%82%D0%B8%D0%BA%D0%BE%D0%B2%D1%81%D0%BA%D0%B0%D1%8F_%D0%94%D0%B0%D0%BD%D1%83%D1%82%D0%B0/%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_k-means&amp;diff=20528"/>
		<updated>2016-12-10T10:52:49Z</updated>

		<summary type="html">&lt;p&gt;DennZo1993: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Assignment|Zhum}}&lt;br /&gt;
&lt;br /&gt;
{{algorithm&lt;br /&gt;
| name              = Алгоритм k средних (k means)&lt;br /&gt;
| serial_complexity = &amp;lt;math&amp;gt;O(ikdn)&amp;lt;/math&amp;gt;&lt;br /&gt;
| input_data        = &amp;lt;math&amp;gt; dn &amp;lt;/math&amp;gt;&lt;br /&gt;
| output_data       = &amp;lt;math&amp;gt; n &amp;lt;/math&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
Авторы страницы &amp;lt;b&amp;gt;[[Участник:Бротиковская Данута|Данута Бротиковская]]&amp;lt;/b&amp;gt; и &amp;lt;b&amp;gt;[[Участник:DennZo1993|Денис Зобнин]]&amp;lt;/b&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
Оба автора внесли одинаковый вклад в написание статьи (поиск материалов, изучение статей, заполнение контента статьи), четких разграничений по пунктам статьи сделать невозможно. &lt;br /&gt;
&lt;br /&gt;
== Свойства и структура алгоритма ==&lt;br /&gt;
&lt;br /&gt;
=== Общее описание алгоритма ===&lt;br /&gt;
Алгоритм &amp;lt;b&amp;gt;&amp;lt;i&amp;gt;k средних&amp;lt;/i&amp;gt;&amp;lt;/b&amp;gt; (&amp;lt;b&amp;gt;&amp;lt;i&amp;gt;k means&amp;lt;/i&amp;gt;&amp;lt;/b&amp;gt;) &amp;amp;ndash; неиерархический&amp;lt;ref&amp;gt;&amp;quot;https://ru.wikipedia.org/wiki/Иерархическая_кластеризация&amp;quot;&amp;lt;/ref&amp;gt;, итерационный метод кластеризации&amp;lt;ref&amp;gt;&amp;quot;https://ru.wikipedia.org/wiki/Кластерный_анализ&amp;quot;&amp;lt;/ref&amp;gt;, получивший большую популярность благодаря своей простоте, наглядности реализации и достаточно высокому качеству работы. Был изобретен в 1950-х годах математиком &amp;lt;i&amp;gt;Гуго Штейнгаузом&amp;lt;/i&amp;gt;&amp;lt;ref&amp;gt;Steinhaus, Hugo. &amp;quot;Sur la division des corp materiels en parties.&amp;quot; Bull. Acad. Polon. Sci 1.804 (1956): 801.&amp;lt;/ref&amp;gt; и почти одновременно &amp;lt;i&amp;gt;Стюартом Ллойдом&amp;lt;/i&amp;gt;&amp;lt;ref&amp;gt;Lloyd, S. P. &amp;quot;Least square quantization in PCM. Bell Telephone Laboratories Paper. Published in journal much later: Lloyd, SP: Least squares quantization in PCM.&amp;quot; IEEE Trans. Inform. Theor.(1957/1982).&amp;lt;/ref&amp;gt;. Особую популярность приобрел после публикации работы &amp;lt;i&amp;gt;МакКуина&amp;lt;/i&amp;gt;&amp;lt;ref&amp;gt;MacQueen, James. &amp;quot;Some methods for classification and analysis of multivariate observations.&amp;quot; Proceedings of the fifth Berkeley symposium on mathematical statistics and probability. Vol. 1. No. 14. 1967.&amp;lt;/ref&amp;gt; в 1967.&lt;br /&gt;
&lt;br /&gt;
Алгоритм представляет собой версию EM-алгоритма&amp;lt;ref&amp;gt;&amp;quot;https://ru.wikipedia.org/wiki/EM-алгоритм&amp;quot;&amp;lt;/ref&amp;gt;, применяемого также для разделения смеси гауссиан. Основная идея &amp;lt;i&amp;gt;k means&amp;lt;/i&amp;gt; заключается в том, что данные произвольно разбиваются на кластеры, после чего итеративно перевычисляется центр масс для каждого кластера, полученного на предыдущем шаге, затем векторы разбиваются на кластеры вновь в соответствии с тем, какой из новых центров оказался ближе по выбранной метрике.&lt;br /&gt;
&lt;br /&gt;
Цель алгоритма заключается в разделении &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; наблюдений на &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластеров таким образом, чтобы каждое наблюдение принадлежало ровно одному кластеру, расположенному на наименьшем расстоянии от наблюдения.&lt;br /&gt;
&lt;br /&gt;
=== Математическое описание алгоритма ===&lt;br /&gt;
&amp;lt;b&amp;gt;&amp;lt;u&amp;gt;Дано:&amp;lt;/u&amp;gt;&amp;lt;/b&amp;gt;&lt;br /&gt;
* набор из &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; наблюдений &amp;lt;math&amp;gt;X=\{\mathbf{x}_1, \mathbf{x}_2, ..., \mathbf{x}_n\}, \mathbf{x}_i \in \mathbb{R}^d, i=\overline{1, n}&amp;lt;/math&amp;gt;;&lt;br /&gt;
* &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; - требуемое число кластеров, &amp;lt;math&amp;gt;k \in \mathbb{N}, k \leq n&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;&amp;lt;u&amp;gt;Требуется:&amp;lt;/u&amp;gt;&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Разделить множество наблюдений &amp;lt;math&amp;gt;X&amp;lt;/math&amp;gt; на &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластеров &amp;lt;math&amp;gt;S_1, S_2, ..., S_k&amp;lt;/math&amp;gt;:&lt;br /&gt;
*   &amp;lt;math&amp;gt;S_i \cap S_j= \varnothing, \quad i \ne j&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
*   &amp;lt;math&amp;gt;\bigcup_{i=1}^{k} S_i = X&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;&amp;lt;u&amp;gt;Действие алгоритма:&amp;lt;/u&amp;gt;&amp;lt;/b&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;Алгоритм &amp;lt;i&amp;gt;k means&amp;lt;/i&amp;gt; разбивает набор &amp;lt;math&amp;gt;X&amp;lt;/math&amp;gt; на &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; наборов &amp;lt;math&amp;gt;S_1, S_2, ..., S_k,&amp;lt;/math&amp;gt; таким образом, чтобы минимизировать сумму квадратов расстояний от каждой точки кластера до его центра (центр масс кластера). Введем обозначение, &amp;lt;math&amp;gt;S=\{S_1, S_2, ..., S_k\}&amp;lt;/math&amp;gt;. Тогда действие алгоритма &amp;lt;i&amp;gt;k means&amp;lt;/i&amp;gt; равносильно поиску:&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;table style=&amp;quot;width:100%&amp;quot;&amp;gt;&lt;br /&gt;
  &amp;lt;tr&amp;gt;&lt;br /&gt;
    &amp;lt;td align=&amp;quot;center&amp;quot; width=&amp;quot;90%&amp;quot;&amp;gt;&amp;lt;math&amp;gt;\arg\min_{S} \sum\limits_{i=1}^k \sum\limits_{\mathbf{x} \in S_i} \rho(\mathbf{x}, \mathbf{\mu}_i )^2,&amp;lt;/math&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;td align=&amp;quot;right&amp;quot;&amp;gt;&amp;lt;math&amp;gt;(1)&amp;lt;/math&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;/table&amp;gt;&lt;br /&gt;
где &amp;lt;math&amp;gt;\mathbf{\mu}_i&amp;lt;/math&amp;gt; &amp;amp;ndash; центры кластеров, &amp;lt;math&amp;gt;i=\overline{1,k}, \quad \rho(\mathbf{x}, \mathbf{\mu}_i)&amp;lt;/math&amp;gt; &amp;amp;ndash; функция расстояния между &amp;lt;math&amp;gt;\mathbf{x}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\mu_i&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;&amp;lt;u&amp;gt;Шаги алгоритма: &amp;lt;/u&amp;gt;&amp;lt;/b&amp;gt;&lt;br /&gt;
&amp;lt;ol&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&lt;br /&gt;
    &amp;lt;b&amp;gt;Начальный шаг: инициализация кластеров&amp;lt;/b&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;Выбирается произвольное множество точек &amp;lt;math&amp;gt;\mu_i, i=\overline{1,k}&amp;lt;/math&amp;gt;, рассматриваемых как начальные центры кластеров: &amp;lt;math&amp;gt;\mu_i^{(0)} = \mu_i, \quad i=\overline{1, k}&amp;lt;/math&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
  &amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&lt;br /&gt;
    &amp;lt;b&amp;gt;Распределение векторов по кластерам&amp;lt;/b&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Шаг&amp;lt;/b&amp;gt; &amp;lt;math&amp;gt;t: \forall \mathbf{x}_i \in X, i=\overline{1,n}: \mathbf{x}_i \in S_j \iff  j=\arg\min_{k}\rho(\mathbf{x}_i,\mathbf{\mu}_k^{(t-1)})^2&amp;lt;/math&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
  &amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&lt;br /&gt;
    &amp;lt;b&amp;gt;Пересчет центров кластеров&amp;lt;/b&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Шаг &amp;lt;/b&amp;gt; &amp;lt;math&amp;gt;t: \forall i=\overline{1,k}:  \mu_i^{(t)} = \cfrac{1}{|S_i|}\sum_{\mathbf{x}\in S_i}\mathbf{x}&amp;lt;/math&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
  &amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&lt;br /&gt;
    &amp;lt;b&amp;gt;Проверка условия останова:&amp;lt;/b&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
    &#039;&#039;&#039;if&#039;&#039;&#039; &amp;lt;math&amp;gt;\exist i\in \overline{1,k}: \mu_i^{(t)} \ne \mu_i^{(t-1)}&amp;lt;/math&amp;gt; &#039;&#039;&#039;then&#039;&#039;&#039;&lt;br /&gt;
        t = t + 1;&lt;br /&gt;
        goto 2;&lt;br /&gt;
    &#039;&#039;&#039;else&#039;&#039;&#039;&lt;br /&gt;
        &#039;&#039;&#039;stop&#039;&#039;&#039;&lt;br /&gt;
  &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ol&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Вычислительное ядро алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Вычислительным ядром являются шаги 2 и 3 приведенного выше алгоритма: &amp;lt;b&amp;gt;&amp;lt;i&amp;gt;распределение векторов по кластерам&amp;lt;/i&amp;gt;&amp;lt;/b&amp;gt; и &amp;lt;b&amp;gt;&amp;lt;i&amp;gt;пересчет центров кластеров&amp;lt;/i&amp;gt;&amp;lt;/b&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;&amp;lt;i&amp;gt;Распределение векторов&amp;lt;/i&amp;gt;&amp;lt;/b&amp;gt; по кластерам предполагает вычисление расстояний между каждым вектором &amp;lt;math&amp;gt;\mathbf{x}_i \in X, i= \overline{1,n}&amp;lt;/math&amp;gt; и центрами кластера &amp;lt;math&amp;gt;\mathbf{\mu}_j, j= \overline{1,k}&amp;lt;/math&amp;gt;. Таким образом, данный шаг предполагает &amp;lt;math&amp;gt;kn&amp;lt;/math&amp;gt; вычислений расстояний между d-мерными векторами. &lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;&amp;lt;i&amp;gt;Пересчет центров кластеров&amp;lt;/i&amp;gt;&amp;lt;/b&amp;gt; предполагает &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; вычислений центров масс &amp;lt;math&amp;gt;\mathbf{\mu}_i&amp;lt;/math&amp;gt; множеств &amp;lt;math&amp;gt;S_i, i=\overline{1,k}&amp;lt;/math&amp;gt; представленных выражением в шаге 3 представленного выше алгоритма.&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Макроструктура алгоритма ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Инициализация центров масс &amp;lt;math&amp;gt;\mu_1, ..., \mu_k&amp;lt;/math&amp;gt;&amp;lt;/b&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
Наиболее распространенными являются следующие стратегии:&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&lt;br /&gt;
    &amp;lt;b&amp;gt;Метод Forgy&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;В качестве начальных значений &amp;lt;math&amp;gt;\mu_1, ..., \mu_k&amp;lt;/math&amp;gt; берутся случайно выбранные векторы.&lt;br /&gt;
  &amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&lt;br /&gt;
    &amp;lt;b&amp;gt;Метод случайно разделения (Random Partitioning)&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;Для каждого вектора &amp;lt;math&amp;gt;\mathbf{x}_i \in X, i=\overline{1, n}&amp;lt;/math&amp;gt; выбирается случайным образом кластер &amp;lt;math&amp;gt;S_1, ..., S_k&amp;lt;/math&amp;gt;, после чего для каждого полученного кластера вычисляются значения &amp;lt;math&amp;gt;\mu_1, ..., \mu_k&amp;lt;/math&amp;gt;.&lt;br /&gt;
  &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Распределение векторов по кластерам&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Для этого шага алгоритма между векторами &amp;lt;math&amp;gt;\mathbf{x}_i \in X, i=\overline{1, n}&amp;lt;/math&amp;gt; и центрами кластеров &amp;lt;math&amp;gt;\mu_1, ..., \mu_k&amp;lt;/math&amp;gt; вычисляются &amp;lt;b&amp;gt;расстояния&amp;lt;/b&amp;gt; по формуле (как правило, используется Евлидово расстояние):&lt;br /&gt;
&amp;lt;table style=&amp;quot;width:100%&amp;quot;&amp;gt;&lt;br /&gt;
  &amp;lt;tr&amp;gt;&lt;br /&gt;
    &amp;lt;td align=&amp;quot;center&amp;quot; width=&amp;quot;90%&amp;quot;&amp;gt;&amp;lt;math&amp;gt; \mathbf{v}_1, \mathbf{v}_2 \in \mathbb{R}^d,  \quad \rho(\mathbf{v}_1, \mathbf{v}_2) = \lVert \mathbf{v}_1- \mathbf{v}_2 \rVert= \sqrt{\sum_{i=1}^{d}(\mathbf{v}_{1,i} - \mathbf{v}_{2,i})^2}&amp;lt;/math&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;td align=&amp;quot;right&amp;quot;&amp;gt;&amp;lt;math&amp;gt;(2)&amp;lt;/math&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;/table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Пересчет центров кластеров&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Для этого шага алгоритма производится пересчет центров кластера по &amp;lt;b&amp;gt;формуле вычисления центра масс&amp;lt;/b&amp;gt;:&lt;br /&gt;
&amp;lt;table style=&amp;quot;width:100%&amp;quot;&amp;gt;&lt;br /&gt;
  &amp;lt;tr&amp;gt;&lt;br /&gt;
    &amp;lt;td align=&amp;quot;center&amp;quot; width=&amp;quot;90%&amp;quot;&amp;gt;&amp;lt;math&amp;gt; \mu = \cfrac{1}{|S|}\sum_{\mathbf{x}\in S}\mathbf{x}&amp;lt;/math&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;td align=&amp;quot;right&amp;quot;&amp;gt;&amp;lt;math&amp;gt;(3)&amp;lt;/math&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;/table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Схема реализации последовательного алгоритма ===&lt;br /&gt;
&lt;br /&gt;
 &#039;&#039;&#039;algorithm&#039;&#039;&#039; k-means &#039;&#039;&#039;is&#039;&#039;&#039;&lt;br /&gt;
     &#039;&#039;&#039;1.&#039;&#039;&#039; Инициализировать центры кластеров &amp;lt;math&amp;gt;\mathbf{\mu}_i^{(1)}, i=\overline{1,k}&amp;lt;/math&amp;gt;&lt;br /&gt;
     &#039;&#039;&#039;2.&#039;&#039;&#039; &amp;lt;math&amp;gt;t \leftarrow 1&amp;lt;/math&amp;gt;&lt;br /&gt;
     &#039;&#039;&#039;3.&#039;&#039;&#039; &#039;&#039;&#039;Распределение по кластерам&#039;&#039;&#039;&amp;lt;br&amp;gt;&lt;br /&gt;
        &amp;lt;math&amp;gt;S_i^{(t)}=\{\mathbf{x}_p: \lVert\mathbf{x}_p-\mathbf{\mu}_i^{(t)}\rVert^2 \leq \lVert\mathbf{x}_p-\mathbf{\mu}_j^{(t)}\rVert^2 \quad \forall j=\overline{1,k}\},&amp;lt;/math&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
        где каждый вектор &amp;lt;math&amp;gt;\mathbf{x}_p&amp;lt;/math&amp;gt; соотносится единственному кластеру &amp;lt;math&amp;gt;S^{(t)}&amp;lt;/math&amp;gt;&lt;br /&gt;
     &#039;&#039;&#039;4.&#039;&#039;&#039; &#039;&#039;&#039;Обновление центров кластеров&#039;&#039;&#039;&amp;lt;br&amp;gt;&lt;br /&gt;
        &amp;lt;math&amp;gt;\mathbf{\mu}_i^{(t+1)} = \frac{1}{|S^{(t)}_i|} \sum_{\mathbf{x}_j \in S^{(t)}_i} \mathbf{x}_j &amp;lt;/math&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
     &#039;&#039;&#039;5.&#039;&#039;&#039; &#039;&#039;&#039;if&#039;&#039;&#039; &amp;lt;math&amp;gt;\exist i \in \overline{1,k}: \mathbf{\mu}_i^{(t+1)} \ne \mathbf{\mu}_i^{(t)}&amp;lt;/math&amp;gt; &#039;&#039;&#039;then&#039;&#039;&#039;&lt;br /&gt;
            t = t + 1;&lt;br /&gt;
            goto &#039;&#039;&#039;3&#039;&#039;&#039;;&lt;br /&gt;
        &#039;&#039;&#039;else&#039;&#039;&#039;&lt;br /&gt;
            &#039;&#039;&#039;stop&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
=== Последовательная сложность алгоритма===&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding-bottom: 20px&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;Обозначим &amp;lt;math&amp;gt;\Theta_{centroid}^{d, m}&amp;lt;/math&amp;gt; временную сложность вычисления центорида кластера, число элементов которого равна &amp;lt;math&amp;gt;m&amp;lt;/math&amp;gt;,  в d-мерном пространстве.&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;Аналогично  &amp;lt;math&amp;gt;\Theta_{distance}^d&amp;lt;/math&amp;gt; &amp;amp;ndash; временная сложность вычисления расстояния между двумя d-мерными векторами.&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding-bottom: 20px&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;Сложность шага инициализации &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластеров мощности &amp;lt;math&amp;gt;m&amp;lt;/math&amp;gt; в d-мерном пространстве &amp;amp;ndash; &amp;lt;math&amp;gt;\Theta_{init}^{k, d, m}&amp;lt;/math&amp;gt;&amp;lt;/b&amp;gt;&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;i&amp;gt;Стратерия Forgy&amp;lt;/i&amp;gt;: вычисления не требуются, &amp;lt;math&amp;gt;\Theta_{init}^{k, d, m} = 0&amp;lt;/math&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;i&amp;gt;Стратегия случайного разбиения&amp;lt;/i&amp;gt;: вычисление центров &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластеров,  &amp;lt;math&amp;gt;\Theta_{init}^{k, d, m} = k \cdot \Theta_{centroid}^{d, m}, m \le n&amp;lt;/math&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding-bottom: 20px&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Cложность шага распределения d мерных векторов по &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластерам &amp;amp;ndash; &amp;lt;math&amp;gt;\Theta_{distribute}^{k, d}&amp;lt;/math&amp;gt;&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
На этом шаге для каждого вектора &amp;lt;math&amp;gt;\mathbf{x}_i \in X, i=\overline{1, n}&amp;lt;/math&amp;gt; вычисляется k расстояний до центров кластеров &amp;lt;math&amp;gt;\mathbf{\mu}_1, ...\mathbf{\mu}_k&amp;lt;/math&amp;gt;&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p align=&amp;quot;center&amp;quot;&amp;gt;&lt;br /&gt;
  &amp;lt;math&amp;gt;\Theta_{distribute}^{k, d} = n \cdot k \cdot \Theta_{distance}^d&amp;lt;/math&amp;gt;&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding-bottom: 20px&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;Сложность шага пересчета центров &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластеров размера &amp;lt;math&amp;gt;m&amp;lt;/math&amp;gt; в d-мерном пространстве &amp;amp;ndash; &amp;lt;math&amp;gt;\Theta_{recenter}^{k, d, m}&amp;lt;/math&amp;gt;&amp;lt;/b&amp;gt;&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;На этом шаге вычисляется &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; центров кластеров &amp;lt;math&amp;gt;\mathbf{\mu}_1, ...\mathbf{\mu}_k&amp;lt;/math&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p align=&amp;quot;center&amp;quot;&amp;gt;&amp;lt;math&amp;gt;\Theta_{recenter}^{k, d, m} = k \cdot \Theta_{centroid}^{d, m}&amp;lt;/math&amp;gt; &amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding-bottom: 20px&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Рассчитаем &amp;lt;math&amp;gt;\Theta_{centroid}^{d, m}&amp;lt;/math&amp;gt; для кластера, число элементов которого равно &amp;lt;math&amp;gt;m&amp;lt;/math&amp;gt;&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p align=&amp;quot;center&amp;quot;&amp;gt;&amp;lt;math&amp;gt;\Theta_{centroid}^{d, m}&amp;lt;/math&amp;gt; = &amp;lt;math&amp;gt;m \cdot d&amp;lt;/math&amp;gt; сложений + &amp;lt;math&amp;gt;d&amp;lt;/math&amp;gt; делений &amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding-bottom: 20px&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Рассчитаем &amp;lt;math&amp;gt;\Theta_{distance}^d&amp;lt;/math&amp;gt; в соответствие с формулой &amp;lt;math&amp;gt;(2)&amp;lt;/math&amp;gt;&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p align=&amp;quot;center&amp;quot;&amp;gt;&amp;lt;math&amp;gt;\Theta_{distance}^d&amp;lt;/math&amp;gt; = &amp;lt;math&amp;gt;d&amp;lt;/math&amp;gt; вычитаний + &amp;lt;math&amp;gt;d&amp;lt;/math&amp;gt; умножений + &amp;lt;math&amp;gt;(d-1)&amp;lt;/math&amp;gt; сложение&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding-bottom: 20px&amp;quot;&amp;gt;&lt;br /&gt;
  &amp;lt;p&amp;gt;Предположим, что алгоритм сошелся за &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt; итераций, тогда временная сложность алгоритма &amp;lt;math&amp;gt;\Theta_{k-means}^{d, n}&amp;lt;/math&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
  &amp;lt;p align=&amp;quot;center&amp;quot;&amp;gt;&amp;lt;b&amp;gt;&amp;lt;math&amp;gt;\Theta_{k-means}^{d, n} \le \Theta_{init}^{k, d, n} + i(\Theta_{distribute}^{k, d} + \Theta_{recenter}^{k, d, n})&amp;lt;/math&amp;gt;&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding-bottom: 5px&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;Операции сложения/вычитания:&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p align=&amp;quot;center&amp;quot;&amp;gt;&amp;lt;b&amp;gt;&amp;lt;math&amp;gt;\Theta_{k-means}^{d, n} \le knd+ i(kn(2d-1) + knd) = knd+ i(kn(3d-1)) \thicksim O(ikdn)&amp;lt;/math&amp;gt;&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding-bottom: 20px&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;Операции умножения/деления:&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p align=&amp;quot;center&amp;quot;&amp;gt;&amp;lt;b&amp;gt;&amp;lt;math&amp;gt;\Theta_{k-means}^{d, n} \le kd + i(knd + kd) = kd + ikd(n+1) \thicksim O(ikdn) &amp;lt;/math&amp;gt;&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding-bottom: 20px&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;Получаем, что &amp;lt;b&amp;gt;временная сложность&amp;lt;/b&amp;gt; алгоритма &amp;lt;b&amp;gt;k means&amp;lt;/b&amp;gt; кластеризации &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; &amp;lt;b&amp;gt;d-мерных&amp;lt;/b&amp;gt; векторов на &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластеров за &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt; итераций:&amp;lt;/p&amp;gt;&lt;br /&gt;
 &amp;lt;p align=&amp;quot;center&amp;quot;&amp;gt;&amp;lt;b&amp;gt;&amp;lt;math&amp;gt; \Theta_{k-means}^{d, n} \thicksim O(ikdn) &amp;lt;/math&amp;gt;&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Информационный граф ===&lt;br /&gt;
&lt;br /&gt;
Рассмотрим информационный граф алгоритма. Алгоритм &amp;lt;i&amp;gt;k means&amp;lt;/i&amp;gt; начинается с этапа инициализации, после которого следуют итерации, на каждой из которых выполняется два последовательных шага (см. [[#Схема реализации последовательного алгоритма|&amp;quot;Схема реализации последовательного алгоритма&amp;quot;]]): &lt;br /&gt;
* распределение векторов по кластерам&lt;br /&gt;
* перерасчет центров кластеров&lt;br /&gt;
&lt;br /&gt;
Поскольку основная часть вычислений приходится на шаги итераций, распишем информационные графы данных шагов.&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Распределение векторов по кластерам&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
Информационный граф шага распределения векторов по кластерам представлен на &#039;&#039;рисунке 1&#039;&#039;. Исходами данного графа является исходные векторы &amp;lt;math&amp;gt;\mathbf{x}_1, ..., \mathbf{x}_n&amp;lt;/math&amp;gt;, а также центры кластеров &amp;lt;math&amp;gt;\mathbf{\mu}_1, ... \mathbf{\mu}_k&amp;lt;/math&amp;gt;, вычисленные ранее (на шаге инициализации, если рассматривается первая итерация алгоритма, или на шаге пересчета центров кластеров предыдущей итерации в противном случае). Каждая пара векторов данных &amp;lt;math&amp;gt;\mathbf{x}_i, i=\overline{1,n}&amp;lt;/math&amp;gt; и центров кластера &amp;lt;math&amp;gt;\mathbf{\mu}_j, j=\overline{1, k}&amp;lt;/math&amp;gt; : (&amp;lt;math&amp;gt;\mathbf{x}_i&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;\mathbf{\mu}_j&amp;lt;/math&amp;gt;) подаются на независимые узлы &amp;lt;i&amp;gt;&amp;quot;d&amp;quot;&amp;lt;/i&amp;gt; вычисления расстояния между векторами (более подробная схема вычисления расстояния представлена далее, &#039;&#039;рисунок 2&#039;&#039;). Далее узлы вычисления расстояния &amp;lt;i&amp;gt;&amp;quot;d&amp;quot;&amp;lt;/i&amp;gt;, соответствующие одному и тому же исходному вектору &amp;lt;math&amp;gt;\mathbf{x}_i&amp;lt;/math&amp;gt; передаются на один узел &amp;lt;i&amp;gt;&amp;quot;m&amp;quot;&amp;lt;/i&amp;gt;, где далее происходит вычисление новой метки кластера для каждого вектора &amp;lt;math&amp;gt;\mathbf{x}_i&amp;lt;/math&amp;gt; (берется кластер с минимальным результатом вычисления расстояния). На выходе графа выдаются метки кластеров , &amp;lt;math&amp;gt;L_1, ..., L_n&amp;lt;/math&amp;gt;, такие что &amp;lt;math&amp;gt;\forall \mathbf{x}_i, i=\overline{1, n}, \mathbf{x}_i \in S_j \Leftrightarrow L_i = j&amp;lt;/math&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
[[file:Clusterization.png|thumb|center|800px|Рис. 1. Схема распределения векторов по кластерам. &#039;&#039;d&#039;&#039; &amp;amp;ndash; вычисление расстояния между векторами; &#039;&#039;m&#039;&#039; &amp;amp;ndash; вычисление минимума.]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Вычисление расстояния между векторами&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
Подробная схема вычисления расстояния между векторами &amp;lt;math&amp;gt;\mathbf{x}_i, \mathbf{\mu}_j&amp;lt;/math&amp;gt; представлена на &#039;&#039;рисунке 2&#039;&#039;. Как показано на графе, узел вычисления расстояния между векторами &amp;lt;i&amp;gt;&amp;quot;d&amp;quot;&amp;lt;/i&amp;gt; состоит из шага взятия разности между векторами (узел &amp;quot;&amp;lt;math&amp;gt;-&amp;lt;/math&amp;gt;&amp;quot;) и взятия нормы получившегося вектора разности (узел &amp;quot;&amp;lt;math&amp;gt;||\cdot||^2&amp;lt;/math&amp;gt;&amp;quot;). Более подробно, вычисление расстояния между векторами &amp;lt;math&amp;gt;\mathbf{x}_i = {x_{i1,}, ...,{x_{in}}}, \mathbf{\mu}_j = {\mu_{j1}, ...,\mu_{jn}}&amp;lt;/math&amp;gt; может быть представлено как вычисление разности между каждой парой компонент &amp;lt;math&amp;gt;(x_{iz}, \mu_{jz}), z=\overline{1, d}&amp;lt;/math&amp;gt; (узел &amp;quot;&amp;lt;math&amp;gt;-&amp;lt;/math&amp;gt;&amp;quot;), далее возведение в квадрат для каждого узла &amp;quot;&amp;lt;math&amp;gt;-&amp;lt;/math&amp;gt;&amp;quot; (узел &amp;quot;&amp;lt;math&amp;gt;()^2&amp;lt;/math&amp;gt;&amp;quot;) и суммирования выходов всех узлов &amp;quot;&amp;lt;math&amp;gt;()^2&amp;lt;/math&amp;gt;&amp;quot; (узел &amp;quot;&amp;lt;math&amp;gt;+&amp;lt;/math&amp;gt;&amp;quot;).  &lt;br /&gt;
&lt;br /&gt;
[[file:dist_calc.png|thumb|center|800px|Рис. 2. Схема вычисления расстояния между вектором и центром кластера.]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Пересчет центров кластеров&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
Информационный граф шага пересчета центров кластеров представлен на &#039;&#039;рисунке 3&#039;&#039;. Исходами данного графа является исходные векторы &amp;lt;math&amp;gt;\mathbf{x}_1, ..., \mathbf{x}_n&amp;lt;/math&amp;gt;, а также им соответствующие метки кластера, &amp;lt;math&amp;gt;L_1, ..., L_n&amp;lt;/math&amp;gt;, такие что &amp;lt;math&amp;gt;\forall x_i, i=\overline{1, n}, \mathbf{x}_i \in S_j \Leftrightarrow L_i = j&amp;lt;/math&amp;gt;, вычисленные на этапе распределения векторов по кластерам. Все векторы &amp;lt;math&amp;gt;\mathbf{x}_1, ..., \mathbf{x}_n&amp;lt;/math&amp;gt; подаются в узлы &amp;lt;math&amp;gt;+_1, ...+_k&amp;lt;/math&amp;gt;, каждый узел &amp;lt;math&amp;gt;+_m, m = \overline{1,k}&amp;lt;/math&amp;gt; соответствует операции сложения векторов кластера с номером &amp;lt;math&amp;gt;m&amp;lt;/math&amp;gt;. Метки кластера &amp;lt;math&amp;gt;L_1, ..., L_n&amp;lt;/math&amp;gt; также совместно передаются на узлы &amp;lt;math&amp;gt;S_m, m = \overline{1,k}&amp;lt;/math&amp;gt;, на каждом из которых вычисляется количество векторов в соответствующем кластере (количество меток с соответствующим значением). Далее каждая пара выходов узлов &amp;lt;math&amp;gt;+_m&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;S_m&amp;lt;/math&amp;gt; подается на узел &amp;quot;&amp;lt;math&amp;gt;/&amp;lt;/math&amp;gt;&amp;quot;, где производится деление суммы векторов кластера на количество элементов в нем. Значения, вычисленные на узлах &amp;quot;&amp;lt;math&amp;gt;/&amp;lt;/math&amp;gt;&amp;quot;, присваиваются новым центрам кластеров (выходные значения графа).&lt;br /&gt;
&lt;br /&gt;
[[file:Recluster.png|thumb|center|800px|Рис. 3. Схема пересчета центров кластеров]]&lt;br /&gt;
&lt;br /&gt;
=== Ресурс параллелизма алгоритма ===&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
Работа алгоритма состоит из &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt; итераций, в каждой из которых происходит &amp;lt;b&amp;gt;распределение d-мерных векторов по &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластерам&amp;lt;/b&amp;gt;, а также &amp;lt;b&amp;gt;пересчет центров кластеров в d-мерном пространстве&amp;lt;/b&amp;gt;. В шаге &amp;lt;b&amp;gt;распределения d-мерных векторов по &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластерам&amp;lt;/b&amp;gt; расстояния между вектором и центрами кластеров вычисляются независимо (отсутствуют информационные зависимости). &amp;lt;b&amp;gt;Центры масс кластеров&amp;lt;/b&amp;gt; также пересчитываются независимо друг от друга. Таким образом, имеет место [[глоссарий#Массовый параллелизм|&#039;&#039;массовый параллелизм&#039;&#039;]]. Вычислим параллельную сложность &amp;lt;math&amp;gt;\Psi_*&amp;lt;/math&amp;gt; каждого из шагов, а также параллельную сложность всего алгоритма, &amp;lt;math&amp;gt;\Psi_{k-means}&amp;lt;/math&amp;gt;. Будем исходить из предположения, что может быть использовано любое необходимое число потоков.&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Распределение d-мерных векторов по &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластерам&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;  &lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
Поскольку на данном шаге для каждой пары векторов &amp;lt;math&amp;gt;\mathbf{x}_i, i=\overline{1,n}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\mathbf{\mu}_j, j=\overline{1,k}&amp;lt;/math&amp;gt; операции вычисления расстояния не зависят друг от друга, они могут выполняться параллельно. Тогда, разделив все вычисление расстояний на &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; потоков, получим, что в каждом потоке будет выполняться только одна операция вычисления расстояния между векторами размерности d. При этом каждому вычислительному потоку передаются координаты центров всех кластеров &amp;lt;math&amp;gt;\mathbf{\mu}_1, ..., \mathbf{\mu}_k&amp;lt;/math&amp;gt;. Таким образом, параллельная сложность данного шага определяется &amp;lt;i&amp;gt; сложностью параллельной операции вычисления расстояния между d-мерными векторами&amp;lt;/i&amp;gt;, &amp;lt;math&amp;gt;\Psi_{distance}^d&amp;lt;/math&amp;gt;  и &amp;lt;i&amp;gt;сложностью определения наиболее близкого кластера&amp;lt;/i&amp;gt; (паралельное взятие минимума по расстояниям), &amp;lt;math&amp;gt;\Psi_{min}^k&amp;lt;/math&amp;gt;. Для оценки &amp;lt;math&amp;gt;\Psi_{distance}^d&amp;lt;/math&amp;gt; воспользуемся  [[Нахождение_частных_сумм_элементов_массива_сдваиванием | параллельной реализацией нахождения частичной суммы элементов массива путем сдваивания]]. Аналогично, &amp;lt;math&amp;gt;\Psi_{min}^k = log(k)&amp;lt;/math&amp;gt;. В результате, &amp;lt;math&amp;gt;\Psi_{distance}^d = O(log(d))&amp;lt;/math&amp;gt;.   Таким образом: &lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p align=&amp;quot;center&amp;quot;&amp;gt;&amp;lt;math&amp;gt;\Psi_{distribute}^{k, d}  = \Psi_{distance}^d + \Psi_{min}^k = O(log(d))+O(log(k)) = O(log(k \cdot d))&amp;lt;/math&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Пересчет центров кластеров в d-мерном пространстве&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
Поскольку на данном шаге для каждого из &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластеров центр масс может быть вычислен независимо, данные операции могут быть выполнены в отдельных потоках. Таким образом, параллельная сложность данного шага, &amp;lt;math&amp;gt;\Psi_{recenter}^{k, d}&amp;lt;/math&amp;gt;,  будет определяться &amp;lt;i&amp;gt;параллельной сложностью вычисления одного центра масс кластера размера &amp;lt;math&amp;gt;m&amp;lt;/math&amp;gt;&amp;lt;/i&amp;gt;, &amp;lt;math&amp;gt;\Psi_{recenter}^{k, d}&amp;lt;/math&amp;gt;,  а так как &amp;lt;math&amp;gt;m \le n \Rightarrow \Psi_{recenter}^{d, m} \le \Psi_{recenter}^{d, n}&amp;lt;/math&amp;gt;. Сложность вычисления центра масс кластера d-мерных векторов размера n аналогично предыдущим вычислениям равна &amp;lt;math&amp;gt;O(log(n))&amp;lt;/math&amp;gt;. Тогда:  &lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p align=&amp;quot;center&amp;quot;&amp;gt;&amp;lt;math&amp;gt;\Psi_{recenter}^{k, d}  \le \Psi_{recenter}^{d, n} = O(log(n))&amp;lt;/math&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Общая параллельная сложность алгоритма&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
На каждой итерации необходимо обновление центров кластеров, которые будут использованы на следующей итерации. Таким образом, итерационный процесс выполняется последовательно&amp;lt;ref&amp;gt;Zhao, Weizhong, Huifang Ma, and Qing He. &amp;quot;Parallel k-means clustering based on mapreduce.&amp;quot; IEEE International Conference on Cloud Computing. Springer Berlin Heidelberg, 2009.&amp;lt;/ref&amp;gt;. Тогда, поскольку сложность каждой итерации  определяется &amp;lt;math&amp;gt;\Psi_{distribute}^{k, d}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\Psi_{recenter}&amp;lt;/math&amp;gt;, сложность всего алгоритма, &amp;lt;math&amp;gt;\Psi_{k-means}&amp;lt;/math&amp;gt; в предположении, что было сделано &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt; операций определяется выражением&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p align=&amp;quot;center&amp;quot;&amp;gt;&amp;lt;math&amp;gt;\Psi_{k-means} \approx i \cdot (\Psi_{distribute}^{k, d} + \Psi_{recenter}^{k, d}) \le i \cdot O(log(kdn))&amp;lt;/math&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Входные и выходные данные алгоритма ===&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;Входные данные&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;Матрица из &amp;lt;math&amp;gt;n \cdot d&amp;lt;/math&amp;gt; элементов &amp;lt;math&amp;gt;x_{i, j} \in \mathbb{R}, i=\overline{1, n}, j=\overline{1, d}&amp;lt;/math&amp;gt;&amp;amp;ndash; координат векторов (наблюдений).&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;Целое положительное число &amp;lt;math&amp;gt;k, k \le n&amp;lt;/math&amp;gt; &amp;amp;ndash; количество кластеров.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;Объем входных данных&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;math&amp;gt;1&amp;lt;/math&amp;gt; целое число + &amp;lt;math&amp;gt;n \cdot d&amp;lt;/math&amp;gt; вещественных чисел (при условии, что координаты &amp;amp;ndash; вещественные числа).&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;Выходные данные&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; целых положительных чисел &amp;lt;math&amp;gt;L_1, ..., L_n&amp;lt;/math&amp;gt;&amp;amp;ndash; номера кластеров, соотвествующие каждому вектору (при условии, что нумерация кластеров начинается с &amp;lt;math&amp;gt;1&amp;lt;/math&amp;gt;).&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;Объем выходных данных&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; целых положительных чисел.&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Свойства алгоритма ===&lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;[[глоссарий#Вычислительная мощность|&#039;&#039;Вычислительная мощность&#039;&#039;]]&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
Вычислительная мощность алгоритма &amp;lt;i&amp;gt;k means&amp;lt;/i&amp;gt; равна &amp;lt;math&amp;gt;\frac{ikdn}{n \cdot d} = k \cdot i &amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; &amp;amp;ndash; число кластеров, &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt; &amp;amp;ndash; число итераций алгоритма.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;[[глоссарий#Детерминированность |&#039;&#039;Детерминированность&#039;&#039;]] и [[глоссарий#Устойчивость |&#039;&#039;Устойчивость&#039;&#039;]] &amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
Алгоритм &amp;lt;i&amp;gt;k means&amp;lt;/i&amp;gt; является итерационным. Количество итераций алгоритма в общем случае не фиксируется и зависит от начального расположения объектов в пространстве, параметра &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt;, а также от начального приближения центров кластеров, &amp;lt;math&amp;gt;\mu_1, ..., \mu_k&amp;lt;/math&amp;gt;. В результате этого может варьироваться результат работы алгоритма. При неудачном выборе начальных параметров итерационный процесс может сойтись к локальному оптимуму&amp;lt;ref&amp;gt;Von Luxburg, Ulrike. Clustering Stability. Now Publishers Inc, 2010.&amp;lt;/ref&amp;gt;. По этим причинам алгоритм не является ни &amp;lt;b&amp;gt;детермирированным&amp;lt;/b&amp;gt;, ни &amp;lt;b&amp;gt;устойчивым&amp;lt;/b&amp;gt;.&lt;br /&gt;
 &lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Соотношение последовательной и параллельной сложности алгоритма&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\frac{\Theta_{k-means}}{\Psi_{k-means}} = \frac{O(ikdn)}{O(i \cdot log(kdn))}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Сильные стороны алгоритма&amp;lt;/b&amp;gt;:&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;i&amp;gt;Сравнительно высокая эффективность при простоте реализации&amp;lt;/i&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;i&amp;gt;Высокое качество кластеризации&amp;lt;/i&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;i&amp;gt;Возможность распараллеливания&amp;lt;/i&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;i&amp;gt;Существование множества модификаций&amp;lt;/i&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;Недостатки алгоритма&amp;lt;/b&amp;gt;&amp;lt;ref&amp;gt;Ortega, Joaquín Pérez, Ma Del Rocío Boone Rojas, and María J. Somodevilla. &amp;quot;Research issues on K-means Algorithm: An Experimental Trial Using Matlab.&amp;quot;&amp;lt;/ref&amp;gt;:&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;i&amp;gt;Количество кластеров является параметром алгоритма&amp;lt;/i&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;&amp;lt;i&amp;gt;Чувствительность к начальным условиям&amp;lt;/i&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;Инициализация центров кластеров в значительной степени влияет на результат кластеризации.&amp;lt;/p&amp;gt;&lt;br /&gt;
  &amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;&amp;lt;i&amp;gt;Чувствительность к выбросам и шумам&amp;lt;/i&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;Выбросы, далекие от центров настоящих кластеров, все равно учитываются при вычислении их центров.&amp;lt;/p&amp;gt;&lt;br /&gt;
  &amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;&amp;lt;i&amp;gt;Возможность сходимости к локальному оптимуму&amp;lt;/i&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;Итеративный подход не дает гарантии сходимости к оптимальному решению.&amp;lt;/p&amp;gt;&lt;br /&gt;
  &amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;&amp;lt;i&amp;gt;Использование понятия &amp;quot;среднего&amp;quot;&amp;lt;/i&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;Алгоритм неприменим к данным, для которых не определено понятие &amp;quot;среднего&amp;quot;, например, категориальным данным.&amp;lt;/p&amp;gt;&lt;br /&gt;
  &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&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;
Исследование масштабируемости параллельной реализации алгоритма k means проводилось на суперкомпьютере &amp;quot;Ломоносов&amp;quot;&amp;lt;ref name=&amp;quot;Lom&amp;quot;&amp;gt;Воеводин Вл., Жуматий С., Соболев С., Антонов А., Брызгалов П., Никитенко Д., Стефанов К., Воеводин Вад. Практика суперкомпьютера «Ломоносов» // Открытые системы, 2012, N 7, С. 36-39.&amp;lt;/ref&amp;gt; [http://parallel.ru/cluster Суперкомпьютерного комплекса Московского университета]. Алгоритм реализован на языке C с использованием средств MPI.&lt;br /&gt;
Для исследования масштабируемости проводилось множество запусков программы с разным значением параметра (количество векторов для кластеризации), а также с различным числом процессоров. Фиксировались результаты запусков &amp;amp;ndash; время работы &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt; и количество произведенных итераций алгоритма &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Параметры запусков для экспериментальной оценки:&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;Значения &amp;lt;b&amp;gt;количества векторов&amp;lt;/b&amp;gt; &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;: 20&#039;000, 30&#039;000, 50&#039;000, 100&#039;000, 200&#039;000, 300&#039;000, 500&#039;000, 700&#039;000, 1&#039;000&#039;000, 1&#039;500&#039;000, 2&#039;000&#039;000.&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;Значения &amp;lt;b&amp;gt;количества процессоров&amp;lt;/b&amp;gt; &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt;: 1, 8, 16, 32, 64, 128, 160, 192, 224, 256, 288, 320, 352, 384, 416, 448, 480, 512.&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;Значение &amp;lt;b&amp;gt;количества кластеров&amp;lt;/b&amp;gt; &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt;: 100.&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;Значение &amp;lt;b&amp;gt;размерности векторов&amp;lt;/b&amp;gt; &amp;lt;math&amp;gt;d&amp;lt;/math&amp;gt;: 10.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Для проведения экспериментов были сгенерированы нормально распределенные псевдослучайные данные (с использованием Python библиотеки [http://scikit-learn.org/ scikit-learn]):&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
from sklearn.datasets import make_classification&lt;br /&gt;
X1, Y1 = make_classification(n_features=10, n_redundant=2, n_informative=8,&lt;br /&gt;
                             n_clusters_per_class=1, n_classes=100,&lt;br /&gt;
                             n_samples=2000000)&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Для заданной конфигурации эксперимента (&amp;lt;math&amp;gt;n, d, p, k&amp;lt;/math&amp;gt;) и полученных результатов (&amp;lt;math&amp;gt;t, i&amp;lt;/math&amp;gt;)  [[Глоссарий#Производительность|производительность]]  и эффективность реализации расчитывались по формулам:&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
&amp;lt;ul&amp;gt;&amp;lt;li&amp;gt;&amp;lt;math&amp;gt;Performance = \frac{N_{k-means}^{d, n}}{t}\ \ (FLOPS),&amp;lt;/math&amp;gt;&amp;lt;/li&amp;gt;&amp;lt;/ul&amp;gt;&lt;br /&gt;
где &amp;lt;math&amp;gt;N_{k-means}^{d, n}&amp;lt;/math&amp;gt; &amp;amp;ndash; точное число операций с плавающей точкой (операции с памятью, а также целочисленные операции не учитывались), вычисленное в соответствие с разделом [[#Последовательная сложность алгоритма| &amp;quot;Последовательная сложность алгоритма&amp;quot;]];&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
&amp;lt;ul&amp;gt;&amp;lt;li&amp;gt;&amp;lt;math&amp;gt;Efficiency = \frac{100 \cdot Performance}{Performance_{Peak}^{p}}\ \ (%),&amp;lt;/math&amp;gt;&amp;lt;/li&amp;gt;&amp;lt;/ul&amp;gt;&lt;br /&gt;
где &amp;lt;math&amp;gt;Performance_{Peak}^{p}&amp;lt;/math&amp;gt; &amp;amp;ndash; пиковая производительность суперкомпьютера при &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt; процессорах, вычисленная согласно спецификациям Intel&amp;lt;sup&amp;gt;&amp;amp;reg;&amp;lt;/sup&amp;gt; XEON&amp;lt;sup&amp;gt;&amp;amp;reg;&amp;lt;/sup&amp;gt; X5670&amp;lt;ref&amp;gt;&amp;quot;http://ark.intel.com/ru/products/47920/Intel-Xeon-Processor-X5670-12M-Cache-2_93-GHz-6_40-GTs-Intel-QPI&amp;quot;&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Графики зависимости производительности и эффективности параллельной реализации k means от числа векторов для кластеризации (&amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;) и числа процессоров (&amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt;) представлены на рисунках 4 и 5 соответственно.&lt;br /&gt;
&lt;br /&gt;
[[file:Flops.png|thumb|center|800px|Рис. 4. Параллельная реализация k means. График зависимости производительности реализации алгоритма от числа векторов для кластеризации (&amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;) и числа процессоров (&amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt;).]]&lt;br /&gt;
[[file:Efficiency.png|thumb|center|800px|Рис. 5. Параллельная реализация k means. График зависимости эффективности реализации алгоритма от числа векторов для кластеризации (&amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;) и числа процессоров (&amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt;).]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;В результате&amp;lt;/b&amp;gt; экспериментальной оценки были получены следующие оценки эффективности реализации:&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;b&amp;gt;Минимальное&amp;lt;/b&amp;gt; значение: 0.000409 % достигается при &amp;lt;math&amp;gt;n=20&#039;000, p=480&amp;lt;/math&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;b&amp;gt;Максимальное&amp;lt;/b&amp;gt; значение: 0.741119 % достигается при &amp;lt;math&amp;gt;n=300&#039;000, p=1&amp;lt;/math&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
Оценки масштабируемости реализации алгоритма k means:&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;b&amp;gt;По числу процессоров:&amp;lt;/b&amp;gt; -0.002683 &amp;amp;ndash; эффективность убывает с ростом числа процессоров. Данный результат вызван ростом накладных расходов для обеспечения параллельного выполнения алгоритма.&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;b&amp;gt;По размеру задачи:&amp;lt;/b&amp;gt; 0.002779 &amp;amp;ndash; эффективность растет с ростом числа векторов. Данный результат вызван тем, что при увеличении размера задачи, количество вычислений растет по сравнению с временем, затрачиваемым на пересылку данных.&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;b&amp;gt;Общая оценка:&amp;lt;/b&amp;gt; -0.000058 &amp;amp;ndash; можно сделать вывод, что в целом эффективность реализации незначительно уменьшается с ростом размера задачи и числа процессоров.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[https://github.com/serban/kmeans Использованная параллельная реализация алгоритма k means]&lt;br /&gt;
&lt;br /&gt;
=== Динамические характеристики и эффективность реализации алгоритма ===&lt;br /&gt;
=== Выводы для классов архитектур ===&lt;br /&gt;
=== Существующие реализации алгоритма ===&lt;br /&gt;
==== Открытое программное обеспечение ====&lt;br /&gt;
&amp;lt;ol&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;[https://www.icpsr.umich.edu/CrimeStat/ CrimeStat]&amp;lt;/li&amp;gt; Программное обеспечение, созданное для операционных систем Windows, предоставляющее инструменты статистического  и пространственного анализа для решения задачи картирования преступности.&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://juliastats.github.io Julia]&amp;lt;/li&amp;gt; Высокоуровневый высокопроизводительный свободный язык программирования с динамической типизацией, созданный для математических вычислений, содержит реализацию k-means.&lt;br /&gt;
  &amp;lt;li&amp;gt;[https://mahout.apache.org Mahout]&amp;lt;/li&amp;gt; Apache Mahout - Java библиотека для работы с алгоритмами машинного обучения с использованием MapReduce. Содержит реализацию k-means.&lt;br /&gt;
  &amp;lt;li&amp;gt;[https://www.gnu.org/software/octave/ Octave]&amp;lt;/li&amp;gt; Написанная на C++  свободная система для математических вычислений, использующая совместимый с MATLAB язык высокого уровня, содержит реализацию k-means.&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://spark.apache.org/docs/latest/mllib-clustering.html Spark]&amp;lt;/li&amp;gt; Распределенная реализация k-means содержится в библиотеке Mlib для работы с алгоритмами машинного обучения, взаимодействующая с Python библиотекой NumPy и библиотека R.&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://torch.ch Torch]&amp;lt;/li&amp;gt;  MATLAB-подобная библиотека для языка программирования Lua с открытым исходным кодом, предоставляет большое количество алгоритмов для глубинного обучения и научных расчётов. Ядро написано на Си, прикладная часть выполняется на LuaJIT, поддерживается распараллеливание вычислений средствами CUDA и OpenMP. Существуют реализации k-means.&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://www.cs.waikato.ac.nz/ml/weka/ Weka]&amp;lt;/li&amp;gt;  Cвободное программное обеспечение для анализа данных, написанное на Java. Содержит k-means и x-means.&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://accord-framework.net/docs/html/T_Accord_MachineLearning_KMeans.htm Accord.NET]&amp;lt;/li&amp;gt; C# реализация алгоритмов k-means, k-means++, k-modes.&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://docs.opencv.org/3.0-beta/doc/py_tutorials/py_ml/py_kmeans/py_kmeans_opencv/py_kmeans_opencv.html OpenCV]&amp;lt;/li&amp;gt; Написанная на С++ библиотека, направленная в основном на решение задач компьютерного зрения. Содержит реализацию k-means.&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://mlpack.org/ MLPACK]&amp;lt;/li&amp;gt; Масштабируемая С++ библиотека для работы с алгоритмами машинного обучения, содержит реализацию k-means.&lt;br /&gt;
  &amp;lt;li&amp;gt;[https://www.scipy.org/ SciPy]&amp;lt;/li&amp;gt; Библиотека Python, содержит множество реализаций k-means.&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://scikit-learn.org/ scikit-learn]&amp;lt;/li&amp;gt; Библиотека Python, содержит множество реализаций k-means.&lt;br /&gt;
  &amp;lt;li&amp;gt;[https://www.r-bloggers.com/k-means-clustering-in-r/ R]&amp;lt;/li&amp;gt; Язык программирования для статистической обработки данных и работы с графикой, а также свободная программная среда вычислений с открытым исходным кодом в рамках проекта GNU, содержит три реализации k-means.&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://elki.dbs.ifi.lmu.de ELKI]&amp;lt;/li&amp;gt; Java фреймворк, содержащий реализацию k-means, а также множество других алгоритмов кластеризации.&lt;br /&gt;
&amp;lt;/ol&amp;gt;&lt;br /&gt;
==== Проприетарное программное обеспечение  ====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ol&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;[https://www.ayasdi.com/blog/bigdata/topological-data-analysis-of-oil-and-gas-petrophysical-data/ Ayasdi]&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://www.stata.com/features/cluster-analysis/ Stata]&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://mathworld.wolfram.com/K-MeansClusteringAlgorithm.html Mathematica]&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://www.mathworks.com/help/stats/kmeans.html?requestedDomain=www.mathworks.com MATLAB]&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;[https://support.sas.com/rnd/app/stat/procedures/fastclus.html SAS]&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://docs.rapidminer.com/studio/operators/modeling/segmentation/k_means.html RapidMiner]&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;[https://blogs.sap.com/2013/03/28/sap-hana-pal-k-means-algorithm-or-how-to-do-customer-segmentation-for-the-telecommunications-industry/ SAP HANA]&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ol&amp;gt;&lt;br /&gt;
== Литература ==&lt;br /&gt;
&amp;lt;references /&amp;gt;&lt;/div&gt;</summary>
		<author><name>DennZo1993</name></author>
	</entry>
	<entry>
		<id>https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:%D0%91%D1%80%D0%BE%D1%82%D0%B8%D0%BA%D0%BE%D0%B2%D1%81%D0%BA%D0%B0%D1%8F_%D0%94%D0%B0%D0%BD%D1%83%D1%82%D0%B0/%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_k-means&amp;diff=20527</id>
		<title>Участник:Бротиковская Данута/Алгоритм k-means</title>
		<link rel="alternate" type="text/html" href="https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:%D0%91%D1%80%D0%BE%D1%82%D0%B8%D0%BA%D0%BE%D0%B2%D1%81%D0%BA%D0%B0%D1%8F_%D0%94%D0%B0%D0%BD%D1%83%D1%82%D0%B0/%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_k-means&amp;diff=20527"/>
		<updated>2016-12-10T10:49:48Z</updated>

		<summary type="html">&lt;p&gt;DennZo1993: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Assignment|Zhum}}&lt;br /&gt;
&lt;br /&gt;
{{algorithm&lt;br /&gt;
| name              = Алгоритм k средних (k means)&lt;br /&gt;
| serial_complexity = &amp;lt;math&amp;gt;O(ikdn)&amp;lt;/math&amp;gt;&lt;br /&gt;
| input_data        = &amp;lt;math&amp;gt; dn &amp;lt;/math&amp;gt;&lt;br /&gt;
| output_data       = &amp;lt;math&amp;gt; n &amp;lt;/math&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
Авторы страницы &amp;lt;b&amp;gt;[[Участник:Бротиковская Данута|Данута Бротиковская]]&amp;lt;/b&amp;gt; и &amp;lt;b&amp;gt;[[Участник:DennZo1993|Денис Зобнин]]&amp;lt;/b&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
Оба автора внесли одинаковый вклад в написание статьи (поиск материалов, изучение статей, заполнение контента статьи), четких разграничений по пунктам статьи сделать невозможно. &lt;br /&gt;
&lt;br /&gt;
== Свойства и структура алгоритма ==&lt;br /&gt;
&lt;br /&gt;
=== Общее описание алгоритма ===&lt;br /&gt;
Алгоритм &amp;lt;b&amp;gt;&amp;lt;i&amp;gt;k средних&amp;lt;/i&amp;gt;&amp;lt;/b&amp;gt; (&amp;lt;b&amp;gt;&amp;lt;i&amp;gt;k means&amp;lt;/i&amp;gt;&amp;lt;/b&amp;gt;) &amp;amp;ndash; неиерархический&amp;lt;ref&amp;gt;&amp;quot;https://ru.wikipedia.org/wiki/Иерархическая_кластеризация&amp;quot;&amp;lt;/ref&amp;gt;, итерационный метод кластеризации&amp;lt;ref&amp;gt;&amp;quot;https://ru.wikipedia.org/wiki/Кластерный_анализ&amp;quot;&amp;lt;/ref&amp;gt;, получивший большую популярность благодаря своей простоте, наглядности реализации и достаточно высокому качеству работы. Был изобретен в 1950-х годах математиком &amp;lt;i&amp;gt;Гуго Штейнгаузом&amp;lt;/i&amp;gt;&amp;lt;ref&amp;gt;Steinhaus, Hugo. &amp;quot;Sur la division des corp materiels en parties.&amp;quot; Bull. Acad. Polon. Sci 1.804 (1956): 801.&amp;lt;/ref&amp;gt; и почти одновременно &amp;lt;i&amp;gt;Стюартом Ллойдом&amp;lt;/i&amp;gt;&amp;lt;ref&amp;gt;Lloyd, S. P. &amp;quot;Least square quantization in PCM. Bell Telephone Laboratories Paper. Published in journal much later: Lloyd, SP: Least squares quantization in PCM.&amp;quot; IEEE Trans. Inform. Theor.(1957/1982).&amp;lt;/ref&amp;gt;. Особую популярность приобрел после публикации работы &amp;lt;i&amp;gt;МакКуина&amp;lt;/i&amp;gt;&amp;lt;ref&amp;gt;MacQueen, James. &amp;quot;Some methods for classification and analysis of multivariate observations.&amp;quot; Proceedings of the fifth Berkeley symposium on mathematical statistics and probability. Vol. 1. No. 14. 1967.&amp;lt;/ref&amp;gt; в 1967.&lt;br /&gt;
&lt;br /&gt;
Алгоритм представляет собой версию EM-алгоритма&amp;lt;ref&amp;gt;&amp;quot;https://ru.wikipedia.org/wiki/EM-алгоритм&amp;quot;&amp;lt;/ref&amp;gt;, применяемого также для разделения смеси гауссиан. Основная идея &amp;lt;i&amp;gt;k means&amp;lt;/i&amp;gt; заключается в том, что данные произвольно разбиваются на кластеры, после чего итеративно перевычисляется центр масс для каждого кластера, полученного на предыдущем шаге, затем векторы разбиваются на кластеры вновь в соответствии с тем, какой из новых центров оказался ближе по выбранной метрике.&lt;br /&gt;
&lt;br /&gt;
Цель алгоритма заключается в разделении &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; наблюдений на &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластеров таким образом, чтобы каждое наблюдение принадлежало ровно одному кластеру, расположенному на наименьшем расстоянии от наблюдения.&lt;br /&gt;
&lt;br /&gt;
=== Математическое описание алгоритма ===&lt;br /&gt;
&amp;lt;b&amp;gt;&amp;lt;u&amp;gt;Дано:&amp;lt;/u&amp;gt;&amp;lt;/b&amp;gt;&lt;br /&gt;
* набор из &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; наблюдений &amp;lt;math&amp;gt;X=\{\mathbf{x}_1, \mathbf{x}_2, ..., \mathbf{x}_n\}, \mathbf{x}_i \in \mathbb{R}^d, i=\overline{1, n}&amp;lt;/math&amp;gt;;&lt;br /&gt;
* &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; - требуемое число кластеров, &amp;lt;math&amp;gt;k \in \mathbb{N}, k \leq n&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;&amp;lt;u&amp;gt;Требуется:&amp;lt;/u&amp;gt;&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Разделить множество наблюдений &amp;lt;math&amp;gt;X&amp;lt;/math&amp;gt; на &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластеров &amp;lt;math&amp;gt;S_1, S_2, ..., S_k&amp;lt;/math&amp;gt;:&lt;br /&gt;
*   &amp;lt;math&amp;gt;S_i \cap S_j= \varnothing, \quad i \ne j&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
*   &amp;lt;math&amp;gt;\bigcup_{i=1}^{k} S_i = X&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;&amp;lt;u&amp;gt;Действие алгоритма:&amp;lt;/u&amp;gt;&amp;lt;/b&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;Алгоритм &amp;lt;i&amp;gt;k means&amp;lt;/i&amp;gt; разбивает набор &amp;lt;math&amp;gt;X&amp;lt;/math&amp;gt; на &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; наборов &amp;lt;math&amp;gt;S_1, S_2, ..., S_k,&amp;lt;/math&amp;gt; таким образом, чтобы минимизировать сумму квадратов расстояний от каждой точки кластера до его центра (центр масс кластера). Введем обозначение, &amp;lt;math&amp;gt;S=\{S_1, S_2, ..., S_k\}&amp;lt;/math&amp;gt;. Тогда действие алгоритма &amp;lt;i&amp;gt;k means&amp;lt;/i&amp;gt; равносильно поиску:&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;table style=&amp;quot;width:100%&amp;quot;&amp;gt;&lt;br /&gt;
  &amp;lt;tr&amp;gt;&lt;br /&gt;
    &amp;lt;td align=&amp;quot;center&amp;quot; width=&amp;quot;90%&amp;quot;&amp;gt;&amp;lt;math&amp;gt;\arg\min_{S} \sum\limits_{i=1}^k \sum\limits_{\mathbf{x} \in S_i} \rho(\mathbf{x}, \mathbf{\mu}_i )^2,&amp;lt;/math&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;td align=&amp;quot;right&amp;quot;&amp;gt;&amp;lt;math&amp;gt;(1)&amp;lt;/math&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;/table&amp;gt;&lt;br /&gt;
где &amp;lt;math&amp;gt;\mathbf{\mu}_i&amp;lt;/math&amp;gt; &amp;amp;ndash; центры кластеров, &amp;lt;math&amp;gt;i=\overline{1,k}, \quad \rho(\mathbf{x}, \mathbf{\mu}_i)&amp;lt;/math&amp;gt; &amp;amp;ndash; функция расстояния между &amp;lt;math&amp;gt;\mathbf{x}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\mu_i&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;&amp;lt;u&amp;gt;Шаги алгоритма: &amp;lt;/u&amp;gt;&amp;lt;/b&amp;gt;&lt;br /&gt;
&amp;lt;ol&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&lt;br /&gt;
    &amp;lt;b&amp;gt;Начальный шаг: инициализация кластеров&amp;lt;/b&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;Выбирается произвольное множество точек &amp;lt;math&amp;gt;\mu_i, i=\overline{1,k}&amp;lt;/math&amp;gt;, рассматриваемых как начальные центры кластеров: &amp;lt;math&amp;gt;\mu_i^{(0)} = \mu_i, \quad i=\overline{1, k}&amp;lt;/math&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
  &amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&lt;br /&gt;
    &amp;lt;b&amp;gt;Распределение векторов по кластерам&amp;lt;/b&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Шаг&amp;lt;/b&amp;gt; &amp;lt;math&amp;gt;t: \forall \mathbf{x}_i \in X, i=\overline{1,n}: \mathbf{x}_i \in S_j \iff  j=\arg\min_{k}\rho(\mathbf{x}_i,\mathbf{\mu}_k^{(t-1)})^2&amp;lt;/math&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
  &amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&lt;br /&gt;
    &amp;lt;b&amp;gt;Пересчет центров кластеров&amp;lt;/b&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Шаг &amp;lt;/b&amp;gt; &amp;lt;math&amp;gt;t: \forall i=\overline{1,k}:  \mu_i^{(t)} = \cfrac{1}{|S_i|}\sum_{\mathbf{x}\in S_i}\mathbf{x}&amp;lt;/math&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
  &amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&lt;br /&gt;
    &amp;lt;b&amp;gt;Проверка условия останова:&amp;lt;/b&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
    &#039;&#039;&#039;if&#039;&#039;&#039; &amp;lt;math&amp;gt;\exist i\in \overline{1,k}: \mu_i^{(t)} \ne \mu_i^{(t-1)}&amp;lt;/math&amp;gt; &#039;&#039;&#039;then&#039;&#039;&#039;&lt;br /&gt;
        t = t + 1;&lt;br /&gt;
        goto 2;&lt;br /&gt;
    &#039;&#039;&#039;else&#039;&#039;&#039;&lt;br /&gt;
        &#039;&#039;&#039;stop&#039;&#039;&#039;&lt;br /&gt;
  &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ol&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Вычислительное ядро алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Вычислительным ядром являются шаги 2 и 3 приведенного выше алгоритма: &amp;lt;b&amp;gt;&amp;lt;i&amp;gt;распределение векторов по кластерам&amp;lt;/i&amp;gt;&amp;lt;/b&amp;gt; и &amp;lt;b&amp;gt;&amp;lt;i&amp;gt;пересчет центров кластеров&amp;lt;/i&amp;gt;&amp;lt;/b&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;&amp;lt;i&amp;gt;Распределение векторов&amp;lt;/i&amp;gt;&amp;lt;/b&amp;gt; по кластерам предполагает вычисление расстояний между каждым вектором &amp;lt;math&amp;gt;\mathbf{x}_i \in X, i= \overline{1,n}&amp;lt;/math&amp;gt; и центрами кластера &amp;lt;math&amp;gt;\mathbf{\mu}_j, j= \overline{1,k}&amp;lt;/math&amp;gt;. Таким образом, данный шаг предполагает &amp;lt;math&amp;gt;kn&amp;lt;/math&amp;gt; вычислений расстояний между d-мерными векторами. &lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;&amp;lt;i&amp;gt;Пересчет центров кластеров&amp;lt;/i&amp;gt;&amp;lt;/b&amp;gt; предполагает &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; вычислений центров масс &amp;lt;math&amp;gt;\mathbf{\mu}_i&amp;lt;/math&amp;gt; множеств &amp;lt;math&amp;gt;S_i, i=\overline{1,k}&amp;lt;/math&amp;gt; представленных выражением в шаге 3 представленного выше алгоритма.&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Макроструктура алгоритма ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Инициализация центров масс &amp;lt;math&amp;gt;\mu_1, ..., \mu_k&amp;lt;/math&amp;gt;&amp;lt;/b&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
Наиболее распространенными являются следующие стратегии:&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&lt;br /&gt;
    &amp;lt;b&amp;gt;Метод Forgy&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;В качестве начальных значений &amp;lt;math&amp;gt;\mu_1, ..., \mu_k&amp;lt;/math&amp;gt; берутся случайно выбранные векторы.&lt;br /&gt;
  &amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&lt;br /&gt;
    &amp;lt;b&amp;gt;Метод случайно разделения (Random Partitioning)&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;Для каждого вектора &amp;lt;math&amp;gt;\mathbf{x}_i \in X, i=\overline{1, n}&amp;lt;/math&amp;gt; выбирается случайным образом кластер &amp;lt;math&amp;gt;S_1, ..., S_k&amp;lt;/math&amp;gt;, после чего для каждого полученного кластера вычисляются значения &amp;lt;math&amp;gt;\mu_1, ..., \mu_k&amp;lt;/math&amp;gt;.&lt;br /&gt;
  &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Распределение векторов по кластерам&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Для этого шага алгоритма между векторами &amp;lt;math&amp;gt;\mathbf{x}_i \in X, i=\overline{1, n}&amp;lt;/math&amp;gt; и центрами кластеров &amp;lt;math&amp;gt;\mu_1, ..., \mu_k&amp;lt;/math&amp;gt; вычисляются &amp;lt;b&amp;gt;расстояния&amp;lt;/b&amp;gt; по формуле (как правило, используется Евлидово расстояние):&lt;br /&gt;
&amp;lt;table style=&amp;quot;width:100%&amp;quot;&amp;gt;&lt;br /&gt;
  &amp;lt;tr&amp;gt;&lt;br /&gt;
    &amp;lt;td align=&amp;quot;center&amp;quot; width=&amp;quot;90%&amp;quot;&amp;gt;&amp;lt;math&amp;gt; \mathbf{v}_1, \mathbf{v}_2 \in \mathbb{R}^d,  \quad \rho(\mathbf{v}_1, \mathbf{v}_2) = \lVert \mathbf{v}_1- \mathbf{v}_2 \rVert= \sqrt{\sum_{i=1}^{d}(\mathbf{v}_{1,i} - \mathbf{v}_{2,i})^2}&amp;lt;/math&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;td align=&amp;quot;right&amp;quot;&amp;gt;&amp;lt;math&amp;gt;(2)&amp;lt;/math&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;/table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Пересчет центров кластеров&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Для этого шага алгоритма производится пересчет центров кластера по &amp;lt;b&amp;gt;формуле вычисления центра масс&amp;lt;/b&amp;gt;:&lt;br /&gt;
&amp;lt;table style=&amp;quot;width:100%&amp;quot;&amp;gt;&lt;br /&gt;
  &amp;lt;tr&amp;gt;&lt;br /&gt;
    &amp;lt;td align=&amp;quot;center&amp;quot; width=&amp;quot;90%&amp;quot;&amp;gt;&amp;lt;math&amp;gt; \mu = \cfrac{1}{|S|}\sum_{\mathbf{x}\in S}\mathbf{x}&amp;lt;/math&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;td align=&amp;quot;right&amp;quot;&amp;gt;&amp;lt;math&amp;gt;(3)&amp;lt;/math&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;/table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Схема реализации последовательного алгоритма ===&lt;br /&gt;
&lt;br /&gt;
 &#039;&#039;&#039;algorithm&#039;&#039;&#039; k-means &#039;&#039;&#039;is&#039;&#039;&#039;&lt;br /&gt;
     &#039;&#039;&#039;1.&#039;&#039;&#039; Инициализировать центры кластеров &amp;lt;math&amp;gt;\mathbf{\mu}_i^{(1)}, i=\overline{1,k}&amp;lt;/math&amp;gt;&lt;br /&gt;
     &#039;&#039;&#039;2.&#039;&#039;&#039; &amp;lt;math&amp;gt;t \leftarrow 1&amp;lt;/math&amp;gt;&lt;br /&gt;
     &#039;&#039;&#039;3.&#039;&#039;&#039; &#039;&#039;&#039;Распределение по кластерам&#039;&#039;&#039;&amp;lt;br&amp;gt;&lt;br /&gt;
        &amp;lt;math&amp;gt;S_i^{(t)}=\{\mathbf{x}_p: \lVert\mathbf{x}_p-\mathbf{\mu}_i^{(t)}\rVert^2 \leq \lVert\mathbf{x}_p-\mathbf{\mu}_j^{(t)}\rVert^2 \quad \forall j=\overline{1,k}\},&amp;lt;/math&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
        где каждый вектор &amp;lt;math&amp;gt;\mathbf{x}_p&amp;lt;/math&amp;gt; соотносится единственному кластеру &amp;lt;math&amp;gt;S^{(t)}&amp;lt;/math&amp;gt;&lt;br /&gt;
     &#039;&#039;&#039;4.&#039;&#039;&#039; &#039;&#039;&#039;Обновление центров кластеров&#039;&#039;&#039;&amp;lt;br&amp;gt;&lt;br /&gt;
        &amp;lt;math&amp;gt;\mathbf{\mu}_i^{(t+1)} = \frac{1}{|S^{(t)}_i|} \sum_{\mathbf{x}_j \in S^{(t)}_i} \mathbf{x}_j &amp;lt;/math&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
     &#039;&#039;&#039;5.&#039;&#039;&#039; &#039;&#039;&#039;if&#039;&#039;&#039; &amp;lt;math&amp;gt;\exist i \in \overline{1,k}: \mathbf{\mu}_i^{(t+1)} \ne \mathbf{\mu}_i^{(t)}&amp;lt;/math&amp;gt; &#039;&#039;&#039;then&#039;&#039;&#039;&lt;br /&gt;
            t = t + 1;&lt;br /&gt;
            goto &#039;&#039;&#039;3&#039;&#039;&#039;;&lt;br /&gt;
        &#039;&#039;&#039;else&#039;&#039;&#039;&lt;br /&gt;
            &#039;&#039;&#039;stop&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
=== Последовательная сложность алгоритма===&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding-bottom: 20px&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;Обозначим &amp;lt;math&amp;gt;\Theta_{centroid}^{d, m}&amp;lt;/math&amp;gt; временную сложность вычисления центорида кластера, число элементов которого равна &amp;lt;math&amp;gt;m&amp;lt;/math&amp;gt;,  в d-мерном пространстве.&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;Аналогично  &amp;lt;math&amp;gt;\Theta_{distance}^d&amp;lt;/math&amp;gt; &amp;amp;ndash; временная сложность вычисления расстояния между двумя d-мерными векторами.&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding-bottom: 20px&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;Сложность шага инициализации &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластеров мощности &amp;lt;math&amp;gt;m&amp;lt;/math&amp;gt; в d-мерном пространстве &amp;amp;ndash; &amp;lt;math&amp;gt;\Theta_{init}^{k, d, m}&amp;lt;/math&amp;gt;&amp;lt;/b&amp;gt;&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;i&amp;gt;Стратерия Forgy&amp;lt;/i&amp;gt;: вычисления не требуются, &amp;lt;math&amp;gt;\Theta_{init}^{k, d, m} = 0&amp;lt;/math&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;i&amp;gt;Стратегия случайного разбиения&amp;lt;/i&amp;gt;: вычисление центров &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластеров,  &amp;lt;math&amp;gt;\Theta_{init}^{k, d, m} = k \cdot \Theta_{centroid}^{d, m}, m \le n&amp;lt;/math&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding-bottom: 20px&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Cложность шага распределения d мерных векторов по &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластерам &amp;amp;ndash; &amp;lt;math&amp;gt;\Theta_{distribute}^{k, d}&amp;lt;/math&amp;gt;&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
На этом шаге для каждого вектора &amp;lt;math&amp;gt;\mathbf{x}_i \in X, i=\overline{1, n}&amp;lt;/math&amp;gt; вычисляется k расстояний до центров кластеров &amp;lt;math&amp;gt;\mathbf{\mu}_1, ...\mathbf{\mu}_k&amp;lt;/math&amp;gt;&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p align=&amp;quot;center&amp;quot;&amp;gt;&lt;br /&gt;
  &amp;lt;math&amp;gt;\Theta_{distribute}^{k, d} = n \cdot k \cdot \Theta_{distance}^d&amp;lt;/math&amp;gt;&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding-bottom: 20px&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;Сложность шага пересчета центров &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластеров размера &amp;lt;math&amp;gt;m&amp;lt;/math&amp;gt; в d-мерном пространстве &amp;amp;ndash; &amp;lt;math&amp;gt;\Theta_{recenter}^{k, d, m}&amp;lt;/math&amp;gt;&amp;lt;/b&amp;gt;&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;На этом шаге вычисляется &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; центров кластеров &amp;lt;math&amp;gt;\mathbf{\mu}_1, ...\mathbf{\mu}_k&amp;lt;/math&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p align=&amp;quot;center&amp;quot;&amp;gt;&amp;lt;math&amp;gt;\Theta_{recenter}^{k, d, m} = k \cdot \Theta_{centroid}^{d, m}&amp;lt;/math&amp;gt; &amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding-bottom: 20px&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Рассчитаем &amp;lt;math&amp;gt;\Theta_{centroid}^{d, m}&amp;lt;/math&amp;gt; для кластера, число элементов которого равно &amp;lt;math&amp;gt;m&amp;lt;/math&amp;gt;&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p align=&amp;quot;center&amp;quot;&amp;gt;&amp;lt;math&amp;gt;\Theta_{centroid}^{d, m}&amp;lt;/math&amp;gt; = &amp;lt;math&amp;gt;m \cdot d&amp;lt;/math&amp;gt; сложений + &amp;lt;math&amp;gt;d&amp;lt;/math&amp;gt; делений &amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding-bottom: 20px&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Рассчитаем &amp;lt;math&amp;gt;\Theta_{distance}^d&amp;lt;/math&amp;gt; в соответствие с формулой &amp;lt;math&amp;gt;(2)&amp;lt;/math&amp;gt;&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p align=&amp;quot;center&amp;quot;&amp;gt;&amp;lt;math&amp;gt;\Theta_{distance}^d&amp;lt;/math&amp;gt; = &amp;lt;math&amp;gt;d&amp;lt;/math&amp;gt; вычитаний + &amp;lt;math&amp;gt;d&amp;lt;/math&amp;gt; умножений + &amp;lt;math&amp;gt;(d-1)&amp;lt;/math&amp;gt; сложение&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding-bottom: 20px&amp;quot;&amp;gt;&lt;br /&gt;
  &amp;lt;p&amp;gt;Предположим, что алгоритм сошелся за &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt; итераций, тогда временная сложность алгоритма &amp;lt;math&amp;gt;\Theta_{k-means}^{d, n}&amp;lt;/math&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
  &amp;lt;p align=&amp;quot;center&amp;quot;&amp;gt;&amp;lt;b&amp;gt;&amp;lt;math&amp;gt;\Theta_{k-means}^{d, n} \le \Theta_{init}^{k, d, n} + i(\Theta_{distribute}^{k, d} + \Theta_{recenter}^{k, d, n})&amp;lt;/math&amp;gt;&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding-bottom: 5px&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;Операции сложения/вычитания:&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p align=&amp;quot;center&amp;quot;&amp;gt;&amp;lt;b&amp;gt;&amp;lt;math&amp;gt;\Theta_{k-means}^{d, n} \le knd+ i(kn(2d-1) + knd) = knd+ i(kn(3d-1)) \thicksim O(ikdn)&amp;lt;/math&amp;gt;&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding-bottom: 20px&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;Операции умножения/деления:&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p align=&amp;quot;center&amp;quot;&amp;gt;&amp;lt;b&amp;gt;&amp;lt;math&amp;gt;\Theta_{k-means}^{d, n} \le kd + i(knd + kd) = kd + ikd(n+1) \thicksim O(ikdn) &amp;lt;/math&amp;gt;&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding-bottom: 20px&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;Получаем, что &amp;lt;b&amp;gt;временная сложность&amp;lt;/b&amp;gt; алгоритма &amp;lt;b&amp;gt;k means&amp;lt;/b&amp;gt; кластеризации &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; &amp;lt;b&amp;gt;d-мерных&amp;lt;/b&amp;gt; векторов на &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластеров за &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt; итераций:&amp;lt;/p&amp;gt;&lt;br /&gt;
 &amp;lt;p align=&amp;quot;center&amp;quot;&amp;gt;&amp;lt;b&amp;gt;&amp;lt;math&amp;gt; \Theta_{k-means}^{d, n} \thicksim O(ikdn) &amp;lt;/math&amp;gt;&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Информационный граф ===&lt;br /&gt;
&lt;br /&gt;
Рассмотрим информационный граф алгоритма. Алгоритм &amp;lt;i&amp;gt;k means&amp;lt;/i&amp;gt; начинается с этапа инициализации, после которого следуют итерации, на каждой из которых выполняется два последовательных шага (см. [[#Схема реализации последовательного алгоритма|&amp;quot;Схема реализации последовательного алгоритма&amp;quot;]]): &lt;br /&gt;
* распределение векторов по кластерам&lt;br /&gt;
* перерасчет центров кластеров&lt;br /&gt;
&lt;br /&gt;
Поскольку основная часть вычислений приходится на шаги итераций, распишем информационные графы данных шагов.&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Распределение векторов по кластерам&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
Информационный граф шага распределения векторов по кластерам представлен на &#039;&#039;рисунке 1&#039;&#039;. Исходами данного графа является исходные векторы &amp;lt;math&amp;gt;\mathbf{x}_1, ..., \mathbf{x}_n&amp;lt;/math&amp;gt;, а также центры кластеров &amp;lt;math&amp;gt;\mathbf{\mu}_1, ... \mathbf{\mu}_k&amp;lt;/math&amp;gt;, вычисленные ранее (на шаге инициализации, если рассматривается первая итерация алгоритма, или на шаге пересчета центров кластеров предыдущей итерации в противном случае). Каждая пара векторов данных &amp;lt;math&amp;gt;\mathbf{x}_i, i=\overline{1,n}&amp;lt;/math&amp;gt; и центров кластера &amp;lt;math&amp;gt;\mathbf{\mu}_j, j=\overline{1, k}&amp;lt;/math&amp;gt; : (&amp;lt;math&amp;gt;\mathbf{x}_i&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;\mathbf{\mu}_j&amp;lt;/math&amp;gt;) подаются на независимые узлы &amp;lt;i&amp;gt;&amp;quot;d&amp;quot;&amp;lt;/i&amp;gt; вычисления расстояния между векторами (более подробная схема вычисления расстояния представлена далее, &#039;&#039;рисунок 2&#039;&#039;). Далее узлы вычисления расстояния &amp;lt;i&amp;gt;&amp;quot;d&amp;quot;&amp;lt;/i&amp;gt;, соответствующие одному и тому же исходному вектору &amp;lt;math&amp;gt;\mathbf{x}_i&amp;lt;/math&amp;gt; передаются на один узел &amp;lt;i&amp;gt;&amp;quot;m&amp;quot;&amp;lt;/i&amp;gt;, где далее происходит вычисление новой метки кластера для каждого вектора &amp;lt;math&amp;gt;\mathbf{x}_i&amp;lt;/math&amp;gt; (берется кластер с минимальным результатом вычисления расстояния). На выходе графа выдаются метки кластеров , &amp;lt;math&amp;gt;L_1, ..., L_n&amp;lt;/math&amp;gt;, такие что &amp;lt;math&amp;gt;\forall \mathbf{x}_i, i=\overline{1, n}, \mathbf{x}_i \in S_j \Leftrightarrow L_i = j&amp;lt;/math&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
[[file:Clusterization.png|thumb|center|800px|Рис. 1. Схема распределения векторов по кластерам. &#039;&#039;d&#039;&#039; &amp;amp;ndash; вычисление расстояния между векторами; &#039;&#039;m&#039;&#039; &amp;amp;ndash; вычисление минимума.]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Вычисление расстояния между векторами&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
Подробная схема вычисления расстояния между векторами &amp;lt;math&amp;gt;\mathbf{x}_i, \mathbf{\mu}_j&amp;lt;/math&amp;gt; представлена на &#039;&#039;рисунке 2&#039;&#039;. Как показано на графе, узел вычисления расстояния между векторами &amp;lt;i&amp;gt;&amp;quot;d&amp;quot;&amp;lt;/i&amp;gt; состоит из шага взятия разности между векторами (узел &amp;quot;&amp;lt;math&amp;gt;-&amp;lt;/math&amp;gt;&amp;quot;) и взятия нормы получившегося вектора разности (узел &amp;quot;&amp;lt;math&amp;gt;||\cdot||^2&amp;lt;/math&amp;gt;&amp;quot;). Более подробно, вычисление расстояния между векторами &amp;lt;math&amp;gt;\mathbf{x}_i = {x_{i1,}, ...,{x_{in}}}, \mathbf{\mu}_j = {\mu_{j1}, ...,\mu_{jn}}&amp;lt;/math&amp;gt; может быть представлено как вычисление разности между каждой парой компонент &amp;lt;math&amp;gt;(x_{iz}, \mu_{jz}), z=\overline{1, d}&amp;lt;/math&amp;gt; (узел &amp;quot;&amp;lt;math&amp;gt;-&amp;lt;/math&amp;gt;&amp;quot;), далее возведение в квадрат для каждого узла &amp;quot;&amp;lt;math&amp;gt;-&amp;lt;/math&amp;gt;&amp;quot; (узел &amp;quot;&amp;lt;math&amp;gt;()^2&amp;lt;/math&amp;gt;&amp;quot;) и суммирования выходов всех узлов &amp;quot;&amp;lt;math&amp;gt;()^2&amp;lt;/math&amp;gt;&amp;quot; (узел &amp;quot;&amp;lt;math&amp;gt;+&amp;lt;/math&amp;gt;&amp;quot;).  &lt;br /&gt;
&lt;br /&gt;
[[file:dist_calc.png|thumb|center|800px|Рис. 2. Схема вычисления расстояния между вектором и центром кластера.]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Пересчет центров кластеров&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
Информационный граф шага пересчета центров кластеров представлен на &#039;&#039;рисунке 3&#039;&#039;. Исходами данного графа является исходные векторы &amp;lt;math&amp;gt;\mathbf{x}_1, ..., \mathbf{x}_n&amp;lt;/math&amp;gt;, а также им соответствующие метки кластера, &amp;lt;math&amp;gt;L_1, ..., L_n&amp;lt;/math&amp;gt;, такие что &amp;lt;math&amp;gt;\forall x_i, i=\overline{1, n}, \mathbf{x}_i \in S_j \Leftrightarrow L_i = j&amp;lt;/math&amp;gt;, вычисленные на этапе распределения векторов по кластерам. Все векторы &amp;lt;math&amp;gt;\mathbf{x}_1, ..., \mathbf{x}_n&amp;lt;/math&amp;gt; подаются в узлы &amp;lt;math&amp;gt;+_1, ...+_k&amp;lt;/math&amp;gt;, каждый узел &amp;lt;math&amp;gt;+_m, m = \overline{1,k}&amp;lt;/math&amp;gt; соответствует операции сложения векторов кластера с номером &amp;lt;math&amp;gt;m&amp;lt;/math&amp;gt;. Метки кластера &amp;lt;math&amp;gt;L_1, ..., L_n&amp;lt;/math&amp;gt; также совместно передаются на узлы &amp;lt;math&amp;gt;S_m, m = \overline{1,k}&amp;lt;/math&amp;gt;, на каждом из которых вычисляется количество векторов в соответствующем кластере (количество меток с соответствующим значением). Далее каждая пара выходов узлов &amp;lt;math&amp;gt;+_m&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;S_m&amp;lt;/math&amp;gt; подается на узел &amp;quot;&amp;lt;math&amp;gt;/&amp;lt;/math&amp;gt;&amp;quot;, где производится деление суммы векторов кластера на количество элементов в нем. Значения, вычисленные на узлах &amp;quot;&amp;lt;math&amp;gt;/&amp;lt;/math&amp;gt;&amp;quot;, присваиваются новым центрам кластеров (выходные значения графа).&lt;br /&gt;
&lt;br /&gt;
[[file:Recluster.png|thumb|center|800px|Рис. 3. Схема пересчета центров кластеров]]&lt;br /&gt;
&lt;br /&gt;
=== Ресурс параллелизма алгоритма ===&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
Работа алгоритма состоит из &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt; итераций, в каждой из которых происходит &amp;lt;b&amp;gt;распределение d-мерных векторов по &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластерам&amp;lt;/b&amp;gt;, а также &amp;lt;b&amp;gt;пересчет центров кластеров в d-мерном пространстве&amp;lt;/b&amp;gt;. В шаге &amp;lt;b&amp;gt;распределения d-мерных векторов по &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластерам&amp;lt;/b&amp;gt; расстояния между вектором и центрами кластеров вычисляются независимо (отсутствуют информационные зависимости). &amp;lt;b&amp;gt;Центры масс кластеров&amp;lt;/b&amp;gt; также пересчитываются независимо друг от друга. Таким образом, имеет место [[глоссарий#Массовый параллелизм|&#039;&#039;массовый параллелизм&#039;&#039;]]. Вычислим параллельную сложность &amp;lt;math&amp;gt;\Psi_*&amp;lt;/math&amp;gt; каждого из шагов, а также параллельную сложность всего алгоритма, &amp;lt;math&amp;gt;\Psi_{k-means}&amp;lt;/math&amp;gt;. Будем исходить из предположения, что может быть использовано любое необходимое число потоков.&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Распределение d-мерных векторов по &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластерам&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;  &lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
Поскольку на данном шаге для каждой пары векторов &amp;lt;math&amp;gt;\mathbf{x}_i, i=\overline{1,n}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\mathbf{\mu}_j, j=\overline{1,k}&amp;lt;/math&amp;gt; операции вычисления расстояния не зависят друг от друга, они могут выполняться параллельно. Тогда, разделив все вычисление расстояний на &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; потоков, получим, что в каждом потоке будет выполняться только одна операция вычисления расстояния между векторами размерности d. При этом каждому вычислительному потоку передаются координаты центров всех кластеров &amp;lt;math&amp;gt;\mathbf{\mu}_1, ..., \mathbf{\mu}_k&amp;lt;/math&amp;gt;. Таким образом, параллельная сложность данного шага определяется &amp;lt;i&amp;gt; сложностью параллельной операции вычисления расстояния между d-мерными векторами&amp;lt;/i&amp;gt;, &amp;lt;math&amp;gt;\Psi_{distance}^d&amp;lt;/math&amp;gt;  и &amp;lt;i&amp;gt;сложностью определения наиболее близкого кластера&amp;lt;/i&amp;gt; (паралельное взятие минимума по расстояниям), &amp;lt;math&amp;gt;\Psi_{min}^k&amp;lt;/math&amp;gt;. Для оценки &amp;lt;math&amp;gt;\Psi_{distance}^d&amp;lt;/math&amp;gt; воспользуемся  [[Нахождение_частных_сумм_элементов_массива_сдваиванием | параллельной реализацией нахождения частичной суммы элементов массива путем сдваивания]]. Аналогично, &amp;lt;math&amp;gt;\Psi_{min}^k = log(k)&amp;lt;/math&amp;gt;. В результате, &amp;lt;math&amp;gt;\Psi_{distance}^d = O(log(d))&amp;lt;/math&amp;gt;.   Таким образом: &lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p align=&amp;quot;center&amp;quot;&amp;gt;&amp;lt;math&amp;gt;\Psi_{distribute}^{k, d}  = \Psi_{distance}^d + \Psi_{min}^k = O(log(d))+O(log(k)) = O(log(k*d))&amp;lt;/math&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Пересчет центров кластеров в d-мерном пространстве&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
Поскольку на данном шаге для каждого из &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластеров центр масс может быть вычислен независимо, данные операции могут быть выполнены в отдельных потоках. Таким образом, параллельная сложность данного шага, &amp;lt;math&amp;gt;\Psi_{recenter}^{k, d}&amp;lt;/math&amp;gt;,  будет определяться &amp;lt;i&amp;gt;параллельной сложностью вычисления одного центра масс кластера размера &amp;lt;math&amp;gt;m&amp;lt;/math&amp;gt;&amp;lt;/i&amp;gt;, &amp;lt;math&amp;gt;\Psi_{recenter}^{k, d}&amp;lt;/math&amp;gt;,  а так как &amp;lt;math&amp;gt;m \le n \Rightarrow \Psi_{recenter}^{d, m} \le \Psi_{recenter}^{d, n}&amp;lt;/math&amp;gt;. Сложность вычисления центра масс кластера d-мерных векторов размера n аналогично предыдущим вычислениям равна &amp;lt;math&amp;gt;O(log(n))&amp;lt;/math&amp;gt;. Тогда:  &lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p align=&amp;quot;center&amp;quot;&amp;gt;&amp;lt;math&amp;gt;\Psi_{recenter}^{k, d}  \le \Psi_{recenter}^{d, n} = O(log(n))&amp;lt;/math&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Общая параллельная сложность алгоритма&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
На каждой итерации необходимо обновление центров кластеров, которые будут использованы на следующей итерации. Таким образом, итерационный процесс выполняется последовательно&amp;lt;ref&amp;gt;Zhao, Weizhong, Huifang Ma, and Qing He. &amp;quot;Parallel k-means clustering based on mapreduce.&amp;quot; IEEE International Conference on Cloud Computing. Springer Berlin Heidelberg, 2009.&amp;lt;/ref&amp;gt;. Тогда, поскольку сложность каждой итерации  определяется &amp;lt;math&amp;gt;\Psi_{distribute}^{k, d}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\Psi_{recenter}&amp;lt;/math&amp;gt;, сложность всего алгоритма, &amp;lt;math&amp;gt;\Psi_{k-means}&amp;lt;/math&amp;gt; в предположении, что было сделано &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt; операций определяется выражением&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p align=&amp;quot;center&amp;quot;&amp;gt;&amp;lt;math&amp;gt;\Psi_{k-means} \approx i \cdot (\Psi_{distribute}^{k, d} + \Psi_{recenter}^{k, d}) \le i \cdot O(log(k*d*n))&amp;lt;/math&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Входные и выходные данные алгоритма ===&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;Входные данные&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;Матрица из &amp;lt;math&amp;gt;n*d&amp;lt;/math&amp;gt; элементов &amp;lt;math&amp;gt;x_{i, j} \in \mathbb{R}, i=\overline{1, n}, j=\overline{1, d}&amp;lt;/math&amp;gt;&amp;amp;ndash; координат векторов (наблюдений).&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;Целое положительное число &amp;lt;math&amp;gt;k, k \le n&amp;lt;/math&amp;gt; &amp;amp;ndash; количество кластеров.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;Объем входных данных&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;math&amp;gt;1&amp;lt;/math&amp;gt; целое число + &amp;lt;math&amp;gt;n*d&amp;lt;/math&amp;gt; вещественных чисел (при условии, что координаты &amp;amp;ndash; вещественные числа).&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;Выходные данные&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; целых положительных чисел &amp;lt;math&amp;gt;L_1, ..., L_n&amp;lt;/math&amp;gt;&amp;amp;ndash; номера кластеров, соотвествующие каждому вектору (при условии, что нумерация кластеров начинается с &amp;lt;math&amp;gt;1&amp;lt;/math&amp;gt;).&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;Объем выходных данных&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; целых положительных чисел.&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Свойства алгоритма ===&lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;[[глоссарий#Вычислительная мощность|&#039;&#039;Вычислительная мощность&#039;&#039;]]&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
Вычислительная мощность алгоритма &amp;lt;i&amp;gt;k means&amp;lt;/i&amp;gt; равна &amp;lt;math&amp;gt;\frac{ikdn}{n*d} = k \cdot i &amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; &amp;amp;ndash; число кластеров, &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt; &amp;amp;ndash; число итераций алгоритма.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;[[глоссарий#Детерминированность |&#039;&#039;Детерминированность&#039;&#039;]] и [[глоссарий#Устойчивость |&#039;&#039;Устойчивость&#039;&#039;]] &amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
Алгоритм &amp;lt;i&amp;gt;k means&amp;lt;/i&amp;gt; является итерационным. Количество итераций алгоритма в общем случае не фиксируется и зависит от начального расположения объектов в пространстве, параметра &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt;, а также от начального приближения центров кластеров, &amp;lt;math&amp;gt;\mu_1, ..., \mu_k&amp;lt;/math&amp;gt;. В результате этого может варьироваться результат работы алгоритма. При неудачном выборе начальных параметров итерационный процесс может сойтись к локальному оптимуму&amp;lt;ref&amp;gt;Von Luxburg, Ulrike. Clustering Stability. Now Publishers Inc, 2010.&amp;lt;/ref&amp;gt;. По этим причинам алгоритм не является ни &amp;lt;b&amp;gt;детермирированным&amp;lt;/b&amp;gt;, ни &amp;lt;b&amp;gt;устойчивым&amp;lt;/b&amp;gt;.&lt;br /&gt;
 &lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Соотношение последовательной и параллельной сложности алгоритма&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\frac{\Theta_{k-means}}{\Psi_{k-means}} = \frac{O(ikdn)}{O(i*log(kdn))}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Сильные стороны алгоритма&amp;lt;/b&amp;gt;:&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;i&amp;gt;Сравнительно высокая эффективность при простоте реализации&amp;lt;/i&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;i&amp;gt;Высокое качество кластеризации&amp;lt;/i&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;i&amp;gt;Возможность распараллеливания&amp;lt;/i&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;i&amp;gt;Существование множества модификаций&amp;lt;/i&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;Недостатки алгоритма&amp;lt;/b&amp;gt;&amp;lt;ref&amp;gt;Ortega, Joaquín Pérez, Ma Del Rocío Boone Rojas, and María J. Somodevilla. &amp;quot;Research issues on K-means Algorithm: An Experimental Trial Using Matlab.&amp;quot;&amp;lt;/ref&amp;gt;:&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;i&amp;gt;Количество кластеров является параметром алгоритма&amp;lt;/i&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;&amp;lt;i&amp;gt;Чувствительность к начальным условиям&amp;lt;/i&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;Инициализация центров кластеров в значительной степени влияет на результат кластеризации.&amp;lt;/p&amp;gt;&lt;br /&gt;
  &amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;&amp;lt;i&amp;gt;Чувствительность к выбросам и шумам&amp;lt;/i&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;Выбросы, далекие от центров настоящих кластеров, все равно учитываются при вычислении их центров.&amp;lt;/p&amp;gt;&lt;br /&gt;
  &amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;&amp;lt;i&amp;gt;Возможность сходимости к локальному оптимуму&amp;lt;/i&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;Итеративный подход не дает гарантии сходимости к оптимальному решению.&amp;lt;/p&amp;gt;&lt;br /&gt;
  &amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;&amp;lt;i&amp;gt;Использование понятия &amp;quot;среднего&amp;quot;&amp;lt;/i&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;Алгоритм неприменим к данным, для которых не определено понятие &amp;quot;среднего&amp;quot;, например, категориальным данным.&amp;lt;/p&amp;gt;&lt;br /&gt;
  &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&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;
Исследование масштабируемости параллельной реализации алгоритма k means проводилось на суперкомпьютере &amp;quot;Ломоносов&amp;quot;&amp;lt;ref name=&amp;quot;Lom&amp;quot;&amp;gt;Воеводин Вл., Жуматий С., Соболев С., Антонов А., Брызгалов П., Никитенко Д., Стефанов К., Воеводин Вад. Практика суперкомпьютера «Ломоносов» // Открытые системы, 2012, N 7, С. 36-39.&amp;lt;/ref&amp;gt; [http://parallel.ru/cluster Суперкомпьютерного комплекса Московского университета]. Алгоритм реализован на языке C с использованием средств MPI.&lt;br /&gt;
Для исследования масштабируемости проводилось множество запусков программы с разным значением параметра (количество векторов для кластеризации), а также с различным числом процессоров. Фиксировались результаты запусков &amp;amp;ndash; время работы &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt; и количество произведенных итераций алгоритма &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Параметры запусков для экспериментальной оценки:&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;Значения &amp;lt;b&amp;gt;количества векторов&amp;lt;/b&amp;gt; &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;: 20&#039;000, 30&#039;000, 50&#039;000, 100&#039;000, 200&#039;000, 300&#039;000, 500&#039;000, 700&#039;000, 1&#039;000&#039;000, 1&#039;500&#039;000, 2&#039;000&#039;000.&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;Значения &amp;lt;b&amp;gt;количества процессоров&amp;lt;/b&amp;gt; &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt;: 1, 8, 16, 32, 64, 128, 160, 192, 224, 256, 288, 320, 352, 384, 416, 448, 480, 512.&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;Значение &amp;lt;b&amp;gt;количества кластеров&amp;lt;/b&amp;gt; &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt;: 100.&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;Значение &amp;lt;b&amp;gt;размерности векторов&amp;lt;/b&amp;gt; &amp;lt;math&amp;gt;d&amp;lt;/math&amp;gt;: 10.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Для проведения экспериментов были сгенерированы нормально распределенные псевдослучайные данные (с использованием Python библиотеки [http://scikit-learn.org/ scikit-learn]):&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
from sklearn.datasets import make_classification&lt;br /&gt;
X1, Y1 = make_classification(n_features=10, n_redundant=2, n_informative=8,&lt;br /&gt;
                             n_clusters_per_class=1, n_classes=100,&lt;br /&gt;
                             n_samples=2000000)&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Для заданной конфигурации эксперимента (&amp;lt;math&amp;gt;n, d, p, k&amp;lt;/math&amp;gt;) и полученных результатов (&amp;lt;math&amp;gt;t, i&amp;lt;/math&amp;gt;)  [[Глоссарий#Производительность|производительность]]  и эффективность реализации расчитывались по формулам:&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
&amp;lt;ul&amp;gt;&amp;lt;li&amp;gt;&amp;lt;math&amp;gt;Performance = \frac{N_{k-means}^{d, n}}{t}\ \ (FLOPS),&amp;lt;/math&amp;gt;&amp;lt;/li&amp;gt;&amp;lt;/ul&amp;gt;&lt;br /&gt;
где &amp;lt;math&amp;gt;N_{k-means}^{d, n}&amp;lt;/math&amp;gt; &amp;amp;ndash; точное число операций с плавающей точкой (операции с памятью, а также целочисленные операции не учитывались), вычисленное в соответствие с разделом [[#Последовательная сложность алгоритма| &amp;quot;Последовательная сложность алгоритма&amp;quot;]];&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
&amp;lt;ul&amp;gt;&amp;lt;li&amp;gt;&amp;lt;math&amp;gt;Efficiency = \frac{100 * Performance}{Performance_{Peak}^{p}}\ \ (%),&amp;lt;/math&amp;gt;&amp;lt;/li&amp;gt;&amp;lt;/ul&amp;gt;&lt;br /&gt;
где &amp;lt;math&amp;gt;Performance_{Peak}^{p}&amp;lt;/math&amp;gt; &amp;amp;ndash; пиковая производительность суперкомпьютера при &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt; процессорах, вычисленная согласно спецификациям Intel&amp;lt;sup&amp;gt;&amp;amp;reg;&amp;lt;/sup&amp;gt; XEON&amp;lt;sup&amp;gt;&amp;amp;reg;&amp;lt;/sup&amp;gt; X5670&amp;lt;ref&amp;gt;&amp;quot;http://ark.intel.com/ru/products/47920/Intel-Xeon-Processor-X5670-12M-Cache-2_93-GHz-6_40-GTs-Intel-QPI&amp;quot;&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Графики зависимости производительности и эффективности параллельной реализации k means от числа векторов для кластеризации (&amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;) и числа процессоров (&amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt;) представлены на рисунках 4 и 5 соответственно.&lt;br /&gt;
&lt;br /&gt;
[[file:Flops.png|thumb|center|800px|Рис. 4. Параллельная реализация k means. График зависимости производительности реализации алгоритма от числа векторов для кластеризации (&amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;) и числа процессоров (&amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt;).]]&lt;br /&gt;
[[file:Efficiency.png|thumb|center|800px|Рис. 5. Параллельная реализация k means. График зависимости эффективности реализации алгоритма от числа векторов для кластеризации (&amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;) и числа процессоров (&amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt;).]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;В результате&amp;lt;/b&amp;gt; экспериментальной оценки были получены следующие оценки эффективности реализации:&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;b&amp;gt;Минимальное&amp;lt;/b&amp;gt; значение: 0.000409 % достигается при &amp;lt;math&amp;gt;n=20&#039;000, p=480&amp;lt;/math&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;b&amp;gt;Максимальное&amp;lt;/b&amp;gt; значение: 0.741119 % достигается при &amp;lt;math&amp;gt;n=300&#039;000, p=1&amp;lt;/math&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
Оценки масштабируемости реализации алгоритма k means:&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;b&amp;gt;По числу процессоров:&amp;lt;/b&amp;gt; -0.002683 &amp;amp;ndash; эффективность убывает с ростом числа процессоров. Данный результат вызван ростом накладных расходов для обеспечения параллельного выполнения алгоритма.&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;b&amp;gt;По размеру задачи:&amp;lt;/b&amp;gt; 0.002779 &amp;amp;ndash; эффективность растет с ростом числа векторов. Данный результат вызван тем, что при увеличении размера задачи, количество вычислений растет по сравнению с временем, затрачиваемым на пересылку данных.&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;b&amp;gt;Общая оценка:&amp;lt;/b&amp;gt; -0.000058 &amp;amp;ndash; можно сделать вывод, что в целом эффективность реализации незначительно уменьшается с ростом размера задачи и числа процессоров.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[https://github.com/serban/kmeans Использованная параллельная реализация алгоритма k means]&lt;br /&gt;
&lt;br /&gt;
=== Динамические характеристики и эффективность реализации алгоритма ===&lt;br /&gt;
=== Выводы для классов архитектур ===&lt;br /&gt;
=== Существующие реализации алгоритма ===&lt;br /&gt;
==== Открытое программное обеспечение ====&lt;br /&gt;
&amp;lt;ol&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;[https://www.icpsr.umich.edu/CrimeStat/ CrimeStat]&amp;lt;/li&amp;gt; Программное обеспечение, созданное для операционных систем Windows, предоставляющее инструменты статистического  и пространственного анализа для решения задачи картирования преступности.&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://juliastats.github.io Julia]&amp;lt;/li&amp;gt; Высокоуровневый высокопроизводительный свободный язык программирования с динамической типизацией, созданный для математических вычислений, содержит реализацию k-means.&lt;br /&gt;
  &amp;lt;li&amp;gt;[https://mahout.apache.org Mahout]&amp;lt;/li&amp;gt; Apache Mahout - Java библиотека для работы с алгоритмами машинного обучения с использованием MapReduce. Содержит реализацию k-means.&lt;br /&gt;
  &amp;lt;li&amp;gt;[https://www.gnu.org/software/octave/ Octave]&amp;lt;/li&amp;gt; Написанная на C++  свободная система для математических вычислений, использующая совместимый с MATLAB язык высокого уровня, содержит реализацию k-means.&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://spark.apache.org/docs/latest/mllib-clustering.html Spark]&amp;lt;/li&amp;gt; Распределенная реализация k-means содержится в библиотеке Mlib для работы с алгоритмами машинного обучения, взаимодействующая с Python библиотекой NumPy и библиотека R.&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://torch.ch Torch]&amp;lt;/li&amp;gt;  MATLAB-подобная библиотека для языка программирования Lua с открытым исходным кодом, предоставляет большое количество алгоритмов для глубинного обучения и научных расчётов. Ядро написано на Си, прикладная часть выполняется на LuaJIT, поддерживается распараллеливание вычислений средствами CUDA и OpenMP. Существуют реализации k-means.&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://www.cs.waikato.ac.nz/ml/weka/ Weka]&amp;lt;/li&amp;gt;  Cвободное программное обеспечение для анализа данных, написанное на Java. Содержит k-means и x-means.&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://accord-framework.net/docs/html/T_Accord_MachineLearning_KMeans.htm Accord.NET]&amp;lt;/li&amp;gt; C# реализация алгоритмов k-means, k-means++, k-modes.&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://docs.opencv.org/3.0-beta/doc/py_tutorials/py_ml/py_kmeans/py_kmeans_opencv/py_kmeans_opencv.html OpenCV]&amp;lt;/li&amp;gt; Написанная на С++ библиотека, направленная в основном на решение задач компьютерного зрения. Содержит реализацию k-means.&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://mlpack.org/ MLPACK]&amp;lt;/li&amp;gt; Масштабируемая С++ библиотека для работы с алгоритмами машинного обучения, содержит реализацию k-means.&lt;br /&gt;
  &amp;lt;li&amp;gt;[https://www.scipy.org/ SciPy]&amp;lt;/li&amp;gt; Библиотека Python, содержит множество реализаций k-means.&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://scikit-learn.org/ scikit-learn]&amp;lt;/li&amp;gt; Библиотека Python, содержит множество реализаций k-means.&lt;br /&gt;
  &amp;lt;li&amp;gt;[https://www.r-bloggers.com/k-means-clustering-in-r/ R]&amp;lt;/li&amp;gt; Язык программирования для статистической обработки данных и работы с графикой, а также свободная программная среда вычислений с открытым исходным кодом в рамках проекта GNU, содержит три реализации k-means.&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://elki.dbs.ifi.lmu.de ELKI]&amp;lt;/li&amp;gt; Java фреймворк, содержащий реализацию k-means, а также множество других алгоритмов кластеризации.&lt;br /&gt;
&amp;lt;/ol&amp;gt;&lt;br /&gt;
==== Проприетарное программное обеспечение  ====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ol&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;[https://www.ayasdi.com/blog/bigdata/topological-data-analysis-of-oil-and-gas-petrophysical-data/ Ayasdi]&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://www.stata.com/features/cluster-analysis/ Stata]&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://mathworld.wolfram.com/K-MeansClusteringAlgorithm.html Mathematica]&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://www.mathworks.com/help/stats/kmeans.html?requestedDomain=www.mathworks.com MATLAB]&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;[https://support.sas.com/rnd/app/stat/procedures/fastclus.html SAS]&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://docs.rapidminer.com/studio/operators/modeling/segmentation/k_means.html RapidMiner]&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;[https://blogs.sap.com/2013/03/28/sap-hana-pal-k-means-algorithm-or-how-to-do-customer-segmentation-for-the-telecommunications-industry/ SAP HANA]&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ol&amp;gt;&lt;br /&gt;
== Литература ==&lt;br /&gt;
&amp;lt;references /&amp;gt;&lt;/div&gt;</summary>
		<author><name>DennZo1993</name></author>
	</entry>
	<entry>
		<id>https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:%D0%91%D1%80%D0%BE%D1%82%D0%B8%D0%BA%D0%BE%D0%B2%D1%81%D0%BA%D0%B0%D1%8F_%D0%94%D0%B0%D0%BD%D1%83%D1%82%D0%B0/%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_k-means&amp;diff=20526</id>
		<title>Участник:Бротиковская Данута/Алгоритм k-means</title>
		<link rel="alternate" type="text/html" href="https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:%D0%91%D1%80%D0%BE%D1%82%D0%B8%D0%BA%D0%BE%D0%B2%D1%81%D0%BA%D0%B0%D1%8F_%D0%94%D0%B0%D0%BD%D1%83%D1%82%D0%B0/%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_k-means&amp;diff=20526"/>
		<updated>2016-12-10T10:47:51Z</updated>

		<summary type="html">&lt;p&gt;DennZo1993: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Assignment|Zhum}}&lt;br /&gt;
&lt;br /&gt;
{{algorithm&lt;br /&gt;
| name              = Алгоритм k средних (k means)&lt;br /&gt;
| serial_complexity = &amp;lt;math&amp;gt;O(ikdn)&amp;lt;/math&amp;gt;&lt;br /&gt;
| input_data        = &amp;lt;math&amp;gt; dn &amp;lt;/math&amp;gt;&lt;br /&gt;
| output_data       = &amp;lt;math&amp;gt; n &amp;lt;/math&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
Авторы страницы &amp;lt;b&amp;gt;[[Участник:Бротиковская Данута|Данута Бротиковская]]&amp;lt;/b&amp;gt; и &amp;lt;b&amp;gt;[[Участник:DennZo1993|Денис Зобнин]]&amp;lt;/b&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
Оба автора внесли одинаковый вклад в написание статьи (поиск материалов, изучение статей, заполнение контента статьи), четких разграничений по пунктам статьи сделать невозможно. &lt;br /&gt;
&lt;br /&gt;
== Свойства и структура алгоритма ==&lt;br /&gt;
&lt;br /&gt;
=== Общее описание алгоритма ===&lt;br /&gt;
Алгоритм &amp;lt;b&amp;gt;&amp;lt;i&amp;gt;k средних&amp;lt;/i&amp;gt;&amp;lt;/b&amp;gt; (&amp;lt;b&amp;gt;&amp;lt;i&amp;gt;k means&amp;lt;/i&amp;gt;&amp;lt;/b&amp;gt;) &amp;amp;ndash; неиерархический&amp;lt;ref&amp;gt;&amp;quot;https://ru.wikipedia.org/wiki/Иерархическая_кластеризация&amp;quot;&amp;lt;/ref&amp;gt;, итерационный метод кластеризации&amp;lt;ref&amp;gt;&amp;quot;https://ru.wikipedia.org/wiki/Кластерный_анализ&amp;quot;&amp;lt;/ref&amp;gt;, получивший большую популярность благодаря своей простоте, наглядности реализации и достаточно высокому качеству работы. Был изобретен в 1950-х годах математиком &amp;lt;i&amp;gt;Гуго Штейнгаузом&amp;lt;/i&amp;gt;&amp;lt;ref&amp;gt;Steinhaus, Hugo. &amp;quot;Sur la division des corp materiels en parties.&amp;quot; Bull. Acad. Polon. Sci 1.804 (1956): 801.&amp;lt;/ref&amp;gt; и почти одновременно &amp;lt;i&amp;gt;Стюартом Ллойдом&amp;lt;/i&amp;gt;&amp;lt;ref&amp;gt;Lloyd, S. P. &amp;quot;Least square quantization in PCM. Bell Telephone Laboratories Paper. Published in journal much later: Lloyd, SP: Least squares quantization in PCM.&amp;quot; IEEE Trans. Inform. Theor.(1957/1982).&amp;lt;/ref&amp;gt;. Особую популярность приобрел после публикации работы &amp;lt;i&amp;gt;МакКуина&amp;lt;/i&amp;gt;&amp;lt;ref&amp;gt;MacQueen, James. &amp;quot;Some methods for classification and analysis of multivariate observations.&amp;quot; Proceedings of the fifth Berkeley symposium on mathematical statistics and probability. Vol. 1. No. 14. 1967.&amp;lt;/ref&amp;gt; в 1967.&lt;br /&gt;
&lt;br /&gt;
Алгоритм представляет собой версию EM-алгоритма&amp;lt;ref&amp;gt;&amp;quot;https://ru.wikipedia.org/wiki/EM-алгоритм&amp;quot;&amp;lt;/ref&amp;gt;, применяемого также для разделения смеси гауссиан. Основная идея &amp;lt;i&amp;gt;k means&amp;lt;/i&amp;gt; заключается в том, что данные произвольно разбиваются на кластеры, после чего итеративно перевычисляется центр масс для каждого кластера, полученного на предыдущем шаге, затем векторы разбиваются на кластеры вновь в соответствии с тем, какой из новых центров оказался ближе по выбранной метрике.&lt;br /&gt;
&lt;br /&gt;
Цель алгоритма заключается в разделении &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; наблюдений на &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластеров таким образом, чтобы каждое наблюдение принадлежало ровно одному кластеру, расположенному на наименьшем расстоянии от наблюдения.&lt;br /&gt;
&lt;br /&gt;
=== Математическое описание алгоритма ===&lt;br /&gt;
&amp;lt;b&amp;gt;&amp;lt;u&amp;gt;Дано:&amp;lt;/u&amp;gt;&amp;lt;/b&amp;gt;&lt;br /&gt;
* набор из &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; наблюдений &amp;lt;math&amp;gt;X=\{\mathbf{x}_1, \mathbf{x}_2, ..., \mathbf{x}_n\}, \mathbf{x}_i \in \mathbb{R}^d, i=\overline{1, n}&amp;lt;/math&amp;gt;;&lt;br /&gt;
* &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; - требуемое число кластеров, &amp;lt;math&amp;gt;k \in \mathbb{N}, k \leq n&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;&amp;lt;u&amp;gt;Требуется:&amp;lt;/u&amp;gt;&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Разделить множество наблюдений &amp;lt;math&amp;gt;X&amp;lt;/math&amp;gt; на &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластеров &amp;lt;math&amp;gt;S_1, S_2, ..., S_k&amp;lt;/math&amp;gt;:&lt;br /&gt;
*   &amp;lt;math&amp;gt;S_i \cap S_j= \varnothing, \quad i \ne j&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
*   &amp;lt;math&amp;gt;\bigcup_{i=1}^{k} S_i = X&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;&amp;lt;u&amp;gt;Действие алгоритма:&amp;lt;/u&amp;gt;&amp;lt;/b&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;Алгоритм &amp;lt;i&amp;gt;k means&amp;lt;/i&amp;gt; разбивает набор &amp;lt;math&amp;gt;X&amp;lt;/math&amp;gt; на &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; наборов &amp;lt;math&amp;gt;S_1, S_2, ..., S_k,&amp;lt;/math&amp;gt; таким образом, чтобы минимизировать сумму квадратов расстояний от каждой точки кластера до его центра (центр масс кластера). Введем обозначение, &amp;lt;math&amp;gt;S=\{S_1, S_2, ..., S_k\}&amp;lt;/math&amp;gt;. Тогда действие алгоритма &amp;lt;i&amp;gt;k means&amp;lt;/i&amp;gt; равносильно поиску:&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;table style=&amp;quot;width:100%&amp;quot;&amp;gt;&lt;br /&gt;
  &amp;lt;tr&amp;gt;&lt;br /&gt;
    &amp;lt;td align=&amp;quot;center&amp;quot; width=&amp;quot;90%&amp;quot;&amp;gt;&amp;lt;math&amp;gt;\arg\min_{S} \sum\limits_{i=1}^k \sum\limits_{\mathbf{x} \in S_i} \rho(\mathbf{x}, \mathbf{\mu}_i )^2,&amp;lt;/math&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;td align=&amp;quot;right&amp;quot;&amp;gt;&amp;lt;math&amp;gt;(1)&amp;lt;/math&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;/table&amp;gt;&lt;br /&gt;
где &amp;lt;math&amp;gt;\mathbf{\mu}_i&amp;lt;/math&amp;gt; &amp;amp;ndash; центры кластеров, &amp;lt;math&amp;gt;i=\overline{1,k}, \quad \rho(\mathbf{x}, \mathbf{\mu}_i)&amp;lt;/math&amp;gt; &amp;amp;ndash; функция расстояния между &amp;lt;math&amp;gt;\mathbf{x}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\mu_i&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;&amp;lt;u&amp;gt;Шаги алгоритма: &amp;lt;/u&amp;gt;&amp;lt;/b&amp;gt;&lt;br /&gt;
&amp;lt;ol&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&lt;br /&gt;
    &amp;lt;b&amp;gt;Начальный шаг: инициализация кластеров&amp;lt;/b&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;Выбирается произвольное множество точек &amp;lt;math&amp;gt;\mu_i, i=\overline{1,k}&amp;lt;/math&amp;gt;, рассматриваемых как начальные центры кластеров: &amp;lt;math&amp;gt;\mu_i^{(0)} = \mu_i, \quad i=\overline{1, k}&amp;lt;/math&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
  &amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&lt;br /&gt;
    &amp;lt;b&amp;gt;Распределение векторов по кластерам&amp;lt;/b&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Шаг&amp;lt;/b&amp;gt; &amp;lt;math&amp;gt;t: \forall \mathbf{x}_i \in X, i=\overline{1,n}: \mathbf{x}_i \in S_j \iff  j=\arg\min_{k}\rho(\mathbf{x}_i,\mathbf{\mu}_k^{(t-1)})^2&amp;lt;/math&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
  &amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&lt;br /&gt;
    &amp;lt;b&amp;gt;Пересчет центров кластеров&amp;lt;/b&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Шаг &amp;lt;/b&amp;gt; &amp;lt;math&amp;gt;t: \forall i=\overline{1,k}:  \mu_i^{(t)} = \cfrac{1}{|S_i|}\sum_{\mathbf{x}\in S_i}\mathbf{x}&amp;lt;/math&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
  &amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&lt;br /&gt;
    &amp;lt;b&amp;gt;Проверка условия останова:&amp;lt;/b&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
    &#039;&#039;&#039;if&#039;&#039;&#039; &amp;lt;math&amp;gt;\exist i\in \overline{1,k}: \mu_i^{(t)} \ne \mu_i^{(t-1)}&amp;lt;/math&amp;gt; &#039;&#039;&#039;then&#039;&#039;&#039;&lt;br /&gt;
        t = t + 1;&lt;br /&gt;
        goto 2;&lt;br /&gt;
    &#039;&#039;&#039;else&#039;&#039;&#039;&lt;br /&gt;
        &#039;&#039;&#039;stop&#039;&#039;&#039;&lt;br /&gt;
  &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ol&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Вычислительное ядро алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Вычислительным ядром являются шаги 2 и 3 приведенного выше алгоритма: &amp;lt;b&amp;gt;&amp;lt;i&amp;gt;распределение векторов по кластерам&amp;lt;/i&amp;gt;&amp;lt;/b&amp;gt; и &amp;lt;b&amp;gt;&amp;lt;i&amp;gt;пересчет центров кластеров&amp;lt;/i&amp;gt;&amp;lt;/b&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;&amp;lt;i&amp;gt;Распределение векторов&amp;lt;/i&amp;gt;&amp;lt;/b&amp;gt; по кластерам предполагает вычисление расстояний между каждым вектором &amp;lt;math&amp;gt;\mathbf{x}_i \in X, i= \overline{1,n}&amp;lt;/math&amp;gt; и центрами кластера &amp;lt;math&amp;gt;\mathbf{\mu}_j, j= \overline{1,k}&amp;lt;/math&amp;gt;. Таким образом, данный шаг предполагает &amp;lt;math&amp;gt;kn&amp;lt;/math&amp;gt; вычислений расстояний между d-мерными векторами. &lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;&amp;lt;i&amp;gt;Пересчет центров кластеров&amp;lt;/i&amp;gt;&amp;lt;/b&amp;gt; предполагает &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; вычислений центров масс &amp;lt;math&amp;gt;\mathbf{\mu}_i&amp;lt;/math&amp;gt; множеств &amp;lt;math&amp;gt;S_i, i=\overline{1,k}&amp;lt;/math&amp;gt; представленных выражением в шаге 3 представленного выше алгоритма.&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Макроструктура алгоритма ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Инициализация центров масс &amp;lt;math&amp;gt;\mu_1, ..., \mu_k&amp;lt;/math&amp;gt;&amp;lt;/b&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
Наиболее распространенными являются следующие стратегии:&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&lt;br /&gt;
    &amp;lt;b&amp;gt;Метод Forgy&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;В качестве начальных значений &amp;lt;math&amp;gt;\mu_1, ..., \mu_k&amp;lt;/math&amp;gt; берутся случайно выбранные векторы.&lt;br /&gt;
  &amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&lt;br /&gt;
    &amp;lt;b&amp;gt;Метод случайно разделения (Random Partitioning)&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;Для каждого вектора &amp;lt;math&amp;gt;\mathbf{x}_i \in X, i=\overline{1, n}&amp;lt;/math&amp;gt; выбирается случайным образом кластер &amp;lt;math&amp;gt;S_1, ..., S_k&amp;lt;/math&amp;gt;, после чего для каждого полученного кластера вычисляются значения &amp;lt;math&amp;gt;\mu_1, ..., \mu_k&amp;lt;/math&amp;gt;.&lt;br /&gt;
  &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Распределение векторов по кластерам&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Для этого шага алгоритма между векторами &amp;lt;math&amp;gt;\mathbf{x}_i \in X, i=\overline{1, n}&amp;lt;/math&amp;gt; и центрами кластеров &amp;lt;math&amp;gt;\mu_1, ..., \mu_k&amp;lt;/math&amp;gt; вычисляются &amp;lt;b&amp;gt;расстояния&amp;lt;/b&amp;gt; по формуле (как правило, используется Евлидово расстояние):&lt;br /&gt;
&amp;lt;table style=&amp;quot;width:100%&amp;quot;&amp;gt;&lt;br /&gt;
  &amp;lt;tr&amp;gt;&lt;br /&gt;
    &amp;lt;td align=&amp;quot;center&amp;quot; width=&amp;quot;90%&amp;quot;&amp;gt;&amp;lt;math&amp;gt; \mathbf{v}_1, \mathbf{v}_2 \in \mathbb{R}^d,  \quad \rho(\mathbf{v}_1, \mathbf{v}_2) = \lVert \mathbf{v}_1- \mathbf{v}_2 \rVert= \sqrt{\sum_{i=1}^{d}(\mathbf{v}_{1,i} - \mathbf{v}_{2,i})^2}&amp;lt;/math&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;td align=&amp;quot;right&amp;quot;&amp;gt;&amp;lt;math&amp;gt;(2)&amp;lt;/math&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;/table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Пересчет центров кластеров&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Для этого шага алгоритма производится пересчет центров кластера по &amp;lt;b&amp;gt;формуле вычисления центра масс&amp;lt;/b&amp;gt;:&lt;br /&gt;
&amp;lt;table style=&amp;quot;width:100%&amp;quot;&amp;gt;&lt;br /&gt;
  &amp;lt;tr&amp;gt;&lt;br /&gt;
    &amp;lt;td align=&amp;quot;center&amp;quot; width=&amp;quot;90%&amp;quot;&amp;gt;&amp;lt;math&amp;gt; \mu = \cfrac{1}{|S|}\sum_{\mathbf{x}\in S}\mathbf{x}&amp;lt;/math&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;td align=&amp;quot;right&amp;quot;&amp;gt;&amp;lt;math&amp;gt;(3)&amp;lt;/math&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;/table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Схема реализации последовательного алгоритма ===&lt;br /&gt;
&lt;br /&gt;
 &#039;&#039;&#039;algorithm&#039;&#039;&#039; k-means &#039;&#039;&#039;is&#039;&#039;&#039;&lt;br /&gt;
     &#039;&#039;&#039;1.&#039;&#039;&#039; Инициализировать центры кластеров &amp;lt;math&amp;gt;\mathbf{\mu}_i^{(1)}, i=\overline{1,k}&amp;lt;/math&amp;gt;&lt;br /&gt;
     &#039;&#039;&#039;2.&#039;&#039;&#039; &amp;lt;math&amp;gt;t \leftarrow 1&amp;lt;/math&amp;gt;&lt;br /&gt;
     &#039;&#039;&#039;3.&#039;&#039;&#039; &#039;&#039;&#039;Распределение по кластерам&#039;&#039;&#039;&amp;lt;br&amp;gt;&lt;br /&gt;
        &amp;lt;math&amp;gt;S_i^{(t)}=\{\mathbf{x}_p: \lVert\mathbf{x}_p-\mathbf{\mu}_i^{(t)}\rVert^2 \leq \lVert\mathbf{x}_p-\mathbf{\mu}_j^{(t)}\rVert^2 \quad \forall j=\overline{1,k}\},&amp;lt;/math&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
        где каждый вектор &amp;lt;math&amp;gt;\mathbf{x}_p&amp;lt;/math&amp;gt; соотносится единственному кластеру &amp;lt;math&amp;gt;S^{(t)}&amp;lt;/math&amp;gt;&lt;br /&gt;
     &#039;&#039;&#039;4.&#039;&#039;&#039; &#039;&#039;&#039;Обновление центров кластеров&#039;&#039;&#039;&amp;lt;br&amp;gt;&lt;br /&gt;
        &amp;lt;math&amp;gt;\mathbf{\mu}_i^{(t+1)} = \frac{1}{|S^{(t)}_i|} \sum_{\mathbf{x}_j \in S^{(t)}_i} \mathbf{x}_j &amp;lt;/math&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
     &#039;&#039;&#039;5.&#039;&#039;&#039; &#039;&#039;&#039;if&#039;&#039;&#039; &amp;lt;math&amp;gt;\exist i \in \overline{1,k}: \mathbf{\mu}_i^{(t+1)} \ne \mathbf{\mu}_i^{(t)}&amp;lt;/math&amp;gt; &#039;&#039;&#039;then&#039;&#039;&#039;&lt;br /&gt;
            t = t + 1;&lt;br /&gt;
            goto &#039;&#039;&#039;3&#039;&#039;&#039;;&lt;br /&gt;
        &#039;&#039;&#039;else&#039;&#039;&#039;&lt;br /&gt;
            &#039;&#039;&#039;stop&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
=== Последовательная сложность алгоритма===&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding-bottom: 20px&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;Обозначим &amp;lt;math&amp;gt;\Theta_{centroid}^{d, m}&amp;lt;/math&amp;gt; временную сложность вычисления центорида кластера, число элементов которого равна &amp;lt;math&amp;gt;m&amp;lt;/math&amp;gt;,  в d-мерном пространстве.&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;Аналогично  &amp;lt;math&amp;gt;\Theta_{distance}^d&amp;lt;/math&amp;gt; &amp;amp;ndash; временная сложность вычисления расстояния между двумя d-мерными векторами.&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding-bottom: 20px&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;Сложность шага инициализации &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластеров мощности &amp;lt;math&amp;gt;m&amp;lt;/math&amp;gt; в d-мерном пространстве &amp;amp;ndash; &amp;lt;math&amp;gt;\Theta_{init}^{k, d, m}&amp;lt;/math&amp;gt;&amp;lt;/b&amp;gt;&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;i&amp;gt;Стратерия Forgy&amp;lt;/i&amp;gt;: вычисления не требуются, &amp;lt;math&amp;gt;\Theta_{init}^{k, d, m} = 0&amp;lt;/math&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;i&amp;gt;Стратегия случайного разбиения&amp;lt;/i&amp;gt;: вычисление центров &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластеров,  &amp;lt;math&amp;gt;\Theta_{init}^{k, d, m} = k \cdot \Theta_{centroid}^{d, m}, m \le n&amp;lt;/math&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding-bottom: 20px&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Cложность шага распределения d мерных векторов по &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластерам &amp;amp;ndash; &amp;lt;math&amp;gt;\Theta_{distribute}^{k, d}&amp;lt;/math&amp;gt;&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
На этом шаге для каждого вектора &amp;lt;math&amp;gt;\mathbf{x}_i \in X, i=\overline{1, n}&amp;lt;/math&amp;gt; вычисляется k расстояний до центров кластеров &amp;lt;math&amp;gt;\mathbf{\mu}_1, ...\mathbf{\mu}_k&amp;lt;/math&amp;gt;&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p align=&amp;quot;center&amp;quot;&amp;gt;&lt;br /&gt;
  &amp;lt;math&amp;gt;\Theta_{distribute}^{k, d} = n \cdot k \cdot \Theta_{distance}^d&amp;lt;/math&amp;gt;&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding-bottom: 20px&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;Сложность шага пересчета центров &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластеров размера &amp;lt;math&amp;gt;m&amp;lt;/math&amp;gt; в d-мерном пространстве &amp;amp;ndash; &amp;lt;math&amp;gt;\Theta_{recenter}^{k, d, m}&amp;lt;/math&amp;gt;&amp;lt;/b&amp;gt;&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;На этом шаге вычисляется &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; центров кластеров &amp;lt;math&amp;gt;\mathbf{\mu}_1, ...\mathbf{\mu}_k&amp;lt;/math&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p align=&amp;quot;center&amp;quot;&amp;gt;&amp;lt;math&amp;gt;\Theta_{recenter}^{k, d, m} = k \cdot \Theta_{centroid}^{d, m}&amp;lt;/math&amp;gt; &amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding-bottom: 20px&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Рассчитаем &amp;lt;math&amp;gt;\Theta_{centroid}^{d, m}&amp;lt;/math&amp;gt; для кластера, число элементов которого равно &amp;lt;math&amp;gt;m&amp;lt;/math&amp;gt;&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p align=&amp;quot;center&amp;quot;&amp;gt;&amp;lt;math&amp;gt;\Theta_{centroid}^{d, m}&amp;lt;/math&amp;gt; = &amp;lt;math&amp;gt;m \cdot d&amp;lt;/math&amp;gt; сложений + &amp;lt;math&amp;gt;d&amp;lt;/math&amp;gt; делений &amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding-bottom: 20px&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Рассчитаем &amp;lt;math&amp;gt;\Theta_{distance}^d&amp;lt;/math&amp;gt; в соответствие с формулой &amp;lt;math&amp;gt;(2)&amp;lt;/math&amp;gt;&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p align=&amp;quot;center&amp;quot;&amp;gt;&amp;lt;math&amp;gt;\Theta_{distance}^d&amp;lt;/math&amp;gt; = &amp;lt;math&amp;gt;d&amp;lt;/math&amp;gt; вычитаний + &amp;lt;math&amp;gt;d&amp;lt;/math&amp;gt; умножений + &amp;lt;math&amp;gt;(d-1)&amp;lt;/math&amp;gt; сложение&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding-bottom: 20px&amp;quot;&amp;gt;&lt;br /&gt;
  &amp;lt;p&amp;gt;Предположим, что алгоритм сошелся за &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt; итераций, тогда временная сложность алгоритма &amp;lt;math&amp;gt;\Theta_{k-means}^{d, n}&amp;lt;/math&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
  &amp;lt;p align=&amp;quot;center&amp;quot;&amp;gt;&amp;lt;b&amp;gt;&amp;lt;math&amp;gt;\Theta_{k-means}^{d, n} \le \Theta_{init}^{k, d, n} + i(\Theta_{distribute}^{k, d} + \Theta_{recenter}^{k, d, n})&amp;lt;/math&amp;gt;&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding-bottom: 5px&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;Операции сложения/вычитания:&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p align=&amp;quot;center&amp;quot;&amp;gt;&amp;lt;b&amp;gt;&amp;lt;math&amp;gt;\Theta_{k-means}^{d, n} \le knd+ i(kn(2d-1) + knd) = knd+ i(kn(3d-1)) \thicksim O(ikdn)&amp;lt;/math&amp;gt;&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding-bottom: 20px&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;Операции умножения/деления:&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p align=&amp;quot;center&amp;quot;&amp;gt;&amp;lt;b&amp;gt;&amp;lt;math&amp;gt;\Theta_{k-means}^{d, n} \le kd + i(knd + kd) = kd + ikd(n+1) \thicksim O(ikdn) &amp;lt;/math&amp;gt;&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding-bottom: 20px&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;Получаем, что &amp;lt;b&amp;gt;временная сложность&amp;lt;/b&amp;gt; алгоритма &amp;lt;b&amp;gt;k means&amp;lt;/b&amp;gt; кластеризации &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; &amp;lt;b&amp;gt;d-мерных&amp;lt;/b&amp;gt; векторов на &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластеров за &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt; итераций:&amp;lt;/p&amp;gt;&lt;br /&gt;
 &amp;lt;p align=&amp;quot;center&amp;quot;&amp;gt;&amp;lt;b&amp;gt;&amp;lt;math&amp;gt; \Theta_{k-means}^{d, n} \thicksim O(ikdn) &amp;lt;/math&amp;gt;&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Информационный граф ===&lt;br /&gt;
&lt;br /&gt;
Рассмотрим информационный граф алгоритма. Алгоритм &amp;lt;i&amp;gt;k means&amp;lt;/i&amp;gt; начинается с этапа инициализации, после которого следуют итерации, на каждой из которых выполняется два последовательных шага (см. [[#Схема реализации последовательного алгоритма|&amp;quot;Схема реализации последовательного алгоритма&amp;quot;]]): &lt;br /&gt;
* распределение векторов по кластерам&lt;br /&gt;
* перерасчет центров кластеров&lt;br /&gt;
&lt;br /&gt;
Поскольку основная часть вычислений приходится на шаги итераций, распишем информационные графы данных шагов.&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Распределение векторов по кластерам&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
Информационный граф шага распределения векторов по кластерам представлен на &#039;&#039;рисунке 1&#039;&#039;. Исходами данного графа является исходные векторы &amp;lt;math&amp;gt;\mathbf{x}_1, ..., \mathbf{x}_n&amp;lt;/math&amp;gt;, а также центры кластеров &amp;lt;math&amp;gt;\mathbf{\mu}_1, ... \mathbf{\mu}_k&amp;lt;/math&amp;gt;, вычисленные ранее (на шаге инициализации, если рассматривается первая итерация алгоритма, или на шаге пересчета центров кластеров предыдущей итерации в противном случае). Каждая пара векторов данных &amp;lt;math&amp;gt;\mathbf{x}_i, i=\overline{1,n}&amp;lt;/math&amp;gt; и центров кластера &amp;lt;math&amp;gt;\mathbf{\mu}_j, j=\overline{1, k}&amp;lt;/math&amp;gt; : (&amp;lt;math&amp;gt;\mathbf{x}_i&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;\mathbf{\mu}_j&amp;lt;/math&amp;gt;) подаются на независимые узлы &amp;lt;i&amp;gt;&amp;quot;d&amp;quot;&amp;lt;/i&amp;gt; вычисления расстояния между векторами (более подробная схема вычисления расстояния представлена далее, &#039;&#039;рисунок 2&#039;&#039;). Далее узлы вычисления расстояния &amp;lt;i&amp;gt;&amp;quot;d&amp;quot;&amp;lt;/i&amp;gt;, соответствующие одному и тому же исходному вектору &amp;lt;math&amp;gt;\mathbf{x}_i&amp;lt;/math&amp;gt; передаются на один узел &amp;lt;i&amp;gt;&amp;quot;m&amp;quot;&amp;lt;/i&amp;gt;, где далее происходит вычисление новой метки кластера для каждого вектора &amp;lt;math&amp;gt;\mathbf{x}_i&amp;lt;/math&amp;gt; (берется кластер с минимальным результатом вычисления расстояния). На выходе графа выдаются метки кластеров , &amp;lt;math&amp;gt;L_1, ..., L_n&amp;lt;/math&amp;gt;, такие что &amp;lt;math&amp;gt;\forall \mathbf{x}_i, i=\overline{1, n}, \mathbf{x}_i \in S_j \Leftrightarrow L_i = j&amp;lt;/math&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
[[file:Clusterization.png|thumb|center|800px|Рис. 1. Схема распределения векторов по кластерам. &#039;&#039;d&#039;&#039; &amp;amp;ndash; вычисление расстояния между векторами; &#039;&#039;m&#039;&#039; &amp;amp;ndash; вычисление минимума.]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Вычисление расстояния между векторами&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
Подробная схема вычисления расстояния между векторами &amp;lt;math&amp;gt;\mathbf{x}_i, \mathbf{\mu}_j&amp;lt;/math&amp;gt; представлена на &#039;&#039;рисунке 2&#039;&#039;. Как показано на графе, узел вычисления расстояния между векторами &amp;lt;i&amp;gt;&amp;quot;d&amp;quot;&amp;lt;/i&amp;gt; состоит из шага взятия разности между векторами (узел &amp;quot;&amp;lt;math&amp;gt;-&amp;lt;/math&amp;gt;&amp;quot;) и взятия нормы получившегося вектора разности (узел &amp;quot;&amp;lt;math&amp;gt;||\cdot||^2&amp;lt;/math&amp;gt;&amp;quot;). Более подробно, вычисление расстояния между векторами &amp;lt;math&amp;gt;\mathbf{x}_i = {x_{i1,}, ...,{x_{in}}}, \mathbf{\mu}_j = {\mu_{j1}, ...,\mu_{jn}}&amp;lt;/math&amp;gt; может быть представлено как вычисление разности между каждой парой компонент &amp;lt;math&amp;gt;(x_{iz}, \mu_{jz}), z=\overline{1, d}&amp;lt;/math&amp;gt; (узел &amp;quot;&amp;lt;math&amp;gt;-&amp;lt;/math&amp;gt;&amp;quot;), далее возведение в квадрат для каждого узла &amp;quot;&amp;lt;math&amp;gt;-&amp;lt;/math&amp;gt;&amp;quot; (узел &amp;quot;&amp;lt;math&amp;gt;()^2&amp;lt;/math&amp;gt;&amp;quot;) и суммирования выходов всех узлов &amp;quot;&amp;lt;math&amp;gt;()^2&amp;lt;/math&amp;gt;&amp;quot; (узел &amp;quot;&amp;lt;math&amp;gt;+&amp;lt;/math&amp;gt;&amp;quot;).  &lt;br /&gt;
&lt;br /&gt;
[[file:dist_calc.png|thumb|center|800px|Рис. 2. Схема вычисления расстояния между вектором и центром кластера.]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Пересчет центров кластеров&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
Информационный граф шага пересчета центров кластеров представлен на &#039;&#039;рисунке 3&#039;&#039;. Исходами данного графа является исходные векторы &amp;lt;math&amp;gt;\mathbf{x}_1, ..., \mathbf{x}_n&amp;lt;/math&amp;gt;, а также им соответствующие метки кластера, &amp;lt;math&amp;gt;L_1, ..., L_n&amp;lt;/math&amp;gt;, такие что &amp;lt;math&amp;gt;\forall x_i, i=\overline{1, n}, \mathbf{x}_i \in S_j \Leftrightarrow L_i = j&amp;lt;/math&amp;gt;, вычисленные на этапе распределения векторов по кластерам. Все векторы &amp;lt;math&amp;gt;\mathbf{x}_1, ..., \mathbf{x}_n&amp;lt;/math&amp;gt; подаются в узлы &amp;lt;math&amp;gt;+_1, ...+_k&amp;lt;/math&amp;gt;, каждый узел &amp;lt;math&amp;gt;+_m, m = \overline{1,k}&amp;lt;/math&amp;gt; соответствует операции сложения векторов кластера с номером &amp;lt;math&amp;gt;m&amp;lt;/math&amp;gt;. Метки кластера &amp;lt;math&amp;gt;L_1, ..., L_n&amp;lt;/math&amp;gt; также совместно передаются на узлы &amp;lt;math&amp;gt;S_m, m = \overline{1,k}&amp;lt;/math&amp;gt;, на каждом из которых вычисляется количество векторов в соответствующем кластере (количество меток с соответствующим значением). Далее каждая пара выходов узлов &amp;lt;math&amp;gt;+_m&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;S_m&amp;lt;/math&amp;gt; подается на узел &amp;quot;&amp;lt;math&amp;gt;/&amp;lt;/math&amp;gt;&amp;quot;, где производится деление суммы векторов кластера на количество элементов в нем. Значения, вычисленные на узлах &amp;quot;&amp;lt;math&amp;gt;/&amp;lt;/math&amp;gt;&amp;quot;, присваиваются новым центрам кластеров (выходные значения графа).&lt;br /&gt;
&lt;br /&gt;
[[file:Recluster.png|thumb|center|800px|Рис. 3. Схема пересчета центров кластеров]]&lt;br /&gt;
&lt;br /&gt;
=== Ресурс параллелизма алгоритма ===&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
Работа алгоритма состоит из &amp;lt;math&amp;gt;\Tau&amp;lt;/math&amp;gt; итераций, в каждой из которых происходит &amp;lt;b&amp;gt;распределение d-мерных векторов по &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластерам&amp;lt;/b&amp;gt;, а также &amp;lt;b&amp;gt;пересчет центров кластеров в d-мерном пространстве&amp;lt;/b&amp;gt;. В шаге &amp;lt;b&amp;gt;распределения d-мерных векторов по &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластерам&amp;lt;/b&amp;gt; расстояния между вектором и центрами кластеров вычисляются независимо (отсутствуют информационные зависимости). &amp;lt;b&amp;gt;Центры масс кластеров&amp;lt;/b&amp;gt; также пересчитываются независимо друг от друга. Таким образом, имеет место [[глоссарий#Массовый параллелизм|&#039;&#039;массовый параллелизм&#039;&#039;]]. Вычислим параллельную сложность &amp;lt;math&amp;gt;\Psi_*&amp;lt;/math&amp;gt; каждого из шагов, а также параллельную сложность всего алгоритма, &amp;lt;math&amp;gt;\Psi_{k-means}&amp;lt;/math&amp;gt;. Будем исходить из предположения, что может быть использовано любое необходимое число потоков.&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Распределение d-мерных векторов по &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластерам&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;  &lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
Поскольку на данном шаге для каждой пары векторов &amp;lt;math&amp;gt;\mathbf{x}_i, i=\overline{1,n}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\mathbf{\mu}_j, j=\overline{1,k}&amp;lt;/math&amp;gt; операции вычисления расстояния не зависят друг от друга, они могут выполняться параллельно. Тогда, разделив все вычисление расстояний на &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; потоков, получим, что в каждом потоке будет выполняться только одна операция вычисления расстояния между векторами размерности d. При этом каждому вычислительному потоку передаются координаты центров всех кластеров &amp;lt;math&amp;gt;\mathbf{\mu}_1, ..., \mathbf{\mu}_k&amp;lt;/math&amp;gt;. Таким образом, параллельная сложность данного шага определяется &amp;lt;i&amp;gt; сложностью параллельной операции вычисления расстояния между d-мерными векторами&amp;lt;/i&amp;gt;, &amp;lt;math&amp;gt;\Psi_{distance}^d&amp;lt;/math&amp;gt;  и &amp;lt;i&amp;gt;сложностью определения наиболее близкого кластера&amp;lt;/i&amp;gt; (паралельное взятие минимума по расстояниям), &amp;lt;math&amp;gt;\Psi_{min}^k&amp;lt;/math&amp;gt;. Для оценки &amp;lt;math&amp;gt;\Psi_{distance}^d&amp;lt;/math&amp;gt; воспользуемся  [[Нахождение_частных_сумм_элементов_массива_сдваиванием | параллельной реализацией нахождения частичной суммы элементов массива путем сдваивания]]. Аналогично, &amp;lt;math&amp;gt;\Psi_{min}^k = log(k)&amp;lt;/math&amp;gt;. В результате, &amp;lt;math&amp;gt;\Psi_{distance}^d = O(log(d))&amp;lt;/math&amp;gt;.   Таким образом: &lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p align=&amp;quot;center&amp;quot;&amp;gt;&amp;lt;math&amp;gt;\Psi_{distribute}^{k, d}  = \Psi_{distance}^d + \Psi_{min}^k = O(log(d))+O(log(k)) = O(log(k*d))&amp;lt;/math&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Пересчет центров кластеров в d-мерном пространстве&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
Поскольку на данном шаге для каждого из &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластеров центр масс может быть вычислен независимо, данные операции могут быть выполнены в отдельных потоках. Таким образом, параллельная сложность данного шага, &amp;lt;math&amp;gt;\Psi_{recenter}^{k, d}&amp;lt;/math&amp;gt;,  будет определяться &amp;lt;i&amp;gt;параллельной сложностью вычисления одного центра масс кластера размера &amp;lt;math&amp;gt;m&amp;lt;/math&amp;gt;&amp;lt;/i&amp;gt;, &amp;lt;math&amp;gt;\Psi_{recenter}^{k, d}&amp;lt;/math&amp;gt;,  а так как &amp;lt;math&amp;gt;m \le n \Rightarrow \Psi_{recenter}^{d, m} \le \Psi_{recenter}^{d, n}&amp;lt;/math&amp;gt;. Сложность вычисления центра масс кластера d-мерных векторов размера n аналогично предыдущим вычислениям равна &amp;lt;math&amp;gt;O(log(n))&amp;lt;/math&amp;gt;. Тогда:  &lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p align=&amp;quot;center&amp;quot;&amp;gt;&amp;lt;math&amp;gt;\Psi_{recenter}^{k, d}  \le \Psi_{recenter}^{d, n} = O(log(n))&amp;lt;/math&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Общая параллельная сложность алгоритма&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
На каждой итерации необходимо обновление центров кластеров, которые будут использованы на следующей итерации. Таким образом, итерационный процесс выполняется последовательно&amp;lt;ref&amp;gt;Zhao, Weizhong, Huifang Ma, and Qing He. &amp;quot;Parallel k-means clustering based on mapreduce.&amp;quot; IEEE International Conference on Cloud Computing. Springer Berlin Heidelberg, 2009.&amp;lt;/ref&amp;gt;. Тогда, поскольку сложность каждой итерации  определяется &amp;lt;math&amp;gt;\Psi_{distribute}^{k, d}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\Psi_{recenter}&amp;lt;/math&amp;gt;, сложность всего алгоритма, &amp;lt;math&amp;gt;\Psi_{k-means}&amp;lt;/math&amp;gt; в предположении, что было сделано &amp;lt;math&amp;gt;\Tau&amp;lt;/math&amp;gt; операций определяется выражением&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p align=&amp;quot;center&amp;quot;&amp;gt;&amp;lt;math&amp;gt;\Psi_{k-means} \approx \Tau * (\Psi_{distribute}^{k, d} + \Psi_{recenter}^{k, d}) \le \Tau * O(log(k*d*n))&amp;lt;/math&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Входные и выходные данные алгоритма ===&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;Входные данные&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;Матрица из &amp;lt;math&amp;gt;n*d&amp;lt;/math&amp;gt; элементов &amp;lt;math&amp;gt;x_{i, j} \in \mathbb{R}, i=\overline{1, n}, j=\overline{1, d}&amp;lt;/math&amp;gt;&amp;amp;ndash; координат векторов (наблюдений).&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;Целое положительное число &amp;lt;math&amp;gt;k, k \le n&amp;lt;/math&amp;gt; &amp;amp;ndash; количество кластеров.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;Объем входных данных&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;math&amp;gt;1&amp;lt;/math&amp;gt; целое число + &amp;lt;math&amp;gt;n*d&amp;lt;/math&amp;gt; вещественных чисел (при условии, что координаты &amp;amp;ndash; вещественные числа).&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;Выходные данные&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; целых положительных чисел &amp;lt;math&amp;gt;L_1, ..., L_n&amp;lt;/math&amp;gt;&amp;amp;ndash; номера кластеров, соотвествующие каждому вектору (при условии, что нумерация кластеров начинается с &amp;lt;math&amp;gt;1&amp;lt;/math&amp;gt;).&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;Объем выходных данных&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; целых положительных чисел.&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Свойства алгоритма ===&lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;[[глоссарий#Вычислительная мощность|&#039;&#039;Вычислительная мощность&#039;&#039;]]&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
Вычислительная мощность алгоритма &amp;lt;i&amp;gt;k means&amp;lt;/i&amp;gt; равна &amp;lt;math&amp;gt;\frac{k*d*n*\Tau}{n*d} = k*\Tau &amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; &amp;amp;ndash; число кластеров, &amp;lt;math&amp;gt;\Tau&amp;lt;/math&amp;gt; &amp;amp;ndash; число итераций алгоритма.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;[[глоссарий#Детерминированность |&#039;&#039;Детерминированность&#039;&#039;]] и [[глоссарий#Устойчивость |&#039;&#039;Устойчивость&#039;&#039;]] &amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
Алгоритм &amp;lt;i&amp;gt;k means&amp;lt;/i&amp;gt; является итерационным. Количество итераций алгоритма в общем случае не фиксируется и зависит от начального расположения объектов в пространстве, параметра &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt;, а также от начального приближения центров кластеров, &amp;lt;math&amp;gt;\mu_1, ..., \mu_k&amp;lt;/math&amp;gt;. В результате этого может варьироваться результат работы алгоритма. При неудачном выборе начальных параметров итерационный процесс может сойтись к локальному оптимуму&amp;lt;ref&amp;gt;Von Luxburg, Ulrike. Clustering Stability. Now Publishers Inc, 2010.&amp;lt;/ref&amp;gt;. По этим причинам алгоритм не является ни &amp;lt;b&amp;gt;детермирированным&amp;lt;/b&amp;gt;, ни &amp;lt;b&amp;gt;устойчивым&amp;lt;/b&amp;gt;.&lt;br /&gt;
 &lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Соотношение последовательной и параллельной сложности алгоритма&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\frac{\Theta_{k-means}}{\Psi_{k-means}} = \frac{O(\Tau*k*d*n)}{O(\Tau*log(k*d*n))}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Сильные стороны алгоритма&amp;lt;/b&amp;gt;:&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;i&amp;gt;Сравнительно высокая эффективность при простоте реализации&amp;lt;/i&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;i&amp;gt;Высокое качество кластеризации&amp;lt;/i&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;i&amp;gt;Возможность распараллеливания&amp;lt;/i&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;i&amp;gt;Существование множества модификаций&amp;lt;/i&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;Недостатки алгоритма&amp;lt;/b&amp;gt;&amp;lt;ref&amp;gt;Ortega, Joaquín Pérez, Ma Del Rocío Boone Rojas, and María J. Somodevilla. &amp;quot;Research issues on K-means Algorithm: An Experimental Trial Using Matlab.&amp;quot;&amp;lt;/ref&amp;gt;:&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;i&amp;gt;Количество кластеров является параметром алгоритма&amp;lt;/i&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;&amp;lt;i&amp;gt;Чувствительность к начальным условиям&amp;lt;/i&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;Инициализация центров кластеров в значительной степени влияет на результат кластеризации.&amp;lt;/p&amp;gt;&lt;br /&gt;
  &amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;&amp;lt;i&amp;gt;Чувствительность к выбросам и шумам&amp;lt;/i&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;Выбросы, далекие от центров настоящих кластеров, все равно учитываются при вычислении их центров.&amp;lt;/p&amp;gt;&lt;br /&gt;
  &amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;&amp;lt;i&amp;gt;Возможность сходимости к локальному оптимуму&amp;lt;/i&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;Итеративный подход не дает гарантии сходимости к оптимальному решению.&amp;lt;/p&amp;gt;&lt;br /&gt;
  &amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;&amp;lt;i&amp;gt;Использование понятия &amp;quot;среднего&amp;quot;&amp;lt;/i&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;Алгоритм неприменим к данным, для которых не определено понятие &amp;quot;среднего&amp;quot;, например, категориальным данным.&amp;lt;/p&amp;gt;&lt;br /&gt;
  &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&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;
Исследование масштабируемости параллельной реализации алгоритма k means проводилось на суперкомпьютере &amp;quot;Ломоносов&amp;quot;&amp;lt;ref name=&amp;quot;Lom&amp;quot;&amp;gt;Воеводин Вл., Жуматий С., Соболев С., Антонов А., Брызгалов П., Никитенко Д., Стефанов К., Воеводин Вад. Практика суперкомпьютера «Ломоносов» // Открытые системы, 2012, N 7, С. 36-39.&amp;lt;/ref&amp;gt; [http://parallel.ru/cluster Суперкомпьютерного комплекса Московского университета]. Алгоритм реализован на языке C с использованием средств MPI.&lt;br /&gt;
Для исследования масштабируемости проводилось множество запусков программы с разным значением параметра (количество векторов для кластеризации), а также с различным числом процессоров. Фиксировались результаты запусков &amp;amp;ndash; время работы &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt; и количество произведенных итераций алгоритма &amp;lt;math&amp;gt;\Tau&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Параметры запусков для экспериментальной оценки:&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;Значения &amp;lt;b&amp;gt;количества векторов&amp;lt;/b&amp;gt; &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;: 20&#039;000, 30&#039;000, 50&#039;000, 100&#039;000, 200&#039;000, 300&#039;000, 500&#039;000, 700&#039;000, 1&#039;000&#039;000, 1&#039;500&#039;000, 2&#039;000&#039;000.&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;Значения &amp;lt;b&amp;gt;количества процессоров&amp;lt;/b&amp;gt; &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt;: 1, 8, 16, 32, 64, 128, 160, 192, 224, 256, 288, 320, 352, 384, 416, 448, 480, 512.&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;Значение &amp;lt;b&amp;gt;количества кластеров&amp;lt;/b&amp;gt; &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt;: 100.&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;Значение &amp;lt;b&amp;gt;размерности векторов&amp;lt;/b&amp;gt; &amp;lt;math&amp;gt;d&amp;lt;/math&amp;gt;: 10.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Для проведения экспериментов были сгенерированы нормально распределенные псевдослучайные данные (с использованием Python библиотеки [http://scikit-learn.org/ scikit-learn]):&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
from sklearn.datasets import make_classification&lt;br /&gt;
X1, Y1 = make_classification(n_features=10, n_redundant=2, n_informative=8,&lt;br /&gt;
                             n_clusters_per_class=1, n_classes=100,&lt;br /&gt;
                             n_samples=2000000)&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Для заданной конфигурации эксперимента (&amp;lt;math&amp;gt;n, d, p, k&amp;lt;/math&amp;gt;) и полученных результатов (&amp;lt;math&amp;gt;t, \Tau&amp;lt;/math&amp;gt;)  [[Глоссарий#Производительность|производительность]]  и эффективность реализации расчитывались по формулам:&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
&amp;lt;ul&amp;gt;&amp;lt;li&amp;gt;&amp;lt;math&amp;gt;Performance = \frac{N_{k-means}^{d, n}}{t}\ \ (FLOPS),&amp;lt;/math&amp;gt;&amp;lt;/li&amp;gt;&amp;lt;/ul&amp;gt;&lt;br /&gt;
где &amp;lt;math&amp;gt;N_{k-means}^{d, n}&amp;lt;/math&amp;gt; &amp;amp;ndash; точное число операций с плавающей точкой (операции с памятью, а также целочисленные операции не учитывались), вычисленное в соответствие с разделом [[#Последовательная сложность алгоритма| &amp;quot;Последовательная сложность алгоритма&amp;quot;]];&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
&amp;lt;ul&amp;gt;&amp;lt;li&amp;gt;&amp;lt;math&amp;gt;Efficiency = \frac{100 * Performance}{Performance_{Peak}^{p}}\ \ (%),&amp;lt;/math&amp;gt;&amp;lt;/li&amp;gt;&amp;lt;/ul&amp;gt;&lt;br /&gt;
где &amp;lt;math&amp;gt;Performance_{Peak}^{p}&amp;lt;/math&amp;gt; &amp;amp;ndash; пиковая производительность суперкомпьютера при &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt; процессорах, вычисленная согласно спецификациям Intel&amp;lt;sup&amp;gt;&amp;amp;reg;&amp;lt;/sup&amp;gt; XEON&amp;lt;sup&amp;gt;&amp;amp;reg;&amp;lt;/sup&amp;gt; X5670&amp;lt;ref&amp;gt;&amp;quot;http://ark.intel.com/ru/products/47920/Intel-Xeon-Processor-X5670-12M-Cache-2_93-GHz-6_40-GTs-Intel-QPI&amp;quot;&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Графики зависимости производительности и эффективности параллельной реализации k means от числа векторов для кластеризации (&amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;) и числа процессоров (&amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt;) представлены на рисунках 4 и 5 соответственно.&lt;br /&gt;
&lt;br /&gt;
[[file:Flops.png|thumb|center|800px|Рис. 4. Параллельная реализация k means. График зависимости производительности реализации алгоритма от числа векторов для кластеризации (&amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;) и числа процессоров (&amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt;).]]&lt;br /&gt;
[[file:Efficiency.png|thumb|center|800px|Рис. 5. Параллельная реализация k means. График зависимости эффективности реализации алгоритма от числа векторов для кластеризации (&amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;) и числа процессоров (&amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt;).]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;В результате&amp;lt;/b&amp;gt; экспериментальной оценки были получены следующие оценки эффективности реализации:&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;b&amp;gt;Минимальное&amp;lt;/b&amp;gt; значение: 0.000409 % достигается при &amp;lt;math&amp;gt;n=20&#039;000, p=480&amp;lt;/math&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;b&amp;gt;Максимальное&amp;lt;/b&amp;gt; значение: 0.741119 % достигается при &amp;lt;math&amp;gt;n=300&#039;000, p=1&amp;lt;/math&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
Оценки масштабируемости реализации алгоритма k means:&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;b&amp;gt;По числу процессоров:&amp;lt;/b&amp;gt; -0.002683 &amp;amp;ndash; эффективность убывает с ростом числа процессоров. Данный результат вызван ростом накладных расходов для обеспечения параллельного выполнения алгоритма.&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;b&amp;gt;По размеру задачи:&amp;lt;/b&amp;gt; 0.002779 &amp;amp;ndash; эффективность растет с ростом числа векторов. Данный результат вызван тем, что при увеличении размера задачи, количество вычислений растет по сравнению с временем, затрачиваемым на пересылку данных.&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;b&amp;gt;Общая оценка:&amp;lt;/b&amp;gt; -0.000058 &amp;amp;ndash; можно сделать вывод, что в целом эффективность реализации незначительно уменьшается с ростом размера задачи и числа процессоров.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[https://github.com/serban/kmeans Использованная параллельная реализация алгоритма k means]&lt;br /&gt;
&lt;br /&gt;
=== Динамические характеристики и эффективность реализации алгоритма ===&lt;br /&gt;
=== Выводы для классов архитектур ===&lt;br /&gt;
=== Существующие реализации алгоритма ===&lt;br /&gt;
==== Открытое программное обеспечение ====&lt;br /&gt;
&amp;lt;ol&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;[https://www.icpsr.umich.edu/CrimeStat/ CrimeStat]&amp;lt;/li&amp;gt; Программное обеспечение, созданное для операционных систем Windows, предоставляющее инструменты статистического  и пространственного анализа для решения задачи картирования преступности.&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://juliastats.github.io Julia]&amp;lt;/li&amp;gt; Высокоуровневый высокопроизводительный свободный язык программирования с динамической типизацией, созданный для математических вычислений, содержит реализацию k-means.&lt;br /&gt;
  &amp;lt;li&amp;gt;[https://mahout.apache.org Mahout]&amp;lt;/li&amp;gt; Apache Mahout - Java библиотека для работы с алгоритмами машинного обучения с использованием MapReduce. Содержит реализацию k-means.&lt;br /&gt;
  &amp;lt;li&amp;gt;[https://www.gnu.org/software/octave/ Octave]&amp;lt;/li&amp;gt; Написанная на C++  свободная система для математических вычислений, использующая совместимый с MATLAB язык высокого уровня, содержит реализацию k-means.&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://spark.apache.org/docs/latest/mllib-clustering.html Spark]&amp;lt;/li&amp;gt; Распределенная реализация k-means содержится в библиотеке Mlib для работы с алгоритмами машинного обучения, взаимодействующая с Python библиотекой NumPy и библиотека R.&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://torch.ch Torch]&amp;lt;/li&amp;gt;  MATLAB-подобная библиотека для языка программирования Lua с открытым исходным кодом, предоставляет большое количество алгоритмов для глубинного обучения и научных расчётов. Ядро написано на Си, прикладная часть выполняется на LuaJIT, поддерживается распараллеливание вычислений средствами CUDA и OpenMP. Существуют реализации k-means.&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://www.cs.waikato.ac.nz/ml/weka/ Weka]&amp;lt;/li&amp;gt;  Cвободное программное обеспечение для анализа данных, написанное на Java. Содержит k-means и x-means.&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://accord-framework.net/docs/html/T_Accord_MachineLearning_KMeans.htm Accord.NET]&amp;lt;/li&amp;gt; C# реализация алгоритмов k-means, k-means++, k-modes.&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://docs.opencv.org/3.0-beta/doc/py_tutorials/py_ml/py_kmeans/py_kmeans_opencv/py_kmeans_opencv.html OpenCV]&amp;lt;/li&amp;gt; Написанная на С++ библиотека, направленная в основном на решение задач компьютерного зрения. Содержит реализацию k-means.&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://mlpack.org/ MLPACK]&amp;lt;/li&amp;gt; Масштабируемая С++ библиотека для работы с алгоритмами машинного обучения, содержит реализацию k-means.&lt;br /&gt;
  &amp;lt;li&amp;gt;[https://www.scipy.org/ SciPy]&amp;lt;/li&amp;gt; Библиотека Python, содержит множество реализаций k-means.&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://scikit-learn.org/ scikit-learn]&amp;lt;/li&amp;gt; Библиотека Python, содержит множество реализаций k-means.&lt;br /&gt;
  &amp;lt;li&amp;gt;[https://www.r-bloggers.com/k-means-clustering-in-r/ R]&amp;lt;/li&amp;gt; Язык программирования для статистической обработки данных и работы с графикой, а также свободная программная среда вычислений с открытым исходным кодом в рамках проекта GNU, содержит три реализации k-means.&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://elki.dbs.ifi.lmu.de ELKI]&amp;lt;/li&amp;gt; Java фреймворк, содержащий реализацию k-means, а также множество других алгоритмов кластеризации.&lt;br /&gt;
&amp;lt;/ol&amp;gt;&lt;br /&gt;
==== Проприетарное программное обеспечение  ====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ol&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;[https://www.ayasdi.com/blog/bigdata/topological-data-analysis-of-oil-and-gas-petrophysical-data/ Ayasdi]&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://www.stata.com/features/cluster-analysis/ Stata]&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://mathworld.wolfram.com/K-MeansClusteringAlgorithm.html Mathematica]&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://www.mathworks.com/help/stats/kmeans.html?requestedDomain=www.mathworks.com MATLAB]&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;[https://support.sas.com/rnd/app/stat/procedures/fastclus.html SAS]&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://docs.rapidminer.com/studio/operators/modeling/segmentation/k_means.html RapidMiner]&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;[https://blogs.sap.com/2013/03/28/sap-hana-pal-k-means-algorithm-or-how-to-do-customer-segmentation-for-the-telecommunications-industry/ SAP HANA]&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ol&amp;gt;&lt;br /&gt;
== Литература ==&lt;br /&gt;
&amp;lt;references /&amp;gt;&lt;/div&gt;</summary>
		<author><name>DennZo1993</name></author>
	</entry>
	<entry>
		<id>https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:%D0%91%D1%80%D0%BE%D1%82%D0%B8%D0%BA%D0%BE%D0%B2%D1%81%D0%BA%D0%B0%D1%8F_%D0%94%D0%B0%D0%BD%D1%83%D1%82%D0%B0/%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_k-means&amp;diff=20525</id>
		<title>Участник:Бротиковская Данута/Алгоритм k-means</title>
		<link rel="alternate" type="text/html" href="https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:%D0%91%D1%80%D0%BE%D1%82%D0%B8%D0%BA%D0%BE%D0%B2%D1%81%D0%BA%D0%B0%D1%8F_%D0%94%D0%B0%D0%BD%D1%83%D1%82%D0%B0/%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_k-means&amp;diff=20525"/>
		<updated>2016-12-10T10:43:46Z</updated>

		<summary type="html">&lt;p&gt;DennZo1993: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Assignment|Zhum}}&lt;br /&gt;
&lt;br /&gt;
{{algorithm&lt;br /&gt;
| name              = Алгоритм k средних (k means)&lt;br /&gt;
| serial_complexity = &amp;lt;math&amp;gt;O(i*k*d*n)&amp;lt;/math&amp;gt;&lt;br /&gt;
| input_data        = &amp;lt;math&amp;gt; d*n &amp;lt;/math&amp;gt;&lt;br /&gt;
| output_data       = &amp;lt;math&amp;gt; n &amp;lt;/math&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
Авторы страницы &amp;lt;b&amp;gt;[[Участник:Бротиковская Данута|Данута Бротиковская]]&amp;lt;/b&amp;gt; и &amp;lt;b&amp;gt;[[Участник:DennZo1993|Денис Зобнин]]&amp;lt;/b&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
Оба автора внесли одинаковый вклад в написание статьи (поиск материалов, изучение статей, заполнение контента статьи), четких разграничений по пунктам статьи сделать невозможно. &lt;br /&gt;
&lt;br /&gt;
== Свойства и структура алгоритма ==&lt;br /&gt;
&lt;br /&gt;
=== Общее описание алгоритма ===&lt;br /&gt;
Алгоритм &amp;lt;b&amp;gt;&amp;lt;i&amp;gt;k средних&amp;lt;/i&amp;gt;&amp;lt;/b&amp;gt; (&amp;lt;b&amp;gt;&amp;lt;i&amp;gt;k means&amp;lt;/i&amp;gt;&amp;lt;/b&amp;gt;) &amp;amp;ndash; неиерархический&amp;lt;ref&amp;gt;&amp;quot;https://ru.wikipedia.org/wiki/Иерархическая_кластеризация&amp;quot;&amp;lt;/ref&amp;gt;, итерационный метод кластеризации&amp;lt;ref&amp;gt;&amp;quot;https://ru.wikipedia.org/wiki/Кластерный_анализ&amp;quot;&amp;lt;/ref&amp;gt;, получивший большую популярность благодаря своей простоте, наглядности реализации и достаточно высокому качеству работы. Был изобретен в 1950-х годах математиком &amp;lt;i&amp;gt;Гуго Штейнгаузом&amp;lt;/i&amp;gt;&amp;lt;ref&amp;gt;Steinhaus, Hugo. &amp;quot;Sur la division des corp materiels en parties.&amp;quot; Bull. Acad. Polon. Sci 1.804 (1956): 801.&amp;lt;/ref&amp;gt; и почти одновременно &amp;lt;i&amp;gt;Стюартом Ллойдом&amp;lt;/i&amp;gt;&amp;lt;ref&amp;gt;Lloyd, S. P. &amp;quot;Least square quantization in PCM. Bell Telephone Laboratories Paper. Published in journal much later: Lloyd, SP: Least squares quantization in PCM.&amp;quot; IEEE Trans. Inform. Theor.(1957/1982).&amp;lt;/ref&amp;gt;. Особую популярность приобрел после публикации работы &amp;lt;i&amp;gt;МакКуина&amp;lt;/i&amp;gt;&amp;lt;ref&amp;gt;MacQueen, James. &amp;quot;Some methods for classification and analysis of multivariate observations.&amp;quot; Proceedings of the fifth Berkeley symposium on mathematical statistics and probability. Vol. 1. No. 14. 1967.&amp;lt;/ref&amp;gt; в 1967.&lt;br /&gt;
&lt;br /&gt;
Алгоритм представляет собой версию EM-алгоритма&amp;lt;ref&amp;gt;&amp;quot;https://ru.wikipedia.org/wiki/EM-алгоритм&amp;quot;&amp;lt;/ref&amp;gt;, применяемого также для разделения смеси гауссиан. Основная идея &amp;lt;i&amp;gt;k means&amp;lt;/i&amp;gt; заключается в том, что данные произвольно разбиваются на кластеры, после чего итеративно перевычисляется центр масс для каждого кластера, полученного на предыдущем шаге, затем векторы разбиваются на кластеры вновь в соответствии с тем, какой из новых центров оказался ближе по выбранной метрике.&lt;br /&gt;
&lt;br /&gt;
Цель алгоритма заключается в разделении &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; наблюдений на &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластеров таким образом, чтобы каждое наблюдение принадлежало ровно одному кластеру, расположенному на наименьшем расстоянии от наблюдения.&lt;br /&gt;
&lt;br /&gt;
=== Математическое описание алгоритма ===&lt;br /&gt;
&amp;lt;b&amp;gt;&amp;lt;u&amp;gt;Дано:&amp;lt;/u&amp;gt;&amp;lt;/b&amp;gt;&lt;br /&gt;
* набор из &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; наблюдений &amp;lt;math&amp;gt;X=\{\mathbf{x}_1, \mathbf{x}_2, ..., \mathbf{x}_n\}, \mathbf{x}_i \in \mathbb{R}^d, i=\overline{1, n}&amp;lt;/math&amp;gt;;&lt;br /&gt;
* &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; - требуемое число кластеров, &amp;lt;math&amp;gt;k \in \mathbb{N}, k \leq n&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;&amp;lt;u&amp;gt;Требуется:&amp;lt;/u&amp;gt;&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Разделить множество наблюдений &amp;lt;math&amp;gt;X&amp;lt;/math&amp;gt; на &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластеров &amp;lt;math&amp;gt;S_1, S_2, ..., S_k&amp;lt;/math&amp;gt;:&lt;br /&gt;
*   &amp;lt;math&amp;gt;S_i \cap S_j= \varnothing, \quad i \ne j&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
*   &amp;lt;math&amp;gt;\bigcup_{i=1}^{k} S_i = X&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;&amp;lt;u&amp;gt;Действие алгоритма:&amp;lt;/u&amp;gt;&amp;lt;/b&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;Алгоритм &amp;lt;i&amp;gt;k means&amp;lt;/i&amp;gt; разбивает набор &amp;lt;math&amp;gt;X&amp;lt;/math&amp;gt; на &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; наборов &amp;lt;math&amp;gt;S_1, S_2, ..., S_k,&amp;lt;/math&amp;gt; таким образом, чтобы минимизировать сумму квадратов расстояний от каждой точки кластера до его центра (центр масс кластера). Введем обозначение, &amp;lt;math&amp;gt;S=\{S_1, S_2, ..., S_k\}&amp;lt;/math&amp;gt;. Тогда действие алгоритма &amp;lt;i&amp;gt;k means&amp;lt;/i&amp;gt; равносильно поиску:&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;table style=&amp;quot;width:100%&amp;quot;&amp;gt;&lt;br /&gt;
  &amp;lt;tr&amp;gt;&lt;br /&gt;
    &amp;lt;td align=&amp;quot;center&amp;quot; width=&amp;quot;90%&amp;quot;&amp;gt;&amp;lt;math&amp;gt;\arg\min_{S} \sum\limits_{i=1}^k \sum\limits_{\mathbf{x} \in S_i} \rho(\mathbf{x}, \mathbf{\mu}_i )^2,&amp;lt;/math&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;td align=&amp;quot;right&amp;quot;&amp;gt;&amp;lt;math&amp;gt;(1)&amp;lt;/math&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;/table&amp;gt;&lt;br /&gt;
где &amp;lt;math&amp;gt;\mathbf{\mu}_i&amp;lt;/math&amp;gt; &amp;amp;ndash; центры кластеров, &amp;lt;math&amp;gt;i=\overline{1,k}, \quad \rho(\mathbf{x}, \mathbf{\mu}_i)&amp;lt;/math&amp;gt; &amp;amp;ndash; функция расстояния между &amp;lt;math&amp;gt;\mathbf{x}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\mu_i&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;&amp;lt;u&amp;gt;Шаги алгоритма: &amp;lt;/u&amp;gt;&amp;lt;/b&amp;gt;&lt;br /&gt;
&amp;lt;ol&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&lt;br /&gt;
    &amp;lt;b&amp;gt;Начальный шаг: инициализация кластеров&amp;lt;/b&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;Выбирается произвольное множество точек &amp;lt;math&amp;gt;\mu_i, i=\overline{1,k}&amp;lt;/math&amp;gt;, рассматриваемых как начальные центры кластеров: &amp;lt;math&amp;gt;\mu_i^{(0)} = \mu_i, \quad i=\overline{1, k}&amp;lt;/math&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
  &amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&lt;br /&gt;
    &amp;lt;b&amp;gt;Распределение векторов по кластерам&amp;lt;/b&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Шаг&amp;lt;/b&amp;gt; &amp;lt;math&amp;gt;t: \forall \mathbf{x}_i \in X, i=\overline{1,n}: \mathbf{x}_i \in S_j \iff  j=\arg\min_{k}\rho(\mathbf{x}_i,\mathbf{\mu}_k^{(t-1)})^2&amp;lt;/math&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
  &amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&lt;br /&gt;
    &amp;lt;b&amp;gt;Пересчет центров кластеров&amp;lt;/b&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Шаг &amp;lt;/b&amp;gt; &amp;lt;math&amp;gt;t: \forall i=\overline{1,k}:  \mu_i^{(t)} = \cfrac{1}{|S_i|}\sum_{\mathbf{x}\in S_i}\mathbf{x}&amp;lt;/math&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
  &amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&lt;br /&gt;
    &amp;lt;b&amp;gt;Проверка условия останова:&amp;lt;/b&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
    &#039;&#039;&#039;if&#039;&#039;&#039; &amp;lt;math&amp;gt;\exist i\in \overline{1,k}: \mu_i^{(t)} \ne \mu_i^{(t-1)}&amp;lt;/math&amp;gt; &#039;&#039;&#039;then&#039;&#039;&#039;&lt;br /&gt;
        t = t + 1;&lt;br /&gt;
        goto 2;&lt;br /&gt;
    &#039;&#039;&#039;else&#039;&#039;&#039;&lt;br /&gt;
        &#039;&#039;&#039;stop&#039;&#039;&#039;&lt;br /&gt;
  &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ol&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Вычислительное ядро алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Вычислительным ядром являются шаги 2 и 3 приведенного выше алгоритма: &amp;lt;b&amp;gt;&amp;lt;i&amp;gt;распределение векторов по кластерам&amp;lt;/i&amp;gt;&amp;lt;/b&amp;gt; и &amp;lt;b&amp;gt;&amp;lt;i&amp;gt;пересчет центров кластеров&amp;lt;/i&amp;gt;&amp;lt;/b&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;&amp;lt;i&amp;gt;Распределение векторов&amp;lt;/i&amp;gt;&amp;lt;/b&amp;gt; по кластерам предполагает вычисление расстояний между каждым вектором &amp;lt;math&amp;gt;\mathbf{x}_i \in X, i= \overline{1,n}&amp;lt;/math&amp;gt; и центрами кластера &amp;lt;math&amp;gt;\mathbf{\mu}_j, j= \overline{1,k}&amp;lt;/math&amp;gt;. Таким образом, данный шаг предполагает &amp;lt;math&amp;gt;kn&amp;lt;/math&amp;gt; вычислений расстояний между d-мерными векторами. &lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;&amp;lt;i&amp;gt;Пересчет центров кластеров&amp;lt;/i&amp;gt;&amp;lt;/b&amp;gt; предполагает &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; вычислений центров масс &amp;lt;math&amp;gt;\mathbf{\mu}_i&amp;lt;/math&amp;gt; множеств &amp;lt;math&amp;gt;S_i, i=\overline{1,k}&amp;lt;/math&amp;gt; представленных выражением в шаге 3 представленного выше алгоритма.&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Макроструктура алгоритма ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Инициализация центров масс &amp;lt;math&amp;gt;\mu_1, ..., \mu_k&amp;lt;/math&amp;gt;&amp;lt;/b&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
Наиболее распространенными являются следующие стратегии:&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&lt;br /&gt;
    &amp;lt;b&amp;gt;Метод Forgy&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;В качестве начальных значений &amp;lt;math&amp;gt;\mu_1, ..., \mu_k&amp;lt;/math&amp;gt; берутся случайно выбранные векторы.&lt;br /&gt;
  &amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&lt;br /&gt;
    &amp;lt;b&amp;gt;Метод случайно разделения (Random Partitioning)&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;Для каждого вектора &amp;lt;math&amp;gt;\mathbf{x}_i \in X, i=\overline{1, n}&amp;lt;/math&amp;gt; выбирается случайным образом кластер &amp;lt;math&amp;gt;S_1, ..., S_k&amp;lt;/math&amp;gt;, после чего для каждого полученного кластера вычисляются значения &amp;lt;math&amp;gt;\mu_1, ..., \mu_k&amp;lt;/math&amp;gt;.&lt;br /&gt;
  &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Распределение векторов по кластерам&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Для этого шага алгоритма между векторами &amp;lt;math&amp;gt;\mathbf{x}_i \in X, i=\overline{1, n}&amp;lt;/math&amp;gt; и центрами кластеров &amp;lt;math&amp;gt;\mu_1, ..., \mu_k&amp;lt;/math&amp;gt; вычисляются &amp;lt;b&amp;gt;расстояния&amp;lt;/b&amp;gt; по формуле (как правило, используется Евлидово расстояние):&lt;br /&gt;
&amp;lt;table style=&amp;quot;width:100%&amp;quot;&amp;gt;&lt;br /&gt;
  &amp;lt;tr&amp;gt;&lt;br /&gt;
    &amp;lt;td align=&amp;quot;center&amp;quot; width=&amp;quot;90%&amp;quot;&amp;gt;&amp;lt;math&amp;gt; \mathbf{v}_1, \mathbf{v}_2 \in \mathbb{R}^d,  \quad \rho(\mathbf{v}_1, \mathbf{v}_2) = \lVert \mathbf{v}_1- \mathbf{v}_2 \rVert= \sqrt{\sum_{i=1}^{d}(\mathbf{v}_{1,i} - \mathbf{v}_{2,i})^2}&amp;lt;/math&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;td align=&amp;quot;right&amp;quot;&amp;gt;&amp;lt;math&amp;gt;(2)&amp;lt;/math&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;/table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Пересчет центров кластеров&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Для этого шага алгоритма производится пересчет центров кластера по &amp;lt;b&amp;gt;формуле вычисления центра масс&amp;lt;/b&amp;gt;:&lt;br /&gt;
&amp;lt;table style=&amp;quot;width:100%&amp;quot;&amp;gt;&lt;br /&gt;
  &amp;lt;tr&amp;gt;&lt;br /&gt;
    &amp;lt;td align=&amp;quot;center&amp;quot; width=&amp;quot;90%&amp;quot;&amp;gt;&amp;lt;math&amp;gt; \mu = \cfrac{1}{|S|}\sum_{\mathbf{x}\in S}\mathbf{x}&amp;lt;/math&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;td align=&amp;quot;right&amp;quot;&amp;gt;&amp;lt;math&amp;gt;(3)&amp;lt;/math&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;/table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Схема реализации последовательного алгоритма ===&lt;br /&gt;
&lt;br /&gt;
 &#039;&#039;&#039;algorithm&#039;&#039;&#039; k-means &#039;&#039;&#039;is&#039;&#039;&#039;&lt;br /&gt;
     &#039;&#039;&#039;1.&#039;&#039;&#039; Инициализировать центры кластеров &amp;lt;math&amp;gt;\mathbf{\mu}_i^{(1)}, i=\overline{1,k}&amp;lt;/math&amp;gt;&lt;br /&gt;
     &#039;&#039;&#039;2.&#039;&#039;&#039; &amp;lt;math&amp;gt;t \leftarrow 1&amp;lt;/math&amp;gt;&lt;br /&gt;
     &#039;&#039;&#039;3.&#039;&#039;&#039; &#039;&#039;&#039;Распределение по кластерам&#039;&#039;&#039;&amp;lt;br&amp;gt;&lt;br /&gt;
        &amp;lt;math&amp;gt;S_i^{(t)}=\{\mathbf{x}_p: \lVert\mathbf{x}_p-\mathbf{\mu}_i^{(t)}\rVert^2 \leq \lVert\mathbf{x}_p-\mathbf{\mu}_j^{(t)}\rVert^2 \quad \forall j=\overline{1,k}\},&amp;lt;/math&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
        где каждый вектор &amp;lt;math&amp;gt;\mathbf{x}_p&amp;lt;/math&amp;gt; соотносится единственному кластеру &amp;lt;math&amp;gt;S^{(t)}&amp;lt;/math&amp;gt;&lt;br /&gt;
     &#039;&#039;&#039;4.&#039;&#039;&#039; &#039;&#039;&#039;Обновление центров кластеров&#039;&#039;&#039;&amp;lt;br&amp;gt;&lt;br /&gt;
        &amp;lt;math&amp;gt;\mathbf{\mu}_i^{(t+1)} = \frac{1}{|S^{(t)}_i|} \sum_{\mathbf{x}_j \in S^{(t)}_i} \mathbf{x}_j &amp;lt;/math&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
     &#039;&#039;&#039;5.&#039;&#039;&#039; &#039;&#039;&#039;if&#039;&#039;&#039; &amp;lt;math&amp;gt;\exist i \in \overline{1,k}: \mathbf{\mu}_i^{(t+1)} \ne \mathbf{\mu}_i^{(t)}&amp;lt;/math&amp;gt; &#039;&#039;&#039;then&#039;&#039;&#039;&lt;br /&gt;
            t = t + 1;&lt;br /&gt;
            goto &#039;&#039;&#039;3&#039;&#039;&#039;;&lt;br /&gt;
        &#039;&#039;&#039;else&#039;&#039;&#039;&lt;br /&gt;
            &#039;&#039;&#039;stop&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
=== Последовательная сложность алгоритма===&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding-bottom: 20px&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;Обозначим &amp;lt;math&amp;gt;\Theta_{centroid}^{d, m}&amp;lt;/math&amp;gt; временную сложность вычисления центорида кластера, число элементов которого равна &amp;lt;math&amp;gt;m&amp;lt;/math&amp;gt;,  в d-мерном пространстве.&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;Аналогично  &amp;lt;math&amp;gt;\Theta_{distance}^d&amp;lt;/math&amp;gt; &amp;amp;ndash; временная сложность вычисления расстояния между двумя d-мерными векторами.&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding-bottom: 20px&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;Сложность шага инициализации &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластеров мощности &amp;lt;math&amp;gt;m&amp;lt;/math&amp;gt; в d-мерном пространстве &amp;amp;ndash; &amp;lt;math&amp;gt;\Theta_{init}^{k, d, m}&amp;lt;/math&amp;gt;&amp;lt;/b&amp;gt;&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;i&amp;gt;Стратерия Forgy&amp;lt;/i&amp;gt;: вычисления не требуются, &amp;lt;math&amp;gt;\Theta_{init}^{k, d, m} = 0&amp;lt;/math&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;i&amp;gt;Стратегия случайного разбиения&amp;lt;/i&amp;gt;: вычисление центров &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластеров,  &amp;lt;math&amp;gt;\Theta_{init}^{k, d, m} = k \cdot \Theta_{centroid}^{d, m}, m \le n&amp;lt;/math&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding-bottom: 20px&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Cложность шага распределения d мерных векторов по &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластерам &amp;amp;ndash; &amp;lt;math&amp;gt;\Theta_{distribute}^{k, d}&amp;lt;/math&amp;gt;&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
На этом шаге для каждого вектора &amp;lt;math&amp;gt;\mathbf{x}_i \in X, i=\overline{1, n}&amp;lt;/math&amp;gt; вычисляется k расстояний до центров кластеров &amp;lt;math&amp;gt;\mathbf{\mu}_1, ...\mathbf{\mu}_k&amp;lt;/math&amp;gt;&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p align=&amp;quot;center&amp;quot;&amp;gt;&lt;br /&gt;
  &amp;lt;math&amp;gt;\Theta_{distribute}^{k, d} = n \cdot k \cdot \Theta_{distance}^d&amp;lt;/math&amp;gt;&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding-bottom: 20px&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;Сложность шага пересчета центров &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластеров размера &amp;lt;math&amp;gt;m&amp;lt;/math&amp;gt; в d-мерном пространстве &amp;amp;ndash; &amp;lt;math&amp;gt;\Theta_{recenter}^{k, d, m}&amp;lt;/math&amp;gt;&amp;lt;/b&amp;gt;&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;На этом шаге вычисляется &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; центров кластеров &amp;lt;math&amp;gt;\mathbf{\mu}_1, ...\mathbf{\mu}_k&amp;lt;/math&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p align=&amp;quot;center&amp;quot;&amp;gt;&amp;lt;math&amp;gt;\Theta_{recenter}^{k, d, m} = k \cdot \Theta_{centroid}^{d, m}&amp;lt;/math&amp;gt; &amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding-bottom: 20px&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Рассчитаем &amp;lt;math&amp;gt;\Theta_{centroid}^{d, m}&amp;lt;/math&amp;gt; для кластера, число элементов которого равно &amp;lt;math&amp;gt;m&amp;lt;/math&amp;gt;&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p align=&amp;quot;center&amp;quot;&amp;gt;&amp;lt;math&amp;gt;\Theta_{centroid}^{d, m}&amp;lt;/math&amp;gt; = &amp;lt;math&amp;gt;m \cdot d&amp;lt;/math&amp;gt; сложений + &amp;lt;math&amp;gt;d&amp;lt;/math&amp;gt; делений &amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding-bottom: 20px&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Рассчитаем &amp;lt;math&amp;gt;\Theta_{distance}^d&amp;lt;/math&amp;gt; в соответствие с формулой &amp;lt;math&amp;gt;(2)&amp;lt;/math&amp;gt;&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p align=&amp;quot;center&amp;quot;&amp;gt;&amp;lt;math&amp;gt;\Theta_{distance}^d&amp;lt;/math&amp;gt; = &amp;lt;math&amp;gt;d&amp;lt;/math&amp;gt; вычитаний + &amp;lt;math&amp;gt;d&amp;lt;/math&amp;gt; умножений + &amp;lt;math&amp;gt;(d-1)&amp;lt;/math&amp;gt; сложение&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding-bottom: 20px&amp;quot;&amp;gt;&lt;br /&gt;
  &amp;lt;p&amp;gt;Предположим, что алгоритм сошелся за &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt; итераций, тогда временная сложность алгоритма &amp;lt;math&amp;gt;\Theta_{k-means}^{d, n}&amp;lt;/math&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
  &amp;lt;p align=&amp;quot;center&amp;quot;&amp;gt;&amp;lt;b&amp;gt;&amp;lt;math&amp;gt;\Theta_{k-means}^{d, n} \le \Theta_{init}^{k, d, n} + i(\Theta_{distribute}^{k, d} + \Theta_{recenter}^{k, d, n})&amp;lt;/math&amp;gt;&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding-bottom: 5px&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;Операции сложения/вычитания:&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p align=&amp;quot;center&amp;quot;&amp;gt;&amp;lt;b&amp;gt;&amp;lt;math&amp;gt;\Theta_{k-means}^{d, n} \le knd+ i(kn(2d-1) + knd) = knd+ i(kn(3d-1)) \thicksim O(ikdn)&amp;lt;/math&amp;gt;&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding-bottom: 20px&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;Операции умножения/деления:&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p align=&amp;quot;center&amp;quot;&amp;gt;&amp;lt;b&amp;gt;&amp;lt;math&amp;gt;\Theta_{k-means}^{d, n} \le kd + i(knd + kd) = kd + ikd(n+1) \thicksim O(ikdn) &amp;lt;/math&amp;gt;&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding-bottom: 20px&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;Получаем, что &amp;lt;b&amp;gt;временная сложность&amp;lt;/b&amp;gt; алгоритма &amp;lt;b&amp;gt;k means&amp;lt;/b&amp;gt; кластеризации &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; &amp;lt;b&amp;gt;d-мерных&amp;lt;/b&amp;gt; векторов на &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластеров за &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt; итераций:&amp;lt;/p&amp;gt;&lt;br /&gt;
 &amp;lt;p align=&amp;quot;center&amp;quot;&amp;gt;&amp;lt;b&amp;gt;&amp;lt;math&amp;gt; \Theta_{k-means}^{d, n} \thicksim O(ikdn) &amp;lt;/math&amp;gt;&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Информационный граф ===&lt;br /&gt;
&lt;br /&gt;
Рассмотрим информационный граф алгоритма. Алгоритм &amp;lt;i&amp;gt;k means&amp;lt;/i&amp;gt; начинается с этапа инициализации, после которого следуют итерации, на каждой из которых выполняется два последовательных шага (см. [[#Схема реализации последовательного алгоритма|&amp;quot;Схема реализации последовательного алгоритма&amp;quot;]]): &lt;br /&gt;
* распределение векторов по кластерам&lt;br /&gt;
* перерасчет центров кластеров&lt;br /&gt;
&lt;br /&gt;
Поскольку основная часть вычислений приходится на шаги итераций, распишем информационные графы данных шагов.&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Распределение векторов по кластерам&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
Информационный граф шага распределения векторов по кластерам представлен на &#039;&#039;рисунке 1&#039;&#039;. Исходами данного графа является исходные векторы &amp;lt;math&amp;gt;\mathbf{x}_1, ..., \mathbf{x}_n&amp;lt;/math&amp;gt;, а также центры кластеров &amp;lt;math&amp;gt;\mathbf{\mu}_1, ... \mathbf{\mu}_k&amp;lt;/math&amp;gt;, вычисленные ранее (на шаге инициализации, если рассматривается первая итерация алгоритма, или на шаге пересчета центров кластеров предыдущей итерации в противном случае). Каждая пара векторов данных &amp;lt;math&amp;gt;\mathbf{x}_i, i=\overline{1,n}&amp;lt;/math&amp;gt; и центров кластера &amp;lt;math&amp;gt;\mathbf{\mu}_j, j=\overline{1, k}&amp;lt;/math&amp;gt; : (&amp;lt;math&amp;gt;\mathbf{x}_i&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;\mathbf{\mu}_j&amp;lt;/math&amp;gt;) подаются на независимые узлы &amp;lt;i&amp;gt;&amp;quot;d&amp;quot;&amp;lt;/i&amp;gt; вычисления расстояния между векторами (более подробная схема вычисления расстояния представлена далее, &#039;&#039;рисунок 2&#039;&#039;). Далее узлы вычисления расстояния &amp;lt;i&amp;gt;&amp;quot;d&amp;quot;&amp;lt;/i&amp;gt;, соответствующие одному и тому же исходному вектору &amp;lt;math&amp;gt;\mathbf{x}_i&amp;lt;/math&amp;gt; передаются на один узел &amp;lt;i&amp;gt;&amp;quot;m&amp;quot;&amp;lt;/i&amp;gt;, где далее происходит вычисление новой метки кластера для каждого вектора &amp;lt;math&amp;gt;\mathbf{x}_i&amp;lt;/math&amp;gt; (берется кластер с минимальным результатом вычисления расстояния). На выходе графа выдаются метки кластеров , &amp;lt;math&amp;gt;L_1, ..., L_n&amp;lt;/math&amp;gt;, такие что &amp;lt;math&amp;gt;\forall \mathbf{x}_i, i=\overline{1, n}, \mathbf{x}_i \in S_j \Leftrightarrow L_i = j&amp;lt;/math&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
[[file:Clusterization.png|thumb|center|800px|Рис. 1. Схема распределения векторов по кластерам. &#039;&#039;d&#039;&#039; &amp;amp;ndash; вычисление расстояния между векторами; &#039;&#039;m&#039;&#039; &amp;amp;ndash; вычисление минимума.]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Вычисление расстояния между векторами&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
Подробная схема вычисления расстояния между векторами &amp;lt;math&amp;gt;\mathbf{x}_i, \mathbf{\mu}_j&amp;lt;/math&amp;gt; представлена на &#039;&#039;рисунке 2&#039;&#039;. Как показано на графе, узел вычисления расстояния между векторами &amp;lt;i&amp;gt;&amp;quot;d&amp;quot;&amp;lt;/i&amp;gt; состоит из шага взятия разности между векторами (узел &amp;quot;&amp;lt;math&amp;gt;-&amp;lt;/math&amp;gt;&amp;quot;) и взятия нормы получившегося вектора разности (узел &amp;quot;&amp;lt;math&amp;gt;||\cdot||^2&amp;lt;/math&amp;gt;&amp;quot;). Более подробно, вычисление расстояния между векторами &amp;lt;math&amp;gt;\mathbf{x}_i = {x_{i1,}, ...,{x_{in}}}, \mathbf{\mu}_j = {\mu_{j1}, ...,\mu_{jn}}&amp;lt;/math&amp;gt; может быть представлено как вычисление разности между каждой парой компонент &amp;lt;math&amp;gt;(x_{iz}, \mu_{jz}), z=\overline{1, d}&amp;lt;/math&amp;gt; (узел &amp;quot;&amp;lt;math&amp;gt;-&amp;lt;/math&amp;gt;&amp;quot;), далее возведение в квадрат для каждого узла &amp;quot;&amp;lt;math&amp;gt;-&amp;lt;/math&amp;gt;&amp;quot; (узел &amp;quot;&amp;lt;math&amp;gt;()^2&amp;lt;/math&amp;gt;&amp;quot;) и суммирования выходов всех узлов &amp;quot;&amp;lt;math&amp;gt;()^2&amp;lt;/math&amp;gt;&amp;quot; (узел &amp;quot;&amp;lt;math&amp;gt;+&amp;lt;/math&amp;gt;&amp;quot;).  &lt;br /&gt;
&lt;br /&gt;
[[file:dist_calc.png|thumb|center|800px|Рис. 2. Схема вычисления расстояния между вектором и центром кластера.]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Пересчет центров кластеров&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
Информационный граф шага пересчета центров кластеров представлен на &#039;&#039;рисунке 3&#039;&#039;. Исходами данного графа является исходные векторы &amp;lt;math&amp;gt;\mathbf{x}_1, ..., \mathbf{x}_n&amp;lt;/math&amp;gt;, а также им соответствующие метки кластера, &amp;lt;math&amp;gt;L_1, ..., L_n&amp;lt;/math&amp;gt;, такие что &amp;lt;math&amp;gt;\forall x_i, i=\overline{1, n}, \mathbf{x}_i \in S_j \Leftrightarrow L_i = j&amp;lt;/math&amp;gt;, вычисленные на этапе распределения векторов по кластерам. Все векторы &amp;lt;math&amp;gt;\mathbf{x}_1, ..., \mathbf{x}_n&amp;lt;/math&amp;gt; подаются в узлы &amp;lt;math&amp;gt;+_1, ...+_k&amp;lt;/math&amp;gt;, каждый узел &amp;lt;math&amp;gt;+_m, m = \overline{1,k}&amp;lt;/math&amp;gt; соответствует операции сложения векторов кластера с номером &amp;lt;math&amp;gt;m&amp;lt;/math&amp;gt;. Метки кластера &amp;lt;math&amp;gt;L_1, ..., L_n&amp;lt;/math&amp;gt; также совместно передаются на узлы &amp;lt;math&amp;gt;S_m, m = \overline{1,k}&amp;lt;/math&amp;gt;, на каждом из которых вычисляется количество векторов в соответствующем кластере (количество меток с соответствующим значением). Далее каждая пара выходов узлов &amp;lt;math&amp;gt;+_m&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;S_m&amp;lt;/math&amp;gt; подается на узел &amp;quot;&amp;lt;math&amp;gt;/&amp;lt;/math&amp;gt;&amp;quot;, где производится деление суммы векторов кластера на количество элементов в нем. Значения, вычисленные на узлах &amp;quot;&amp;lt;math&amp;gt;/&amp;lt;/math&amp;gt;&amp;quot;, присваиваются новым центрам кластеров (выходные значения графа).&lt;br /&gt;
&lt;br /&gt;
[[file:Recluster.png|thumb|center|800px|Рис. 3. Схема пересчета центров кластеров]]&lt;br /&gt;
&lt;br /&gt;
=== Ресурс параллелизма алгоритма ===&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
Работа алгоритма состоит из &amp;lt;math&amp;gt;\Tau&amp;lt;/math&amp;gt; итераций, в каждой из которых происходит &amp;lt;b&amp;gt;распределение d-мерных векторов по &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластерам&amp;lt;/b&amp;gt;, а также &amp;lt;b&amp;gt;пересчет центров кластеров в d-мерном пространстве&amp;lt;/b&amp;gt;. В шаге &amp;lt;b&amp;gt;распределения d-мерных векторов по &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластерам&amp;lt;/b&amp;gt; расстояния между вектором и центрами кластеров вычисляются независимо (отсутствуют информационные зависимости). &amp;lt;b&amp;gt;Центры масс кластеров&amp;lt;/b&amp;gt; также пересчитываются независимо друг от друга. Таким образом, имеет место [[глоссарий#Массовый параллелизм|&#039;&#039;массовый параллелизм&#039;&#039;]]. Вычислим параллельную сложность &amp;lt;math&amp;gt;\Psi_*&amp;lt;/math&amp;gt; каждого из шагов, а также параллельную сложность всего алгоритма, &amp;lt;math&amp;gt;\Psi_{k-means}&amp;lt;/math&amp;gt;. Будем исходить из предположения, что может быть использовано любое необходимое число потоков.&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Распределение d-мерных векторов по &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластерам&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;  &lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
Поскольку на данном шаге для каждой пары векторов &amp;lt;math&amp;gt;\mathbf{x}_i, i=\overline{1,n}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\mathbf{\mu}_j, j=\overline{1,k}&amp;lt;/math&amp;gt; операции вычисления расстояния не зависят друг от друга, они могут выполняться параллельно. Тогда, разделив все вычисление расстояний на &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; потоков, получим, что в каждом потоке будет выполняться только одна операция вычисления расстояния между векторами размерности d. При этом каждому вычислительному потоку передаются координаты центров всех кластеров &amp;lt;math&amp;gt;\mathbf{\mu}_1, ..., \mathbf{\mu}_k&amp;lt;/math&amp;gt;. Таким образом, параллельная сложность данного шага определяется &amp;lt;i&amp;gt; сложностью параллельной операции вычисления расстояния между d-мерными векторами&amp;lt;/i&amp;gt;, &amp;lt;math&amp;gt;\Psi_{distance}^d&amp;lt;/math&amp;gt;  и &amp;lt;i&amp;gt;сложностью определения наиболее близкого кластера&amp;lt;/i&amp;gt; (паралельное взятие минимума по расстояниям), &amp;lt;math&amp;gt;\Psi_{min}^k&amp;lt;/math&amp;gt;. Для оценки &amp;lt;math&amp;gt;\Psi_{distance}^d&amp;lt;/math&amp;gt; воспользуемся  [[Нахождение_частных_сумм_элементов_массива_сдваиванием | параллельной реализацией нахождения частичной суммы элементов массива путем сдваивания]]. Аналогично, &amp;lt;math&amp;gt;\Psi_{min}^k = log(k)&amp;lt;/math&amp;gt;. В результате, &amp;lt;math&amp;gt;\Psi_{distance}^d = O(log(d))&amp;lt;/math&amp;gt;.   Таким образом: &lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p align=&amp;quot;center&amp;quot;&amp;gt;&amp;lt;math&amp;gt;\Psi_{distribute}^{k, d}  = \Psi_{distance}^d + \Psi_{min}^k = O(log(d))+O(log(k)) = O(log(k*d))&amp;lt;/math&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Пересчет центров кластеров в d-мерном пространстве&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
Поскольку на данном шаге для каждого из &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластеров центр масс может быть вычислен независимо, данные операции могут быть выполнены в отдельных потоках. Таким образом, параллельная сложность данного шага, &amp;lt;math&amp;gt;\Psi_{recenter}^{k, d}&amp;lt;/math&amp;gt;,  будет определяться &amp;lt;i&amp;gt;параллельной сложностью вычисления одного центра масс кластера размера &amp;lt;math&amp;gt;m&amp;lt;/math&amp;gt;&amp;lt;/i&amp;gt;, &amp;lt;math&amp;gt;\Psi_{recenter}^{k, d}&amp;lt;/math&amp;gt;,  а так как &amp;lt;math&amp;gt;m \le n \Rightarrow \Psi_{recenter}^{d, m} \le \Psi_{recenter}^{d, n}&amp;lt;/math&amp;gt;. Сложность вычисления центра масс кластера d-мерных векторов размера n аналогично предыдущим вычислениям равна &amp;lt;math&amp;gt;O(log(n))&amp;lt;/math&amp;gt;. Тогда:  &lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p align=&amp;quot;center&amp;quot;&amp;gt;&amp;lt;math&amp;gt;\Psi_{recenter}^{k, d}  \le \Psi_{recenter}^{d, n} = O(log(n))&amp;lt;/math&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Общая параллельная сложность алгоритма&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
На каждой итерации необходимо обновление центров кластеров, которые будут использованы на следующей итерации. Таким образом, итерационный процесс выполняется последовательно&amp;lt;ref&amp;gt;Zhao, Weizhong, Huifang Ma, and Qing He. &amp;quot;Parallel k-means clustering based on mapreduce.&amp;quot; IEEE International Conference on Cloud Computing. Springer Berlin Heidelberg, 2009.&amp;lt;/ref&amp;gt;. Тогда, поскольку сложность каждой итерации  определяется &amp;lt;math&amp;gt;\Psi_{distribute}^{k, d}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\Psi_{recenter}&amp;lt;/math&amp;gt;, сложность всего алгоритма, &amp;lt;math&amp;gt;\Psi_{k-means}&amp;lt;/math&amp;gt; в предположении, что было сделано &amp;lt;math&amp;gt;\Tau&amp;lt;/math&amp;gt; операций определяется выражением&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p align=&amp;quot;center&amp;quot;&amp;gt;&amp;lt;math&amp;gt;\Psi_{k-means} \approx \Tau * (\Psi_{distribute}^{k, d} + \Psi_{recenter}^{k, d}) \le \Tau * O(log(k*d*n))&amp;lt;/math&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Входные и выходные данные алгоритма ===&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;Входные данные&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;Матрица из &amp;lt;math&amp;gt;n*d&amp;lt;/math&amp;gt; элементов &amp;lt;math&amp;gt;x_{i, j} \in \mathbb{R}, i=\overline{1, n}, j=\overline{1, d}&amp;lt;/math&amp;gt;&amp;amp;ndash; координат векторов (наблюдений).&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;Целое положительное число &amp;lt;math&amp;gt;k, k \le n&amp;lt;/math&amp;gt; &amp;amp;ndash; количество кластеров.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;Объем входных данных&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;math&amp;gt;1&amp;lt;/math&amp;gt; целое число + &amp;lt;math&amp;gt;n*d&amp;lt;/math&amp;gt; вещественных чисел (при условии, что координаты &amp;amp;ndash; вещественные числа).&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;Выходные данные&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; целых положительных чисел &amp;lt;math&amp;gt;L_1, ..., L_n&amp;lt;/math&amp;gt;&amp;amp;ndash; номера кластеров, соотвествующие каждому вектору (при условии, что нумерация кластеров начинается с &amp;lt;math&amp;gt;1&amp;lt;/math&amp;gt;).&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;Объем выходных данных&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; целых положительных чисел.&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Свойства алгоритма ===&lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;[[глоссарий#Вычислительная мощность|&#039;&#039;Вычислительная мощность&#039;&#039;]]&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
Вычислительная мощность алгоритма &amp;lt;i&amp;gt;k means&amp;lt;/i&amp;gt; равна &amp;lt;math&amp;gt;\frac{k*d*n*\Tau}{n*d} = k*\Tau &amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; &amp;amp;ndash; число кластеров, &amp;lt;math&amp;gt;\Tau&amp;lt;/math&amp;gt; &amp;amp;ndash; число итераций алгоритма.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;[[глоссарий#Детерминированность |&#039;&#039;Детерминированность&#039;&#039;]] и [[глоссарий#Устойчивость |&#039;&#039;Устойчивость&#039;&#039;]] &amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
Алгоритм &amp;lt;i&amp;gt;k means&amp;lt;/i&amp;gt; является итерационным. Количество итераций алгоритма в общем случае не фиксируется и зависит от начального расположения объектов в пространстве, параметра &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt;, а также от начального приближения центров кластеров, &amp;lt;math&amp;gt;\mu_1, ..., \mu_k&amp;lt;/math&amp;gt;. В результате этого может варьироваться результат работы алгоритма. При неудачном выборе начальных параметров итерационный процесс может сойтись к локальному оптимуму&amp;lt;ref&amp;gt;Von Luxburg, Ulrike. Clustering Stability. Now Publishers Inc, 2010.&amp;lt;/ref&amp;gt;. По этим причинам алгоритм не является ни &amp;lt;b&amp;gt;детермирированным&amp;lt;/b&amp;gt;, ни &amp;lt;b&amp;gt;устойчивым&amp;lt;/b&amp;gt;.&lt;br /&gt;
 &lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Соотношение последовательной и параллельной сложности алгоритма&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\frac{\Theta_{k-means}}{\Psi_{k-means}} = \frac{O(\Tau*k*d*n)}{O(\Tau*log(k*d*n))}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Сильные стороны алгоритма&amp;lt;/b&amp;gt;:&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;i&amp;gt;Сравнительно высокая эффективность при простоте реализации&amp;lt;/i&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;i&amp;gt;Высокое качество кластеризации&amp;lt;/i&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;i&amp;gt;Возможность распараллеливания&amp;lt;/i&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;i&amp;gt;Существование множества модификаций&amp;lt;/i&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;Недостатки алгоритма&amp;lt;/b&amp;gt;&amp;lt;ref&amp;gt;Ortega, Joaquín Pérez, Ma Del Rocío Boone Rojas, and María J. Somodevilla. &amp;quot;Research issues on K-means Algorithm: An Experimental Trial Using Matlab.&amp;quot;&amp;lt;/ref&amp;gt;:&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;i&amp;gt;Количество кластеров является параметром алгоритма&amp;lt;/i&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;&amp;lt;i&amp;gt;Чувствительность к начальным условиям&amp;lt;/i&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;Инициализация центров кластеров в значительной степени влияет на результат кластеризации.&amp;lt;/p&amp;gt;&lt;br /&gt;
  &amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;&amp;lt;i&amp;gt;Чувствительность к выбросам и шумам&amp;lt;/i&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;Выбросы, далекие от центров настоящих кластеров, все равно учитываются при вычислении их центров.&amp;lt;/p&amp;gt;&lt;br /&gt;
  &amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;&amp;lt;i&amp;gt;Возможность сходимости к локальному оптимуму&amp;lt;/i&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;Итеративный подход не дает гарантии сходимости к оптимальному решению.&amp;lt;/p&amp;gt;&lt;br /&gt;
  &amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;&amp;lt;i&amp;gt;Использование понятия &amp;quot;среднего&amp;quot;&amp;lt;/i&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;Алгоритм неприменим к данным, для которых не определено понятие &amp;quot;среднего&amp;quot;, например, категориальным данным.&amp;lt;/p&amp;gt;&lt;br /&gt;
  &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&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;
Исследование масштабируемости параллельной реализации алгоритма k means проводилось на суперкомпьютере &amp;quot;Ломоносов&amp;quot;&amp;lt;ref name=&amp;quot;Lom&amp;quot;&amp;gt;Воеводин Вл., Жуматий С., Соболев С., Антонов А., Брызгалов П., Никитенко Д., Стефанов К., Воеводин Вад. Практика суперкомпьютера «Ломоносов» // Открытые системы, 2012, N 7, С. 36-39.&amp;lt;/ref&amp;gt; [http://parallel.ru/cluster Суперкомпьютерного комплекса Московского университета]. Алгоритм реализован на языке C с использованием средств MPI.&lt;br /&gt;
Для исследования масштабируемости проводилось множество запусков программы с разным значением параметра (количество векторов для кластеризации), а также с различным числом процессоров. Фиксировались результаты запусков &amp;amp;ndash; время работы &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt; и количество произведенных итераций алгоритма &amp;lt;math&amp;gt;\Tau&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Параметры запусков для экспериментальной оценки:&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;Значения &amp;lt;b&amp;gt;количества векторов&amp;lt;/b&amp;gt; &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;: 20&#039;000, 30&#039;000, 50&#039;000, 100&#039;000, 200&#039;000, 300&#039;000, 500&#039;000, 700&#039;000, 1&#039;000&#039;000, 1&#039;500&#039;000, 2&#039;000&#039;000.&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;Значения &amp;lt;b&amp;gt;количества процессоров&amp;lt;/b&amp;gt; &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt;: 1, 8, 16, 32, 64, 128, 160, 192, 224, 256, 288, 320, 352, 384, 416, 448, 480, 512.&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;Значение &amp;lt;b&amp;gt;количества кластеров&amp;lt;/b&amp;gt; &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt;: 100.&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;Значение &amp;lt;b&amp;gt;размерности векторов&amp;lt;/b&amp;gt; &amp;lt;math&amp;gt;d&amp;lt;/math&amp;gt;: 10.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Для проведения экспериментов были сгенерированы нормально распределенные псевдослучайные данные (с использованием Python библиотеки [http://scikit-learn.org/ scikit-learn]):&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
from sklearn.datasets import make_classification&lt;br /&gt;
X1, Y1 = make_classification(n_features=10, n_redundant=2, n_informative=8,&lt;br /&gt;
                             n_clusters_per_class=1, n_classes=100,&lt;br /&gt;
                             n_samples=2000000)&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Для заданной конфигурации эксперимента (&amp;lt;math&amp;gt;n, d, p, k&amp;lt;/math&amp;gt;) и полученных результатов (&amp;lt;math&amp;gt;t, \Tau&amp;lt;/math&amp;gt;)  [[Глоссарий#Производительность|производительность]]  и эффективность реализации расчитывались по формулам:&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
&amp;lt;ul&amp;gt;&amp;lt;li&amp;gt;&amp;lt;math&amp;gt;Performance = \frac{N_{k-means}^{d, n}}{t}\ \ (FLOPS),&amp;lt;/math&amp;gt;&amp;lt;/li&amp;gt;&amp;lt;/ul&amp;gt;&lt;br /&gt;
где &amp;lt;math&amp;gt;N_{k-means}^{d, n}&amp;lt;/math&amp;gt; &amp;amp;ndash; точное число операций с плавающей точкой (операции с памятью, а также целочисленные операции не учитывались), вычисленное в соответствие с разделом [[#Последовательная сложность алгоритма| &amp;quot;Последовательная сложность алгоритма&amp;quot;]];&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
&amp;lt;ul&amp;gt;&amp;lt;li&amp;gt;&amp;lt;math&amp;gt;Efficiency = \frac{100 * Performance}{Performance_{Peak}^{p}}\ \ (%),&amp;lt;/math&amp;gt;&amp;lt;/li&amp;gt;&amp;lt;/ul&amp;gt;&lt;br /&gt;
где &amp;lt;math&amp;gt;Performance_{Peak}^{p}&amp;lt;/math&amp;gt; &amp;amp;ndash; пиковая производительность суперкомпьютера при &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt; процессорах, вычисленная согласно спецификациям Intel&amp;lt;sup&amp;gt;&amp;amp;reg;&amp;lt;/sup&amp;gt; XEON&amp;lt;sup&amp;gt;&amp;amp;reg;&amp;lt;/sup&amp;gt; X5670&amp;lt;ref&amp;gt;&amp;quot;http://ark.intel.com/ru/products/47920/Intel-Xeon-Processor-X5670-12M-Cache-2_93-GHz-6_40-GTs-Intel-QPI&amp;quot;&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Графики зависимости производительности и эффективности параллельной реализации k means от числа векторов для кластеризации (&amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;) и числа процессоров (&amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt;) представлены на рисунках 4 и 5 соответственно.&lt;br /&gt;
&lt;br /&gt;
[[file:Flops.png|thumb|center|800px|Рис. 4. Параллельная реализация k means. График зависимости производительности реализации алгоритма от числа векторов для кластеризации (&amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;) и числа процессоров (&amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt;).]]&lt;br /&gt;
[[file:Efficiency.png|thumb|center|800px|Рис. 5. Параллельная реализация k means. График зависимости эффективности реализации алгоритма от числа векторов для кластеризации (&amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;) и числа процессоров (&amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt;).]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;В результате&amp;lt;/b&amp;gt; экспериментальной оценки были получены следующие оценки эффективности реализации:&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;b&amp;gt;Минимальное&amp;lt;/b&amp;gt; значение: 0.000409 % достигается при &amp;lt;math&amp;gt;n=20&#039;000, p=480&amp;lt;/math&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;b&amp;gt;Максимальное&amp;lt;/b&amp;gt; значение: 0.741119 % достигается при &amp;lt;math&amp;gt;n=300&#039;000, p=1&amp;lt;/math&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
Оценки масштабируемости реализации алгоритма k means:&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;b&amp;gt;По числу процессоров:&amp;lt;/b&amp;gt; -0.002683 &amp;amp;ndash; эффективность убывает с ростом числа процессоров. Данный результат вызван ростом накладных расходов для обеспечения параллельного выполнения алгоритма.&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;b&amp;gt;По размеру задачи:&amp;lt;/b&amp;gt; 0.002779 &amp;amp;ndash; эффективность растет с ростом числа векторов. Данный результат вызван тем, что при увеличении размера задачи, количество вычислений растет по сравнению с временем, затрачиваемым на пересылку данных.&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;b&amp;gt;Общая оценка:&amp;lt;/b&amp;gt; -0.000058 &amp;amp;ndash; можно сделать вывод, что в целом эффективность реализации незначительно уменьшается с ростом размера задачи и числа процессоров.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[https://github.com/serban/kmeans Использованная параллельная реализация алгоритма k means]&lt;br /&gt;
&lt;br /&gt;
=== Динамические характеристики и эффективность реализации алгоритма ===&lt;br /&gt;
=== Выводы для классов архитектур ===&lt;br /&gt;
=== Существующие реализации алгоритма ===&lt;br /&gt;
==== Открытое программное обеспечение ====&lt;br /&gt;
&amp;lt;ol&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;[https://www.icpsr.umich.edu/CrimeStat/ CrimeStat]&amp;lt;/li&amp;gt; Программное обеспечение, созданное для операционных систем Windows, предоставляющее инструменты статистического  и пространственного анализа для решения задачи картирования преступности.&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://juliastats.github.io Julia]&amp;lt;/li&amp;gt; Высокоуровневый высокопроизводительный свободный язык программирования с динамической типизацией, созданный для математических вычислений, содержит реализацию k-means.&lt;br /&gt;
  &amp;lt;li&amp;gt;[https://mahout.apache.org Mahout]&amp;lt;/li&amp;gt; Apache Mahout - Java библиотека для работы с алгоритмами машинного обучения с использованием MapReduce. Содержит реализацию k-means.&lt;br /&gt;
  &amp;lt;li&amp;gt;[https://www.gnu.org/software/octave/ Octave]&amp;lt;/li&amp;gt; Написанная на C++  свободная система для математических вычислений, использующая совместимый с MATLAB язык высокого уровня, содержит реализацию k-means.&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://spark.apache.org/docs/latest/mllib-clustering.html Spark]&amp;lt;/li&amp;gt; Распределенная реализация k-means содержится в библиотеке Mlib для работы с алгоритмами машинного обучения, взаимодействующая с Python библиотекой NumPy и библиотека R.&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://torch.ch Torch]&amp;lt;/li&amp;gt;  MATLAB-подобная библиотека для языка программирования Lua с открытым исходным кодом, предоставляет большое количество алгоритмов для глубинного обучения и научных расчётов. Ядро написано на Си, прикладная часть выполняется на LuaJIT, поддерживается распараллеливание вычислений средствами CUDA и OpenMP. Существуют реализации k-means.&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://www.cs.waikato.ac.nz/ml/weka/ Weka]&amp;lt;/li&amp;gt;  Cвободное программное обеспечение для анализа данных, написанное на Java. Содержит k-means и x-means.&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://accord-framework.net/docs/html/T_Accord_MachineLearning_KMeans.htm Accord.NET]&amp;lt;/li&amp;gt; C# реализация алгоритмов k-means, k-means++, k-modes.&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://docs.opencv.org/3.0-beta/doc/py_tutorials/py_ml/py_kmeans/py_kmeans_opencv/py_kmeans_opencv.html OpenCV]&amp;lt;/li&amp;gt; Написанная на С++ библиотека, направленная в основном на решение задач компьютерного зрения. Содержит реализацию k-means.&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://mlpack.org/ MLPACK]&amp;lt;/li&amp;gt; Масштабируемая С++ библиотека для работы с алгоритмами машинного обучения, содержит реализацию k-means.&lt;br /&gt;
  &amp;lt;li&amp;gt;[https://www.scipy.org/ SciPy]&amp;lt;/li&amp;gt; Библиотека Python, содержит множество реализаций k-means.&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://scikit-learn.org/ scikit-learn]&amp;lt;/li&amp;gt; Библиотека Python, содержит множество реализаций k-means.&lt;br /&gt;
  &amp;lt;li&amp;gt;[https://www.r-bloggers.com/k-means-clustering-in-r/ R]&amp;lt;/li&amp;gt; Язык программирования для статистической обработки данных и работы с графикой, а также свободная программная среда вычислений с открытым исходным кодом в рамках проекта GNU, содержит три реализации k-means.&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://elki.dbs.ifi.lmu.de ELKI]&amp;lt;/li&amp;gt; Java фреймворк, содержащий реализацию k-means, а также множество других алгоритмов кластеризации.&lt;br /&gt;
&amp;lt;/ol&amp;gt;&lt;br /&gt;
==== Проприетарное программное обеспечение  ====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ol&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;[https://www.ayasdi.com/blog/bigdata/topological-data-analysis-of-oil-and-gas-petrophysical-data/ Ayasdi]&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://www.stata.com/features/cluster-analysis/ Stata]&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://mathworld.wolfram.com/K-MeansClusteringAlgorithm.html Mathematica]&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://www.mathworks.com/help/stats/kmeans.html?requestedDomain=www.mathworks.com MATLAB]&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;[https://support.sas.com/rnd/app/stat/procedures/fastclus.html SAS]&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://docs.rapidminer.com/studio/operators/modeling/segmentation/k_means.html RapidMiner]&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;[https://blogs.sap.com/2013/03/28/sap-hana-pal-k-means-algorithm-or-how-to-do-customer-segmentation-for-the-telecommunications-industry/ SAP HANA]&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ol&amp;gt;&lt;br /&gt;
== Литература ==&lt;br /&gt;
&amp;lt;references /&amp;gt;&lt;/div&gt;</summary>
		<author><name>DennZo1993</name></author>
	</entry>
	<entry>
		<id>https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:%D0%91%D1%80%D0%BE%D1%82%D0%B8%D0%BA%D0%BE%D0%B2%D1%81%D0%BA%D0%B0%D1%8F_%D0%94%D0%B0%D0%BD%D1%83%D1%82%D0%B0/%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_k-means&amp;diff=20524</id>
		<title>Участник:Бротиковская Данута/Алгоритм k-means</title>
		<link rel="alternate" type="text/html" href="https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:%D0%91%D1%80%D0%BE%D1%82%D0%B8%D0%BA%D0%BE%D0%B2%D1%81%D0%BA%D0%B0%D1%8F_%D0%94%D0%B0%D0%BD%D1%83%D1%82%D0%B0/%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_k-means&amp;diff=20524"/>
		<updated>2016-12-10T10:41:02Z</updated>

		<summary type="html">&lt;p&gt;DennZo1993: /* Последовательная сложность алгоритма */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Assignment|Zhum}}&lt;br /&gt;
&lt;br /&gt;
{{algorithm&lt;br /&gt;
| name              = Алгоритм k средних (k means)&lt;br /&gt;
| serial_complexity = &amp;lt;math&amp;gt;O(\Tau*k*d*n)&amp;lt;/math&amp;gt;&lt;br /&gt;
| input_data        = &amp;lt;math&amp;gt; d*n &amp;lt;/math&amp;gt;&lt;br /&gt;
| output_data       = &amp;lt;math&amp;gt; n &amp;lt;/math&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
Авторы страницы &amp;lt;b&amp;gt;[[Участник:Бротиковская Данута|Данута Бротиковская]]&amp;lt;/b&amp;gt; и &amp;lt;b&amp;gt;[[Участник:DennZo1993|Денис Зобнин]]&amp;lt;/b&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
Оба автора внесли одинаковый вклад в написание статьи (поиск материалов, изучение статей, заполнение контента статьи), четких разграничений по пунктам статьи сделать невозможно. &lt;br /&gt;
&lt;br /&gt;
== Свойства и структура алгоритма ==&lt;br /&gt;
&lt;br /&gt;
=== Общее описание алгоритма ===&lt;br /&gt;
Алгоритм &amp;lt;b&amp;gt;&amp;lt;i&amp;gt;k средних&amp;lt;/i&amp;gt;&amp;lt;/b&amp;gt; (&amp;lt;b&amp;gt;&amp;lt;i&amp;gt;k means&amp;lt;/i&amp;gt;&amp;lt;/b&amp;gt;) &amp;amp;ndash; неиерархический&amp;lt;ref&amp;gt;&amp;quot;https://ru.wikipedia.org/wiki/Иерархическая_кластеризация&amp;quot;&amp;lt;/ref&amp;gt;, итерационный метод кластеризации&amp;lt;ref&amp;gt;&amp;quot;https://ru.wikipedia.org/wiki/Кластерный_анализ&amp;quot;&amp;lt;/ref&amp;gt;, получивший большую популярность благодаря своей простоте, наглядности реализации и достаточно высокому качеству работы. Был изобретен в 1950-х годах математиком &amp;lt;i&amp;gt;Гуго Штейнгаузом&amp;lt;/i&amp;gt;&amp;lt;ref&amp;gt;Steinhaus, Hugo. &amp;quot;Sur la division des corp materiels en parties.&amp;quot; Bull. Acad. Polon. Sci 1.804 (1956): 801.&amp;lt;/ref&amp;gt; и почти одновременно &amp;lt;i&amp;gt;Стюартом Ллойдом&amp;lt;/i&amp;gt;&amp;lt;ref&amp;gt;Lloyd, S. P. &amp;quot;Least square quantization in PCM. Bell Telephone Laboratories Paper. Published in journal much later: Lloyd, SP: Least squares quantization in PCM.&amp;quot; IEEE Trans. Inform. Theor.(1957/1982).&amp;lt;/ref&amp;gt;. Особую популярность приобрел после публикации работы &amp;lt;i&amp;gt;МакКуина&amp;lt;/i&amp;gt;&amp;lt;ref&amp;gt;MacQueen, James. &amp;quot;Some methods for classification and analysis of multivariate observations.&amp;quot; Proceedings of the fifth Berkeley symposium on mathematical statistics and probability. Vol. 1. No. 14. 1967.&amp;lt;/ref&amp;gt; в 1967.&lt;br /&gt;
&lt;br /&gt;
Алгоритм представляет собой версию EM-алгоритма&amp;lt;ref&amp;gt;&amp;quot;https://ru.wikipedia.org/wiki/EM-алгоритм&amp;quot;&amp;lt;/ref&amp;gt;, применяемого также для разделения смеси гауссиан. Основная идея &amp;lt;i&amp;gt;k means&amp;lt;/i&amp;gt; заключается в том, что данные произвольно разбиваются на кластеры, после чего итеративно перевычисляется центр масс для каждого кластера, полученного на предыдущем шаге, затем векторы разбиваются на кластеры вновь в соответствии с тем, какой из новых центров оказался ближе по выбранной метрике.&lt;br /&gt;
&lt;br /&gt;
Цель алгоритма заключается в разделении &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; наблюдений на &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластеров таким образом, чтобы каждое наблюдение принадлежало ровно одному кластеру, расположенному на наименьшем расстоянии от наблюдения.&lt;br /&gt;
&lt;br /&gt;
=== Математическое описание алгоритма ===&lt;br /&gt;
&amp;lt;b&amp;gt;&amp;lt;u&amp;gt;Дано:&amp;lt;/u&amp;gt;&amp;lt;/b&amp;gt;&lt;br /&gt;
* набор из &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; наблюдений &amp;lt;math&amp;gt;X=\{\mathbf{x}_1, \mathbf{x}_2, ..., \mathbf{x}_n\}, \mathbf{x}_i \in \mathbb{R}^d, i=\overline{1, n}&amp;lt;/math&amp;gt;;&lt;br /&gt;
* &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; - требуемое число кластеров, &amp;lt;math&amp;gt;k \in \mathbb{N}, k \leq n&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;&amp;lt;u&amp;gt;Требуется:&amp;lt;/u&amp;gt;&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Разделить множество наблюдений &amp;lt;math&amp;gt;X&amp;lt;/math&amp;gt; на &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластеров &amp;lt;math&amp;gt;S_1, S_2, ..., S_k&amp;lt;/math&amp;gt;:&lt;br /&gt;
*   &amp;lt;math&amp;gt;S_i \cap S_j= \varnothing, \quad i \ne j&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
*   &amp;lt;math&amp;gt;\bigcup_{i=1}^{k} S_i = X&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;&amp;lt;u&amp;gt;Действие алгоритма:&amp;lt;/u&amp;gt;&amp;lt;/b&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;Алгоритм &amp;lt;i&amp;gt;k means&amp;lt;/i&amp;gt; разбивает набор &amp;lt;math&amp;gt;X&amp;lt;/math&amp;gt; на &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; наборов &amp;lt;math&amp;gt;S_1, S_2, ..., S_k,&amp;lt;/math&amp;gt; таким образом, чтобы минимизировать сумму квадратов расстояний от каждой точки кластера до его центра (центр масс кластера). Введем обозначение, &amp;lt;math&amp;gt;S=\{S_1, S_2, ..., S_k\}&amp;lt;/math&amp;gt;. Тогда действие алгоритма &amp;lt;i&amp;gt;k means&amp;lt;/i&amp;gt; равносильно поиску:&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;table style=&amp;quot;width:100%&amp;quot;&amp;gt;&lt;br /&gt;
  &amp;lt;tr&amp;gt;&lt;br /&gt;
    &amp;lt;td align=&amp;quot;center&amp;quot; width=&amp;quot;90%&amp;quot;&amp;gt;&amp;lt;math&amp;gt;\arg\min_{S} \sum\limits_{i=1}^k \sum\limits_{\mathbf{x} \in S_i} \rho(\mathbf{x}, \mathbf{\mu}_i )^2,&amp;lt;/math&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;td align=&amp;quot;right&amp;quot;&amp;gt;&amp;lt;math&amp;gt;(1)&amp;lt;/math&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;/table&amp;gt;&lt;br /&gt;
где &amp;lt;math&amp;gt;\mathbf{\mu}_i&amp;lt;/math&amp;gt; &amp;amp;ndash; центры кластеров, &amp;lt;math&amp;gt;i=\overline{1,k}, \quad \rho(\mathbf{x}, \mathbf{\mu}_i)&amp;lt;/math&amp;gt; &amp;amp;ndash; функция расстояния между &amp;lt;math&amp;gt;\mathbf{x}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\mu_i&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;&amp;lt;u&amp;gt;Шаги алгоритма: &amp;lt;/u&amp;gt;&amp;lt;/b&amp;gt;&lt;br /&gt;
&amp;lt;ol&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&lt;br /&gt;
    &amp;lt;b&amp;gt;Начальный шаг: инициализация кластеров&amp;lt;/b&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;Выбирается произвольное множество точек &amp;lt;math&amp;gt;\mu_i, i=\overline{1,k}&amp;lt;/math&amp;gt;, рассматриваемых как начальные центры кластеров: &amp;lt;math&amp;gt;\mu_i^{(0)} = \mu_i, \quad i=\overline{1, k}&amp;lt;/math&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
  &amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&lt;br /&gt;
    &amp;lt;b&amp;gt;Распределение векторов по кластерам&amp;lt;/b&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Шаг&amp;lt;/b&amp;gt; &amp;lt;math&amp;gt;t: \forall \mathbf{x}_i \in X, i=\overline{1,n}: \mathbf{x}_i \in S_j \iff  j=\arg\min_{k}\rho(\mathbf{x}_i,\mathbf{\mu}_k^{(t-1)})^2&amp;lt;/math&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
  &amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&lt;br /&gt;
    &amp;lt;b&amp;gt;Пересчет центров кластеров&amp;lt;/b&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Шаг &amp;lt;/b&amp;gt; &amp;lt;math&amp;gt;t: \forall i=\overline{1,k}:  \mu_i^{(t)} = \cfrac{1}{|S_i|}\sum_{\mathbf{x}\in S_i}\mathbf{x}&amp;lt;/math&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
  &amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&lt;br /&gt;
    &amp;lt;b&amp;gt;Проверка условия останова:&amp;lt;/b&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
    &#039;&#039;&#039;if&#039;&#039;&#039; &amp;lt;math&amp;gt;\exist i\in \overline{1,k}: \mu_i^{(t)} \ne \mu_i^{(t-1)}&amp;lt;/math&amp;gt; &#039;&#039;&#039;then&#039;&#039;&#039;&lt;br /&gt;
        t = t + 1;&lt;br /&gt;
        goto 2;&lt;br /&gt;
    &#039;&#039;&#039;else&#039;&#039;&#039;&lt;br /&gt;
        &#039;&#039;&#039;stop&#039;&#039;&#039;&lt;br /&gt;
  &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ol&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Вычислительное ядро алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Вычислительным ядром являются шаги 2 и 3 приведенного выше алгоритма: &amp;lt;b&amp;gt;&amp;lt;i&amp;gt;распределение векторов по кластерам&amp;lt;/i&amp;gt;&amp;lt;/b&amp;gt; и &amp;lt;b&amp;gt;&amp;lt;i&amp;gt;пересчет центров кластеров&amp;lt;/i&amp;gt;&amp;lt;/b&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;&amp;lt;i&amp;gt;Распределение векторов&amp;lt;/i&amp;gt;&amp;lt;/b&amp;gt; по кластерам предполагает вычисление расстояний между каждым вектором &amp;lt;math&amp;gt;\mathbf{x}_i \in X, i= \overline{1,n}&amp;lt;/math&amp;gt; и центрами кластера &amp;lt;math&amp;gt;\mathbf{\mu}_j, j= \overline{1,k}&amp;lt;/math&amp;gt;. Таким образом, данный шаг предполагает &amp;lt;math&amp;gt;kn&amp;lt;/math&amp;gt; вычислений расстояний между d-мерными векторами. &lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;&amp;lt;i&amp;gt;Пересчет центров кластеров&amp;lt;/i&amp;gt;&amp;lt;/b&amp;gt; предполагает &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; вычислений центров масс &amp;lt;math&amp;gt;\mathbf{\mu}_i&amp;lt;/math&amp;gt; множеств &amp;lt;math&amp;gt;S_i, i=\overline{1,k}&amp;lt;/math&amp;gt; представленных выражением в шаге 3 представленного выше алгоритма.&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Макроструктура алгоритма ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Инициализация центров масс &amp;lt;math&amp;gt;\mu_1, ..., \mu_k&amp;lt;/math&amp;gt;&amp;lt;/b&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
Наиболее распространенными являются следующие стратегии:&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&lt;br /&gt;
    &amp;lt;b&amp;gt;Метод Forgy&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;В качестве начальных значений &amp;lt;math&amp;gt;\mu_1, ..., \mu_k&amp;lt;/math&amp;gt; берутся случайно выбранные векторы.&lt;br /&gt;
  &amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&lt;br /&gt;
    &amp;lt;b&amp;gt;Метод случайно разделения (Random Partitioning)&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;Для каждого вектора &amp;lt;math&amp;gt;\mathbf{x}_i \in X, i=\overline{1, n}&amp;lt;/math&amp;gt; выбирается случайным образом кластер &amp;lt;math&amp;gt;S_1, ..., S_k&amp;lt;/math&amp;gt;, после чего для каждого полученного кластера вычисляются значения &amp;lt;math&amp;gt;\mu_1, ..., \mu_k&amp;lt;/math&amp;gt;.&lt;br /&gt;
  &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Распределение векторов по кластерам&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Для этого шага алгоритма между векторами &amp;lt;math&amp;gt;\mathbf{x}_i \in X, i=\overline{1, n}&amp;lt;/math&amp;gt; и центрами кластеров &amp;lt;math&amp;gt;\mu_1, ..., \mu_k&amp;lt;/math&amp;gt; вычисляются &amp;lt;b&amp;gt;расстояния&amp;lt;/b&amp;gt; по формуле (как правило, используется Евлидово расстояние):&lt;br /&gt;
&amp;lt;table style=&amp;quot;width:100%&amp;quot;&amp;gt;&lt;br /&gt;
  &amp;lt;tr&amp;gt;&lt;br /&gt;
    &amp;lt;td align=&amp;quot;center&amp;quot; width=&amp;quot;90%&amp;quot;&amp;gt;&amp;lt;math&amp;gt; \mathbf{v}_1, \mathbf{v}_2 \in \mathbb{R}^d,  \quad \rho(\mathbf{v}_1, \mathbf{v}_2) = \lVert \mathbf{v}_1- \mathbf{v}_2 \rVert= \sqrt{\sum_{i=1}^{d}(\mathbf{v}_{1,i} - \mathbf{v}_{2,i})^2}&amp;lt;/math&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;td align=&amp;quot;right&amp;quot;&amp;gt;&amp;lt;math&amp;gt;(2)&amp;lt;/math&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;/table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Пересчет центров кластеров&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Для этого шага алгоритма производится пересчет центров кластера по &amp;lt;b&amp;gt;формуле вычисления центра масс&amp;lt;/b&amp;gt;:&lt;br /&gt;
&amp;lt;table style=&amp;quot;width:100%&amp;quot;&amp;gt;&lt;br /&gt;
  &amp;lt;tr&amp;gt;&lt;br /&gt;
    &amp;lt;td align=&amp;quot;center&amp;quot; width=&amp;quot;90%&amp;quot;&amp;gt;&amp;lt;math&amp;gt; \mu = \cfrac{1}{|S|}\sum_{\mathbf{x}\in S}\mathbf{x}&amp;lt;/math&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;td align=&amp;quot;right&amp;quot;&amp;gt;&amp;lt;math&amp;gt;(3)&amp;lt;/math&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;/table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Схема реализации последовательного алгоритма ===&lt;br /&gt;
&lt;br /&gt;
 &#039;&#039;&#039;algorithm&#039;&#039;&#039; k-means &#039;&#039;&#039;is&#039;&#039;&#039;&lt;br /&gt;
     &#039;&#039;&#039;1.&#039;&#039;&#039; Инициализировать центры кластеров &amp;lt;math&amp;gt;\mathbf{\mu}_i^{(1)}, i=\overline{1,k}&amp;lt;/math&amp;gt;&lt;br /&gt;
     &#039;&#039;&#039;2.&#039;&#039;&#039; &amp;lt;math&amp;gt;t \leftarrow 1&amp;lt;/math&amp;gt;&lt;br /&gt;
     &#039;&#039;&#039;3.&#039;&#039;&#039; &#039;&#039;&#039;Распределение по кластерам&#039;&#039;&#039;&amp;lt;br&amp;gt;&lt;br /&gt;
        &amp;lt;math&amp;gt;S_i^{(t)}=\{\mathbf{x}_p: \lVert\mathbf{x}_p-\mathbf{\mu}_i^{(t)}\rVert^2 \leq \lVert\mathbf{x}_p-\mathbf{\mu}_j^{(t)}\rVert^2 \quad \forall j=\overline{1,k}\},&amp;lt;/math&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
        где каждый вектор &amp;lt;math&amp;gt;\mathbf{x}_p&amp;lt;/math&amp;gt; соотносится единственному кластеру &amp;lt;math&amp;gt;S^{(t)}&amp;lt;/math&amp;gt;&lt;br /&gt;
     &#039;&#039;&#039;4.&#039;&#039;&#039; &#039;&#039;&#039;Обновление центров кластеров&#039;&#039;&#039;&amp;lt;br&amp;gt;&lt;br /&gt;
        &amp;lt;math&amp;gt;\mathbf{\mu}_i^{(t+1)} = \frac{1}{|S^{(t)}_i|} \sum_{\mathbf{x}_j \in S^{(t)}_i} \mathbf{x}_j &amp;lt;/math&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
     &#039;&#039;&#039;5.&#039;&#039;&#039; &#039;&#039;&#039;if&#039;&#039;&#039; &amp;lt;math&amp;gt;\exist i \in \overline{1,k}: \mathbf{\mu}_i^{(t+1)} \ne \mathbf{\mu}_i^{(t)}&amp;lt;/math&amp;gt; &#039;&#039;&#039;then&#039;&#039;&#039;&lt;br /&gt;
            t = t + 1;&lt;br /&gt;
            goto &#039;&#039;&#039;3&#039;&#039;&#039;;&lt;br /&gt;
        &#039;&#039;&#039;else&#039;&#039;&#039;&lt;br /&gt;
            &#039;&#039;&#039;stop&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
=== Последовательная сложность алгоритма===&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding-bottom: 20px&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;Обозначим &amp;lt;math&amp;gt;\Theta_{centroid}^{d, m}&amp;lt;/math&amp;gt; временную сложность вычисления центорида кластера, число элементов которого равна &amp;lt;math&amp;gt;m&amp;lt;/math&amp;gt;,  в d-мерном пространстве.&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;Аналогично  &amp;lt;math&amp;gt;\Theta_{distance}^d&amp;lt;/math&amp;gt; &amp;amp;ndash; временная сложность вычисления расстояния между двумя d-мерными векторами.&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding-bottom: 20px&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;Сложность шага инициализации &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластеров мощности &amp;lt;math&amp;gt;m&amp;lt;/math&amp;gt; в d-мерном пространстве &amp;amp;ndash; &amp;lt;math&amp;gt;\Theta_{init}^{k, d, m}&amp;lt;/math&amp;gt;&amp;lt;/b&amp;gt;&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;i&amp;gt;Стратерия Forgy&amp;lt;/i&amp;gt;: вычисления не требуются, &amp;lt;math&amp;gt;\Theta_{init}^{k, d, m} = 0&amp;lt;/math&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;i&amp;gt;Стратегия случайного разбиения&amp;lt;/i&amp;gt;: вычисление центров &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластеров,  &amp;lt;math&amp;gt;\Theta_{init}^{k, d, m} = k \cdot \Theta_{centroid}^{d, m}, m \le n&amp;lt;/math&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding-bottom: 20px&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Cложность шага распределения d мерных векторов по &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластерам &amp;amp;ndash; &amp;lt;math&amp;gt;\Theta_{distribute}^{k, d}&amp;lt;/math&amp;gt;&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
На этом шаге для каждого вектора &amp;lt;math&amp;gt;\mathbf{x}_i \in X, i=\overline{1, n}&amp;lt;/math&amp;gt; вычисляется k расстояний до центров кластеров &amp;lt;math&amp;gt;\mathbf{\mu}_1, ...\mathbf{\mu}_k&amp;lt;/math&amp;gt;&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p align=&amp;quot;center&amp;quot;&amp;gt;&lt;br /&gt;
  &amp;lt;math&amp;gt;\Theta_{distribute}^{k, d} = n \cdot k \cdot \Theta_{distance}^d&amp;lt;/math&amp;gt;&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding-bottom: 20px&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;Сложность шага пересчета центров &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластеров размера &amp;lt;math&amp;gt;m&amp;lt;/math&amp;gt; в d-мерном пространстве &amp;amp;ndash; &amp;lt;math&amp;gt;\Theta_{recenter}^{k, d, m}&amp;lt;/math&amp;gt;&amp;lt;/b&amp;gt;&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;На этом шаге вычисляется &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; центров кластеров &amp;lt;math&amp;gt;\mathbf{\mu}_1, ...\mathbf{\mu}_k&amp;lt;/math&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p align=&amp;quot;center&amp;quot;&amp;gt;&amp;lt;math&amp;gt;\Theta_{recenter}^{k, d, m} = k \cdot \Theta_{centroid}^{d, m}&amp;lt;/math&amp;gt; &amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding-bottom: 20px&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Рассчитаем &amp;lt;math&amp;gt;\Theta_{centroid}^{d, m}&amp;lt;/math&amp;gt; для кластера, число элементов которого равно &amp;lt;math&amp;gt;m&amp;lt;/math&amp;gt;&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p align=&amp;quot;center&amp;quot;&amp;gt;&amp;lt;math&amp;gt;\Theta_{centroid}^{d, m}&amp;lt;/math&amp;gt; = &amp;lt;math&amp;gt;m \cdot d&amp;lt;/math&amp;gt; сложений + &amp;lt;math&amp;gt;d&amp;lt;/math&amp;gt; делений &amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding-bottom: 20px&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Рассчитаем &amp;lt;math&amp;gt;\Theta_{distance}^d&amp;lt;/math&amp;gt; в соответствие с формулой &amp;lt;math&amp;gt;(2)&amp;lt;/math&amp;gt;&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p align=&amp;quot;center&amp;quot;&amp;gt;&amp;lt;math&amp;gt;\Theta_{distance}^d&amp;lt;/math&amp;gt; = &amp;lt;math&amp;gt;d&amp;lt;/math&amp;gt; вычитаний + &amp;lt;math&amp;gt;d&amp;lt;/math&amp;gt; умножений + &amp;lt;math&amp;gt;(d-1)&amp;lt;/math&amp;gt; сложение&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding-bottom: 20px&amp;quot;&amp;gt;&lt;br /&gt;
  &amp;lt;p&amp;gt;Предположим, что алгоритм сошелся за &amp;lt;math&amp;gt;\Tau&amp;lt;/math&amp;gt; итераций, тогда временная сложность алгоритма &amp;lt;math&amp;gt;\Theta_{k-means}^{d, n}&amp;lt;/math&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
  &amp;lt;p align=&amp;quot;center&amp;quot;&amp;gt;&amp;lt;b&amp;gt;&amp;lt;math&amp;gt;\Theta_{k-means}^{d, n} \le \Theta_{init}^{k, d, n} + \Tau(\Theta_{distribute}^{k, d} + \Theta_{recenter}^{k, d, n})&amp;lt;/math&amp;gt;&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding-bottom: 5px&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;Операции сложения/вычитания:&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p align=&amp;quot;center&amp;quot;&amp;gt;&amp;lt;b&amp;gt;&amp;lt;math&amp;gt;\Theta_{k-means}^{d, n} \le knd+ \Tau(kn(2d-1) + knd) = knd+ \Tau(kn(3d-1)) \thicksim O(\Tau kdn)&amp;lt;/math&amp;gt;&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding-bottom: 20px&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;Операции умножения/деления:&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p align=&amp;quot;center&amp;quot;&amp;gt;&amp;lt;b&amp;gt;&amp;lt;math&amp;gt;\Theta_{k-means}^{d, n} \le kd + \Tau(knd + kd) = kd + \Tau kd(n+1) \thicksim O(\Tau kdn) &amp;lt;/math&amp;gt;&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding-bottom: 20px&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;Получаем, что &amp;lt;b&amp;gt;временная сложность&amp;lt;/b&amp;gt; алгоритма &amp;lt;b&amp;gt;k means&amp;lt;/b&amp;gt; кластеризации &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; &amp;lt;b&amp;gt;d-мерных&amp;lt;/b&amp;gt; векторов на &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластеров за &amp;lt;math&amp;gt;\Tau&amp;lt;/math&amp;gt; итераций:&amp;lt;/p&amp;gt;&lt;br /&gt;
 &amp;lt;p align=&amp;quot;center&amp;quot;&amp;gt;&amp;lt;b&amp;gt;&amp;lt;math&amp;gt; \Theta_{k-means}^{d, n} \thicksim O(\Tau kdn) &amp;lt;/math&amp;gt;&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Информационный граф ===&lt;br /&gt;
&lt;br /&gt;
Рассмотрим информационный граф алгоритма. Алгоритм &amp;lt;i&amp;gt;k means&amp;lt;/i&amp;gt; начинается с этапа инициализации, после которого следуют итерации, на каждой из которых выполняется два последовательных шага (см. [[#Схема реализации последовательного алгоритма|&amp;quot;Схема реализации последовательного алгоритма&amp;quot;]]): &lt;br /&gt;
* распределение векторов по кластерам&lt;br /&gt;
* перерасчет центров кластеров&lt;br /&gt;
&lt;br /&gt;
Поскольку основная часть вычислений приходится на шаги итераций, распишем информационные графы данных шагов.&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Распределение векторов по кластерам&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
Информационный граф шага распределения векторов по кластерам представлен на &#039;&#039;рисунке 1&#039;&#039;. Исходами данного графа является исходные векторы &amp;lt;math&amp;gt;\mathbf{x}_1, ..., \mathbf{x}_n&amp;lt;/math&amp;gt;, а также центры кластеров &amp;lt;math&amp;gt;\mathbf{\mu}_1, ... \mathbf{\mu}_k&amp;lt;/math&amp;gt;, вычисленные ранее (на шаге инициализации, если рассматривается первая итерация алгоритма, или на шаге пересчета центров кластеров предыдущей итерации в противном случае). Каждая пара векторов данных &amp;lt;math&amp;gt;\mathbf{x}_i, i=\overline{1,n}&amp;lt;/math&amp;gt; и центров кластера &amp;lt;math&amp;gt;\mathbf{\mu}_j, j=\overline{1, k}&amp;lt;/math&amp;gt; : (&amp;lt;math&amp;gt;\mathbf{x}_i&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;\mathbf{\mu}_j&amp;lt;/math&amp;gt;) подаются на независимые узлы &amp;lt;i&amp;gt;&amp;quot;d&amp;quot;&amp;lt;/i&amp;gt; вычисления расстояния между векторами (более подробная схема вычисления расстояния представлена далее, &#039;&#039;рисунок 2&#039;&#039;). Далее узлы вычисления расстояния &amp;lt;i&amp;gt;&amp;quot;d&amp;quot;&amp;lt;/i&amp;gt;, соответствующие одному и тому же исходному вектору &amp;lt;math&amp;gt;\mathbf{x}_i&amp;lt;/math&amp;gt; передаются на один узел &amp;lt;i&amp;gt;&amp;quot;m&amp;quot;&amp;lt;/i&amp;gt;, где далее происходит вычисление новой метки кластера для каждого вектора &amp;lt;math&amp;gt;\mathbf{x}_i&amp;lt;/math&amp;gt; (берется кластер с минимальным результатом вычисления расстояния). На выходе графа выдаются метки кластеров , &amp;lt;math&amp;gt;L_1, ..., L_n&amp;lt;/math&amp;gt;, такие что &amp;lt;math&amp;gt;\forall \mathbf{x}_i, i=\overline{1, n}, \mathbf{x}_i \in S_j \Leftrightarrow L_i = j&amp;lt;/math&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
[[file:Clusterization.png|thumb|center|800px|Рис. 1. Схема распределения векторов по кластерам. &#039;&#039;d&#039;&#039; &amp;amp;ndash; вычисление расстояния между векторами; &#039;&#039;m&#039;&#039; &amp;amp;ndash; вычисление минимума.]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Вычисление расстояния между векторами&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
Подробная схема вычисления расстояния между векторами &amp;lt;math&amp;gt;\mathbf{x}_i, \mathbf{\mu}_j&amp;lt;/math&amp;gt; представлена на &#039;&#039;рисунке 2&#039;&#039;. Как показано на графе, узел вычисления расстояния между векторами &amp;lt;i&amp;gt;&amp;quot;d&amp;quot;&amp;lt;/i&amp;gt; состоит из шага взятия разности между векторами (узел &amp;quot;&amp;lt;math&amp;gt;-&amp;lt;/math&amp;gt;&amp;quot;) и взятия нормы получившегося вектора разности (узел &amp;quot;&amp;lt;math&amp;gt;||\cdot||^2&amp;lt;/math&amp;gt;&amp;quot;). Более подробно, вычисление расстояния между векторами &amp;lt;math&amp;gt;\mathbf{x}_i = {x_{i1,}, ...,{x_{in}}}, \mathbf{\mu}_j = {\mu_{j1}, ...,\mu_{jn}}&amp;lt;/math&amp;gt; может быть представлено как вычисление разности между каждой парой компонент &amp;lt;math&amp;gt;(x_{iz}, \mu_{jz}), z=\overline{1, d}&amp;lt;/math&amp;gt; (узел &amp;quot;&amp;lt;math&amp;gt;-&amp;lt;/math&amp;gt;&amp;quot;), далее возведение в квадрат для каждого узла &amp;quot;&amp;lt;math&amp;gt;-&amp;lt;/math&amp;gt;&amp;quot; (узел &amp;quot;&amp;lt;math&amp;gt;()^2&amp;lt;/math&amp;gt;&amp;quot;) и суммирования выходов всех узлов &amp;quot;&amp;lt;math&amp;gt;()^2&amp;lt;/math&amp;gt;&amp;quot; (узел &amp;quot;&amp;lt;math&amp;gt;+&amp;lt;/math&amp;gt;&amp;quot;).  &lt;br /&gt;
&lt;br /&gt;
[[file:dist_calc.png|thumb|center|800px|Рис. 2. Схема вычисления расстояния между вектором и центром кластера.]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Пересчет центров кластеров&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
Информационный граф шага пересчета центров кластеров представлен на &#039;&#039;рисунке 3&#039;&#039;. Исходами данного графа является исходные векторы &amp;lt;math&amp;gt;\mathbf{x}_1, ..., \mathbf{x}_n&amp;lt;/math&amp;gt;, а также им соответствующие метки кластера, &amp;lt;math&amp;gt;L_1, ..., L_n&amp;lt;/math&amp;gt;, такие что &amp;lt;math&amp;gt;\forall x_i, i=\overline{1, n}, \mathbf{x}_i \in S_j \Leftrightarrow L_i = j&amp;lt;/math&amp;gt;, вычисленные на этапе распределения векторов по кластерам. Все векторы &amp;lt;math&amp;gt;\mathbf{x}_1, ..., \mathbf{x}_n&amp;lt;/math&amp;gt; подаются в узлы &amp;lt;math&amp;gt;+_1, ...+_k&amp;lt;/math&amp;gt;, каждый узел &amp;lt;math&amp;gt;+_m, m = \overline{1,k}&amp;lt;/math&amp;gt; соответствует операции сложения векторов кластера с номером &amp;lt;math&amp;gt;m&amp;lt;/math&amp;gt;. Метки кластера &amp;lt;math&amp;gt;L_1, ..., L_n&amp;lt;/math&amp;gt; также совместно передаются на узлы &amp;lt;math&amp;gt;S_m, m = \overline{1,k}&amp;lt;/math&amp;gt;, на каждом из которых вычисляется количество векторов в соответствующем кластере (количество меток с соответствующим значением). Далее каждая пара выходов узлов &amp;lt;math&amp;gt;+_m&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;S_m&amp;lt;/math&amp;gt; подается на узел &amp;quot;&amp;lt;math&amp;gt;/&amp;lt;/math&amp;gt;&amp;quot;, где производится деление суммы векторов кластера на количество элементов в нем. Значения, вычисленные на узлах &amp;quot;&amp;lt;math&amp;gt;/&amp;lt;/math&amp;gt;&amp;quot;, присваиваются новым центрам кластеров (выходные значения графа).&lt;br /&gt;
&lt;br /&gt;
[[file:Recluster.png|thumb|center|800px|Рис. 3. Схема пересчета центров кластеров]]&lt;br /&gt;
&lt;br /&gt;
=== Ресурс параллелизма алгоритма ===&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
Работа алгоритма состоит из &amp;lt;math&amp;gt;\Tau&amp;lt;/math&amp;gt; итераций, в каждой из которых происходит &amp;lt;b&amp;gt;распределение d-мерных векторов по &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластерам&amp;lt;/b&amp;gt;, а также &amp;lt;b&amp;gt;пересчет центров кластеров в d-мерном пространстве&amp;lt;/b&amp;gt;. В шаге &amp;lt;b&amp;gt;распределения d-мерных векторов по &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластерам&amp;lt;/b&amp;gt; расстояния между вектором и центрами кластеров вычисляются независимо (отсутствуют информационные зависимости). &amp;lt;b&amp;gt;Центры масс кластеров&amp;lt;/b&amp;gt; также пересчитываются независимо друг от друга. Таким образом, имеет место [[глоссарий#Массовый параллелизм|&#039;&#039;массовый параллелизм&#039;&#039;]]. Вычислим параллельную сложность &amp;lt;math&amp;gt;\Psi_*&amp;lt;/math&amp;gt; каждого из шагов, а также параллельную сложность всего алгоритма, &amp;lt;math&amp;gt;\Psi_{k-means}&amp;lt;/math&amp;gt;. Будем исходить из предположения, что может быть использовано любое необходимое число потоков.&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Распределение d-мерных векторов по &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластерам&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;  &lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
Поскольку на данном шаге для каждой пары векторов &amp;lt;math&amp;gt;\mathbf{x}_i, i=\overline{1,n}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\mathbf{\mu}_j, j=\overline{1,k}&amp;lt;/math&amp;gt; операции вычисления расстояния не зависят друг от друга, они могут выполняться параллельно. Тогда, разделив все вычисление расстояний на &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; потоков, получим, что в каждом потоке будет выполняться только одна операция вычисления расстояния между векторами размерности d. При этом каждому вычислительному потоку передаются координаты центров всех кластеров &amp;lt;math&amp;gt;\mathbf{\mu}_1, ..., \mathbf{\mu}_k&amp;lt;/math&amp;gt;. Таким образом, параллельная сложность данного шага определяется &amp;lt;i&amp;gt; сложностью параллельной операции вычисления расстояния между d-мерными векторами&amp;lt;/i&amp;gt;, &amp;lt;math&amp;gt;\Psi_{distance}^d&amp;lt;/math&amp;gt;  и &amp;lt;i&amp;gt;сложностью определения наиболее близкого кластера&amp;lt;/i&amp;gt; (паралельное взятие минимума по расстояниям), &amp;lt;math&amp;gt;\Psi_{min}^k&amp;lt;/math&amp;gt;. Для оценки &amp;lt;math&amp;gt;\Psi_{distance}^d&amp;lt;/math&amp;gt; воспользуемся  [[Нахождение_частных_сумм_элементов_массива_сдваиванием | параллельной реализацией нахождения частичной суммы элементов массива путем сдваивания]]. Аналогично, &amp;lt;math&amp;gt;\Psi_{min}^k = log(k)&amp;lt;/math&amp;gt;. В результате, &amp;lt;math&amp;gt;\Psi_{distance}^d = O(log(d))&amp;lt;/math&amp;gt;.   Таким образом: &lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p align=&amp;quot;center&amp;quot;&amp;gt;&amp;lt;math&amp;gt;\Psi_{distribute}^{k, d}  = \Psi_{distance}^d + \Psi_{min}^k = O(log(d))+O(log(k)) = O(log(k*d))&amp;lt;/math&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Пересчет центров кластеров в d-мерном пространстве&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
Поскольку на данном шаге для каждого из &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластеров центр масс может быть вычислен независимо, данные операции могут быть выполнены в отдельных потоках. Таким образом, параллельная сложность данного шага, &amp;lt;math&amp;gt;\Psi_{recenter}^{k, d}&amp;lt;/math&amp;gt;,  будет определяться &amp;lt;i&amp;gt;параллельной сложностью вычисления одного центра масс кластера размера &amp;lt;math&amp;gt;m&amp;lt;/math&amp;gt;&amp;lt;/i&amp;gt;, &amp;lt;math&amp;gt;\Psi_{recenter}^{k, d}&amp;lt;/math&amp;gt;,  а так как &amp;lt;math&amp;gt;m \le n \Rightarrow \Psi_{recenter}^{d, m} \le \Psi_{recenter}^{d, n}&amp;lt;/math&amp;gt;. Сложность вычисления центра масс кластера d-мерных векторов размера n аналогично предыдущим вычислениям равна &amp;lt;math&amp;gt;O(log(n))&amp;lt;/math&amp;gt;. Тогда:  &lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p align=&amp;quot;center&amp;quot;&amp;gt;&amp;lt;math&amp;gt;\Psi_{recenter}^{k, d}  \le \Psi_{recenter}^{d, n} = O(log(n))&amp;lt;/math&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Общая параллельная сложность алгоритма&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
На каждой итерации необходимо обновление центров кластеров, которые будут использованы на следующей итерации. Таким образом, итерационный процесс выполняется последовательно&amp;lt;ref&amp;gt;Zhao, Weizhong, Huifang Ma, and Qing He. &amp;quot;Parallel k-means clustering based on mapreduce.&amp;quot; IEEE International Conference on Cloud Computing. Springer Berlin Heidelberg, 2009.&amp;lt;/ref&amp;gt;. Тогда, поскольку сложность каждой итерации  определяется &amp;lt;math&amp;gt;\Psi_{distribute}^{k, d}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\Psi_{recenter}&amp;lt;/math&amp;gt;, сложность всего алгоритма, &amp;lt;math&amp;gt;\Psi_{k-means}&amp;lt;/math&amp;gt; в предположении, что было сделано &amp;lt;math&amp;gt;\Tau&amp;lt;/math&amp;gt; операций определяется выражением&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p align=&amp;quot;center&amp;quot;&amp;gt;&amp;lt;math&amp;gt;\Psi_{k-means} \approx \Tau * (\Psi_{distribute}^{k, d} + \Psi_{recenter}^{k, d}) \le \Tau * O(log(k*d*n))&amp;lt;/math&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Входные и выходные данные алгоритма ===&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;Входные данные&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;Матрица из &amp;lt;math&amp;gt;n*d&amp;lt;/math&amp;gt; элементов &amp;lt;math&amp;gt;x_{i, j} \in \mathbb{R}, i=\overline{1, n}, j=\overline{1, d}&amp;lt;/math&amp;gt;&amp;amp;ndash; координат векторов (наблюдений).&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;Целое положительное число &amp;lt;math&amp;gt;k, k \le n&amp;lt;/math&amp;gt; &amp;amp;ndash; количество кластеров.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;Объем входных данных&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;math&amp;gt;1&amp;lt;/math&amp;gt; целое число + &amp;lt;math&amp;gt;n*d&amp;lt;/math&amp;gt; вещественных чисел (при условии, что координаты &amp;amp;ndash; вещественные числа).&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;Выходные данные&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; целых положительных чисел &amp;lt;math&amp;gt;L_1, ..., L_n&amp;lt;/math&amp;gt;&amp;amp;ndash; номера кластеров, соотвествующие каждому вектору (при условии, что нумерация кластеров начинается с &amp;lt;math&amp;gt;1&amp;lt;/math&amp;gt;).&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;Объем выходных данных&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; целых положительных чисел.&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Свойства алгоритма ===&lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;[[глоссарий#Вычислительная мощность|&#039;&#039;Вычислительная мощность&#039;&#039;]]&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
Вычислительная мощность алгоритма &amp;lt;i&amp;gt;k means&amp;lt;/i&amp;gt; равна &amp;lt;math&amp;gt;\frac{k*d*n*\Tau}{n*d} = k*\Tau &amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; &amp;amp;ndash; число кластеров, &amp;lt;math&amp;gt;\Tau&amp;lt;/math&amp;gt; &amp;amp;ndash; число итераций алгоритма.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;[[глоссарий#Детерминированность |&#039;&#039;Детерминированность&#039;&#039;]] и [[глоссарий#Устойчивость |&#039;&#039;Устойчивость&#039;&#039;]] &amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
Алгоритм &amp;lt;i&amp;gt;k means&amp;lt;/i&amp;gt; является итерационным. Количество итераций алгоритма в общем случае не фиксируется и зависит от начального расположения объектов в пространстве, параметра &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt;, а также от начального приближения центров кластеров, &amp;lt;math&amp;gt;\mu_1, ..., \mu_k&amp;lt;/math&amp;gt;. В результате этого может варьироваться результат работы алгоритма. При неудачном выборе начальных параметров итерационный процесс может сойтись к локальному оптимуму&amp;lt;ref&amp;gt;Von Luxburg, Ulrike. Clustering Stability. Now Publishers Inc, 2010.&amp;lt;/ref&amp;gt;. По этим причинам алгоритм не является ни &amp;lt;b&amp;gt;детермирированным&amp;lt;/b&amp;gt;, ни &amp;lt;b&amp;gt;устойчивым&amp;lt;/b&amp;gt;.&lt;br /&gt;
 &lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Соотношение последовательной и параллельной сложности алгоритма&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\frac{\Theta_{k-means}}{\Psi_{k-means}} = \frac{O(\Tau*k*d*n)}{O(\Tau*log(k*d*n))}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Сильные стороны алгоритма&amp;lt;/b&amp;gt;:&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;i&amp;gt;Сравнительно высокая эффективность при простоте реализации&amp;lt;/i&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;i&amp;gt;Высокое качество кластеризации&amp;lt;/i&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;i&amp;gt;Возможность распараллеливания&amp;lt;/i&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;i&amp;gt;Существование множества модификаций&amp;lt;/i&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;Недостатки алгоритма&amp;lt;/b&amp;gt;&amp;lt;ref&amp;gt;Ortega, Joaquín Pérez, Ma Del Rocío Boone Rojas, and María J. Somodevilla. &amp;quot;Research issues on K-means Algorithm: An Experimental Trial Using Matlab.&amp;quot;&amp;lt;/ref&amp;gt;:&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;i&amp;gt;Количество кластеров является параметром алгоритма&amp;lt;/i&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;&amp;lt;i&amp;gt;Чувствительность к начальным условиям&amp;lt;/i&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;Инициализация центров кластеров в значительной степени влияет на результат кластеризации.&amp;lt;/p&amp;gt;&lt;br /&gt;
  &amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;&amp;lt;i&amp;gt;Чувствительность к выбросам и шумам&amp;lt;/i&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;Выбросы, далекие от центров настоящих кластеров, все равно учитываются при вычислении их центров.&amp;lt;/p&amp;gt;&lt;br /&gt;
  &amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;&amp;lt;i&amp;gt;Возможность сходимости к локальному оптимуму&amp;lt;/i&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;Итеративный подход не дает гарантии сходимости к оптимальному решению.&amp;lt;/p&amp;gt;&lt;br /&gt;
  &amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;&amp;lt;i&amp;gt;Использование понятия &amp;quot;среднего&amp;quot;&amp;lt;/i&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;Алгоритм неприменим к данным, для которых не определено понятие &amp;quot;среднего&amp;quot;, например, категориальным данным.&amp;lt;/p&amp;gt;&lt;br /&gt;
  &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&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;
Исследование масштабируемости параллельной реализации алгоритма k means проводилось на суперкомпьютере &amp;quot;Ломоносов&amp;quot;&amp;lt;ref name=&amp;quot;Lom&amp;quot;&amp;gt;Воеводин Вл., Жуматий С., Соболев С., Антонов А., Брызгалов П., Никитенко Д., Стефанов К., Воеводин Вад. Практика суперкомпьютера «Ломоносов» // Открытые системы, 2012, N 7, С. 36-39.&amp;lt;/ref&amp;gt; [http://parallel.ru/cluster Суперкомпьютерного комплекса Московского университета]. Алгоритм реализован на языке C с использованием средств MPI.&lt;br /&gt;
Для исследования масштабируемости проводилось множество запусков программы с разным значением параметра (количество векторов для кластеризации), а также с различным числом процессоров. Фиксировались результаты запусков &amp;amp;ndash; время работы &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt; и количество произведенных итераций алгоритма &amp;lt;math&amp;gt;\Tau&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Параметры запусков для экспериментальной оценки:&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;Значения &amp;lt;b&amp;gt;количества векторов&amp;lt;/b&amp;gt; &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;: 20&#039;000, 30&#039;000, 50&#039;000, 100&#039;000, 200&#039;000, 300&#039;000, 500&#039;000, 700&#039;000, 1&#039;000&#039;000, 1&#039;500&#039;000, 2&#039;000&#039;000.&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;Значения &amp;lt;b&amp;gt;количества процессоров&amp;lt;/b&amp;gt; &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt;: 1, 8, 16, 32, 64, 128, 160, 192, 224, 256, 288, 320, 352, 384, 416, 448, 480, 512.&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;Значение &amp;lt;b&amp;gt;количества кластеров&amp;lt;/b&amp;gt; &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt;: 100.&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;Значение &amp;lt;b&amp;gt;размерности векторов&amp;lt;/b&amp;gt; &amp;lt;math&amp;gt;d&amp;lt;/math&amp;gt;: 10.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Для проведения экспериментов были сгенерированы нормально распределенные псевдослучайные данные (с использованием Python библиотеки [http://scikit-learn.org/ scikit-learn]):&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
from sklearn.datasets import make_classification&lt;br /&gt;
X1, Y1 = make_classification(n_features=10, n_redundant=2, n_informative=8,&lt;br /&gt;
                             n_clusters_per_class=1, n_classes=100,&lt;br /&gt;
                             n_samples=2000000)&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Для заданной конфигурации эксперимента (&amp;lt;math&amp;gt;n, d, p, k&amp;lt;/math&amp;gt;) и полученных результатов (&amp;lt;math&amp;gt;t, \Tau&amp;lt;/math&amp;gt;)  [[Глоссарий#Производительность|производительность]]  и эффективность реализации расчитывались по формулам:&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
&amp;lt;ul&amp;gt;&amp;lt;li&amp;gt;&amp;lt;math&amp;gt;Performance = \frac{N_{k-means}^{d, n}}{t}\ \ (FLOPS),&amp;lt;/math&amp;gt;&amp;lt;/li&amp;gt;&amp;lt;/ul&amp;gt;&lt;br /&gt;
где &amp;lt;math&amp;gt;N_{k-means}^{d, n}&amp;lt;/math&amp;gt; &amp;amp;ndash; точное число операций с плавающей точкой (операции с памятью, а также целочисленные операции не учитывались), вычисленное в соответствие с разделом [[#Последовательная сложность алгоритма| &amp;quot;Последовательная сложность алгоритма&amp;quot;]];&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
&amp;lt;ul&amp;gt;&amp;lt;li&amp;gt;&amp;lt;math&amp;gt;Efficiency = \frac{100 * Performance}{Performance_{Peak}^{p}}\ \ (%),&amp;lt;/math&amp;gt;&amp;lt;/li&amp;gt;&amp;lt;/ul&amp;gt;&lt;br /&gt;
где &amp;lt;math&amp;gt;Performance_{Peak}^{p}&amp;lt;/math&amp;gt; &amp;amp;ndash; пиковая производительность суперкомпьютера при &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt; процессорах, вычисленная согласно спецификациям Intel&amp;lt;sup&amp;gt;&amp;amp;reg;&amp;lt;/sup&amp;gt; XEON&amp;lt;sup&amp;gt;&amp;amp;reg;&amp;lt;/sup&amp;gt; X5670&amp;lt;ref&amp;gt;&amp;quot;http://ark.intel.com/ru/products/47920/Intel-Xeon-Processor-X5670-12M-Cache-2_93-GHz-6_40-GTs-Intel-QPI&amp;quot;&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Графики зависимости производительности и эффективности параллельной реализации k means от числа векторов для кластеризации (&amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;) и числа процессоров (&amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt;) представлены на рисунках 4 и 5 соответственно.&lt;br /&gt;
&lt;br /&gt;
[[file:Flops.png|thumb|center|800px|Рис. 4. Параллельная реализация k means. График зависимости производительности реализации алгоритма от числа векторов для кластеризации (&amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;) и числа процессоров (&amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt;).]]&lt;br /&gt;
[[file:Efficiency.png|thumb|center|800px|Рис. 5. Параллельная реализация k means. График зависимости эффективности реализации алгоритма от числа векторов для кластеризации (&amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;) и числа процессоров (&amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt;).]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;В результате&amp;lt;/b&amp;gt; экспериментальной оценки были получены следующие оценки эффективности реализации:&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;b&amp;gt;Минимальное&amp;lt;/b&amp;gt; значение: 0.000409 % достигается при &amp;lt;math&amp;gt;n=20&#039;000, p=480&amp;lt;/math&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;b&amp;gt;Максимальное&amp;lt;/b&amp;gt; значение: 0.741119 % достигается при &amp;lt;math&amp;gt;n=300&#039;000, p=1&amp;lt;/math&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
Оценки масштабируемости реализации алгоритма k means:&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;b&amp;gt;По числу процессоров:&amp;lt;/b&amp;gt; -0.002683 &amp;amp;ndash; эффективность убывает с ростом числа процессоров. Данный результат вызван ростом накладных расходов для обеспечения параллельного выполнения алгоритма.&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;b&amp;gt;По размеру задачи:&amp;lt;/b&amp;gt; 0.002779 &amp;amp;ndash; эффективность растет с ростом числа векторов. Данный результат вызван тем, что при увеличении размера задачи, количество вычислений растет по сравнению с временем, затрачиваемым на пересылку данных.&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;b&amp;gt;Общая оценка:&amp;lt;/b&amp;gt; -0.000058 &amp;amp;ndash; можно сделать вывод, что в целом эффективность реализации незначительно уменьшается с ростом размера задачи и числа процессоров.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[https://github.com/serban/kmeans Использованная параллельная реализация алгоритма k means]&lt;br /&gt;
&lt;br /&gt;
=== Динамические характеристики и эффективность реализации алгоритма ===&lt;br /&gt;
=== Выводы для классов архитектур ===&lt;br /&gt;
=== Существующие реализации алгоритма ===&lt;br /&gt;
==== Открытое программное обеспечение ====&lt;br /&gt;
&amp;lt;ol&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;[https://www.icpsr.umich.edu/CrimeStat/ CrimeStat]&amp;lt;/li&amp;gt; Программное обеспечение, созданное для операционных систем Windows, предоставляющее инструменты статистического  и пространственного анализа для решения задачи картирования преступности.&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://juliastats.github.io Julia]&amp;lt;/li&amp;gt; Высокоуровневый высокопроизводительный свободный язык программирования с динамической типизацией, созданный для математических вычислений, содержит реализацию k-means.&lt;br /&gt;
  &amp;lt;li&amp;gt;[https://mahout.apache.org Mahout]&amp;lt;/li&amp;gt; Apache Mahout - Java библиотека для работы с алгоритмами машинного обучения с использованием MapReduce. Содержит реализацию k-means.&lt;br /&gt;
  &amp;lt;li&amp;gt;[https://www.gnu.org/software/octave/ Octave]&amp;lt;/li&amp;gt; Написанная на C++  свободная система для математических вычислений, использующая совместимый с MATLAB язык высокого уровня, содержит реализацию k-means.&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://spark.apache.org/docs/latest/mllib-clustering.html Spark]&amp;lt;/li&amp;gt; Распределенная реализация k-means содержится в библиотеке Mlib для работы с алгоритмами машинного обучения, взаимодействующая с Python библиотекой NumPy и библиотека R.&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://torch.ch Torch]&amp;lt;/li&amp;gt;  MATLAB-подобная библиотека для языка программирования Lua с открытым исходным кодом, предоставляет большое количество алгоритмов для глубинного обучения и научных расчётов. Ядро написано на Си, прикладная часть выполняется на LuaJIT, поддерживается распараллеливание вычислений средствами CUDA и OpenMP. Существуют реализации k-means.&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://www.cs.waikato.ac.nz/ml/weka/ Weka]&amp;lt;/li&amp;gt;  Cвободное программное обеспечение для анализа данных, написанное на Java. Содержит k-means и x-means.&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://accord-framework.net/docs/html/T_Accord_MachineLearning_KMeans.htm Accord.NET]&amp;lt;/li&amp;gt; C# реализация алгоритмов k-means, k-means++, k-modes.&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://docs.opencv.org/3.0-beta/doc/py_tutorials/py_ml/py_kmeans/py_kmeans_opencv/py_kmeans_opencv.html OpenCV]&amp;lt;/li&amp;gt; Написанная на С++ библиотека, направленная в основном на решение задач компьютерного зрения. Содержит реализацию k-means.&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://mlpack.org/ MLPACK]&amp;lt;/li&amp;gt; Масштабируемая С++ библиотека для работы с алгоритмами машинного обучения, содержит реализацию k-means.&lt;br /&gt;
  &amp;lt;li&amp;gt;[https://www.scipy.org/ SciPy]&amp;lt;/li&amp;gt; Библиотека Python, содержит множество реализаций k-means.&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://scikit-learn.org/ scikit-learn]&amp;lt;/li&amp;gt; Библиотека Python, содержит множество реализаций k-means.&lt;br /&gt;
  &amp;lt;li&amp;gt;[https://www.r-bloggers.com/k-means-clustering-in-r/ R]&amp;lt;/li&amp;gt; Язык программирования для статистической обработки данных и работы с графикой, а также свободная программная среда вычислений с открытым исходным кодом в рамках проекта GNU, содержит три реализации k-means.&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://elki.dbs.ifi.lmu.de ELKI]&amp;lt;/li&amp;gt; Java фреймворк, содержащий реализацию k-means, а также множество других алгоритмов кластеризации.&lt;br /&gt;
&amp;lt;/ol&amp;gt;&lt;br /&gt;
==== Проприетарное программное обеспечение  ====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ol&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;[https://www.ayasdi.com/blog/bigdata/topological-data-analysis-of-oil-and-gas-petrophysical-data/ Ayasdi]&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://www.stata.com/features/cluster-analysis/ Stata]&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://mathworld.wolfram.com/K-MeansClusteringAlgorithm.html Mathematica]&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://www.mathworks.com/help/stats/kmeans.html?requestedDomain=www.mathworks.com MATLAB]&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;[https://support.sas.com/rnd/app/stat/procedures/fastclus.html SAS]&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://docs.rapidminer.com/studio/operators/modeling/segmentation/k_means.html RapidMiner]&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;[https://blogs.sap.com/2013/03/28/sap-hana-pal-k-means-algorithm-or-how-to-do-customer-segmentation-for-the-telecommunications-industry/ SAP HANA]&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ol&amp;gt;&lt;br /&gt;
== Литература ==&lt;br /&gt;
&amp;lt;references /&amp;gt;&lt;/div&gt;</summary>
		<author><name>DennZo1993</name></author>
	</entry>
	<entry>
		<id>https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:%D0%91%D1%80%D0%BE%D1%82%D0%B8%D0%BA%D0%BE%D0%B2%D1%81%D0%BA%D0%B0%D1%8F_%D0%94%D0%B0%D0%BD%D1%83%D1%82%D0%B0/%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_k-means&amp;diff=20523</id>
		<title>Участник:Бротиковская Данута/Алгоритм k-means</title>
		<link rel="alternate" type="text/html" href="https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:%D0%91%D1%80%D0%BE%D1%82%D0%B8%D0%BA%D0%BE%D0%B2%D1%81%D0%BA%D0%B0%D1%8F_%D0%94%D0%B0%D0%BD%D1%83%D1%82%D0%B0/%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_k-means&amp;diff=20523"/>
		<updated>2016-12-10T10:39:26Z</updated>

		<summary type="html">&lt;p&gt;DennZo1993: /* Последовательная сложность алгоритма */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Assignment|Zhum}}&lt;br /&gt;
&lt;br /&gt;
{{algorithm&lt;br /&gt;
| name              = Алгоритм k средних (k means)&lt;br /&gt;
| serial_complexity = &amp;lt;math&amp;gt;O(\Tau*k*d*n)&amp;lt;/math&amp;gt;&lt;br /&gt;
| input_data        = &amp;lt;math&amp;gt; d*n &amp;lt;/math&amp;gt;&lt;br /&gt;
| output_data       = &amp;lt;math&amp;gt; n &amp;lt;/math&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
Авторы страницы &amp;lt;b&amp;gt;[[Участник:Бротиковская Данута|Данута Бротиковская]]&amp;lt;/b&amp;gt; и &amp;lt;b&amp;gt;[[Участник:DennZo1993|Денис Зобнин]]&amp;lt;/b&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
Оба автора внесли одинаковый вклад в написание статьи (поиск материалов, изучение статей, заполнение контента статьи), четких разграничений по пунктам статьи сделать невозможно. &lt;br /&gt;
&lt;br /&gt;
== Свойства и структура алгоритма ==&lt;br /&gt;
&lt;br /&gt;
=== Общее описание алгоритма ===&lt;br /&gt;
Алгоритм &amp;lt;b&amp;gt;&amp;lt;i&amp;gt;k средних&amp;lt;/i&amp;gt;&amp;lt;/b&amp;gt; (&amp;lt;b&amp;gt;&amp;lt;i&amp;gt;k means&amp;lt;/i&amp;gt;&amp;lt;/b&amp;gt;) &amp;amp;ndash; неиерархический&amp;lt;ref&amp;gt;&amp;quot;https://ru.wikipedia.org/wiki/Иерархическая_кластеризация&amp;quot;&amp;lt;/ref&amp;gt;, итерационный метод кластеризации&amp;lt;ref&amp;gt;&amp;quot;https://ru.wikipedia.org/wiki/Кластерный_анализ&amp;quot;&amp;lt;/ref&amp;gt;, получивший большую популярность благодаря своей простоте, наглядности реализации и достаточно высокому качеству работы. Был изобретен в 1950-х годах математиком &amp;lt;i&amp;gt;Гуго Штейнгаузом&amp;lt;/i&amp;gt;&amp;lt;ref&amp;gt;Steinhaus, Hugo. &amp;quot;Sur la division des corp materiels en parties.&amp;quot; Bull. Acad. Polon. Sci 1.804 (1956): 801.&amp;lt;/ref&amp;gt; и почти одновременно &amp;lt;i&amp;gt;Стюартом Ллойдом&amp;lt;/i&amp;gt;&amp;lt;ref&amp;gt;Lloyd, S. P. &amp;quot;Least square quantization in PCM. Bell Telephone Laboratories Paper. Published in journal much later: Lloyd, SP: Least squares quantization in PCM.&amp;quot; IEEE Trans. Inform. Theor.(1957/1982).&amp;lt;/ref&amp;gt;. Особую популярность приобрел после публикации работы &amp;lt;i&amp;gt;МакКуина&amp;lt;/i&amp;gt;&amp;lt;ref&amp;gt;MacQueen, James. &amp;quot;Some methods for classification and analysis of multivariate observations.&amp;quot; Proceedings of the fifth Berkeley symposium on mathematical statistics and probability. Vol. 1. No. 14. 1967.&amp;lt;/ref&amp;gt; в 1967.&lt;br /&gt;
&lt;br /&gt;
Алгоритм представляет собой версию EM-алгоритма&amp;lt;ref&amp;gt;&amp;quot;https://ru.wikipedia.org/wiki/EM-алгоритм&amp;quot;&amp;lt;/ref&amp;gt;, применяемого также для разделения смеси гауссиан. Основная идея &amp;lt;i&amp;gt;k means&amp;lt;/i&amp;gt; заключается в том, что данные произвольно разбиваются на кластеры, после чего итеративно перевычисляется центр масс для каждого кластера, полученного на предыдущем шаге, затем векторы разбиваются на кластеры вновь в соответствии с тем, какой из новых центров оказался ближе по выбранной метрике.&lt;br /&gt;
&lt;br /&gt;
Цель алгоритма заключается в разделении &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; наблюдений на &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластеров таким образом, чтобы каждое наблюдение принадлежало ровно одному кластеру, расположенному на наименьшем расстоянии от наблюдения.&lt;br /&gt;
&lt;br /&gt;
=== Математическое описание алгоритма ===&lt;br /&gt;
&amp;lt;b&amp;gt;&amp;lt;u&amp;gt;Дано:&amp;lt;/u&amp;gt;&amp;lt;/b&amp;gt;&lt;br /&gt;
* набор из &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; наблюдений &amp;lt;math&amp;gt;X=\{\mathbf{x}_1, \mathbf{x}_2, ..., \mathbf{x}_n\}, \mathbf{x}_i \in \mathbb{R}^d, i=\overline{1, n}&amp;lt;/math&amp;gt;;&lt;br /&gt;
* &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; - требуемое число кластеров, &amp;lt;math&amp;gt;k \in \mathbb{N}, k \leq n&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;&amp;lt;u&amp;gt;Требуется:&amp;lt;/u&amp;gt;&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Разделить множество наблюдений &amp;lt;math&amp;gt;X&amp;lt;/math&amp;gt; на &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластеров &amp;lt;math&amp;gt;S_1, S_2, ..., S_k&amp;lt;/math&amp;gt;:&lt;br /&gt;
*   &amp;lt;math&amp;gt;S_i \cap S_j= \varnothing, \quad i \ne j&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
*   &amp;lt;math&amp;gt;\bigcup_{i=1}^{k} S_i = X&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;&amp;lt;u&amp;gt;Действие алгоритма:&amp;lt;/u&amp;gt;&amp;lt;/b&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;Алгоритм &amp;lt;i&amp;gt;k means&amp;lt;/i&amp;gt; разбивает набор &amp;lt;math&amp;gt;X&amp;lt;/math&amp;gt; на &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; наборов &amp;lt;math&amp;gt;S_1, S_2, ..., S_k,&amp;lt;/math&amp;gt; таким образом, чтобы минимизировать сумму квадратов расстояний от каждой точки кластера до его центра (центр масс кластера). Введем обозначение, &amp;lt;math&amp;gt;S=\{S_1, S_2, ..., S_k\}&amp;lt;/math&amp;gt;. Тогда действие алгоритма &amp;lt;i&amp;gt;k means&amp;lt;/i&amp;gt; равносильно поиску:&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;table style=&amp;quot;width:100%&amp;quot;&amp;gt;&lt;br /&gt;
  &amp;lt;tr&amp;gt;&lt;br /&gt;
    &amp;lt;td align=&amp;quot;center&amp;quot; width=&amp;quot;90%&amp;quot;&amp;gt;&amp;lt;math&amp;gt;\arg\min_{S} \sum\limits_{i=1}^k \sum\limits_{\mathbf{x} \in S_i} \rho(\mathbf{x}, \mathbf{\mu}_i )^2,&amp;lt;/math&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;td align=&amp;quot;right&amp;quot;&amp;gt;&amp;lt;math&amp;gt;(1)&amp;lt;/math&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;/table&amp;gt;&lt;br /&gt;
где &amp;lt;math&amp;gt;\mathbf{\mu}_i&amp;lt;/math&amp;gt; &amp;amp;ndash; центры кластеров, &amp;lt;math&amp;gt;i=\overline{1,k}, \quad \rho(\mathbf{x}, \mathbf{\mu}_i)&amp;lt;/math&amp;gt; &amp;amp;ndash; функция расстояния между &amp;lt;math&amp;gt;\mathbf{x}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\mu_i&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;&amp;lt;u&amp;gt;Шаги алгоритма: &amp;lt;/u&amp;gt;&amp;lt;/b&amp;gt;&lt;br /&gt;
&amp;lt;ol&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&lt;br /&gt;
    &amp;lt;b&amp;gt;Начальный шаг: инициализация кластеров&amp;lt;/b&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;Выбирается произвольное множество точек &amp;lt;math&amp;gt;\mu_i, i=\overline{1,k}&amp;lt;/math&amp;gt;, рассматриваемых как начальные центры кластеров: &amp;lt;math&amp;gt;\mu_i^{(0)} = \mu_i, \quad i=\overline{1, k}&amp;lt;/math&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
  &amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&lt;br /&gt;
    &amp;lt;b&amp;gt;Распределение векторов по кластерам&amp;lt;/b&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Шаг&amp;lt;/b&amp;gt; &amp;lt;math&amp;gt;t: \forall \mathbf{x}_i \in X, i=\overline{1,n}: \mathbf{x}_i \in S_j \iff  j=\arg\min_{k}\rho(\mathbf{x}_i,\mathbf{\mu}_k^{(t-1)})^2&amp;lt;/math&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
  &amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&lt;br /&gt;
    &amp;lt;b&amp;gt;Пересчет центров кластеров&amp;lt;/b&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Шаг &amp;lt;/b&amp;gt; &amp;lt;math&amp;gt;t: \forall i=\overline{1,k}:  \mu_i^{(t)} = \cfrac{1}{|S_i|}\sum_{\mathbf{x}\in S_i}\mathbf{x}&amp;lt;/math&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
  &amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&lt;br /&gt;
    &amp;lt;b&amp;gt;Проверка условия останова:&amp;lt;/b&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
    &#039;&#039;&#039;if&#039;&#039;&#039; &amp;lt;math&amp;gt;\exist i\in \overline{1,k}: \mu_i^{(t)} \ne \mu_i^{(t-1)}&amp;lt;/math&amp;gt; &#039;&#039;&#039;then&#039;&#039;&#039;&lt;br /&gt;
        t = t + 1;&lt;br /&gt;
        goto 2;&lt;br /&gt;
    &#039;&#039;&#039;else&#039;&#039;&#039;&lt;br /&gt;
        &#039;&#039;&#039;stop&#039;&#039;&#039;&lt;br /&gt;
  &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ol&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Вычислительное ядро алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Вычислительным ядром являются шаги 2 и 3 приведенного выше алгоритма: &amp;lt;b&amp;gt;&amp;lt;i&amp;gt;распределение векторов по кластерам&amp;lt;/i&amp;gt;&amp;lt;/b&amp;gt; и &amp;lt;b&amp;gt;&amp;lt;i&amp;gt;пересчет центров кластеров&amp;lt;/i&amp;gt;&amp;lt;/b&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;&amp;lt;i&amp;gt;Распределение векторов&amp;lt;/i&amp;gt;&amp;lt;/b&amp;gt; по кластерам предполагает вычисление расстояний между каждым вектором &amp;lt;math&amp;gt;\mathbf{x}_i \in X, i= \overline{1,n}&amp;lt;/math&amp;gt; и центрами кластера &amp;lt;math&amp;gt;\mathbf{\mu}_j, j= \overline{1,k}&amp;lt;/math&amp;gt;. Таким образом, данный шаг предполагает &amp;lt;math&amp;gt;kn&amp;lt;/math&amp;gt; вычислений расстояний между d-мерными векторами. &lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;&amp;lt;i&amp;gt;Пересчет центров кластеров&amp;lt;/i&amp;gt;&amp;lt;/b&amp;gt; предполагает &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; вычислений центров масс &amp;lt;math&amp;gt;\mathbf{\mu}_i&amp;lt;/math&amp;gt; множеств &amp;lt;math&amp;gt;S_i, i=\overline{1,k}&amp;lt;/math&amp;gt; представленных выражением в шаге 3 представленного выше алгоритма.&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Макроструктура алгоритма ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Инициализация центров масс &amp;lt;math&amp;gt;\mu_1, ..., \mu_k&amp;lt;/math&amp;gt;&amp;lt;/b&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
Наиболее распространенными являются следующие стратегии:&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&lt;br /&gt;
    &amp;lt;b&amp;gt;Метод Forgy&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;В качестве начальных значений &amp;lt;math&amp;gt;\mu_1, ..., \mu_k&amp;lt;/math&amp;gt; берутся случайно выбранные векторы.&lt;br /&gt;
  &amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&lt;br /&gt;
    &amp;lt;b&amp;gt;Метод случайно разделения (Random Partitioning)&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;Для каждого вектора &amp;lt;math&amp;gt;\mathbf{x}_i \in X, i=\overline{1, n}&amp;lt;/math&amp;gt; выбирается случайным образом кластер &amp;lt;math&amp;gt;S_1, ..., S_k&amp;lt;/math&amp;gt;, после чего для каждого полученного кластера вычисляются значения &amp;lt;math&amp;gt;\mu_1, ..., \mu_k&amp;lt;/math&amp;gt;.&lt;br /&gt;
  &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Распределение векторов по кластерам&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Для этого шага алгоритма между векторами &amp;lt;math&amp;gt;\mathbf{x}_i \in X, i=\overline{1, n}&amp;lt;/math&amp;gt; и центрами кластеров &amp;lt;math&amp;gt;\mu_1, ..., \mu_k&amp;lt;/math&amp;gt; вычисляются &amp;lt;b&amp;gt;расстояния&amp;lt;/b&amp;gt; по формуле (как правило, используется Евлидово расстояние):&lt;br /&gt;
&amp;lt;table style=&amp;quot;width:100%&amp;quot;&amp;gt;&lt;br /&gt;
  &amp;lt;tr&amp;gt;&lt;br /&gt;
    &amp;lt;td align=&amp;quot;center&amp;quot; width=&amp;quot;90%&amp;quot;&amp;gt;&amp;lt;math&amp;gt; \mathbf{v}_1, \mathbf{v}_2 \in \mathbb{R}^d,  \quad \rho(\mathbf{v}_1, \mathbf{v}_2) = \lVert \mathbf{v}_1- \mathbf{v}_2 \rVert= \sqrt{\sum_{i=1}^{d}(\mathbf{v}_{1,i} - \mathbf{v}_{2,i})^2}&amp;lt;/math&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;td align=&amp;quot;right&amp;quot;&amp;gt;&amp;lt;math&amp;gt;(2)&amp;lt;/math&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;/table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Пересчет центров кластеров&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Для этого шага алгоритма производится пересчет центров кластера по &amp;lt;b&amp;gt;формуле вычисления центра масс&amp;lt;/b&amp;gt;:&lt;br /&gt;
&amp;lt;table style=&amp;quot;width:100%&amp;quot;&amp;gt;&lt;br /&gt;
  &amp;lt;tr&amp;gt;&lt;br /&gt;
    &amp;lt;td align=&amp;quot;center&amp;quot; width=&amp;quot;90%&amp;quot;&amp;gt;&amp;lt;math&amp;gt; \mu = \cfrac{1}{|S|}\sum_{\mathbf{x}\in S}\mathbf{x}&amp;lt;/math&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;td align=&amp;quot;right&amp;quot;&amp;gt;&amp;lt;math&amp;gt;(3)&amp;lt;/math&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;/table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Схема реализации последовательного алгоритма ===&lt;br /&gt;
&lt;br /&gt;
 &#039;&#039;&#039;algorithm&#039;&#039;&#039; k-means &#039;&#039;&#039;is&#039;&#039;&#039;&lt;br /&gt;
     &#039;&#039;&#039;1.&#039;&#039;&#039; Инициализировать центры кластеров &amp;lt;math&amp;gt;\mathbf{\mu}_i^{(1)}, i=\overline{1,k}&amp;lt;/math&amp;gt;&lt;br /&gt;
     &#039;&#039;&#039;2.&#039;&#039;&#039; &amp;lt;math&amp;gt;t \leftarrow 1&amp;lt;/math&amp;gt;&lt;br /&gt;
     &#039;&#039;&#039;3.&#039;&#039;&#039; &#039;&#039;&#039;Распределение по кластерам&#039;&#039;&#039;&amp;lt;br&amp;gt;&lt;br /&gt;
        &amp;lt;math&amp;gt;S_i^{(t)}=\{\mathbf{x}_p: \lVert\mathbf{x}_p-\mathbf{\mu}_i^{(t)}\rVert^2 \leq \lVert\mathbf{x}_p-\mathbf{\mu}_j^{(t)}\rVert^2 \quad \forall j=\overline{1,k}\},&amp;lt;/math&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
        где каждый вектор &amp;lt;math&amp;gt;\mathbf{x}_p&amp;lt;/math&amp;gt; соотносится единственному кластеру &amp;lt;math&amp;gt;S^{(t)}&amp;lt;/math&amp;gt;&lt;br /&gt;
     &#039;&#039;&#039;4.&#039;&#039;&#039; &#039;&#039;&#039;Обновление центров кластеров&#039;&#039;&#039;&amp;lt;br&amp;gt;&lt;br /&gt;
        &amp;lt;math&amp;gt;\mathbf{\mu}_i^{(t+1)} = \frac{1}{|S^{(t)}_i|} \sum_{\mathbf{x}_j \in S^{(t)}_i} \mathbf{x}_j &amp;lt;/math&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
     &#039;&#039;&#039;5.&#039;&#039;&#039; &#039;&#039;&#039;if&#039;&#039;&#039; &amp;lt;math&amp;gt;\exist i \in \overline{1,k}: \mathbf{\mu}_i^{(t+1)} \ne \mathbf{\mu}_i^{(t)}&amp;lt;/math&amp;gt; &#039;&#039;&#039;then&#039;&#039;&#039;&lt;br /&gt;
            t = t + 1;&lt;br /&gt;
            goto &#039;&#039;&#039;3&#039;&#039;&#039;;&lt;br /&gt;
        &#039;&#039;&#039;else&#039;&#039;&#039;&lt;br /&gt;
            &#039;&#039;&#039;stop&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
=== Последовательная сложность алгоритма===&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding-bottom: 20px&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;Обозначим &amp;lt;math&amp;gt;\Theta_{centroid}^{d, m}&amp;lt;/math&amp;gt; временную сложность вычисления центорида кластера, число элементов которого равна &amp;lt;math&amp;gt;m&amp;lt;/math&amp;gt;,  в d-мерном пространстве.&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;Аналогично  &amp;lt;math&amp;gt;\Theta_{distance}^d&amp;lt;/math&amp;gt; &amp;amp;ndash; временная сложность вычисления расстояния между двумя d-мерными векторами.&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding-bottom: 20px&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;Сложность шага инициализации &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластеров мощности &amp;lt;math&amp;gt;m&amp;lt;/math&amp;gt; в d-мерном пространстве &amp;amp;ndash; &amp;lt;math&amp;gt;\Theta_{init}^{k, d, m}&amp;lt;/math&amp;gt;&amp;lt;/b&amp;gt;&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;i&amp;gt;Стратерия Forgy&amp;lt;/i&amp;gt;: вычисления не требуются, &amp;lt;math&amp;gt;\Theta_{init}^{k, d, m} = 0&amp;lt;/math&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;i&amp;gt;Стратегия случайного разбиения&amp;lt;/i&amp;gt;: вычисление центров &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластеров,  &amp;lt;math&amp;gt;\Theta_{init}^{k, d, m} = k \cdot \Theta_{centroid}^{d, m}, m \le n&amp;lt;/math&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding-bottom: 20px&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Cложность шага распределения d мерных векторов по &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластерам &amp;amp;ndash; &amp;lt;math&amp;gt;\Theta_{distribute}^{k, d}&amp;lt;/math&amp;gt;&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
На этом шаге для каждого вектора &amp;lt;math&amp;gt;\mathbf{x}_i \in X, i=\overline{1, n}&amp;lt;/math&amp;gt; вычисляется k расстояний до центров кластеров &amp;lt;math&amp;gt;\mathbf{\mu}_1, ...\mathbf{\mu}_k&amp;lt;/math&amp;gt;&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p align=&amp;quot;center&amp;quot;&amp;gt;&lt;br /&gt;
  &amp;lt;math&amp;gt;\Theta_{distribute}^{k, d} = n \cdot k \cdot \Theta_{distance}^d&amp;lt;/math&amp;gt;&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding-bottom: 20px&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;Сложность шага пересчета центров &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластеров размера &amp;lt;math&amp;gt;m&amp;lt;/math&amp;gt; в d-мерном пространстве &amp;amp;ndash; &amp;lt;math&amp;gt;\Theta_{recenter}^{k, d, m}&amp;lt;/math&amp;gt;&amp;lt;/b&amp;gt;&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;На этом шаге вычисляется &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; центров кластеров &amp;lt;math&amp;gt;\mathbf{\mu}_1, ...\mathbf{\mu}_k&amp;lt;/math&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p align=&amp;quot;center&amp;quot;&amp;gt;&amp;lt;math&amp;gt;\Theta_{recenter}^{k, d, m} = k \cdot \Theta_{centroid}^{d, m}&amp;lt;/math&amp;gt; &amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding-bottom: 20px&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Рассчитаем &amp;lt;math&amp;gt;\Theta_{centroid}^{d, m}&amp;lt;/math&amp;gt; для кластера, число элементов которого равно &amp;lt;math&amp;gt;m&amp;lt;/math&amp;gt;&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p align=&amp;quot;center&amp;quot;&amp;gt;&amp;lt;math&amp;gt;\Theta_{centroid}^{d, m}&amp;lt;/math&amp;gt; = &amp;lt;math&amp;gt;m \cdot d&amp;lt;/math&amp;gt; сложений + &amp;lt;math&amp;gt;d&amp;lt;/math&amp;gt; делений &amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding-bottom: 20px&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Рассчитаем &amp;lt;math&amp;gt;\Theta_{distance}^d&amp;lt;/math&amp;gt; в соответствие с формулой &amp;lt;math&amp;gt;(2)&amp;lt;/math&amp;gt;&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p align=&amp;quot;center&amp;quot;&amp;gt;&amp;lt;math&amp;gt;\Theta_{distance}^d&amp;lt;/math&amp;gt; = &amp;lt;math&amp;gt;d&amp;lt;/math&amp;gt; вычитаний + &amp;lt;math&amp;gt;d&amp;lt;/math&amp;gt; умножений + &amp;lt;math&amp;gt;(d-1)&amp;lt;/math&amp;gt; сложение&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding-bottom: 20px&amp;quot;&amp;gt;&lt;br /&gt;
  &amp;lt;p&amp;gt;Предположим, что алгоритм сошелся за &amp;lt;math&amp;gt;\Tau&amp;lt;/math&amp;gt; итераций, тогда временная сложность алгоритма &amp;lt;math&amp;gt;\Theta_{k-means}^{d, n}&amp;lt;/math&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
  &amp;lt;p align=&amp;quot;center&amp;quot;&amp;gt;&amp;lt;b&amp;gt;&amp;lt;math&amp;gt;\Theta_{k-means}^{d, n} \le \Theta_{init}^{k, d, n} + \Tau(\Theta_{distribute}^{k, d} + \Theta_{recenter}^{k, d, n})&amp;lt;/math&amp;gt;&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding-bottom: 5px&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;Операции сложения/вычитания:&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p align=&amp;quot;center&amp;quot;&amp;gt;&amp;lt;b&amp;gt;&amp;lt;math&amp;gt;\Theta_{k-means}^{d, n} \le knd+ \Tau(kn(2d-1) + knd) = knd+ \Tau(kn(3d-1)) \thicksim O(\Tau kdn)&amp;lt;/math&amp;gt;&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding-bottom: 20px&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;Операции умножения/деления:&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p align=&amp;quot;center&amp;quot;&amp;gt;&amp;lt;b&amp;gt;&amp;lt;math&amp;gt;\Theta_{k-means}^{d, n} \le k \cdot d + \Tau \cdot (k \cdot n \cdot d + k \cdot d) = k \cdot d + \Tau \cdot k \cdot d \cdot (n+1) \thicksim O(\Tau \cdot k \cdot d \cdot n) &amp;lt;/math&amp;gt;&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding-bottom: 20px&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;Получаем, что &amp;lt;b&amp;gt;временная сложность&amp;lt;/b&amp;gt; алгоритма &amp;lt;b&amp;gt;k means&amp;lt;/b&amp;gt; кластеризации &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; &amp;lt;b&amp;gt;d-мерных&amp;lt;/b&amp;gt; векторов на &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластеров за &amp;lt;math&amp;gt;\Tau&amp;lt;/math&amp;gt; итераций:&amp;lt;/p&amp;gt;&lt;br /&gt;
 &amp;lt;p align=&amp;quot;center&amp;quot;&amp;gt;&amp;lt;b&amp;gt;&amp;lt;math&amp;gt; \Theta_{k-means}^{d, n} \thicksim O(\Tau \cdot k \cdot d \cdot n) &amp;lt;/math&amp;gt;&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Информационный граф ===&lt;br /&gt;
&lt;br /&gt;
Рассмотрим информационный граф алгоритма. Алгоритм &amp;lt;i&amp;gt;k means&amp;lt;/i&amp;gt; начинается с этапа инициализации, после которого следуют итерации, на каждой из которых выполняется два последовательных шага (см. [[#Схема реализации последовательного алгоритма|&amp;quot;Схема реализации последовательного алгоритма&amp;quot;]]): &lt;br /&gt;
* распределение векторов по кластерам&lt;br /&gt;
* перерасчет центров кластеров&lt;br /&gt;
&lt;br /&gt;
Поскольку основная часть вычислений приходится на шаги итераций, распишем информационные графы данных шагов.&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Распределение векторов по кластерам&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
Информационный граф шага распределения векторов по кластерам представлен на &#039;&#039;рисунке 1&#039;&#039;. Исходами данного графа является исходные векторы &amp;lt;math&amp;gt;\mathbf{x}_1, ..., \mathbf{x}_n&amp;lt;/math&amp;gt;, а также центры кластеров &amp;lt;math&amp;gt;\mathbf{\mu}_1, ... \mathbf{\mu}_k&amp;lt;/math&amp;gt;, вычисленные ранее (на шаге инициализации, если рассматривается первая итерация алгоритма, или на шаге пересчета центров кластеров предыдущей итерации в противном случае). Каждая пара векторов данных &amp;lt;math&amp;gt;\mathbf{x}_i, i=\overline{1,n}&amp;lt;/math&amp;gt; и центров кластера &amp;lt;math&amp;gt;\mathbf{\mu}_j, j=\overline{1, k}&amp;lt;/math&amp;gt; : (&amp;lt;math&amp;gt;\mathbf{x}_i&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;\mathbf{\mu}_j&amp;lt;/math&amp;gt;) подаются на независимые узлы &amp;lt;i&amp;gt;&amp;quot;d&amp;quot;&amp;lt;/i&amp;gt; вычисления расстояния между векторами (более подробная схема вычисления расстояния представлена далее, &#039;&#039;рисунок 2&#039;&#039;). Далее узлы вычисления расстояния &amp;lt;i&amp;gt;&amp;quot;d&amp;quot;&amp;lt;/i&amp;gt;, соответствующие одному и тому же исходному вектору &amp;lt;math&amp;gt;\mathbf{x}_i&amp;lt;/math&amp;gt; передаются на один узел &amp;lt;i&amp;gt;&amp;quot;m&amp;quot;&amp;lt;/i&amp;gt;, где далее происходит вычисление новой метки кластера для каждого вектора &amp;lt;math&amp;gt;\mathbf{x}_i&amp;lt;/math&amp;gt; (берется кластер с минимальным результатом вычисления расстояния). На выходе графа выдаются метки кластеров , &amp;lt;math&amp;gt;L_1, ..., L_n&amp;lt;/math&amp;gt;, такие что &amp;lt;math&amp;gt;\forall \mathbf{x}_i, i=\overline{1, n}, \mathbf{x}_i \in S_j \Leftrightarrow L_i = j&amp;lt;/math&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
[[file:Clusterization.png|thumb|center|800px|Рис. 1. Схема распределения векторов по кластерам. &#039;&#039;d&#039;&#039; &amp;amp;ndash; вычисление расстояния между векторами; &#039;&#039;m&#039;&#039; &amp;amp;ndash; вычисление минимума.]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Вычисление расстояния между векторами&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
Подробная схема вычисления расстояния между векторами &amp;lt;math&amp;gt;\mathbf{x}_i, \mathbf{\mu}_j&amp;lt;/math&amp;gt; представлена на &#039;&#039;рисунке 2&#039;&#039;. Как показано на графе, узел вычисления расстояния между векторами &amp;lt;i&amp;gt;&amp;quot;d&amp;quot;&amp;lt;/i&amp;gt; состоит из шага взятия разности между векторами (узел &amp;quot;&amp;lt;math&amp;gt;-&amp;lt;/math&amp;gt;&amp;quot;) и взятия нормы получившегося вектора разности (узел &amp;quot;&amp;lt;math&amp;gt;||\cdot||^2&amp;lt;/math&amp;gt;&amp;quot;). Более подробно, вычисление расстояния между векторами &amp;lt;math&amp;gt;\mathbf{x}_i = {x_{i1,}, ...,{x_{in}}}, \mathbf{\mu}_j = {\mu_{j1}, ...,\mu_{jn}}&amp;lt;/math&amp;gt; может быть представлено как вычисление разности между каждой парой компонент &amp;lt;math&amp;gt;(x_{iz}, \mu_{jz}), z=\overline{1, d}&amp;lt;/math&amp;gt; (узел &amp;quot;&amp;lt;math&amp;gt;-&amp;lt;/math&amp;gt;&amp;quot;), далее возведение в квадрат для каждого узла &amp;quot;&amp;lt;math&amp;gt;-&amp;lt;/math&amp;gt;&amp;quot; (узел &amp;quot;&amp;lt;math&amp;gt;()^2&amp;lt;/math&amp;gt;&amp;quot;) и суммирования выходов всех узлов &amp;quot;&amp;lt;math&amp;gt;()^2&amp;lt;/math&amp;gt;&amp;quot; (узел &amp;quot;&amp;lt;math&amp;gt;+&amp;lt;/math&amp;gt;&amp;quot;).  &lt;br /&gt;
&lt;br /&gt;
[[file:dist_calc.png|thumb|center|800px|Рис. 2. Схема вычисления расстояния между вектором и центром кластера.]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Пересчет центров кластеров&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
Информационный граф шага пересчета центров кластеров представлен на &#039;&#039;рисунке 3&#039;&#039;. Исходами данного графа является исходные векторы &amp;lt;math&amp;gt;\mathbf{x}_1, ..., \mathbf{x}_n&amp;lt;/math&amp;gt;, а также им соответствующие метки кластера, &amp;lt;math&amp;gt;L_1, ..., L_n&amp;lt;/math&amp;gt;, такие что &amp;lt;math&amp;gt;\forall x_i, i=\overline{1, n}, \mathbf{x}_i \in S_j \Leftrightarrow L_i = j&amp;lt;/math&amp;gt;, вычисленные на этапе распределения векторов по кластерам. Все векторы &amp;lt;math&amp;gt;\mathbf{x}_1, ..., \mathbf{x}_n&amp;lt;/math&amp;gt; подаются в узлы &amp;lt;math&amp;gt;+_1, ...+_k&amp;lt;/math&amp;gt;, каждый узел &amp;lt;math&amp;gt;+_m, m = \overline{1,k}&amp;lt;/math&amp;gt; соответствует операции сложения векторов кластера с номером &amp;lt;math&amp;gt;m&amp;lt;/math&amp;gt;. Метки кластера &amp;lt;math&amp;gt;L_1, ..., L_n&amp;lt;/math&amp;gt; также совместно передаются на узлы &amp;lt;math&amp;gt;S_m, m = \overline{1,k}&amp;lt;/math&amp;gt;, на каждом из которых вычисляется количество векторов в соответствующем кластере (количество меток с соответствующим значением). Далее каждая пара выходов узлов &amp;lt;math&amp;gt;+_m&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;S_m&amp;lt;/math&amp;gt; подается на узел &amp;quot;&amp;lt;math&amp;gt;/&amp;lt;/math&amp;gt;&amp;quot;, где производится деление суммы векторов кластера на количество элементов в нем. Значения, вычисленные на узлах &amp;quot;&amp;lt;math&amp;gt;/&amp;lt;/math&amp;gt;&amp;quot;, присваиваются новым центрам кластеров (выходные значения графа).&lt;br /&gt;
&lt;br /&gt;
[[file:Recluster.png|thumb|center|800px|Рис. 3. Схема пересчета центров кластеров]]&lt;br /&gt;
&lt;br /&gt;
=== Ресурс параллелизма алгоритма ===&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
Работа алгоритма состоит из &amp;lt;math&amp;gt;\Tau&amp;lt;/math&amp;gt; итераций, в каждой из которых происходит &amp;lt;b&amp;gt;распределение d-мерных векторов по &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластерам&amp;lt;/b&amp;gt;, а также &amp;lt;b&amp;gt;пересчет центров кластеров в d-мерном пространстве&amp;lt;/b&amp;gt;. В шаге &amp;lt;b&amp;gt;распределения d-мерных векторов по &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластерам&amp;lt;/b&amp;gt; расстояния между вектором и центрами кластеров вычисляются независимо (отсутствуют информационные зависимости). &amp;lt;b&amp;gt;Центры масс кластеров&amp;lt;/b&amp;gt; также пересчитываются независимо друг от друга. Таким образом, имеет место [[глоссарий#Массовый параллелизм|&#039;&#039;массовый параллелизм&#039;&#039;]]. Вычислим параллельную сложность &amp;lt;math&amp;gt;\Psi_*&amp;lt;/math&amp;gt; каждого из шагов, а также параллельную сложность всего алгоритма, &amp;lt;math&amp;gt;\Psi_{k-means}&amp;lt;/math&amp;gt;. Будем исходить из предположения, что может быть использовано любое необходимое число потоков.&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Распределение d-мерных векторов по &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластерам&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;  &lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
Поскольку на данном шаге для каждой пары векторов &amp;lt;math&amp;gt;\mathbf{x}_i, i=\overline{1,n}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\mathbf{\mu}_j, j=\overline{1,k}&amp;lt;/math&amp;gt; операции вычисления расстояния не зависят друг от друга, они могут выполняться параллельно. Тогда, разделив все вычисление расстояний на &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; потоков, получим, что в каждом потоке будет выполняться только одна операция вычисления расстояния между векторами размерности d. При этом каждому вычислительному потоку передаются координаты центров всех кластеров &amp;lt;math&amp;gt;\mathbf{\mu}_1, ..., \mathbf{\mu}_k&amp;lt;/math&amp;gt;. Таким образом, параллельная сложность данного шага определяется &amp;lt;i&amp;gt; сложностью параллельной операции вычисления расстояния между d-мерными векторами&amp;lt;/i&amp;gt;, &amp;lt;math&amp;gt;\Psi_{distance}^d&amp;lt;/math&amp;gt;  и &amp;lt;i&amp;gt;сложностью определения наиболее близкого кластера&amp;lt;/i&amp;gt; (паралельное взятие минимума по расстояниям), &amp;lt;math&amp;gt;\Psi_{min}^k&amp;lt;/math&amp;gt;. Для оценки &amp;lt;math&amp;gt;\Psi_{distance}^d&amp;lt;/math&amp;gt; воспользуемся  [[Нахождение_частных_сумм_элементов_массива_сдваиванием | параллельной реализацией нахождения частичной суммы элементов массива путем сдваивания]]. Аналогично, &amp;lt;math&amp;gt;\Psi_{min}^k = log(k)&amp;lt;/math&amp;gt;. В результате, &amp;lt;math&amp;gt;\Psi_{distance}^d = O(log(d))&amp;lt;/math&amp;gt;.   Таким образом: &lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p align=&amp;quot;center&amp;quot;&amp;gt;&amp;lt;math&amp;gt;\Psi_{distribute}^{k, d}  = \Psi_{distance}^d + \Psi_{min}^k = O(log(d))+O(log(k)) = O(log(k*d))&amp;lt;/math&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Пересчет центров кластеров в d-мерном пространстве&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
Поскольку на данном шаге для каждого из &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластеров центр масс может быть вычислен независимо, данные операции могут быть выполнены в отдельных потоках. Таким образом, параллельная сложность данного шага, &amp;lt;math&amp;gt;\Psi_{recenter}^{k, d}&amp;lt;/math&amp;gt;,  будет определяться &amp;lt;i&amp;gt;параллельной сложностью вычисления одного центра масс кластера размера &amp;lt;math&amp;gt;m&amp;lt;/math&amp;gt;&amp;lt;/i&amp;gt;, &amp;lt;math&amp;gt;\Psi_{recenter}^{k, d}&amp;lt;/math&amp;gt;,  а так как &amp;lt;math&amp;gt;m \le n \Rightarrow \Psi_{recenter}^{d, m} \le \Psi_{recenter}^{d, n}&amp;lt;/math&amp;gt;. Сложность вычисления центра масс кластера d-мерных векторов размера n аналогично предыдущим вычислениям равна &amp;lt;math&amp;gt;O(log(n))&amp;lt;/math&amp;gt;. Тогда:  &lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p align=&amp;quot;center&amp;quot;&amp;gt;&amp;lt;math&amp;gt;\Psi_{recenter}^{k, d}  \le \Psi_{recenter}^{d, n} = O(log(n))&amp;lt;/math&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Общая параллельная сложность алгоритма&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
На каждой итерации необходимо обновление центров кластеров, которые будут использованы на следующей итерации. Таким образом, итерационный процесс выполняется последовательно&amp;lt;ref&amp;gt;Zhao, Weizhong, Huifang Ma, and Qing He. &amp;quot;Parallel k-means clustering based on mapreduce.&amp;quot; IEEE International Conference on Cloud Computing. Springer Berlin Heidelberg, 2009.&amp;lt;/ref&amp;gt;. Тогда, поскольку сложность каждой итерации  определяется &amp;lt;math&amp;gt;\Psi_{distribute}^{k, d}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\Psi_{recenter}&amp;lt;/math&amp;gt;, сложность всего алгоритма, &amp;lt;math&amp;gt;\Psi_{k-means}&amp;lt;/math&amp;gt; в предположении, что было сделано &amp;lt;math&amp;gt;\Tau&amp;lt;/math&amp;gt; операций определяется выражением&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p align=&amp;quot;center&amp;quot;&amp;gt;&amp;lt;math&amp;gt;\Psi_{k-means} \approx \Tau * (\Psi_{distribute}^{k, d} + \Psi_{recenter}^{k, d}) \le \Tau * O(log(k*d*n))&amp;lt;/math&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Входные и выходные данные алгоритма ===&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;Входные данные&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;Матрица из &amp;lt;math&amp;gt;n*d&amp;lt;/math&amp;gt; элементов &amp;lt;math&amp;gt;x_{i, j} \in \mathbb{R}, i=\overline{1, n}, j=\overline{1, d}&amp;lt;/math&amp;gt;&amp;amp;ndash; координат векторов (наблюдений).&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;Целое положительное число &amp;lt;math&amp;gt;k, k \le n&amp;lt;/math&amp;gt; &amp;amp;ndash; количество кластеров.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;Объем входных данных&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;math&amp;gt;1&amp;lt;/math&amp;gt; целое число + &amp;lt;math&amp;gt;n*d&amp;lt;/math&amp;gt; вещественных чисел (при условии, что координаты &amp;amp;ndash; вещественные числа).&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;Выходные данные&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; целых положительных чисел &amp;lt;math&amp;gt;L_1, ..., L_n&amp;lt;/math&amp;gt;&amp;amp;ndash; номера кластеров, соотвествующие каждому вектору (при условии, что нумерация кластеров начинается с &amp;lt;math&amp;gt;1&amp;lt;/math&amp;gt;).&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;Объем выходных данных&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; целых положительных чисел.&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Свойства алгоритма ===&lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;[[глоссарий#Вычислительная мощность|&#039;&#039;Вычислительная мощность&#039;&#039;]]&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
Вычислительная мощность алгоритма &amp;lt;i&amp;gt;k means&amp;lt;/i&amp;gt; равна &amp;lt;math&amp;gt;\frac{k*d*n*\Tau}{n*d} = k*\Tau &amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; &amp;amp;ndash; число кластеров, &amp;lt;math&amp;gt;\Tau&amp;lt;/math&amp;gt; &amp;amp;ndash; число итераций алгоритма.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;[[глоссарий#Детерминированность |&#039;&#039;Детерминированность&#039;&#039;]] и [[глоссарий#Устойчивость |&#039;&#039;Устойчивость&#039;&#039;]] &amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
Алгоритм &amp;lt;i&amp;gt;k means&amp;lt;/i&amp;gt; является итерационным. Количество итераций алгоритма в общем случае не фиксируется и зависит от начального расположения объектов в пространстве, параметра &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt;, а также от начального приближения центров кластеров, &amp;lt;math&amp;gt;\mu_1, ..., \mu_k&amp;lt;/math&amp;gt;. В результате этого может варьироваться результат работы алгоритма. При неудачном выборе начальных параметров итерационный процесс может сойтись к локальному оптимуму&amp;lt;ref&amp;gt;Von Luxburg, Ulrike. Clustering Stability. Now Publishers Inc, 2010.&amp;lt;/ref&amp;gt;. По этим причинам алгоритм не является ни &amp;lt;b&amp;gt;детермирированным&amp;lt;/b&amp;gt;, ни &amp;lt;b&amp;gt;устойчивым&amp;lt;/b&amp;gt;.&lt;br /&gt;
 &lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Соотношение последовательной и параллельной сложности алгоритма&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\frac{\Theta_{k-means}}{\Psi_{k-means}} = \frac{O(\Tau*k*d*n)}{O(\Tau*log(k*d*n))}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Сильные стороны алгоритма&amp;lt;/b&amp;gt;:&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;i&amp;gt;Сравнительно высокая эффективность при простоте реализации&amp;lt;/i&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;i&amp;gt;Высокое качество кластеризации&amp;lt;/i&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;i&amp;gt;Возможность распараллеливания&amp;lt;/i&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;i&amp;gt;Существование множества модификаций&amp;lt;/i&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;Недостатки алгоритма&amp;lt;/b&amp;gt;&amp;lt;ref&amp;gt;Ortega, Joaquín Pérez, Ma Del Rocío Boone Rojas, and María J. Somodevilla. &amp;quot;Research issues on K-means Algorithm: An Experimental Trial Using Matlab.&amp;quot;&amp;lt;/ref&amp;gt;:&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;i&amp;gt;Количество кластеров является параметром алгоритма&amp;lt;/i&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;&amp;lt;i&amp;gt;Чувствительность к начальным условиям&amp;lt;/i&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;Инициализация центров кластеров в значительной степени влияет на результат кластеризации.&amp;lt;/p&amp;gt;&lt;br /&gt;
  &amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;&amp;lt;i&amp;gt;Чувствительность к выбросам и шумам&amp;lt;/i&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;Выбросы, далекие от центров настоящих кластеров, все равно учитываются при вычислении их центров.&amp;lt;/p&amp;gt;&lt;br /&gt;
  &amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;&amp;lt;i&amp;gt;Возможность сходимости к локальному оптимуму&amp;lt;/i&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;Итеративный подход не дает гарантии сходимости к оптимальному решению.&amp;lt;/p&amp;gt;&lt;br /&gt;
  &amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;&amp;lt;i&amp;gt;Использование понятия &amp;quot;среднего&amp;quot;&amp;lt;/i&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;Алгоритм неприменим к данным, для которых не определено понятие &amp;quot;среднего&amp;quot;, например, категориальным данным.&amp;lt;/p&amp;gt;&lt;br /&gt;
  &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&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;
Исследование масштабируемости параллельной реализации алгоритма k means проводилось на суперкомпьютере &amp;quot;Ломоносов&amp;quot;&amp;lt;ref name=&amp;quot;Lom&amp;quot;&amp;gt;Воеводин Вл., Жуматий С., Соболев С., Антонов А., Брызгалов П., Никитенко Д., Стефанов К., Воеводин Вад. Практика суперкомпьютера «Ломоносов» // Открытые системы, 2012, N 7, С. 36-39.&amp;lt;/ref&amp;gt; [http://parallel.ru/cluster Суперкомпьютерного комплекса Московского университета]. Алгоритм реализован на языке C с использованием средств MPI.&lt;br /&gt;
Для исследования масштабируемости проводилось множество запусков программы с разным значением параметра (количество векторов для кластеризации), а также с различным числом процессоров. Фиксировались результаты запусков &amp;amp;ndash; время работы &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt; и количество произведенных итераций алгоритма &amp;lt;math&amp;gt;\Tau&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Параметры запусков для экспериментальной оценки:&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;Значения &amp;lt;b&amp;gt;количества векторов&amp;lt;/b&amp;gt; &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;: 20&#039;000, 30&#039;000, 50&#039;000, 100&#039;000, 200&#039;000, 300&#039;000, 500&#039;000, 700&#039;000, 1&#039;000&#039;000, 1&#039;500&#039;000, 2&#039;000&#039;000.&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;Значения &amp;lt;b&amp;gt;количества процессоров&amp;lt;/b&amp;gt; &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt;: 1, 8, 16, 32, 64, 128, 160, 192, 224, 256, 288, 320, 352, 384, 416, 448, 480, 512.&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;Значение &amp;lt;b&amp;gt;количества кластеров&amp;lt;/b&amp;gt; &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt;: 100.&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;Значение &amp;lt;b&amp;gt;размерности векторов&amp;lt;/b&amp;gt; &amp;lt;math&amp;gt;d&amp;lt;/math&amp;gt;: 10.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Для проведения экспериментов были сгенерированы нормально распределенные псевдослучайные данные (с использованием Python библиотеки [http://scikit-learn.org/ scikit-learn]):&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
from sklearn.datasets import make_classification&lt;br /&gt;
X1, Y1 = make_classification(n_features=10, n_redundant=2, n_informative=8,&lt;br /&gt;
                             n_clusters_per_class=1, n_classes=100,&lt;br /&gt;
                             n_samples=2000000)&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Для заданной конфигурации эксперимента (&amp;lt;math&amp;gt;n, d, p, k&amp;lt;/math&amp;gt;) и полученных результатов (&amp;lt;math&amp;gt;t, \Tau&amp;lt;/math&amp;gt;)  [[Глоссарий#Производительность|производительность]]  и эффективность реализации расчитывались по формулам:&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
&amp;lt;ul&amp;gt;&amp;lt;li&amp;gt;&amp;lt;math&amp;gt;Performance = \frac{N_{k-means}^{d, n}}{t}\ \ (FLOPS),&amp;lt;/math&amp;gt;&amp;lt;/li&amp;gt;&amp;lt;/ul&amp;gt;&lt;br /&gt;
где &amp;lt;math&amp;gt;N_{k-means}^{d, n}&amp;lt;/math&amp;gt; &amp;amp;ndash; точное число операций с плавающей точкой (операции с памятью, а также целочисленные операции не учитывались), вычисленное в соответствие с разделом [[#Последовательная сложность алгоритма| &amp;quot;Последовательная сложность алгоритма&amp;quot;]];&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
&amp;lt;ul&amp;gt;&amp;lt;li&amp;gt;&amp;lt;math&amp;gt;Efficiency = \frac{100 * Performance}{Performance_{Peak}^{p}}\ \ (%),&amp;lt;/math&amp;gt;&amp;lt;/li&amp;gt;&amp;lt;/ul&amp;gt;&lt;br /&gt;
где &amp;lt;math&amp;gt;Performance_{Peak}^{p}&amp;lt;/math&amp;gt; &amp;amp;ndash; пиковая производительность суперкомпьютера при &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt; процессорах, вычисленная согласно спецификациям Intel&amp;lt;sup&amp;gt;&amp;amp;reg;&amp;lt;/sup&amp;gt; XEON&amp;lt;sup&amp;gt;&amp;amp;reg;&amp;lt;/sup&amp;gt; X5670&amp;lt;ref&amp;gt;&amp;quot;http://ark.intel.com/ru/products/47920/Intel-Xeon-Processor-X5670-12M-Cache-2_93-GHz-6_40-GTs-Intel-QPI&amp;quot;&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Графики зависимости производительности и эффективности параллельной реализации k means от числа векторов для кластеризации (&amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;) и числа процессоров (&amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt;) представлены на рисунках 4 и 5 соответственно.&lt;br /&gt;
&lt;br /&gt;
[[file:Flops.png|thumb|center|800px|Рис. 4. Параллельная реализация k means. График зависимости производительности реализации алгоритма от числа векторов для кластеризации (&amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;) и числа процессоров (&amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt;).]]&lt;br /&gt;
[[file:Efficiency.png|thumb|center|800px|Рис. 5. Параллельная реализация k means. График зависимости эффективности реализации алгоритма от числа векторов для кластеризации (&amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;) и числа процессоров (&amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt;).]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;В результате&amp;lt;/b&amp;gt; экспериментальной оценки были получены следующие оценки эффективности реализации:&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;b&amp;gt;Минимальное&amp;lt;/b&amp;gt; значение: 0.000409 % достигается при &amp;lt;math&amp;gt;n=20&#039;000, p=480&amp;lt;/math&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;b&amp;gt;Максимальное&amp;lt;/b&amp;gt; значение: 0.741119 % достигается при &amp;lt;math&amp;gt;n=300&#039;000, p=1&amp;lt;/math&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
Оценки масштабируемости реализации алгоритма k means:&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;b&amp;gt;По числу процессоров:&amp;lt;/b&amp;gt; -0.002683 &amp;amp;ndash; эффективность убывает с ростом числа процессоров. Данный результат вызван ростом накладных расходов для обеспечения параллельного выполнения алгоритма.&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;b&amp;gt;По размеру задачи:&amp;lt;/b&amp;gt; 0.002779 &amp;amp;ndash; эффективность растет с ростом числа векторов. Данный результат вызван тем, что при увеличении размера задачи, количество вычислений растет по сравнению с временем, затрачиваемым на пересылку данных.&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;b&amp;gt;Общая оценка:&amp;lt;/b&amp;gt; -0.000058 &amp;amp;ndash; можно сделать вывод, что в целом эффективность реализации незначительно уменьшается с ростом размера задачи и числа процессоров.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[https://github.com/serban/kmeans Использованная параллельная реализация алгоритма k means]&lt;br /&gt;
&lt;br /&gt;
=== Динамические характеристики и эффективность реализации алгоритма ===&lt;br /&gt;
=== Выводы для классов архитектур ===&lt;br /&gt;
=== Существующие реализации алгоритма ===&lt;br /&gt;
==== Открытое программное обеспечение ====&lt;br /&gt;
&amp;lt;ol&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;[https://www.icpsr.umich.edu/CrimeStat/ CrimeStat]&amp;lt;/li&amp;gt; Программное обеспечение, созданное для операционных систем Windows, предоставляющее инструменты статистического  и пространственного анализа для решения задачи картирования преступности.&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://juliastats.github.io Julia]&amp;lt;/li&amp;gt; Высокоуровневый высокопроизводительный свободный язык программирования с динамической типизацией, созданный для математических вычислений, содержит реализацию k-means.&lt;br /&gt;
  &amp;lt;li&amp;gt;[https://mahout.apache.org Mahout]&amp;lt;/li&amp;gt; Apache Mahout - Java библиотека для работы с алгоритмами машинного обучения с использованием MapReduce. Содержит реализацию k-means.&lt;br /&gt;
  &amp;lt;li&amp;gt;[https://www.gnu.org/software/octave/ Octave]&amp;lt;/li&amp;gt; Написанная на C++  свободная система для математических вычислений, использующая совместимый с MATLAB язык высокого уровня, содержит реализацию k-means.&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://spark.apache.org/docs/latest/mllib-clustering.html Spark]&amp;lt;/li&amp;gt; Распределенная реализация k-means содержится в библиотеке Mlib для работы с алгоритмами машинного обучения, взаимодействующая с Python библиотекой NumPy и библиотека R.&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://torch.ch Torch]&amp;lt;/li&amp;gt;  MATLAB-подобная библиотека для языка программирования Lua с открытым исходным кодом, предоставляет большое количество алгоритмов для глубинного обучения и научных расчётов. Ядро написано на Си, прикладная часть выполняется на LuaJIT, поддерживается распараллеливание вычислений средствами CUDA и OpenMP. Существуют реализации k-means.&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://www.cs.waikato.ac.nz/ml/weka/ Weka]&amp;lt;/li&amp;gt;  Cвободное программное обеспечение для анализа данных, написанное на Java. Содержит k-means и x-means.&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://accord-framework.net/docs/html/T_Accord_MachineLearning_KMeans.htm Accord.NET]&amp;lt;/li&amp;gt; C# реализация алгоритмов k-means, k-means++, k-modes.&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://docs.opencv.org/3.0-beta/doc/py_tutorials/py_ml/py_kmeans/py_kmeans_opencv/py_kmeans_opencv.html OpenCV]&amp;lt;/li&amp;gt; Написанная на С++ библиотека, направленная в основном на решение задач компьютерного зрения. Содержит реализацию k-means.&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://mlpack.org/ MLPACK]&amp;lt;/li&amp;gt; Масштабируемая С++ библиотека для работы с алгоритмами машинного обучения, содержит реализацию k-means.&lt;br /&gt;
  &amp;lt;li&amp;gt;[https://www.scipy.org/ SciPy]&amp;lt;/li&amp;gt; Библиотека Python, содержит множество реализаций k-means.&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://scikit-learn.org/ scikit-learn]&amp;lt;/li&amp;gt; Библиотека Python, содержит множество реализаций k-means.&lt;br /&gt;
  &amp;lt;li&amp;gt;[https://www.r-bloggers.com/k-means-clustering-in-r/ R]&amp;lt;/li&amp;gt; Язык программирования для статистической обработки данных и работы с графикой, а также свободная программная среда вычислений с открытым исходным кодом в рамках проекта GNU, содержит три реализации k-means.&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://elki.dbs.ifi.lmu.de ELKI]&amp;lt;/li&amp;gt; Java фреймворк, содержащий реализацию k-means, а также множество других алгоритмов кластеризации.&lt;br /&gt;
&amp;lt;/ol&amp;gt;&lt;br /&gt;
==== Проприетарное программное обеспечение  ====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ol&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;[https://www.ayasdi.com/blog/bigdata/topological-data-analysis-of-oil-and-gas-petrophysical-data/ Ayasdi]&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://www.stata.com/features/cluster-analysis/ Stata]&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://mathworld.wolfram.com/K-MeansClusteringAlgorithm.html Mathematica]&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://www.mathworks.com/help/stats/kmeans.html?requestedDomain=www.mathworks.com MATLAB]&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;[https://support.sas.com/rnd/app/stat/procedures/fastclus.html SAS]&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://docs.rapidminer.com/studio/operators/modeling/segmentation/k_means.html RapidMiner]&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;[https://blogs.sap.com/2013/03/28/sap-hana-pal-k-means-algorithm-or-how-to-do-customer-segmentation-for-the-telecommunications-industry/ SAP HANA]&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ol&amp;gt;&lt;br /&gt;
== Литература ==&lt;br /&gt;
&amp;lt;references /&amp;gt;&lt;/div&gt;</summary>
		<author><name>DennZo1993</name></author>
	</entry>
	<entry>
		<id>https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:%D0%91%D1%80%D0%BE%D1%82%D0%B8%D0%BA%D0%BE%D0%B2%D1%81%D0%BA%D0%B0%D1%8F_%D0%94%D0%B0%D0%BD%D1%83%D1%82%D0%B0/%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_k-means&amp;diff=20522</id>
		<title>Участник:Бротиковская Данута/Алгоритм k-means</title>
		<link rel="alternate" type="text/html" href="https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:%D0%91%D1%80%D0%BE%D1%82%D0%B8%D0%BA%D0%BE%D0%B2%D1%81%D0%BA%D0%B0%D1%8F_%D0%94%D0%B0%D0%BD%D1%83%D1%82%D0%B0/%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_k-means&amp;diff=20522"/>
		<updated>2016-12-10T10:38:18Z</updated>

		<summary type="html">&lt;p&gt;DennZo1993: /* Последовательная сложность алгоритма */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Assignment|Zhum}}&lt;br /&gt;
&lt;br /&gt;
{{algorithm&lt;br /&gt;
| name              = Алгоритм k средних (k means)&lt;br /&gt;
| serial_complexity = &amp;lt;math&amp;gt;O(\Tau*k*d*n)&amp;lt;/math&amp;gt;&lt;br /&gt;
| input_data        = &amp;lt;math&amp;gt; d*n &amp;lt;/math&amp;gt;&lt;br /&gt;
| output_data       = &amp;lt;math&amp;gt; n &amp;lt;/math&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
Авторы страницы &amp;lt;b&amp;gt;[[Участник:Бротиковская Данута|Данута Бротиковская]]&amp;lt;/b&amp;gt; и &amp;lt;b&amp;gt;[[Участник:DennZo1993|Денис Зобнин]]&amp;lt;/b&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
Оба автора внесли одинаковый вклад в написание статьи (поиск материалов, изучение статей, заполнение контента статьи), четких разграничений по пунктам статьи сделать невозможно. &lt;br /&gt;
&lt;br /&gt;
== Свойства и структура алгоритма ==&lt;br /&gt;
&lt;br /&gt;
=== Общее описание алгоритма ===&lt;br /&gt;
Алгоритм &amp;lt;b&amp;gt;&amp;lt;i&amp;gt;k средних&amp;lt;/i&amp;gt;&amp;lt;/b&amp;gt; (&amp;lt;b&amp;gt;&amp;lt;i&amp;gt;k means&amp;lt;/i&amp;gt;&amp;lt;/b&amp;gt;) &amp;amp;ndash; неиерархический&amp;lt;ref&amp;gt;&amp;quot;https://ru.wikipedia.org/wiki/Иерархическая_кластеризация&amp;quot;&amp;lt;/ref&amp;gt;, итерационный метод кластеризации&amp;lt;ref&amp;gt;&amp;quot;https://ru.wikipedia.org/wiki/Кластерный_анализ&amp;quot;&amp;lt;/ref&amp;gt;, получивший большую популярность благодаря своей простоте, наглядности реализации и достаточно высокому качеству работы. Был изобретен в 1950-х годах математиком &amp;lt;i&amp;gt;Гуго Штейнгаузом&amp;lt;/i&amp;gt;&amp;lt;ref&amp;gt;Steinhaus, Hugo. &amp;quot;Sur la division des corp materiels en parties.&amp;quot; Bull. Acad. Polon. Sci 1.804 (1956): 801.&amp;lt;/ref&amp;gt; и почти одновременно &amp;lt;i&amp;gt;Стюартом Ллойдом&amp;lt;/i&amp;gt;&amp;lt;ref&amp;gt;Lloyd, S. P. &amp;quot;Least square quantization in PCM. Bell Telephone Laboratories Paper. Published in journal much later: Lloyd, SP: Least squares quantization in PCM.&amp;quot; IEEE Trans. Inform. Theor.(1957/1982).&amp;lt;/ref&amp;gt;. Особую популярность приобрел после публикации работы &amp;lt;i&amp;gt;МакКуина&amp;lt;/i&amp;gt;&amp;lt;ref&amp;gt;MacQueen, James. &amp;quot;Some methods for classification and analysis of multivariate observations.&amp;quot; Proceedings of the fifth Berkeley symposium on mathematical statistics and probability. Vol. 1. No. 14. 1967.&amp;lt;/ref&amp;gt; в 1967.&lt;br /&gt;
&lt;br /&gt;
Алгоритм представляет собой версию EM-алгоритма&amp;lt;ref&amp;gt;&amp;quot;https://ru.wikipedia.org/wiki/EM-алгоритм&amp;quot;&amp;lt;/ref&amp;gt;, применяемого также для разделения смеси гауссиан. Основная идея &amp;lt;i&amp;gt;k means&amp;lt;/i&amp;gt; заключается в том, что данные произвольно разбиваются на кластеры, после чего итеративно перевычисляется центр масс для каждого кластера, полученного на предыдущем шаге, затем векторы разбиваются на кластеры вновь в соответствии с тем, какой из новых центров оказался ближе по выбранной метрике.&lt;br /&gt;
&lt;br /&gt;
Цель алгоритма заключается в разделении &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; наблюдений на &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластеров таким образом, чтобы каждое наблюдение принадлежало ровно одному кластеру, расположенному на наименьшем расстоянии от наблюдения.&lt;br /&gt;
&lt;br /&gt;
=== Математическое описание алгоритма ===&lt;br /&gt;
&amp;lt;b&amp;gt;&amp;lt;u&amp;gt;Дано:&amp;lt;/u&amp;gt;&amp;lt;/b&amp;gt;&lt;br /&gt;
* набор из &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; наблюдений &amp;lt;math&amp;gt;X=\{\mathbf{x}_1, \mathbf{x}_2, ..., \mathbf{x}_n\}, \mathbf{x}_i \in \mathbb{R}^d, i=\overline{1, n}&amp;lt;/math&amp;gt;;&lt;br /&gt;
* &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; - требуемое число кластеров, &amp;lt;math&amp;gt;k \in \mathbb{N}, k \leq n&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;&amp;lt;u&amp;gt;Требуется:&amp;lt;/u&amp;gt;&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Разделить множество наблюдений &amp;lt;math&amp;gt;X&amp;lt;/math&amp;gt; на &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластеров &amp;lt;math&amp;gt;S_1, S_2, ..., S_k&amp;lt;/math&amp;gt;:&lt;br /&gt;
*   &amp;lt;math&amp;gt;S_i \cap S_j= \varnothing, \quad i \ne j&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
*   &amp;lt;math&amp;gt;\bigcup_{i=1}^{k} S_i = X&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;&amp;lt;u&amp;gt;Действие алгоритма:&amp;lt;/u&amp;gt;&amp;lt;/b&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;Алгоритм &amp;lt;i&amp;gt;k means&amp;lt;/i&amp;gt; разбивает набор &amp;lt;math&amp;gt;X&amp;lt;/math&amp;gt; на &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; наборов &amp;lt;math&amp;gt;S_1, S_2, ..., S_k,&amp;lt;/math&amp;gt; таким образом, чтобы минимизировать сумму квадратов расстояний от каждой точки кластера до его центра (центр масс кластера). Введем обозначение, &amp;lt;math&amp;gt;S=\{S_1, S_2, ..., S_k\}&amp;lt;/math&amp;gt;. Тогда действие алгоритма &amp;lt;i&amp;gt;k means&amp;lt;/i&amp;gt; равносильно поиску:&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;table style=&amp;quot;width:100%&amp;quot;&amp;gt;&lt;br /&gt;
  &amp;lt;tr&amp;gt;&lt;br /&gt;
    &amp;lt;td align=&amp;quot;center&amp;quot; width=&amp;quot;90%&amp;quot;&amp;gt;&amp;lt;math&amp;gt;\arg\min_{S} \sum\limits_{i=1}^k \sum\limits_{\mathbf{x} \in S_i} \rho(\mathbf{x}, \mathbf{\mu}_i )^2,&amp;lt;/math&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;td align=&amp;quot;right&amp;quot;&amp;gt;&amp;lt;math&amp;gt;(1)&amp;lt;/math&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;/table&amp;gt;&lt;br /&gt;
где &amp;lt;math&amp;gt;\mathbf{\mu}_i&amp;lt;/math&amp;gt; &amp;amp;ndash; центры кластеров, &amp;lt;math&amp;gt;i=\overline{1,k}, \quad \rho(\mathbf{x}, \mathbf{\mu}_i)&amp;lt;/math&amp;gt; &amp;amp;ndash; функция расстояния между &amp;lt;math&amp;gt;\mathbf{x}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\mu_i&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;&amp;lt;u&amp;gt;Шаги алгоритма: &amp;lt;/u&amp;gt;&amp;lt;/b&amp;gt;&lt;br /&gt;
&amp;lt;ol&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&lt;br /&gt;
    &amp;lt;b&amp;gt;Начальный шаг: инициализация кластеров&amp;lt;/b&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;Выбирается произвольное множество точек &amp;lt;math&amp;gt;\mu_i, i=\overline{1,k}&amp;lt;/math&amp;gt;, рассматриваемых как начальные центры кластеров: &amp;lt;math&amp;gt;\mu_i^{(0)} = \mu_i, \quad i=\overline{1, k}&amp;lt;/math&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
  &amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&lt;br /&gt;
    &amp;lt;b&amp;gt;Распределение векторов по кластерам&amp;lt;/b&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Шаг&amp;lt;/b&amp;gt; &amp;lt;math&amp;gt;t: \forall \mathbf{x}_i \in X, i=\overline{1,n}: \mathbf{x}_i \in S_j \iff  j=\arg\min_{k}\rho(\mathbf{x}_i,\mathbf{\mu}_k^{(t-1)})^2&amp;lt;/math&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
  &amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&lt;br /&gt;
    &amp;lt;b&amp;gt;Пересчет центров кластеров&amp;lt;/b&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Шаг &amp;lt;/b&amp;gt; &amp;lt;math&amp;gt;t: \forall i=\overline{1,k}:  \mu_i^{(t)} = \cfrac{1}{|S_i|}\sum_{\mathbf{x}\in S_i}\mathbf{x}&amp;lt;/math&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
  &amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&lt;br /&gt;
    &amp;lt;b&amp;gt;Проверка условия останова:&amp;lt;/b&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
    &#039;&#039;&#039;if&#039;&#039;&#039; &amp;lt;math&amp;gt;\exist i\in \overline{1,k}: \mu_i^{(t)} \ne \mu_i^{(t-1)}&amp;lt;/math&amp;gt; &#039;&#039;&#039;then&#039;&#039;&#039;&lt;br /&gt;
        t = t + 1;&lt;br /&gt;
        goto 2;&lt;br /&gt;
    &#039;&#039;&#039;else&#039;&#039;&#039;&lt;br /&gt;
        &#039;&#039;&#039;stop&#039;&#039;&#039;&lt;br /&gt;
  &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ol&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Вычислительное ядро алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Вычислительным ядром являются шаги 2 и 3 приведенного выше алгоритма: &amp;lt;b&amp;gt;&amp;lt;i&amp;gt;распределение векторов по кластерам&amp;lt;/i&amp;gt;&amp;lt;/b&amp;gt; и &amp;lt;b&amp;gt;&amp;lt;i&amp;gt;пересчет центров кластеров&amp;lt;/i&amp;gt;&amp;lt;/b&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;&amp;lt;i&amp;gt;Распределение векторов&amp;lt;/i&amp;gt;&amp;lt;/b&amp;gt; по кластерам предполагает вычисление расстояний между каждым вектором &amp;lt;math&amp;gt;\mathbf{x}_i \in X, i= \overline{1,n}&amp;lt;/math&amp;gt; и центрами кластера &amp;lt;math&amp;gt;\mathbf{\mu}_j, j= \overline{1,k}&amp;lt;/math&amp;gt;. Таким образом, данный шаг предполагает &amp;lt;math&amp;gt;kn&amp;lt;/math&amp;gt; вычислений расстояний между d-мерными векторами. &lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;&amp;lt;i&amp;gt;Пересчет центров кластеров&amp;lt;/i&amp;gt;&amp;lt;/b&amp;gt; предполагает &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; вычислений центров масс &amp;lt;math&amp;gt;\mathbf{\mu}_i&amp;lt;/math&amp;gt; множеств &amp;lt;math&amp;gt;S_i, i=\overline{1,k}&amp;lt;/math&amp;gt; представленных выражением в шаге 3 представленного выше алгоритма.&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Макроструктура алгоритма ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Инициализация центров масс &amp;lt;math&amp;gt;\mu_1, ..., \mu_k&amp;lt;/math&amp;gt;&amp;lt;/b&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
Наиболее распространенными являются следующие стратегии:&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&lt;br /&gt;
    &amp;lt;b&amp;gt;Метод Forgy&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;В качестве начальных значений &amp;lt;math&amp;gt;\mu_1, ..., \mu_k&amp;lt;/math&amp;gt; берутся случайно выбранные векторы.&lt;br /&gt;
  &amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&lt;br /&gt;
    &amp;lt;b&amp;gt;Метод случайно разделения (Random Partitioning)&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;Для каждого вектора &amp;lt;math&amp;gt;\mathbf{x}_i \in X, i=\overline{1, n}&amp;lt;/math&amp;gt; выбирается случайным образом кластер &amp;lt;math&amp;gt;S_1, ..., S_k&amp;lt;/math&amp;gt;, после чего для каждого полученного кластера вычисляются значения &amp;lt;math&amp;gt;\mu_1, ..., \mu_k&amp;lt;/math&amp;gt;.&lt;br /&gt;
  &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Распределение векторов по кластерам&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Для этого шага алгоритма между векторами &amp;lt;math&amp;gt;\mathbf{x}_i \in X, i=\overline{1, n}&amp;lt;/math&amp;gt; и центрами кластеров &amp;lt;math&amp;gt;\mu_1, ..., \mu_k&amp;lt;/math&amp;gt; вычисляются &amp;lt;b&amp;gt;расстояния&amp;lt;/b&amp;gt; по формуле (как правило, используется Евлидово расстояние):&lt;br /&gt;
&amp;lt;table style=&amp;quot;width:100%&amp;quot;&amp;gt;&lt;br /&gt;
  &amp;lt;tr&amp;gt;&lt;br /&gt;
    &amp;lt;td align=&amp;quot;center&amp;quot; width=&amp;quot;90%&amp;quot;&amp;gt;&amp;lt;math&amp;gt; \mathbf{v}_1, \mathbf{v}_2 \in \mathbb{R}^d,  \quad \rho(\mathbf{v}_1, \mathbf{v}_2) = \lVert \mathbf{v}_1- \mathbf{v}_2 \rVert= \sqrt{\sum_{i=1}^{d}(\mathbf{v}_{1,i} - \mathbf{v}_{2,i})^2}&amp;lt;/math&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;td align=&amp;quot;right&amp;quot;&amp;gt;&amp;lt;math&amp;gt;(2)&amp;lt;/math&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;/table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Пересчет центров кластеров&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Для этого шага алгоритма производится пересчет центров кластера по &amp;lt;b&amp;gt;формуле вычисления центра масс&amp;lt;/b&amp;gt;:&lt;br /&gt;
&amp;lt;table style=&amp;quot;width:100%&amp;quot;&amp;gt;&lt;br /&gt;
  &amp;lt;tr&amp;gt;&lt;br /&gt;
    &amp;lt;td align=&amp;quot;center&amp;quot; width=&amp;quot;90%&amp;quot;&amp;gt;&amp;lt;math&amp;gt; \mu = \cfrac{1}{|S|}\sum_{\mathbf{x}\in S}\mathbf{x}&amp;lt;/math&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;td align=&amp;quot;right&amp;quot;&amp;gt;&amp;lt;math&amp;gt;(3)&amp;lt;/math&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;/table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Схема реализации последовательного алгоритма ===&lt;br /&gt;
&lt;br /&gt;
 &#039;&#039;&#039;algorithm&#039;&#039;&#039; k-means &#039;&#039;&#039;is&#039;&#039;&#039;&lt;br /&gt;
     &#039;&#039;&#039;1.&#039;&#039;&#039; Инициализировать центры кластеров &amp;lt;math&amp;gt;\mathbf{\mu}_i^{(1)}, i=\overline{1,k}&amp;lt;/math&amp;gt;&lt;br /&gt;
     &#039;&#039;&#039;2.&#039;&#039;&#039; &amp;lt;math&amp;gt;t \leftarrow 1&amp;lt;/math&amp;gt;&lt;br /&gt;
     &#039;&#039;&#039;3.&#039;&#039;&#039; &#039;&#039;&#039;Распределение по кластерам&#039;&#039;&#039;&amp;lt;br&amp;gt;&lt;br /&gt;
        &amp;lt;math&amp;gt;S_i^{(t)}=\{\mathbf{x}_p: \lVert\mathbf{x}_p-\mathbf{\mu}_i^{(t)}\rVert^2 \leq \lVert\mathbf{x}_p-\mathbf{\mu}_j^{(t)}\rVert^2 \quad \forall j=\overline{1,k}\},&amp;lt;/math&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
        где каждый вектор &amp;lt;math&amp;gt;\mathbf{x}_p&amp;lt;/math&amp;gt; соотносится единственному кластеру &amp;lt;math&amp;gt;S^{(t)}&amp;lt;/math&amp;gt;&lt;br /&gt;
     &#039;&#039;&#039;4.&#039;&#039;&#039; &#039;&#039;&#039;Обновление центров кластеров&#039;&#039;&#039;&amp;lt;br&amp;gt;&lt;br /&gt;
        &amp;lt;math&amp;gt;\mathbf{\mu}_i^{(t+1)} = \frac{1}{|S^{(t)}_i|} \sum_{\mathbf{x}_j \in S^{(t)}_i} \mathbf{x}_j &amp;lt;/math&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
     &#039;&#039;&#039;5.&#039;&#039;&#039; &#039;&#039;&#039;if&#039;&#039;&#039; &amp;lt;math&amp;gt;\exist i \in \overline{1,k}: \mathbf{\mu}_i^{(t+1)} \ne \mathbf{\mu}_i^{(t)}&amp;lt;/math&amp;gt; &#039;&#039;&#039;then&#039;&#039;&#039;&lt;br /&gt;
            t = t + 1;&lt;br /&gt;
            goto &#039;&#039;&#039;3&#039;&#039;&#039;;&lt;br /&gt;
        &#039;&#039;&#039;else&#039;&#039;&#039;&lt;br /&gt;
            &#039;&#039;&#039;stop&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
=== Последовательная сложность алгоритма===&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding-bottom: 20px&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;Обозначим &amp;lt;math&amp;gt;\Theta_{centroid}^{d, m}&amp;lt;/math&amp;gt; временную сложность вычисления центорида кластера, число элементов которого равна &amp;lt;math&amp;gt;m&amp;lt;/math&amp;gt;,  в d-мерном пространстве.&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;Аналогично  &amp;lt;math&amp;gt;\Theta_{distance}^d&amp;lt;/math&amp;gt; &amp;amp;ndash; временная сложность вычисления расстояния между двумя d-мерными векторами.&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding-bottom: 20px&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;Сложность шага инициализации &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластеров мощности &amp;lt;math&amp;gt;m&amp;lt;/math&amp;gt; в d-мерном пространстве &amp;amp;ndash; &amp;lt;math&amp;gt;\Theta_{init}^{k, d, m}&amp;lt;/math&amp;gt;&amp;lt;/b&amp;gt;&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;i&amp;gt;Стратерия Forgy&amp;lt;/i&amp;gt;: вычисления не требуются, &amp;lt;math&amp;gt;\Theta_{init}^{k, d, m} = 0&amp;lt;/math&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;i&amp;gt;Стратегия случайного разбиения&amp;lt;/i&amp;gt;: вычисление центров &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластеров,  &amp;lt;math&amp;gt;\Theta_{init}^{k, d, m} = k \cdot \Theta_{centroid}^{d, m}, m \le n&amp;lt;/math&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding-bottom: 20px&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Cложность шага распределения d мерных векторов по &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластерам &amp;amp;ndash; &amp;lt;math&amp;gt;\Theta_{distribute}^{k, d}&amp;lt;/math&amp;gt;&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
На этом шаге для каждого вектора &amp;lt;math&amp;gt;\mathbf{x}_i \in X, i=\overline{1, n}&amp;lt;/math&amp;gt; вычисляется k расстояний до центров кластеров &amp;lt;math&amp;gt;\mathbf{\mu}_1, ...\mathbf{\mu}_k&amp;lt;/math&amp;gt;&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p align=&amp;quot;center&amp;quot;&amp;gt;&lt;br /&gt;
  &amp;lt;math&amp;gt;\Theta_{distribute}^{k, d} = n \cdot k \cdot \Theta_{distance}^d&amp;lt;/math&amp;gt;&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding-bottom: 20px&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;Сложность шага пересчета центров &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластеров размера &amp;lt;math&amp;gt;m&amp;lt;/math&amp;gt; в d-мерном пространстве &amp;amp;ndash; &amp;lt;math&amp;gt;\Theta_{recenter}^{k, d, m}&amp;lt;/math&amp;gt;&amp;lt;/b&amp;gt;&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;На этом шаге вычисляется &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; центров кластеров &amp;lt;math&amp;gt;\mathbf{\mu}_1, ...\mathbf{\mu}_k&amp;lt;/math&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p align=&amp;quot;center&amp;quot;&amp;gt;&amp;lt;math&amp;gt;\Theta_{recenter}^{k, d, m} = k \cdot \Theta_{centroid}^{d, m}&amp;lt;/math&amp;gt; &amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding-bottom: 20px&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Рассчитаем &amp;lt;math&amp;gt;\Theta_{centroid}^{d, m}&amp;lt;/math&amp;gt; для кластера, число элементов которого равно &amp;lt;math&amp;gt;m&amp;lt;/math&amp;gt;&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p align=&amp;quot;center&amp;quot;&amp;gt;&amp;lt;math&amp;gt;\Theta_{centroid}^{d, m}&amp;lt;/math&amp;gt; = &amp;lt;math&amp;gt;m \cdot d&amp;lt;/math&amp;gt; сложений + &amp;lt;math&amp;gt;d&amp;lt;/math&amp;gt; делений &amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding-bottom: 20px&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Рассчитаем &amp;lt;math&amp;gt;\Theta_{distance}^d&amp;lt;/math&amp;gt; в соответствие с формулой &amp;lt;math&amp;gt;(2)&amp;lt;/math&amp;gt;&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p align=&amp;quot;center&amp;quot;&amp;gt;&amp;lt;math&amp;gt;\Theta_{distance}^d&amp;lt;/math&amp;gt; = &amp;lt;math&amp;gt;d&amp;lt;/math&amp;gt; вычитаний + &amp;lt;math&amp;gt;d&amp;lt;/math&amp;gt; умножений + &amp;lt;math&amp;gt;(d-1)&amp;lt;/math&amp;gt; сложение&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding-bottom: 20px&amp;quot;&amp;gt;&lt;br /&gt;
  &amp;lt;p&amp;gt;Предположим, что алгоритм сошелся за &amp;lt;math&amp;gt;\Tau&amp;lt;/math&amp;gt; итераций, тогда временная сложность алгоритма &amp;lt;math&amp;gt;\Theta_{k-means}^{d, n}&amp;lt;/math&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
  &amp;lt;p align=&amp;quot;center&amp;quot;&amp;gt;&amp;lt;b&amp;gt;&amp;lt;math&amp;gt;\Theta_{k-means}^{d, n} \le \Theta_{init}^{k, d, n} + \Tau(\Theta_{distribute}^{k, d} + \Theta_{recenter}^{k, d, n})&amp;lt;/math&amp;gt;&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding-bottom: 5px&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;Операции сложения/вычитания:&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p align=&amp;quot;center&amp;quot;&amp;gt;&amp;lt;b&amp;gt;&amp;lt;math&amp;gt;\Theta_{k-means}^{d, n} \le k \cdot n \cdot d+ \Tau \cdot (k \cdot n(2d-1) + k \cdot n \cdot d) = k \cdot n \cdot d+ \Tau \cdot (k \cdot n(3d-1)) \thicksim O(\Tau k \cdot d \cdot n)&amp;lt;/math&amp;gt;&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding-bottom: 20px&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;Операции умножения/деления:&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p align=&amp;quot;center&amp;quot;&amp;gt;&amp;lt;b&amp;gt;&amp;lt;math&amp;gt;\Theta_{k-means}^{d, n} \le k \cdot d + \Tau \cdot (k \cdot n \cdot d + k \cdot d) = k \cdot d + \Tau \cdot k \cdot d \cdot (n+1) \thicksim O(\Tau \cdot k \cdot d \cdot n) &amp;lt;/math&amp;gt;&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding-bottom: 20px&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;Получаем, что &amp;lt;b&amp;gt;временная сложность&amp;lt;/b&amp;gt; алгоритма &amp;lt;b&amp;gt;k means&amp;lt;/b&amp;gt; кластеризации &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; &amp;lt;b&amp;gt;d-мерных&amp;lt;/b&amp;gt; векторов на &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластеров за &amp;lt;math&amp;gt;\Tau&amp;lt;/math&amp;gt; итераций:&amp;lt;/p&amp;gt;&lt;br /&gt;
 &amp;lt;p align=&amp;quot;center&amp;quot;&amp;gt;&amp;lt;b&amp;gt;&amp;lt;math&amp;gt; \Theta_{k-means}^{d, n} \thicksim O(\Tau \cdot k \cdot d \cdot n) &amp;lt;/math&amp;gt;&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Информационный граф ===&lt;br /&gt;
&lt;br /&gt;
Рассмотрим информационный граф алгоритма. Алгоритм &amp;lt;i&amp;gt;k means&amp;lt;/i&amp;gt; начинается с этапа инициализации, после которого следуют итерации, на каждой из которых выполняется два последовательных шага (см. [[#Схема реализации последовательного алгоритма|&amp;quot;Схема реализации последовательного алгоритма&amp;quot;]]): &lt;br /&gt;
* распределение векторов по кластерам&lt;br /&gt;
* перерасчет центров кластеров&lt;br /&gt;
&lt;br /&gt;
Поскольку основная часть вычислений приходится на шаги итераций, распишем информационные графы данных шагов.&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Распределение векторов по кластерам&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
Информационный граф шага распределения векторов по кластерам представлен на &#039;&#039;рисунке 1&#039;&#039;. Исходами данного графа является исходные векторы &amp;lt;math&amp;gt;\mathbf{x}_1, ..., \mathbf{x}_n&amp;lt;/math&amp;gt;, а также центры кластеров &amp;lt;math&amp;gt;\mathbf{\mu}_1, ... \mathbf{\mu}_k&amp;lt;/math&amp;gt;, вычисленные ранее (на шаге инициализации, если рассматривается первая итерация алгоритма, или на шаге пересчета центров кластеров предыдущей итерации в противном случае). Каждая пара векторов данных &amp;lt;math&amp;gt;\mathbf{x}_i, i=\overline{1,n}&amp;lt;/math&amp;gt; и центров кластера &amp;lt;math&amp;gt;\mathbf{\mu}_j, j=\overline{1, k}&amp;lt;/math&amp;gt; : (&amp;lt;math&amp;gt;\mathbf{x}_i&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;\mathbf{\mu}_j&amp;lt;/math&amp;gt;) подаются на независимые узлы &amp;lt;i&amp;gt;&amp;quot;d&amp;quot;&amp;lt;/i&amp;gt; вычисления расстояния между векторами (более подробная схема вычисления расстояния представлена далее, &#039;&#039;рисунок 2&#039;&#039;). Далее узлы вычисления расстояния &amp;lt;i&amp;gt;&amp;quot;d&amp;quot;&amp;lt;/i&amp;gt;, соответствующие одному и тому же исходному вектору &amp;lt;math&amp;gt;\mathbf{x}_i&amp;lt;/math&amp;gt; передаются на один узел &amp;lt;i&amp;gt;&amp;quot;m&amp;quot;&amp;lt;/i&amp;gt;, где далее происходит вычисление новой метки кластера для каждого вектора &amp;lt;math&amp;gt;\mathbf{x}_i&amp;lt;/math&amp;gt; (берется кластер с минимальным результатом вычисления расстояния). На выходе графа выдаются метки кластеров , &amp;lt;math&amp;gt;L_1, ..., L_n&amp;lt;/math&amp;gt;, такие что &amp;lt;math&amp;gt;\forall \mathbf{x}_i, i=\overline{1, n}, \mathbf{x}_i \in S_j \Leftrightarrow L_i = j&amp;lt;/math&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
[[file:Clusterization.png|thumb|center|800px|Рис. 1. Схема распределения векторов по кластерам. &#039;&#039;d&#039;&#039; &amp;amp;ndash; вычисление расстояния между векторами; &#039;&#039;m&#039;&#039; &amp;amp;ndash; вычисление минимума.]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Вычисление расстояния между векторами&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
Подробная схема вычисления расстояния между векторами &amp;lt;math&amp;gt;\mathbf{x}_i, \mathbf{\mu}_j&amp;lt;/math&amp;gt; представлена на &#039;&#039;рисунке 2&#039;&#039;. Как показано на графе, узел вычисления расстояния между векторами &amp;lt;i&amp;gt;&amp;quot;d&amp;quot;&amp;lt;/i&amp;gt; состоит из шага взятия разности между векторами (узел &amp;quot;&amp;lt;math&amp;gt;-&amp;lt;/math&amp;gt;&amp;quot;) и взятия нормы получившегося вектора разности (узел &amp;quot;&amp;lt;math&amp;gt;||\cdot||^2&amp;lt;/math&amp;gt;&amp;quot;). Более подробно, вычисление расстояния между векторами &amp;lt;math&amp;gt;\mathbf{x}_i = {x_{i1,}, ...,{x_{in}}}, \mathbf{\mu}_j = {\mu_{j1}, ...,\mu_{jn}}&amp;lt;/math&amp;gt; может быть представлено как вычисление разности между каждой парой компонент &amp;lt;math&amp;gt;(x_{iz}, \mu_{jz}), z=\overline{1, d}&amp;lt;/math&amp;gt; (узел &amp;quot;&amp;lt;math&amp;gt;-&amp;lt;/math&amp;gt;&amp;quot;), далее возведение в квадрат для каждого узла &amp;quot;&amp;lt;math&amp;gt;-&amp;lt;/math&amp;gt;&amp;quot; (узел &amp;quot;&amp;lt;math&amp;gt;()^2&amp;lt;/math&amp;gt;&amp;quot;) и суммирования выходов всех узлов &amp;quot;&amp;lt;math&amp;gt;()^2&amp;lt;/math&amp;gt;&amp;quot; (узел &amp;quot;&amp;lt;math&amp;gt;+&amp;lt;/math&amp;gt;&amp;quot;).  &lt;br /&gt;
&lt;br /&gt;
[[file:dist_calc.png|thumb|center|800px|Рис. 2. Схема вычисления расстояния между вектором и центром кластера.]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Пересчет центров кластеров&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
Информационный граф шага пересчета центров кластеров представлен на &#039;&#039;рисунке 3&#039;&#039;. Исходами данного графа является исходные векторы &amp;lt;math&amp;gt;\mathbf{x}_1, ..., \mathbf{x}_n&amp;lt;/math&amp;gt;, а также им соответствующие метки кластера, &amp;lt;math&amp;gt;L_1, ..., L_n&amp;lt;/math&amp;gt;, такие что &amp;lt;math&amp;gt;\forall x_i, i=\overline{1, n}, \mathbf{x}_i \in S_j \Leftrightarrow L_i = j&amp;lt;/math&amp;gt;, вычисленные на этапе распределения векторов по кластерам. Все векторы &amp;lt;math&amp;gt;\mathbf{x}_1, ..., \mathbf{x}_n&amp;lt;/math&amp;gt; подаются в узлы &amp;lt;math&amp;gt;+_1, ...+_k&amp;lt;/math&amp;gt;, каждый узел &amp;lt;math&amp;gt;+_m, m = \overline{1,k}&amp;lt;/math&amp;gt; соответствует операции сложения векторов кластера с номером &amp;lt;math&amp;gt;m&amp;lt;/math&amp;gt;. Метки кластера &amp;lt;math&amp;gt;L_1, ..., L_n&amp;lt;/math&amp;gt; также совместно передаются на узлы &amp;lt;math&amp;gt;S_m, m = \overline{1,k}&amp;lt;/math&amp;gt;, на каждом из которых вычисляется количество векторов в соответствующем кластере (количество меток с соответствующим значением). Далее каждая пара выходов узлов &amp;lt;math&amp;gt;+_m&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;S_m&amp;lt;/math&amp;gt; подается на узел &amp;quot;&amp;lt;math&amp;gt;/&amp;lt;/math&amp;gt;&amp;quot;, где производится деление суммы векторов кластера на количество элементов в нем. Значения, вычисленные на узлах &amp;quot;&amp;lt;math&amp;gt;/&amp;lt;/math&amp;gt;&amp;quot;, присваиваются новым центрам кластеров (выходные значения графа).&lt;br /&gt;
&lt;br /&gt;
[[file:Recluster.png|thumb|center|800px|Рис. 3. Схема пересчета центров кластеров]]&lt;br /&gt;
&lt;br /&gt;
=== Ресурс параллелизма алгоритма ===&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
Работа алгоритма состоит из &amp;lt;math&amp;gt;\Tau&amp;lt;/math&amp;gt; итераций, в каждой из которых происходит &amp;lt;b&amp;gt;распределение d-мерных векторов по &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластерам&amp;lt;/b&amp;gt;, а также &amp;lt;b&amp;gt;пересчет центров кластеров в d-мерном пространстве&amp;lt;/b&amp;gt;. В шаге &amp;lt;b&amp;gt;распределения d-мерных векторов по &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластерам&amp;lt;/b&amp;gt; расстояния между вектором и центрами кластеров вычисляются независимо (отсутствуют информационные зависимости). &amp;lt;b&amp;gt;Центры масс кластеров&amp;lt;/b&amp;gt; также пересчитываются независимо друг от друга. Таким образом, имеет место [[глоссарий#Массовый параллелизм|&#039;&#039;массовый параллелизм&#039;&#039;]]. Вычислим параллельную сложность &amp;lt;math&amp;gt;\Psi_*&amp;lt;/math&amp;gt; каждого из шагов, а также параллельную сложность всего алгоритма, &amp;lt;math&amp;gt;\Psi_{k-means}&amp;lt;/math&amp;gt;. Будем исходить из предположения, что может быть использовано любое необходимое число потоков.&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Распределение d-мерных векторов по &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластерам&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;  &lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
Поскольку на данном шаге для каждой пары векторов &amp;lt;math&amp;gt;\mathbf{x}_i, i=\overline{1,n}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\mathbf{\mu}_j, j=\overline{1,k}&amp;lt;/math&amp;gt; операции вычисления расстояния не зависят друг от друга, они могут выполняться параллельно. Тогда, разделив все вычисление расстояний на &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; потоков, получим, что в каждом потоке будет выполняться только одна операция вычисления расстояния между векторами размерности d. При этом каждому вычислительному потоку передаются координаты центров всех кластеров &amp;lt;math&amp;gt;\mathbf{\mu}_1, ..., \mathbf{\mu}_k&amp;lt;/math&amp;gt;. Таким образом, параллельная сложность данного шага определяется &amp;lt;i&amp;gt; сложностью параллельной операции вычисления расстояния между d-мерными векторами&amp;lt;/i&amp;gt;, &amp;lt;math&amp;gt;\Psi_{distance}^d&amp;lt;/math&amp;gt;  и &amp;lt;i&amp;gt;сложностью определения наиболее близкого кластера&amp;lt;/i&amp;gt; (паралельное взятие минимума по расстояниям), &amp;lt;math&amp;gt;\Psi_{min}^k&amp;lt;/math&amp;gt;. Для оценки &amp;lt;math&amp;gt;\Psi_{distance}^d&amp;lt;/math&amp;gt; воспользуемся  [[Нахождение_частных_сумм_элементов_массива_сдваиванием | параллельной реализацией нахождения частичной суммы элементов массива путем сдваивания]]. Аналогично, &amp;lt;math&amp;gt;\Psi_{min}^k = log(k)&amp;lt;/math&amp;gt;. В результате, &amp;lt;math&amp;gt;\Psi_{distance}^d = O(log(d))&amp;lt;/math&amp;gt;.   Таким образом: &lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p align=&amp;quot;center&amp;quot;&amp;gt;&amp;lt;math&amp;gt;\Psi_{distribute}^{k, d}  = \Psi_{distance}^d + \Psi_{min}^k = O(log(d))+O(log(k)) = O(log(k*d))&amp;lt;/math&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Пересчет центров кластеров в d-мерном пространстве&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
Поскольку на данном шаге для каждого из &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластеров центр масс может быть вычислен независимо, данные операции могут быть выполнены в отдельных потоках. Таким образом, параллельная сложность данного шага, &amp;lt;math&amp;gt;\Psi_{recenter}^{k, d}&amp;lt;/math&amp;gt;,  будет определяться &amp;lt;i&amp;gt;параллельной сложностью вычисления одного центра масс кластера размера &amp;lt;math&amp;gt;m&amp;lt;/math&amp;gt;&amp;lt;/i&amp;gt;, &amp;lt;math&amp;gt;\Psi_{recenter}^{k, d}&amp;lt;/math&amp;gt;,  а так как &amp;lt;math&amp;gt;m \le n \Rightarrow \Psi_{recenter}^{d, m} \le \Psi_{recenter}^{d, n}&amp;lt;/math&amp;gt;. Сложность вычисления центра масс кластера d-мерных векторов размера n аналогично предыдущим вычислениям равна &amp;lt;math&amp;gt;O(log(n))&amp;lt;/math&amp;gt;. Тогда:  &lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p align=&amp;quot;center&amp;quot;&amp;gt;&amp;lt;math&amp;gt;\Psi_{recenter}^{k, d}  \le \Psi_{recenter}^{d, n} = O(log(n))&amp;lt;/math&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Общая параллельная сложность алгоритма&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
На каждой итерации необходимо обновление центров кластеров, которые будут использованы на следующей итерации. Таким образом, итерационный процесс выполняется последовательно&amp;lt;ref&amp;gt;Zhao, Weizhong, Huifang Ma, and Qing He. &amp;quot;Parallel k-means clustering based on mapreduce.&amp;quot; IEEE International Conference on Cloud Computing. Springer Berlin Heidelberg, 2009.&amp;lt;/ref&amp;gt;. Тогда, поскольку сложность каждой итерации  определяется &amp;lt;math&amp;gt;\Psi_{distribute}^{k, d}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\Psi_{recenter}&amp;lt;/math&amp;gt;, сложность всего алгоритма, &amp;lt;math&amp;gt;\Psi_{k-means}&amp;lt;/math&amp;gt; в предположении, что было сделано &amp;lt;math&amp;gt;\Tau&amp;lt;/math&amp;gt; операций определяется выражением&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p align=&amp;quot;center&amp;quot;&amp;gt;&amp;lt;math&amp;gt;\Psi_{k-means} \approx \Tau * (\Psi_{distribute}^{k, d} + \Psi_{recenter}^{k, d}) \le \Tau * O(log(k*d*n))&amp;lt;/math&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Входные и выходные данные алгоритма ===&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;Входные данные&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;Матрица из &amp;lt;math&amp;gt;n*d&amp;lt;/math&amp;gt; элементов &amp;lt;math&amp;gt;x_{i, j} \in \mathbb{R}, i=\overline{1, n}, j=\overline{1, d}&amp;lt;/math&amp;gt;&amp;amp;ndash; координат векторов (наблюдений).&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;Целое положительное число &amp;lt;math&amp;gt;k, k \le n&amp;lt;/math&amp;gt; &amp;amp;ndash; количество кластеров.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;Объем входных данных&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;math&amp;gt;1&amp;lt;/math&amp;gt; целое число + &amp;lt;math&amp;gt;n*d&amp;lt;/math&amp;gt; вещественных чисел (при условии, что координаты &amp;amp;ndash; вещественные числа).&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;Выходные данные&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; целых положительных чисел &amp;lt;math&amp;gt;L_1, ..., L_n&amp;lt;/math&amp;gt;&amp;amp;ndash; номера кластеров, соотвествующие каждому вектору (при условии, что нумерация кластеров начинается с &amp;lt;math&amp;gt;1&amp;lt;/math&amp;gt;).&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;Объем выходных данных&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; целых положительных чисел.&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Свойства алгоритма ===&lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;[[глоссарий#Вычислительная мощность|&#039;&#039;Вычислительная мощность&#039;&#039;]]&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
Вычислительная мощность алгоритма &amp;lt;i&amp;gt;k means&amp;lt;/i&amp;gt; равна &amp;lt;math&amp;gt;\frac{k*d*n*\Tau}{n*d} = k*\Tau &amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; &amp;amp;ndash; число кластеров, &amp;lt;math&amp;gt;\Tau&amp;lt;/math&amp;gt; &amp;amp;ndash; число итераций алгоритма.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;[[глоссарий#Детерминированность |&#039;&#039;Детерминированность&#039;&#039;]] и [[глоссарий#Устойчивость |&#039;&#039;Устойчивость&#039;&#039;]] &amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
Алгоритм &amp;lt;i&amp;gt;k means&amp;lt;/i&amp;gt; является итерационным. Количество итераций алгоритма в общем случае не фиксируется и зависит от начального расположения объектов в пространстве, параметра &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt;, а также от начального приближения центров кластеров, &amp;lt;math&amp;gt;\mu_1, ..., \mu_k&amp;lt;/math&amp;gt;. В результате этого может варьироваться результат работы алгоритма. При неудачном выборе начальных параметров итерационный процесс может сойтись к локальному оптимуму&amp;lt;ref&amp;gt;Von Luxburg, Ulrike. Clustering Stability. Now Publishers Inc, 2010.&amp;lt;/ref&amp;gt;. По этим причинам алгоритм не является ни &amp;lt;b&amp;gt;детермирированным&amp;lt;/b&amp;gt;, ни &amp;lt;b&amp;gt;устойчивым&amp;lt;/b&amp;gt;.&lt;br /&gt;
 &lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Соотношение последовательной и параллельной сложности алгоритма&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\frac{\Theta_{k-means}}{\Psi_{k-means}} = \frac{O(\Tau*k*d*n)}{O(\Tau*log(k*d*n))}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Сильные стороны алгоритма&amp;lt;/b&amp;gt;:&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;i&amp;gt;Сравнительно высокая эффективность при простоте реализации&amp;lt;/i&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;i&amp;gt;Высокое качество кластеризации&amp;lt;/i&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;i&amp;gt;Возможность распараллеливания&amp;lt;/i&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;i&amp;gt;Существование множества модификаций&amp;lt;/i&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;Недостатки алгоритма&amp;lt;/b&amp;gt;&amp;lt;ref&amp;gt;Ortega, Joaquín Pérez, Ma Del Rocío Boone Rojas, and María J. Somodevilla. &amp;quot;Research issues on K-means Algorithm: An Experimental Trial Using Matlab.&amp;quot;&amp;lt;/ref&amp;gt;:&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;i&amp;gt;Количество кластеров является параметром алгоритма&amp;lt;/i&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;&amp;lt;i&amp;gt;Чувствительность к начальным условиям&amp;lt;/i&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;Инициализация центров кластеров в значительной степени влияет на результат кластеризации.&amp;lt;/p&amp;gt;&lt;br /&gt;
  &amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;&amp;lt;i&amp;gt;Чувствительность к выбросам и шумам&amp;lt;/i&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;Выбросы, далекие от центров настоящих кластеров, все равно учитываются при вычислении их центров.&amp;lt;/p&amp;gt;&lt;br /&gt;
  &amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;&amp;lt;i&amp;gt;Возможность сходимости к локальному оптимуму&amp;lt;/i&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;Итеративный подход не дает гарантии сходимости к оптимальному решению.&amp;lt;/p&amp;gt;&lt;br /&gt;
  &amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;&amp;lt;i&amp;gt;Использование понятия &amp;quot;среднего&amp;quot;&amp;lt;/i&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;Алгоритм неприменим к данным, для которых не определено понятие &amp;quot;среднего&amp;quot;, например, категориальным данным.&amp;lt;/p&amp;gt;&lt;br /&gt;
  &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&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;
Исследование масштабируемости параллельной реализации алгоритма k means проводилось на суперкомпьютере &amp;quot;Ломоносов&amp;quot;&amp;lt;ref name=&amp;quot;Lom&amp;quot;&amp;gt;Воеводин Вл., Жуматий С., Соболев С., Антонов А., Брызгалов П., Никитенко Д., Стефанов К., Воеводин Вад. Практика суперкомпьютера «Ломоносов» // Открытые системы, 2012, N 7, С. 36-39.&amp;lt;/ref&amp;gt; [http://parallel.ru/cluster Суперкомпьютерного комплекса Московского университета]. Алгоритм реализован на языке C с использованием средств MPI.&lt;br /&gt;
Для исследования масштабируемости проводилось множество запусков программы с разным значением параметра (количество векторов для кластеризации), а также с различным числом процессоров. Фиксировались результаты запусков &amp;amp;ndash; время работы &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt; и количество произведенных итераций алгоритма &amp;lt;math&amp;gt;\Tau&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Параметры запусков для экспериментальной оценки:&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;Значения &amp;lt;b&amp;gt;количества векторов&amp;lt;/b&amp;gt; &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;: 20&#039;000, 30&#039;000, 50&#039;000, 100&#039;000, 200&#039;000, 300&#039;000, 500&#039;000, 700&#039;000, 1&#039;000&#039;000, 1&#039;500&#039;000, 2&#039;000&#039;000.&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;Значения &amp;lt;b&amp;gt;количества процессоров&amp;lt;/b&amp;gt; &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt;: 1, 8, 16, 32, 64, 128, 160, 192, 224, 256, 288, 320, 352, 384, 416, 448, 480, 512.&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;Значение &amp;lt;b&amp;gt;количества кластеров&amp;lt;/b&amp;gt; &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt;: 100.&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;Значение &amp;lt;b&amp;gt;размерности векторов&amp;lt;/b&amp;gt; &amp;lt;math&amp;gt;d&amp;lt;/math&amp;gt;: 10.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Для проведения экспериментов были сгенерированы нормально распределенные псевдослучайные данные (с использованием Python библиотеки [http://scikit-learn.org/ scikit-learn]):&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
from sklearn.datasets import make_classification&lt;br /&gt;
X1, Y1 = make_classification(n_features=10, n_redundant=2, n_informative=8,&lt;br /&gt;
                             n_clusters_per_class=1, n_classes=100,&lt;br /&gt;
                             n_samples=2000000)&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Для заданной конфигурации эксперимента (&amp;lt;math&amp;gt;n, d, p, k&amp;lt;/math&amp;gt;) и полученных результатов (&amp;lt;math&amp;gt;t, \Tau&amp;lt;/math&amp;gt;)  [[Глоссарий#Производительность|производительность]]  и эффективность реализации расчитывались по формулам:&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
&amp;lt;ul&amp;gt;&amp;lt;li&amp;gt;&amp;lt;math&amp;gt;Performance = \frac{N_{k-means}^{d, n}}{t}\ \ (FLOPS),&amp;lt;/math&amp;gt;&amp;lt;/li&amp;gt;&amp;lt;/ul&amp;gt;&lt;br /&gt;
где &amp;lt;math&amp;gt;N_{k-means}^{d, n}&amp;lt;/math&amp;gt; &amp;amp;ndash; точное число операций с плавающей точкой (операции с памятью, а также целочисленные операции не учитывались), вычисленное в соответствие с разделом [[#Последовательная сложность алгоритма| &amp;quot;Последовательная сложность алгоритма&amp;quot;]];&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
&amp;lt;ul&amp;gt;&amp;lt;li&amp;gt;&amp;lt;math&amp;gt;Efficiency = \frac{100 * Performance}{Performance_{Peak}^{p}}\ \ (%),&amp;lt;/math&amp;gt;&amp;lt;/li&amp;gt;&amp;lt;/ul&amp;gt;&lt;br /&gt;
где &amp;lt;math&amp;gt;Performance_{Peak}^{p}&amp;lt;/math&amp;gt; &amp;amp;ndash; пиковая производительность суперкомпьютера при &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt; процессорах, вычисленная согласно спецификациям Intel&amp;lt;sup&amp;gt;&amp;amp;reg;&amp;lt;/sup&amp;gt; XEON&amp;lt;sup&amp;gt;&amp;amp;reg;&amp;lt;/sup&amp;gt; X5670&amp;lt;ref&amp;gt;&amp;quot;http://ark.intel.com/ru/products/47920/Intel-Xeon-Processor-X5670-12M-Cache-2_93-GHz-6_40-GTs-Intel-QPI&amp;quot;&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Графики зависимости производительности и эффективности параллельной реализации k means от числа векторов для кластеризации (&amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;) и числа процессоров (&amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt;) представлены на рисунках 4 и 5 соответственно.&lt;br /&gt;
&lt;br /&gt;
[[file:Flops.png|thumb|center|800px|Рис. 4. Параллельная реализация k means. График зависимости производительности реализации алгоритма от числа векторов для кластеризации (&amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;) и числа процессоров (&amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt;).]]&lt;br /&gt;
[[file:Efficiency.png|thumb|center|800px|Рис. 5. Параллельная реализация k means. График зависимости эффективности реализации алгоритма от числа векторов для кластеризации (&amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;) и числа процессоров (&amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt;).]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;В результате&amp;lt;/b&amp;gt; экспериментальной оценки были получены следующие оценки эффективности реализации:&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;b&amp;gt;Минимальное&amp;lt;/b&amp;gt; значение: 0.000409 % достигается при &amp;lt;math&amp;gt;n=20&#039;000, p=480&amp;lt;/math&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;b&amp;gt;Максимальное&amp;lt;/b&amp;gt; значение: 0.741119 % достигается при &amp;lt;math&amp;gt;n=300&#039;000, p=1&amp;lt;/math&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
Оценки масштабируемости реализации алгоритма k means:&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;b&amp;gt;По числу процессоров:&amp;lt;/b&amp;gt; -0.002683 &amp;amp;ndash; эффективность убывает с ростом числа процессоров. Данный результат вызван ростом накладных расходов для обеспечения параллельного выполнения алгоритма.&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;b&amp;gt;По размеру задачи:&amp;lt;/b&amp;gt; 0.002779 &amp;amp;ndash; эффективность растет с ростом числа векторов. Данный результат вызван тем, что при увеличении размера задачи, количество вычислений растет по сравнению с временем, затрачиваемым на пересылку данных.&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;b&amp;gt;Общая оценка:&amp;lt;/b&amp;gt; -0.000058 &amp;amp;ndash; можно сделать вывод, что в целом эффективность реализации незначительно уменьшается с ростом размера задачи и числа процессоров.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[https://github.com/serban/kmeans Использованная параллельная реализация алгоритма k means]&lt;br /&gt;
&lt;br /&gt;
=== Динамические характеристики и эффективность реализации алгоритма ===&lt;br /&gt;
=== Выводы для классов архитектур ===&lt;br /&gt;
=== Существующие реализации алгоритма ===&lt;br /&gt;
==== Открытое программное обеспечение ====&lt;br /&gt;
&amp;lt;ol&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;[https://www.icpsr.umich.edu/CrimeStat/ CrimeStat]&amp;lt;/li&amp;gt; Программное обеспечение, созданное для операционных систем Windows, предоставляющее инструменты статистического  и пространственного анализа для решения задачи картирования преступности.&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://juliastats.github.io Julia]&amp;lt;/li&amp;gt; Высокоуровневый высокопроизводительный свободный язык программирования с динамической типизацией, созданный для математических вычислений, содержит реализацию k-means.&lt;br /&gt;
  &amp;lt;li&amp;gt;[https://mahout.apache.org Mahout]&amp;lt;/li&amp;gt; Apache Mahout - Java библиотека для работы с алгоритмами машинного обучения с использованием MapReduce. Содержит реализацию k-means.&lt;br /&gt;
  &amp;lt;li&amp;gt;[https://www.gnu.org/software/octave/ Octave]&amp;lt;/li&amp;gt; Написанная на C++  свободная система для математических вычислений, использующая совместимый с MATLAB язык высокого уровня, содержит реализацию k-means.&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://spark.apache.org/docs/latest/mllib-clustering.html Spark]&amp;lt;/li&amp;gt; Распределенная реализация k-means содержится в библиотеке Mlib для работы с алгоритмами машинного обучения, взаимодействующая с Python библиотекой NumPy и библиотека R.&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://torch.ch Torch]&amp;lt;/li&amp;gt;  MATLAB-подобная библиотека для языка программирования Lua с открытым исходным кодом, предоставляет большое количество алгоритмов для глубинного обучения и научных расчётов. Ядро написано на Си, прикладная часть выполняется на LuaJIT, поддерживается распараллеливание вычислений средствами CUDA и OpenMP. Существуют реализации k-means.&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://www.cs.waikato.ac.nz/ml/weka/ Weka]&amp;lt;/li&amp;gt;  Cвободное программное обеспечение для анализа данных, написанное на Java. Содержит k-means и x-means.&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://accord-framework.net/docs/html/T_Accord_MachineLearning_KMeans.htm Accord.NET]&amp;lt;/li&amp;gt; C# реализация алгоритмов k-means, k-means++, k-modes.&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://docs.opencv.org/3.0-beta/doc/py_tutorials/py_ml/py_kmeans/py_kmeans_opencv/py_kmeans_opencv.html OpenCV]&amp;lt;/li&amp;gt; Написанная на С++ библиотека, направленная в основном на решение задач компьютерного зрения. Содержит реализацию k-means.&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://mlpack.org/ MLPACK]&amp;lt;/li&amp;gt; Масштабируемая С++ библиотека для работы с алгоритмами машинного обучения, содержит реализацию k-means.&lt;br /&gt;
  &amp;lt;li&amp;gt;[https://www.scipy.org/ SciPy]&amp;lt;/li&amp;gt; Библиотека Python, содержит множество реализаций k-means.&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://scikit-learn.org/ scikit-learn]&amp;lt;/li&amp;gt; Библиотека Python, содержит множество реализаций k-means.&lt;br /&gt;
  &amp;lt;li&amp;gt;[https://www.r-bloggers.com/k-means-clustering-in-r/ R]&amp;lt;/li&amp;gt; Язык программирования для статистической обработки данных и работы с графикой, а также свободная программная среда вычислений с открытым исходным кодом в рамках проекта GNU, содержит три реализации k-means.&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://elki.dbs.ifi.lmu.de ELKI]&amp;lt;/li&amp;gt; Java фреймворк, содержащий реализацию k-means, а также множество других алгоритмов кластеризации.&lt;br /&gt;
&amp;lt;/ol&amp;gt;&lt;br /&gt;
==== Проприетарное программное обеспечение  ====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ol&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;[https://www.ayasdi.com/blog/bigdata/topological-data-analysis-of-oil-and-gas-petrophysical-data/ Ayasdi]&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://www.stata.com/features/cluster-analysis/ Stata]&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://mathworld.wolfram.com/K-MeansClusteringAlgorithm.html Mathematica]&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://www.mathworks.com/help/stats/kmeans.html?requestedDomain=www.mathworks.com MATLAB]&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;[https://support.sas.com/rnd/app/stat/procedures/fastclus.html SAS]&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://docs.rapidminer.com/studio/operators/modeling/segmentation/k_means.html RapidMiner]&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;[https://blogs.sap.com/2013/03/28/sap-hana-pal-k-means-algorithm-or-how-to-do-customer-segmentation-for-the-telecommunications-industry/ SAP HANA]&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ol&amp;gt;&lt;br /&gt;
== Литература ==&lt;br /&gt;
&amp;lt;references /&amp;gt;&lt;/div&gt;</summary>
		<author><name>DennZo1993</name></author>
	</entry>
	<entry>
		<id>https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:%D0%91%D1%80%D0%BE%D1%82%D0%B8%D0%BA%D0%BE%D0%B2%D1%81%D0%BA%D0%B0%D1%8F_%D0%94%D0%B0%D0%BD%D1%83%D1%82%D0%B0/%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_k-means&amp;diff=20521</id>
		<title>Участник:Бротиковская Данута/Алгоритм k-means</title>
		<link rel="alternate" type="text/html" href="https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:%D0%91%D1%80%D0%BE%D1%82%D0%B8%D0%BA%D0%BE%D0%B2%D1%81%D0%BA%D0%B0%D1%8F_%D0%94%D0%B0%D0%BD%D1%83%D1%82%D0%B0/%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_k-means&amp;diff=20521"/>
		<updated>2016-12-10T10:37:24Z</updated>

		<summary type="html">&lt;p&gt;DennZo1993: /* Последовательная сложность алгоритма */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Assignment|Zhum}}&lt;br /&gt;
&lt;br /&gt;
{{algorithm&lt;br /&gt;
| name              = Алгоритм k средних (k means)&lt;br /&gt;
| serial_complexity = &amp;lt;math&amp;gt;O(\Tau*k*d*n)&amp;lt;/math&amp;gt;&lt;br /&gt;
| input_data        = &amp;lt;math&amp;gt; d*n &amp;lt;/math&amp;gt;&lt;br /&gt;
| output_data       = &amp;lt;math&amp;gt; n &amp;lt;/math&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
Авторы страницы &amp;lt;b&amp;gt;[[Участник:Бротиковская Данута|Данута Бротиковская]]&amp;lt;/b&amp;gt; и &amp;lt;b&amp;gt;[[Участник:DennZo1993|Денис Зобнин]]&amp;lt;/b&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
Оба автора внесли одинаковый вклад в написание статьи (поиск материалов, изучение статей, заполнение контента статьи), четких разграничений по пунктам статьи сделать невозможно. &lt;br /&gt;
&lt;br /&gt;
== Свойства и структура алгоритма ==&lt;br /&gt;
&lt;br /&gt;
=== Общее описание алгоритма ===&lt;br /&gt;
Алгоритм &amp;lt;b&amp;gt;&amp;lt;i&amp;gt;k средних&amp;lt;/i&amp;gt;&amp;lt;/b&amp;gt; (&amp;lt;b&amp;gt;&amp;lt;i&amp;gt;k means&amp;lt;/i&amp;gt;&amp;lt;/b&amp;gt;) &amp;amp;ndash; неиерархический&amp;lt;ref&amp;gt;&amp;quot;https://ru.wikipedia.org/wiki/Иерархическая_кластеризация&amp;quot;&amp;lt;/ref&amp;gt;, итерационный метод кластеризации&amp;lt;ref&amp;gt;&amp;quot;https://ru.wikipedia.org/wiki/Кластерный_анализ&amp;quot;&amp;lt;/ref&amp;gt;, получивший большую популярность благодаря своей простоте, наглядности реализации и достаточно высокому качеству работы. Был изобретен в 1950-х годах математиком &amp;lt;i&amp;gt;Гуго Штейнгаузом&amp;lt;/i&amp;gt;&amp;lt;ref&amp;gt;Steinhaus, Hugo. &amp;quot;Sur la division des corp materiels en parties.&amp;quot; Bull. Acad. Polon. Sci 1.804 (1956): 801.&amp;lt;/ref&amp;gt; и почти одновременно &amp;lt;i&amp;gt;Стюартом Ллойдом&amp;lt;/i&amp;gt;&amp;lt;ref&amp;gt;Lloyd, S. P. &amp;quot;Least square quantization in PCM. Bell Telephone Laboratories Paper. Published in journal much later: Lloyd, SP: Least squares quantization in PCM.&amp;quot; IEEE Trans. Inform. Theor.(1957/1982).&amp;lt;/ref&amp;gt;. Особую популярность приобрел после публикации работы &amp;lt;i&amp;gt;МакКуина&amp;lt;/i&amp;gt;&amp;lt;ref&amp;gt;MacQueen, James. &amp;quot;Some methods for classification and analysis of multivariate observations.&amp;quot; Proceedings of the fifth Berkeley symposium on mathematical statistics and probability. Vol. 1. No. 14. 1967.&amp;lt;/ref&amp;gt; в 1967.&lt;br /&gt;
&lt;br /&gt;
Алгоритм представляет собой версию EM-алгоритма&amp;lt;ref&amp;gt;&amp;quot;https://ru.wikipedia.org/wiki/EM-алгоритм&amp;quot;&amp;lt;/ref&amp;gt;, применяемого также для разделения смеси гауссиан. Основная идея &amp;lt;i&amp;gt;k means&amp;lt;/i&amp;gt; заключается в том, что данные произвольно разбиваются на кластеры, после чего итеративно перевычисляется центр масс для каждого кластера, полученного на предыдущем шаге, затем векторы разбиваются на кластеры вновь в соответствии с тем, какой из новых центров оказался ближе по выбранной метрике.&lt;br /&gt;
&lt;br /&gt;
Цель алгоритма заключается в разделении &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; наблюдений на &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластеров таким образом, чтобы каждое наблюдение принадлежало ровно одному кластеру, расположенному на наименьшем расстоянии от наблюдения.&lt;br /&gt;
&lt;br /&gt;
=== Математическое описание алгоритма ===&lt;br /&gt;
&amp;lt;b&amp;gt;&amp;lt;u&amp;gt;Дано:&amp;lt;/u&amp;gt;&amp;lt;/b&amp;gt;&lt;br /&gt;
* набор из &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; наблюдений &amp;lt;math&amp;gt;X=\{\mathbf{x}_1, \mathbf{x}_2, ..., \mathbf{x}_n\}, \mathbf{x}_i \in \mathbb{R}^d, i=\overline{1, n}&amp;lt;/math&amp;gt;;&lt;br /&gt;
* &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; - требуемое число кластеров, &amp;lt;math&amp;gt;k \in \mathbb{N}, k \leq n&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;&amp;lt;u&amp;gt;Требуется:&amp;lt;/u&amp;gt;&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Разделить множество наблюдений &amp;lt;math&amp;gt;X&amp;lt;/math&amp;gt; на &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластеров &amp;lt;math&amp;gt;S_1, S_2, ..., S_k&amp;lt;/math&amp;gt;:&lt;br /&gt;
*   &amp;lt;math&amp;gt;S_i \cap S_j= \varnothing, \quad i \ne j&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
*   &amp;lt;math&amp;gt;\bigcup_{i=1}^{k} S_i = X&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;&amp;lt;u&amp;gt;Действие алгоритма:&amp;lt;/u&amp;gt;&amp;lt;/b&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;Алгоритм &amp;lt;i&amp;gt;k means&amp;lt;/i&amp;gt; разбивает набор &amp;lt;math&amp;gt;X&amp;lt;/math&amp;gt; на &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; наборов &amp;lt;math&amp;gt;S_1, S_2, ..., S_k,&amp;lt;/math&amp;gt; таким образом, чтобы минимизировать сумму квадратов расстояний от каждой точки кластера до его центра (центр масс кластера). Введем обозначение, &amp;lt;math&amp;gt;S=\{S_1, S_2, ..., S_k\}&amp;lt;/math&amp;gt;. Тогда действие алгоритма &amp;lt;i&amp;gt;k means&amp;lt;/i&amp;gt; равносильно поиску:&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;table style=&amp;quot;width:100%&amp;quot;&amp;gt;&lt;br /&gt;
  &amp;lt;tr&amp;gt;&lt;br /&gt;
    &amp;lt;td align=&amp;quot;center&amp;quot; width=&amp;quot;90%&amp;quot;&amp;gt;&amp;lt;math&amp;gt;\arg\min_{S} \sum\limits_{i=1}^k \sum\limits_{\mathbf{x} \in S_i} \rho(\mathbf{x}, \mathbf{\mu}_i )^2,&amp;lt;/math&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;td align=&amp;quot;right&amp;quot;&amp;gt;&amp;lt;math&amp;gt;(1)&amp;lt;/math&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;/table&amp;gt;&lt;br /&gt;
где &amp;lt;math&amp;gt;\mathbf{\mu}_i&amp;lt;/math&amp;gt; &amp;amp;ndash; центры кластеров, &amp;lt;math&amp;gt;i=\overline{1,k}, \quad \rho(\mathbf{x}, \mathbf{\mu}_i)&amp;lt;/math&amp;gt; &amp;amp;ndash; функция расстояния между &amp;lt;math&amp;gt;\mathbf{x}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\mu_i&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;&amp;lt;u&amp;gt;Шаги алгоритма: &amp;lt;/u&amp;gt;&amp;lt;/b&amp;gt;&lt;br /&gt;
&amp;lt;ol&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&lt;br /&gt;
    &amp;lt;b&amp;gt;Начальный шаг: инициализация кластеров&amp;lt;/b&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;Выбирается произвольное множество точек &amp;lt;math&amp;gt;\mu_i, i=\overline{1,k}&amp;lt;/math&amp;gt;, рассматриваемых как начальные центры кластеров: &amp;lt;math&amp;gt;\mu_i^{(0)} = \mu_i, \quad i=\overline{1, k}&amp;lt;/math&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
  &amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&lt;br /&gt;
    &amp;lt;b&amp;gt;Распределение векторов по кластерам&amp;lt;/b&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Шаг&amp;lt;/b&amp;gt; &amp;lt;math&amp;gt;t: \forall \mathbf{x}_i \in X, i=\overline{1,n}: \mathbf{x}_i \in S_j \iff  j=\arg\min_{k}\rho(\mathbf{x}_i,\mathbf{\mu}_k^{(t-1)})^2&amp;lt;/math&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
  &amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&lt;br /&gt;
    &amp;lt;b&amp;gt;Пересчет центров кластеров&amp;lt;/b&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Шаг &amp;lt;/b&amp;gt; &amp;lt;math&amp;gt;t: \forall i=\overline{1,k}:  \mu_i^{(t)} = \cfrac{1}{|S_i|}\sum_{\mathbf{x}\in S_i}\mathbf{x}&amp;lt;/math&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
  &amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&lt;br /&gt;
    &amp;lt;b&amp;gt;Проверка условия останова:&amp;lt;/b&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
    &#039;&#039;&#039;if&#039;&#039;&#039; &amp;lt;math&amp;gt;\exist i\in \overline{1,k}: \mu_i^{(t)} \ne \mu_i^{(t-1)}&amp;lt;/math&amp;gt; &#039;&#039;&#039;then&#039;&#039;&#039;&lt;br /&gt;
        t = t + 1;&lt;br /&gt;
        goto 2;&lt;br /&gt;
    &#039;&#039;&#039;else&#039;&#039;&#039;&lt;br /&gt;
        &#039;&#039;&#039;stop&#039;&#039;&#039;&lt;br /&gt;
  &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ol&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Вычислительное ядро алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Вычислительным ядром являются шаги 2 и 3 приведенного выше алгоритма: &amp;lt;b&amp;gt;&amp;lt;i&amp;gt;распределение векторов по кластерам&amp;lt;/i&amp;gt;&amp;lt;/b&amp;gt; и &amp;lt;b&amp;gt;&amp;lt;i&amp;gt;пересчет центров кластеров&amp;lt;/i&amp;gt;&amp;lt;/b&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;&amp;lt;i&amp;gt;Распределение векторов&amp;lt;/i&amp;gt;&amp;lt;/b&amp;gt; по кластерам предполагает вычисление расстояний между каждым вектором &amp;lt;math&amp;gt;\mathbf{x}_i \in X, i= \overline{1,n}&amp;lt;/math&amp;gt; и центрами кластера &amp;lt;math&amp;gt;\mathbf{\mu}_j, j= \overline{1,k}&amp;lt;/math&amp;gt;. Таким образом, данный шаг предполагает &amp;lt;math&amp;gt;kn&amp;lt;/math&amp;gt; вычислений расстояний между d-мерными векторами. &lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;&amp;lt;i&amp;gt;Пересчет центров кластеров&amp;lt;/i&amp;gt;&amp;lt;/b&amp;gt; предполагает &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; вычислений центров масс &amp;lt;math&amp;gt;\mathbf{\mu}_i&amp;lt;/math&amp;gt; множеств &amp;lt;math&amp;gt;S_i, i=\overline{1,k}&amp;lt;/math&amp;gt; представленных выражением в шаге 3 представленного выше алгоритма.&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Макроструктура алгоритма ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Инициализация центров масс &amp;lt;math&amp;gt;\mu_1, ..., \mu_k&amp;lt;/math&amp;gt;&amp;lt;/b&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
Наиболее распространенными являются следующие стратегии:&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&lt;br /&gt;
    &amp;lt;b&amp;gt;Метод Forgy&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;В качестве начальных значений &amp;lt;math&amp;gt;\mu_1, ..., \mu_k&amp;lt;/math&amp;gt; берутся случайно выбранные векторы.&lt;br /&gt;
  &amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&lt;br /&gt;
    &amp;lt;b&amp;gt;Метод случайно разделения (Random Partitioning)&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;Для каждого вектора &amp;lt;math&amp;gt;\mathbf{x}_i \in X, i=\overline{1, n}&amp;lt;/math&amp;gt; выбирается случайным образом кластер &amp;lt;math&amp;gt;S_1, ..., S_k&amp;lt;/math&amp;gt;, после чего для каждого полученного кластера вычисляются значения &amp;lt;math&amp;gt;\mu_1, ..., \mu_k&amp;lt;/math&amp;gt;.&lt;br /&gt;
  &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Распределение векторов по кластерам&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Для этого шага алгоритма между векторами &amp;lt;math&amp;gt;\mathbf{x}_i \in X, i=\overline{1, n}&amp;lt;/math&amp;gt; и центрами кластеров &amp;lt;math&amp;gt;\mu_1, ..., \mu_k&amp;lt;/math&amp;gt; вычисляются &amp;lt;b&amp;gt;расстояния&amp;lt;/b&amp;gt; по формуле (как правило, используется Евлидово расстояние):&lt;br /&gt;
&amp;lt;table style=&amp;quot;width:100%&amp;quot;&amp;gt;&lt;br /&gt;
  &amp;lt;tr&amp;gt;&lt;br /&gt;
    &amp;lt;td align=&amp;quot;center&amp;quot; width=&amp;quot;90%&amp;quot;&amp;gt;&amp;lt;math&amp;gt; \mathbf{v}_1, \mathbf{v}_2 \in \mathbb{R}^d,  \quad \rho(\mathbf{v}_1, \mathbf{v}_2) = \lVert \mathbf{v}_1- \mathbf{v}_2 \rVert= \sqrt{\sum_{i=1}^{d}(\mathbf{v}_{1,i} - \mathbf{v}_{2,i})^2}&amp;lt;/math&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;td align=&amp;quot;right&amp;quot;&amp;gt;&amp;lt;math&amp;gt;(2)&amp;lt;/math&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;/table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Пересчет центров кластеров&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Для этого шага алгоритма производится пересчет центров кластера по &amp;lt;b&amp;gt;формуле вычисления центра масс&amp;lt;/b&amp;gt;:&lt;br /&gt;
&amp;lt;table style=&amp;quot;width:100%&amp;quot;&amp;gt;&lt;br /&gt;
  &amp;lt;tr&amp;gt;&lt;br /&gt;
    &amp;lt;td align=&amp;quot;center&amp;quot; width=&amp;quot;90%&amp;quot;&amp;gt;&amp;lt;math&amp;gt; \mu = \cfrac{1}{|S|}\sum_{\mathbf{x}\in S}\mathbf{x}&amp;lt;/math&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;td align=&amp;quot;right&amp;quot;&amp;gt;&amp;lt;math&amp;gt;(3)&amp;lt;/math&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;/table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Схема реализации последовательного алгоритма ===&lt;br /&gt;
&lt;br /&gt;
 &#039;&#039;&#039;algorithm&#039;&#039;&#039; k-means &#039;&#039;&#039;is&#039;&#039;&#039;&lt;br /&gt;
     &#039;&#039;&#039;1.&#039;&#039;&#039; Инициализировать центры кластеров &amp;lt;math&amp;gt;\mathbf{\mu}_i^{(1)}, i=\overline{1,k}&amp;lt;/math&amp;gt;&lt;br /&gt;
     &#039;&#039;&#039;2.&#039;&#039;&#039; &amp;lt;math&amp;gt;t \leftarrow 1&amp;lt;/math&amp;gt;&lt;br /&gt;
     &#039;&#039;&#039;3.&#039;&#039;&#039; &#039;&#039;&#039;Распределение по кластерам&#039;&#039;&#039;&amp;lt;br&amp;gt;&lt;br /&gt;
        &amp;lt;math&amp;gt;S_i^{(t)}=\{\mathbf{x}_p: \lVert\mathbf{x}_p-\mathbf{\mu}_i^{(t)}\rVert^2 \leq \lVert\mathbf{x}_p-\mathbf{\mu}_j^{(t)}\rVert^2 \quad \forall j=\overline{1,k}\},&amp;lt;/math&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
        где каждый вектор &amp;lt;math&amp;gt;\mathbf{x}_p&amp;lt;/math&amp;gt; соотносится единственному кластеру &amp;lt;math&amp;gt;S^{(t)}&amp;lt;/math&amp;gt;&lt;br /&gt;
     &#039;&#039;&#039;4.&#039;&#039;&#039; &#039;&#039;&#039;Обновление центров кластеров&#039;&#039;&#039;&amp;lt;br&amp;gt;&lt;br /&gt;
        &amp;lt;math&amp;gt;\mathbf{\mu}_i^{(t+1)} = \frac{1}{|S^{(t)}_i|} \sum_{\mathbf{x}_j \in S^{(t)}_i} \mathbf{x}_j &amp;lt;/math&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
     &#039;&#039;&#039;5.&#039;&#039;&#039; &#039;&#039;&#039;if&#039;&#039;&#039; &amp;lt;math&amp;gt;\exist i \in \overline{1,k}: \mathbf{\mu}_i^{(t+1)} \ne \mathbf{\mu}_i^{(t)}&amp;lt;/math&amp;gt; &#039;&#039;&#039;then&#039;&#039;&#039;&lt;br /&gt;
            t = t + 1;&lt;br /&gt;
            goto &#039;&#039;&#039;3&#039;&#039;&#039;;&lt;br /&gt;
        &#039;&#039;&#039;else&#039;&#039;&#039;&lt;br /&gt;
            &#039;&#039;&#039;stop&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
=== Последовательная сложность алгоритма===&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding-bottom: 20px&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;Обозначим &amp;lt;math&amp;gt;\Theta_{centroid}^{d, m}&amp;lt;/math&amp;gt; временную сложность вычисления центорида кластера, число элементов которого равна &amp;lt;math&amp;gt;m&amp;lt;/math&amp;gt;,  в d-мерном пространстве.&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;Аналогично  &amp;lt;math&amp;gt;\Theta_{distance}^d&amp;lt;/math&amp;gt; &amp;amp;ndash; временная сложность вычисления расстояния между двумя d-мерными векторами.&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding-bottom: 20px&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;Сложность шага инициализации &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластеров мощности &amp;lt;math&amp;gt;m&amp;lt;/math&amp;gt; в d-мерном пространстве &amp;amp;ndash; &amp;lt;math&amp;gt;\Theta_{init}^{k, d, m}&amp;lt;/math&amp;gt;&amp;lt;/b&amp;gt;&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;i&amp;gt;Стратерия Forgy&amp;lt;/i&amp;gt;: вычисления не требуются, &amp;lt;math&amp;gt;\Theta_{init}^{k, d, m} = 0&amp;lt;/math&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;i&amp;gt;Стратегия случайного разбиения&amp;lt;/i&amp;gt;: вычисление центров &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластеров,  &amp;lt;math&amp;gt;\Theta_{init}^{k, d, m} = k \cdot \Theta_{centroid}^{d, m}, m \le n&amp;lt;/math&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding-bottom: 20px&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Cложность шага распределения d мерных векторов по &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластерам &amp;amp;ndash; &amp;lt;math&amp;gt;\Theta_{distribute}^{k, d}&amp;lt;/math&amp;gt;&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
На этом шаге для каждого вектора &amp;lt;math&amp;gt;\mathbf{x}_i \in X, i=\overline{1, n}&amp;lt;/math&amp;gt; вычисляется k расстояний до центров кластеров &amp;lt;math&amp;gt;\mathbf{\mu}_1, ...\mathbf{\mu}_k&amp;lt;/math&amp;gt;&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p align=&amp;quot;center&amp;quot;&amp;gt;&lt;br /&gt;
  &amp;lt;math&amp;gt;\Theta_{distribute}^{k, d} = nk \cdot \Theta_{distance}^d&amp;lt;/math&amp;gt;&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding-bottom: 20px&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;Сложность шага пересчета центров &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластеров размера &amp;lt;math&amp;gt;m&amp;lt;/math&amp;gt; в d-мерном пространстве &amp;amp;ndash; &amp;lt;math&amp;gt;\Theta_{recenter}^{k, d, m}&amp;lt;/math&amp;gt;&amp;lt;/b&amp;gt;&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;На этом шаге вычисляется &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; центров кластеров &amp;lt;math&amp;gt;\mathbf{\mu}_1, ...\mathbf{\mu}_k&amp;lt;/math&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p align=&amp;quot;center&amp;quot;&amp;gt;&amp;lt;math&amp;gt;\Theta_{recenter}^{k, d, m} = k \cdot \Theta_{centroid}^{d, m}&amp;lt;/math&amp;gt; &amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding-bottom: 20px&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Рассчитаем &amp;lt;math&amp;gt;\Theta_{centroid}^{d, m}&amp;lt;/math&amp;gt; для кластера, число элементов которого равно &amp;lt;math&amp;gt;m&amp;lt;/math&amp;gt;&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p align=&amp;quot;center&amp;quot;&amp;gt;&amp;lt;math&amp;gt;\Theta_{centroid}^{d, m}&amp;lt;/math&amp;gt; = &amp;lt;math&amp;gt;md&amp;lt;/math&amp;gt; сложений + &amp;lt;math&amp;gt;d&amp;lt;/math&amp;gt; делений &amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding-bottom: 20px&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Рассчитаем &amp;lt;math&amp;gt;\Theta_{distance}^d&amp;lt;/math&amp;gt; в соответствие с формулой &amp;lt;math&amp;gt;(2)&amp;lt;/math&amp;gt;&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p align=&amp;quot;center&amp;quot;&amp;gt;&amp;lt;math&amp;gt;\Theta_{distance}^d&amp;lt;/math&amp;gt; = &amp;lt;math&amp;gt;d&amp;lt;/math&amp;gt; вычитаний + &amp;lt;math&amp;gt;d&amp;lt;/math&amp;gt; умножений + &amp;lt;math&amp;gt;(d-1)&amp;lt;/math&amp;gt; сложение&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding-bottom: 20px&amp;quot;&amp;gt;&lt;br /&gt;
  &amp;lt;p&amp;gt;Предположим, что алгоритм сошелся за &amp;lt;math&amp;gt;\Tau&amp;lt;/math&amp;gt; итераций, тогда временная сложность алгоритма &amp;lt;math&amp;gt;\Theta_{k-means}^{d, n}&amp;lt;/math&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
  &amp;lt;p align=&amp;quot;center&amp;quot;&amp;gt;&amp;lt;b&amp;gt;&amp;lt;math&amp;gt;\Theta_{k-means}^{d, n} \le \Theta_{init}^{k, d, n} + \Tau(\Theta_{distribute}^{k, d} + \Theta_{recenter}^{k, d, n})&amp;lt;/math&amp;gt;&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding-bottom: 5px&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;Операции сложения/вычитания:&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p align=&amp;quot;center&amp;quot;&amp;gt;&amp;lt;b&amp;gt;&amp;lt;math&amp;gt;\Theta_{k-means}^{d, n} \le k \cdot n \cdot d+ \Tau \cdot (k \cdot n(2d-1) + k \cdot n \cdot d) = k \cdot n \cdot d+ \Tau \cdot (k \cdot n(3d-1)) \thicksim O(\Tau k \cdot d \cdot n)&amp;lt;/math&amp;gt;&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding-bottom: 20px&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;Операции умножения/деления:&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p align=&amp;quot;center&amp;quot;&amp;gt;&amp;lt;b&amp;gt;&amp;lt;math&amp;gt;\Theta_{k-means}^{d, n} \le k \cdot d + \Tau \cdot (k \cdot n \cdot d + k \cdot d) = k \cdot d + \Tau \cdot k \cdot d \cdot (n+1) \thicksim O(\Tau \cdot k \cdot d \cdot n) &amp;lt;/math&amp;gt;&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding-bottom: 20px&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;Получаем, что &amp;lt;b&amp;gt;временная сложность&amp;lt;/b&amp;gt; алгоритма &amp;lt;b&amp;gt;k means&amp;lt;/b&amp;gt; кластеризации &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; &amp;lt;b&amp;gt;d-мерных&amp;lt;/b&amp;gt; векторов на &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластеров за &amp;lt;math&amp;gt;\Tau&amp;lt;/math&amp;gt; итераций:&amp;lt;/p&amp;gt;&lt;br /&gt;
 &amp;lt;p align=&amp;quot;center&amp;quot;&amp;gt;&amp;lt;b&amp;gt;&amp;lt;math&amp;gt; \Theta_{k-means}^{d, n} \thicksim O(\Tau \cdot k \cdot d \cdot n) &amp;lt;/math&amp;gt;&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Информационный граф ===&lt;br /&gt;
&lt;br /&gt;
Рассмотрим информационный граф алгоритма. Алгоритм &amp;lt;i&amp;gt;k means&amp;lt;/i&amp;gt; начинается с этапа инициализации, после которого следуют итерации, на каждой из которых выполняется два последовательных шага (см. [[#Схема реализации последовательного алгоритма|&amp;quot;Схема реализации последовательного алгоритма&amp;quot;]]): &lt;br /&gt;
* распределение векторов по кластерам&lt;br /&gt;
* перерасчет центров кластеров&lt;br /&gt;
&lt;br /&gt;
Поскольку основная часть вычислений приходится на шаги итераций, распишем информационные графы данных шагов.&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Распределение векторов по кластерам&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
Информационный граф шага распределения векторов по кластерам представлен на &#039;&#039;рисунке 1&#039;&#039;. Исходами данного графа является исходные векторы &amp;lt;math&amp;gt;\mathbf{x}_1, ..., \mathbf{x}_n&amp;lt;/math&amp;gt;, а также центры кластеров &amp;lt;math&amp;gt;\mathbf{\mu}_1, ... \mathbf{\mu}_k&amp;lt;/math&amp;gt;, вычисленные ранее (на шаге инициализации, если рассматривается первая итерация алгоритма, или на шаге пересчета центров кластеров предыдущей итерации в противном случае). Каждая пара векторов данных &amp;lt;math&amp;gt;\mathbf{x}_i, i=\overline{1,n}&amp;lt;/math&amp;gt; и центров кластера &amp;lt;math&amp;gt;\mathbf{\mu}_j, j=\overline{1, k}&amp;lt;/math&amp;gt; : (&amp;lt;math&amp;gt;\mathbf{x}_i&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;\mathbf{\mu}_j&amp;lt;/math&amp;gt;) подаются на независимые узлы &amp;lt;i&amp;gt;&amp;quot;d&amp;quot;&amp;lt;/i&amp;gt; вычисления расстояния между векторами (более подробная схема вычисления расстояния представлена далее, &#039;&#039;рисунок 2&#039;&#039;). Далее узлы вычисления расстояния &amp;lt;i&amp;gt;&amp;quot;d&amp;quot;&amp;lt;/i&amp;gt;, соответствующие одному и тому же исходному вектору &amp;lt;math&amp;gt;\mathbf{x}_i&amp;lt;/math&amp;gt; передаются на один узел &amp;lt;i&amp;gt;&amp;quot;m&amp;quot;&amp;lt;/i&amp;gt;, где далее происходит вычисление новой метки кластера для каждого вектора &amp;lt;math&amp;gt;\mathbf{x}_i&amp;lt;/math&amp;gt; (берется кластер с минимальным результатом вычисления расстояния). На выходе графа выдаются метки кластеров , &amp;lt;math&amp;gt;L_1, ..., L_n&amp;lt;/math&amp;gt;, такие что &amp;lt;math&amp;gt;\forall \mathbf{x}_i, i=\overline{1, n}, \mathbf{x}_i \in S_j \Leftrightarrow L_i = j&amp;lt;/math&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
[[file:Clusterization.png|thumb|center|800px|Рис. 1. Схема распределения векторов по кластерам. &#039;&#039;d&#039;&#039; &amp;amp;ndash; вычисление расстояния между векторами; &#039;&#039;m&#039;&#039; &amp;amp;ndash; вычисление минимума.]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Вычисление расстояния между векторами&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
Подробная схема вычисления расстояния между векторами &amp;lt;math&amp;gt;\mathbf{x}_i, \mathbf{\mu}_j&amp;lt;/math&amp;gt; представлена на &#039;&#039;рисунке 2&#039;&#039;. Как показано на графе, узел вычисления расстояния между векторами &amp;lt;i&amp;gt;&amp;quot;d&amp;quot;&amp;lt;/i&amp;gt; состоит из шага взятия разности между векторами (узел &amp;quot;&amp;lt;math&amp;gt;-&amp;lt;/math&amp;gt;&amp;quot;) и взятия нормы получившегося вектора разности (узел &amp;quot;&amp;lt;math&amp;gt;||\cdot||^2&amp;lt;/math&amp;gt;&amp;quot;). Более подробно, вычисление расстояния между векторами &amp;lt;math&amp;gt;\mathbf{x}_i = {x_{i1,}, ...,{x_{in}}}, \mathbf{\mu}_j = {\mu_{j1}, ...,\mu_{jn}}&amp;lt;/math&amp;gt; может быть представлено как вычисление разности между каждой парой компонент &amp;lt;math&amp;gt;(x_{iz}, \mu_{jz}), z=\overline{1, d}&amp;lt;/math&amp;gt; (узел &amp;quot;&amp;lt;math&amp;gt;-&amp;lt;/math&amp;gt;&amp;quot;), далее возведение в квадрат для каждого узла &amp;quot;&amp;lt;math&amp;gt;-&amp;lt;/math&amp;gt;&amp;quot; (узел &amp;quot;&amp;lt;math&amp;gt;()^2&amp;lt;/math&amp;gt;&amp;quot;) и суммирования выходов всех узлов &amp;quot;&amp;lt;math&amp;gt;()^2&amp;lt;/math&amp;gt;&amp;quot; (узел &amp;quot;&amp;lt;math&amp;gt;+&amp;lt;/math&amp;gt;&amp;quot;).  &lt;br /&gt;
&lt;br /&gt;
[[file:dist_calc.png|thumb|center|800px|Рис. 2. Схема вычисления расстояния между вектором и центром кластера.]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Пересчет центров кластеров&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
Информационный граф шага пересчета центров кластеров представлен на &#039;&#039;рисунке 3&#039;&#039;. Исходами данного графа является исходные векторы &amp;lt;math&amp;gt;\mathbf{x}_1, ..., \mathbf{x}_n&amp;lt;/math&amp;gt;, а также им соответствующие метки кластера, &amp;lt;math&amp;gt;L_1, ..., L_n&amp;lt;/math&amp;gt;, такие что &amp;lt;math&amp;gt;\forall x_i, i=\overline{1, n}, \mathbf{x}_i \in S_j \Leftrightarrow L_i = j&amp;lt;/math&amp;gt;, вычисленные на этапе распределения векторов по кластерам. Все векторы &amp;lt;math&amp;gt;\mathbf{x}_1, ..., \mathbf{x}_n&amp;lt;/math&amp;gt; подаются в узлы &amp;lt;math&amp;gt;+_1, ...+_k&amp;lt;/math&amp;gt;, каждый узел &amp;lt;math&amp;gt;+_m, m = \overline{1,k}&amp;lt;/math&amp;gt; соответствует операции сложения векторов кластера с номером &amp;lt;math&amp;gt;m&amp;lt;/math&amp;gt;. Метки кластера &amp;lt;math&amp;gt;L_1, ..., L_n&amp;lt;/math&amp;gt; также совместно передаются на узлы &amp;lt;math&amp;gt;S_m, m = \overline{1,k}&amp;lt;/math&amp;gt;, на каждом из которых вычисляется количество векторов в соответствующем кластере (количество меток с соответствующим значением). Далее каждая пара выходов узлов &amp;lt;math&amp;gt;+_m&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;S_m&amp;lt;/math&amp;gt; подается на узел &amp;quot;&amp;lt;math&amp;gt;/&amp;lt;/math&amp;gt;&amp;quot;, где производится деление суммы векторов кластера на количество элементов в нем. Значения, вычисленные на узлах &amp;quot;&amp;lt;math&amp;gt;/&amp;lt;/math&amp;gt;&amp;quot;, присваиваются новым центрам кластеров (выходные значения графа).&lt;br /&gt;
&lt;br /&gt;
[[file:Recluster.png|thumb|center|800px|Рис. 3. Схема пересчета центров кластеров]]&lt;br /&gt;
&lt;br /&gt;
=== Ресурс параллелизма алгоритма ===&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
Работа алгоритма состоит из &amp;lt;math&amp;gt;\Tau&amp;lt;/math&amp;gt; итераций, в каждой из которых происходит &amp;lt;b&amp;gt;распределение d-мерных векторов по &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластерам&amp;lt;/b&amp;gt;, а также &amp;lt;b&amp;gt;пересчет центров кластеров в d-мерном пространстве&amp;lt;/b&amp;gt;. В шаге &amp;lt;b&amp;gt;распределения d-мерных векторов по &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластерам&amp;lt;/b&amp;gt; расстояния между вектором и центрами кластеров вычисляются независимо (отсутствуют информационные зависимости). &amp;lt;b&amp;gt;Центры масс кластеров&amp;lt;/b&amp;gt; также пересчитываются независимо друг от друга. Таким образом, имеет место [[глоссарий#Массовый параллелизм|&#039;&#039;массовый параллелизм&#039;&#039;]]. Вычислим параллельную сложность &amp;lt;math&amp;gt;\Psi_*&amp;lt;/math&amp;gt; каждого из шагов, а также параллельную сложность всего алгоритма, &amp;lt;math&amp;gt;\Psi_{k-means}&amp;lt;/math&amp;gt;. Будем исходить из предположения, что может быть использовано любое необходимое число потоков.&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Распределение d-мерных векторов по &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластерам&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;  &lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
Поскольку на данном шаге для каждой пары векторов &amp;lt;math&amp;gt;\mathbf{x}_i, i=\overline{1,n}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\mathbf{\mu}_j, j=\overline{1,k}&amp;lt;/math&amp;gt; операции вычисления расстояния не зависят друг от друга, они могут выполняться параллельно. Тогда, разделив все вычисление расстояний на &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; потоков, получим, что в каждом потоке будет выполняться только одна операция вычисления расстояния между векторами размерности d. При этом каждому вычислительному потоку передаются координаты центров всех кластеров &amp;lt;math&amp;gt;\mathbf{\mu}_1, ..., \mathbf{\mu}_k&amp;lt;/math&amp;gt;. Таким образом, параллельная сложность данного шага определяется &amp;lt;i&amp;gt; сложностью параллельной операции вычисления расстояния между d-мерными векторами&amp;lt;/i&amp;gt;, &amp;lt;math&amp;gt;\Psi_{distance}^d&amp;lt;/math&amp;gt;  и &amp;lt;i&amp;gt;сложностью определения наиболее близкого кластера&amp;lt;/i&amp;gt; (паралельное взятие минимума по расстояниям), &amp;lt;math&amp;gt;\Psi_{min}^k&amp;lt;/math&amp;gt;. Для оценки &amp;lt;math&amp;gt;\Psi_{distance}^d&amp;lt;/math&amp;gt; воспользуемся  [[Нахождение_частных_сумм_элементов_массива_сдваиванием | параллельной реализацией нахождения частичной суммы элементов массива путем сдваивания]]. Аналогично, &amp;lt;math&amp;gt;\Psi_{min}^k = log(k)&amp;lt;/math&amp;gt;. В результате, &amp;lt;math&amp;gt;\Psi_{distance}^d = O(log(d))&amp;lt;/math&amp;gt;.   Таким образом: &lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p align=&amp;quot;center&amp;quot;&amp;gt;&amp;lt;math&amp;gt;\Psi_{distribute}^{k, d}  = \Psi_{distance}^d + \Psi_{min}^k = O(log(d))+O(log(k)) = O(log(k*d))&amp;lt;/math&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Пересчет центров кластеров в d-мерном пространстве&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
Поскольку на данном шаге для каждого из &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластеров центр масс может быть вычислен независимо, данные операции могут быть выполнены в отдельных потоках. Таким образом, параллельная сложность данного шага, &amp;lt;math&amp;gt;\Psi_{recenter}^{k, d}&amp;lt;/math&amp;gt;,  будет определяться &amp;lt;i&amp;gt;параллельной сложностью вычисления одного центра масс кластера размера &amp;lt;math&amp;gt;m&amp;lt;/math&amp;gt;&amp;lt;/i&amp;gt;, &amp;lt;math&amp;gt;\Psi_{recenter}^{k, d}&amp;lt;/math&amp;gt;,  а так как &amp;lt;math&amp;gt;m \le n \Rightarrow \Psi_{recenter}^{d, m} \le \Psi_{recenter}^{d, n}&amp;lt;/math&amp;gt;. Сложность вычисления центра масс кластера d-мерных векторов размера n аналогично предыдущим вычислениям равна &amp;lt;math&amp;gt;O(log(n))&amp;lt;/math&amp;gt;. Тогда:  &lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p align=&amp;quot;center&amp;quot;&amp;gt;&amp;lt;math&amp;gt;\Psi_{recenter}^{k, d}  \le \Psi_{recenter}^{d, n} = O(log(n))&amp;lt;/math&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Общая параллельная сложность алгоритма&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
На каждой итерации необходимо обновление центров кластеров, которые будут использованы на следующей итерации. Таким образом, итерационный процесс выполняется последовательно&amp;lt;ref&amp;gt;Zhao, Weizhong, Huifang Ma, and Qing He. &amp;quot;Parallel k-means clustering based on mapreduce.&amp;quot; IEEE International Conference on Cloud Computing. Springer Berlin Heidelberg, 2009.&amp;lt;/ref&amp;gt;. Тогда, поскольку сложность каждой итерации  определяется &amp;lt;math&amp;gt;\Psi_{distribute}^{k, d}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\Psi_{recenter}&amp;lt;/math&amp;gt;, сложность всего алгоритма, &amp;lt;math&amp;gt;\Psi_{k-means}&amp;lt;/math&amp;gt; в предположении, что было сделано &amp;lt;math&amp;gt;\Tau&amp;lt;/math&amp;gt; операций определяется выражением&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p align=&amp;quot;center&amp;quot;&amp;gt;&amp;lt;math&amp;gt;\Psi_{k-means} \approx \Tau * (\Psi_{distribute}^{k, d} + \Psi_{recenter}^{k, d}) \le \Tau * O(log(k*d*n))&amp;lt;/math&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Входные и выходные данные алгоритма ===&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;Входные данные&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;Матрица из &amp;lt;math&amp;gt;n*d&amp;lt;/math&amp;gt; элементов &amp;lt;math&amp;gt;x_{i, j} \in \mathbb{R}, i=\overline{1, n}, j=\overline{1, d}&amp;lt;/math&amp;gt;&amp;amp;ndash; координат векторов (наблюдений).&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;Целое положительное число &amp;lt;math&amp;gt;k, k \le n&amp;lt;/math&amp;gt; &amp;amp;ndash; количество кластеров.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;Объем входных данных&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;math&amp;gt;1&amp;lt;/math&amp;gt; целое число + &amp;lt;math&amp;gt;n*d&amp;lt;/math&amp;gt; вещественных чисел (при условии, что координаты &amp;amp;ndash; вещественные числа).&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;Выходные данные&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; целых положительных чисел &amp;lt;math&amp;gt;L_1, ..., L_n&amp;lt;/math&amp;gt;&amp;amp;ndash; номера кластеров, соотвествующие каждому вектору (при условии, что нумерация кластеров начинается с &amp;lt;math&amp;gt;1&amp;lt;/math&amp;gt;).&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;Объем выходных данных&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; целых положительных чисел.&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Свойства алгоритма ===&lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;[[глоссарий#Вычислительная мощность|&#039;&#039;Вычислительная мощность&#039;&#039;]]&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
Вычислительная мощность алгоритма &amp;lt;i&amp;gt;k means&amp;lt;/i&amp;gt; равна &amp;lt;math&amp;gt;\frac{k*d*n*\Tau}{n*d} = k*\Tau &amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; &amp;amp;ndash; число кластеров, &amp;lt;math&amp;gt;\Tau&amp;lt;/math&amp;gt; &amp;amp;ndash; число итераций алгоритма.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;[[глоссарий#Детерминированность |&#039;&#039;Детерминированность&#039;&#039;]] и [[глоссарий#Устойчивость |&#039;&#039;Устойчивость&#039;&#039;]] &amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
Алгоритм &amp;lt;i&amp;gt;k means&amp;lt;/i&amp;gt; является итерационным. Количество итераций алгоритма в общем случае не фиксируется и зависит от начального расположения объектов в пространстве, параметра &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt;, а также от начального приближения центров кластеров, &amp;lt;math&amp;gt;\mu_1, ..., \mu_k&amp;lt;/math&amp;gt;. В результате этого может варьироваться результат работы алгоритма. При неудачном выборе начальных параметров итерационный процесс может сойтись к локальному оптимуму&amp;lt;ref&amp;gt;Von Luxburg, Ulrike. Clustering Stability. Now Publishers Inc, 2010.&amp;lt;/ref&amp;gt;. По этим причинам алгоритм не является ни &amp;lt;b&amp;gt;детермирированным&amp;lt;/b&amp;gt;, ни &amp;lt;b&amp;gt;устойчивым&amp;lt;/b&amp;gt;.&lt;br /&gt;
 &lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Соотношение последовательной и параллельной сложности алгоритма&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\frac{\Theta_{k-means}}{\Psi_{k-means}} = \frac{O(\Tau*k*d*n)}{O(\Tau*log(k*d*n))}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Сильные стороны алгоритма&amp;lt;/b&amp;gt;:&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;i&amp;gt;Сравнительно высокая эффективность при простоте реализации&amp;lt;/i&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;i&amp;gt;Высокое качество кластеризации&amp;lt;/i&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;i&amp;gt;Возможность распараллеливания&amp;lt;/i&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;i&amp;gt;Существование множества модификаций&amp;lt;/i&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;Недостатки алгоритма&amp;lt;/b&amp;gt;&amp;lt;ref&amp;gt;Ortega, Joaquín Pérez, Ma Del Rocío Boone Rojas, and María J. Somodevilla. &amp;quot;Research issues on K-means Algorithm: An Experimental Trial Using Matlab.&amp;quot;&amp;lt;/ref&amp;gt;:&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;i&amp;gt;Количество кластеров является параметром алгоритма&amp;lt;/i&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;&amp;lt;i&amp;gt;Чувствительность к начальным условиям&amp;lt;/i&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;Инициализация центров кластеров в значительной степени влияет на результат кластеризации.&amp;lt;/p&amp;gt;&lt;br /&gt;
  &amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;&amp;lt;i&amp;gt;Чувствительность к выбросам и шумам&amp;lt;/i&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;Выбросы, далекие от центров настоящих кластеров, все равно учитываются при вычислении их центров.&amp;lt;/p&amp;gt;&lt;br /&gt;
  &amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;&amp;lt;i&amp;gt;Возможность сходимости к локальному оптимуму&amp;lt;/i&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;Итеративный подход не дает гарантии сходимости к оптимальному решению.&amp;lt;/p&amp;gt;&lt;br /&gt;
  &amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;&amp;lt;i&amp;gt;Использование понятия &amp;quot;среднего&amp;quot;&amp;lt;/i&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;Алгоритм неприменим к данным, для которых не определено понятие &amp;quot;среднего&amp;quot;, например, категориальным данным.&amp;lt;/p&amp;gt;&lt;br /&gt;
  &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&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;
Исследование масштабируемости параллельной реализации алгоритма k means проводилось на суперкомпьютере &amp;quot;Ломоносов&amp;quot;&amp;lt;ref name=&amp;quot;Lom&amp;quot;&amp;gt;Воеводин Вл., Жуматий С., Соболев С., Антонов А., Брызгалов П., Никитенко Д., Стефанов К., Воеводин Вад. Практика суперкомпьютера «Ломоносов» // Открытые системы, 2012, N 7, С. 36-39.&amp;lt;/ref&amp;gt; [http://parallel.ru/cluster Суперкомпьютерного комплекса Московского университета]. Алгоритм реализован на языке C с использованием средств MPI.&lt;br /&gt;
Для исследования масштабируемости проводилось множество запусков программы с разным значением параметра (количество векторов для кластеризации), а также с различным числом процессоров. Фиксировались результаты запусков &amp;amp;ndash; время работы &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt; и количество произведенных итераций алгоритма &amp;lt;math&amp;gt;\Tau&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Параметры запусков для экспериментальной оценки:&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;Значения &amp;lt;b&amp;gt;количества векторов&amp;lt;/b&amp;gt; &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;: 20&#039;000, 30&#039;000, 50&#039;000, 100&#039;000, 200&#039;000, 300&#039;000, 500&#039;000, 700&#039;000, 1&#039;000&#039;000, 1&#039;500&#039;000, 2&#039;000&#039;000.&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;Значения &amp;lt;b&amp;gt;количества процессоров&amp;lt;/b&amp;gt; &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt;: 1, 8, 16, 32, 64, 128, 160, 192, 224, 256, 288, 320, 352, 384, 416, 448, 480, 512.&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;Значение &amp;lt;b&amp;gt;количества кластеров&amp;lt;/b&amp;gt; &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt;: 100.&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;Значение &amp;lt;b&amp;gt;размерности векторов&amp;lt;/b&amp;gt; &amp;lt;math&amp;gt;d&amp;lt;/math&amp;gt;: 10.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Для проведения экспериментов были сгенерированы нормально распределенные псевдослучайные данные (с использованием Python библиотеки [http://scikit-learn.org/ scikit-learn]):&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
from sklearn.datasets import make_classification&lt;br /&gt;
X1, Y1 = make_classification(n_features=10, n_redundant=2, n_informative=8,&lt;br /&gt;
                             n_clusters_per_class=1, n_classes=100,&lt;br /&gt;
                             n_samples=2000000)&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Для заданной конфигурации эксперимента (&amp;lt;math&amp;gt;n, d, p, k&amp;lt;/math&amp;gt;) и полученных результатов (&amp;lt;math&amp;gt;t, \Tau&amp;lt;/math&amp;gt;)  [[Глоссарий#Производительность|производительность]]  и эффективность реализации расчитывались по формулам:&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
&amp;lt;ul&amp;gt;&amp;lt;li&amp;gt;&amp;lt;math&amp;gt;Performance = \frac{N_{k-means}^{d, n}}{t}\ \ (FLOPS),&amp;lt;/math&amp;gt;&amp;lt;/li&amp;gt;&amp;lt;/ul&amp;gt;&lt;br /&gt;
где &amp;lt;math&amp;gt;N_{k-means}^{d, n}&amp;lt;/math&amp;gt; &amp;amp;ndash; точное число операций с плавающей точкой (операции с памятью, а также целочисленные операции не учитывались), вычисленное в соответствие с разделом [[#Последовательная сложность алгоритма| &amp;quot;Последовательная сложность алгоритма&amp;quot;]];&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
&amp;lt;ul&amp;gt;&amp;lt;li&amp;gt;&amp;lt;math&amp;gt;Efficiency = \frac{100 * Performance}{Performance_{Peak}^{p}}\ \ (%),&amp;lt;/math&amp;gt;&amp;lt;/li&amp;gt;&amp;lt;/ul&amp;gt;&lt;br /&gt;
где &amp;lt;math&amp;gt;Performance_{Peak}^{p}&amp;lt;/math&amp;gt; &amp;amp;ndash; пиковая производительность суперкомпьютера при &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt; процессорах, вычисленная согласно спецификациям Intel&amp;lt;sup&amp;gt;&amp;amp;reg;&amp;lt;/sup&amp;gt; XEON&amp;lt;sup&amp;gt;&amp;amp;reg;&amp;lt;/sup&amp;gt; X5670&amp;lt;ref&amp;gt;&amp;quot;http://ark.intel.com/ru/products/47920/Intel-Xeon-Processor-X5670-12M-Cache-2_93-GHz-6_40-GTs-Intel-QPI&amp;quot;&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Графики зависимости производительности и эффективности параллельной реализации k means от числа векторов для кластеризации (&amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;) и числа процессоров (&amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt;) представлены на рисунках 4 и 5 соответственно.&lt;br /&gt;
&lt;br /&gt;
[[file:Flops.png|thumb|center|800px|Рис. 4. Параллельная реализация k means. График зависимости производительности реализации алгоритма от числа векторов для кластеризации (&amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;) и числа процессоров (&amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt;).]]&lt;br /&gt;
[[file:Efficiency.png|thumb|center|800px|Рис. 5. Параллельная реализация k means. График зависимости эффективности реализации алгоритма от числа векторов для кластеризации (&amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;) и числа процессоров (&amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt;).]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;В результате&amp;lt;/b&amp;gt; экспериментальной оценки были получены следующие оценки эффективности реализации:&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;b&amp;gt;Минимальное&amp;lt;/b&amp;gt; значение: 0.000409 % достигается при &amp;lt;math&amp;gt;n=20&#039;000, p=480&amp;lt;/math&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;b&amp;gt;Максимальное&amp;lt;/b&amp;gt; значение: 0.741119 % достигается при &amp;lt;math&amp;gt;n=300&#039;000, p=1&amp;lt;/math&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
Оценки масштабируемости реализации алгоритма k means:&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;b&amp;gt;По числу процессоров:&amp;lt;/b&amp;gt; -0.002683 &amp;amp;ndash; эффективность убывает с ростом числа процессоров. Данный результат вызван ростом накладных расходов для обеспечения параллельного выполнения алгоритма.&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;b&amp;gt;По размеру задачи:&amp;lt;/b&amp;gt; 0.002779 &amp;amp;ndash; эффективность растет с ростом числа векторов. Данный результат вызван тем, что при увеличении размера задачи, количество вычислений растет по сравнению с временем, затрачиваемым на пересылку данных.&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;b&amp;gt;Общая оценка:&amp;lt;/b&amp;gt; -0.000058 &amp;amp;ndash; можно сделать вывод, что в целом эффективность реализации незначительно уменьшается с ростом размера задачи и числа процессоров.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[https://github.com/serban/kmeans Использованная параллельная реализация алгоритма k means]&lt;br /&gt;
&lt;br /&gt;
=== Динамические характеристики и эффективность реализации алгоритма ===&lt;br /&gt;
=== Выводы для классов архитектур ===&lt;br /&gt;
=== Существующие реализации алгоритма ===&lt;br /&gt;
==== Открытое программное обеспечение ====&lt;br /&gt;
&amp;lt;ol&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;[https://www.icpsr.umich.edu/CrimeStat/ CrimeStat]&amp;lt;/li&amp;gt; Программное обеспечение, созданное для операционных систем Windows, предоставляющее инструменты статистического  и пространственного анализа для решения задачи картирования преступности.&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://juliastats.github.io Julia]&amp;lt;/li&amp;gt; Высокоуровневый высокопроизводительный свободный язык программирования с динамической типизацией, созданный для математических вычислений, содержит реализацию k-means.&lt;br /&gt;
  &amp;lt;li&amp;gt;[https://mahout.apache.org Mahout]&amp;lt;/li&amp;gt; Apache Mahout - Java библиотека для работы с алгоритмами машинного обучения с использованием MapReduce. Содержит реализацию k-means.&lt;br /&gt;
  &amp;lt;li&amp;gt;[https://www.gnu.org/software/octave/ Octave]&amp;lt;/li&amp;gt; Написанная на C++  свободная система для математических вычислений, использующая совместимый с MATLAB язык высокого уровня, содержит реализацию k-means.&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://spark.apache.org/docs/latest/mllib-clustering.html Spark]&amp;lt;/li&amp;gt; Распределенная реализация k-means содержится в библиотеке Mlib для работы с алгоритмами машинного обучения, взаимодействующая с Python библиотекой NumPy и библиотека R.&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://torch.ch Torch]&amp;lt;/li&amp;gt;  MATLAB-подобная библиотека для языка программирования Lua с открытым исходным кодом, предоставляет большое количество алгоритмов для глубинного обучения и научных расчётов. Ядро написано на Си, прикладная часть выполняется на LuaJIT, поддерживается распараллеливание вычислений средствами CUDA и OpenMP. Существуют реализации k-means.&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://www.cs.waikato.ac.nz/ml/weka/ Weka]&amp;lt;/li&amp;gt;  Cвободное программное обеспечение для анализа данных, написанное на Java. Содержит k-means и x-means.&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://accord-framework.net/docs/html/T_Accord_MachineLearning_KMeans.htm Accord.NET]&amp;lt;/li&amp;gt; C# реализация алгоритмов k-means, k-means++, k-modes.&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://docs.opencv.org/3.0-beta/doc/py_tutorials/py_ml/py_kmeans/py_kmeans_opencv/py_kmeans_opencv.html OpenCV]&amp;lt;/li&amp;gt; Написанная на С++ библиотека, направленная в основном на решение задач компьютерного зрения. Содержит реализацию k-means.&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://mlpack.org/ MLPACK]&amp;lt;/li&amp;gt; Масштабируемая С++ библиотека для работы с алгоритмами машинного обучения, содержит реализацию k-means.&lt;br /&gt;
  &amp;lt;li&amp;gt;[https://www.scipy.org/ SciPy]&amp;lt;/li&amp;gt; Библиотека Python, содержит множество реализаций k-means.&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://scikit-learn.org/ scikit-learn]&amp;lt;/li&amp;gt; Библиотека Python, содержит множество реализаций k-means.&lt;br /&gt;
  &amp;lt;li&amp;gt;[https://www.r-bloggers.com/k-means-clustering-in-r/ R]&amp;lt;/li&amp;gt; Язык программирования для статистической обработки данных и работы с графикой, а также свободная программная среда вычислений с открытым исходным кодом в рамках проекта GNU, содержит три реализации k-means.&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://elki.dbs.ifi.lmu.de ELKI]&amp;lt;/li&amp;gt; Java фреймворк, содержащий реализацию k-means, а также множество других алгоритмов кластеризации.&lt;br /&gt;
&amp;lt;/ol&amp;gt;&lt;br /&gt;
==== Проприетарное программное обеспечение  ====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ol&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;[https://www.ayasdi.com/blog/bigdata/topological-data-analysis-of-oil-and-gas-petrophysical-data/ Ayasdi]&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://www.stata.com/features/cluster-analysis/ Stata]&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://mathworld.wolfram.com/K-MeansClusteringAlgorithm.html Mathematica]&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://www.mathworks.com/help/stats/kmeans.html?requestedDomain=www.mathworks.com MATLAB]&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;[https://support.sas.com/rnd/app/stat/procedures/fastclus.html SAS]&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://docs.rapidminer.com/studio/operators/modeling/segmentation/k_means.html RapidMiner]&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;[https://blogs.sap.com/2013/03/28/sap-hana-pal-k-means-algorithm-or-how-to-do-customer-segmentation-for-the-telecommunications-industry/ SAP HANA]&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ol&amp;gt;&lt;br /&gt;
== Литература ==&lt;br /&gt;
&amp;lt;references /&amp;gt;&lt;/div&gt;</summary>
		<author><name>DennZo1993</name></author>
	</entry>
	<entry>
		<id>https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:%D0%91%D1%80%D0%BE%D1%82%D0%B8%D0%BA%D0%BE%D0%B2%D1%81%D0%BA%D0%B0%D1%8F_%D0%94%D0%B0%D0%BD%D1%83%D1%82%D0%B0/%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_k-means&amp;diff=20520</id>
		<title>Участник:Бротиковская Данута/Алгоритм k-means</title>
		<link rel="alternate" type="text/html" href="https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:%D0%91%D1%80%D0%BE%D1%82%D0%B8%D0%BA%D0%BE%D0%B2%D1%81%D0%BA%D0%B0%D1%8F_%D0%94%D0%B0%D0%BD%D1%83%D1%82%D0%B0/%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_k-means&amp;diff=20520"/>
		<updated>2016-12-10T10:36:14Z</updated>

		<summary type="html">&lt;p&gt;DennZo1993: /* Последовательная сложность алгоритма */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Assignment|Zhum}}&lt;br /&gt;
&lt;br /&gt;
{{algorithm&lt;br /&gt;
| name              = Алгоритм k средних (k means)&lt;br /&gt;
| serial_complexity = &amp;lt;math&amp;gt;O(\Tau*k*d*n)&amp;lt;/math&amp;gt;&lt;br /&gt;
| input_data        = &amp;lt;math&amp;gt; d*n &amp;lt;/math&amp;gt;&lt;br /&gt;
| output_data       = &amp;lt;math&amp;gt; n &amp;lt;/math&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
Авторы страницы &amp;lt;b&amp;gt;[[Участник:Бротиковская Данута|Данута Бротиковская]]&amp;lt;/b&amp;gt; и &amp;lt;b&amp;gt;[[Участник:DennZo1993|Денис Зобнин]]&amp;lt;/b&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
Оба автора внесли одинаковый вклад в написание статьи (поиск материалов, изучение статей, заполнение контента статьи), четких разграничений по пунктам статьи сделать невозможно. &lt;br /&gt;
&lt;br /&gt;
== Свойства и структура алгоритма ==&lt;br /&gt;
&lt;br /&gt;
=== Общее описание алгоритма ===&lt;br /&gt;
Алгоритм &amp;lt;b&amp;gt;&amp;lt;i&amp;gt;k средних&amp;lt;/i&amp;gt;&amp;lt;/b&amp;gt; (&amp;lt;b&amp;gt;&amp;lt;i&amp;gt;k means&amp;lt;/i&amp;gt;&amp;lt;/b&amp;gt;) &amp;amp;ndash; неиерархический&amp;lt;ref&amp;gt;&amp;quot;https://ru.wikipedia.org/wiki/Иерархическая_кластеризация&amp;quot;&amp;lt;/ref&amp;gt;, итерационный метод кластеризации&amp;lt;ref&amp;gt;&amp;quot;https://ru.wikipedia.org/wiki/Кластерный_анализ&amp;quot;&amp;lt;/ref&amp;gt;, получивший большую популярность благодаря своей простоте, наглядности реализации и достаточно высокому качеству работы. Был изобретен в 1950-х годах математиком &amp;lt;i&amp;gt;Гуго Штейнгаузом&amp;lt;/i&amp;gt;&amp;lt;ref&amp;gt;Steinhaus, Hugo. &amp;quot;Sur la division des corp materiels en parties.&amp;quot; Bull. Acad. Polon. Sci 1.804 (1956): 801.&amp;lt;/ref&amp;gt; и почти одновременно &amp;lt;i&amp;gt;Стюартом Ллойдом&amp;lt;/i&amp;gt;&amp;lt;ref&amp;gt;Lloyd, S. P. &amp;quot;Least square quantization in PCM. Bell Telephone Laboratories Paper. Published in journal much later: Lloyd, SP: Least squares quantization in PCM.&amp;quot; IEEE Trans. Inform. Theor.(1957/1982).&amp;lt;/ref&amp;gt;. Особую популярность приобрел после публикации работы &amp;lt;i&amp;gt;МакКуина&amp;lt;/i&amp;gt;&amp;lt;ref&amp;gt;MacQueen, James. &amp;quot;Some methods for classification and analysis of multivariate observations.&amp;quot; Proceedings of the fifth Berkeley symposium on mathematical statistics and probability. Vol. 1. No. 14. 1967.&amp;lt;/ref&amp;gt; в 1967.&lt;br /&gt;
&lt;br /&gt;
Алгоритм представляет собой версию EM-алгоритма&amp;lt;ref&amp;gt;&amp;quot;https://ru.wikipedia.org/wiki/EM-алгоритм&amp;quot;&amp;lt;/ref&amp;gt;, применяемого также для разделения смеси гауссиан. Основная идея &amp;lt;i&amp;gt;k means&amp;lt;/i&amp;gt; заключается в том, что данные произвольно разбиваются на кластеры, после чего итеративно перевычисляется центр масс для каждого кластера, полученного на предыдущем шаге, затем векторы разбиваются на кластеры вновь в соответствии с тем, какой из новых центров оказался ближе по выбранной метрике.&lt;br /&gt;
&lt;br /&gt;
Цель алгоритма заключается в разделении &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; наблюдений на &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластеров таким образом, чтобы каждое наблюдение принадлежало ровно одному кластеру, расположенному на наименьшем расстоянии от наблюдения.&lt;br /&gt;
&lt;br /&gt;
=== Математическое описание алгоритма ===&lt;br /&gt;
&amp;lt;b&amp;gt;&amp;lt;u&amp;gt;Дано:&amp;lt;/u&amp;gt;&amp;lt;/b&amp;gt;&lt;br /&gt;
* набор из &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; наблюдений &amp;lt;math&amp;gt;X=\{\mathbf{x}_1, \mathbf{x}_2, ..., \mathbf{x}_n\}, \mathbf{x}_i \in \mathbb{R}^d, i=\overline{1, n}&amp;lt;/math&amp;gt;;&lt;br /&gt;
* &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; - требуемое число кластеров, &amp;lt;math&amp;gt;k \in \mathbb{N}, k \leq n&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;&amp;lt;u&amp;gt;Требуется:&amp;lt;/u&amp;gt;&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Разделить множество наблюдений &amp;lt;math&amp;gt;X&amp;lt;/math&amp;gt; на &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластеров &amp;lt;math&amp;gt;S_1, S_2, ..., S_k&amp;lt;/math&amp;gt;:&lt;br /&gt;
*   &amp;lt;math&amp;gt;S_i \cap S_j= \varnothing, \quad i \ne j&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
*   &amp;lt;math&amp;gt;\bigcup_{i=1}^{k} S_i = X&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;&amp;lt;u&amp;gt;Действие алгоритма:&amp;lt;/u&amp;gt;&amp;lt;/b&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;Алгоритм &amp;lt;i&amp;gt;k means&amp;lt;/i&amp;gt; разбивает набор &amp;lt;math&amp;gt;X&amp;lt;/math&amp;gt; на &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; наборов &amp;lt;math&amp;gt;S_1, S_2, ..., S_k,&amp;lt;/math&amp;gt; таким образом, чтобы минимизировать сумму квадратов расстояний от каждой точки кластера до его центра (центр масс кластера). Введем обозначение, &amp;lt;math&amp;gt;S=\{S_1, S_2, ..., S_k\}&amp;lt;/math&amp;gt;. Тогда действие алгоритма &amp;lt;i&amp;gt;k means&amp;lt;/i&amp;gt; равносильно поиску:&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;table style=&amp;quot;width:100%&amp;quot;&amp;gt;&lt;br /&gt;
  &amp;lt;tr&amp;gt;&lt;br /&gt;
    &amp;lt;td align=&amp;quot;center&amp;quot; width=&amp;quot;90%&amp;quot;&amp;gt;&amp;lt;math&amp;gt;\arg\min_{S} \sum\limits_{i=1}^k \sum\limits_{\mathbf{x} \in S_i} \rho(\mathbf{x}, \mathbf{\mu}_i )^2,&amp;lt;/math&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;td align=&amp;quot;right&amp;quot;&amp;gt;&amp;lt;math&amp;gt;(1)&amp;lt;/math&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;/table&amp;gt;&lt;br /&gt;
где &amp;lt;math&amp;gt;\mathbf{\mu}_i&amp;lt;/math&amp;gt; &amp;amp;ndash; центры кластеров, &amp;lt;math&amp;gt;i=\overline{1,k}, \quad \rho(\mathbf{x}, \mathbf{\mu}_i)&amp;lt;/math&amp;gt; &amp;amp;ndash; функция расстояния между &amp;lt;math&amp;gt;\mathbf{x}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\mu_i&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;&amp;lt;u&amp;gt;Шаги алгоритма: &amp;lt;/u&amp;gt;&amp;lt;/b&amp;gt;&lt;br /&gt;
&amp;lt;ol&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&lt;br /&gt;
    &amp;lt;b&amp;gt;Начальный шаг: инициализация кластеров&amp;lt;/b&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;Выбирается произвольное множество точек &amp;lt;math&amp;gt;\mu_i, i=\overline{1,k}&amp;lt;/math&amp;gt;, рассматриваемых как начальные центры кластеров: &amp;lt;math&amp;gt;\mu_i^{(0)} = \mu_i, \quad i=\overline{1, k}&amp;lt;/math&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
  &amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&lt;br /&gt;
    &amp;lt;b&amp;gt;Распределение векторов по кластерам&amp;lt;/b&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Шаг&amp;lt;/b&amp;gt; &amp;lt;math&amp;gt;t: \forall \mathbf{x}_i \in X, i=\overline{1,n}: \mathbf{x}_i \in S_j \iff  j=\arg\min_{k}\rho(\mathbf{x}_i,\mathbf{\mu}_k^{(t-1)})^2&amp;lt;/math&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
  &amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&lt;br /&gt;
    &amp;lt;b&amp;gt;Пересчет центров кластеров&amp;lt;/b&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Шаг &amp;lt;/b&amp;gt; &amp;lt;math&amp;gt;t: \forall i=\overline{1,k}:  \mu_i^{(t)} = \cfrac{1}{|S_i|}\sum_{\mathbf{x}\in S_i}\mathbf{x}&amp;lt;/math&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
  &amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&lt;br /&gt;
    &amp;lt;b&amp;gt;Проверка условия останова:&amp;lt;/b&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
    &#039;&#039;&#039;if&#039;&#039;&#039; &amp;lt;math&amp;gt;\exist i\in \overline{1,k}: \mu_i^{(t)} \ne \mu_i^{(t-1)}&amp;lt;/math&amp;gt; &#039;&#039;&#039;then&#039;&#039;&#039;&lt;br /&gt;
        t = t + 1;&lt;br /&gt;
        goto 2;&lt;br /&gt;
    &#039;&#039;&#039;else&#039;&#039;&#039;&lt;br /&gt;
        &#039;&#039;&#039;stop&#039;&#039;&#039;&lt;br /&gt;
  &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ol&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Вычислительное ядро алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Вычислительным ядром являются шаги 2 и 3 приведенного выше алгоритма: &amp;lt;b&amp;gt;&amp;lt;i&amp;gt;распределение векторов по кластерам&amp;lt;/i&amp;gt;&amp;lt;/b&amp;gt; и &amp;lt;b&amp;gt;&amp;lt;i&amp;gt;пересчет центров кластеров&amp;lt;/i&amp;gt;&amp;lt;/b&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;&amp;lt;i&amp;gt;Распределение векторов&amp;lt;/i&amp;gt;&amp;lt;/b&amp;gt; по кластерам предполагает вычисление расстояний между каждым вектором &amp;lt;math&amp;gt;\mathbf{x}_i \in X, i= \overline{1,n}&amp;lt;/math&amp;gt; и центрами кластера &amp;lt;math&amp;gt;\mathbf{\mu}_j, j= \overline{1,k}&amp;lt;/math&amp;gt;. Таким образом, данный шаг предполагает &amp;lt;math&amp;gt;kn&amp;lt;/math&amp;gt; вычислений расстояний между d-мерными векторами. &lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;&amp;lt;i&amp;gt;Пересчет центров кластеров&amp;lt;/i&amp;gt;&amp;lt;/b&amp;gt; предполагает &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; вычислений центров масс &amp;lt;math&amp;gt;\mathbf{\mu}_i&amp;lt;/math&amp;gt; множеств &amp;lt;math&amp;gt;S_i, i=\overline{1,k}&amp;lt;/math&amp;gt; представленных выражением в шаге 3 представленного выше алгоритма.&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Макроструктура алгоритма ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Инициализация центров масс &amp;lt;math&amp;gt;\mu_1, ..., \mu_k&amp;lt;/math&amp;gt;&amp;lt;/b&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
Наиболее распространенными являются следующие стратегии:&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&lt;br /&gt;
    &amp;lt;b&amp;gt;Метод Forgy&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;В качестве начальных значений &amp;lt;math&amp;gt;\mu_1, ..., \mu_k&amp;lt;/math&amp;gt; берутся случайно выбранные векторы.&lt;br /&gt;
  &amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&lt;br /&gt;
    &amp;lt;b&amp;gt;Метод случайно разделения (Random Partitioning)&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;Для каждого вектора &amp;lt;math&amp;gt;\mathbf{x}_i \in X, i=\overline{1, n}&amp;lt;/math&amp;gt; выбирается случайным образом кластер &amp;lt;math&amp;gt;S_1, ..., S_k&amp;lt;/math&amp;gt;, после чего для каждого полученного кластера вычисляются значения &amp;lt;math&amp;gt;\mu_1, ..., \mu_k&amp;lt;/math&amp;gt;.&lt;br /&gt;
  &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Распределение векторов по кластерам&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Для этого шага алгоритма между векторами &amp;lt;math&amp;gt;\mathbf{x}_i \in X, i=\overline{1, n}&amp;lt;/math&amp;gt; и центрами кластеров &amp;lt;math&amp;gt;\mu_1, ..., \mu_k&amp;lt;/math&amp;gt; вычисляются &amp;lt;b&amp;gt;расстояния&amp;lt;/b&amp;gt; по формуле (как правило, используется Евлидово расстояние):&lt;br /&gt;
&amp;lt;table style=&amp;quot;width:100%&amp;quot;&amp;gt;&lt;br /&gt;
  &amp;lt;tr&amp;gt;&lt;br /&gt;
    &amp;lt;td align=&amp;quot;center&amp;quot; width=&amp;quot;90%&amp;quot;&amp;gt;&amp;lt;math&amp;gt; \mathbf{v}_1, \mathbf{v}_2 \in \mathbb{R}^d,  \quad \rho(\mathbf{v}_1, \mathbf{v}_2) = \lVert \mathbf{v}_1- \mathbf{v}_2 \rVert= \sqrt{\sum_{i=1}^{d}(\mathbf{v}_{1,i} - \mathbf{v}_{2,i})^2}&amp;lt;/math&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;td align=&amp;quot;right&amp;quot;&amp;gt;&amp;lt;math&amp;gt;(2)&amp;lt;/math&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;/table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Пересчет центров кластеров&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Для этого шага алгоритма производится пересчет центров кластера по &amp;lt;b&amp;gt;формуле вычисления центра масс&amp;lt;/b&amp;gt;:&lt;br /&gt;
&amp;lt;table style=&amp;quot;width:100%&amp;quot;&amp;gt;&lt;br /&gt;
  &amp;lt;tr&amp;gt;&lt;br /&gt;
    &amp;lt;td align=&amp;quot;center&amp;quot; width=&amp;quot;90%&amp;quot;&amp;gt;&amp;lt;math&amp;gt; \mu = \cfrac{1}{|S|}\sum_{\mathbf{x}\in S}\mathbf{x}&amp;lt;/math&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;td align=&amp;quot;right&amp;quot;&amp;gt;&amp;lt;math&amp;gt;(3)&amp;lt;/math&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;/table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Схема реализации последовательного алгоритма ===&lt;br /&gt;
&lt;br /&gt;
 &#039;&#039;&#039;algorithm&#039;&#039;&#039; k-means &#039;&#039;&#039;is&#039;&#039;&#039;&lt;br /&gt;
     &#039;&#039;&#039;1.&#039;&#039;&#039; Инициализировать центры кластеров &amp;lt;math&amp;gt;\mathbf{\mu}_i^{(1)}, i=\overline{1,k}&amp;lt;/math&amp;gt;&lt;br /&gt;
     &#039;&#039;&#039;2.&#039;&#039;&#039; &amp;lt;math&amp;gt;t \leftarrow 1&amp;lt;/math&amp;gt;&lt;br /&gt;
     &#039;&#039;&#039;3.&#039;&#039;&#039; &#039;&#039;&#039;Распределение по кластерам&#039;&#039;&#039;&amp;lt;br&amp;gt;&lt;br /&gt;
        &amp;lt;math&amp;gt;S_i^{(t)}=\{\mathbf{x}_p: \lVert\mathbf{x}_p-\mathbf{\mu}_i^{(t)}\rVert^2 \leq \lVert\mathbf{x}_p-\mathbf{\mu}_j^{(t)}\rVert^2 \quad \forall j=\overline{1,k}\},&amp;lt;/math&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
        где каждый вектор &amp;lt;math&amp;gt;\mathbf{x}_p&amp;lt;/math&amp;gt; соотносится единственному кластеру &amp;lt;math&amp;gt;S^{(t)}&amp;lt;/math&amp;gt;&lt;br /&gt;
     &#039;&#039;&#039;4.&#039;&#039;&#039; &#039;&#039;&#039;Обновление центров кластеров&#039;&#039;&#039;&amp;lt;br&amp;gt;&lt;br /&gt;
        &amp;lt;math&amp;gt;\mathbf{\mu}_i^{(t+1)} = \frac{1}{|S^{(t)}_i|} \sum_{\mathbf{x}_j \in S^{(t)}_i} \mathbf{x}_j &amp;lt;/math&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
     &#039;&#039;&#039;5.&#039;&#039;&#039; &#039;&#039;&#039;if&#039;&#039;&#039; &amp;lt;math&amp;gt;\exist i \in \overline{1,k}: \mathbf{\mu}_i^{(t+1)} \ne \mathbf{\mu}_i^{(t)}&amp;lt;/math&amp;gt; &#039;&#039;&#039;then&#039;&#039;&#039;&lt;br /&gt;
            t = t + 1;&lt;br /&gt;
            goto &#039;&#039;&#039;3&#039;&#039;&#039;;&lt;br /&gt;
        &#039;&#039;&#039;else&#039;&#039;&#039;&lt;br /&gt;
            &#039;&#039;&#039;stop&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
=== Последовательная сложность алгоритма===&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding-bottom: 20px&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;Обозначим &amp;lt;math&amp;gt;\Theta_{centroid}^{d, m}&amp;lt;/math&amp;gt; временную сложность вычисления центорида кластера, число элементов которого равна &amp;lt;math&amp;gt;m&amp;lt;/math&amp;gt;,  в d-мерном пространстве.&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;Аналогично  &amp;lt;math&amp;gt;\Theta_{distance}^d&amp;lt;/math&amp;gt; &amp;amp;ndash; временная сложность вычисления расстояния между двумя d-мерными векторами.&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding-bottom: 20px&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;Сложность шага инициализации &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластеров мощности &amp;lt;math&amp;gt;m&amp;lt;/math&amp;gt; в d-мерном пространстве &amp;amp;ndash; &amp;lt;math&amp;gt;\Theta_{init}^{k, d, m}&amp;lt;/math&amp;gt;&amp;lt;/b&amp;gt;&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;i&amp;gt;Стратерия Forgy&amp;lt;/i&amp;gt;: вычисления не требуются, &amp;lt;math&amp;gt;\Theta_{init}^{k, d, m} = 0&amp;lt;/math&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;i&amp;gt;Стратегия случайного разбиения&amp;lt;/i&amp;gt;: вычисление центров &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластеров,  &amp;lt;math&amp;gt;\Theta_{init}^{k, d, m} = k \cdot \Theta_{centroid}^{d, m}, m \le n&amp;lt;/math&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding-bottom: 20px&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Cложность шага распределения d мерных векторов по &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластерам &amp;amp;ndash; &amp;lt;math&amp;gt;\Theta_{distribute}^{k, d}&amp;lt;/math&amp;gt;&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
На этом шаге для каждого вектора &amp;lt;math&amp;gt;\mathbf{x}_i \in X, i=\overline{1, n}&amp;lt;/math&amp;gt; вычисляется k расстояний до центров кластеров &amp;lt;math&amp;gt;\mathbf{\mu}_1, ...\mathbf{\mu}_k&amp;lt;/math&amp;gt;&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p align=&amp;quot;center&amp;quot;&amp;gt;&lt;br /&gt;
  &amp;lt;math&amp;gt;\Theta_{distribute}^{k, d} = n \cdot k \cdot \Theta_{distance}^d&amp;lt;/math&amp;gt;&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding-bottom: 20px&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;Сложность шага пересчета центров &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластеров размера &amp;lt;math&amp;gt;m&amp;lt;/math&amp;gt; в d-мерном пространстве &amp;amp;ndash; &amp;lt;math&amp;gt;\Theta_{recenter}^{k, d, m}&amp;lt;/math&amp;gt;&amp;lt;/b&amp;gt;&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;На этом шаге вычисляется &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; центров кластеров &amp;lt;math&amp;gt;\mathbf{\mu}_1, ...\mathbf{\mu}_k&amp;lt;/math&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p align=&amp;quot;center&amp;quot;&amp;gt;&amp;lt;math&amp;gt;\Theta_{recenter}^{k, d, m} = k \cdot \Theta_{centroid}^{d, m}&amp;lt;/math&amp;gt; &amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding-bottom: 20px&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Рассчитаем &amp;lt;math&amp;gt;\Theta_{centroid}^{d, m}&amp;lt;/math&amp;gt; для кластера, число элементов которого равно &amp;lt;math&amp;gt;m&amp;lt;/math&amp;gt;&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p align=&amp;quot;center&amp;quot;&amp;gt;&amp;lt;math&amp;gt;\Theta_{centroid}^{d, m}&amp;lt;/math&amp;gt; = &amp;lt;math&amp;gt;m \cdot d&amp;lt;/math&amp;gt; сложений + &amp;lt;math&amp;gt;d&amp;lt;/math&amp;gt; делений &amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding-bottom: 20px&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Рассчитаем &amp;lt;math&amp;gt;\Theta_{distance}^d&amp;lt;/math&amp;gt; в соответствие с формулой &amp;lt;math&amp;gt;(2)&amp;lt;/math&amp;gt;&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p align=&amp;quot;center&amp;quot;&amp;gt;&amp;lt;math&amp;gt;\Theta_{distance}^d&amp;lt;/math&amp;gt; = &amp;lt;math&amp;gt;d&amp;lt;/math&amp;gt; вычитаний + &amp;lt;math&amp;gt;d&amp;lt;/math&amp;gt; умножений + &amp;lt;math&amp;gt;(d-1)&amp;lt;/math&amp;gt; сложение&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding-bottom: 20px&amp;quot;&amp;gt;&lt;br /&gt;
  &amp;lt;p&amp;gt;Предположим, что алгоритм сошелся за &amp;lt;math&amp;gt;\Tau&amp;lt;/math&amp;gt; итераций, тогда временная сложность алгоритма &amp;lt;math&amp;gt;\Theta_{k-means}^{d, n}&amp;lt;/math&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
  &amp;lt;p align=&amp;quot;center&amp;quot;&amp;gt;&amp;lt;b&amp;gt;&amp;lt;math&amp;gt;\Theta_{k-means}^{d, n} \le \Theta_{init}^{k, d, n} + \Tau(\Theta_{distribute}^{k, d} + \Theta_{recenter}^{k, d, n})&amp;lt;/math&amp;gt;&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding-bottom: 5px&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;Операции сложения/вычитания:&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p align=&amp;quot;center&amp;quot;&amp;gt;&amp;lt;b&amp;gt;&amp;lt;math&amp;gt;\Theta_{k-means}^{d, n} \le k \cdot n \cdot d+ \Tau \cdot (k \cdot n(2d-1) + k \cdot n \cdot d) = k \cdot n \cdot d+ \Tau \cdot (k \cdot n(3d-1)) \thicksim O(\Tau k \cdot d \cdot n)&amp;lt;/math&amp;gt;&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding-bottom: 20px&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;Операции умножения/деления:&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p align=&amp;quot;center&amp;quot;&amp;gt;&amp;lt;b&amp;gt;&amp;lt;math&amp;gt;\Theta_{k-means}^{d, n} \le k \cdot d + \Tau \cdot (k \cdot n \cdot d + k \cdot d) = k \cdot d + \Tau \cdot k \cdot d \cdot (n+1) \thicksim O(\Tau \cdot k \cdot d \cdot n) &amp;lt;/math&amp;gt;&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding-bottom: 20px&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;Получаем, что &amp;lt;b&amp;gt;временная сложность&amp;lt;/b&amp;gt; алгоритма &amp;lt;b&amp;gt;k means&amp;lt;/b&amp;gt; кластеризации &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; &amp;lt;b&amp;gt;d-мерных&amp;lt;/b&amp;gt; векторов на &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластеров за &amp;lt;math&amp;gt;\Tau&amp;lt;/math&amp;gt; итераций:&amp;lt;/p&amp;gt;&lt;br /&gt;
 &amp;lt;p align=&amp;quot;center&amp;quot;&amp;gt;&amp;lt;b&amp;gt;&amp;lt;math&amp;gt; \Theta_{k-means}^{d, n} \thicksim O(\Tau \cdot k \cdot d \cdot n) &amp;lt;/math&amp;gt;&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Информационный граф ===&lt;br /&gt;
&lt;br /&gt;
Рассмотрим информационный граф алгоритма. Алгоритм &amp;lt;i&amp;gt;k means&amp;lt;/i&amp;gt; начинается с этапа инициализации, после которого следуют итерации, на каждой из которых выполняется два последовательных шага (см. [[#Схема реализации последовательного алгоритма|&amp;quot;Схема реализации последовательного алгоритма&amp;quot;]]): &lt;br /&gt;
* распределение векторов по кластерам&lt;br /&gt;
* перерасчет центров кластеров&lt;br /&gt;
&lt;br /&gt;
Поскольку основная часть вычислений приходится на шаги итераций, распишем информационные графы данных шагов.&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Распределение векторов по кластерам&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
Информационный граф шага распределения векторов по кластерам представлен на &#039;&#039;рисунке 1&#039;&#039;. Исходами данного графа является исходные векторы &amp;lt;math&amp;gt;\mathbf{x}_1, ..., \mathbf{x}_n&amp;lt;/math&amp;gt;, а также центры кластеров &amp;lt;math&amp;gt;\mathbf{\mu}_1, ... \mathbf{\mu}_k&amp;lt;/math&amp;gt;, вычисленные ранее (на шаге инициализации, если рассматривается первая итерация алгоритма, или на шаге пересчета центров кластеров предыдущей итерации в противном случае). Каждая пара векторов данных &amp;lt;math&amp;gt;\mathbf{x}_i, i=\overline{1,n}&amp;lt;/math&amp;gt; и центров кластера &amp;lt;math&amp;gt;\mathbf{\mu}_j, j=\overline{1, k}&amp;lt;/math&amp;gt; : (&amp;lt;math&amp;gt;\mathbf{x}_i&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;\mathbf{\mu}_j&amp;lt;/math&amp;gt;) подаются на независимые узлы &amp;lt;i&amp;gt;&amp;quot;d&amp;quot;&amp;lt;/i&amp;gt; вычисления расстояния между векторами (более подробная схема вычисления расстояния представлена далее, &#039;&#039;рисунок 2&#039;&#039;). Далее узлы вычисления расстояния &amp;lt;i&amp;gt;&amp;quot;d&amp;quot;&amp;lt;/i&amp;gt;, соответствующие одному и тому же исходному вектору &amp;lt;math&amp;gt;\mathbf{x}_i&amp;lt;/math&amp;gt; передаются на один узел &amp;lt;i&amp;gt;&amp;quot;m&amp;quot;&amp;lt;/i&amp;gt;, где далее происходит вычисление новой метки кластера для каждого вектора &amp;lt;math&amp;gt;\mathbf{x}_i&amp;lt;/math&amp;gt; (берется кластер с минимальным результатом вычисления расстояния). На выходе графа выдаются метки кластеров , &amp;lt;math&amp;gt;L_1, ..., L_n&amp;lt;/math&amp;gt;, такие что &amp;lt;math&amp;gt;\forall \mathbf{x}_i, i=\overline{1, n}, \mathbf{x}_i \in S_j \Leftrightarrow L_i = j&amp;lt;/math&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
[[file:Clusterization.png|thumb|center|800px|Рис. 1. Схема распределения векторов по кластерам. &#039;&#039;d&#039;&#039; &amp;amp;ndash; вычисление расстояния между векторами; &#039;&#039;m&#039;&#039; &amp;amp;ndash; вычисление минимума.]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Вычисление расстояния между векторами&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
Подробная схема вычисления расстояния между векторами &amp;lt;math&amp;gt;\mathbf{x}_i, \mathbf{\mu}_j&amp;lt;/math&amp;gt; представлена на &#039;&#039;рисунке 2&#039;&#039;. Как показано на графе, узел вычисления расстояния между векторами &amp;lt;i&amp;gt;&amp;quot;d&amp;quot;&amp;lt;/i&amp;gt; состоит из шага взятия разности между векторами (узел &amp;quot;&amp;lt;math&amp;gt;-&amp;lt;/math&amp;gt;&amp;quot;) и взятия нормы получившегося вектора разности (узел &amp;quot;&amp;lt;math&amp;gt;||\cdot||^2&amp;lt;/math&amp;gt;&amp;quot;). Более подробно, вычисление расстояния между векторами &amp;lt;math&amp;gt;\mathbf{x}_i = {x_{i1,}, ...,{x_{in}}}, \mathbf{\mu}_j = {\mu_{j1}, ...,\mu_{jn}}&amp;lt;/math&amp;gt; может быть представлено как вычисление разности между каждой парой компонент &amp;lt;math&amp;gt;(x_{iz}, \mu_{jz}), z=\overline{1, d}&amp;lt;/math&amp;gt; (узел &amp;quot;&amp;lt;math&amp;gt;-&amp;lt;/math&amp;gt;&amp;quot;), далее возведение в квадрат для каждого узла &amp;quot;&amp;lt;math&amp;gt;-&amp;lt;/math&amp;gt;&amp;quot; (узел &amp;quot;&amp;lt;math&amp;gt;()^2&amp;lt;/math&amp;gt;&amp;quot;) и суммирования выходов всех узлов &amp;quot;&amp;lt;math&amp;gt;()^2&amp;lt;/math&amp;gt;&amp;quot; (узел &amp;quot;&amp;lt;math&amp;gt;+&amp;lt;/math&amp;gt;&amp;quot;).  &lt;br /&gt;
&lt;br /&gt;
[[file:dist_calc.png|thumb|center|800px|Рис. 2. Схема вычисления расстояния между вектором и центром кластера.]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Пересчет центров кластеров&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
Информационный граф шага пересчета центров кластеров представлен на &#039;&#039;рисунке 3&#039;&#039;. Исходами данного графа является исходные векторы &amp;lt;math&amp;gt;\mathbf{x}_1, ..., \mathbf{x}_n&amp;lt;/math&amp;gt;, а также им соответствующие метки кластера, &amp;lt;math&amp;gt;L_1, ..., L_n&amp;lt;/math&amp;gt;, такие что &amp;lt;math&amp;gt;\forall x_i, i=\overline{1, n}, \mathbf{x}_i \in S_j \Leftrightarrow L_i = j&amp;lt;/math&amp;gt;, вычисленные на этапе распределения векторов по кластерам. Все векторы &amp;lt;math&amp;gt;\mathbf{x}_1, ..., \mathbf{x}_n&amp;lt;/math&amp;gt; подаются в узлы &amp;lt;math&amp;gt;+_1, ...+_k&amp;lt;/math&amp;gt;, каждый узел &amp;lt;math&amp;gt;+_m, m = \overline{1,k}&amp;lt;/math&amp;gt; соответствует операции сложения векторов кластера с номером &amp;lt;math&amp;gt;m&amp;lt;/math&amp;gt;. Метки кластера &amp;lt;math&amp;gt;L_1, ..., L_n&amp;lt;/math&amp;gt; также совместно передаются на узлы &amp;lt;math&amp;gt;S_m, m = \overline{1,k}&amp;lt;/math&amp;gt;, на каждом из которых вычисляется количество векторов в соответствующем кластере (количество меток с соответствующим значением). Далее каждая пара выходов узлов &amp;lt;math&amp;gt;+_m&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;S_m&amp;lt;/math&amp;gt; подается на узел &amp;quot;&amp;lt;math&amp;gt;/&amp;lt;/math&amp;gt;&amp;quot;, где производится деление суммы векторов кластера на количество элементов в нем. Значения, вычисленные на узлах &amp;quot;&amp;lt;math&amp;gt;/&amp;lt;/math&amp;gt;&amp;quot;, присваиваются новым центрам кластеров (выходные значения графа).&lt;br /&gt;
&lt;br /&gt;
[[file:Recluster.png|thumb|center|800px|Рис. 3. Схема пересчета центров кластеров]]&lt;br /&gt;
&lt;br /&gt;
=== Ресурс параллелизма алгоритма ===&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
Работа алгоритма состоит из &amp;lt;math&amp;gt;\Tau&amp;lt;/math&amp;gt; итераций, в каждой из которых происходит &amp;lt;b&amp;gt;распределение d-мерных векторов по &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластерам&amp;lt;/b&amp;gt;, а также &amp;lt;b&amp;gt;пересчет центров кластеров в d-мерном пространстве&amp;lt;/b&amp;gt;. В шаге &amp;lt;b&amp;gt;распределения d-мерных векторов по &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластерам&amp;lt;/b&amp;gt; расстояния между вектором и центрами кластеров вычисляются независимо (отсутствуют информационные зависимости). &amp;lt;b&amp;gt;Центры масс кластеров&amp;lt;/b&amp;gt; также пересчитываются независимо друг от друга. Таким образом, имеет место [[глоссарий#Массовый параллелизм|&#039;&#039;массовый параллелизм&#039;&#039;]]. Вычислим параллельную сложность &amp;lt;math&amp;gt;\Psi_*&amp;lt;/math&amp;gt; каждого из шагов, а также параллельную сложность всего алгоритма, &amp;lt;math&amp;gt;\Psi_{k-means}&amp;lt;/math&amp;gt;. Будем исходить из предположения, что может быть использовано любое необходимое число потоков.&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Распределение d-мерных векторов по &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластерам&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;  &lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
Поскольку на данном шаге для каждой пары векторов &amp;lt;math&amp;gt;\mathbf{x}_i, i=\overline{1,n}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\mathbf{\mu}_j, j=\overline{1,k}&amp;lt;/math&amp;gt; операции вычисления расстояния не зависят друг от друга, они могут выполняться параллельно. Тогда, разделив все вычисление расстояний на &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; потоков, получим, что в каждом потоке будет выполняться только одна операция вычисления расстояния между векторами размерности d. При этом каждому вычислительному потоку передаются координаты центров всех кластеров &amp;lt;math&amp;gt;\mathbf{\mu}_1, ..., \mathbf{\mu}_k&amp;lt;/math&amp;gt;. Таким образом, параллельная сложность данного шага определяется &amp;lt;i&amp;gt; сложностью параллельной операции вычисления расстояния между d-мерными векторами&amp;lt;/i&amp;gt;, &amp;lt;math&amp;gt;\Psi_{distance}^d&amp;lt;/math&amp;gt;  и &amp;lt;i&amp;gt;сложностью определения наиболее близкого кластера&amp;lt;/i&amp;gt; (паралельное взятие минимума по расстояниям), &amp;lt;math&amp;gt;\Psi_{min}^k&amp;lt;/math&amp;gt;. Для оценки &amp;lt;math&amp;gt;\Psi_{distance}^d&amp;lt;/math&amp;gt; воспользуемся  [[Нахождение_частных_сумм_элементов_массива_сдваиванием | параллельной реализацией нахождения частичной суммы элементов массива путем сдваивания]]. Аналогично, &amp;lt;math&amp;gt;\Psi_{min}^k = log(k)&amp;lt;/math&amp;gt;. В результате, &amp;lt;math&amp;gt;\Psi_{distance}^d = O(log(d))&amp;lt;/math&amp;gt;.   Таким образом: &lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p align=&amp;quot;center&amp;quot;&amp;gt;&amp;lt;math&amp;gt;\Psi_{distribute}^{k, d}  = \Psi_{distance}^d + \Psi_{min}^k = O(log(d))+O(log(k)) = O(log(k*d))&amp;lt;/math&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Пересчет центров кластеров в d-мерном пространстве&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
Поскольку на данном шаге для каждого из &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластеров центр масс может быть вычислен независимо, данные операции могут быть выполнены в отдельных потоках. Таким образом, параллельная сложность данного шага, &amp;lt;math&amp;gt;\Psi_{recenter}^{k, d}&amp;lt;/math&amp;gt;,  будет определяться &amp;lt;i&amp;gt;параллельной сложностью вычисления одного центра масс кластера размера &amp;lt;math&amp;gt;m&amp;lt;/math&amp;gt;&amp;lt;/i&amp;gt;, &amp;lt;math&amp;gt;\Psi_{recenter}^{k, d}&amp;lt;/math&amp;gt;,  а так как &amp;lt;math&amp;gt;m \le n \Rightarrow \Psi_{recenter}^{d, m} \le \Psi_{recenter}^{d, n}&amp;lt;/math&amp;gt;. Сложность вычисления центра масс кластера d-мерных векторов размера n аналогично предыдущим вычислениям равна &amp;lt;math&amp;gt;O(log(n))&amp;lt;/math&amp;gt;. Тогда:  &lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p align=&amp;quot;center&amp;quot;&amp;gt;&amp;lt;math&amp;gt;\Psi_{recenter}^{k, d}  \le \Psi_{recenter}^{d, n} = O(log(n))&amp;lt;/math&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Общая параллельная сложность алгоритма&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
На каждой итерации необходимо обновление центров кластеров, которые будут использованы на следующей итерации. Таким образом, итерационный процесс выполняется последовательно&amp;lt;ref&amp;gt;Zhao, Weizhong, Huifang Ma, and Qing He. &amp;quot;Parallel k-means clustering based on mapreduce.&amp;quot; IEEE International Conference on Cloud Computing. Springer Berlin Heidelberg, 2009.&amp;lt;/ref&amp;gt;. Тогда, поскольку сложность каждой итерации  определяется &amp;lt;math&amp;gt;\Psi_{distribute}^{k, d}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\Psi_{recenter}&amp;lt;/math&amp;gt;, сложность всего алгоритма, &amp;lt;math&amp;gt;\Psi_{k-means}&amp;lt;/math&amp;gt; в предположении, что было сделано &amp;lt;math&amp;gt;\Tau&amp;lt;/math&amp;gt; операций определяется выражением&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p align=&amp;quot;center&amp;quot;&amp;gt;&amp;lt;math&amp;gt;\Psi_{k-means} \approx \Tau * (\Psi_{distribute}^{k, d} + \Psi_{recenter}^{k, d}) \le \Tau * O(log(k*d*n))&amp;lt;/math&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Входные и выходные данные алгоритма ===&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;Входные данные&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;Матрица из &amp;lt;math&amp;gt;n*d&amp;lt;/math&amp;gt; элементов &amp;lt;math&amp;gt;x_{i, j} \in \mathbb{R}, i=\overline{1, n}, j=\overline{1, d}&amp;lt;/math&amp;gt;&amp;amp;ndash; координат векторов (наблюдений).&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;Целое положительное число &amp;lt;math&amp;gt;k, k \le n&amp;lt;/math&amp;gt; &amp;amp;ndash; количество кластеров.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;Объем входных данных&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;math&amp;gt;1&amp;lt;/math&amp;gt; целое число + &amp;lt;math&amp;gt;n*d&amp;lt;/math&amp;gt; вещественных чисел (при условии, что координаты &amp;amp;ndash; вещественные числа).&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;Выходные данные&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; целых положительных чисел &amp;lt;math&amp;gt;L_1, ..., L_n&amp;lt;/math&amp;gt;&amp;amp;ndash; номера кластеров, соотвествующие каждому вектору (при условии, что нумерация кластеров начинается с &amp;lt;math&amp;gt;1&amp;lt;/math&amp;gt;).&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;Объем выходных данных&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; целых положительных чисел.&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Свойства алгоритма ===&lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;[[глоссарий#Вычислительная мощность|&#039;&#039;Вычислительная мощность&#039;&#039;]]&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
Вычислительная мощность алгоритма &amp;lt;i&amp;gt;k means&amp;lt;/i&amp;gt; равна &amp;lt;math&amp;gt;\frac{k*d*n*\Tau}{n*d} = k*\Tau &amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; &amp;amp;ndash; число кластеров, &amp;lt;math&amp;gt;\Tau&amp;lt;/math&amp;gt; &amp;amp;ndash; число итераций алгоритма.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;[[глоссарий#Детерминированность |&#039;&#039;Детерминированность&#039;&#039;]] и [[глоссарий#Устойчивость |&#039;&#039;Устойчивость&#039;&#039;]] &amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
Алгоритм &amp;lt;i&amp;gt;k means&amp;lt;/i&amp;gt; является итерационным. Количество итераций алгоритма в общем случае не фиксируется и зависит от начального расположения объектов в пространстве, параметра &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt;, а также от начального приближения центров кластеров, &amp;lt;math&amp;gt;\mu_1, ..., \mu_k&amp;lt;/math&amp;gt;. В результате этого может варьироваться результат работы алгоритма. При неудачном выборе начальных параметров итерационный процесс может сойтись к локальному оптимуму&amp;lt;ref&amp;gt;Von Luxburg, Ulrike. Clustering Stability. Now Publishers Inc, 2010.&amp;lt;/ref&amp;gt;. По этим причинам алгоритм не является ни &amp;lt;b&amp;gt;детермирированным&amp;lt;/b&amp;gt;, ни &amp;lt;b&amp;gt;устойчивым&amp;lt;/b&amp;gt;.&lt;br /&gt;
 &lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Соотношение последовательной и параллельной сложности алгоритма&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\frac{\Theta_{k-means}}{\Psi_{k-means}} = \frac{O(\Tau*k*d*n)}{O(\Tau*log(k*d*n))}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Сильные стороны алгоритма&amp;lt;/b&amp;gt;:&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;i&amp;gt;Сравнительно высокая эффективность при простоте реализации&amp;lt;/i&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;i&amp;gt;Высокое качество кластеризации&amp;lt;/i&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;i&amp;gt;Возможность распараллеливания&amp;lt;/i&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;i&amp;gt;Существование множества модификаций&amp;lt;/i&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;Недостатки алгоритма&amp;lt;/b&amp;gt;&amp;lt;ref&amp;gt;Ortega, Joaquín Pérez, Ma Del Rocío Boone Rojas, and María J. Somodevilla. &amp;quot;Research issues on K-means Algorithm: An Experimental Trial Using Matlab.&amp;quot;&amp;lt;/ref&amp;gt;:&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;i&amp;gt;Количество кластеров является параметром алгоритма&amp;lt;/i&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;&amp;lt;i&amp;gt;Чувствительность к начальным условиям&amp;lt;/i&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;Инициализация центров кластеров в значительной степени влияет на результат кластеризации.&amp;lt;/p&amp;gt;&lt;br /&gt;
  &amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;&amp;lt;i&amp;gt;Чувствительность к выбросам и шумам&amp;lt;/i&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;Выбросы, далекие от центров настоящих кластеров, все равно учитываются при вычислении их центров.&amp;lt;/p&amp;gt;&lt;br /&gt;
  &amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;&amp;lt;i&amp;gt;Возможность сходимости к локальному оптимуму&amp;lt;/i&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;Итеративный подход не дает гарантии сходимости к оптимальному решению.&amp;lt;/p&amp;gt;&lt;br /&gt;
  &amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;&amp;lt;i&amp;gt;Использование понятия &amp;quot;среднего&amp;quot;&amp;lt;/i&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;Алгоритм неприменим к данным, для которых не определено понятие &amp;quot;среднего&amp;quot;, например, категориальным данным.&amp;lt;/p&amp;gt;&lt;br /&gt;
  &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&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;
Исследование масштабируемости параллельной реализации алгоритма k means проводилось на суперкомпьютере &amp;quot;Ломоносов&amp;quot;&amp;lt;ref name=&amp;quot;Lom&amp;quot;&amp;gt;Воеводин Вл., Жуматий С., Соболев С., Антонов А., Брызгалов П., Никитенко Д., Стефанов К., Воеводин Вад. Практика суперкомпьютера «Ломоносов» // Открытые системы, 2012, N 7, С. 36-39.&amp;lt;/ref&amp;gt; [http://parallel.ru/cluster Суперкомпьютерного комплекса Московского университета]. Алгоритм реализован на языке C с использованием средств MPI.&lt;br /&gt;
Для исследования масштабируемости проводилось множество запусков программы с разным значением параметра (количество векторов для кластеризации), а также с различным числом процессоров. Фиксировались результаты запусков &amp;amp;ndash; время работы &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt; и количество произведенных итераций алгоритма &amp;lt;math&amp;gt;\Tau&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Параметры запусков для экспериментальной оценки:&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;Значения &amp;lt;b&amp;gt;количества векторов&amp;lt;/b&amp;gt; &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;: 20&#039;000, 30&#039;000, 50&#039;000, 100&#039;000, 200&#039;000, 300&#039;000, 500&#039;000, 700&#039;000, 1&#039;000&#039;000, 1&#039;500&#039;000, 2&#039;000&#039;000.&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;Значения &amp;lt;b&amp;gt;количества процессоров&amp;lt;/b&amp;gt; &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt;: 1, 8, 16, 32, 64, 128, 160, 192, 224, 256, 288, 320, 352, 384, 416, 448, 480, 512.&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;Значение &amp;lt;b&amp;gt;количества кластеров&amp;lt;/b&amp;gt; &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt;: 100.&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;Значение &amp;lt;b&amp;gt;размерности векторов&amp;lt;/b&amp;gt; &amp;lt;math&amp;gt;d&amp;lt;/math&amp;gt;: 10.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Для проведения экспериментов были сгенерированы нормально распределенные псевдослучайные данные (с использованием Python библиотеки [http://scikit-learn.org/ scikit-learn]):&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
from sklearn.datasets import make_classification&lt;br /&gt;
X1, Y1 = make_classification(n_features=10, n_redundant=2, n_informative=8,&lt;br /&gt;
                             n_clusters_per_class=1, n_classes=100,&lt;br /&gt;
                             n_samples=2000000)&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Для заданной конфигурации эксперимента (&amp;lt;math&amp;gt;n, d, p, k&amp;lt;/math&amp;gt;) и полученных результатов (&amp;lt;math&amp;gt;t, \Tau&amp;lt;/math&amp;gt;)  [[Глоссарий#Производительность|производительность]]  и эффективность реализации расчитывались по формулам:&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
&amp;lt;ul&amp;gt;&amp;lt;li&amp;gt;&amp;lt;math&amp;gt;Performance = \frac{N_{k-means}^{d, n}}{t}\ \ (FLOPS),&amp;lt;/math&amp;gt;&amp;lt;/li&amp;gt;&amp;lt;/ul&amp;gt;&lt;br /&gt;
где &amp;lt;math&amp;gt;N_{k-means}^{d, n}&amp;lt;/math&amp;gt; &amp;amp;ndash; точное число операций с плавающей точкой (операции с памятью, а также целочисленные операции не учитывались), вычисленное в соответствие с разделом [[#Последовательная сложность алгоритма| &amp;quot;Последовательная сложность алгоритма&amp;quot;]];&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
&amp;lt;ul&amp;gt;&amp;lt;li&amp;gt;&amp;lt;math&amp;gt;Efficiency = \frac{100 * Performance}{Performance_{Peak}^{p}}\ \ (%),&amp;lt;/math&amp;gt;&amp;lt;/li&amp;gt;&amp;lt;/ul&amp;gt;&lt;br /&gt;
где &amp;lt;math&amp;gt;Performance_{Peak}^{p}&amp;lt;/math&amp;gt; &amp;amp;ndash; пиковая производительность суперкомпьютера при &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt; процессорах, вычисленная согласно спецификациям Intel&amp;lt;sup&amp;gt;&amp;amp;reg;&amp;lt;/sup&amp;gt; XEON&amp;lt;sup&amp;gt;&amp;amp;reg;&amp;lt;/sup&amp;gt; X5670&amp;lt;ref&amp;gt;&amp;quot;http://ark.intel.com/ru/products/47920/Intel-Xeon-Processor-X5670-12M-Cache-2_93-GHz-6_40-GTs-Intel-QPI&amp;quot;&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Графики зависимости производительности и эффективности параллельной реализации k means от числа векторов для кластеризации (&amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;) и числа процессоров (&amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt;) представлены на рисунках 4 и 5 соответственно.&lt;br /&gt;
&lt;br /&gt;
[[file:Flops.png|thumb|center|800px|Рис. 4. Параллельная реализация k means. График зависимости производительности реализации алгоритма от числа векторов для кластеризации (&amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;) и числа процессоров (&amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt;).]]&lt;br /&gt;
[[file:Efficiency.png|thumb|center|800px|Рис. 5. Параллельная реализация k means. График зависимости эффективности реализации алгоритма от числа векторов для кластеризации (&amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;) и числа процессоров (&amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt;).]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;В результате&amp;lt;/b&amp;gt; экспериментальной оценки были получены следующие оценки эффективности реализации:&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;b&amp;gt;Минимальное&amp;lt;/b&amp;gt; значение: 0.000409 % достигается при &amp;lt;math&amp;gt;n=20&#039;000, p=480&amp;lt;/math&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;b&amp;gt;Максимальное&amp;lt;/b&amp;gt; значение: 0.741119 % достигается при &amp;lt;math&amp;gt;n=300&#039;000, p=1&amp;lt;/math&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
Оценки масштабируемости реализации алгоритма k means:&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;b&amp;gt;По числу процессоров:&amp;lt;/b&amp;gt; -0.002683 &amp;amp;ndash; эффективность убывает с ростом числа процессоров. Данный результат вызван ростом накладных расходов для обеспечения параллельного выполнения алгоритма.&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;b&amp;gt;По размеру задачи:&amp;lt;/b&amp;gt; 0.002779 &amp;amp;ndash; эффективность растет с ростом числа векторов. Данный результат вызван тем, что при увеличении размера задачи, количество вычислений растет по сравнению с временем, затрачиваемым на пересылку данных.&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;b&amp;gt;Общая оценка:&amp;lt;/b&amp;gt; -0.000058 &amp;amp;ndash; можно сделать вывод, что в целом эффективность реализации незначительно уменьшается с ростом размера задачи и числа процессоров.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[https://github.com/serban/kmeans Использованная параллельная реализация алгоритма k means]&lt;br /&gt;
&lt;br /&gt;
=== Динамические характеристики и эффективность реализации алгоритма ===&lt;br /&gt;
=== Выводы для классов архитектур ===&lt;br /&gt;
=== Существующие реализации алгоритма ===&lt;br /&gt;
==== Открытое программное обеспечение ====&lt;br /&gt;
&amp;lt;ol&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;[https://www.icpsr.umich.edu/CrimeStat/ CrimeStat]&amp;lt;/li&amp;gt; Программное обеспечение, созданное для операционных систем Windows, предоставляющее инструменты статистического  и пространственного анализа для решения задачи картирования преступности.&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://juliastats.github.io Julia]&amp;lt;/li&amp;gt; Высокоуровневый высокопроизводительный свободный язык программирования с динамической типизацией, созданный для математических вычислений, содержит реализацию k-means.&lt;br /&gt;
  &amp;lt;li&amp;gt;[https://mahout.apache.org Mahout]&amp;lt;/li&amp;gt; Apache Mahout - Java библиотека для работы с алгоритмами машинного обучения с использованием MapReduce. Содержит реализацию k-means.&lt;br /&gt;
  &amp;lt;li&amp;gt;[https://www.gnu.org/software/octave/ Octave]&amp;lt;/li&amp;gt; Написанная на C++  свободная система для математических вычислений, использующая совместимый с MATLAB язык высокого уровня, содержит реализацию k-means.&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://spark.apache.org/docs/latest/mllib-clustering.html Spark]&amp;lt;/li&amp;gt; Распределенная реализация k-means содержится в библиотеке Mlib для работы с алгоритмами машинного обучения, взаимодействующая с Python библиотекой NumPy и библиотека R.&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://torch.ch Torch]&amp;lt;/li&amp;gt;  MATLAB-подобная библиотека для языка программирования Lua с открытым исходным кодом, предоставляет большое количество алгоритмов для глубинного обучения и научных расчётов. Ядро написано на Си, прикладная часть выполняется на LuaJIT, поддерживается распараллеливание вычислений средствами CUDA и OpenMP. Существуют реализации k-means.&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://www.cs.waikato.ac.nz/ml/weka/ Weka]&amp;lt;/li&amp;gt;  Cвободное программное обеспечение для анализа данных, написанное на Java. Содержит k-means и x-means.&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://accord-framework.net/docs/html/T_Accord_MachineLearning_KMeans.htm Accord.NET]&amp;lt;/li&amp;gt; C# реализация алгоритмов k-means, k-means++, k-modes.&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://docs.opencv.org/3.0-beta/doc/py_tutorials/py_ml/py_kmeans/py_kmeans_opencv/py_kmeans_opencv.html OpenCV]&amp;lt;/li&amp;gt; Написанная на С++ библиотека, направленная в основном на решение задач компьютерного зрения. Содержит реализацию k-means.&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://mlpack.org/ MLPACK]&amp;lt;/li&amp;gt; Масштабируемая С++ библиотека для работы с алгоритмами машинного обучения, содержит реализацию k-means.&lt;br /&gt;
  &amp;lt;li&amp;gt;[https://www.scipy.org/ SciPy]&amp;lt;/li&amp;gt; Библиотека Python, содержит множество реализаций k-means.&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://scikit-learn.org/ scikit-learn]&amp;lt;/li&amp;gt; Библиотека Python, содержит множество реализаций k-means.&lt;br /&gt;
  &amp;lt;li&amp;gt;[https://www.r-bloggers.com/k-means-clustering-in-r/ R]&amp;lt;/li&amp;gt; Язык программирования для статистической обработки данных и работы с графикой, а также свободная программная среда вычислений с открытым исходным кодом в рамках проекта GNU, содержит три реализации k-means.&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://elki.dbs.ifi.lmu.de ELKI]&amp;lt;/li&amp;gt; Java фреймворк, содержащий реализацию k-means, а также множество других алгоритмов кластеризации.&lt;br /&gt;
&amp;lt;/ol&amp;gt;&lt;br /&gt;
==== Проприетарное программное обеспечение  ====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ol&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;[https://www.ayasdi.com/blog/bigdata/topological-data-analysis-of-oil-and-gas-petrophysical-data/ Ayasdi]&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://www.stata.com/features/cluster-analysis/ Stata]&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://mathworld.wolfram.com/K-MeansClusteringAlgorithm.html Mathematica]&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://www.mathworks.com/help/stats/kmeans.html?requestedDomain=www.mathworks.com MATLAB]&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;[https://support.sas.com/rnd/app/stat/procedures/fastclus.html SAS]&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://docs.rapidminer.com/studio/operators/modeling/segmentation/k_means.html RapidMiner]&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;[https://blogs.sap.com/2013/03/28/sap-hana-pal-k-means-algorithm-or-how-to-do-customer-segmentation-for-the-telecommunications-industry/ SAP HANA]&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ol&amp;gt;&lt;br /&gt;
== Литература ==&lt;br /&gt;
&amp;lt;references /&amp;gt;&lt;/div&gt;</summary>
		<author><name>DennZo1993</name></author>
	</entry>
	<entry>
		<id>https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:%D0%91%D1%80%D0%BE%D1%82%D0%B8%D0%BA%D0%BE%D0%B2%D1%81%D0%BA%D0%B0%D1%8F_%D0%94%D0%B0%D0%BD%D1%83%D1%82%D0%B0/%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_k-means&amp;diff=20519</id>
		<title>Участник:Бротиковская Данута/Алгоритм k-means</title>
		<link rel="alternate" type="text/html" href="https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:%D0%91%D1%80%D0%BE%D1%82%D0%B8%D0%BA%D0%BE%D0%B2%D1%81%D0%BA%D0%B0%D1%8F_%D0%94%D0%B0%D0%BD%D1%83%D1%82%D0%B0/%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_k-means&amp;diff=20519"/>
		<updated>2016-12-10T10:35:13Z</updated>

		<summary type="html">&lt;p&gt;DennZo1993: /* Последовательная сложность алгоритма */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Assignment|Zhum}}&lt;br /&gt;
&lt;br /&gt;
{{algorithm&lt;br /&gt;
| name              = Алгоритм k средних (k means)&lt;br /&gt;
| serial_complexity = &amp;lt;math&amp;gt;O(\Tau*k*d*n)&amp;lt;/math&amp;gt;&lt;br /&gt;
| input_data        = &amp;lt;math&amp;gt; d*n &amp;lt;/math&amp;gt;&lt;br /&gt;
| output_data       = &amp;lt;math&amp;gt; n &amp;lt;/math&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
Авторы страницы &amp;lt;b&amp;gt;[[Участник:Бротиковская Данута|Данута Бротиковская]]&amp;lt;/b&amp;gt; и &amp;lt;b&amp;gt;[[Участник:DennZo1993|Денис Зобнин]]&amp;lt;/b&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
Оба автора внесли одинаковый вклад в написание статьи (поиск материалов, изучение статей, заполнение контента статьи), четких разграничений по пунктам статьи сделать невозможно. &lt;br /&gt;
&lt;br /&gt;
== Свойства и структура алгоритма ==&lt;br /&gt;
&lt;br /&gt;
=== Общее описание алгоритма ===&lt;br /&gt;
Алгоритм &amp;lt;b&amp;gt;&amp;lt;i&amp;gt;k средних&amp;lt;/i&amp;gt;&amp;lt;/b&amp;gt; (&amp;lt;b&amp;gt;&amp;lt;i&amp;gt;k means&amp;lt;/i&amp;gt;&amp;lt;/b&amp;gt;) &amp;amp;ndash; неиерархический&amp;lt;ref&amp;gt;&amp;quot;https://ru.wikipedia.org/wiki/Иерархическая_кластеризация&amp;quot;&amp;lt;/ref&amp;gt;, итерационный метод кластеризации&amp;lt;ref&amp;gt;&amp;quot;https://ru.wikipedia.org/wiki/Кластерный_анализ&amp;quot;&amp;lt;/ref&amp;gt;, получивший большую популярность благодаря своей простоте, наглядности реализации и достаточно высокому качеству работы. Был изобретен в 1950-х годах математиком &amp;lt;i&amp;gt;Гуго Штейнгаузом&amp;lt;/i&amp;gt;&amp;lt;ref&amp;gt;Steinhaus, Hugo. &amp;quot;Sur la division des corp materiels en parties.&amp;quot; Bull. Acad. Polon. Sci 1.804 (1956): 801.&amp;lt;/ref&amp;gt; и почти одновременно &amp;lt;i&amp;gt;Стюартом Ллойдом&amp;lt;/i&amp;gt;&amp;lt;ref&amp;gt;Lloyd, S. P. &amp;quot;Least square quantization in PCM. Bell Telephone Laboratories Paper. Published in journal much later: Lloyd, SP: Least squares quantization in PCM.&amp;quot; IEEE Trans. Inform. Theor.(1957/1982).&amp;lt;/ref&amp;gt;. Особую популярность приобрел после публикации работы &amp;lt;i&amp;gt;МакКуина&amp;lt;/i&amp;gt;&amp;lt;ref&amp;gt;MacQueen, James. &amp;quot;Some methods for classification and analysis of multivariate observations.&amp;quot; Proceedings of the fifth Berkeley symposium on mathematical statistics and probability. Vol. 1. No. 14. 1967.&amp;lt;/ref&amp;gt; в 1967.&lt;br /&gt;
&lt;br /&gt;
Алгоритм представляет собой версию EM-алгоритма&amp;lt;ref&amp;gt;&amp;quot;https://ru.wikipedia.org/wiki/EM-алгоритм&amp;quot;&amp;lt;/ref&amp;gt;, применяемого также для разделения смеси гауссиан. Основная идея &amp;lt;i&amp;gt;k means&amp;lt;/i&amp;gt; заключается в том, что данные произвольно разбиваются на кластеры, после чего итеративно перевычисляется центр масс для каждого кластера, полученного на предыдущем шаге, затем векторы разбиваются на кластеры вновь в соответствии с тем, какой из новых центров оказался ближе по выбранной метрике.&lt;br /&gt;
&lt;br /&gt;
Цель алгоритма заключается в разделении &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; наблюдений на &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластеров таким образом, чтобы каждое наблюдение принадлежало ровно одному кластеру, расположенному на наименьшем расстоянии от наблюдения.&lt;br /&gt;
&lt;br /&gt;
=== Математическое описание алгоритма ===&lt;br /&gt;
&amp;lt;b&amp;gt;&amp;lt;u&amp;gt;Дано:&amp;lt;/u&amp;gt;&amp;lt;/b&amp;gt;&lt;br /&gt;
* набор из &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; наблюдений &amp;lt;math&amp;gt;X=\{\mathbf{x}_1, \mathbf{x}_2, ..., \mathbf{x}_n\}, \mathbf{x}_i \in \mathbb{R}^d, i=\overline{1, n}&amp;lt;/math&amp;gt;;&lt;br /&gt;
* &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; - требуемое число кластеров, &amp;lt;math&amp;gt;k \in \mathbb{N}, k \leq n&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;&amp;lt;u&amp;gt;Требуется:&amp;lt;/u&amp;gt;&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Разделить множество наблюдений &amp;lt;math&amp;gt;X&amp;lt;/math&amp;gt; на &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластеров &amp;lt;math&amp;gt;S_1, S_2, ..., S_k&amp;lt;/math&amp;gt;:&lt;br /&gt;
*   &amp;lt;math&amp;gt;S_i \cap S_j= \varnothing, \quad i \ne j&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
*   &amp;lt;math&amp;gt;\bigcup_{i=1}^{k} S_i = X&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;&amp;lt;u&amp;gt;Действие алгоритма:&amp;lt;/u&amp;gt;&amp;lt;/b&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;Алгоритм &amp;lt;i&amp;gt;k means&amp;lt;/i&amp;gt; разбивает набор &amp;lt;math&amp;gt;X&amp;lt;/math&amp;gt; на &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; наборов &amp;lt;math&amp;gt;S_1, S_2, ..., S_k,&amp;lt;/math&amp;gt; таким образом, чтобы минимизировать сумму квадратов расстояний от каждой точки кластера до его центра (центр масс кластера). Введем обозначение, &amp;lt;math&amp;gt;S=\{S_1, S_2, ..., S_k\}&amp;lt;/math&amp;gt;. Тогда действие алгоритма &amp;lt;i&amp;gt;k means&amp;lt;/i&amp;gt; равносильно поиску:&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;table style=&amp;quot;width:100%&amp;quot;&amp;gt;&lt;br /&gt;
  &amp;lt;tr&amp;gt;&lt;br /&gt;
    &amp;lt;td align=&amp;quot;center&amp;quot; width=&amp;quot;90%&amp;quot;&amp;gt;&amp;lt;math&amp;gt;\arg\min_{S} \sum\limits_{i=1}^k \sum\limits_{\mathbf{x} \in S_i} \rho(\mathbf{x}, \mathbf{\mu}_i )^2,&amp;lt;/math&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;td align=&amp;quot;right&amp;quot;&amp;gt;&amp;lt;math&amp;gt;(1)&amp;lt;/math&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;/table&amp;gt;&lt;br /&gt;
где &amp;lt;math&amp;gt;\mathbf{\mu}_i&amp;lt;/math&amp;gt; &amp;amp;ndash; центры кластеров, &amp;lt;math&amp;gt;i=\overline{1,k}, \quad \rho(\mathbf{x}, \mathbf{\mu}_i)&amp;lt;/math&amp;gt; &amp;amp;ndash; функция расстояния между &amp;lt;math&amp;gt;\mathbf{x}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\mu_i&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;&amp;lt;u&amp;gt;Шаги алгоритма: &amp;lt;/u&amp;gt;&amp;lt;/b&amp;gt;&lt;br /&gt;
&amp;lt;ol&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&lt;br /&gt;
    &amp;lt;b&amp;gt;Начальный шаг: инициализация кластеров&amp;lt;/b&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;Выбирается произвольное множество точек &amp;lt;math&amp;gt;\mu_i, i=\overline{1,k}&amp;lt;/math&amp;gt;, рассматриваемых как начальные центры кластеров: &amp;lt;math&amp;gt;\mu_i^{(0)} = \mu_i, \quad i=\overline{1, k}&amp;lt;/math&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
  &amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&lt;br /&gt;
    &amp;lt;b&amp;gt;Распределение векторов по кластерам&amp;lt;/b&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Шаг&amp;lt;/b&amp;gt; &amp;lt;math&amp;gt;t: \forall \mathbf{x}_i \in X, i=\overline{1,n}: \mathbf{x}_i \in S_j \iff  j=\arg\min_{k}\rho(\mathbf{x}_i,\mathbf{\mu}_k^{(t-1)})^2&amp;lt;/math&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
  &amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&lt;br /&gt;
    &amp;lt;b&amp;gt;Пересчет центров кластеров&amp;lt;/b&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Шаг &amp;lt;/b&amp;gt; &amp;lt;math&amp;gt;t: \forall i=\overline{1,k}:  \mu_i^{(t)} = \cfrac{1}{|S_i|}\sum_{\mathbf{x}\in S_i}\mathbf{x}&amp;lt;/math&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
  &amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&lt;br /&gt;
    &amp;lt;b&amp;gt;Проверка условия останова:&amp;lt;/b&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
    &#039;&#039;&#039;if&#039;&#039;&#039; &amp;lt;math&amp;gt;\exist i\in \overline{1,k}: \mu_i^{(t)} \ne \mu_i^{(t-1)}&amp;lt;/math&amp;gt; &#039;&#039;&#039;then&#039;&#039;&#039;&lt;br /&gt;
        t = t + 1;&lt;br /&gt;
        goto 2;&lt;br /&gt;
    &#039;&#039;&#039;else&#039;&#039;&#039;&lt;br /&gt;
        &#039;&#039;&#039;stop&#039;&#039;&#039;&lt;br /&gt;
  &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ol&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Вычислительное ядро алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Вычислительным ядром являются шаги 2 и 3 приведенного выше алгоритма: &amp;lt;b&amp;gt;&amp;lt;i&amp;gt;распределение векторов по кластерам&amp;lt;/i&amp;gt;&amp;lt;/b&amp;gt; и &amp;lt;b&amp;gt;&amp;lt;i&amp;gt;пересчет центров кластеров&amp;lt;/i&amp;gt;&amp;lt;/b&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;&amp;lt;i&amp;gt;Распределение векторов&amp;lt;/i&amp;gt;&amp;lt;/b&amp;gt; по кластерам предполагает вычисление расстояний между каждым вектором &amp;lt;math&amp;gt;\mathbf{x}_i \in X, i= \overline{1,n}&amp;lt;/math&amp;gt; и центрами кластера &amp;lt;math&amp;gt;\mathbf{\mu}_j, j= \overline{1,k}&amp;lt;/math&amp;gt;. Таким образом, данный шаг предполагает &amp;lt;math&amp;gt;kn&amp;lt;/math&amp;gt; вычислений расстояний между d-мерными векторами. &lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;&amp;lt;i&amp;gt;Пересчет центров кластеров&amp;lt;/i&amp;gt;&amp;lt;/b&amp;gt; предполагает &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; вычислений центров масс &amp;lt;math&amp;gt;\mathbf{\mu}_i&amp;lt;/math&amp;gt; множеств &amp;lt;math&amp;gt;S_i, i=\overline{1,k}&amp;lt;/math&amp;gt; представленных выражением в шаге 3 представленного выше алгоритма.&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Макроструктура алгоритма ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Инициализация центров масс &amp;lt;math&amp;gt;\mu_1, ..., \mu_k&amp;lt;/math&amp;gt;&amp;lt;/b&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
Наиболее распространенными являются следующие стратегии:&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&lt;br /&gt;
    &amp;lt;b&amp;gt;Метод Forgy&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;В качестве начальных значений &amp;lt;math&amp;gt;\mu_1, ..., \mu_k&amp;lt;/math&amp;gt; берутся случайно выбранные векторы.&lt;br /&gt;
  &amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&lt;br /&gt;
    &amp;lt;b&amp;gt;Метод случайно разделения (Random Partitioning)&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;Для каждого вектора &amp;lt;math&amp;gt;\mathbf{x}_i \in X, i=\overline{1, n}&amp;lt;/math&amp;gt; выбирается случайным образом кластер &amp;lt;math&amp;gt;S_1, ..., S_k&amp;lt;/math&amp;gt;, после чего для каждого полученного кластера вычисляются значения &amp;lt;math&amp;gt;\mu_1, ..., \mu_k&amp;lt;/math&amp;gt;.&lt;br /&gt;
  &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Распределение векторов по кластерам&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Для этого шага алгоритма между векторами &amp;lt;math&amp;gt;\mathbf{x}_i \in X, i=\overline{1, n}&amp;lt;/math&amp;gt; и центрами кластеров &amp;lt;math&amp;gt;\mu_1, ..., \mu_k&amp;lt;/math&amp;gt; вычисляются &amp;lt;b&amp;gt;расстояния&amp;lt;/b&amp;gt; по формуле (как правило, используется Евлидово расстояние):&lt;br /&gt;
&amp;lt;table style=&amp;quot;width:100%&amp;quot;&amp;gt;&lt;br /&gt;
  &amp;lt;tr&amp;gt;&lt;br /&gt;
    &amp;lt;td align=&amp;quot;center&amp;quot; width=&amp;quot;90%&amp;quot;&amp;gt;&amp;lt;math&amp;gt; \mathbf{v}_1, \mathbf{v}_2 \in \mathbb{R}^d,  \quad \rho(\mathbf{v}_1, \mathbf{v}_2) = \lVert \mathbf{v}_1- \mathbf{v}_2 \rVert= \sqrt{\sum_{i=1}^{d}(\mathbf{v}_{1,i} - \mathbf{v}_{2,i})^2}&amp;lt;/math&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;td align=&amp;quot;right&amp;quot;&amp;gt;&amp;lt;math&amp;gt;(2)&amp;lt;/math&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;/table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Пересчет центров кластеров&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Для этого шага алгоритма производится пересчет центров кластера по &amp;lt;b&amp;gt;формуле вычисления центра масс&amp;lt;/b&amp;gt;:&lt;br /&gt;
&amp;lt;table style=&amp;quot;width:100%&amp;quot;&amp;gt;&lt;br /&gt;
  &amp;lt;tr&amp;gt;&lt;br /&gt;
    &amp;lt;td align=&amp;quot;center&amp;quot; width=&amp;quot;90%&amp;quot;&amp;gt;&amp;lt;math&amp;gt; \mu = \cfrac{1}{|S|}\sum_{\mathbf{x}\in S}\mathbf{x}&amp;lt;/math&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;td align=&amp;quot;right&amp;quot;&amp;gt;&amp;lt;math&amp;gt;(3)&amp;lt;/math&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;/table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Схема реализации последовательного алгоритма ===&lt;br /&gt;
&lt;br /&gt;
 &#039;&#039;&#039;algorithm&#039;&#039;&#039; k-means &#039;&#039;&#039;is&#039;&#039;&#039;&lt;br /&gt;
     &#039;&#039;&#039;1.&#039;&#039;&#039; Инициализировать центры кластеров &amp;lt;math&amp;gt;\mathbf{\mu}_i^{(1)}, i=\overline{1,k}&amp;lt;/math&amp;gt;&lt;br /&gt;
     &#039;&#039;&#039;2.&#039;&#039;&#039; &amp;lt;math&amp;gt;t \leftarrow 1&amp;lt;/math&amp;gt;&lt;br /&gt;
     &#039;&#039;&#039;3.&#039;&#039;&#039; &#039;&#039;&#039;Распределение по кластерам&#039;&#039;&#039;&amp;lt;br&amp;gt;&lt;br /&gt;
        &amp;lt;math&amp;gt;S_i^{(t)}=\{\mathbf{x}_p: \lVert\mathbf{x}_p-\mathbf{\mu}_i^{(t)}\rVert^2 \leq \lVert\mathbf{x}_p-\mathbf{\mu}_j^{(t)}\rVert^2 \quad \forall j=\overline{1,k}\},&amp;lt;/math&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
        где каждый вектор &amp;lt;math&amp;gt;\mathbf{x}_p&amp;lt;/math&amp;gt; соотносится единственному кластеру &amp;lt;math&amp;gt;S^{(t)}&amp;lt;/math&amp;gt;&lt;br /&gt;
     &#039;&#039;&#039;4.&#039;&#039;&#039; &#039;&#039;&#039;Обновление центров кластеров&#039;&#039;&#039;&amp;lt;br&amp;gt;&lt;br /&gt;
        &amp;lt;math&amp;gt;\mathbf{\mu}_i^{(t+1)} = \frac{1}{|S^{(t)}_i|} \sum_{\mathbf{x}_j \in S^{(t)}_i} \mathbf{x}_j &amp;lt;/math&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
     &#039;&#039;&#039;5.&#039;&#039;&#039; &#039;&#039;&#039;if&#039;&#039;&#039; &amp;lt;math&amp;gt;\exist i \in \overline{1,k}: \mathbf{\mu}_i^{(t+1)} \ne \mathbf{\mu}_i^{(t)}&amp;lt;/math&amp;gt; &#039;&#039;&#039;then&#039;&#039;&#039;&lt;br /&gt;
            t = t + 1;&lt;br /&gt;
            goto &#039;&#039;&#039;3&#039;&#039;&#039;;&lt;br /&gt;
        &#039;&#039;&#039;else&#039;&#039;&#039;&lt;br /&gt;
            &#039;&#039;&#039;stop&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
=== Последовательная сложность алгоритма===&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding-bottom: 20px&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;Обозначим &amp;lt;math&amp;gt;\Theta_{centroid}^{d, m}&amp;lt;/math&amp;gt; временную сложность вычисления центорида кластера, число элементов которого равна &amp;lt;math&amp;gt;m&amp;lt;/math&amp;gt;,  в d-мерном пространстве.&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;Аналогично  &amp;lt;math&amp;gt;\Theta_{distance}^d&amp;lt;/math&amp;gt; &amp;amp;ndash; временная сложность вычисления расстояния между двумя d-мерными векторами.&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding-bottom: 20px&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;Сложность шага инициализации &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластеров мощности &amp;lt;math&amp;gt;m&amp;lt;/math&amp;gt; в d-мерном пространстве &amp;amp;ndash; &amp;lt;math&amp;gt;\Theta_{init}^{k, d, m}&amp;lt;/math&amp;gt;&amp;lt;/b&amp;gt;&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;i&amp;gt;Стратерия Forgy&amp;lt;/i&amp;gt;: вычисления не требуются, &amp;lt;math&amp;gt;\Theta_{init}^{k, d, m} = 0&amp;lt;/math&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;i&amp;gt;Стратегия случайного разбиения&amp;lt;/i&amp;gt;: вычисление центров &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластеров,  &amp;lt;math&amp;gt;\Theta_{init}^{k, d, m} = k \cdot \Theta_{centroid}^{d, m}, m \le n&amp;lt;/math&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding-bottom: 20px&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Cложность шага распределения d мерных векторов по &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластерам &amp;amp;ndash; &amp;lt;math&amp;gt;\Theta_{distribute}^{k, d}&amp;lt;/math&amp;gt;&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
На этом шаге для каждого вектора &amp;lt;math&amp;gt;\mathbf{x}_i \in X, i=\overline{1, n}&amp;lt;/math&amp;gt; вычисляется k расстояний до центров кластеров &amp;lt;math&amp;gt;\mathbf{\mu}_1, ...\mathbf{\mu}_k&amp;lt;/math&amp;gt;&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p align=&amp;quot;center&amp;quot;&amp;gt;&lt;br /&gt;
  &amp;lt;math&amp;gt;\Theta_{distribute}^{k, d} = n \cdot k \cdot \Theta_{distance}^d&amp;lt;/math&amp;gt;&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding-bottom: 20px&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;Сложность шага пересчета центров &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластеров размера &amp;lt;math&amp;gt;m&amp;lt;/math&amp;gt; в d-мерном пространстве &amp;amp;ndash; &amp;lt;math&amp;gt;\Theta_{recenter}^{k, d, m}&amp;lt;/math&amp;gt;&amp;lt;/b&amp;gt;&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;На этом шаге вычисляется &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; центров кластеров &amp;lt;math&amp;gt;\mathbf{\mu}_1, ...\mathbf{\mu}_k&amp;lt;/math&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p align=&amp;quot;center&amp;quot;&amp;gt;&amp;lt;math&amp;gt;\Theta_{recenter}^{k, d, m} = k \cdot \Theta_{centroid}^{d, m}&amp;lt;/math&amp;gt; &amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding-bottom: 20px&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Рассчитаем &amp;lt;math&amp;gt;\Theta_{centroid}^{d, m}&amp;lt;/math&amp;gt; для кластера, число элементов которого равно &amp;lt;math&amp;gt;m&amp;lt;/math&amp;gt;&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p align=&amp;quot;center&amp;quot;&amp;gt;&amp;lt;math&amp;gt;\Theta_{centroid}^{d, m}&amp;lt;/math&amp;gt; = &amp;lt;math&amp;gt;m \cdot d&amp;lt;/math&amp;gt; сложений + &amp;lt;math&amp;gt;d&amp;lt;/math&amp;gt; делений &amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding-bottom: 20px&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Рассчитаем &amp;lt;math&amp;gt;\Theta_{distance}^d&amp;lt;/math&amp;gt; в соответствие с формулой &amp;lt;math&amp;gt;(2)&amp;lt;/math&amp;gt;&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p align=&amp;quot;center&amp;quot;&amp;gt;&amp;lt;math&amp;gt;\Theta_{distance}^d&amp;lt;/math&amp;gt; = &amp;lt;math&amp;gt;d&amp;lt;/math&amp;gt; вычитаний + &amp;lt;math&amp;gt;d&amp;lt;/math&amp;gt; умножений + &amp;lt;math&amp;gt;(d-1)&amp;lt;/math&amp;gt; сложение&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding-bottom: 20px&amp;quot;&amp;gt;&lt;br /&gt;
  &amp;lt;p&amp;gt;Предположим, что алгоритм сошелся за &amp;lt;math&amp;gt;\Tau&amp;lt;/math&amp;gt; итераций, тогда временная сложность алгоритма &amp;lt;math&amp;gt;\Theta_{k-means}^{d, n}&amp;lt;/math&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
  &amp;lt;p align=&amp;quot;center&amp;quot;&amp;gt;&amp;lt;b&amp;gt;&amp;lt;math&amp;gt;\Theta_{k-means}^{d, n} \le \Theta_{init}^{k, d, n} + \Tau(\Theta_{distribute}^{k, d} + \Theta_{recenter}^{k, d, n})&amp;lt;/math&amp;gt;&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding-bottom: 5px&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;Операции сложения/вычитания:&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p align=&amp;quot;center&amp;quot;&amp;gt;&amp;lt;b&amp;gt;&amp;lt;math&amp;gt;\Theta_{k-means}^{d, n} \le k \cdot n \cdot d+ \Tau \cdot (k \cdot n(2d-1) + k \cdot n \cdot d) = k \cdot n \cdot d+ \Tau*(kn(3d-1)) \thicksim O(\Tau k \cdot d \cdot n)&amp;lt;/math&amp;gt;&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding-bottom: 20px&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;Операции умножения/деления:&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p align=&amp;quot;center&amp;quot;&amp;gt;&amp;lt;b&amp;gt;&amp;lt;math&amp;gt;\Theta_{k-means}^{d, n} \le k \cdot d + \Tau \cdot (k \cdot n \cdot d + k \cdot d) = k \cdot d + \Tau \cdot k \cdot d \cdot (n+1) \thicksim O(\Tau \cdot k \cdot d \cdot n) &amp;lt;/math&amp;gt;&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding-bottom: 20px&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;Получаем, что &amp;lt;b&amp;gt;временная сложность&amp;lt;/b&amp;gt; алгоритма &amp;lt;b&amp;gt;k means&amp;lt;/b&amp;gt; кластеризации &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; &amp;lt;b&amp;gt;d-мерных&amp;lt;/b&amp;gt; векторов на &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластеров за &amp;lt;math&amp;gt;\Tau&amp;lt;/math&amp;gt; итераций:&amp;lt;/p&amp;gt;&lt;br /&gt;
 &amp;lt;p align=&amp;quot;center&amp;quot;&amp;gt;&amp;lt;b&amp;gt;&amp;lt;math&amp;gt; \Theta_{k-means}^{d, n} \thicksim O(\Tau \cdot k \cdot d \cdot n) &amp;lt;/math&amp;gt;&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Информационный граф ===&lt;br /&gt;
&lt;br /&gt;
Рассмотрим информационный граф алгоритма. Алгоритм &amp;lt;i&amp;gt;k means&amp;lt;/i&amp;gt; начинается с этапа инициализации, после которого следуют итерации, на каждой из которых выполняется два последовательных шага (см. [[#Схема реализации последовательного алгоритма|&amp;quot;Схема реализации последовательного алгоритма&amp;quot;]]): &lt;br /&gt;
* распределение векторов по кластерам&lt;br /&gt;
* перерасчет центров кластеров&lt;br /&gt;
&lt;br /&gt;
Поскольку основная часть вычислений приходится на шаги итераций, распишем информационные графы данных шагов.&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Распределение векторов по кластерам&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
Информационный граф шага распределения векторов по кластерам представлен на &#039;&#039;рисунке 1&#039;&#039;. Исходами данного графа является исходные векторы &amp;lt;math&amp;gt;\mathbf{x}_1, ..., \mathbf{x}_n&amp;lt;/math&amp;gt;, а также центры кластеров &amp;lt;math&amp;gt;\mathbf{\mu}_1, ... \mathbf{\mu}_k&amp;lt;/math&amp;gt;, вычисленные ранее (на шаге инициализации, если рассматривается первая итерация алгоритма, или на шаге пересчета центров кластеров предыдущей итерации в противном случае). Каждая пара векторов данных &amp;lt;math&amp;gt;\mathbf{x}_i, i=\overline{1,n}&amp;lt;/math&amp;gt; и центров кластера &amp;lt;math&amp;gt;\mathbf{\mu}_j, j=\overline{1, k}&amp;lt;/math&amp;gt; : (&amp;lt;math&amp;gt;\mathbf{x}_i&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;\mathbf{\mu}_j&amp;lt;/math&amp;gt;) подаются на независимые узлы &amp;lt;i&amp;gt;&amp;quot;d&amp;quot;&amp;lt;/i&amp;gt; вычисления расстояния между векторами (более подробная схема вычисления расстояния представлена далее, &#039;&#039;рисунок 2&#039;&#039;). Далее узлы вычисления расстояния &amp;lt;i&amp;gt;&amp;quot;d&amp;quot;&amp;lt;/i&amp;gt;, соответствующие одному и тому же исходному вектору &amp;lt;math&amp;gt;\mathbf{x}_i&amp;lt;/math&amp;gt; передаются на один узел &amp;lt;i&amp;gt;&amp;quot;m&amp;quot;&amp;lt;/i&amp;gt;, где далее происходит вычисление новой метки кластера для каждого вектора &amp;lt;math&amp;gt;\mathbf{x}_i&amp;lt;/math&amp;gt; (берется кластер с минимальным результатом вычисления расстояния). На выходе графа выдаются метки кластеров , &amp;lt;math&amp;gt;L_1, ..., L_n&amp;lt;/math&amp;gt;, такие что &amp;lt;math&amp;gt;\forall \mathbf{x}_i, i=\overline{1, n}, \mathbf{x}_i \in S_j \Leftrightarrow L_i = j&amp;lt;/math&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
[[file:Clusterization.png|thumb|center|800px|Рис. 1. Схема распределения векторов по кластерам. &#039;&#039;d&#039;&#039; &amp;amp;ndash; вычисление расстояния между векторами; &#039;&#039;m&#039;&#039; &amp;amp;ndash; вычисление минимума.]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Вычисление расстояния между векторами&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
Подробная схема вычисления расстояния между векторами &amp;lt;math&amp;gt;\mathbf{x}_i, \mathbf{\mu}_j&amp;lt;/math&amp;gt; представлена на &#039;&#039;рисунке 2&#039;&#039;. Как показано на графе, узел вычисления расстояния между векторами &amp;lt;i&amp;gt;&amp;quot;d&amp;quot;&amp;lt;/i&amp;gt; состоит из шага взятия разности между векторами (узел &amp;quot;&amp;lt;math&amp;gt;-&amp;lt;/math&amp;gt;&amp;quot;) и взятия нормы получившегося вектора разности (узел &amp;quot;&amp;lt;math&amp;gt;||\cdot||^2&amp;lt;/math&amp;gt;&amp;quot;). Более подробно, вычисление расстояния между векторами &amp;lt;math&amp;gt;\mathbf{x}_i = {x_{i1,}, ...,{x_{in}}}, \mathbf{\mu}_j = {\mu_{j1}, ...,\mu_{jn}}&amp;lt;/math&amp;gt; может быть представлено как вычисление разности между каждой парой компонент &amp;lt;math&amp;gt;(x_{iz}, \mu_{jz}), z=\overline{1, d}&amp;lt;/math&amp;gt; (узел &amp;quot;&amp;lt;math&amp;gt;-&amp;lt;/math&amp;gt;&amp;quot;), далее возведение в квадрат для каждого узла &amp;quot;&amp;lt;math&amp;gt;-&amp;lt;/math&amp;gt;&amp;quot; (узел &amp;quot;&amp;lt;math&amp;gt;()^2&amp;lt;/math&amp;gt;&amp;quot;) и суммирования выходов всех узлов &amp;quot;&amp;lt;math&amp;gt;()^2&amp;lt;/math&amp;gt;&amp;quot; (узел &amp;quot;&amp;lt;math&amp;gt;+&amp;lt;/math&amp;gt;&amp;quot;).  &lt;br /&gt;
&lt;br /&gt;
[[file:dist_calc.png|thumb|center|800px|Рис. 2. Схема вычисления расстояния между вектором и центром кластера.]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Пересчет центров кластеров&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
Информационный граф шага пересчета центров кластеров представлен на &#039;&#039;рисунке 3&#039;&#039;. Исходами данного графа является исходные векторы &amp;lt;math&amp;gt;\mathbf{x}_1, ..., \mathbf{x}_n&amp;lt;/math&amp;gt;, а также им соответствующие метки кластера, &amp;lt;math&amp;gt;L_1, ..., L_n&amp;lt;/math&amp;gt;, такие что &amp;lt;math&amp;gt;\forall x_i, i=\overline{1, n}, \mathbf{x}_i \in S_j \Leftrightarrow L_i = j&amp;lt;/math&amp;gt;, вычисленные на этапе распределения векторов по кластерам. Все векторы &amp;lt;math&amp;gt;\mathbf{x}_1, ..., \mathbf{x}_n&amp;lt;/math&amp;gt; подаются в узлы &amp;lt;math&amp;gt;+_1, ...+_k&amp;lt;/math&amp;gt;, каждый узел &amp;lt;math&amp;gt;+_m, m = \overline{1,k}&amp;lt;/math&amp;gt; соответствует операции сложения векторов кластера с номером &amp;lt;math&amp;gt;m&amp;lt;/math&amp;gt;. Метки кластера &amp;lt;math&amp;gt;L_1, ..., L_n&amp;lt;/math&amp;gt; также совместно передаются на узлы &amp;lt;math&amp;gt;S_m, m = \overline{1,k}&amp;lt;/math&amp;gt;, на каждом из которых вычисляется количество векторов в соответствующем кластере (количество меток с соответствующим значением). Далее каждая пара выходов узлов &amp;lt;math&amp;gt;+_m&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;S_m&amp;lt;/math&amp;gt; подается на узел &amp;quot;&amp;lt;math&amp;gt;/&amp;lt;/math&amp;gt;&amp;quot;, где производится деление суммы векторов кластера на количество элементов в нем. Значения, вычисленные на узлах &amp;quot;&amp;lt;math&amp;gt;/&amp;lt;/math&amp;gt;&amp;quot;, присваиваются новым центрам кластеров (выходные значения графа).&lt;br /&gt;
&lt;br /&gt;
[[file:Recluster.png|thumb|center|800px|Рис. 3. Схема пересчета центров кластеров]]&lt;br /&gt;
&lt;br /&gt;
=== Ресурс параллелизма алгоритма ===&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
Работа алгоритма состоит из &amp;lt;math&amp;gt;\Tau&amp;lt;/math&amp;gt; итераций, в каждой из которых происходит &amp;lt;b&amp;gt;распределение d-мерных векторов по &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластерам&amp;lt;/b&amp;gt;, а также &amp;lt;b&amp;gt;пересчет центров кластеров в d-мерном пространстве&amp;lt;/b&amp;gt;. В шаге &amp;lt;b&amp;gt;распределения d-мерных векторов по &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластерам&amp;lt;/b&amp;gt; расстояния между вектором и центрами кластеров вычисляются независимо (отсутствуют информационные зависимости). &amp;lt;b&amp;gt;Центры масс кластеров&amp;lt;/b&amp;gt; также пересчитываются независимо друг от друга. Таким образом, имеет место [[глоссарий#Массовый параллелизм|&#039;&#039;массовый параллелизм&#039;&#039;]]. Вычислим параллельную сложность &amp;lt;math&amp;gt;\Psi_*&amp;lt;/math&amp;gt; каждого из шагов, а также параллельную сложность всего алгоритма, &amp;lt;math&amp;gt;\Psi_{k-means}&amp;lt;/math&amp;gt;. Будем исходить из предположения, что может быть использовано любое необходимое число потоков.&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Распределение d-мерных векторов по &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластерам&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;  &lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
Поскольку на данном шаге для каждой пары векторов &amp;lt;math&amp;gt;\mathbf{x}_i, i=\overline{1,n}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\mathbf{\mu}_j, j=\overline{1,k}&amp;lt;/math&amp;gt; операции вычисления расстояния не зависят друг от друга, они могут выполняться параллельно. Тогда, разделив все вычисление расстояний на &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; потоков, получим, что в каждом потоке будет выполняться только одна операция вычисления расстояния между векторами размерности d. При этом каждому вычислительному потоку передаются координаты центров всех кластеров &amp;lt;math&amp;gt;\mathbf{\mu}_1, ..., \mathbf{\mu}_k&amp;lt;/math&amp;gt;. Таким образом, параллельная сложность данного шага определяется &amp;lt;i&amp;gt; сложностью параллельной операции вычисления расстояния между d-мерными векторами&amp;lt;/i&amp;gt;, &amp;lt;math&amp;gt;\Psi_{distance}^d&amp;lt;/math&amp;gt;  и &amp;lt;i&amp;gt;сложностью определения наиболее близкого кластера&amp;lt;/i&amp;gt; (паралельное взятие минимума по расстояниям), &amp;lt;math&amp;gt;\Psi_{min}^k&amp;lt;/math&amp;gt;. Для оценки &amp;lt;math&amp;gt;\Psi_{distance}^d&amp;lt;/math&amp;gt; воспользуемся  [[Нахождение_частных_сумм_элементов_массива_сдваиванием | параллельной реализацией нахождения частичной суммы элементов массива путем сдваивания]]. Аналогично, &amp;lt;math&amp;gt;\Psi_{min}^k = log(k)&amp;lt;/math&amp;gt;. В результате, &amp;lt;math&amp;gt;\Psi_{distance}^d = O(log(d))&amp;lt;/math&amp;gt;.   Таким образом: &lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p align=&amp;quot;center&amp;quot;&amp;gt;&amp;lt;math&amp;gt;\Psi_{distribute}^{k, d}  = \Psi_{distance}^d + \Psi_{min}^k = O(log(d))+O(log(k)) = O(log(k*d))&amp;lt;/math&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Пересчет центров кластеров в d-мерном пространстве&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
Поскольку на данном шаге для каждого из &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластеров центр масс может быть вычислен независимо, данные операции могут быть выполнены в отдельных потоках. Таким образом, параллельная сложность данного шага, &amp;lt;math&amp;gt;\Psi_{recenter}^{k, d}&amp;lt;/math&amp;gt;,  будет определяться &amp;lt;i&amp;gt;параллельной сложностью вычисления одного центра масс кластера размера &amp;lt;math&amp;gt;m&amp;lt;/math&amp;gt;&amp;lt;/i&amp;gt;, &amp;lt;math&amp;gt;\Psi_{recenter}^{k, d}&amp;lt;/math&amp;gt;,  а так как &amp;lt;math&amp;gt;m \le n \Rightarrow \Psi_{recenter}^{d, m} \le \Psi_{recenter}^{d, n}&amp;lt;/math&amp;gt;. Сложность вычисления центра масс кластера d-мерных векторов размера n аналогично предыдущим вычислениям равна &amp;lt;math&amp;gt;O(log(n))&amp;lt;/math&amp;gt;. Тогда:  &lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p align=&amp;quot;center&amp;quot;&amp;gt;&amp;lt;math&amp;gt;\Psi_{recenter}^{k, d}  \le \Psi_{recenter}^{d, n} = O(log(n))&amp;lt;/math&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Общая параллельная сложность алгоритма&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
На каждой итерации необходимо обновление центров кластеров, которые будут использованы на следующей итерации. Таким образом, итерационный процесс выполняется последовательно&amp;lt;ref&amp;gt;Zhao, Weizhong, Huifang Ma, and Qing He. &amp;quot;Parallel k-means clustering based on mapreduce.&amp;quot; IEEE International Conference on Cloud Computing. Springer Berlin Heidelberg, 2009.&amp;lt;/ref&amp;gt;. Тогда, поскольку сложность каждой итерации  определяется &amp;lt;math&amp;gt;\Psi_{distribute}^{k, d}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\Psi_{recenter}&amp;lt;/math&amp;gt;, сложность всего алгоритма, &amp;lt;math&amp;gt;\Psi_{k-means}&amp;lt;/math&amp;gt; в предположении, что было сделано &amp;lt;math&amp;gt;\Tau&amp;lt;/math&amp;gt; операций определяется выражением&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p align=&amp;quot;center&amp;quot;&amp;gt;&amp;lt;math&amp;gt;\Psi_{k-means} \approx \Tau * (\Psi_{distribute}^{k, d} + \Psi_{recenter}^{k, d}) \le \Tau * O(log(k*d*n))&amp;lt;/math&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Входные и выходные данные алгоритма ===&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;Входные данные&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;Матрица из &amp;lt;math&amp;gt;n*d&amp;lt;/math&amp;gt; элементов &amp;lt;math&amp;gt;x_{i, j} \in \mathbb{R}, i=\overline{1, n}, j=\overline{1, d}&amp;lt;/math&amp;gt;&amp;amp;ndash; координат векторов (наблюдений).&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;Целое положительное число &amp;lt;math&amp;gt;k, k \le n&amp;lt;/math&amp;gt; &amp;amp;ndash; количество кластеров.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;Объем входных данных&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;math&amp;gt;1&amp;lt;/math&amp;gt; целое число + &amp;lt;math&amp;gt;n*d&amp;lt;/math&amp;gt; вещественных чисел (при условии, что координаты &amp;amp;ndash; вещественные числа).&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;Выходные данные&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; целых положительных чисел &amp;lt;math&amp;gt;L_1, ..., L_n&amp;lt;/math&amp;gt;&amp;amp;ndash; номера кластеров, соотвествующие каждому вектору (при условии, что нумерация кластеров начинается с &amp;lt;math&amp;gt;1&amp;lt;/math&amp;gt;).&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;Объем выходных данных&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; целых положительных чисел.&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Свойства алгоритма ===&lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;[[глоссарий#Вычислительная мощность|&#039;&#039;Вычислительная мощность&#039;&#039;]]&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
Вычислительная мощность алгоритма &amp;lt;i&amp;gt;k means&amp;lt;/i&amp;gt; равна &amp;lt;math&amp;gt;\frac{k*d*n*\Tau}{n*d} = k*\Tau &amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; &amp;amp;ndash; число кластеров, &amp;lt;math&amp;gt;\Tau&amp;lt;/math&amp;gt; &amp;amp;ndash; число итераций алгоритма.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;[[глоссарий#Детерминированность |&#039;&#039;Детерминированность&#039;&#039;]] и [[глоссарий#Устойчивость |&#039;&#039;Устойчивость&#039;&#039;]] &amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
Алгоритм &amp;lt;i&amp;gt;k means&amp;lt;/i&amp;gt; является итерационным. Количество итераций алгоритма в общем случае не фиксируется и зависит от начального расположения объектов в пространстве, параметра &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt;, а также от начального приближения центров кластеров, &amp;lt;math&amp;gt;\mu_1, ..., \mu_k&amp;lt;/math&amp;gt;. В результате этого может варьироваться результат работы алгоритма. При неудачном выборе начальных параметров итерационный процесс может сойтись к локальному оптимуму&amp;lt;ref&amp;gt;Von Luxburg, Ulrike. Clustering Stability. Now Publishers Inc, 2010.&amp;lt;/ref&amp;gt;. По этим причинам алгоритм не является ни &amp;lt;b&amp;gt;детермирированным&amp;lt;/b&amp;gt;, ни &amp;lt;b&amp;gt;устойчивым&amp;lt;/b&amp;gt;.&lt;br /&gt;
 &lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Соотношение последовательной и параллельной сложности алгоритма&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\frac{\Theta_{k-means}}{\Psi_{k-means}} = \frac{O(\Tau*k*d*n)}{O(\Tau*log(k*d*n))}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Сильные стороны алгоритма&amp;lt;/b&amp;gt;:&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;i&amp;gt;Сравнительно высокая эффективность при простоте реализации&amp;lt;/i&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;i&amp;gt;Высокое качество кластеризации&amp;lt;/i&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;i&amp;gt;Возможность распараллеливания&amp;lt;/i&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;i&amp;gt;Существование множества модификаций&amp;lt;/i&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;Недостатки алгоритма&amp;lt;/b&amp;gt;&amp;lt;ref&amp;gt;Ortega, Joaquín Pérez, Ma Del Rocío Boone Rojas, and María J. Somodevilla. &amp;quot;Research issues on K-means Algorithm: An Experimental Trial Using Matlab.&amp;quot;&amp;lt;/ref&amp;gt;:&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;i&amp;gt;Количество кластеров является параметром алгоритма&amp;lt;/i&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;&amp;lt;i&amp;gt;Чувствительность к начальным условиям&amp;lt;/i&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;Инициализация центров кластеров в значительной степени влияет на результат кластеризации.&amp;lt;/p&amp;gt;&lt;br /&gt;
  &amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;&amp;lt;i&amp;gt;Чувствительность к выбросам и шумам&amp;lt;/i&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;Выбросы, далекие от центров настоящих кластеров, все равно учитываются при вычислении их центров.&amp;lt;/p&amp;gt;&lt;br /&gt;
  &amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;&amp;lt;i&amp;gt;Возможность сходимости к локальному оптимуму&amp;lt;/i&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;Итеративный подход не дает гарантии сходимости к оптимальному решению.&amp;lt;/p&amp;gt;&lt;br /&gt;
  &amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;&amp;lt;i&amp;gt;Использование понятия &amp;quot;среднего&amp;quot;&amp;lt;/i&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;Алгоритм неприменим к данным, для которых не определено понятие &amp;quot;среднего&amp;quot;, например, категориальным данным.&amp;lt;/p&amp;gt;&lt;br /&gt;
  &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&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;
Исследование масштабируемости параллельной реализации алгоритма k means проводилось на суперкомпьютере &amp;quot;Ломоносов&amp;quot;&amp;lt;ref name=&amp;quot;Lom&amp;quot;&amp;gt;Воеводин Вл., Жуматий С., Соболев С., Антонов А., Брызгалов П., Никитенко Д., Стефанов К., Воеводин Вад. Практика суперкомпьютера «Ломоносов» // Открытые системы, 2012, N 7, С. 36-39.&amp;lt;/ref&amp;gt; [http://parallel.ru/cluster Суперкомпьютерного комплекса Московского университета]. Алгоритм реализован на языке C с использованием средств MPI.&lt;br /&gt;
Для исследования масштабируемости проводилось множество запусков программы с разным значением параметра (количество векторов для кластеризации), а также с различным числом процессоров. Фиксировались результаты запусков &amp;amp;ndash; время работы &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt; и количество произведенных итераций алгоритма &amp;lt;math&amp;gt;\Tau&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Параметры запусков для экспериментальной оценки:&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;Значения &amp;lt;b&amp;gt;количества векторов&amp;lt;/b&amp;gt; &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;: 20&#039;000, 30&#039;000, 50&#039;000, 100&#039;000, 200&#039;000, 300&#039;000, 500&#039;000, 700&#039;000, 1&#039;000&#039;000, 1&#039;500&#039;000, 2&#039;000&#039;000.&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;Значения &amp;lt;b&amp;gt;количества процессоров&amp;lt;/b&amp;gt; &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt;: 1, 8, 16, 32, 64, 128, 160, 192, 224, 256, 288, 320, 352, 384, 416, 448, 480, 512.&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;Значение &amp;lt;b&amp;gt;количества кластеров&amp;lt;/b&amp;gt; &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt;: 100.&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;Значение &amp;lt;b&amp;gt;размерности векторов&amp;lt;/b&amp;gt; &amp;lt;math&amp;gt;d&amp;lt;/math&amp;gt;: 10.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Для проведения экспериментов были сгенерированы нормально распределенные псевдослучайные данные (с использованием Python библиотеки [http://scikit-learn.org/ scikit-learn]):&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
from sklearn.datasets import make_classification&lt;br /&gt;
X1, Y1 = make_classification(n_features=10, n_redundant=2, n_informative=8,&lt;br /&gt;
                             n_clusters_per_class=1, n_classes=100,&lt;br /&gt;
                             n_samples=2000000)&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Для заданной конфигурации эксперимента (&amp;lt;math&amp;gt;n, d, p, k&amp;lt;/math&amp;gt;) и полученных результатов (&amp;lt;math&amp;gt;t, \Tau&amp;lt;/math&amp;gt;)  [[Глоссарий#Производительность|производительность]]  и эффективность реализации расчитывались по формулам:&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
&amp;lt;ul&amp;gt;&amp;lt;li&amp;gt;&amp;lt;math&amp;gt;Performance = \frac{N_{k-means}^{d, n}}{t}\ \ (FLOPS),&amp;lt;/math&amp;gt;&amp;lt;/li&amp;gt;&amp;lt;/ul&amp;gt;&lt;br /&gt;
где &amp;lt;math&amp;gt;N_{k-means}^{d, n}&amp;lt;/math&amp;gt; &amp;amp;ndash; точное число операций с плавающей точкой (операции с памятью, а также целочисленные операции не учитывались), вычисленное в соответствие с разделом [[#Последовательная сложность алгоритма| &amp;quot;Последовательная сложность алгоритма&amp;quot;]];&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
&amp;lt;ul&amp;gt;&amp;lt;li&amp;gt;&amp;lt;math&amp;gt;Efficiency = \frac{100 * Performance}{Performance_{Peak}^{p}}\ \ (%),&amp;lt;/math&amp;gt;&amp;lt;/li&amp;gt;&amp;lt;/ul&amp;gt;&lt;br /&gt;
где &amp;lt;math&amp;gt;Performance_{Peak}^{p}&amp;lt;/math&amp;gt; &amp;amp;ndash; пиковая производительность суперкомпьютера при &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt; процессорах, вычисленная согласно спецификациям Intel&amp;lt;sup&amp;gt;&amp;amp;reg;&amp;lt;/sup&amp;gt; XEON&amp;lt;sup&amp;gt;&amp;amp;reg;&amp;lt;/sup&amp;gt; X5670&amp;lt;ref&amp;gt;&amp;quot;http://ark.intel.com/ru/products/47920/Intel-Xeon-Processor-X5670-12M-Cache-2_93-GHz-6_40-GTs-Intel-QPI&amp;quot;&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Графики зависимости производительности и эффективности параллельной реализации k means от числа векторов для кластеризации (&amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;) и числа процессоров (&amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt;) представлены на рисунках 4 и 5 соответственно.&lt;br /&gt;
&lt;br /&gt;
[[file:Flops.png|thumb|center|800px|Рис. 4. Параллельная реализация k means. График зависимости производительности реализации алгоритма от числа векторов для кластеризации (&amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;) и числа процессоров (&amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt;).]]&lt;br /&gt;
[[file:Efficiency.png|thumb|center|800px|Рис. 5. Параллельная реализация k means. График зависимости эффективности реализации алгоритма от числа векторов для кластеризации (&amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;) и числа процессоров (&amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt;).]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;В результате&amp;lt;/b&amp;gt; экспериментальной оценки были получены следующие оценки эффективности реализации:&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;b&amp;gt;Минимальное&amp;lt;/b&amp;gt; значение: 0.000409 % достигается при &amp;lt;math&amp;gt;n=20&#039;000, p=480&amp;lt;/math&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;b&amp;gt;Максимальное&amp;lt;/b&amp;gt; значение: 0.741119 % достигается при &amp;lt;math&amp;gt;n=300&#039;000, p=1&amp;lt;/math&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
Оценки масштабируемости реализации алгоритма k means:&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;b&amp;gt;По числу процессоров:&amp;lt;/b&amp;gt; -0.002683 &amp;amp;ndash; эффективность убывает с ростом числа процессоров. Данный результат вызван ростом накладных расходов для обеспечения параллельного выполнения алгоритма.&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;b&amp;gt;По размеру задачи:&amp;lt;/b&amp;gt; 0.002779 &amp;amp;ndash; эффективность растет с ростом числа векторов. Данный результат вызван тем, что при увеличении размера задачи, количество вычислений растет по сравнению с временем, затрачиваемым на пересылку данных.&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;b&amp;gt;Общая оценка:&amp;lt;/b&amp;gt; -0.000058 &amp;amp;ndash; можно сделать вывод, что в целом эффективность реализации незначительно уменьшается с ростом размера задачи и числа процессоров.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[https://github.com/serban/kmeans Использованная параллельная реализация алгоритма k means]&lt;br /&gt;
&lt;br /&gt;
=== Динамические характеристики и эффективность реализации алгоритма ===&lt;br /&gt;
=== Выводы для классов архитектур ===&lt;br /&gt;
=== Существующие реализации алгоритма ===&lt;br /&gt;
==== Открытое программное обеспечение ====&lt;br /&gt;
&amp;lt;ol&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;[https://www.icpsr.umich.edu/CrimeStat/ CrimeStat]&amp;lt;/li&amp;gt; Программное обеспечение, созданное для операционных систем Windows, предоставляющее инструменты статистического  и пространственного анализа для решения задачи картирования преступности.&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://juliastats.github.io Julia]&amp;lt;/li&amp;gt; Высокоуровневый высокопроизводительный свободный язык программирования с динамической типизацией, созданный для математических вычислений, содержит реализацию k-means.&lt;br /&gt;
  &amp;lt;li&amp;gt;[https://mahout.apache.org Mahout]&amp;lt;/li&amp;gt; Apache Mahout - Java библиотека для работы с алгоритмами машинного обучения с использованием MapReduce. Содержит реализацию k-means.&lt;br /&gt;
  &amp;lt;li&amp;gt;[https://www.gnu.org/software/octave/ Octave]&amp;lt;/li&amp;gt; Написанная на C++  свободная система для математических вычислений, использующая совместимый с MATLAB язык высокого уровня, содержит реализацию k-means.&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://spark.apache.org/docs/latest/mllib-clustering.html Spark]&amp;lt;/li&amp;gt; Распределенная реализация k-means содержится в библиотеке Mlib для работы с алгоритмами машинного обучения, взаимодействующая с Python библиотекой NumPy и библиотека R.&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://torch.ch Torch]&amp;lt;/li&amp;gt;  MATLAB-подобная библиотека для языка программирования Lua с открытым исходным кодом, предоставляет большое количество алгоритмов для глубинного обучения и научных расчётов. Ядро написано на Си, прикладная часть выполняется на LuaJIT, поддерживается распараллеливание вычислений средствами CUDA и OpenMP. Существуют реализации k-means.&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://www.cs.waikato.ac.nz/ml/weka/ Weka]&amp;lt;/li&amp;gt;  Cвободное программное обеспечение для анализа данных, написанное на Java. Содержит k-means и x-means.&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://accord-framework.net/docs/html/T_Accord_MachineLearning_KMeans.htm Accord.NET]&amp;lt;/li&amp;gt; C# реализация алгоритмов k-means, k-means++, k-modes.&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://docs.opencv.org/3.0-beta/doc/py_tutorials/py_ml/py_kmeans/py_kmeans_opencv/py_kmeans_opencv.html OpenCV]&amp;lt;/li&amp;gt; Написанная на С++ библиотека, направленная в основном на решение задач компьютерного зрения. Содержит реализацию k-means.&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://mlpack.org/ MLPACK]&amp;lt;/li&amp;gt; Масштабируемая С++ библиотека для работы с алгоритмами машинного обучения, содержит реализацию k-means.&lt;br /&gt;
  &amp;lt;li&amp;gt;[https://www.scipy.org/ SciPy]&amp;lt;/li&amp;gt; Библиотека Python, содержит множество реализаций k-means.&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://scikit-learn.org/ scikit-learn]&amp;lt;/li&amp;gt; Библиотека Python, содержит множество реализаций k-means.&lt;br /&gt;
  &amp;lt;li&amp;gt;[https://www.r-bloggers.com/k-means-clustering-in-r/ R]&amp;lt;/li&amp;gt; Язык программирования для статистической обработки данных и работы с графикой, а также свободная программная среда вычислений с открытым исходным кодом в рамках проекта GNU, содержит три реализации k-means.&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://elki.dbs.ifi.lmu.de ELKI]&amp;lt;/li&amp;gt; Java фреймворк, содержащий реализацию k-means, а также множество других алгоритмов кластеризации.&lt;br /&gt;
&amp;lt;/ol&amp;gt;&lt;br /&gt;
==== Проприетарное программное обеспечение  ====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ol&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;[https://www.ayasdi.com/blog/bigdata/topological-data-analysis-of-oil-and-gas-petrophysical-data/ Ayasdi]&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://www.stata.com/features/cluster-analysis/ Stata]&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://mathworld.wolfram.com/K-MeansClusteringAlgorithm.html Mathematica]&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://www.mathworks.com/help/stats/kmeans.html?requestedDomain=www.mathworks.com MATLAB]&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;[https://support.sas.com/rnd/app/stat/procedures/fastclus.html SAS]&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://docs.rapidminer.com/studio/operators/modeling/segmentation/k_means.html RapidMiner]&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;[https://blogs.sap.com/2013/03/28/sap-hana-pal-k-means-algorithm-or-how-to-do-customer-segmentation-for-the-telecommunications-industry/ SAP HANA]&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ol&amp;gt;&lt;br /&gt;
== Литература ==&lt;br /&gt;
&amp;lt;references /&amp;gt;&lt;/div&gt;</summary>
		<author><name>DennZo1993</name></author>
	</entry>
	<entry>
		<id>https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:%D0%91%D1%80%D0%BE%D1%82%D0%B8%D0%BA%D0%BE%D0%B2%D1%81%D0%BA%D0%B0%D1%8F_%D0%94%D0%B0%D0%BD%D1%83%D1%82%D0%B0/%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_k-means&amp;diff=20518</id>
		<title>Участник:Бротиковская Данута/Алгоритм k-means</title>
		<link rel="alternate" type="text/html" href="https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:%D0%91%D1%80%D0%BE%D1%82%D0%B8%D0%BA%D0%BE%D0%B2%D1%81%D0%BA%D0%B0%D1%8F_%D0%94%D0%B0%D0%BD%D1%83%D1%82%D0%B0/%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_k-means&amp;diff=20518"/>
		<updated>2016-12-10T10:33:35Z</updated>

		<summary type="html">&lt;p&gt;DennZo1993: /* Последовательная сложность алгоритма */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Assignment|Zhum}}&lt;br /&gt;
&lt;br /&gt;
{{algorithm&lt;br /&gt;
| name              = Алгоритм k средних (k means)&lt;br /&gt;
| serial_complexity = &amp;lt;math&amp;gt;O(\Tau*k*d*n)&amp;lt;/math&amp;gt;&lt;br /&gt;
| input_data        = &amp;lt;math&amp;gt; d*n &amp;lt;/math&amp;gt;&lt;br /&gt;
| output_data       = &amp;lt;math&amp;gt; n &amp;lt;/math&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
Авторы страницы &amp;lt;b&amp;gt;[[Участник:Бротиковская Данута|Данута Бротиковская]]&amp;lt;/b&amp;gt; и &amp;lt;b&amp;gt;[[Участник:DennZo1993|Денис Зобнин]]&amp;lt;/b&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
Оба автора внесли одинаковый вклад в написание статьи (поиск материалов, изучение статей, заполнение контента статьи), четких разграничений по пунктам статьи сделать невозможно. &lt;br /&gt;
&lt;br /&gt;
== Свойства и структура алгоритма ==&lt;br /&gt;
&lt;br /&gt;
=== Общее описание алгоритма ===&lt;br /&gt;
Алгоритм &amp;lt;b&amp;gt;&amp;lt;i&amp;gt;k средних&amp;lt;/i&amp;gt;&amp;lt;/b&amp;gt; (&amp;lt;b&amp;gt;&amp;lt;i&amp;gt;k means&amp;lt;/i&amp;gt;&amp;lt;/b&amp;gt;) &amp;amp;ndash; неиерархический&amp;lt;ref&amp;gt;&amp;quot;https://ru.wikipedia.org/wiki/Иерархическая_кластеризация&amp;quot;&amp;lt;/ref&amp;gt;, итерационный метод кластеризации&amp;lt;ref&amp;gt;&amp;quot;https://ru.wikipedia.org/wiki/Кластерный_анализ&amp;quot;&amp;lt;/ref&amp;gt;, получивший большую популярность благодаря своей простоте, наглядности реализации и достаточно высокому качеству работы. Был изобретен в 1950-х годах математиком &amp;lt;i&amp;gt;Гуго Штейнгаузом&amp;lt;/i&amp;gt;&amp;lt;ref&amp;gt;Steinhaus, Hugo. &amp;quot;Sur la division des corp materiels en parties.&amp;quot; Bull. Acad. Polon. Sci 1.804 (1956): 801.&amp;lt;/ref&amp;gt; и почти одновременно &amp;lt;i&amp;gt;Стюартом Ллойдом&amp;lt;/i&amp;gt;&amp;lt;ref&amp;gt;Lloyd, S. P. &amp;quot;Least square quantization in PCM. Bell Telephone Laboratories Paper. Published in journal much later: Lloyd, SP: Least squares quantization in PCM.&amp;quot; IEEE Trans. Inform. Theor.(1957/1982).&amp;lt;/ref&amp;gt;. Особую популярность приобрел после публикации работы &amp;lt;i&amp;gt;МакКуина&amp;lt;/i&amp;gt;&amp;lt;ref&amp;gt;MacQueen, James. &amp;quot;Some methods for classification and analysis of multivariate observations.&amp;quot; Proceedings of the fifth Berkeley symposium on mathematical statistics and probability. Vol. 1. No. 14. 1967.&amp;lt;/ref&amp;gt; в 1967.&lt;br /&gt;
&lt;br /&gt;
Алгоритм представляет собой версию EM-алгоритма&amp;lt;ref&amp;gt;&amp;quot;https://ru.wikipedia.org/wiki/EM-алгоритм&amp;quot;&amp;lt;/ref&amp;gt;, применяемого также для разделения смеси гауссиан. Основная идея &amp;lt;i&amp;gt;k means&amp;lt;/i&amp;gt; заключается в том, что данные произвольно разбиваются на кластеры, после чего итеративно перевычисляется центр масс для каждого кластера, полученного на предыдущем шаге, затем векторы разбиваются на кластеры вновь в соответствии с тем, какой из новых центров оказался ближе по выбранной метрике.&lt;br /&gt;
&lt;br /&gt;
Цель алгоритма заключается в разделении &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; наблюдений на &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластеров таким образом, чтобы каждое наблюдение принадлежало ровно одному кластеру, расположенному на наименьшем расстоянии от наблюдения.&lt;br /&gt;
&lt;br /&gt;
=== Математическое описание алгоритма ===&lt;br /&gt;
&amp;lt;b&amp;gt;&amp;lt;u&amp;gt;Дано:&amp;lt;/u&amp;gt;&amp;lt;/b&amp;gt;&lt;br /&gt;
* набор из &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; наблюдений &amp;lt;math&amp;gt;X=\{\mathbf{x}_1, \mathbf{x}_2, ..., \mathbf{x}_n\}, \mathbf{x}_i \in \mathbb{R}^d, i=\overline{1, n}&amp;lt;/math&amp;gt;;&lt;br /&gt;
* &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; - требуемое число кластеров, &amp;lt;math&amp;gt;k \in \mathbb{N}, k \leq n&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;&amp;lt;u&amp;gt;Требуется:&amp;lt;/u&amp;gt;&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Разделить множество наблюдений &amp;lt;math&amp;gt;X&amp;lt;/math&amp;gt; на &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластеров &amp;lt;math&amp;gt;S_1, S_2, ..., S_k&amp;lt;/math&amp;gt;:&lt;br /&gt;
*   &amp;lt;math&amp;gt;S_i \cap S_j= \varnothing, \quad i \ne j&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
*   &amp;lt;math&amp;gt;\bigcup_{i=1}^{k} S_i = X&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;&amp;lt;u&amp;gt;Действие алгоритма:&amp;lt;/u&amp;gt;&amp;lt;/b&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;Алгоритм &amp;lt;i&amp;gt;k means&amp;lt;/i&amp;gt; разбивает набор &amp;lt;math&amp;gt;X&amp;lt;/math&amp;gt; на &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; наборов &amp;lt;math&amp;gt;S_1, S_2, ..., S_k,&amp;lt;/math&amp;gt; таким образом, чтобы минимизировать сумму квадратов расстояний от каждой точки кластера до его центра (центр масс кластера). Введем обозначение, &amp;lt;math&amp;gt;S=\{S_1, S_2, ..., S_k\}&amp;lt;/math&amp;gt;. Тогда действие алгоритма &amp;lt;i&amp;gt;k means&amp;lt;/i&amp;gt; равносильно поиску:&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;table style=&amp;quot;width:100%&amp;quot;&amp;gt;&lt;br /&gt;
  &amp;lt;tr&amp;gt;&lt;br /&gt;
    &amp;lt;td align=&amp;quot;center&amp;quot; width=&amp;quot;90%&amp;quot;&amp;gt;&amp;lt;math&amp;gt;\arg\min_{S} \sum\limits_{i=1}^k \sum\limits_{\mathbf{x} \in S_i} \rho(\mathbf{x}, \mathbf{\mu}_i )^2,&amp;lt;/math&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;td align=&amp;quot;right&amp;quot;&amp;gt;&amp;lt;math&amp;gt;(1)&amp;lt;/math&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;/table&amp;gt;&lt;br /&gt;
где &amp;lt;math&amp;gt;\mathbf{\mu}_i&amp;lt;/math&amp;gt; &amp;amp;ndash; центры кластеров, &amp;lt;math&amp;gt;i=\overline{1,k}, \quad \rho(\mathbf{x}, \mathbf{\mu}_i)&amp;lt;/math&amp;gt; &amp;amp;ndash; функция расстояния между &amp;lt;math&amp;gt;\mathbf{x}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\mu_i&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;&amp;lt;u&amp;gt;Шаги алгоритма: &amp;lt;/u&amp;gt;&amp;lt;/b&amp;gt;&lt;br /&gt;
&amp;lt;ol&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&lt;br /&gt;
    &amp;lt;b&amp;gt;Начальный шаг: инициализация кластеров&amp;lt;/b&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;Выбирается произвольное множество точек &amp;lt;math&amp;gt;\mu_i, i=\overline{1,k}&amp;lt;/math&amp;gt;, рассматриваемых как начальные центры кластеров: &amp;lt;math&amp;gt;\mu_i^{(0)} = \mu_i, \quad i=\overline{1, k}&amp;lt;/math&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
  &amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&lt;br /&gt;
    &amp;lt;b&amp;gt;Распределение векторов по кластерам&amp;lt;/b&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Шаг&amp;lt;/b&amp;gt; &amp;lt;math&amp;gt;t: \forall \mathbf{x}_i \in X, i=\overline{1,n}: \mathbf{x}_i \in S_j \iff  j=\arg\min_{k}\rho(\mathbf{x}_i,\mathbf{\mu}_k^{(t-1)})^2&amp;lt;/math&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
  &amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&lt;br /&gt;
    &amp;lt;b&amp;gt;Пересчет центров кластеров&amp;lt;/b&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Шаг &amp;lt;/b&amp;gt; &amp;lt;math&amp;gt;t: \forall i=\overline{1,k}:  \mu_i^{(t)} = \cfrac{1}{|S_i|}\sum_{\mathbf{x}\in S_i}\mathbf{x}&amp;lt;/math&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
  &amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&lt;br /&gt;
    &amp;lt;b&amp;gt;Проверка условия останова:&amp;lt;/b&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
    &#039;&#039;&#039;if&#039;&#039;&#039; &amp;lt;math&amp;gt;\exist i\in \overline{1,k}: \mu_i^{(t)} \ne \mu_i^{(t-1)}&amp;lt;/math&amp;gt; &#039;&#039;&#039;then&#039;&#039;&#039;&lt;br /&gt;
        t = t + 1;&lt;br /&gt;
        goto 2;&lt;br /&gt;
    &#039;&#039;&#039;else&#039;&#039;&#039;&lt;br /&gt;
        &#039;&#039;&#039;stop&#039;&#039;&#039;&lt;br /&gt;
  &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ol&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Вычислительное ядро алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Вычислительным ядром являются шаги 2 и 3 приведенного выше алгоритма: &amp;lt;b&amp;gt;&amp;lt;i&amp;gt;распределение векторов по кластерам&amp;lt;/i&amp;gt;&amp;lt;/b&amp;gt; и &amp;lt;b&amp;gt;&amp;lt;i&amp;gt;пересчет центров кластеров&amp;lt;/i&amp;gt;&amp;lt;/b&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;&amp;lt;i&amp;gt;Распределение векторов&amp;lt;/i&amp;gt;&amp;lt;/b&amp;gt; по кластерам предполагает вычисление расстояний между каждым вектором &amp;lt;math&amp;gt;\mathbf{x}_i \in X, i= \overline{1,n}&amp;lt;/math&amp;gt; и центрами кластера &amp;lt;math&amp;gt;\mathbf{\mu}_j, j= \overline{1,k}&amp;lt;/math&amp;gt;. Таким образом, данный шаг предполагает &amp;lt;math&amp;gt;kn&amp;lt;/math&amp;gt; вычислений расстояний между d-мерными векторами. &lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;&amp;lt;i&amp;gt;Пересчет центров кластеров&amp;lt;/i&amp;gt;&amp;lt;/b&amp;gt; предполагает &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; вычислений центров масс &amp;lt;math&amp;gt;\mathbf{\mu}_i&amp;lt;/math&amp;gt; множеств &amp;lt;math&amp;gt;S_i, i=\overline{1,k}&amp;lt;/math&amp;gt; представленных выражением в шаге 3 представленного выше алгоритма.&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Макроструктура алгоритма ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Инициализация центров масс &amp;lt;math&amp;gt;\mu_1, ..., \mu_k&amp;lt;/math&amp;gt;&amp;lt;/b&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
Наиболее распространенными являются следующие стратегии:&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&lt;br /&gt;
    &amp;lt;b&amp;gt;Метод Forgy&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;В качестве начальных значений &amp;lt;math&amp;gt;\mu_1, ..., \mu_k&amp;lt;/math&amp;gt; берутся случайно выбранные векторы.&lt;br /&gt;
  &amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&lt;br /&gt;
    &amp;lt;b&amp;gt;Метод случайно разделения (Random Partitioning)&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;Для каждого вектора &amp;lt;math&amp;gt;\mathbf{x}_i \in X, i=\overline{1, n}&amp;lt;/math&amp;gt; выбирается случайным образом кластер &amp;lt;math&amp;gt;S_1, ..., S_k&amp;lt;/math&amp;gt;, после чего для каждого полученного кластера вычисляются значения &amp;lt;math&amp;gt;\mu_1, ..., \mu_k&amp;lt;/math&amp;gt;.&lt;br /&gt;
  &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Распределение векторов по кластерам&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Для этого шага алгоритма между векторами &amp;lt;math&amp;gt;\mathbf{x}_i \in X, i=\overline{1, n}&amp;lt;/math&amp;gt; и центрами кластеров &amp;lt;math&amp;gt;\mu_1, ..., \mu_k&amp;lt;/math&amp;gt; вычисляются &amp;lt;b&amp;gt;расстояния&amp;lt;/b&amp;gt; по формуле (как правило, используется Евлидово расстояние):&lt;br /&gt;
&amp;lt;table style=&amp;quot;width:100%&amp;quot;&amp;gt;&lt;br /&gt;
  &amp;lt;tr&amp;gt;&lt;br /&gt;
    &amp;lt;td align=&amp;quot;center&amp;quot; width=&amp;quot;90%&amp;quot;&amp;gt;&amp;lt;math&amp;gt; \mathbf{v}_1, \mathbf{v}_2 \in \mathbb{R}^d,  \quad \rho(\mathbf{v}_1, \mathbf{v}_2) = \lVert \mathbf{v}_1- \mathbf{v}_2 \rVert= \sqrt{\sum_{i=1}^{d}(\mathbf{v}_{1,i} - \mathbf{v}_{2,i})^2}&amp;lt;/math&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;td align=&amp;quot;right&amp;quot;&amp;gt;&amp;lt;math&amp;gt;(2)&amp;lt;/math&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;/table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Пересчет центров кластеров&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Для этого шага алгоритма производится пересчет центров кластера по &amp;lt;b&amp;gt;формуле вычисления центра масс&amp;lt;/b&amp;gt;:&lt;br /&gt;
&amp;lt;table style=&amp;quot;width:100%&amp;quot;&amp;gt;&lt;br /&gt;
  &amp;lt;tr&amp;gt;&lt;br /&gt;
    &amp;lt;td align=&amp;quot;center&amp;quot; width=&amp;quot;90%&amp;quot;&amp;gt;&amp;lt;math&amp;gt; \mu = \cfrac{1}{|S|}\sum_{\mathbf{x}\in S}\mathbf{x}&amp;lt;/math&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;td align=&amp;quot;right&amp;quot;&amp;gt;&amp;lt;math&amp;gt;(3)&amp;lt;/math&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;/table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Схема реализации последовательного алгоритма ===&lt;br /&gt;
&lt;br /&gt;
 &#039;&#039;&#039;algorithm&#039;&#039;&#039; k-means &#039;&#039;&#039;is&#039;&#039;&#039;&lt;br /&gt;
     &#039;&#039;&#039;1.&#039;&#039;&#039; Инициализировать центры кластеров &amp;lt;math&amp;gt;\mathbf{\mu}_i^{(1)}, i=\overline{1,k}&amp;lt;/math&amp;gt;&lt;br /&gt;
     &#039;&#039;&#039;2.&#039;&#039;&#039; &amp;lt;math&amp;gt;t \leftarrow 1&amp;lt;/math&amp;gt;&lt;br /&gt;
     &#039;&#039;&#039;3.&#039;&#039;&#039; &#039;&#039;&#039;Распределение по кластерам&#039;&#039;&#039;&amp;lt;br&amp;gt;&lt;br /&gt;
        &amp;lt;math&amp;gt;S_i^{(t)}=\{\mathbf{x}_p: \lVert\mathbf{x}_p-\mathbf{\mu}_i^{(t)}\rVert^2 \leq \lVert\mathbf{x}_p-\mathbf{\mu}_j^{(t)}\rVert^2 \quad \forall j=\overline{1,k}\},&amp;lt;/math&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
        где каждый вектор &amp;lt;math&amp;gt;\mathbf{x}_p&amp;lt;/math&amp;gt; соотносится единственному кластеру &amp;lt;math&amp;gt;S^{(t)}&amp;lt;/math&amp;gt;&lt;br /&gt;
     &#039;&#039;&#039;4.&#039;&#039;&#039; &#039;&#039;&#039;Обновление центров кластеров&#039;&#039;&#039;&amp;lt;br&amp;gt;&lt;br /&gt;
        &amp;lt;math&amp;gt;\mathbf{\mu}_i^{(t+1)} = \frac{1}{|S^{(t)}_i|} \sum_{\mathbf{x}_j \in S^{(t)}_i} \mathbf{x}_j &amp;lt;/math&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
     &#039;&#039;&#039;5.&#039;&#039;&#039; &#039;&#039;&#039;if&#039;&#039;&#039; &amp;lt;math&amp;gt;\exist i \in \overline{1,k}: \mathbf{\mu}_i^{(t+1)} \ne \mathbf{\mu}_i^{(t)}&amp;lt;/math&amp;gt; &#039;&#039;&#039;then&#039;&#039;&#039;&lt;br /&gt;
            t = t + 1;&lt;br /&gt;
            goto &#039;&#039;&#039;3&#039;&#039;&#039;;&lt;br /&gt;
        &#039;&#039;&#039;else&#039;&#039;&#039;&lt;br /&gt;
            &#039;&#039;&#039;stop&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
=== Последовательная сложность алгоритма===&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding-bottom: 20px&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;Обозначим &amp;lt;math&amp;gt;\Theta_{centroid}^{d, m}&amp;lt;/math&amp;gt; временную сложность вычисления центорида кластера, число элементов которого равна &amp;lt;math&amp;gt;m&amp;lt;/math&amp;gt;,  в d-мерном пространстве.&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;Аналогично  &amp;lt;math&amp;gt;\Theta_{distance}^d&amp;lt;/math&amp;gt; &amp;amp;ndash; временная сложность вычисления расстояния между двумя d-мерными векторами.&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding-bottom: 20px&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;Сложность шага инициализации &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластеров мощности &amp;lt;math&amp;gt;m&amp;lt;/math&amp;gt; в d-мерном пространстве &amp;amp;ndash; &amp;lt;math&amp;gt;\Theta_{init}^{k, d, m}&amp;lt;/math&amp;gt;&amp;lt;/b&amp;gt;&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;i&amp;gt;Стратерия Forgy&amp;lt;/i&amp;gt;: вычисления не требуются, &amp;lt;math&amp;gt;\Theta_{init}^{k, d, m} = 0&amp;lt;/math&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;i&amp;gt;Стратегия случайного разбиения&amp;lt;/i&amp;gt;: вычисление центров &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластеров,  &amp;lt;math&amp;gt;\Theta_{init}^{k, d, m} = k \cdot \Theta_{centroid}^{d, m}, m \le n&amp;lt;/math&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding-bottom: 20px&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Cложность шага распределения d мерных векторов по &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластерам &amp;amp;ndash; &amp;lt;math&amp;gt;\Theta_{distribute}^{k, d}&amp;lt;/math&amp;gt;&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
На этом шаге для каждого вектора &amp;lt;math&amp;gt;\mathbf{x}_i \in X, i=\overline{1, n}&amp;lt;/math&amp;gt; вычисляется k расстояний до центров кластеров &amp;lt;math&amp;gt;\mathbf{\mu}_1, ...\mathbf{\mu}_k&amp;lt;/math&amp;gt;&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p align=&amp;quot;center&amp;quot;&amp;gt;&lt;br /&gt;
  &amp;lt;math&amp;gt;\Theta_{distribute}^{k, d} = n \cdot k \cdot \Theta_{distance}^d&amp;lt;/math&amp;gt;&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding-bottom: 20px&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;Сложность шага пересчета центров &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластеров размера &amp;lt;math&amp;gt;m&amp;lt;/math&amp;gt; в d-мерном пространстве &amp;amp;ndash; &amp;lt;math&amp;gt;\Theta_{recenter}^{k, d, m}&amp;lt;/math&amp;gt;&amp;lt;/b&amp;gt;&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;На этом шаге вычисляется &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; центров кластеров &amp;lt;math&amp;gt;\mathbf{\mu}_1, ...\mathbf{\mu}_k&amp;lt;/math&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p align=&amp;quot;center&amp;quot;&amp;gt;&amp;lt;math&amp;gt;\Theta_{recenter}^{k, d, m} = k \cdot \Theta_{centroid}^{d, m}&amp;lt;/math&amp;gt; &amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding-bottom: 20px&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Рассчитаем &amp;lt;math&amp;gt;\Theta_{centroid}^{d, m}&amp;lt;/math&amp;gt; для кластера, число элементов которого равно &amp;lt;math&amp;gt;m&amp;lt;/math&amp;gt;&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p align=&amp;quot;center&amp;quot;&amp;gt;&amp;lt;math&amp;gt;\Theta_{centroid}^{d, m}&amp;lt;/math&amp;gt; = &amp;lt;math&amp;gt;md&amp;lt;/math&amp;gt; сложений + &amp;lt;math&amp;gt;d&amp;lt;/math&amp;gt; делений &amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding-bottom: 20px&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Рассчитаем &amp;lt;math&amp;gt;\Theta_{distance}^d&amp;lt;/math&amp;gt; в соответствие с формулой &amp;lt;math&amp;gt;(2)&amp;lt;/math&amp;gt;&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p align=&amp;quot;center&amp;quot;&amp;gt;&amp;lt;math&amp;gt;\Theta_{distance}^d&amp;lt;/math&amp;gt; = &amp;lt;math&amp;gt;d&amp;lt;/math&amp;gt; вычитаний + &amp;lt;math&amp;gt;d&amp;lt;/math&amp;gt; умножений + &amp;lt;math&amp;gt;(d-1)&amp;lt;/math&amp;gt; сложение&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding-bottom: 20px&amp;quot;&amp;gt;&lt;br /&gt;
  &amp;lt;p&amp;gt;Предположим, что алгоритм сошелся за &amp;lt;math&amp;gt;\Tau&amp;lt;/math&amp;gt; итераций, тогда временная сложность алгоритма &amp;lt;math&amp;gt;\Theta_{k-means}^{d, n}&amp;lt;/math&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
  &amp;lt;p align=&amp;quot;center&amp;quot;&amp;gt;&amp;lt;b&amp;gt;&amp;lt;math&amp;gt;\Theta_{k-means}^{d, n} \le \Theta_{init}^{k, d, n} + \Tau(\Theta_{distribute}^{k, d} + \Theta_{recenter}^{k, d, n})&amp;lt;/math&amp;gt;&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding-bottom: 5px&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;Операции сложения/вычитания:&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p align=&amp;quot;center&amp;quot;&amp;gt;&amp;lt;b&amp;gt;&amp;lt;math&amp;gt;\Theta_{k-means}^{d, n} \le knd+ \Tau*(kn(2d-1) + k \cdot n \cdot d) = knd+ \Tau*(kn(3d-1)) \thicksim O(\Tau kdn)&amp;lt;/math&amp;gt;&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding-bottom: 20px&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;Операции умножения/деления:&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p align=&amp;quot;center&amp;quot;&amp;gt;&amp;lt;b&amp;gt;&amp;lt;math&amp;gt;\Theta_{k-means}^{d, n} \le k \cdot d + \Tau \cdot (k \cdot n \cdot d + k \cdot d) = k \cdot d + \Tau \cdot k \cdot d \cdot (n+1) \thicksim O(\Tau \cdot k \cdot d \cdot n) &amp;lt;/math&amp;gt;&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding-bottom: 20px&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;Получаем, что &amp;lt;b&amp;gt;временная сложность&amp;lt;/b&amp;gt; алгоритма &amp;lt;b&amp;gt;k means&amp;lt;/b&amp;gt; кластеризации &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; &amp;lt;b&amp;gt;d-мерных&amp;lt;/b&amp;gt; векторов на &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластеров за &amp;lt;math&amp;gt;\Tau&amp;lt;/math&amp;gt; итераций:&amp;lt;/p&amp;gt;&lt;br /&gt;
 &amp;lt;p align=&amp;quot;center&amp;quot;&amp;gt;&amp;lt;b&amp;gt;&amp;lt;math&amp;gt; \Theta_{k-means}^{d, n} \thicksim O(\Tau \cdot k \cdot d \cdot n) &amp;lt;/math&amp;gt;&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Информационный граф ===&lt;br /&gt;
&lt;br /&gt;
Рассмотрим информационный граф алгоритма. Алгоритм &amp;lt;i&amp;gt;k means&amp;lt;/i&amp;gt; начинается с этапа инициализации, после которого следуют итерации, на каждой из которых выполняется два последовательных шага (см. [[#Схема реализации последовательного алгоритма|&amp;quot;Схема реализации последовательного алгоритма&amp;quot;]]): &lt;br /&gt;
* распределение векторов по кластерам&lt;br /&gt;
* перерасчет центров кластеров&lt;br /&gt;
&lt;br /&gt;
Поскольку основная часть вычислений приходится на шаги итераций, распишем информационные графы данных шагов.&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Распределение векторов по кластерам&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
Информационный граф шага распределения векторов по кластерам представлен на &#039;&#039;рисунке 1&#039;&#039;. Исходами данного графа является исходные векторы &amp;lt;math&amp;gt;\mathbf{x}_1, ..., \mathbf{x}_n&amp;lt;/math&amp;gt;, а также центры кластеров &amp;lt;math&amp;gt;\mathbf{\mu}_1, ... \mathbf{\mu}_k&amp;lt;/math&amp;gt;, вычисленные ранее (на шаге инициализации, если рассматривается первая итерация алгоритма, или на шаге пересчета центров кластеров предыдущей итерации в противном случае). Каждая пара векторов данных &amp;lt;math&amp;gt;\mathbf{x}_i, i=\overline{1,n}&amp;lt;/math&amp;gt; и центров кластера &amp;lt;math&amp;gt;\mathbf{\mu}_j, j=\overline{1, k}&amp;lt;/math&amp;gt; : (&amp;lt;math&amp;gt;\mathbf{x}_i&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;\mathbf{\mu}_j&amp;lt;/math&amp;gt;) подаются на независимые узлы &amp;lt;i&amp;gt;&amp;quot;d&amp;quot;&amp;lt;/i&amp;gt; вычисления расстояния между векторами (более подробная схема вычисления расстояния представлена далее, &#039;&#039;рисунок 2&#039;&#039;). Далее узлы вычисления расстояния &amp;lt;i&amp;gt;&amp;quot;d&amp;quot;&amp;lt;/i&amp;gt;, соответствующие одному и тому же исходному вектору &amp;lt;math&amp;gt;\mathbf{x}_i&amp;lt;/math&amp;gt; передаются на один узел &amp;lt;i&amp;gt;&amp;quot;m&amp;quot;&amp;lt;/i&amp;gt;, где далее происходит вычисление новой метки кластера для каждого вектора &amp;lt;math&amp;gt;\mathbf{x}_i&amp;lt;/math&amp;gt; (берется кластер с минимальным результатом вычисления расстояния). На выходе графа выдаются метки кластеров , &amp;lt;math&amp;gt;L_1, ..., L_n&amp;lt;/math&amp;gt;, такие что &amp;lt;math&amp;gt;\forall \mathbf{x}_i, i=\overline{1, n}, \mathbf{x}_i \in S_j \Leftrightarrow L_i = j&amp;lt;/math&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
[[file:Clusterization.png|thumb|center|800px|Рис. 1. Схема распределения векторов по кластерам. &#039;&#039;d&#039;&#039; &amp;amp;ndash; вычисление расстояния между векторами; &#039;&#039;m&#039;&#039; &amp;amp;ndash; вычисление минимума.]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Вычисление расстояния между векторами&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
Подробная схема вычисления расстояния между векторами &amp;lt;math&amp;gt;\mathbf{x}_i, \mathbf{\mu}_j&amp;lt;/math&amp;gt; представлена на &#039;&#039;рисунке 2&#039;&#039;. Как показано на графе, узел вычисления расстояния между векторами &amp;lt;i&amp;gt;&amp;quot;d&amp;quot;&amp;lt;/i&amp;gt; состоит из шага взятия разности между векторами (узел &amp;quot;&amp;lt;math&amp;gt;-&amp;lt;/math&amp;gt;&amp;quot;) и взятия нормы получившегося вектора разности (узел &amp;quot;&amp;lt;math&amp;gt;||\cdot||^2&amp;lt;/math&amp;gt;&amp;quot;). Более подробно, вычисление расстояния между векторами &amp;lt;math&amp;gt;\mathbf{x}_i = {x_{i1,}, ...,{x_{in}}}, \mathbf{\mu}_j = {\mu_{j1}, ...,\mu_{jn}}&amp;lt;/math&amp;gt; может быть представлено как вычисление разности между каждой парой компонент &amp;lt;math&amp;gt;(x_{iz}, \mu_{jz}), z=\overline{1, d}&amp;lt;/math&amp;gt; (узел &amp;quot;&amp;lt;math&amp;gt;-&amp;lt;/math&amp;gt;&amp;quot;), далее возведение в квадрат для каждого узла &amp;quot;&amp;lt;math&amp;gt;-&amp;lt;/math&amp;gt;&amp;quot; (узел &amp;quot;&amp;lt;math&amp;gt;()^2&amp;lt;/math&amp;gt;&amp;quot;) и суммирования выходов всех узлов &amp;quot;&amp;lt;math&amp;gt;()^2&amp;lt;/math&amp;gt;&amp;quot; (узел &amp;quot;&amp;lt;math&amp;gt;+&amp;lt;/math&amp;gt;&amp;quot;).  &lt;br /&gt;
&lt;br /&gt;
[[file:dist_calc.png|thumb|center|800px|Рис. 2. Схема вычисления расстояния между вектором и центром кластера.]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Пересчет центров кластеров&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
Информационный граф шага пересчета центров кластеров представлен на &#039;&#039;рисунке 3&#039;&#039;. Исходами данного графа является исходные векторы &amp;lt;math&amp;gt;\mathbf{x}_1, ..., \mathbf{x}_n&amp;lt;/math&amp;gt;, а также им соответствующие метки кластера, &amp;lt;math&amp;gt;L_1, ..., L_n&amp;lt;/math&amp;gt;, такие что &amp;lt;math&amp;gt;\forall x_i, i=\overline{1, n}, \mathbf{x}_i \in S_j \Leftrightarrow L_i = j&amp;lt;/math&amp;gt;, вычисленные на этапе распределения векторов по кластерам. Все векторы &amp;lt;math&amp;gt;\mathbf{x}_1, ..., \mathbf{x}_n&amp;lt;/math&amp;gt; подаются в узлы &amp;lt;math&amp;gt;+_1, ...+_k&amp;lt;/math&amp;gt;, каждый узел &amp;lt;math&amp;gt;+_m, m = \overline{1,k}&amp;lt;/math&amp;gt; соответствует операции сложения векторов кластера с номером &amp;lt;math&amp;gt;m&amp;lt;/math&amp;gt;. Метки кластера &amp;lt;math&amp;gt;L_1, ..., L_n&amp;lt;/math&amp;gt; также совместно передаются на узлы &amp;lt;math&amp;gt;S_m, m = \overline{1,k}&amp;lt;/math&amp;gt;, на каждом из которых вычисляется количество векторов в соответствующем кластере (количество меток с соответствующим значением). Далее каждая пара выходов узлов &amp;lt;math&amp;gt;+_m&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;S_m&amp;lt;/math&amp;gt; подается на узел &amp;quot;&amp;lt;math&amp;gt;/&amp;lt;/math&amp;gt;&amp;quot;, где производится деление суммы векторов кластера на количество элементов в нем. Значения, вычисленные на узлах &amp;quot;&amp;lt;math&amp;gt;/&amp;lt;/math&amp;gt;&amp;quot;, присваиваются новым центрам кластеров (выходные значения графа).&lt;br /&gt;
&lt;br /&gt;
[[file:Recluster.png|thumb|center|800px|Рис. 3. Схема пересчета центров кластеров]]&lt;br /&gt;
&lt;br /&gt;
=== Ресурс параллелизма алгоритма ===&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
Работа алгоритма состоит из &amp;lt;math&amp;gt;\Tau&amp;lt;/math&amp;gt; итераций, в каждой из которых происходит &amp;lt;b&amp;gt;распределение d-мерных векторов по &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластерам&amp;lt;/b&amp;gt;, а также &amp;lt;b&amp;gt;пересчет центров кластеров в d-мерном пространстве&amp;lt;/b&amp;gt;. В шаге &amp;lt;b&amp;gt;распределения d-мерных векторов по &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластерам&amp;lt;/b&amp;gt; расстояния между вектором и центрами кластеров вычисляются независимо (отсутствуют информационные зависимости). &amp;lt;b&amp;gt;Центры масс кластеров&amp;lt;/b&amp;gt; также пересчитываются независимо друг от друга. Таким образом, имеет место [[глоссарий#Массовый параллелизм|&#039;&#039;массовый параллелизм&#039;&#039;]]. Вычислим параллельную сложность &amp;lt;math&amp;gt;\Psi_*&amp;lt;/math&amp;gt; каждого из шагов, а также параллельную сложность всего алгоритма, &amp;lt;math&amp;gt;\Psi_{k-means}&amp;lt;/math&amp;gt;. Будем исходить из предположения, что может быть использовано любое необходимое число потоков.&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Распределение d-мерных векторов по &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластерам&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;  &lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
Поскольку на данном шаге для каждой пары векторов &amp;lt;math&amp;gt;\mathbf{x}_i, i=\overline{1,n}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\mathbf{\mu}_j, j=\overline{1,k}&amp;lt;/math&amp;gt; операции вычисления расстояния не зависят друг от друга, они могут выполняться параллельно. Тогда, разделив все вычисление расстояний на &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; потоков, получим, что в каждом потоке будет выполняться только одна операция вычисления расстояния между векторами размерности d. При этом каждому вычислительному потоку передаются координаты центров всех кластеров &amp;lt;math&amp;gt;\mathbf{\mu}_1, ..., \mathbf{\mu}_k&amp;lt;/math&amp;gt;. Таким образом, параллельная сложность данного шага определяется &amp;lt;i&amp;gt; сложностью параллельной операции вычисления расстояния между d-мерными векторами&amp;lt;/i&amp;gt;, &amp;lt;math&amp;gt;\Psi_{distance}^d&amp;lt;/math&amp;gt;  и &amp;lt;i&amp;gt;сложностью определения наиболее близкого кластера&amp;lt;/i&amp;gt; (паралельное взятие минимума по расстояниям), &amp;lt;math&amp;gt;\Psi_{min}^k&amp;lt;/math&amp;gt;. Для оценки &amp;lt;math&amp;gt;\Psi_{distance}^d&amp;lt;/math&amp;gt; воспользуемся  [[Нахождение_частных_сумм_элементов_массива_сдваиванием | параллельной реализацией нахождения частичной суммы элементов массива путем сдваивания]]. Аналогично, &amp;lt;math&amp;gt;\Psi_{min}^k = log(k)&amp;lt;/math&amp;gt;. В результате, &amp;lt;math&amp;gt;\Psi_{distance}^d = O(log(d))&amp;lt;/math&amp;gt;.   Таким образом: &lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p align=&amp;quot;center&amp;quot;&amp;gt;&amp;lt;math&amp;gt;\Psi_{distribute}^{k, d}  = \Psi_{distance}^d + \Psi_{min}^k = O(log(d))+O(log(k)) = O(log(k*d))&amp;lt;/math&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Пересчет центров кластеров в d-мерном пространстве&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
Поскольку на данном шаге для каждого из &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластеров центр масс может быть вычислен независимо, данные операции могут быть выполнены в отдельных потоках. Таким образом, параллельная сложность данного шага, &amp;lt;math&amp;gt;\Psi_{recenter}^{k, d}&amp;lt;/math&amp;gt;,  будет определяться &amp;lt;i&amp;gt;параллельной сложностью вычисления одного центра масс кластера размера &amp;lt;math&amp;gt;m&amp;lt;/math&amp;gt;&amp;lt;/i&amp;gt;, &amp;lt;math&amp;gt;\Psi_{recenter}^{k, d}&amp;lt;/math&amp;gt;,  а так как &amp;lt;math&amp;gt;m \le n \Rightarrow \Psi_{recenter}^{d, m} \le \Psi_{recenter}^{d, n}&amp;lt;/math&amp;gt;. Сложность вычисления центра масс кластера d-мерных векторов размера n аналогично предыдущим вычислениям равна &amp;lt;math&amp;gt;O(log(n))&amp;lt;/math&amp;gt;. Тогда:  &lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p align=&amp;quot;center&amp;quot;&amp;gt;&amp;lt;math&amp;gt;\Psi_{recenter}^{k, d}  \le \Psi_{recenter}^{d, n} = O(log(n))&amp;lt;/math&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Общая параллельная сложность алгоритма&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
На каждой итерации необходимо обновление центров кластеров, которые будут использованы на следующей итерации. Таким образом, итерационный процесс выполняется последовательно&amp;lt;ref&amp;gt;Zhao, Weizhong, Huifang Ma, and Qing He. &amp;quot;Parallel k-means clustering based on mapreduce.&amp;quot; IEEE International Conference on Cloud Computing. Springer Berlin Heidelberg, 2009.&amp;lt;/ref&amp;gt;. Тогда, поскольку сложность каждой итерации  определяется &amp;lt;math&amp;gt;\Psi_{distribute}^{k, d}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\Psi_{recenter}&amp;lt;/math&amp;gt;, сложность всего алгоритма, &amp;lt;math&amp;gt;\Psi_{k-means}&amp;lt;/math&amp;gt; в предположении, что было сделано &amp;lt;math&amp;gt;\Tau&amp;lt;/math&amp;gt; операций определяется выражением&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p align=&amp;quot;center&amp;quot;&amp;gt;&amp;lt;math&amp;gt;\Psi_{k-means} \approx \Tau * (\Psi_{distribute}^{k, d} + \Psi_{recenter}^{k, d}) \le \Tau * O(log(k*d*n))&amp;lt;/math&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Входные и выходные данные алгоритма ===&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;Входные данные&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;Матрица из &amp;lt;math&amp;gt;n*d&amp;lt;/math&amp;gt; элементов &amp;lt;math&amp;gt;x_{i, j} \in \mathbb{R}, i=\overline{1, n}, j=\overline{1, d}&amp;lt;/math&amp;gt;&amp;amp;ndash; координат векторов (наблюдений).&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;Целое положительное число &amp;lt;math&amp;gt;k, k \le n&amp;lt;/math&amp;gt; &amp;amp;ndash; количество кластеров.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;Объем входных данных&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;math&amp;gt;1&amp;lt;/math&amp;gt; целое число + &amp;lt;math&amp;gt;n*d&amp;lt;/math&amp;gt; вещественных чисел (при условии, что координаты &amp;amp;ndash; вещественные числа).&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;Выходные данные&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; целых положительных чисел &amp;lt;math&amp;gt;L_1, ..., L_n&amp;lt;/math&amp;gt;&amp;amp;ndash; номера кластеров, соотвествующие каждому вектору (при условии, что нумерация кластеров начинается с &amp;lt;math&amp;gt;1&amp;lt;/math&amp;gt;).&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;Объем выходных данных&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; целых положительных чисел.&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Свойства алгоритма ===&lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;[[глоссарий#Вычислительная мощность|&#039;&#039;Вычислительная мощность&#039;&#039;]]&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
Вычислительная мощность алгоритма &amp;lt;i&amp;gt;k means&amp;lt;/i&amp;gt; равна &amp;lt;math&amp;gt;\frac{k*d*n*\Tau}{n*d} = k*\Tau &amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; &amp;amp;ndash; число кластеров, &amp;lt;math&amp;gt;\Tau&amp;lt;/math&amp;gt; &amp;amp;ndash; число итераций алгоритма.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;[[глоссарий#Детерминированность |&#039;&#039;Детерминированность&#039;&#039;]] и [[глоссарий#Устойчивость |&#039;&#039;Устойчивость&#039;&#039;]] &amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
Алгоритм &amp;lt;i&amp;gt;k means&amp;lt;/i&amp;gt; является итерационным. Количество итераций алгоритма в общем случае не фиксируется и зависит от начального расположения объектов в пространстве, параметра &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt;, а также от начального приближения центров кластеров, &amp;lt;math&amp;gt;\mu_1, ..., \mu_k&amp;lt;/math&amp;gt;. В результате этого может варьироваться результат работы алгоритма. При неудачном выборе начальных параметров итерационный процесс может сойтись к локальному оптимуму&amp;lt;ref&amp;gt;Von Luxburg, Ulrike. Clustering Stability. Now Publishers Inc, 2010.&amp;lt;/ref&amp;gt;. По этим причинам алгоритм не является ни &amp;lt;b&amp;gt;детермирированным&amp;lt;/b&amp;gt;, ни &amp;lt;b&amp;gt;устойчивым&amp;lt;/b&amp;gt;.&lt;br /&gt;
 &lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Соотношение последовательной и параллельной сложности алгоритма&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\frac{\Theta_{k-means}}{\Psi_{k-means}} = \frac{O(\Tau*k*d*n)}{O(\Tau*log(k*d*n))}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Сильные стороны алгоритма&amp;lt;/b&amp;gt;:&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;i&amp;gt;Сравнительно высокая эффективность при простоте реализации&amp;lt;/i&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;i&amp;gt;Высокое качество кластеризации&amp;lt;/i&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;i&amp;gt;Возможность распараллеливания&amp;lt;/i&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;i&amp;gt;Существование множества модификаций&amp;lt;/i&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;Недостатки алгоритма&amp;lt;/b&amp;gt;&amp;lt;ref&amp;gt;Ortega, Joaquín Pérez, Ma Del Rocío Boone Rojas, and María J. Somodevilla. &amp;quot;Research issues on K-means Algorithm: An Experimental Trial Using Matlab.&amp;quot;&amp;lt;/ref&amp;gt;:&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;i&amp;gt;Количество кластеров является параметром алгоритма&amp;lt;/i&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;&amp;lt;i&amp;gt;Чувствительность к начальным условиям&amp;lt;/i&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;Инициализация центров кластеров в значительной степени влияет на результат кластеризации.&amp;lt;/p&amp;gt;&lt;br /&gt;
  &amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;&amp;lt;i&amp;gt;Чувствительность к выбросам и шумам&amp;lt;/i&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;Выбросы, далекие от центров настоящих кластеров, все равно учитываются при вычислении их центров.&amp;lt;/p&amp;gt;&lt;br /&gt;
  &amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;&amp;lt;i&amp;gt;Возможность сходимости к локальному оптимуму&amp;lt;/i&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;Итеративный подход не дает гарантии сходимости к оптимальному решению.&amp;lt;/p&amp;gt;&lt;br /&gt;
  &amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;&amp;lt;i&amp;gt;Использование понятия &amp;quot;среднего&amp;quot;&amp;lt;/i&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;Алгоритм неприменим к данным, для которых не определено понятие &amp;quot;среднего&amp;quot;, например, категориальным данным.&amp;lt;/p&amp;gt;&lt;br /&gt;
  &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&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;
Исследование масштабируемости параллельной реализации алгоритма k means проводилось на суперкомпьютере &amp;quot;Ломоносов&amp;quot;&amp;lt;ref name=&amp;quot;Lom&amp;quot;&amp;gt;Воеводин Вл., Жуматий С., Соболев С., Антонов А., Брызгалов П., Никитенко Д., Стефанов К., Воеводин Вад. Практика суперкомпьютера «Ломоносов» // Открытые системы, 2012, N 7, С. 36-39.&amp;lt;/ref&amp;gt; [http://parallel.ru/cluster Суперкомпьютерного комплекса Московского университета]. Алгоритм реализован на языке C с использованием средств MPI.&lt;br /&gt;
Для исследования масштабируемости проводилось множество запусков программы с разным значением параметра (количество векторов для кластеризации), а также с различным числом процессоров. Фиксировались результаты запусков &amp;amp;ndash; время работы &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt; и количество произведенных итераций алгоритма &amp;lt;math&amp;gt;\Tau&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Параметры запусков для экспериментальной оценки:&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;Значения &amp;lt;b&amp;gt;количества векторов&amp;lt;/b&amp;gt; &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;: 20&#039;000, 30&#039;000, 50&#039;000, 100&#039;000, 200&#039;000, 300&#039;000, 500&#039;000, 700&#039;000, 1&#039;000&#039;000, 1&#039;500&#039;000, 2&#039;000&#039;000.&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;Значения &amp;lt;b&amp;gt;количества процессоров&amp;lt;/b&amp;gt; &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt;: 1, 8, 16, 32, 64, 128, 160, 192, 224, 256, 288, 320, 352, 384, 416, 448, 480, 512.&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;Значение &amp;lt;b&amp;gt;количества кластеров&amp;lt;/b&amp;gt; &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt;: 100.&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;Значение &amp;lt;b&amp;gt;размерности векторов&amp;lt;/b&amp;gt; &amp;lt;math&amp;gt;d&amp;lt;/math&amp;gt;: 10.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Для проведения экспериментов были сгенерированы нормально распределенные псевдослучайные данные (с использованием Python библиотеки [http://scikit-learn.org/ scikit-learn]):&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
from sklearn.datasets import make_classification&lt;br /&gt;
X1, Y1 = make_classification(n_features=10, n_redundant=2, n_informative=8,&lt;br /&gt;
                             n_clusters_per_class=1, n_classes=100,&lt;br /&gt;
                             n_samples=2000000)&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Для заданной конфигурации эксперимента (&amp;lt;math&amp;gt;n, d, p, k&amp;lt;/math&amp;gt;) и полученных результатов (&amp;lt;math&amp;gt;t, \Tau&amp;lt;/math&amp;gt;)  [[Глоссарий#Производительность|производительность]]  и эффективность реализации расчитывались по формулам:&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
&amp;lt;ul&amp;gt;&amp;lt;li&amp;gt;&amp;lt;math&amp;gt;Performance = \frac{N_{k-means}^{d, n}}{t}\ \ (FLOPS),&amp;lt;/math&amp;gt;&amp;lt;/li&amp;gt;&amp;lt;/ul&amp;gt;&lt;br /&gt;
где &amp;lt;math&amp;gt;N_{k-means}^{d, n}&amp;lt;/math&amp;gt; &amp;amp;ndash; точное число операций с плавающей точкой (операции с памятью, а также целочисленные операции не учитывались), вычисленное в соответствие с разделом [[#Последовательная сложность алгоритма| &amp;quot;Последовательная сложность алгоритма&amp;quot;]];&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
&amp;lt;ul&amp;gt;&amp;lt;li&amp;gt;&amp;lt;math&amp;gt;Efficiency = \frac{100 * Performance}{Performance_{Peak}^{p}}\ \ (%),&amp;lt;/math&amp;gt;&amp;lt;/li&amp;gt;&amp;lt;/ul&amp;gt;&lt;br /&gt;
где &amp;lt;math&amp;gt;Performance_{Peak}^{p}&amp;lt;/math&amp;gt; &amp;amp;ndash; пиковая производительность суперкомпьютера при &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt; процессорах, вычисленная согласно спецификациям Intel&amp;lt;sup&amp;gt;&amp;amp;reg;&amp;lt;/sup&amp;gt; XEON&amp;lt;sup&amp;gt;&amp;amp;reg;&amp;lt;/sup&amp;gt; X5670&amp;lt;ref&amp;gt;&amp;quot;http://ark.intel.com/ru/products/47920/Intel-Xeon-Processor-X5670-12M-Cache-2_93-GHz-6_40-GTs-Intel-QPI&amp;quot;&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Графики зависимости производительности и эффективности параллельной реализации k means от числа векторов для кластеризации (&amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;) и числа процессоров (&amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt;) представлены на рисунках 4 и 5 соответственно.&lt;br /&gt;
&lt;br /&gt;
[[file:Flops.png|thumb|center|800px|Рис. 4. Параллельная реализация k means. График зависимости производительности реализации алгоритма от числа векторов для кластеризации (&amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;) и числа процессоров (&amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt;).]]&lt;br /&gt;
[[file:Efficiency.png|thumb|center|800px|Рис. 5. Параллельная реализация k means. График зависимости эффективности реализации алгоритма от числа векторов для кластеризации (&amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;) и числа процессоров (&amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt;).]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;В результате&amp;lt;/b&amp;gt; экспериментальной оценки были получены следующие оценки эффективности реализации:&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;b&amp;gt;Минимальное&amp;lt;/b&amp;gt; значение: 0.000409 % достигается при &amp;lt;math&amp;gt;n=20&#039;000, p=480&amp;lt;/math&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;b&amp;gt;Максимальное&amp;lt;/b&amp;gt; значение: 0.741119 % достигается при &amp;lt;math&amp;gt;n=300&#039;000, p=1&amp;lt;/math&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
Оценки масштабируемости реализации алгоритма k means:&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;b&amp;gt;По числу процессоров:&amp;lt;/b&amp;gt; -0.002683 &amp;amp;ndash; эффективность убывает с ростом числа процессоров. Данный результат вызван ростом накладных расходов для обеспечения параллельного выполнения алгоритма.&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;b&amp;gt;По размеру задачи:&amp;lt;/b&amp;gt; 0.002779 &amp;amp;ndash; эффективность растет с ростом числа векторов. Данный результат вызван тем, что при увеличении размера задачи, количество вычислений растет по сравнению с временем, затрачиваемым на пересылку данных.&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;b&amp;gt;Общая оценка:&amp;lt;/b&amp;gt; -0.000058 &amp;amp;ndash; можно сделать вывод, что в целом эффективность реализации незначительно уменьшается с ростом размера задачи и числа процессоров.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[https://github.com/serban/kmeans Использованная параллельная реализация алгоритма k means]&lt;br /&gt;
&lt;br /&gt;
=== Динамические характеристики и эффективность реализации алгоритма ===&lt;br /&gt;
=== Выводы для классов архитектур ===&lt;br /&gt;
=== Существующие реализации алгоритма ===&lt;br /&gt;
==== Открытое программное обеспечение ====&lt;br /&gt;
&amp;lt;ol&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;[https://www.icpsr.umich.edu/CrimeStat/ CrimeStat]&amp;lt;/li&amp;gt; Программное обеспечение, созданное для операционных систем Windows, предоставляющее инструменты статистического  и пространственного анализа для решения задачи картирования преступности.&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://juliastats.github.io Julia]&amp;lt;/li&amp;gt; Высокоуровневый высокопроизводительный свободный язык программирования с динамической типизацией, созданный для математических вычислений, содержит реализацию k-means.&lt;br /&gt;
  &amp;lt;li&amp;gt;[https://mahout.apache.org Mahout]&amp;lt;/li&amp;gt; Apache Mahout - Java библиотека для работы с алгоритмами машинного обучения с использованием MapReduce. Содержит реализацию k-means.&lt;br /&gt;
  &amp;lt;li&amp;gt;[https://www.gnu.org/software/octave/ Octave]&amp;lt;/li&amp;gt; Написанная на C++  свободная система для математических вычислений, использующая совместимый с MATLAB язык высокого уровня, содержит реализацию k-means.&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://spark.apache.org/docs/latest/mllib-clustering.html Spark]&amp;lt;/li&amp;gt; Распределенная реализация k-means содержится в библиотеке Mlib для работы с алгоритмами машинного обучения, взаимодействующая с Python библиотекой NumPy и библиотека R.&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://torch.ch Torch]&amp;lt;/li&amp;gt;  MATLAB-подобная библиотека для языка программирования Lua с открытым исходным кодом, предоставляет большое количество алгоритмов для глубинного обучения и научных расчётов. Ядро написано на Си, прикладная часть выполняется на LuaJIT, поддерживается распараллеливание вычислений средствами CUDA и OpenMP. Существуют реализации k-means.&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://www.cs.waikato.ac.nz/ml/weka/ Weka]&amp;lt;/li&amp;gt;  Cвободное программное обеспечение для анализа данных, написанное на Java. Содержит k-means и x-means.&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://accord-framework.net/docs/html/T_Accord_MachineLearning_KMeans.htm Accord.NET]&amp;lt;/li&amp;gt; C# реализация алгоритмов k-means, k-means++, k-modes.&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://docs.opencv.org/3.0-beta/doc/py_tutorials/py_ml/py_kmeans/py_kmeans_opencv/py_kmeans_opencv.html OpenCV]&amp;lt;/li&amp;gt; Написанная на С++ библиотека, направленная в основном на решение задач компьютерного зрения. Содержит реализацию k-means.&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://mlpack.org/ MLPACK]&amp;lt;/li&amp;gt; Масштабируемая С++ библиотека для работы с алгоритмами машинного обучения, содержит реализацию k-means.&lt;br /&gt;
  &amp;lt;li&amp;gt;[https://www.scipy.org/ SciPy]&amp;lt;/li&amp;gt; Библиотека Python, содержит множество реализаций k-means.&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://scikit-learn.org/ scikit-learn]&amp;lt;/li&amp;gt; Библиотека Python, содержит множество реализаций k-means.&lt;br /&gt;
  &amp;lt;li&amp;gt;[https://www.r-bloggers.com/k-means-clustering-in-r/ R]&amp;lt;/li&amp;gt; Язык программирования для статистической обработки данных и работы с графикой, а также свободная программная среда вычислений с открытым исходным кодом в рамках проекта GNU, содержит три реализации k-means.&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://elki.dbs.ifi.lmu.de ELKI]&amp;lt;/li&amp;gt; Java фреймворк, содержащий реализацию k-means, а также множество других алгоритмов кластеризации.&lt;br /&gt;
&amp;lt;/ol&amp;gt;&lt;br /&gt;
==== Проприетарное программное обеспечение  ====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ol&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;[https://www.ayasdi.com/blog/bigdata/topological-data-analysis-of-oil-and-gas-petrophysical-data/ Ayasdi]&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://www.stata.com/features/cluster-analysis/ Stata]&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://mathworld.wolfram.com/K-MeansClusteringAlgorithm.html Mathematica]&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://www.mathworks.com/help/stats/kmeans.html?requestedDomain=www.mathworks.com MATLAB]&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;[https://support.sas.com/rnd/app/stat/procedures/fastclus.html SAS]&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://docs.rapidminer.com/studio/operators/modeling/segmentation/k_means.html RapidMiner]&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;[https://blogs.sap.com/2013/03/28/sap-hana-pal-k-means-algorithm-or-how-to-do-customer-segmentation-for-the-telecommunications-industry/ SAP HANA]&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ol&amp;gt;&lt;br /&gt;
== Литература ==&lt;br /&gt;
&amp;lt;references /&amp;gt;&lt;/div&gt;</summary>
		<author><name>DennZo1993</name></author>
	</entry>
	<entry>
		<id>https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:%D0%91%D1%80%D0%BE%D1%82%D0%B8%D0%BA%D0%BE%D0%B2%D1%81%D0%BA%D0%B0%D1%8F_%D0%94%D0%B0%D0%BD%D1%83%D1%82%D0%B0/%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_k-means&amp;diff=20517</id>
		<title>Участник:Бротиковская Данута/Алгоритм k-means</title>
		<link rel="alternate" type="text/html" href="https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:%D0%91%D1%80%D0%BE%D1%82%D0%B8%D0%BA%D0%BE%D0%B2%D1%81%D0%BA%D0%B0%D1%8F_%D0%94%D0%B0%D0%BD%D1%83%D1%82%D0%B0/%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_k-means&amp;diff=20517"/>
		<updated>2016-12-10T10:32:10Z</updated>

		<summary type="html">&lt;p&gt;DennZo1993: /* Последовательная сложность алгоритма */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Assignment|Zhum}}&lt;br /&gt;
&lt;br /&gt;
{{algorithm&lt;br /&gt;
| name              = Алгоритм k средних (k means)&lt;br /&gt;
| serial_complexity = &amp;lt;math&amp;gt;O(\Tau*k*d*n)&amp;lt;/math&amp;gt;&lt;br /&gt;
| input_data        = &amp;lt;math&amp;gt; d*n &amp;lt;/math&amp;gt;&lt;br /&gt;
| output_data       = &amp;lt;math&amp;gt; n &amp;lt;/math&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
Авторы страницы &amp;lt;b&amp;gt;[[Участник:Бротиковская Данута|Данута Бротиковская]]&amp;lt;/b&amp;gt; и &amp;lt;b&amp;gt;[[Участник:DennZo1993|Денис Зобнин]]&amp;lt;/b&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
Оба автора внесли одинаковый вклад в написание статьи (поиск материалов, изучение статей, заполнение контента статьи), четких разграничений по пунктам статьи сделать невозможно. &lt;br /&gt;
&lt;br /&gt;
== Свойства и структура алгоритма ==&lt;br /&gt;
&lt;br /&gt;
=== Общее описание алгоритма ===&lt;br /&gt;
Алгоритм &amp;lt;b&amp;gt;&amp;lt;i&amp;gt;k средних&amp;lt;/i&amp;gt;&amp;lt;/b&amp;gt; (&amp;lt;b&amp;gt;&amp;lt;i&amp;gt;k means&amp;lt;/i&amp;gt;&amp;lt;/b&amp;gt;) &amp;amp;ndash; неиерархический&amp;lt;ref&amp;gt;&amp;quot;https://ru.wikipedia.org/wiki/Иерархическая_кластеризация&amp;quot;&amp;lt;/ref&amp;gt;, итерационный метод кластеризации&amp;lt;ref&amp;gt;&amp;quot;https://ru.wikipedia.org/wiki/Кластерный_анализ&amp;quot;&amp;lt;/ref&amp;gt;, получивший большую популярность благодаря своей простоте, наглядности реализации и достаточно высокому качеству работы. Был изобретен в 1950-х годах математиком &amp;lt;i&amp;gt;Гуго Штейнгаузом&amp;lt;/i&amp;gt;&amp;lt;ref&amp;gt;Steinhaus, Hugo. &amp;quot;Sur la division des corp materiels en parties.&amp;quot; Bull. Acad. Polon. Sci 1.804 (1956): 801.&amp;lt;/ref&amp;gt; и почти одновременно &amp;lt;i&amp;gt;Стюартом Ллойдом&amp;lt;/i&amp;gt;&amp;lt;ref&amp;gt;Lloyd, S. P. &amp;quot;Least square quantization in PCM. Bell Telephone Laboratories Paper. Published in journal much later: Lloyd, SP: Least squares quantization in PCM.&amp;quot; IEEE Trans. Inform. Theor.(1957/1982).&amp;lt;/ref&amp;gt;. Особую популярность приобрел после публикации работы &amp;lt;i&amp;gt;МакКуина&amp;lt;/i&amp;gt;&amp;lt;ref&amp;gt;MacQueen, James. &amp;quot;Some methods for classification and analysis of multivariate observations.&amp;quot; Proceedings of the fifth Berkeley symposium on mathematical statistics and probability. Vol. 1. No. 14. 1967.&amp;lt;/ref&amp;gt; в 1967.&lt;br /&gt;
&lt;br /&gt;
Алгоритм представляет собой версию EM-алгоритма&amp;lt;ref&amp;gt;&amp;quot;https://ru.wikipedia.org/wiki/EM-алгоритм&amp;quot;&amp;lt;/ref&amp;gt;, применяемого также для разделения смеси гауссиан. Основная идея &amp;lt;i&amp;gt;k means&amp;lt;/i&amp;gt; заключается в том, что данные произвольно разбиваются на кластеры, после чего итеративно перевычисляется центр масс для каждого кластера, полученного на предыдущем шаге, затем векторы разбиваются на кластеры вновь в соответствии с тем, какой из новых центров оказался ближе по выбранной метрике.&lt;br /&gt;
&lt;br /&gt;
Цель алгоритма заключается в разделении &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; наблюдений на &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластеров таким образом, чтобы каждое наблюдение принадлежало ровно одному кластеру, расположенному на наименьшем расстоянии от наблюдения.&lt;br /&gt;
&lt;br /&gt;
=== Математическое описание алгоритма ===&lt;br /&gt;
&amp;lt;b&amp;gt;&amp;lt;u&amp;gt;Дано:&amp;lt;/u&amp;gt;&amp;lt;/b&amp;gt;&lt;br /&gt;
* набор из &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; наблюдений &amp;lt;math&amp;gt;X=\{\mathbf{x}_1, \mathbf{x}_2, ..., \mathbf{x}_n\}, \mathbf{x}_i \in \mathbb{R}^d, i=\overline{1, n}&amp;lt;/math&amp;gt;;&lt;br /&gt;
* &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; - требуемое число кластеров, &amp;lt;math&amp;gt;k \in \mathbb{N}, k \leq n&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;&amp;lt;u&amp;gt;Требуется:&amp;lt;/u&amp;gt;&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Разделить множество наблюдений &amp;lt;math&amp;gt;X&amp;lt;/math&amp;gt; на &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластеров &amp;lt;math&amp;gt;S_1, S_2, ..., S_k&amp;lt;/math&amp;gt;:&lt;br /&gt;
*   &amp;lt;math&amp;gt;S_i \cap S_j= \varnothing, \quad i \ne j&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
*   &amp;lt;math&amp;gt;\bigcup_{i=1}^{k} S_i = X&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;&amp;lt;u&amp;gt;Действие алгоритма:&amp;lt;/u&amp;gt;&amp;lt;/b&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;Алгоритм &amp;lt;i&amp;gt;k means&amp;lt;/i&amp;gt; разбивает набор &amp;lt;math&amp;gt;X&amp;lt;/math&amp;gt; на &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; наборов &amp;lt;math&amp;gt;S_1, S_2, ..., S_k,&amp;lt;/math&amp;gt; таким образом, чтобы минимизировать сумму квадратов расстояний от каждой точки кластера до его центра (центр масс кластера). Введем обозначение, &amp;lt;math&amp;gt;S=\{S_1, S_2, ..., S_k\}&amp;lt;/math&amp;gt;. Тогда действие алгоритма &amp;lt;i&amp;gt;k means&amp;lt;/i&amp;gt; равносильно поиску:&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;table style=&amp;quot;width:100%&amp;quot;&amp;gt;&lt;br /&gt;
  &amp;lt;tr&amp;gt;&lt;br /&gt;
    &amp;lt;td align=&amp;quot;center&amp;quot; width=&amp;quot;90%&amp;quot;&amp;gt;&amp;lt;math&amp;gt;\arg\min_{S} \sum\limits_{i=1}^k \sum\limits_{\mathbf{x} \in S_i} \rho(\mathbf{x}, \mathbf{\mu}_i )^2,&amp;lt;/math&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;td align=&amp;quot;right&amp;quot;&amp;gt;&amp;lt;math&amp;gt;(1)&amp;lt;/math&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;/table&amp;gt;&lt;br /&gt;
где &amp;lt;math&amp;gt;\mathbf{\mu}_i&amp;lt;/math&amp;gt; &amp;amp;ndash; центры кластеров, &amp;lt;math&amp;gt;i=\overline{1,k}, \quad \rho(\mathbf{x}, \mathbf{\mu}_i)&amp;lt;/math&amp;gt; &amp;amp;ndash; функция расстояния между &amp;lt;math&amp;gt;\mathbf{x}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\mu_i&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;&amp;lt;u&amp;gt;Шаги алгоритма: &amp;lt;/u&amp;gt;&amp;lt;/b&amp;gt;&lt;br /&gt;
&amp;lt;ol&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&lt;br /&gt;
    &amp;lt;b&amp;gt;Начальный шаг: инициализация кластеров&amp;lt;/b&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;Выбирается произвольное множество точек &amp;lt;math&amp;gt;\mu_i, i=\overline{1,k}&amp;lt;/math&amp;gt;, рассматриваемых как начальные центры кластеров: &amp;lt;math&amp;gt;\mu_i^{(0)} = \mu_i, \quad i=\overline{1, k}&amp;lt;/math&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
  &amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&lt;br /&gt;
    &amp;lt;b&amp;gt;Распределение векторов по кластерам&amp;lt;/b&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Шаг&amp;lt;/b&amp;gt; &amp;lt;math&amp;gt;t: \forall \mathbf{x}_i \in X, i=\overline{1,n}: \mathbf{x}_i \in S_j \iff  j=\arg\min_{k}\rho(\mathbf{x}_i,\mathbf{\mu}_k^{(t-1)})^2&amp;lt;/math&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
  &amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&lt;br /&gt;
    &amp;lt;b&amp;gt;Пересчет центров кластеров&amp;lt;/b&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Шаг &amp;lt;/b&amp;gt; &amp;lt;math&amp;gt;t: \forall i=\overline{1,k}:  \mu_i^{(t)} = \cfrac{1}{|S_i|}\sum_{\mathbf{x}\in S_i}\mathbf{x}&amp;lt;/math&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
  &amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&lt;br /&gt;
    &amp;lt;b&amp;gt;Проверка условия останова:&amp;lt;/b&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
    &#039;&#039;&#039;if&#039;&#039;&#039; &amp;lt;math&amp;gt;\exist i\in \overline{1,k}: \mu_i^{(t)} \ne \mu_i^{(t-1)}&amp;lt;/math&amp;gt; &#039;&#039;&#039;then&#039;&#039;&#039;&lt;br /&gt;
        t = t + 1;&lt;br /&gt;
        goto 2;&lt;br /&gt;
    &#039;&#039;&#039;else&#039;&#039;&#039;&lt;br /&gt;
        &#039;&#039;&#039;stop&#039;&#039;&#039;&lt;br /&gt;
  &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ol&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Вычислительное ядро алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Вычислительным ядром являются шаги 2 и 3 приведенного выше алгоритма: &amp;lt;b&amp;gt;&amp;lt;i&amp;gt;распределение векторов по кластерам&amp;lt;/i&amp;gt;&amp;lt;/b&amp;gt; и &amp;lt;b&amp;gt;&amp;lt;i&amp;gt;пересчет центров кластеров&amp;lt;/i&amp;gt;&amp;lt;/b&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;&amp;lt;i&amp;gt;Распределение векторов&amp;lt;/i&amp;gt;&amp;lt;/b&amp;gt; по кластерам предполагает вычисление расстояний между каждым вектором &amp;lt;math&amp;gt;\mathbf{x}_i \in X, i= \overline{1,n}&amp;lt;/math&amp;gt; и центрами кластера &amp;lt;math&amp;gt;\mathbf{\mu}_j, j= \overline{1,k}&amp;lt;/math&amp;gt;. Таким образом, данный шаг предполагает &amp;lt;math&amp;gt;kn&amp;lt;/math&amp;gt; вычислений расстояний между d-мерными векторами. &lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;&amp;lt;i&amp;gt;Пересчет центров кластеров&amp;lt;/i&amp;gt;&amp;lt;/b&amp;gt; предполагает &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; вычислений центров масс &amp;lt;math&amp;gt;\mathbf{\mu}_i&amp;lt;/math&amp;gt; множеств &amp;lt;math&amp;gt;S_i, i=\overline{1,k}&amp;lt;/math&amp;gt; представленных выражением в шаге 3 представленного выше алгоритма.&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Макроструктура алгоритма ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Инициализация центров масс &amp;lt;math&amp;gt;\mu_1, ..., \mu_k&amp;lt;/math&amp;gt;&amp;lt;/b&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
Наиболее распространенными являются следующие стратегии:&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&lt;br /&gt;
    &amp;lt;b&amp;gt;Метод Forgy&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;В качестве начальных значений &amp;lt;math&amp;gt;\mu_1, ..., \mu_k&amp;lt;/math&amp;gt; берутся случайно выбранные векторы.&lt;br /&gt;
  &amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&lt;br /&gt;
    &amp;lt;b&amp;gt;Метод случайно разделения (Random Partitioning)&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;Для каждого вектора &amp;lt;math&amp;gt;\mathbf{x}_i \in X, i=\overline{1, n}&amp;lt;/math&amp;gt; выбирается случайным образом кластер &amp;lt;math&amp;gt;S_1, ..., S_k&amp;lt;/math&amp;gt;, после чего для каждого полученного кластера вычисляются значения &amp;lt;math&amp;gt;\mu_1, ..., \mu_k&amp;lt;/math&amp;gt;.&lt;br /&gt;
  &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Распределение векторов по кластерам&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Для этого шага алгоритма между векторами &amp;lt;math&amp;gt;\mathbf{x}_i \in X, i=\overline{1, n}&amp;lt;/math&amp;gt; и центрами кластеров &amp;lt;math&amp;gt;\mu_1, ..., \mu_k&amp;lt;/math&amp;gt; вычисляются &amp;lt;b&amp;gt;расстояния&amp;lt;/b&amp;gt; по формуле (как правило, используется Евлидово расстояние):&lt;br /&gt;
&amp;lt;table style=&amp;quot;width:100%&amp;quot;&amp;gt;&lt;br /&gt;
  &amp;lt;tr&amp;gt;&lt;br /&gt;
    &amp;lt;td align=&amp;quot;center&amp;quot; width=&amp;quot;90%&amp;quot;&amp;gt;&amp;lt;math&amp;gt; \mathbf{v}_1, \mathbf{v}_2 \in \mathbb{R}^d,  \quad \rho(\mathbf{v}_1, \mathbf{v}_2) = \lVert \mathbf{v}_1- \mathbf{v}_2 \rVert= \sqrt{\sum_{i=1}^{d}(\mathbf{v}_{1,i} - \mathbf{v}_{2,i})^2}&amp;lt;/math&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;td align=&amp;quot;right&amp;quot;&amp;gt;&amp;lt;math&amp;gt;(2)&amp;lt;/math&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;/table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Пересчет центров кластеров&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Для этого шага алгоритма производится пересчет центров кластера по &amp;lt;b&amp;gt;формуле вычисления центра масс&amp;lt;/b&amp;gt;:&lt;br /&gt;
&amp;lt;table style=&amp;quot;width:100%&amp;quot;&amp;gt;&lt;br /&gt;
  &amp;lt;tr&amp;gt;&lt;br /&gt;
    &amp;lt;td align=&amp;quot;center&amp;quot; width=&amp;quot;90%&amp;quot;&amp;gt;&amp;lt;math&amp;gt; \mu = \cfrac{1}{|S|}\sum_{\mathbf{x}\in S}\mathbf{x}&amp;lt;/math&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;td align=&amp;quot;right&amp;quot;&amp;gt;&amp;lt;math&amp;gt;(3)&amp;lt;/math&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;/table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Схема реализации последовательного алгоритма ===&lt;br /&gt;
&lt;br /&gt;
 &#039;&#039;&#039;algorithm&#039;&#039;&#039; k-means &#039;&#039;&#039;is&#039;&#039;&#039;&lt;br /&gt;
     &#039;&#039;&#039;1.&#039;&#039;&#039; Инициализировать центры кластеров &amp;lt;math&amp;gt;\mathbf{\mu}_i^{(1)}, i=\overline{1,k}&amp;lt;/math&amp;gt;&lt;br /&gt;
     &#039;&#039;&#039;2.&#039;&#039;&#039; &amp;lt;math&amp;gt;t \leftarrow 1&amp;lt;/math&amp;gt;&lt;br /&gt;
     &#039;&#039;&#039;3.&#039;&#039;&#039; &#039;&#039;&#039;Распределение по кластерам&#039;&#039;&#039;&amp;lt;br&amp;gt;&lt;br /&gt;
        &amp;lt;math&amp;gt;S_i^{(t)}=\{\mathbf{x}_p: \lVert\mathbf{x}_p-\mathbf{\mu}_i^{(t)}\rVert^2 \leq \lVert\mathbf{x}_p-\mathbf{\mu}_j^{(t)}\rVert^2 \quad \forall j=\overline{1,k}\},&amp;lt;/math&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
        где каждый вектор &amp;lt;math&amp;gt;\mathbf{x}_p&amp;lt;/math&amp;gt; соотносится единственному кластеру &amp;lt;math&amp;gt;S^{(t)}&amp;lt;/math&amp;gt;&lt;br /&gt;
     &#039;&#039;&#039;4.&#039;&#039;&#039; &#039;&#039;&#039;Обновление центров кластеров&#039;&#039;&#039;&amp;lt;br&amp;gt;&lt;br /&gt;
        &amp;lt;math&amp;gt;\mathbf{\mu}_i^{(t+1)} = \frac{1}{|S^{(t)}_i|} \sum_{\mathbf{x}_j \in S^{(t)}_i} \mathbf{x}_j &amp;lt;/math&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
     &#039;&#039;&#039;5.&#039;&#039;&#039; &#039;&#039;&#039;if&#039;&#039;&#039; &amp;lt;math&amp;gt;\exist i \in \overline{1,k}: \mathbf{\mu}_i^{(t+1)} \ne \mathbf{\mu}_i^{(t)}&amp;lt;/math&amp;gt; &#039;&#039;&#039;then&#039;&#039;&#039;&lt;br /&gt;
            t = t + 1;&lt;br /&gt;
            goto &#039;&#039;&#039;3&#039;&#039;&#039;;&lt;br /&gt;
        &#039;&#039;&#039;else&#039;&#039;&#039;&lt;br /&gt;
            &#039;&#039;&#039;stop&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
=== Последовательная сложность алгоритма===&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding-bottom: 20px&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;Обозначим &amp;lt;math&amp;gt;\Theta_{centroid}^{d, m}&amp;lt;/math&amp;gt; временную сложность вычисления центорида кластера, число элементов которого равна &amp;lt;math&amp;gt;m&amp;lt;/math&amp;gt;,  в d-мерном пространстве.&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;Аналогично  &amp;lt;math&amp;gt;\Theta_{distance}^d&amp;lt;/math&amp;gt; &amp;amp;ndash; временная сложность вычисления расстояния между двумя d-мерными векторами.&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding-bottom: 20px&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;Сложность шага инициализации &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластеров мощности &amp;lt;math&amp;gt;m&amp;lt;/math&amp;gt; в d-мерном пространстве &amp;amp;ndash; &amp;lt;math&amp;gt;\Theta_{init}^{k, d, m}&amp;lt;/math&amp;gt;&amp;lt;/b&amp;gt;&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;i&amp;gt;Стратерия Forgy&amp;lt;/i&amp;gt;: вычисления не требуются, &amp;lt;math&amp;gt;\Theta_{init}^{k, d, m} = 0&amp;lt;/math&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;i&amp;gt;Стратегия случайного разбиения&amp;lt;/i&amp;gt;: вычисление центров &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластеров,  &amp;lt;math&amp;gt;\Theta_{init}^{k, d, m} = k \cdot \Theta_{centroid}^{d, m}, m \le n&amp;lt;/math&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding-bottom: 20px&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Cложность шага распределения d мерных векторов по &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластерам &amp;amp;ndash; &amp;lt;math&amp;gt;\Theta_{distribute}^{k, d}&amp;lt;/math&amp;gt;&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
На этом шаге для каждого вектора &amp;lt;math&amp;gt;\mathbf{x}_i \in X, i=\overline{1, n}&amp;lt;/math&amp;gt; вычисляется k расстояний до центров кластеров &amp;lt;math&amp;gt;\mathbf{\mu}_1, ...\mathbf{\mu}_k&amp;lt;/math&amp;gt;&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p align=&amp;quot;center&amp;quot;&amp;gt;&lt;br /&gt;
  &amp;lt;math&amp;gt;\Theta_{distribute}^{k, d} = n \cdot k \cdot \Theta_{distance}^d&amp;lt;/math&amp;gt;&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding-bottom: 20px&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;Сложность шага пересчета центров &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластеров размера &amp;lt;math&amp;gt;m&amp;lt;/math&amp;gt; в d-мерном пространстве &amp;amp;ndash; &amp;lt;math&amp;gt;\Theta_{recenter}^{k, d, m}&amp;lt;/math&amp;gt;&amp;lt;/b&amp;gt;&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;На этом шаге вычисляется &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; центров кластеров &amp;lt;math&amp;gt;\mathbf{\mu}_1, ...\mathbf{\mu}_k&amp;lt;/math&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p align=&amp;quot;center&amp;quot;&amp;gt;&amp;lt;math&amp;gt;\Theta_{recenter}^{k, d, m} = k \cdot \Theta_{centroid}^{d, m}&amp;lt;/math&amp;gt; &amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding-bottom: 20px&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Рассчитаем &amp;lt;math&amp;gt;\Theta_{centroid}^{d, m}&amp;lt;/math&amp;gt; для кластера, число элементов которого равно &amp;lt;math&amp;gt;m&amp;lt;/math&amp;gt;&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p align=&amp;quot;center&amp;quot;&amp;gt;&amp;lt;math&amp;gt;\Theta_{centroid}^{d, m}&amp;lt;/math&amp;gt; = &amp;lt;math&amp;gt;md&amp;lt;/math&amp;gt; сложений + &amp;lt;math&amp;gt;d&amp;lt;/math&amp;gt; делений &amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding-bottom: 20px&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Рассчитаем &amp;lt;math&amp;gt;\Theta_{distance}^d&amp;lt;/math&amp;gt; в соответствие с формулой &amp;lt;math&amp;gt;(2)&amp;lt;/math&amp;gt;&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p align=&amp;quot;center&amp;quot;&amp;gt;&amp;lt;math&amp;gt;\Theta_{distance}^d&amp;lt;/math&amp;gt; = &amp;lt;math&amp;gt;d&amp;lt;/math&amp;gt; вычитаний + &amp;lt;math&amp;gt;d&amp;lt;/math&amp;gt; умножений + &amp;lt;math&amp;gt;(d-1)&amp;lt;/math&amp;gt; сложение&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding-bottom: 20px&amp;quot;&amp;gt;&lt;br /&gt;
  &amp;lt;p&amp;gt;Предположим, что алгоритм сошелся за &amp;lt;math&amp;gt;\Tau&amp;lt;/math&amp;gt; итераций, тогда временная сложность алгоритма &amp;lt;math&amp;gt;\Theta_{k-means}^{d, n}&amp;lt;/math&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
  &amp;lt;p align=&amp;quot;center&amp;quot;&amp;gt;&amp;lt;b&amp;gt;&amp;lt;math&amp;gt;\Theta_{k-means}^{d, n} \le \Theta_{init}^{k, d, n} + \Tau(\Theta_{distribute}^{k, d} + \Theta_{recenter}^{k, d, n})&amp;lt;/math&amp;gt;&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding-bottom: 5px&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;Операции сложения/вычитания:&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p align=&amp;quot;center&amp;quot;&amp;gt;&amp;lt;b&amp;gt;&amp;lt;math&amp;gt;\Theta_{k-means}^{d, n} \le knd+ \Tau*(kn(2d-1) + k \cdot n \cdot d) = knd+ \Tau*(kn(3d-1)) \thicksim O(\Tau kdn)&amp;lt;/math&amp;gt;&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding-bottom: 20px&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;Операции умножения/деления:&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p align=&amp;quot;center&amp;quot;&amp;gt;&amp;lt;b&amp;gt;&amp;lt;math&amp;gt;\Theta_{k-means}^{d, n} \le k*d + \Tau*(k*n*d + k*d) = k*d + \Tau * k*d*(n+1) \thicksim O(\Tau*k*d*n) &amp;lt;/math&amp;gt;&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding-bottom: 20px&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;Получаем, что &amp;lt;b&amp;gt;временная сложность&amp;lt;/b&amp;gt; алгоритма &amp;lt;b&amp;gt;k means&amp;lt;/b&amp;gt; кластеризации &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; &amp;lt;b&amp;gt;d-мерных&amp;lt;/b&amp;gt; векторов на &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластеров за &amp;lt;math&amp;gt;\Tau&amp;lt;/math&amp;gt; итераций:&amp;lt;/p&amp;gt;&lt;br /&gt;
 &amp;lt;p align=&amp;quot;center&amp;quot;&amp;gt;&amp;lt;b&amp;gt;&amp;lt;math&amp;gt; \Theta_{k-means}^{d, n} \thicksim O(\Tau*k*d*n) &amp;lt;/math&amp;gt;&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Информационный граф ===&lt;br /&gt;
&lt;br /&gt;
Рассмотрим информационный граф алгоритма. Алгоритм &amp;lt;i&amp;gt;k means&amp;lt;/i&amp;gt; начинается с этапа инициализации, после которого следуют итерации, на каждой из которых выполняется два последовательных шага (см. [[#Схема реализации последовательного алгоритма|&amp;quot;Схема реализации последовательного алгоритма&amp;quot;]]): &lt;br /&gt;
* распределение векторов по кластерам&lt;br /&gt;
* перерасчет центров кластеров&lt;br /&gt;
&lt;br /&gt;
Поскольку основная часть вычислений приходится на шаги итераций, распишем информационные графы данных шагов.&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Распределение векторов по кластерам&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
Информационный граф шага распределения векторов по кластерам представлен на &#039;&#039;рисунке 1&#039;&#039;. Исходами данного графа является исходные векторы &amp;lt;math&amp;gt;\mathbf{x}_1, ..., \mathbf{x}_n&amp;lt;/math&amp;gt;, а также центры кластеров &amp;lt;math&amp;gt;\mathbf{\mu}_1, ... \mathbf{\mu}_k&amp;lt;/math&amp;gt;, вычисленные ранее (на шаге инициализации, если рассматривается первая итерация алгоритма, или на шаге пересчета центров кластеров предыдущей итерации в противном случае). Каждая пара векторов данных &amp;lt;math&amp;gt;\mathbf{x}_i, i=\overline{1,n}&amp;lt;/math&amp;gt; и центров кластера &amp;lt;math&amp;gt;\mathbf{\mu}_j, j=\overline{1, k}&amp;lt;/math&amp;gt; : (&amp;lt;math&amp;gt;\mathbf{x}_i&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;\mathbf{\mu}_j&amp;lt;/math&amp;gt;) подаются на независимые узлы &amp;lt;i&amp;gt;&amp;quot;d&amp;quot;&amp;lt;/i&amp;gt; вычисления расстояния между векторами (более подробная схема вычисления расстояния представлена далее, &#039;&#039;рисунок 2&#039;&#039;). Далее узлы вычисления расстояния &amp;lt;i&amp;gt;&amp;quot;d&amp;quot;&amp;lt;/i&amp;gt;, соответствующие одному и тому же исходному вектору &amp;lt;math&amp;gt;\mathbf{x}_i&amp;lt;/math&amp;gt; передаются на один узел &amp;lt;i&amp;gt;&amp;quot;m&amp;quot;&amp;lt;/i&amp;gt;, где далее происходит вычисление новой метки кластера для каждого вектора &amp;lt;math&amp;gt;\mathbf{x}_i&amp;lt;/math&amp;gt; (берется кластер с минимальным результатом вычисления расстояния). На выходе графа выдаются метки кластеров , &amp;lt;math&amp;gt;L_1, ..., L_n&amp;lt;/math&amp;gt;, такие что &amp;lt;math&amp;gt;\forall \mathbf{x}_i, i=\overline{1, n}, \mathbf{x}_i \in S_j \Leftrightarrow L_i = j&amp;lt;/math&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
[[file:Clusterization.png|thumb|center|800px|Рис. 1. Схема распределения векторов по кластерам. &#039;&#039;d&#039;&#039; &amp;amp;ndash; вычисление расстояния между векторами; &#039;&#039;m&#039;&#039; &amp;amp;ndash; вычисление минимума.]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Вычисление расстояния между векторами&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
Подробная схема вычисления расстояния между векторами &amp;lt;math&amp;gt;\mathbf{x}_i, \mathbf{\mu}_j&amp;lt;/math&amp;gt; представлена на &#039;&#039;рисунке 2&#039;&#039;. Как показано на графе, узел вычисления расстояния между векторами &amp;lt;i&amp;gt;&amp;quot;d&amp;quot;&amp;lt;/i&amp;gt; состоит из шага взятия разности между векторами (узел &amp;quot;&amp;lt;math&amp;gt;-&amp;lt;/math&amp;gt;&amp;quot;) и взятия нормы получившегося вектора разности (узел &amp;quot;&amp;lt;math&amp;gt;||\cdot||^2&amp;lt;/math&amp;gt;&amp;quot;). Более подробно, вычисление расстояния между векторами &amp;lt;math&amp;gt;\mathbf{x}_i = {x_{i1,}, ...,{x_{in}}}, \mathbf{\mu}_j = {\mu_{j1}, ...,\mu_{jn}}&amp;lt;/math&amp;gt; может быть представлено как вычисление разности между каждой парой компонент &amp;lt;math&amp;gt;(x_{iz}, \mu_{jz}), z=\overline{1, d}&amp;lt;/math&amp;gt; (узел &amp;quot;&amp;lt;math&amp;gt;-&amp;lt;/math&amp;gt;&amp;quot;), далее возведение в квадрат для каждого узла &amp;quot;&amp;lt;math&amp;gt;-&amp;lt;/math&amp;gt;&amp;quot; (узел &amp;quot;&amp;lt;math&amp;gt;()^2&amp;lt;/math&amp;gt;&amp;quot;) и суммирования выходов всех узлов &amp;quot;&amp;lt;math&amp;gt;()^2&amp;lt;/math&amp;gt;&amp;quot; (узел &amp;quot;&amp;lt;math&amp;gt;+&amp;lt;/math&amp;gt;&amp;quot;).  &lt;br /&gt;
&lt;br /&gt;
[[file:dist_calc.png|thumb|center|800px|Рис. 2. Схема вычисления расстояния между вектором и центром кластера.]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Пересчет центров кластеров&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
Информационный граф шага пересчета центров кластеров представлен на &#039;&#039;рисунке 3&#039;&#039;. Исходами данного графа является исходные векторы &amp;lt;math&amp;gt;\mathbf{x}_1, ..., \mathbf{x}_n&amp;lt;/math&amp;gt;, а также им соответствующие метки кластера, &amp;lt;math&amp;gt;L_1, ..., L_n&amp;lt;/math&amp;gt;, такие что &amp;lt;math&amp;gt;\forall x_i, i=\overline{1, n}, \mathbf{x}_i \in S_j \Leftrightarrow L_i = j&amp;lt;/math&amp;gt;, вычисленные на этапе распределения векторов по кластерам. Все векторы &amp;lt;math&amp;gt;\mathbf{x}_1, ..., \mathbf{x}_n&amp;lt;/math&amp;gt; подаются в узлы &amp;lt;math&amp;gt;+_1, ...+_k&amp;lt;/math&amp;gt;, каждый узел &amp;lt;math&amp;gt;+_m, m = \overline{1,k}&amp;lt;/math&amp;gt; соответствует операции сложения векторов кластера с номером &amp;lt;math&amp;gt;m&amp;lt;/math&amp;gt;. Метки кластера &amp;lt;math&amp;gt;L_1, ..., L_n&amp;lt;/math&amp;gt; также совместно передаются на узлы &amp;lt;math&amp;gt;S_m, m = \overline{1,k}&amp;lt;/math&amp;gt;, на каждом из которых вычисляется количество векторов в соответствующем кластере (количество меток с соответствующим значением). Далее каждая пара выходов узлов &amp;lt;math&amp;gt;+_m&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;S_m&amp;lt;/math&amp;gt; подается на узел &amp;quot;&amp;lt;math&amp;gt;/&amp;lt;/math&amp;gt;&amp;quot;, где производится деление суммы векторов кластера на количество элементов в нем. Значения, вычисленные на узлах &amp;quot;&amp;lt;math&amp;gt;/&amp;lt;/math&amp;gt;&amp;quot;, присваиваются новым центрам кластеров (выходные значения графа).&lt;br /&gt;
&lt;br /&gt;
[[file:Recluster.png|thumb|center|800px|Рис. 3. Схема пересчета центров кластеров]]&lt;br /&gt;
&lt;br /&gt;
=== Ресурс параллелизма алгоритма ===&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
Работа алгоритма состоит из &amp;lt;math&amp;gt;\Tau&amp;lt;/math&amp;gt; итераций, в каждой из которых происходит &amp;lt;b&amp;gt;распределение d-мерных векторов по &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластерам&amp;lt;/b&amp;gt;, а также &amp;lt;b&amp;gt;пересчет центров кластеров в d-мерном пространстве&amp;lt;/b&amp;gt;. В шаге &amp;lt;b&amp;gt;распределения d-мерных векторов по &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластерам&amp;lt;/b&amp;gt; расстояния между вектором и центрами кластеров вычисляются независимо (отсутствуют информационные зависимости). &amp;lt;b&amp;gt;Центры масс кластеров&amp;lt;/b&amp;gt; также пересчитываются независимо друг от друга. Таким образом, имеет место [[глоссарий#Массовый параллелизм|&#039;&#039;массовый параллелизм&#039;&#039;]]. Вычислим параллельную сложность &amp;lt;math&amp;gt;\Psi_*&amp;lt;/math&amp;gt; каждого из шагов, а также параллельную сложность всего алгоритма, &amp;lt;math&amp;gt;\Psi_{k-means}&amp;lt;/math&amp;gt;. Будем исходить из предположения, что может быть использовано любое необходимое число потоков.&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Распределение d-мерных векторов по &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластерам&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;  &lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
Поскольку на данном шаге для каждой пары векторов &amp;lt;math&amp;gt;\mathbf{x}_i, i=\overline{1,n}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\mathbf{\mu}_j, j=\overline{1,k}&amp;lt;/math&amp;gt; операции вычисления расстояния не зависят друг от друга, они могут выполняться параллельно. Тогда, разделив все вычисление расстояний на &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; потоков, получим, что в каждом потоке будет выполняться только одна операция вычисления расстояния между векторами размерности d. При этом каждому вычислительному потоку передаются координаты центров всех кластеров &amp;lt;math&amp;gt;\mathbf{\mu}_1, ..., \mathbf{\mu}_k&amp;lt;/math&amp;gt;. Таким образом, параллельная сложность данного шага определяется &amp;lt;i&amp;gt; сложностью параллельной операции вычисления расстояния между d-мерными векторами&amp;lt;/i&amp;gt;, &amp;lt;math&amp;gt;\Psi_{distance}^d&amp;lt;/math&amp;gt;  и &amp;lt;i&amp;gt;сложностью определения наиболее близкого кластера&amp;lt;/i&amp;gt; (паралельное взятие минимума по расстояниям), &amp;lt;math&amp;gt;\Psi_{min}^k&amp;lt;/math&amp;gt;. Для оценки &amp;lt;math&amp;gt;\Psi_{distance}^d&amp;lt;/math&amp;gt; воспользуемся  [[Нахождение_частных_сумм_элементов_массива_сдваиванием | параллельной реализацией нахождения частичной суммы элементов массива путем сдваивания]]. Аналогично, &amp;lt;math&amp;gt;\Psi_{min}^k = log(k)&amp;lt;/math&amp;gt;. В результате, &amp;lt;math&amp;gt;\Psi_{distance}^d = O(log(d))&amp;lt;/math&amp;gt;.   Таким образом: &lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p align=&amp;quot;center&amp;quot;&amp;gt;&amp;lt;math&amp;gt;\Psi_{distribute}^{k, d}  = \Psi_{distance}^d + \Psi_{min}^k = O(log(d))+O(log(k)) = O(log(k*d))&amp;lt;/math&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Пересчет центров кластеров в d-мерном пространстве&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
Поскольку на данном шаге для каждого из &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластеров центр масс может быть вычислен независимо, данные операции могут быть выполнены в отдельных потоках. Таким образом, параллельная сложность данного шага, &amp;lt;math&amp;gt;\Psi_{recenter}^{k, d}&amp;lt;/math&amp;gt;,  будет определяться &amp;lt;i&amp;gt;параллельной сложностью вычисления одного центра масс кластера размера &amp;lt;math&amp;gt;m&amp;lt;/math&amp;gt;&amp;lt;/i&amp;gt;, &amp;lt;math&amp;gt;\Psi_{recenter}^{k, d}&amp;lt;/math&amp;gt;,  а так как &amp;lt;math&amp;gt;m \le n \Rightarrow \Psi_{recenter}^{d, m} \le \Psi_{recenter}^{d, n}&amp;lt;/math&amp;gt;. Сложность вычисления центра масс кластера d-мерных векторов размера n аналогично предыдущим вычислениям равна &amp;lt;math&amp;gt;O(log(n))&amp;lt;/math&amp;gt;. Тогда:  &lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p align=&amp;quot;center&amp;quot;&amp;gt;&amp;lt;math&amp;gt;\Psi_{recenter}^{k, d}  \le \Psi_{recenter}^{d, n} = O(log(n))&amp;lt;/math&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Общая параллельная сложность алгоритма&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
На каждой итерации необходимо обновление центров кластеров, которые будут использованы на следующей итерации. Таким образом, итерационный процесс выполняется последовательно&amp;lt;ref&amp;gt;Zhao, Weizhong, Huifang Ma, and Qing He. &amp;quot;Parallel k-means clustering based on mapreduce.&amp;quot; IEEE International Conference on Cloud Computing. Springer Berlin Heidelberg, 2009.&amp;lt;/ref&amp;gt;. Тогда, поскольку сложность каждой итерации  определяется &amp;lt;math&amp;gt;\Psi_{distribute}^{k, d}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\Psi_{recenter}&amp;lt;/math&amp;gt;, сложность всего алгоритма, &amp;lt;math&amp;gt;\Psi_{k-means}&amp;lt;/math&amp;gt; в предположении, что было сделано &amp;lt;math&amp;gt;\Tau&amp;lt;/math&amp;gt; операций определяется выражением&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p align=&amp;quot;center&amp;quot;&amp;gt;&amp;lt;math&amp;gt;\Psi_{k-means} \approx \Tau * (\Psi_{distribute}^{k, d} + \Psi_{recenter}^{k, d}) \le \Tau * O(log(k*d*n))&amp;lt;/math&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Входные и выходные данные алгоритма ===&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;Входные данные&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;Матрица из &amp;lt;math&amp;gt;n*d&amp;lt;/math&amp;gt; элементов &amp;lt;math&amp;gt;x_{i, j} \in \mathbb{R}, i=\overline{1, n}, j=\overline{1, d}&amp;lt;/math&amp;gt;&amp;amp;ndash; координат векторов (наблюдений).&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;Целое положительное число &amp;lt;math&amp;gt;k, k \le n&amp;lt;/math&amp;gt; &amp;amp;ndash; количество кластеров.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;Объем входных данных&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;math&amp;gt;1&amp;lt;/math&amp;gt; целое число + &amp;lt;math&amp;gt;n*d&amp;lt;/math&amp;gt; вещественных чисел (при условии, что координаты &amp;amp;ndash; вещественные числа).&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;Выходные данные&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; целых положительных чисел &amp;lt;math&amp;gt;L_1, ..., L_n&amp;lt;/math&amp;gt;&amp;amp;ndash; номера кластеров, соотвествующие каждому вектору (при условии, что нумерация кластеров начинается с &amp;lt;math&amp;gt;1&amp;lt;/math&amp;gt;).&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;Объем выходных данных&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; целых положительных чисел.&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Свойства алгоритма ===&lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;[[глоссарий#Вычислительная мощность|&#039;&#039;Вычислительная мощность&#039;&#039;]]&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
Вычислительная мощность алгоритма &amp;lt;i&amp;gt;k means&amp;lt;/i&amp;gt; равна &amp;lt;math&amp;gt;\frac{k*d*n*\Tau}{n*d} = k*\Tau &amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; &amp;amp;ndash; число кластеров, &amp;lt;math&amp;gt;\Tau&amp;lt;/math&amp;gt; &amp;amp;ndash; число итераций алгоритма.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;[[глоссарий#Детерминированность |&#039;&#039;Детерминированность&#039;&#039;]] и [[глоссарий#Устойчивость |&#039;&#039;Устойчивость&#039;&#039;]] &amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
Алгоритм &amp;lt;i&amp;gt;k means&amp;lt;/i&amp;gt; является итерационным. Количество итераций алгоритма в общем случае не фиксируется и зависит от начального расположения объектов в пространстве, параметра &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt;, а также от начального приближения центров кластеров, &amp;lt;math&amp;gt;\mu_1, ..., \mu_k&amp;lt;/math&amp;gt;. В результате этого может варьироваться результат работы алгоритма. При неудачном выборе начальных параметров итерационный процесс может сойтись к локальному оптимуму&amp;lt;ref&amp;gt;Von Luxburg, Ulrike. Clustering Stability. Now Publishers Inc, 2010.&amp;lt;/ref&amp;gt;. По этим причинам алгоритм не является ни &amp;lt;b&amp;gt;детермирированным&amp;lt;/b&amp;gt;, ни &amp;lt;b&amp;gt;устойчивым&amp;lt;/b&amp;gt;.&lt;br /&gt;
 &lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Соотношение последовательной и параллельной сложности алгоритма&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\frac{\Theta_{k-means}}{\Psi_{k-means}} = \frac{O(\Tau*k*d*n)}{O(\Tau*log(k*d*n))}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Сильные стороны алгоритма&amp;lt;/b&amp;gt;:&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;i&amp;gt;Сравнительно высокая эффективность при простоте реализации&amp;lt;/i&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;i&amp;gt;Высокое качество кластеризации&amp;lt;/i&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;i&amp;gt;Возможность распараллеливания&amp;lt;/i&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;i&amp;gt;Существование множества модификаций&amp;lt;/i&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;Недостатки алгоритма&amp;lt;/b&amp;gt;&amp;lt;ref&amp;gt;Ortega, Joaquín Pérez, Ma Del Rocío Boone Rojas, and María J. Somodevilla. &amp;quot;Research issues on K-means Algorithm: An Experimental Trial Using Matlab.&amp;quot;&amp;lt;/ref&amp;gt;:&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;i&amp;gt;Количество кластеров является параметром алгоритма&amp;lt;/i&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;&amp;lt;i&amp;gt;Чувствительность к начальным условиям&amp;lt;/i&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;Инициализация центров кластеров в значительной степени влияет на результат кластеризации.&amp;lt;/p&amp;gt;&lt;br /&gt;
  &amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;&amp;lt;i&amp;gt;Чувствительность к выбросам и шумам&amp;lt;/i&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;Выбросы, далекие от центров настоящих кластеров, все равно учитываются при вычислении их центров.&amp;lt;/p&amp;gt;&lt;br /&gt;
  &amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;&amp;lt;i&amp;gt;Возможность сходимости к локальному оптимуму&amp;lt;/i&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;Итеративный подход не дает гарантии сходимости к оптимальному решению.&amp;lt;/p&amp;gt;&lt;br /&gt;
  &amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;&amp;lt;i&amp;gt;Использование понятия &amp;quot;среднего&amp;quot;&amp;lt;/i&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;Алгоритм неприменим к данным, для которых не определено понятие &amp;quot;среднего&amp;quot;, например, категориальным данным.&amp;lt;/p&amp;gt;&lt;br /&gt;
  &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&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;
Исследование масштабируемости параллельной реализации алгоритма k means проводилось на суперкомпьютере &amp;quot;Ломоносов&amp;quot;&amp;lt;ref name=&amp;quot;Lom&amp;quot;&amp;gt;Воеводин Вл., Жуматий С., Соболев С., Антонов А., Брызгалов П., Никитенко Д., Стефанов К., Воеводин Вад. Практика суперкомпьютера «Ломоносов» // Открытые системы, 2012, N 7, С. 36-39.&amp;lt;/ref&amp;gt; [http://parallel.ru/cluster Суперкомпьютерного комплекса Московского университета]. Алгоритм реализован на языке C с использованием средств MPI.&lt;br /&gt;
Для исследования масштабируемости проводилось множество запусков программы с разным значением параметра (количество векторов для кластеризации), а также с различным числом процессоров. Фиксировались результаты запусков &amp;amp;ndash; время работы &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt; и количество произведенных итераций алгоритма &amp;lt;math&amp;gt;\Tau&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Параметры запусков для экспериментальной оценки:&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;Значения &amp;lt;b&amp;gt;количества векторов&amp;lt;/b&amp;gt; &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;: 20&#039;000, 30&#039;000, 50&#039;000, 100&#039;000, 200&#039;000, 300&#039;000, 500&#039;000, 700&#039;000, 1&#039;000&#039;000, 1&#039;500&#039;000, 2&#039;000&#039;000.&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;Значения &amp;lt;b&amp;gt;количества процессоров&amp;lt;/b&amp;gt; &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt;: 1, 8, 16, 32, 64, 128, 160, 192, 224, 256, 288, 320, 352, 384, 416, 448, 480, 512.&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;Значение &amp;lt;b&amp;gt;количества кластеров&amp;lt;/b&amp;gt; &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt;: 100.&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;Значение &amp;lt;b&amp;gt;размерности векторов&amp;lt;/b&amp;gt; &amp;lt;math&amp;gt;d&amp;lt;/math&amp;gt;: 10.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Для проведения экспериментов были сгенерированы нормально распределенные псевдослучайные данные (с использованием Python библиотеки [http://scikit-learn.org/ scikit-learn]):&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
from sklearn.datasets import make_classification&lt;br /&gt;
X1, Y1 = make_classification(n_features=10, n_redundant=2, n_informative=8,&lt;br /&gt;
                             n_clusters_per_class=1, n_classes=100,&lt;br /&gt;
                             n_samples=2000000)&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Для заданной конфигурации эксперимента (&amp;lt;math&amp;gt;n, d, p, k&amp;lt;/math&amp;gt;) и полученных результатов (&amp;lt;math&amp;gt;t, \Tau&amp;lt;/math&amp;gt;)  [[Глоссарий#Производительность|производительность]]  и эффективность реализации расчитывались по формулам:&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
&amp;lt;ul&amp;gt;&amp;lt;li&amp;gt;&amp;lt;math&amp;gt;Performance = \frac{N_{k-means}^{d, n}}{t}\ \ (FLOPS),&amp;lt;/math&amp;gt;&amp;lt;/li&amp;gt;&amp;lt;/ul&amp;gt;&lt;br /&gt;
где &amp;lt;math&amp;gt;N_{k-means}^{d, n}&amp;lt;/math&amp;gt; &amp;amp;ndash; точное число операций с плавающей точкой (операции с памятью, а также целочисленные операции не учитывались), вычисленное в соответствие с разделом [[#Последовательная сложность алгоритма| &amp;quot;Последовательная сложность алгоритма&amp;quot;]];&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
&amp;lt;ul&amp;gt;&amp;lt;li&amp;gt;&amp;lt;math&amp;gt;Efficiency = \frac{100 * Performance}{Performance_{Peak}^{p}}\ \ (%),&amp;lt;/math&amp;gt;&amp;lt;/li&amp;gt;&amp;lt;/ul&amp;gt;&lt;br /&gt;
где &amp;lt;math&amp;gt;Performance_{Peak}^{p}&amp;lt;/math&amp;gt; &amp;amp;ndash; пиковая производительность суперкомпьютера при &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt; процессорах, вычисленная согласно спецификациям Intel&amp;lt;sup&amp;gt;&amp;amp;reg;&amp;lt;/sup&amp;gt; XEON&amp;lt;sup&amp;gt;&amp;amp;reg;&amp;lt;/sup&amp;gt; X5670&amp;lt;ref&amp;gt;&amp;quot;http://ark.intel.com/ru/products/47920/Intel-Xeon-Processor-X5670-12M-Cache-2_93-GHz-6_40-GTs-Intel-QPI&amp;quot;&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Графики зависимости производительности и эффективности параллельной реализации k means от числа векторов для кластеризации (&amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;) и числа процессоров (&amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt;) представлены на рисунках 4 и 5 соответственно.&lt;br /&gt;
&lt;br /&gt;
[[file:Flops.png|thumb|center|800px|Рис. 4. Параллельная реализация k means. График зависимости производительности реализации алгоритма от числа векторов для кластеризации (&amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;) и числа процессоров (&amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt;).]]&lt;br /&gt;
[[file:Efficiency.png|thumb|center|800px|Рис. 5. Параллельная реализация k means. График зависимости эффективности реализации алгоритма от числа векторов для кластеризации (&amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;) и числа процессоров (&amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt;).]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;В результате&amp;lt;/b&amp;gt; экспериментальной оценки были получены следующие оценки эффективности реализации:&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;b&amp;gt;Минимальное&amp;lt;/b&amp;gt; значение: 0.000409 % достигается при &amp;lt;math&amp;gt;n=20&#039;000, p=480&amp;lt;/math&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;b&amp;gt;Максимальное&amp;lt;/b&amp;gt; значение: 0.741119 % достигается при &amp;lt;math&amp;gt;n=300&#039;000, p=1&amp;lt;/math&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
Оценки масштабируемости реализации алгоритма k means:&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;b&amp;gt;По числу процессоров:&amp;lt;/b&amp;gt; -0.002683 &amp;amp;ndash; эффективность убывает с ростом числа процессоров. Данный результат вызван ростом накладных расходов для обеспечения параллельного выполнения алгоритма.&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;b&amp;gt;По размеру задачи:&amp;lt;/b&amp;gt; 0.002779 &amp;amp;ndash; эффективность растет с ростом числа векторов. Данный результат вызван тем, что при увеличении размера задачи, количество вычислений растет по сравнению с временем, затрачиваемым на пересылку данных.&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;b&amp;gt;Общая оценка:&amp;lt;/b&amp;gt; -0.000058 &amp;amp;ndash; можно сделать вывод, что в целом эффективность реализации незначительно уменьшается с ростом размера задачи и числа процессоров.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[https://github.com/serban/kmeans Использованная параллельная реализация алгоритма k means]&lt;br /&gt;
&lt;br /&gt;
=== Динамические характеристики и эффективность реализации алгоритма ===&lt;br /&gt;
=== Выводы для классов архитектур ===&lt;br /&gt;
=== Существующие реализации алгоритма ===&lt;br /&gt;
==== Открытое программное обеспечение ====&lt;br /&gt;
&amp;lt;ol&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;[https://www.icpsr.umich.edu/CrimeStat/ CrimeStat]&amp;lt;/li&amp;gt; Программное обеспечение, созданное для операционных систем Windows, предоставляющее инструменты статистического  и пространственного анализа для решения задачи картирования преступности.&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://juliastats.github.io Julia]&amp;lt;/li&amp;gt; Высокоуровневый высокопроизводительный свободный язык программирования с динамической типизацией, созданный для математических вычислений, содержит реализацию k-means.&lt;br /&gt;
  &amp;lt;li&amp;gt;[https://mahout.apache.org Mahout]&amp;lt;/li&amp;gt; Apache Mahout - Java библиотека для работы с алгоритмами машинного обучения с использованием MapReduce. Содержит реализацию k-means.&lt;br /&gt;
  &amp;lt;li&amp;gt;[https://www.gnu.org/software/octave/ Octave]&amp;lt;/li&amp;gt; Написанная на C++  свободная система для математических вычислений, использующая совместимый с MATLAB язык высокого уровня, содержит реализацию k-means.&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://spark.apache.org/docs/latest/mllib-clustering.html Spark]&amp;lt;/li&amp;gt; Распределенная реализация k-means содержится в библиотеке Mlib для работы с алгоритмами машинного обучения, взаимодействующая с Python библиотекой NumPy и библиотека R.&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://torch.ch Torch]&amp;lt;/li&amp;gt;  MATLAB-подобная библиотека для языка программирования Lua с открытым исходным кодом, предоставляет большое количество алгоритмов для глубинного обучения и научных расчётов. Ядро написано на Си, прикладная часть выполняется на LuaJIT, поддерживается распараллеливание вычислений средствами CUDA и OpenMP. Существуют реализации k-means.&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://www.cs.waikato.ac.nz/ml/weka/ Weka]&amp;lt;/li&amp;gt;  Cвободное программное обеспечение для анализа данных, написанное на Java. Содержит k-means и x-means.&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://accord-framework.net/docs/html/T_Accord_MachineLearning_KMeans.htm Accord.NET]&amp;lt;/li&amp;gt; C# реализация алгоритмов k-means, k-means++, k-modes.&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://docs.opencv.org/3.0-beta/doc/py_tutorials/py_ml/py_kmeans/py_kmeans_opencv/py_kmeans_opencv.html OpenCV]&amp;lt;/li&amp;gt; Написанная на С++ библиотека, направленная в основном на решение задач компьютерного зрения. Содержит реализацию k-means.&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://mlpack.org/ MLPACK]&amp;lt;/li&amp;gt; Масштабируемая С++ библиотека для работы с алгоритмами машинного обучения, содержит реализацию k-means.&lt;br /&gt;
  &amp;lt;li&amp;gt;[https://www.scipy.org/ SciPy]&amp;lt;/li&amp;gt; Библиотека Python, содержит множество реализаций k-means.&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://scikit-learn.org/ scikit-learn]&amp;lt;/li&amp;gt; Библиотека Python, содержит множество реализаций k-means.&lt;br /&gt;
  &amp;lt;li&amp;gt;[https://www.r-bloggers.com/k-means-clustering-in-r/ R]&amp;lt;/li&amp;gt; Язык программирования для статистической обработки данных и работы с графикой, а также свободная программная среда вычислений с открытым исходным кодом в рамках проекта GNU, содержит три реализации k-means.&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://elki.dbs.ifi.lmu.de ELKI]&amp;lt;/li&amp;gt; Java фреймворк, содержащий реализацию k-means, а также множество других алгоритмов кластеризации.&lt;br /&gt;
&amp;lt;/ol&amp;gt;&lt;br /&gt;
==== Проприетарное программное обеспечение  ====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ol&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;[https://www.ayasdi.com/blog/bigdata/topological-data-analysis-of-oil-and-gas-petrophysical-data/ Ayasdi]&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://www.stata.com/features/cluster-analysis/ Stata]&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://mathworld.wolfram.com/K-MeansClusteringAlgorithm.html Mathematica]&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://www.mathworks.com/help/stats/kmeans.html?requestedDomain=www.mathworks.com MATLAB]&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;[https://support.sas.com/rnd/app/stat/procedures/fastclus.html SAS]&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://docs.rapidminer.com/studio/operators/modeling/segmentation/k_means.html RapidMiner]&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;[https://blogs.sap.com/2013/03/28/sap-hana-pal-k-means-algorithm-or-how-to-do-customer-segmentation-for-the-telecommunications-industry/ SAP HANA]&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ol&amp;gt;&lt;br /&gt;
== Литература ==&lt;br /&gt;
&amp;lt;references /&amp;gt;&lt;/div&gt;</summary>
		<author><name>DennZo1993</name></author>
	</entry>
	<entry>
		<id>https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:%D0%91%D1%80%D0%BE%D1%82%D0%B8%D0%BA%D0%BE%D0%B2%D1%81%D0%BA%D0%B0%D1%8F_%D0%94%D0%B0%D0%BD%D1%83%D1%82%D0%B0/%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_k-means&amp;diff=20516</id>
		<title>Участник:Бротиковская Данута/Алгоритм k-means</title>
		<link rel="alternate" type="text/html" href="https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:%D0%91%D1%80%D0%BE%D1%82%D0%B8%D0%BA%D0%BE%D0%B2%D1%81%D0%BA%D0%B0%D1%8F_%D0%94%D0%B0%D0%BD%D1%83%D1%82%D0%B0/%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_k-means&amp;diff=20516"/>
		<updated>2016-12-10T10:29:01Z</updated>

		<summary type="html">&lt;p&gt;DennZo1993: /* Последовательная сложность алгоритма */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Assignment|Zhum}}&lt;br /&gt;
&lt;br /&gt;
{{algorithm&lt;br /&gt;
| name              = Алгоритм k средних (k means)&lt;br /&gt;
| serial_complexity = &amp;lt;math&amp;gt;O(\Tau*k*d*n)&amp;lt;/math&amp;gt;&lt;br /&gt;
| input_data        = &amp;lt;math&amp;gt; d*n &amp;lt;/math&amp;gt;&lt;br /&gt;
| output_data       = &amp;lt;math&amp;gt; n &amp;lt;/math&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
Авторы страницы &amp;lt;b&amp;gt;[[Участник:Бротиковская Данута|Данута Бротиковская]]&amp;lt;/b&amp;gt; и &amp;lt;b&amp;gt;[[Участник:DennZo1993|Денис Зобнин]]&amp;lt;/b&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
Оба автора внесли одинаковый вклад в написание статьи (поиск материалов, изучение статей, заполнение контента статьи), четких разграничений по пунктам статьи сделать невозможно. &lt;br /&gt;
&lt;br /&gt;
== Свойства и структура алгоритма ==&lt;br /&gt;
&lt;br /&gt;
=== Общее описание алгоритма ===&lt;br /&gt;
Алгоритм &amp;lt;b&amp;gt;&amp;lt;i&amp;gt;k средних&amp;lt;/i&amp;gt;&amp;lt;/b&amp;gt; (&amp;lt;b&amp;gt;&amp;lt;i&amp;gt;k means&amp;lt;/i&amp;gt;&amp;lt;/b&amp;gt;) &amp;amp;ndash; неиерархический&amp;lt;ref&amp;gt;&amp;quot;https://ru.wikipedia.org/wiki/Иерархическая_кластеризация&amp;quot;&amp;lt;/ref&amp;gt;, итерационный метод кластеризации&amp;lt;ref&amp;gt;&amp;quot;https://ru.wikipedia.org/wiki/Кластерный_анализ&amp;quot;&amp;lt;/ref&amp;gt;, получивший большую популярность благодаря своей простоте, наглядности реализации и достаточно высокому качеству работы. Был изобретен в 1950-х годах математиком &amp;lt;i&amp;gt;Гуго Штейнгаузом&amp;lt;/i&amp;gt;&amp;lt;ref&amp;gt;Steinhaus, Hugo. &amp;quot;Sur la division des corp materiels en parties.&amp;quot; Bull. Acad. Polon. Sci 1.804 (1956): 801.&amp;lt;/ref&amp;gt; и почти одновременно &amp;lt;i&amp;gt;Стюартом Ллойдом&amp;lt;/i&amp;gt;&amp;lt;ref&amp;gt;Lloyd, S. P. &amp;quot;Least square quantization in PCM. Bell Telephone Laboratories Paper. Published in journal much later: Lloyd, SP: Least squares quantization in PCM.&amp;quot; IEEE Trans. Inform. Theor.(1957/1982).&amp;lt;/ref&amp;gt;. Особую популярность приобрел после публикации работы &amp;lt;i&amp;gt;МакКуина&amp;lt;/i&amp;gt;&amp;lt;ref&amp;gt;MacQueen, James. &amp;quot;Some methods for classification and analysis of multivariate observations.&amp;quot; Proceedings of the fifth Berkeley symposium on mathematical statistics and probability. Vol. 1. No. 14. 1967.&amp;lt;/ref&amp;gt; в 1967.&lt;br /&gt;
&lt;br /&gt;
Алгоритм представляет собой версию EM-алгоритма&amp;lt;ref&amp;gt;&amp;quot;https://ru.wikipedia.org/wiki/EM-алгоритм&amp;quot;&amp;lt;/ref&amp;gt;, применяемого также для разделения смеси гауссиан. Основная идея &amp;lt;i&amp;gt;k means&amp;lt;/i&amp;gt; заключается в том, что данные произвольно разбиваются на кластеры, после чего итеративно перевычисляется центр масс для каждого кластера, полученного на предыдущем шаге, затем векторы разбиваются на кластеры вновь в соответствии с тем, какой из новых центров оказался ближе по выбранной метрике.&lt;br /&gt;
&lt;br /&gt;
Цель алгоритма заключается в разделении &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; наблюдений на &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластеров таким образом, чтобы каждое наблюдение принадлежало ровно одному кластеру, расположенному на наименьшем расстоянии от наблюдения.&lt;br /&gt;
&lt;br /&gt;
=== Математическое описание алгоритма ===&lt;br /&gt;
&amp;lt;b&amp;gt;&amp;lt;u&amp;gt;Дано:&amp;lt;/u&amp;gt;&amp;lt;/b&amp;gt;&lt;br /&gt;
* набор из &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; наблюдений &amp;lt;math&amp;gt;X=\{\mathbf{x}_1, \mathbf{x}_2, ..., \mathbf{x}_n\}, \mathbf{x}_i \in \mathbb{R}^d, i=\overline{1, n}&amp;lt;/math&amp;gt;;&lt;br /&gt;
* &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; - требуемое число кластеров, &amp;lt;math&amp;gt;k \in \mathbb{N}, k \leq n&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;&amp;lt;u&amp;gt;Требуется:&amp;lt;/u&amp;gt;&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Разделить множество наблюдений &amp;lt;math&amp;gt;X&amp;lt;/math&amp;gt; на &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластеров &amp;lt;math&amp;gt;S_1, S_2, ..., S_k&amp;lt;/math&amp;gt;:&lt;br /&gt;
*   &amp;lt;math&amp;gt;S_i \cap S_j= \varnothing, \quad i \ne j&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
*   &amp;lt;math&amp;gt;\bigcup_{i=1}^{k} S_i = X&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;&amp;lt;u&amp;gt;Действие алгоритма:&amp;lt;/u&amp;gt;&amp;lt;/b&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;Алгоритм &amp;lt;i&amp;gt;k means&amp;lt;/i&amp;gt; разбивает набор &amp;lt;math&amp;gt;X&amp;lt;/math&amp;gt; на &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; наборов &amp;lt;math&amp;gt;S_1, S_2, ..., S_k,&amp;lt;/math&amp;gt; таким образом, чтобы минимизировать сумму квадратов расстояний от каждой точки кластера до его центра (центр масс кластера). Введем обозначение, &amp;lt;math&amp;gt;S=\{S_1, S_2, ..., S_k\}&amp;lt;/math&amp;gt;. Тогда действие алгоритма &amp;lt;i&amp;gt;k means&amp;lt;/i&amp;gt; равносильно поиску:&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;table style=&amp;quot;width:100%&amp;quot;&amp;gt;&lt;br /&gt;
  &amp;lt;tr&amp;gt;&lt;br /&gt;
    &amp;lt;td align=&amp;quot;center&amp;quot; width=&amp;quot;90%&amp;quot;&amp;gt;&amp;lt;math&amp;gt;\arg\min_{S} \sum\limits_{i=1}^k \sum\limits_{\mathbf{x} \in S_i} \rho(\mathbf{x}, \mathbf{\mu}_i )^2,&amp;lt;/math&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;td align=&amp;quot;right&amp;quot;&amp;gt;&amp;lt;math&amp;gt;(1)&amp;lt;/math&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;/table&amp;gt;&lt;br /&gt;
где &amp;lt;math&amp;gt;\mathbf{\mu}_i&amp;lt;/math&amp;gt; &amp;amp;ndash; центры кластеров, &amp;lt;math&amp;gt;i=\overline{1,k}, \quad \rho(\mathbf{x}, \mathbf{\mu}_i)&amp;lt;/math&amp;gt; &amp;amp;ndash; функция расстояния между &amp;lt;math&amp;gt;\mathbf{x}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\mu_i&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;&amp;lt;u&amp;gt;Шаги алгоритма: &amp;lt;/u&amp;gt;&amp;lt;/b&amp;gt;&lt;br /&gt;
&amp;lt;ol&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&lt;br /&gt;
    &amp;lt;b&amp;gt;Начальный шаг: инициализация кластеров&amp;lt;/b&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;Выбирается произвольное множество точек &amp;lt;math&amp;gt;\mu_i, i=\overline{1,k}&amp;lt;/math&amp;gt;, рассматриваемых как начальные центры кластеров: &amp;lt;math&amp;gt;\mu_i^{(0)} = \mu_i, \quad i=\overline{1, k}&amp;lt;/math&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
  &amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&lt;br /&gt;
    &amp;lt;b&amp;gt;Распределение векторов по кластерам&amp;lt;/b&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Шаг&amp;lt;/b&amp;gt; &amp;lt;math&amp;gt;t: \forall \mathbf{x}_i \in X, i=\overline{1,n}: \mathbf{x}_i \in S_j \iff  j=\arg\min_{k}\rho(\mathbf{x}_i,\mathbf{\mu}_k^{(t-1)})^2&amp;lt;/math&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
  &amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&lt;br /&gt;
    &amp;lt;b&amp;gt;Пересчет центров кластеров&amp;lt;/b&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Шаг &amp;lt;/b&amp;gt; &amp;lt;math&amp;gt;t: \forall i=\overline{1,k}:  \mu_i^{(t)} = \cfrac{1}{|S_i|}\sum_{\mathbf{x}\in S_i}\mathbf{x}&amp;lt;/math&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
  &amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&lt;br /&gt;
    &amp;lt;b&amp;gt;Проверка условия останова:&amp;lt;/b&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
    &#039;&#039;&#039;if&#039;&#039;&#039; &amp;lt;math&amp;gt;\exist i\in \overline{1,k}: \mu_i^{(t)} \ne \mu_i^{(t-1)}&amp;lt;/math&amp;gt; &#039;&#039;&#039;then&#039;&#039;&#039;&lt;br /&gt;
        t = t + 1;&lt;br /&gt;
        goto 2;&lt;br /&gt;
    &#039;&#039;&#039;else&#039;&#039;&#039;&lt;br /&gt;
        &#039;&#039;&#039;stop&#039;&#039;&#039;&lt;br /&gt;
  &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ol&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Вычислительное ядро алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Вычислительным ядром являются шаги 2 и 3 приведенного выше алгоритма: &amp;lt;b&amp;gt;&amp;lt;i&amp;gt;распределение векторов по кластерам&amp;lt;/i&amp;gt;&amp;lt;/b&amp;gt; и &amp;lt;b&amp;gt;&amp;lt;i&amp;gt;пересчет центров кластеров&amp;lt;/i&amp;gt;&amp;lt;/b&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;&amp;lt;i&amp;gt;Распределение векторов&amp;lt;/i&amp;gt;&amp;lt;/b&amp;gt; по кластерам предполагает вычисление расстояний между каждым вектором &amp;lt;math&amp;gt;\mathbf{x}_i \in X, i= \overline{1,n}&amp;lt;/math&amp;gt; и центрами кластера &amp;lt;math&amp;gt;\mathbf{\mu}_j, j= \overline{1,k}&amp;lt;/math&amp;gt;. Таким образом, данный шаг предполагает &amp;lt;math&amp;gt;kn&amp;lt;/math&amp;gt; вычислений расстояний между d-мерными векторами. &lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;&amp;lt;i&amp;gt;Пересчет центров кластеров&amp;lt;/i&amp;gt;&amp;lt;/b&amp;gt; предполагает &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; вычислений центров масс &amp;lt;math&amp;gt;\mathbf{\mu}_i&amp;lt;/math&amp;gt; множеств &amp;lt;math&amp;gt;S_i, i=\overline{1,k}&amp;lt;/math&amp;gt; представленных выражением в шаге 3 представленного выше алгоритма.&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Макроструктура алгоритма ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Инициализация центров масс &amp;lt;math&amp;gt;\mu_1, ..., \mu_k&amp;lt;/math&amp;gt;&amp;lt;/b&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
Наиболее распространенными являются следующие стратегии:&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&lt;br /&gt;
    &amp;lt;b&amp;gt;Метод Forgy&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;В качестве начальных значений &amp;lt;math&amp;gt;\mu_1, ..., \mu_k&amp;lt;/math&amp;gt; берутся случайно выбранные векторы.&lt;br /&gt;
  &amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&lt;br /&gt;
    &amp;lt;b&amp;gt;Метод случайно разделения (Random Partitioning)&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;Для каждого вектора &amp;lt;math&amp;gt;\mathbf{x}_i \in X, i=\overline{1, n}&amp;lt;/math&amp;gt; выбирается случайным образом кластер &amp;lt;math&amp;gt;S_1, ..., S_k&amp;lt;/math&amp;gt;, после чего для каждого полученного кластера вычисляются значения &amp;lt;math&amp;gt;\mu_1, ..., \mu_k&amp;lt;/math&amp;gt;.&lt;br /&gt;
  &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Распределение векторов по кластерам&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Для этого шага алгоритма между векторами &amp;lt;math&amp;gt;\mathbf{x}_i \in X, i=\overline{1, n}&amp;lt;/math&amp;gt; и центрами кластеров &amp;lt;math&amp;gt;\mu_1, ..., \mu_k&amp;lt;/math&amp;gt; вычисляются &amp;lt;b&amp;gt;расстояния&amp;lt;/b&amp;gt; по формуле (как правило, используется Евлидово расстояние):&lt;br /&gt;
&amp;lt;table style=&amp;quot;width:100%&amp;quot;&amp;gt;&lt;br /&gt;
  &amp;lt;tr&amp;gt;&lt;br /&gt;
    &amp;lt;td align=&amp;quot;center&amp;quot; width=&amp;quot;90%&amp;quot;&amp;gt;&amp;lt;math&amp;gt; \mathbf{v}_1, \mathbf{v}_2 \in \mathbb{R}^d,  \quad \rho(\mathbf{v}_1, \mathbf{v}_2) = \lVert \mathbf{v}_1- \mathbf{v}_2 \rVert= \sqrt{\sum_{i=1}^{d}(\mathbf{v}_{1,i} - \mathbf{v}_{2,i})^2}&amp;lt;/math&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;td align=&amp;quot;right&amp;quot;&amp;gt;&amp;lt;math&amp;gt;(2)&amp;lt;/math&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;/table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Пересчет центров кластеров&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Для этого шага алгоритма производится пересчет центров кластера по &amp;lt;b&amp;gt;формуле вычисления центра масс&amp;lt;/b&amp;gt;:&lt;br /&gt;
&amp;lt;table style=&amp;quot;width:100%&amp;quot;&amp;gt;&lt;br /&gt;
  &amp;lt;tr&amp;gt;&lt;br /&gt;
    &amp;lt;td align=&amp;quot;center&amp;quot; width=&amp;quot;90%&amp;quot;&amp;gt;&amp;lt;math&amp;gt; \mu = \cfrac{1}{|S|}\sum_{\mathbf{x}\in S}\mathbf{x}&amp;lt;/math&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;td align=&amp;quot;right&amp;quot;&amp;gt;&amp;lt;math&amp;gt;(3)&amp;lt;/math&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;/table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Схема реализации последовательного алгоритма ===&lt;br /&gt;
&lt;br /&gt;
 &#039;&#039;&#039;algorithm&#039;&#039;&#039; k-means &#039;&#039;&#039;is&#039;&#039;&#039;&lt;br /&gt;
     &#039;&#039;&#039;1.&#039;&#039;&#039; Инициализировать центры кластеров &amp;lt;math&amp;gt;\mathbf{\mu}_i^{(1)}, i=\overline{1,k}&amp;lt;/math&amp;gt;&lt;br /&gt;
     &#039;&#039;&#039;2.&#039;&#039;&#039; &amp;lt;math&amp;gt;t \leftarrow 1&amp;lt;/math&amp;gt;&lt;br /&gt;
     &#039;&#039;&#039;3.&#039;&#039;&#039; &#039;&#039;&#039;Распределение по кластерам&#039;&#039;&#039;&amp;lt;br&amp;gt;&lt;br /&gt;
        &amp;lt;math&amp;gt;S_i^{(t)}=\{\mathbf{x}_p: \lVert\mathbf{x}_p-\mathbf{\mu}_i^{(t)}\rVert^2 \leq \lVert\mathbf{x}_p-\mathbf{\mu}_j^{(t)}\rVert^2 \quad \forall j=\overline{1,k}\},&amp;lt;/math&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
        где каждый вектор &amp;lt;math&amp;gt;\mathbf{x}_p&amp;lt;/math&amp;gt; соотносится единственному кластеру &amp;lt;math&amp;gt;S^{(t)}&amp;lt;/math&amp;gt;&lt;br /&gt;
     &#039;&#039;&#039;4.&#039;&#039;&#039; &#039;&#039;&#039;Обновление центров кластеров&#039;&#039;&#039;&amp;lt;br&amp;gt;&lt;br /&gt;
        &amp;lt;math&amp;gt;\mathbf{\mu}_i^{(t+1)} = \frac{1}{|S^{(t)}_i|} \sum_{\mathbf{x}_j \in S^{(t)}_i} \mathbf{x}_j &amp;lt;/math&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
     &#039;&#039;&#039;5.&#039;&#039;&#039; &#039;&#039;&#039;if&#039;&#039;&#039; &amp;lt;math&amp;gt;\exist i \in \overline{1,k}: \mathbf{\mu}_i^{(t+1)} \ne \mathbf{\mu}_i^{(t)}&amp;lt;/math&amp;gt; &#039;&#039;&#039;then&#039;&#039;&#039;&lt;br /&gt;
            t = t + 1;&lt;br /&gt;
            goto &#039;&#039;&#039;3&#039;&#039;&#039;;&lt;br /&gt;
        &#039;&#039;&#039;else&#039;&#039;&#039;&lt;br /&gt;
            &#039;&#039;&#039;stop&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
=== Последовательная сложность алгоритма===&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding-bottom: 20px&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;Обозначим &amp;lt;math&amp;gt;\Theta_{centroid}^{d, m}&amp;lt;/math&amp;gt; временную сложность вычисления центорида кластера, число элементов которого равна &amp;lt;math&amp;gt;m&amp;lt;/math&amp;gt;,  в d-мерном пространстве.&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;Аналогично  &amp;lt;math&amp;gt;\Theta_{distance}^d&amp;lt;/math&amp;gt; &amp;amp;ndash; временная сложность вычисления расстояния между двумя d-мерными векторами.&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding-bottom: 20px&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;Сложность шага инициализации &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластеров мощности &amp;lt;math&amp;gt;m&amp;lt;/math&amp;gt; в d-мерном пространстве &amp;amp;ndash; &amp;lt;math&amp;gt;\Theta_{init}^{k, d, m}&amp;lt;/math&amp;gt;&amp;lt;/b&amp;gt;&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;i&amp;gt;Стратерия Forgy&amp;lt;/i&amp;gt;: вычисления не требуются, &amp;lt;math&amp;gt;\Theta_{init}^{k, d, m} = 0&amp;lt;/math&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;i&amp;gt;Стратегия случайного разбиения&amp;lt;/i&amp;gt;: вычисление центров &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластеров,  &amp;lt;math&amp;gt;\Theta_{init}^{k, d, m} = k\Theta_{centroid}^{d, m}, m \le n&amp;lt;/math&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding-bottom: 20px&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Cложность шага распределения d мерных векторов по &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластерам &amp;amp;ndash; &amp;lt;math&amp;gt;\Theta_{distribute}^{k, d}&amp;lt;/math&amp;gt;&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
На этом шаге для каждого вектора &amp;lt;math&amp;gt;\mathbf{x}_i \in X, i=\overline{1, n}&amp;lt;/math&amp;gt; вычисляется k расстояний до центров кластеров &amp;lt;math&amp;gt;\mathbf{\mu}_1, ...\mathbf{\mu}_k&amp;lt;/math&amp;gt;&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p align=&amp;quot;center&amp;quot;&amp;gt;&lt;br /&gt;
  &amp;lt;math&amp;gt;\Theta_{distribute}^{k, d} = nk\Theta_{distance}^d&amp;lt;/math&amp;gt;&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding-bottom: 20px&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;Сложность шага пересчета центров &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластеров размера &amp;lt;math&amp;gt;m&amp;lt;/math&amp;gt; в d-мерном пространстве &amp;amp;ndash; &amp;lt;math&amp;gt;\Theta_{recenter}^{k, d, m}&amp;lt;/math&amp;gt;&amp;lt;/b&amp;gt;&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;На этом шаге вычисляется &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; центров кластеров &amp;lt;math&amp;gt;\mathbf{\mu}_1, ...\mathbf{\mu}_k&amp;lt;/math&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p align=&amp;quot;center&amp;quot;&amp;gt;&amp;lt;math&amp;gt;\Theta_{recenter}^{k, d, m} = k*\Theta_{centroid}^{d, m}&amp;lt;/math&amp;gt; &amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding-bottom: 20px&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Рассчитаем &amp;lt;math&amp;gt;\Theta_{centroid}^{d, m}&amp;lt;/math&amp;gt; для кластера, число элементов которого равно &amp;lt;math&amp;gt;m&amp;lt;/math&amp;gt;&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p align=&amp;quot;center&amp;quot;&amp;gt;&amp;lt;math&amp;gt;\Theta_{centroid}^{d, m}&amp;lt;/math&amp;gt; = &amp;lt;math&amp;gt;md&amp;lt;/math&amp;gt; сложений + &amp;lt;math&amp;gt;d&amp;lt;/math&amp;gt; делений &amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding-bottom: 20px&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Рассчитаем &amp;lt;math&amp;gt;\Theta_{distance}^d&amp;lt;/math&amp;gt; в соответствие с формулой &amp;lt;math&amp;gt;(2)&amp;lt;/math&amp;gt;&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p align=&amp;quot;center&amp;quot;&amp;gt;&amp;lt;math&amp;gt;\Theta_{distance}^d&amp;lt;/math&amp;gt; = &amp;lt;math&amp;gt;d&amp;lt;/math&amp;gt; вычитаний + &amp;lt;math&amp;gt;d&amp;lt;/math&amp;gt; умножений + &amp;lt;math&amp;gt;(d-1)&amp;lt;/math&amp;gt; сложение&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding-bottom: 20px&amp;quot;&amp;gt;&lt;br /&gt;
  &amp;lt;p&amp;gt;Предположим, что алгоритм сошелся за &amp;lt;math&amp;gt;\Tau&amp;lt;/math&amp;gt; итераций, тогда временная сложность алгоритма &amp;lt;math&amp;gt;\Theta_{k-means}^{d, n}&amp;lt;/math&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
  &amp;lt;p align=&amp;quot;center&amp;quot;&amp;gt;&amp;lt;b&amp;gt;&amp;lt;math&amp;gt;\Theta_{k-means}^{d, n} \le \Theta_{init}^{k, d, n} + \Tau(\Theta_{distribute}^{k, d} + \Theta_{recenter}^{k, d, n})&amp;lt;/math&amp;gt;&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding-bottom: 5px&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;Операции сложения/вычитания:&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p align=&amp;quot;center&amp;quot;&amp;gt;&amp;lt;b&amp;gt;&amp;lt;math&amp;gt;\Theta_{k-means}^{d, n} \le knd+ \Tau*(kn(2d-1) + knd) = knd+ \Tau*(kn(3d-1)) \thicksim O(\Tau kdn)&amp;lt;/math&amp;gt;&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding-bottom: 20px&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;Операции умножения/деления:&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p align=&amp;quot;center&amp;quot;&amp;gt;&amp;lt;b&amp;gt;&amp;lt;math&amp;gt;\Theta_{k-means}^{d, n} \le k*d + \Tau*(k*n*d + k*d) = k*d + \Tau * k*d*(n+1) \thicksim O(\Tau*k*d*n) &amp;lt;/math&amp;gt;&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding-bottom: 20px&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;Получаем, что &amp;lt;b&amp;gt;временная сложность&amp;lt;/b&amp;gt; алгоритма &amp;lt;b&amp;gt;k means&amp;lt;/b&amp;gt; кластеризации &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; &amp;lt;b&amp;gt;d-мерных&amp;lt;/b&amp;gt; векторов на &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластеров за &amp;lt;math&amp;gt;\Tau&amp;lt;/math&amp;gt; итераций:&amp;lt;/p&amp;gt;&lt;br /&gt;
 &amp;lt;p align=&amp;quot;center&amp;quot;&amp;gt;&amp;lt;b&amp;gt;&amp;lt;math&amp;gt; \Theta_{k-means}^{d, n} \thicksim O(\Tau*k*d*n) &amp;lt;/math&amp;gt;&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Информационный граф ===&lt;br /&gt;
&lt;br /&gt;
Рассмотрим информационный граф алгоритма. Алгоритм &amp;lt;i&amp;gt;k means&amp;lt;/i&amp;gt; начинается с этапа инициализации, после которого следуют итерации, на каждой из которых выполняется два последовательных шага (см. [[#Схема реализации последовательного алгоритма|&amp;quot;Схема реализации последовательного алгоритма&amp;quot;]]): &lt;br /&gt;
* распределение векторов по кластерам&lt;br /&gt;
* перерасчет центров кластеров&lt;br /&gt;
&lt;br /&gt;
Поскольку основная часть вычислений приходится на шаги итераций, распишем информационные графы данных шагов.&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Распределение векторов по кластерам&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
Информационный граф шага распределения векторов по кластерам представлен на &#039;&#039;рисунке 1&#039;&#039;. Исходами данного графа является исходные векторы &amp;lt;math&amp;gt;\mathbf{x}_1, ..., \mathbf{x}_n&amp;lt;/math&amp;gt;, а также центры кластеров &amp;lt;math&amp;gt;\mathbf{\mu}_1, ... \mathbf{\mu}_k&amp;lt;/math&amp;gt;, вычисленные ранее (на шаге инициализации, если рассматривается первая итерация алгоритма, или на шаге пересчета центров кластеров предыдущей итерации в противном случае). Каждая пара векторов данных &amp;lt;math&amp;gt;\mathbf{x}_i, i=\overline{1,n}&amp;lt;/math&amp;gt; и центров кластера &amp;lt;math&amp;gt;\mathbf{\mu}_j, j=\overline{1, k}&amp;lt;/math&amp;gt; : (&amp;lt;math&amp;gt;\mathbf{x}_i&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;\mathbf{\mu}_j&amp;lt;/math&amp;gt;) подаются на независимые узлы &amp;lt;i&amp;gt;&amp;quot;d&amp;quot;&amp;lt;/i&amp;gt; вычисления расстояния между векторами (более подробная схема вычисления расстояния представлена далее, &#039;&#039;рисунок 2&#039;&#039;). Далее узлы вычисления расстояния &amp;lt;i&amp;gt;&amp;quot;d&amp;quot;&amp;lt;/i&amp;gt;, соответствующие одному и тому же исходному вектору &amp;lt;math&amp;gt;\mathbf{x}_i&amp;lt;/math&amp;gt; передаются на один узел &amp;lt;i&amp;gt;&amp;quot;m&amp;quot;&amp;lt;/i&amp;gt;, где далее происходит вычисление новой метки кластера для каждого вектора &amp;lt;math&amp;gt;\mathbf{x}_i&amp;lt;/math&amp;gt; (берется кластер с минимальным результатом вычисления расстояния). На выходе графа выдаются метки кластеров , &amp;lt;math&amp;gt;L_1, ..., L_n&amp;lt;/math&amp;gt;, такие что &amp;lt;math&amp;gt;\forall \mathbf{x}_i, i=\overline{1, n}, \mathbf{x}_i \in S_j \Leftrightarrow L_i = j&amp;lt;/math&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
[[file:Clusterization.png|thumb|center|800px|Рис. 1. Схема распределения векторов по кластерам. &#039;&#039;d&#039;&#039; &amp;amp;ndash; вычисление расстояния между векторами; &#039;&#039;m&#039;&#039; &amp;amp;ndash; вычисление минимума.]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Вычисление расстояния между векторами&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
Подробная схема вычисления расстояния между векторами &amp;lt;math&amp;gt;\mathbf{x}_i, \mathbf{\mu}_j&amp;lt;/math&amp;gt; представлена на &#039;&#039;рисунке 2&#039;&#039;. Как показано на графе, узел вычисления расстояния между векторами &amp;lt;i&amp;gt;&amp;quot;d&amp;quot;&amp;lt;/i&amp;gt; состоит из шага взятия разности между векторами (узел &amp;quot;&amp;lt;math&amp;gt;-&amp;lt;/math&amp;gt;&amp;quot;) и взятия нормы получившегося вектора разности (узел &amp;quot;&amp;lt;math&amp;gt;||\cdot||^2&amp;lt;/math&amp;gt;&amp;quot;). Более подробно, вычисление расстояния между векторами &amp;lt;math&amp;gt;\mathbf{x}_i = {x_{i1,}, ...,{x_{in}}}, \mathbf{\mu}_j = {\mu_{j1}, ...,\mu_{jn}}&amp;lt;/math&amp;gt; может быть представлено как вычисление разности между каждой парой компонент &amp;lt;math&amp;gt;(x_{iz}, \mu_{jz}), z=\overline{1, d}&amp;lt;/math&amp;gt; (узел &amp;quot;&amp;lt;math&amp;gt;-&amp;lt;/math&amp;gt;&amp;quot;), далее возведение в квадрат для каждого узла &amp;quot;&amp;lt;math&amp;gt;-&amp;lt;/math&amp;gt;&amp;quot; (узел &amp;quot;&amp;lt;math&amp;gt;()^2&amp;lt;/math&amp;gt;&amp;quot;) и суммирования выходов всех узлов &amp;quot;&amp;lt;math&amp;gt;()^2&amp;lt;/math&amp;gt;&amp;quot; (узел &amp;quot;&amp;lt;math&amp;gt;+&amp;lt;/math&amp;gt;&amp;quot;).  &lt;br /&gt;
&lt;br /&gt;
[[file:dist_calc.png|thumb|center|800px|Рис. 2. Схема вычисления расстояния между вектором и центром кластера.]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Пересчет центров кластеров&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
Информационный граф шага пересчета центров кластеров представлен на &#039;&#039;рисунке 3&#039;&#039;. Исходами данного графа является исходные векторы &amp;lt;math&amp;gt;\mathbf{x}_1, ..., \mathbf{x}_n&amp;lt;/math&amp;gt;, а также им соответствующие метки кластера, &amp;lt;math&amp;gt;L_1, ..., L_n&amp;lt;/math&amp;gt;, такие что &amp;lt;math&amp;gt;\forall x_i, i=\overline{1, n}, \mathbf{x}_i \in S_j \Leftrightarrow L_i = j&amp;lt;/math&amp;gt;, вычисленные на этапе распределения векторов по кластерам. Все векторы &amp;lt;math&amp;gt;\mathbf{x}_1, ..., \mathbf{x}_n&amp;lt;/math&amp;gt; подаются в узлы &amp;lt;math&amp;gt;+_1, ...+_k&amp;lt;/math&amp;gt;, каждый узел &amp;lt;math&amp;gt;+_m, m = \overline{1,k}&amp;lt;/math&amp;gt; соответствует операции сложения векторов кластера с номером &amp;lt;math&amp;gt;m&amp;lt;/math&amp;gt;. Метки кластера &amp;lt;math&amp;gt;L_1, ..., L_n&amp;lt;/math&amp;gt; также совместно передаются на узлы &amp;lt;math&amp;gt;S_m, m = \overline{1,k}&amp;lt;/math&amp;gt;, на каждом из которых вычисляется количество векторов в соответствующем кластере (количество меток с соответствующим значением). Далее каждая пара выходов узлов &amp;lt;math&amp;gt;+_m&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;S_m&amp;lt;/math&amp;gt; подается на узел &amp;quot;&amp;lt;math&amp;gt;/&amp;lt;/math&amp;gt;&amp;quot;, где производится деление суммы векторов кластера на количество элементов в нем. Значения, вычисленные на узлах &amp;quot;&amp;lt;math&amp;gt;/&amp;lt;/math&amp;gt;&amp;quot;, присваиваются новым центрам кластеров (выходные значения графа).&lt;br /&gt;
&lt;br /&gt;
[[file:Recluster.png|thumb|center|800px|Рис. 3. Схема пересчета центров кластеров]]&lt;br /&gt;
&lt;br /&gt;
=== Ресурс параллелизма алгоритма ===&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
Работа алгоритма состоит из &amp;lt;math&amp;gt;\Tau&amp;lt;/math&amp;gt; итераций, в каждой из которых происходит &amp;lt;b&amp;gt;распределение d-мерных векторов по &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластерам&amp;lt;/b&amp;gt;, а также &amp;lt;b&amp;gt;пересчет центров кластеров в d-мерном пространстве&amp;lt;/b&amp;gt;. В шаге &amp;lt;b&amp;gt;распределения d-мерных векторов по &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластерам&amp;lt;/b&amp;gt; расстояния между вектором и центрами кластеров вычисляются независимо (отсутствуют информационные зависимости). &amp;lt;b&amp;gt;Центры масс кластеров&amp;lt;/b&amp;gt; также пересчитываются независимо друг от друга. Таким образом, имеет место [[глоссарий#Массовый параллелизм|&#039;&#039;массовый параллелизм&#039;&#039;]]. Вычислим параллельную сложность &amp;lt;math&amp;gt;\Psi_*&amp;lt;/math&amp;gt; каждого из шагов, а также параллельную сложность всего алгоритма, &amp;lt;math&amp;gt;\Psi_{k-means}&amp;lt;/math&amp;gt;. Будем исходить из предположения, что может быть использовано любое необходимое число потоков.&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Распределение d-мерных векторов по &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластерам&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;  &lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
Поскольку на данном шаге для каждой пары векторов &amp;lt;math&amp;gt;\mathbf{x}_i, i=\overline{1,n}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\mathbf{\mu}_j, j=\overline{1,k}&amp;lt;/math&amp;gt; операции вычисления расстояния не зависят друг от друга, они могут выполняться параллельно. Тогда, разделив все вычисление расстояний на &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; потоков, получим, что в каждом потоке будет выполняться только одна операция вычисления расстояния между векторами размерности d. При этом каждому вычислительному потоку передаются координаты центров всех кластеров &amp;lt;math&amp;gt;\mathbf{\mu}_1, ..., \mathbf{\mu}_k&amp;lt;/math&amp;gt;. Таким образом, параллельная сложность данного шага определяется &amp;lt;i&amp;gt; сложностью параллельной операции вычисления расстояния между d-мерными векторами&amp;lt;/i&amp;gt;, &amp;lt;math&amp;gt;\Psi_{distance}^d&amp;lt;/math&amp;gt;  и &amp;lt;i&amp;gt;сложностью определения наиболее близкого кластера&amp;lt;/i&amp;gt; (паралельное взятие минимума по расстояниям), &amp;lt;math&amp;gt;\Psi_{min}^k&amp;lt;/math&amp;gt;. Для оценки &amp;lt;math&amp;gt;\Psi_{distance}^d&amp;lt;/math&amp;gt; воспользуемся  [[Нахождение_частных_сумм_элементов_массива_сдваиванием | параллельной реализацией нахождения частичной суммы элементов массива путем сдваивания]]. Аналогично, &amp;lt;math&amp;gt;\Psi_{min}^k = log(k)&amp;lt;/math&amp;gt;. В результате, &amp;lt;math&amp;gt;\Psi_{distance}^d = O(log(d))&amp;lt;/math&amp;gt;.   Таким образом: &lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p align=&amp;quot;center&amp;quot;&amp;gt;&amp;lt;math&amp;gt;\Psi_{distribute}^{k, d}  = \Psi_{distance}^d + \Psi_{min}^k = O(log(d))+O(log(k)) = O(log(k*d))&amp;lt;/math&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Пересчет центров кластеров в d-мерном пространстве&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
Поскольку на данном шаге для каждого из &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластеров центр масс может быть вычислен независимо, данные операции могут быть выполнены в отдельных потоках. Таким образом, параллельная сложность данного шага, &amp;lt;math&amp;gt;\Psi_{recenter}^{k, d}&amp;lt;/math&amp;gt;,  будет определяться &amp;lt;i&amp;gt;параллельной сложностью вычисления одного центра масс кластера размера &amp;lt;math&amp;gt;m&amp;lt;/math&amp;gt;&amp;lt;/i&amp;gt;, &amp;lt;math&amp;gt;\Psi_{recenter}^{k, d}&amp;lt;/math&amp;gt;,  а так как &amp;lt;math&amp;gt;m \le n \Rightarrow \Psi_{recenter}^{d, m} \le \Psi_{recenter}^{d, n}&amp;lt;/math&amp;gt;. Сложность вычисления центра масс кластера d-мерных векторов размера n аналогично предыдущим вычислениям равна &amp;lt;math&amp;gt;O(log(n))&amp;lt;/math&amp;gt;. Тогда:  &lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p align=&amp;quot;center&amp;quot;&amp;gt;&amp;lt;math&amp;gt;\Psi_{recenter}^{k, d}  \le \Psi_{recenter}^{d, n} = O(log(n))&amp;lt;/math&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Общая параллельная сложность алгоритма&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
На каждой итерации необходимо обновление центров кластеров, которые будут использованы на следующей итерации. Таким образом, итерационный процесс выполняется последовательно&amp;lt;ref&amp;gt;Zhao, Weizhong, Huifang Ma, and Qing He. &amp;quot;Parallel k-means clustering based on mapreduce.&amp;quot; IEEE International Conference on Cloud Computing. Springer Berlin Heidelberg, 2009.&amp;lt;/ref&amp;gt;. Тогда, поскольку сложность каждой итерации  определяется &amp;lt;math&amp;gt;\Psi_{distribute}^{k, d}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\Psi_{recenter}&amp;lt;/math&amp;gt;, сложность всего алгоритма, &amp;lt;math&amp;gt;\Psi_{k-means}&amp;lt;/math&amp;gt; в предположении, что было сделано &amp;lt;math&amp;gt;\Tau&amp;lt;/math&amp;gt; операций определяется выражением&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p align=&amp;quot;center&amp;quot;&amp;gt;&amp;lt;math&amp;gt;\Psi_{k-means} \approx \Tau * (\Psi_{distribute}^{k, d} + \Psi_{recenter}^{k, d}) \le \Tau * O(log(k*d*n))&amp;lt;/math&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Входные и выходные данные алгоритма ===&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;Входные данные&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;Матрица из &amp;lt;math&amp;gt;n*d&amp;lt;/math&amp;gt; элементов &amp;lt;math&amp;gt;x_{i, j} \in \mathbb{R}, i=\overline{1, n}, j=\overline{1, d}&amp;lt;/math&amp;gt;&amp;amp;ndash; координат векторов (наблюдений).&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;Целое положительное число &amp;lt;math&amp;gt;k, k \le n&amp;lt;/math&amp;gt; &amp;amp;ndash; количество кластеров.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;Объем входных данных&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;math&amp;gt;1&amp;lt;/math&amp;gt; целое число + &amp;lt;math&amp;gt;n*d&amp;lt;/math&amp;gt; вещественных чисел (при условии, что координаты &amp;amp;ndash; вещественные числа).&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;Выходные данные&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; целых положительных чисел &amp;lt;math&amp;gt;L_1, ..., L_n&amp;lt;/math&amp;gt;&amp;amp;ndash; номера кластеров, соотвествующие каждому вектору (при условии, что нумерация кластеров начинается с &amp;lt;math&amp;gt;1&amp;lt;/math&amp;gt;).&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;Объем выходных данных&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; целых положительных чисел.&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Свойства алгоритма ===&lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;[[глоссарий#Вычислительная мощность|&#039;&#039;Вычислительная мощность&#039;&#039;]]&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
Вычислительная мощность алгоритма &amp;lt;i&amp;gt;k means&amp;lt;/i&amp;gt; равна &amp;lt;math&amp;gt;\frac{k*d*n*\Tau}{n*d} = k*\Tau &amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; &amp;amp;ndash; число кластеров, &amp;lt;math&amp;gt;\Tau&amp;lt;/math&amp;gt; &amp;amp;ndash; число итераций алгоритма.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;[[глоссарий#Детерминированность |&#039;&#039;Детерминированность&#039;&#039;]] и [[глоссарий#Устойчивость |&#039;&#039;Устойчивость&#039;&#039;]] &amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
Алгоритм &amp;lt;i&amp;gt;k means&amp;lt;/i&amp;gt; является итерационным. Количество итераций алгоритма в общем случае не фиксируется и зависит от начального расположения объектов в пространстве, параметра &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt;, а также от начального приближения центров кластеров, &amp;lt;math&amp;gt;\mu_1, ..., \mu_k&amp;lt;/math&amp;gt;. В результате этого может варьироваться результат работы алгоритма. При неудачном выборе начальных параметров итерационный процесс может сойтись к локальному оптимуму&amp;lt;ref&amp;gt;Von Luxburg, Ulrike. Clustering Stability. Now Publishers Inc, 2010.&amp;lt;/ref&amp;gt;. По этим причинам алгоритм не является ни &amp;lt;b&amp;gt;детермирированным&amp;lt;/b&amp;gt;, ни &amp;lt;b&amp;gt;устойчивым&amp;lt;/b&amp;gt;.&lt;br /&gt;
 &lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Соотношение последовательной и параллельной сложности алгоритма&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\frac{\Theta_{k-means}}{\Psi_{k-means}} = \frac{O(\Tau*k*d*n)}{O(\Tau*log(k*d*n))}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Сильные стороны алгоритма&amp;lt;/b&amp;gt;:&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;i&amp;gt;Сравнительно высокая эффективность при простоте реализации&amp;lt;/i&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;i&amp;gt;Высокое качество кластеризации&amp;lt;/i&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;i&amp;gt;Возможность распараллеливания&amp;lt;/i&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;i&amp;gt;Существование множества модификаций&amp;lt;/i&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;Недостатки алгоритма&amp;lt;/b&amp;gt;&amp;lt;ref&amp;gt;Ortega, Joaquín Pérez, Ma Del Rocío Boone Rojas, and María J. Somodevilla. &amp;quot;Research issues on K-means Algorithm: An Experimental Trial Using Matlab.&amp;quot;&amp;lt;/ref&amp;gt;:&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;i&amp;gt;Количество кластеров является параметром алгоритма&amp;lt;/i&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;&amp;lt;i&amp;gt;Чувствительность к начальным условиям&amp;lt;/i&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;Инициализация центров кластеров в значительной степени влияет на результат кластеризации.&amp;lt;/p&amp;gt;&lt;br /&gt;
  &amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;&amp;lt;i&amp;gt;Чувствительность к выбросам и шумам&amp;lt;/i&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;Выбросы, далекие от центров настоящих кластеров, все равно учитываются при вычислении их центров.&amp;lt;/p&amp;gt;&lt;br /&gt;
  &amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;&amp;lt;i&amp;gt;Возможность сходимости к локальному оптимуму&amp;lt;/i&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;Итеративный подход не дает гарантии сходимости к оптимальному решению.&amp;lt;/p&amp;gt;&lt;br /&gt;
  &amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;&amp;lt;i&amp;gt;Использование понятия &amp;quot;среднего&amp;quot;&amp;lt;/i&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;Алгоритм неприменим к данным, для которых не определено понятие &amp;quot;среднего&amp;quot;, например, категориальным данным.&amp;lt;/p&amp;gt;&lt;br /&gt;
  &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&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;
Исследование масштабируемости параллельной реализации алгоритма k means проводилось на суперкомпьютере &amp;quot;Ломоносов&amp;quot;&amp;lt;ref name=&amp;quot;Lom&amp;quot;&amp;gt;Воеводин Вл., Жуматий С., Соболев С., Антонов А., Брызгалов П., Никитенко Д., Стефанов К., Воеводин Вад. Практика суперкомпьютера «Ломоносов» // Открытые системы, 2012, N 7, С. 36-39.&amp;lt;/ref&amp;gt; [http://parallel.ru/cluster Суперкомпьютерного комплекса Московского университета]. Алгоритм реализован на языке C с использованием средств MPI.&lt;br /&gt;
Для исследования масштабируемости проводилось множество запусков программы с разным значением параметра (количество векторов для кластеризации), а также с различным числом процессоров. Фиксировались результаты запусков &amp;amp;ndash; время работы &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt; и количество произведенных итераций алгоритма &amp;lt;math&amp;gt;\Tau&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Параметры запусков для экспериментальной оценки:&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;Значения &amp;lt;b&amp;gt;количества векторов&amp;lt;/b&amp;gt; &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;: 20&#039;000, 30&#039;000, 50&#039;000, 100&#039;000, 200&#039;000, 300&#039;000, 500&#039;000, 700&#039;000, 1&#039;000&#039;000, 1&#039;500&#039;000, 2&#039;000&#039;000.&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;Значения &amp;lt;b&amp;gt;количества процессоров&amp;lt;/b&amp;gt; &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt;: 1, 8, 16, 32, 64, 128, 160, 192, 224, 256, 288, 320, 352, 384, 416, 448, 480, 512.&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;Значение &amp;lt;b&amp;gt;количества кластеров&amp;lt;/b&amp;gt; &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt;: 100.&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;Значение &amp;lt;b&amp;gt;размерности векторов&amp;lt;/b&amp;gt; &amp;lt;math&amp;gt;d&amp;lt;/math&amp;gt;: 10.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Для проведения экспериментов были сгенерированы нормально распределенные псевдослучайные данные (с использованием Python библиотеки [http://scikit-learn.org/ scikit-learn]):&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
from sklearn.datasets import make_classification&lt;br /&gt;
X1, Y1 = make_classification(n_features=10, n_redundant=2, n_informative=8,&lt;br /&gt;
                             n_clusters_per_class=1, n_classes=100,&lt;br /&gt;
                             n_samples=2000000)&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Для заданной конфигурации эксперимента (&amp;lt;math&amp;gt;n, d, p, k&amp;lt;/math&amp;gt;) и полученных результатов (&amp;lt;math&amp;gt;t, \Tau&amp;lt;/math&amp;gt;)  [[Глоссарий#Производительность|производительность]]  и эффективность реализации расчитывались по формулам:&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
&amp;lt;ul&amp;gt;&amp;lt;li&amp;gt;&amp;lt;math&amp;gt;Performance = \frac{N_{k-means}^{d, n}}{t}\ \ (FLOPS),&amp;lt;/math&amp;gt;&amp;lt;/li&amp;gt;&amp;lt;/ul&amp;gt;&lt;br /&gt;
где &amp;lt;math&amp;gt;N_{k-means}^{d, n}&amp;lt;/math&amp;gt; &amp;amp;ndash; точное число операций с плавающей точкой (операции с памятью, а также целочисленные операции не учитывались), вычисленное в соответствие с разделом [[#Последовательная сложность алгоритма| &amp;quot;Последовательная сложность алгоритма&amp;quot;]];&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
&amp;lt;ul&amp;gt;&amp;lt;li&amp;gt;&amp;lt;math&amp;gt;Efficiency = \frac{100 * Performance}{Performance_{Peak}^{p}}\ \ (%),&amp;lt;/math&amp;gt;&amp;lt;/li&amp;gt;&amp;lt;/ul&amp;gt;&lt;br /&gt;
где &amp;lt;math&amp;gt;Performance_{Peak}^{p}&amp;lt;/math&amp;gt; &amp;amp;ndash; пиковая производительность суперкомпьютера при &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt; процессорах, вычисленная согласно спецификациям Intel&amp;lt;sup&amp;gt;&amp;amp;reg;&amp;lt;/sup&amp;gt; XEON&amp;lt;sup&amp;gt;&amp;amp;reg;&amp;lt;/sup&amp;gt; X5670&amp;lt;ref&amp;gt;&amp;quot;http://ark.intel.com/ru/products/47920/Intel-Xeon-Processor-X5670-12M-Cache-2_93-GHz-6_40-GTs-Intel-QPI&amp;quot;&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Графики зависимости производительности и эффективности параллельной реализации k means от числа векторов для кластеризации (&amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;) и числа процессоров (&amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt;) представлены на рисунках 4 и 5 соответственно.&lt;br /&gt;
&lt;br /&gt;
[[file:Flops.png|thumb|center|800px|Рис. 4. Параллельная реализация k means. График зависимости производительности реализации алгоритма от числа векторов для кластеризации (&amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;) и числа процессоров (&amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt;).]]&lt;br /&gt;
[[file:Efficiency.png|thumb|center|800px|Рис. 5. Параллельная реализация k means. График зависимости эффективности реализации алгоритма от числа векторов для кластеризации (&amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;) и числа процессоров (&amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt;).]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;В результате&amp;lt;/b&amp;gt; экспериментальной оценки были получены следующие оценки эффективности реализации:&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;b&amp;gt;Минимальное&amp;lt;/b&amp;gt; значение: 0.000409 % достигается при &amp;lt;math&amp;gt;n=20&#039;000, p=480&amp;lt;/math&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;b&amp;gt;Максимальное&amp;lt;/b&amp;gt; значение: 0.741119 % достигается при &amp;lt;math&amp;gt;n=300&#039;000, p=1&amp;lt;/math&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
Оценки масштабируемости реализации алгоритма k means:&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;b&amp;gt;По числу процессоров:&amp;lt;/b&amp;gt; -0.002683 &amp;amp;ndash; эффективность убывает с ростом числа процессоров. Данный результат вызван ростом накладных расходов для обеспечения параллельного выполнения алгоритма.&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;b&amp;gt;По размеру задачи:&amp;lt;/b&amp;gt; 0.002779 &amp;amp;ndash; эффективность растет с ростом числа векторов. Данный результат вызван тем, что при увеличении размера задачи, количество вычислений растет по сравнению с временем, затрачиваемым на пересылку данных.&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;b&amp;gt;Общая оценка:&amp;lt;/b&amp;gt; -0.000058 &amp;amp;ndash; можно сделать вывод, что в целом эффективность реализации незначительно уменьшается с ростом размера задачи и числа процессоров.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[https://github.com/serban/kmeans Использованная параллельная реализация алгоритма k means]&lt;br /&gt;
&lt;br /&gt;
=== Динамические характеристики и эффективность реализации алгоритма ===&lt;br /&gt;
=== Выводы для классов архитектур ===&lt;br /&gt;
=== Существующие реализации алгоритма ===&lt;br /&gt;
==== Открытое программное обеспечение ====&lt;br /&gt;
&amp;lt;ol&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;[https://www.icpsr.umich.edu/CrimeStat/ CrimeStat]&amp;lt;/li&amp;gt; Программное обеспечение, созданное для операционных систем Windows, предоставляющее инструменты статистического  и пространственного анализа для решения задачи картирования преступности.&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://juliastats.github.io Julia]&amp;lt;/li&amp;gt; Высокоуровневый высокопроизводительный свободный язык программирования с динамической типизацией, созданный для математических вычислений, содержит реализацию k-means.&lt;br /&gt;
  &amp;lt;li&amp;gt;[https://mahout.apache.org Mahout]&amp;lt;/li&amp;gt; Apache Mahout - Java библиотека для работы с алгоритмами машинного обучения с использованием MapReduce. Содержит реализацию k-means.&lt;br /&gt;
  &amp;lt;li&amp;gt;[https://www.gnu.org/software/octave/ Octave]&amp;lt;/li&amp;gt; Написанная на C++  свободная система для математических вычислений, использующая совместимый с MATLAB язык высокого уровня, содержит реализацию k-means.&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://spark.apache.org/docs/latest/mllib-clustering.html Spark]&amp;lt;/li&amp;gt; Распределенная реализация k-means содержится в библиотеке Mlib для работы с алгоритмами машинного обучения, взаимодействующая с Python библиотекой NumPy и библиотека R.&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://torch.ch Torch]&amp;lt;/li&amp;gt;  MATLAB-подобная библиотека для языка программирования Lua с открытым исходным кодом, предоставляет большое количество алгоритмов для глубинного обучения и научных расчётов. Ядро написано на Си, прикладная часть выполняется на LuaJIT, поддерживается распараллеливание вычислений средствами CUDA и OpenMP. Существуют реализации k-means.&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://www.cs.waikato.ac.nz/ml/weka/ Weka]&amp;lt;/li&amp;gt;  Cвободное программное обеспечение для анализа данных, написанное на Java. Содержит k-means и x-means.&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://accord-framework.net/docs/html/T_Accord_MachineLearning_KMeans.htm Accord.NET]&amp;lt;/li&amp;gt; C# реализация алгоритмов k-means, k-means++, k-modes.&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://docs.opencv.org/3.0-beta/doc/py_tutorials/py_ml/py_kmeans/py_kmeans_opencv/py_kmeans_opencv.html OpenCV]&amp;lt;/li&amp;gt; Написанная на С++ библиотека, направленная в основном на решение задач компьютерного зрения. Содержит реализацию k-means.&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://mlpack.org/ MLPACK]&amp;lt;/li&amp;gt; Масштабируемая С++ библиотека для работы с алгоритмами машинного обучения, содержит реализацию k-means.&lt;br /&gt;
  &amp;lt;li&amp;gt;[https://www.scipy.org/ SciPy]&amp;lt;/li&amp;gt; Библиотека Python, содержит множество реализаций k-means.&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://scikit-learn.org/ scikit-learn]&amp;lt;/li&amp;gt; Библиотека Python, содержит множество реализаций k-means.&lt;br /&gt;
  &amp;lt;li&amp;gt;[https://www.r-bloggers.com/k-means-clustering-in-r/ R]&amp;lt;/li&amp;gt; Язык программирования для статистической обработки данных и работы с графикой, а также свободная программная среда вычислений с открытым исходным кодом в рамках проекта GNU, содержит три реализации k-means.&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://elki.dbs.ifi.lmu.de ELKI]&amp;lt;/li&amp;gt; Java фреймворк, содержащий реализацию k-means, а также множество других алгоритмов кластеризации.&lt;br /&gt;
&amp;lt;/ol&amp;gt;&lt;br /&gt;
==== Проприетарное программное обеспечение  ====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ol&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;[https://www.ayasdi.com/blog/bigdata/topological-data-analysis-of-oil-and-gas-petrophysical-data/ Ayasdi]&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://www.stata.com/features/cluster-analysis/ Stata]&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://mathworld.wolfram.com/K-MeansClusteringAlgorithm.html Mathematica]&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://www.mathworks.com/help/stats/kmeans.html?requestedDomain=www.mathworks.com MATLAB]&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;[https://support.sas.com/rnd/app/stat/procedures/fastclus.html SAS]&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://docs.rapidminer.com/studio/operators/modeling/segmentation/k_means.html RapidMiner]&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;[https://blogs.sap.com/2013/03/28/sap-hana-pal-k-means-algorithm-or-how-to-do-customer-segmentation-for-the-telecommunications-industry/ SAP HANA]&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ol&amp;gt;&lt;br /&gt;
== Литература ==&lt;br /&gt;
&amp;lt;references /&amp;gt;&lt;/div&gt;</summary>
		<author><name>DennZo1993</name></author>
	</entry>
	<entry>
		<id>https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:%D0%91%D1%80%D0%BE%D1%82%D0%B8%D0%BA%D0%BE%D0%B2%D1%81%D0%BA%D0%B0%D1%8F_%D0%94%D0%B0%D0%BD%D1%83%D1%82%D0%B0/%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_k-means&amp;diff=20515</id>
		<title>Участник:Бротиковская Данута/Алгоритм k-means</title>
		<link rel="alternate" type="text/html" href="https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:%D0%91%D1%80%D0%BE%D1%82%D0%B8%D0%BA%D0%BE%D0%B2%D1%81%D0%BA%D0%B0%D1%8F_%D0%94%D0%B0%D0%BD%D1%83%D1%82%D0%B0/%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_k-means&amp;diff=20515"/>
		<updated>2016-12-10T10:25:47Z</updated>

		<summary type="html">&lt;p&gt;DennZo1993: /* Вычислительное ядро алгоритма */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Assignment|Zhum}}&lt;br /&gt;
&lt;br /&gt;
{{algorithm&lt;br /&gt;
| name              = Алгоритм k средних (k means)&lt;br /&gt;
| serial_complexity = &amp;lt;math&amp;gt;O(\Tau*k*d*n)&amp;lt;/math&amp;gt;&lt;br /&gt;
| input_data        = &amp;lt;math&amp;gt; d*n &amp;lt;/math&amp;gt;&lt;br /&gt;
| output_data       = &amp;lt;math&amp;gt; n &amp;lt;/math&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
Авторы страницы &amp;lt;b&amp;gt;[[Участник:Бротиковская Данута|Данута Бротиковская]]&amp;lt;/b&amp;gt; и &amp;lt;b&amp;gt;[[Участник:DennZo1993|Денис Зобнин]]&amp;lt;/b&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
Оба автора внесли одинаковый вклад в написание статьи (поиск материалов, изучение статей, заполнение контента статьи), четких разграничений по пунктам статьи сделать невозможно. &lt;br /&gt;
&lt;br /&gt;
== Свойства и структура алгоритма ==&lt;br /&gt;
&lt;br /&gt;
=== Общее описание алгоритма ===&lt;br /&gt;
Алгоритм &amp;lt;b&amp;gt;&amp;lt;i&amp;gt;k средних&amp;lt;/i&amp;gt;&amp;lt;/b&amp;gt; (&amp;lt;b&amp;gt;&amp;lt;i&amp;gt;k means&amp;lt;/i&amp;gt;&amp;lt;/b&amp;gt;) &amp;amp;ndash; неиерархический&amp;lt;ref&amp;gt;&amp;quot;https://ru.wikipedia.org/wiki/Иерархическая_кластеризация&amp;quot;&amp;lt;/ref&amp;gt;, итерационный метод кластеризации&amp;lt;ref&amp;gt;&amp;quot;https://ru.wikipedia.org/wiki/Кластерный_анализ&amp;quot;&amp;lt;/ref&amp;gt;, получивший большую популярность благодаря своей простоте, наглядности реализации и достаточно высокому качеству работы. Был изобретен в 1950-х годах математиком &amp;lt;i&amp;gt;Гуго Штейнгаузом&amp;lt;/i&amp;gt;&amp;lt;ref&amp;gt;Steinhaus, Hugo. &amp;quot;Sur la division des corp materiels en parties.&amp;quot; Bull. Acad. Polon. Sci 1.804 (1956): 801.&amp;lt;/ref&amp;gt; и почти одновременно &amp;lt;i&amp;gt;Стюартом Ллойдом&amp;lt;/i&amp;gt;&amp;lt;ref&amp;gt;Lloyd, S. P. &amp;quot;Least square quantization in PCM. Bell Telephone Laboratories Paper. Published in journal much later: Lloyd, SP: Least squares quantization in PCM.&amp;quot; IEEE Trans. Inform. Theor.(1957/1982).&amp;lt;/ref&amp;gt;. Особую популярность приобрел после публикации работы &amp;lt;i&amp;gt;МакКуина&amp;lt;/i&amp;gt;&amp;lt;ref&amp;gt;MacQueen, James. &amp;quot;Some methods for classification and analysis of multivariate observations.&amp;quot; Proceedings of the fifth Berkeley symposium on mathematical statistics and probability. Vol. 1. No. 14. 1967.&amp;lt;/ref&amp;gt; в 1967.&lt;br /&gt;
&lt;br /&gt;
Алгоритм представляет собой версию EM-алгоритма&amp;lt;ref&amp;gt;&amp;quot;https://ru.wikipedia.org/wiki/EM-алгоритм&amp;quot;&amp;lt;/ref&amp;gt;, применяемого также для разделения смеси гауссиан. Основная идея &amp;lt;i&amp;gt;k means&amp;lt;/i&amp;gt; заключается в том, что данные произвольно разбиваются на кластеры, после чего итеративно перевычисляется центр масс для каждого кластера, полученного на предыдущем шаге, затем векторы разбиваются на кластеры вновь в соответствии с тем, какой из новых центров оказался ближе по выбранной метрике.&lt;br /&gt;
&lt;br /&gt;
Цель алгоритма заключается в разделении &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; наблюдений на &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластеров таким образом, чтобы каждое наблюдение принадлежало ровно одному кластеру, расположенному на наименьшем расстоянии от наблюдения.&lt;br /&gt;
&lt;br /&gt;
=== Математическое описание алгоритма ===&lt;br /&gt;
&amp;lt;b&amp;gt;&amp;lt;u&amp;gt;Дано:&amp;lt;/u&amp;gt;&amp;lt;/b&amp;gt;&lt;br /&gt;
* набор из &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; наблюдений &amp;lt;math&amp;gt;X=\{\mathbf{x}_1, \mathbf{x}_2, ..., \mathbf{x}_n\}, \mathbf{x}_i \in \mathbb{R}^d, i=\overline{1, n}&amp;lt;/math&amp;gt;;&lt;br /&gt;
* &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; - требуемое число кластеров, &amp;lt;math&amp;gt;k \in \mathbb{N}, k \leq n&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;&amp;lt;u&amp;gt;Требуется:&amp;lt;/u&amp;gt;&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Разделить множество наблюдений &amp;lt;math&amp;gt;X&amp;lt;/math&amp;gt; на &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластеров &amp;lt;math&amp;gt;S_1, S_2, ..., S_k&amp;lt;/math&amp;gt;:&lt;br /&gt;
*   &amp;lt;math&amp;gt;S_i \cap S_j= \varnothing, \quad i \ne j&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
*   &amp;lt;math&amp;gt;\bigcup_{i=1}^{k} S_i = X&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;&amp;lt;u&amp;gt;Действие алгоритма:&amp;lt;/u&amp;gt;&amp;lt;/b&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;Алгоритм &amp;lt;i&amp;gt;k means&amp;lt;/i&amp;gt; разбивает набор &amp;lt;math&amp;gt;X&amp;lt;/math&amp;gt; на &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; наборов &amp;lt;math&amp;gt;S_1, S_2, ..., S_k,&amp;lt;/math&amp;gt; таким образом, чтобы минимизировать сумму квадратов расстояний от каждой точки кластера до его центра (центр масс кластера). Введем обозначение, &amp;lt;math&amp;gt;S=\{S_1, S_2, ..., S_k\}&amp;lt;/math&amp;gt;. Тогда действие алгоритма &amp;lt;i&amp;gt;k means&amp;lt;/i&amp;gt; равносильно поиску:&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;table style=&amp;quot;width:100%&amp;quot;&amp;gt;&lt;br /&gt;
  &amp;lt;tr&amp;gt;&lt;br /&gt;
    &amp;lt;td align=&amp;quot;center&amp;quot; width=&amp;quot;90%&amp;quot;&amp;gt;&amp;lt;math&amp;gt;\arg\min_{S} \sum\limits_{i=1}^k \sum\limits_{\mathbf{x} \in S_i} \rho(\mathbf{x}, \mathbf{\mu}_i )^2,&amp;lt;/math&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;td align=&amp;quot;right&amp;quot;&amp;gt;&amp;lt;math&amp;gt;(1)&amp;lt;/math&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;/table&amp;gt;&lt;br /&gt;
где &amp;lt;math&amp;gt;\mathbf{\mu}_i&amp;lt;/math&amp;gt; &amp;amp;ndash; центры кластеров, &amp;lt;math&amp;gt;i=\overline{1,k}, \quad \rho(\mathbf{x}, \mathbf{\mu}_i)&amp;lt;/math&amp;gt; &amp;amp;ndash; функция расстояния между &amp;lt;math&amp;gt;\mathbf{x}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\mu_i&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;&amp;lt;u&amp;gt;Шаги алгоритма: &amp;lt;/u&amp;gt;&amp;lt;/b&amp;gt;&lt;br /&gt;
&amp;lt;ol&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&lt;br /&gt;
    &amp;lt;b&amp;gt;Начальный шаг: инициализация кластеров&amp;lt;/b&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;Выбирается произвольное множество точек &amp;lt;math&amp;gt;\mu_i, i=\overline{1,k}&amp;lt;/math&amp;gt;, рассматриваемых как начальные центры кластеров: &amp;lt;math&amp;gt;\mu_i^{(0)} = \mu_i, \quad i=\overline{1, k}&amp;lt;/math&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
  &amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&lt;br /&gt;
    &amp;lt;b&amp;gt;Распределение векторов по кластерам&amp;lt;/b&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Шаг&amp;lt;/b&amp;gt; &amp;lt;math&amp;gt;t: \forall \mathbf{x}_i \in X, i=\overline{1,n}: \mathbf{x}_i \in S_j \iff  j=\arg\min_{k}\rho(\mathbf{x}_i,\mathbf{\mu}_k^{(t-1)})^2&amp;lt;/math&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
  &amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&lt;br /&gt;
    &amp;lt;b&amp;gt;Пересчет центров кластеров&amp;lt;/b&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Шаг &amp;lt;/b&amp;gt; &amp;lt;math&amp;gt;t: \forall i=\overline{1,k}:  \mu_i^{(t)} = \cfrac{1}{|S_i|}\sum_{\mathbf{x}\in S_i}\mathbf{x}&amp;lt;/math&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
  &amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&lt;br /&gt;
    &amp;lt;b&amp;gt;Проверка условия останова:&amp;lt;/b&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
    &#039;&#039;&#039;if&#039;&#039;&#039; &amp;lt;math&amp;gt;\exist i\in \overline{1,k}: \mu_i^{(t)} \ne \mu_i^{(t-1)}&amp;lt;/math&amp;gt; &#039;&#039;&#039;then&#039;&#039;&#039;&lt;br /&gt;
        t = t + 1;&lt;br /&gt;
        goto 2;&lt;br /&gt;
    &#039;&#039;&#039;else&#039;&#039;&#039;&lt;br /&gt;
        &#039;&#039;&#039;stop&#039;&#039;&#039;&lt;br /&gt;
  &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ol&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Вычислительное ядро алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Вычислительным ядром являются шаги 2 и 3 приведенного выше алгоритма: &amp;lt;b&amp;gt;&amp;lt;i&amp;gt;распределение векторов по кластерам&amp;lt;/i&amp;gt;&amp;lt;/b&amp;gt; и &amp;lt;b&amp;gt;&amp;lt;i&amp;gt;пересчет центров кластеров&amp;lt;/i&amp;gt;&amp;lt;/b&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;&amp;lt;i&amp;gt;Распределение векторов&amp;lt;/i&amp;gt;&amp;lt;/b&amp;gt; по кластерам предполагает вычисление расстояний между каждым вектором &amp;lt;math&amp;gt;\mathbf{x}_i \in X, i= \overline{1,n}&amp;lt;/math&amp;gt; и центрами кластера &amp;lt;math&amp;gt;\mathbf{\mu}_j, j= \overline{1,k}&amp;lt;/math&amp;gt;. Таким образом, данный шаг предполагает &amp;lt;math&amp;gt;kn&amp;lt;/math&amp;gt; вычислений расстояний между d-мерными векторами. &lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;&amp;lt;i&amp;gt;Пересчет центров кластеров&amp;lt;/i&amp;gt;&amp;lt;/b&amp;gt; предполагает &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; вычислений центров масс &amp;lt;math&amp;gt;\mathbf{\mu}_i&amp;lt;/math&amp;gt; множеств &amp;lt;math&amp;gt;S_i, i=\overline{1,k}&amp;lt;/math&amp;gt; представленных выражением в шаге 3 представленного выше алгоритма.&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Макроструктура алгоритма ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Инициализация центров масс &amp;lt;math&amp;gt;\mu_1, ..., \mu_k&amp;lt;/math&amp;gt;&amp;lt;/b&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
Наиболее распространенными являются следующие стратегии:&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&lt;br /&gt;
    &amp;lt;b&amp;gt;Метод Forgy&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;В качестве начальных значений &amp;lt;math&amp;gt;\mu_1, ..., \mu_k&amp;lt;/math&amp;gt; берутся случайно выбранные векторы.&lt;br /&gt;
  &amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&lt;br /&gt;
    &amp;lt;b&amp;gt;Метод случайно разделения (Random Partitioning)&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;Для каждого вектора &amp;lt;math&amp;gt;\mathbf{x}_i \in X, i=\overline{1, n}&amp;lt;/math&amp;gt; выбирается случайным образом кластер &amp;lt;math&amp;gt;S_1, ..., S_k&amp;lt;/math&amp;gt;, после чего для каждого полученного кластера вычисляются значения &amp;lt;math&amp;gt;\mu_1, ..., \mu_k&amp;lt;/math&amp;gt;.&lt;br /&gt;
  &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Распределение векторов по кластерам&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Для этого шага алгоритма между векторами &amp;lt;math&amp;gt;\mathbf{x}_i \in X, i=\overline{1, n}&amp;lt;/math&amp;gt; и центрами кластеров &amp;lt;math&amp;gt;\mu_1, ..., \mu_k&amp;lt;/math&amp;gt; вычисляются &amp;lt;b&amp;gt;расстояния&amp;lt;/b&amp;gt; по формуле (как правило, используется Евлидово расстояние):&lt;br /&gt;
&amp;lt;table style=&amp;quot;width:100%&amp;quot;&amp;gt;&lt;br /&gt;
  &amp;lt;tr&amp;gt;&lt;br /&gt;
    &amp;lt;td align=&amp;quot;center&amp;quot; width=&amp;quot;90%&amp;quot;&amp;gt;&amp;lt;math&amp;gt; \mathbf{v}_1, \mathbf{v}_2 \in \mathbb{R}^d,  \quad \rho(\mathbf{v}_1, \mathbf{v}_2) = \lVert \mathbf{v}_1- \mathbf{v}_2 \rVert= \sqrt{\sum_{i=1}^{d}(\mathbf{v}_{1,i} - \mathbf{v}_{2,i})^2}&amp;lt;/math&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;td align=&amp;quot;right&amp;quot;&amp;gt;&amp;lt;math&amp;gt;(2)&amp;lt;/math&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;/table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Пересчет центров кластеров&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Для этого шага алгоритма производится пересчет центров кластера по &amp;lt;b&amp;gt;формуле вычисления центра масс&amp;lt;/b&amp;gt;:&lt;br /&gt;
&amp;lt;table style=&amp;quot;width:100%&amp;quot;&amp;gt;&lt;br /&gt;
  &amp;lt;tr&amp;gt;&lt;br /&gt;
    &amp;lt;td align=&amp;quot;center&amp;quot; width=&amp;quot;90%&amp;quot;&amp;gt;&amp;lt;math&amp;gt; \mu = \cfrac{1}{|S|}\sum_{\mathbf{x}\in S}\mathbf{x}&amp;lt;/math&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;td align=&amp;quot;right&amp;quot;&amp;gt;&amp;lt;math&amp;gt;(3)&amp;lt;/math&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;/table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Схема реализации последовательного алгоритма ===&lt;br /&gt;
&lt;br /&gt;
 &#039;&#039;&#039;algorithm&#039;&#039;&#039; k-means &#039;&#039;&#039;is&#039;&#039;&#039;&lt;br /&gt;
     &#039;&#039;&#039;1.&#039;&#039;&#039; Инициализировать центры кластеров &amp;lt;math&amp;gt;\mathbf{\mu}_i^{(1)}, i=\overline{1,k}&amp;lt;/math&amp;gt;&lt;br /&gt;
     &#039;&#039;&#039;2.&#039;&#039;&#039; &amp;lt;math&amp;gt;t \leftarrow 1&amp;lt;/math&amp;gt;&lt;br /&gt;
     &#039;&#039;&#039;3.&#039;&#039;&#039; &#039;&#039;&#039;Распределение по кластерам&#039;&#039;&#039;&amp;lt;br&amp;gt;&lt;br /&gt;
        &amp;lt;math&amp;gt;S_i^{(t)}=\{\mathbf{x}_p: \lVert\mathbf{x}_p-\mathbf{\mu}_i^{(t)}\rVert^2 \leq \lVert\mathbf{x}_p-\mathbf{\mu}_j^{(t)}\rVert^2 \quad \forall j=\overline{1,k}\},&amp;lt;/math&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
        где каждый вектор &amp;lt;math&amp;gt;\mathbf{x}_p&amp;lt;/math&amp;gt; соотносится единственному кластеру &amp;lt;math&amp;gt;S^{(t)}&amp;lt;/math&amp;gt;&lt;br /&gt;
     &#039;&#039;&#039;4.&#039;&#039;&#039; &#039;&#039;&#039;Обновление центров кластеров&#039;&#039;&#039;&amp;lt;br&amp;gt;&lt;br /&gt;
        &amp;lt;math&amp;gt;\mathbf{\mu}_i^{(t+1)} = \frac{1}{|S^{(t)}_i|} \sum_{\mathbf{x}_j \in S^{(t)}_i} \mathbf{x}_j &amp;lt;/math&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
     &#039;&#039;&#039;5.&#039;&#039;&#039; &#039;&#039;&#039;if&#039;&#039;&#039; &amp;lt;math&amp;gt;\exist i \in \overline{1,k}: \mathbf{\mu}_i^{(t+1)} \ne \mathbf{\mu}_i^{(t)}&amp;lt;/math&amp;gt; &#039;&#039;&#039;then&#039;&#039;&#039;&lt;br /&gt;
            t = t + 1;&lt;br /&gt;
            goto &#039;&#039;&#039;3&#039;&#039;&#039;;&lt;br /&gt;
        &#039;&#039;&#039;else&#039;&#039;&#039;&lt;br /&gt;
            &#039;&#039;&#039;stop&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
=== Последовательная сложность алгоритма===&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding-bottom: 20px&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;Обозначим &amp;lt;math&amp;gt;\Theta_{centroid}^{d, m}&amp;lt;/math&amp;gt; временную сложность вычисления центорида кластера, число элементов которого равна &amp;lt;math&amp;gt;m&amp;lt;/math&amp;gt;,  в d-мерном пространстве.&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;Аналогично  &amp;lt;math&amp;gt;\Theta_{distance}^d&amp;lt;/math&amp;gt; &amp;amp;ndash; временная сложность вычисления расстояния между двумя d-мерными векторами.&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding-bottom: 20px&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;Сложность шага инициализации &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластеров мощности &amp;lt;math&amp;gt;m&amp;lt;/math&amp;gt; в d-мерном пространстве &amp;amp;ndash; &amp;lt;math&amp;gt;\Theta_{init}^{k, d, m}&amp;lt;/math&amp;gt;&amp;lt;/b&amp;gt;&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;i&amp;gt;Стратерия Forgy&amp;lt;/i&amp;gt;: вычисления не требуются, &amp;lt;math&amp;gt;\Theta_{init}^{k, d, m} = 0&amp;lt;/math&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;i&amp;gt;Стратегия случайного разбиения&amp;lt;/i&amp;gt;: вычисление центров &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластеров,  &amp;lt;math&amp;gt;\Theta_{init}^{k, d, m} = k*\Theta_{centroid}^{d, m}, m \le n&amp;lt;/math&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding-bottom: 20px&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Cложность шага распределения d мерных векторов по &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластерам &amp;amp;ndash; &amp;lt;math&amp;gt;\Theta_{distribute}^{k, d}&amp;lt;/math&amp;gt;&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
На этом шаге для каждого вектора &amp;lt;math&amp;gt;\mathbf{x}_i \in X, i=\overline{1, n}&amp;lt;/math&amp;gt; вычисляется k расстояний до центров кластеров &amp;lt;math&amp;gt;\mathbf{\mu}_1, ...\mathbf{\mu}_k&amp;lt;/math&amp;gt;&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p align=&amp;quot;center&amp;quot;&amp;gt;&lt;br /&gt;
  &amp;lt;math&amp;gt;\Theta_{distribute}^{k, d} = n*k*\Theta_{distance}^d&amp;lt;/math&amp;gt;&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding-bottom: 20px&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;Сложность шага пересчета центров &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластеров размера &amp;lt;math&amp;gt;m&amp;lt;/math&amp;gt; в d-мерном пространстве &amp;amp;ndash; &amp;lt;math&amp;gt;\Theta_{recenter}^{k, d, m}&amp;lt;/math&amp;gt;&amp;lt;/b&amp;gt;&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;На этом шаге вычисляется &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; центров кластеров &amp;lt;math&amp;gt;\mathbf{\mu}_1, ...\mathbf{\mu}_k&amp;lt;/math&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p align=&amp;quot;center&amp;quot;&amp;gt;&amp;lt;math&amp;gt;\Theta_{recenter}^{k, d, m} = k*\Theta_{centroid}^{d, m}&amp;lt;/math&amp;gt; &amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding-bottom: 20px&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Рассчитаем &amp;lt;math&amp;gt;\Theta_{centroid}^{d, m}&amp;lt;/math&amp;gt; для кластера, число элементов которого равно &amp;lt;math&amp;gt;m&amp;lt;/math&amp;gt;&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p align=&amp;quot;center&amp;quot;&amp;gt;&amp;lt;math&amp;gt;\Theta_{centroid}^{d, m}&amp;lt;/math&amp;gt; = &amp;lt;math&amp;gt;m * d&amp;lt;/math&amp;gt; сложений + &amp;lt;math&amp;gt;d&amp;lt;/math&amp;gt; делений &amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding-bottom: 20px&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Рассчитаем &amp;lt;math&amp;gt;\Theta_{distance}^d&amp;lt;/math&amp;gt; в соответствие с формулой &amp;lt;math&amp;gt;(2)&amp;lt;/math&amp;gt;&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p align=&amp;quot;center&amp;quot;&amp;gt;&amp;lt;math&amp;gt;\Theta_{distance}^d&amp;lt;/math&amp;gt; = &amp;lt;math&amp;gt;d&amp;lt;/math&amp;gt; вычитаний + &amp;lt;math&amp;gt;d&amp;lt;/math&amp;gt; умножений + &amp;lt;math&amp;gt;(d-1)&amp;lt;/math&amp;gt; сложение&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding-bottom: 20px&amp;quot;&amp;gt;&lt;br /&gt;
  &amp;lt;p&amp;gt;Предположим, что алгоритм сошелся за &amp;lt;math&amp;gt;\Tau&amp;lt;/math&amp;gt; итераций, тогда временная сложность алгоритма &amp;lt;math&amp;gt;\Theta_{k-means}^{d, n}&amp;lt;/math&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
  &amp;lt;p align=&amp;quot;center&amp;quot;&amp;gt;&amp;lt;b&amp;gt;&amp;lt;math&amp;gt;\Theta_{k-means}^{d, n} \le \Theta_{init}^{k, d, n} + \Tau*(\Theta_{distribute}^{k, d} + \Theta_{recenter}^{k, d, n})&amp;lt;/math&amp;gt;&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding-bottom: 5px&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;Операции сложения/вычитания:&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p align=&amp;quot;center&amp;quot;&amp;gt;&amp;lt;b&amp;gt;&amp;lt;math&amp;gt;\Theta_{k-means}^{d, n} \le k*n*d+ \Tau*(k*n*(2d-1) + k*n*d) = k*n*d+ \Tau*(k*n*(3d-1)) \thicksim O(\Tau*k*d*n)&amp;lt;/math&amp;gt;&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding-bottom: 20px&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;Операции умножения/деления:&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p align=&amp;quot;center&amp;quot;&amp;gt;&amp;lt;b&amp;gt;&amp;lt;math&amp;gt;\Theta_{k-means}^{d, n} \le k*d + \Tau*(k*n*d + k*d) = k*d + \Tau * k*d*(n+1) \thicksim O(\Tau*k*d*n) &amp;lt;/math&amp;gt;&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding-bottom: 20px&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;Получаем, что &amp;lt;b&amp;gt;временная сложность&amp;lt;/b&amp;gt; алгоритма &amp;lt;b&amp;gt;k means&amp;lt;/b&amp;gt; кластеризации &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; &amp;lt;b&amp;gt;d-мерных&amp;lt;/b&amp;gt; векторов на &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластеров за &amp;lt;math&amp;gt;\Tau&amp;lt;/math&amp;gt; итераций:&amp;lt;/p&amp;gt;&lt;br /&gt;
 &amp;lt;p align=&amp;quot;center&amp;quot;&amp;gt;&amp;lt;b&amp;gt;&amp;lt;math&amp;gt; \Theta_{k-means}^{d, n} \thicksim O(\Tau*k*d*n) &amp;lt;/math&amp;gt;&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Информационный граф ===&lt;br /&gt;
&lt;br /&gt;
Рассмотрим информационный граф алгоритма. Алгоритм &amp;lt;i&amp;gt;k means&amp;lt;/i&amp;gt; начинается с этапа инициализации, после которого следуют итерации, на каждой из которых выполняется два последовательных шага (см. [[#Схема реализации последовательного алгоритма|&amp;quot;Схема реализации последовательного алгоритма&amp;quot;]]): &lt;br /&gt;
* распределение векторов по кластерам&lt;br /&gt;
* перерасчет центров кластеров&lt;br /&gt;
&lt;br /&gt;
Поскольку основная часть вычислений приходится на шаги итераций, распишем информационные графы данных шагов.&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Распределение векторов по кластерам&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
Информационный граф шага распределения векторов по кластерам представлен на &#039;&#039;рисунке 1&#039;&#039;. Исходами данного графа является исходные векторы &amp;lt;math&amp;gt;\mathbf{x}_1, ..., \mathbf{x}_n&amp;lt;/math&amp;gt;, а также центры кластеров &amp;lt;math&amp;gt;\mathbf{\mu}_1, ... \mathbf{\mu}_k&amp;lt;/math&amp;gt;, вычисленные ранее (на шаге инициализации, если рассматривается первая итерация алгоритма, или на шаге пересчета центров кластеров предыдущей итерации в противном случае). Каждая пара векторов данных &amp;lt;math&amp;gt;\mathbf{x}_i, i=\overline{1,n}&amp;lt;/math&amp;gt; и центров кластера &amp;lt;math&amp;gt;\mathbf{\mu}_j, j=\overline{1, k}&amp;lt;/math&amp;gt; : (&amp;lt;math&amp;gt;\mathbf{x}_i&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;\mathbf{\mu}_j&amp;lt;/math&amp;gt;) подаются на независимые узлы &amp;lt;i&amp;gt;&amp;quot;d&amp;quot;&amp;lt;/i&amp;gt; вычисления расстояния между векторами (более подробная схема вычисления расстояния представлена далее, &#039;&#039;рисунок 2&#039;&#039;). Далее узлы вычисления расстояния &amp;lt;i&amp;gt;&amp;quot;d&amp;quot;&amp;lt;/i&amp;gt;, соответствующие одному и тому же исходному вектору &amp;lt;math&amp;gt;\mathbf{x}_i&amp;lt;/math&amp;gt; передаются на один узел &amp;lt;i&amp;gt;&amp;quot;m&amp;quot;&amp;lt;/i&amp;gt;, где далее происходит вычисление новой метки кластера для каждого вектора &amp;lt;math&amp;gt;\mathbf{x}_i&amp;lt;/math&amp;gt; (берется кластер с минимальным результатом вычисления расстояния). На выходе графа выдаются метки кластеров , &amp;lt;math&amp;gt;L_1, ..., L_n&amp;lt;/math&amp;gt;, такие что &amp;lt;math&amp;gt;\forall \mathbf{x}_i, i=\overline{1, n}, \mathbf{x}_i \in S_j \Leftrightarrow L_i = j&amp;lt;/math&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
[[file:Clusterization.png|thumb|center|800px|Рис. 1. Схема распределения векторов по кластерам. &#039;&#039;d&#039;&#039; &amp;amp;ndash; вычисление расстояния между векторами; &#039;&#039;m&#039;&#039; &amp;amp;ndash; вычисление минимума.]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Вычисление расстояния между векторами&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
Подробная схема вычисления расстояния между векторами &amp;lt;math&amp;gt;\mathbf{x}_i, \mathbf{\mu}_j&amp;lt;/math&amp;gt; представлена на &#039;&#039;рисунке 2&#039;&#039;. Как показано на графе, узел вычисления расстояния между векторами &amp;lt;i&amp;gt;&amp;quot;d&amp;quot;&amp;lt;/i&amp;gt; состоит из шага взятия разности между векторами (узел &amp;quot;&amp;lt;math&amp;gt;-&amp;lt;/math&amp;gt;&amp;quot;) и взятия нормы получившегося вектора разности (узел &amp;quot;&amp;lt;math&amp;gt;||\cdot||^2&amp;lt;/math&amp;gt;&amp;quot;). Более подробно, вычисление расстояния между векторами &amp;lt;math&amp;gt;\mathbf{x}_i = {x_{i1,}, ...,{x_{in}}}, \mathbf{\mu}_j = {\mu_{j1}, ...,\mu_{jn}}&amp;lt;/math&amp;gt; может быть представлено как вычисление разности между каждой парой компонент &amp;lt;math&amp;gt;(x_{iz}, \mu_{jz}), z=\overline{1, d}&amp;lt;/math&amp;gt; (узел &amp;quot;&amp;lt;math&amp;gt;-&amp;lt;/math&amp;gt;&amp;quot;), далее возведение в квадрат для каждого узла &amp;quot;&amp;lt;math&amp;gt;-&amp;lt;/math&amp;gt;&amp;quot; (узел &amp;quot;&amp;lt;math&amp;gt;()^2&amp;lt;/math&amp;gt;&amp;quot;) и суммирования выходов всех узлов &amp;quot;&amp;lt;math&amp;gt;()^2&amp;lt;/math&amp;gt;&amp;quot; (узел &amp;quot;&amp;lt;math&amp;gt;+&amp;lt;/math&amp;gt;&amp;quot;).  &lt;br /&gt;
&lt;br /&gt;
[[file:dist_calc.png|thumb|center|800px|Рис. 2. Схема вычисления расстояния между вектором и центром кластера.]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Пересчет центров кластеров&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
Информационный граф шага пересчета центров кластеров представлен на &#039;&#039;рисунке 3&#039;&#039;. Исходами данного графа является исходные векторы &amp;lt;math&amp;gt;\mathbf{x}_1, ..., \mathbf{x}_n&amp;lt;/math&amp;gt;, а также им соответствующие метки кластера, &amp;lt;math&amp;gt;L_1, ..., L_n&amp;lt;/math&amp;gt;, такие что &amp;lt;math&amp;gt;\forall x_i, i=\overline{1, n}, \mathbf{x}_i \in S_j \Leftrightarrow L_i = j&amp;lt;/math&amp;gt;, вычисленные на этапе распределения векторов по кластерам. Все векторы &amp;lt;math&amp;gt;\mathbf{x}_1, ..., \mathbf{x}_n&amp;lt;/math&amp;gt; подаются в узлы &amp;lt;math&amp;gt;+_1, ...+_k&amp;lt;/math&amp;gt;, каждый узел &amp;lt;math&amp;gt;+_m, m = \overline{1,k}&amp;lt;/math&amp;gt; соответствует операции сложения векторов кластера с номером &amp;lt;math&amp;gt;m&amp;lt;/math&amp;gt;. Метки кластера &amp;lt;math&amp;gt;L_1, ..., L_n&amp;lt;/math&amp;gt; также совместно передаются на узлы &amp;lt;math&amp;gt;S_m, m = \overline{1,k}&amp;lt;/math&amp;gt;, на каждом из которых вычисляется количество векторов в соответствующем кластере (количество меток с соответствующим значением). Далее каждая пара выходов узлов &amp;lt;math&amp;gt;+_m&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;S_m&amp;lt;/math&amp;gt; подается на узел &amp;quot;&amp;lt;math&amp;gt;/&amp;lt;/math&amp;gt;&amp;quot;, где производится деление суммы векторов кластера на количество элементов в нем. Значения, вычисленные на узлах &amp;quot;&amp;lt;math&amp;gt;/&amp;lt;/math&amp;gt;&amp;quot;, присваиваются новым центрам кластеров (выходные значения графа).&lt;br /&gt;
&lt;br /&gt;
[[file:Recluster.png|thumb|center|800px|Рис. 3. Схема пересчета центров кластеров]]&lt;br /&gt;
&lt;br /&gt;
=== Ресурс параллелизма алгоритма ===&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
Работа алгоритма состоит из &amp;lt;math&amp;gt;\Tau&amp;lt;/math&amp;gt; итераций, в каждой из которых происходит &amp;lt;b&amp;gt;распределение d-мерных векторов по &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластерам&amp;lt;/b&amp;gt;, а также &amp;lt;b&amp;gt;пересчет центров кластеров в d-мерном пространстве&amp;lt;/b&amp;gt;. В шаге &amp;lt;b&amp;gt;распределения d-мерных векторов по &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластерам&amp;lt;/b&amp;gt; расстояния между вектором и центрами кластеров вычисляются независимо (отсутствуют информационные зависимости). &amp;lt;b&amp;gt;Центры масс кластеров&amp;lt;/b&amp;gt; также пересчитываются независимо друг от друга. Таким образом, имеет место [[глоссарий#Массовый параллелизм|&#039;&#039;массовый параллелизм&#039;&#039;]]. Вычислим параллельную сложность &amp;lt;math&amp;gt;\Psi_*&amp;lt;/math&amp;gt; каждого из шагов, а также параллельную сложность всего алгоритма, &amp;lt;math&amp;gt;\Psi_{k-means}&amp;lt;/math&amp;gt;. Будем исходить из предположения, что может быть использовано любое необходимое число потоков.&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Распределение d-мерных векторов по &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластерам&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;  &lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
Поскольку на данном шаге для каждой пары векторов &amp;lt;math&amp;gt;\mathbf{x}_i, i=\overline{1,n}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\mathbf{\mu}_j, j=\overline{1,k}&amp;lt;/math&amp;gt; операции вычисления расстояния не зависят друг от друга, они могут выполняться параллельно. Тогда, разделив все вычисление расстояний на &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; потоков, получим, что в каждом потоке будет выполняться только одна операция вычисления расстояния между векторами размерности d. При этом каждому вычислительному потоку передаются координаты центров всех кластеров &amp;lt;math&amp;gt;\mathbf{\mu}_1, ..., \mathbf{\mu}_k&amp;lt;/math&amp;gt;. Таким образом, параллельная сложность данного шага определяется &amp;lt;i&amp;gt; сложностью параллельной операции вычисления расстояния между d-мерными векторами&amp;lt;/i&amp;gt;, &amp;lt;math&amp;gt;\Psi_{distance}^d&amp;lt;/math&amp;gt;  и &amp;lt;i&amp;gt;сложностью определения наиболее близкого кластера&amp;lt;/i&amp;gt; (паралельное взятие минимума по расстояниям), &amp;lt;math&amp;gt;\Psi_{min}^k&amp;lt;/math&amp;gt;. Для оценки &amp;lt;math&amp;gt;\Psi_{distance}^d&amp;lt;/math&amp;gt; воспользуемся  [[Нахождение_частных_сумм_элементов_массива_сдваиванием | параллельной реализацией нахождения частичной суммы элементов массива путем сдваивания]]. Аналогично, &amp;lt;math&amp;gt;\Psi_{min}^k = log(k)&amp;lt;/math&amp;gt;. В результате, &amp;lt;math&amp;gt;\Psi_{distance}^d = O(log(d))&amp;lt;/math&amp;gt;.   Таким образом: &lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p align=&amp;quot;center&amp;quot;&amp;gt;&amp;lt;math&amp;gt;\Psi_{distribute}^{k, d}  = \Psi_{distance}^d + \Psi_{min}^k = O(log(d))+O(log(k)) = O(log(k*d))&amp;lt;/math&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Пересчет центров кластеров в d-мерном пространстве&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
Поскольку на данном шаге для каждого из &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластеров центр масс может быть вычислен независимо, данные операции могут быть выполнены в отдельных потоках. Таким образом, параллельная сложность данного шага, &amp;lt;math&amp;gt;\Psi_{recenter}^{k, d}&amp;lt;/math&amp;gt;,  будет определяться &amp;lt;i&amp;gt;параллельной сложностью вычисления одного центра масс кластера размера &amp;lt;math&amp;gt;m&amp;lt;/math&amp;gt;&amp;lt;/i&amp;gt;, &amp;lt;math&amp;gt;\Psi_{recenter}^{k, d}&amp;lt;/math&amp;gt;,  а так как &amp;lt;math&amp;gt;m \le n \Rightarrow \Psi_{recenter}^{d, m} \le \Psi_{recenter}^{d, n}&amp;lt;/math&amp;gt;. Сложность вычисления центра масс кластера d-мерных векторов размера n аналогично предыдущим вычислениям равна &amp;lt;math&amp;gt;O(log(n))&amp;lt;/math&amp;gt;. Тогда:  &lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p align=&amp;quot;center&amp;quot;&amp;gt;&amp;lt;math&amp;gt;\Psi_{recenter}^{k, d}  \le \Psi_{recenter}^{d, n} = O(log(n))&amp;lt;/math&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Общая параллельная сложность алгоритма&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
На каждой итерации необходимо обновление центров кластеров, которые будут использованы на следующей итерации. Таким образом, итерационный процесс выполняется последовательно&amp;lt;ref&amp;gt;Zhao, Weizhong, Huifang Ma, and Qing He. &amp;quot;Parallel k-means clustering based on mapreduce.&amp;quot; IEEE International Conference on Cloud Computing. Springer Berlin Heidelberg, 2009.&amp;lt;/ref&amp;gt;. Тогда, поскольку сложность каждой итерации  определяется &amp;lt;math&amp;gt;\Psi_{distribute}^{k, d}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\Psi_{recenter}&amp;lt;/math&amp;gt;, сложность всего алгоритма, &amp;lt;math&amp;gt;\Psi_{k-means}&amp;lt;/math&amp;gt; в предположении, что было сделано &amp;lt;math&amp;gt;\Tau&amp;lt;/math&amp;gt; операций определяется выражением&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p align=&amp;quot;center&amp;quot;&amp;gt;&amp;lt;math&amp;gt;\Psi_{k-means} \approx \Tau * (\Psi_{distribute}^{k, d} + \Psi_{recenter}^{k, d}) \le \Tau * O(log(k*d*n))&amp;lt;/math&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Входные и выходные данные алгоритма ===&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;Входные данные&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;Матрица из &amp;lt;math&amp;gt;n*d&amp;lt;/math&amp;gt; элементов &amp;lt;math&amp;gt;x_{i, j} \in \mathbb{R}, i=\overline{1, n}, j=\overline{1, d}&amp;lt;/math&amp;gt;&amp;amp;ndash; координат векторов (наблюдений).&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;Целое положительное число &amp;lt;math&amp;gt;k, k \le n&amp;lt;/math&amp;gt; &amp;amp;ndash; количество кластеров.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;Объем входных данных&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;math&amp;gt;1&amp;lt;/math&amp;gt; целое число + &amp;lt;math&amp;gt;n*d&amp;lt;/math&amp;gt; вещественных чисел (при условии, что координаты &amp;amp;ndash; вещественные числа).&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;Выходные данные&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; целых положительных чисел &amp;lt;math&amp;gt;L_1, ..., L_n&amp;lt;/math&amp;gt;&amp;amp;ndash; номера кластеров, соотвествующие каждому вектору (при условии, что нумерация кластеров начинается с &amp;lt;math&amp;gt;1&amp;lt;/math&amp;gt;).&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;Объем выходных данных&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; целых положительных чисел.&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Свойства алгоритма ===&lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;[[глоссарий#Вычислительная мощность|&#039;&#039;Вычислительная мощность&#039;&#039;]]&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
Вычислительная мощность алгоритма &amp;lt;i&amp;gt;k means&amp;lt;/i&amp;gt; равна &amp;lt;math&amp;gt;\frac{k*d*n*\Tau}{n*d} = k*\Tau &amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; &amp;amp;ndash; число кластеров, &amp;lt;math&amp;gt;\Tau&amp;lt;/math&amp;gt; &amp;amp;ndash; число итераций алгоритма.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;[[глоссарий#Детерминированность |&#039;&#039;Детерминированность&#039;&#039;]] и [[глоссарий#Устойчивость |&#039;&#039;Устойчивость&#039;&#039;]] &amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
Алгоритм &amp;lt;i&amp;gt;k means&amp;lt;/i&amp;gt; является итерационным. Количество итераций алгоритма в общем случае не фиксируется и зависит от начального расположения объектов в пространстве, параметра &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt;, а также от начального приближения центров кластеров, &amp;lt;math&amp;gt;\mu_1, ..., \mu_k&amp;lt;/math&amp;gt;. В результате этого может варьироваться результат работы алгоритма. При неудачном выборе начальных параметров итерационный процесс может сойтись к локальному оптимуму&amp;lt;ref&amp;gt;Von Luxburg, Ulrike. Clustering Stability. Now Publishers Inc, 2010.&amp;lt;/ref&amp;gt;. По этим причинам алгоритм не является ни &amp;lt;b&amp;gt;детермирированным&amp;lt;/b&amp;gt;, ни &amp;lt;b&amp;gt;устойчивым&amp;lt;/b&amp;gt;.&lt;br /&gt;
 &lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Соотношение последовательной и параллельной сложности алгоритма&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\frac{\Theta_{k-means}}{\Psi_{k-means}} = \frac{O(\Tau*k*d*n)}{O(\Tau*log(k*d*n))}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Сильные стороны алгоритма&amp;lt;/b&amp;gt;:&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;i&amp;gt;Сравнительно высокая эффективность при простоте реализации&amp;lt;/i&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;i&amp;gt;Высокое качество кластеризации&amp;lt;/i&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;i&amp;gt;Возможность распараллеливания&amp;lt;/i&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;i&amp;gt;Существование множества модификаций&amp;lt;/i&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;Недостатки алгоритма&amp;lt;/b&amp;gt;&amp;lt;ref&amp;gt;Ortega, Joaquín Pérez, Ma Del Rocío Boone Rojas, and María J. Somodevilla. &amp;quot;Research issues on K-means Algorithm: An Experimental Trial Using Matlab.&amp;quot;&amp;lt;/ref&amp;gt;:&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;i&amp;gt;Количество кластеров является параметром алгоритма&amp;lt;/i&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;&amp;lt;i&amp;gt;Чувствительность к начальным условиям&amp;lt;/i&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;Инициализация центров кластеров в значительной степени влияет на результат кластеризации.&amp;lt;/p&amp;gt;&lt;br /&gt;
  &amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;&amp;lt;i&amp;gt;Чувствительность к выбросам и шумам&amp;lt;/i&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;Выбросы, далекие от центров настоящих кластеров, все равно учитываются при вычислении их центров.&amp;lt;/p&amp;gt;&lt;br /&gt;
  &amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;&amp;lt;i&amp;gt;Возможность сходимости к локальному оптимуму&amp;lt;/i&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;Итеративный подход не дает гарантии сходимости к оптимальному решению.&amp;lt;/p&amp;gt;&lt;br /&gt;
  &amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;&amp;lt;i&amp;gt;Использование понятия &amp;quot;среднего&amp;quot;&amp;lt;/i&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;Алгоритм неприменим к данным, для которых не определено понятие &amp;quot;среднего&amp;quot;, например, категориальным данным.&amp;lt;/p&amp;gt;&lt;br /&gt;
  &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&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;
Исследование масштабируемости параллельной реализации алгоритма k means проводилось на суперкомпьютере &amp;quot;Ломоносов&amp;quot;&amp;lt;ref name=&amp;quot;Lom&amp;quot;&amp;gt;Воеводин Вл., Жуматий С., Соболев С., Антонов А., Брызгалов П., Никитенко Д., Стефанов К., Воеводин Вад. Практика суперкомпьютера «Ломоносов» // Открытые системы, 2012, N 7, С. 36-39.&amp;lt;/ref&amp;gt; [http://parallel.ru/cluster Суперкомпьютерного комплекса Московского университета]. Алгоритм реализован на языке C с использованием средств MPI.&lt;br /&gt;
Для исследования масштабируемости проводилось множество запусков программы с разным значением параметра (количество векторов для кластеризации), а также с различным числом процессоров. Фиксировались результаты запусков &amp;amp;ndash; время работы &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt; и количество произведенных итераций алгоритма &amp;lt;math&amp;gt;\Tau&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Параметры запусков для экспериментальной оценки:&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;Значения &amp;lt;b&amp;gt;количества векторов&amp;lt;/b&amp;gt; &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;: 20&#039;000, 30&#039;000, 50&#039;000, 100&#039;000, 200&#039;000, 300&#039;000, 500&#039;000, 700&#039;000, 1&#039;000&#039;000, 1&#039;500&#039;000, 2&#039;000&#039;000.&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;Значения &amp;lt;b&amp;gt;количества процессоров&amp;lt;/b&amp;gt; &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt;: 1, 8, 16, 32, 64, 128, 160, 192, 224, 256, 288, 320, 352, 384, 416, 448, 480, 512.&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;Значение &amp;lt;b&amp;gt;количества кластеров&amp;lt;/b&amp;gt; &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt;: 100.&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;Значение &amp;lt;b&amp;gt;размерности векторов&amp;lt;/b&amp;gt; &amp;lt;math&amp;gt;d&amp;lt;/math&amp;gt;: 10.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Для проведения экспериментов были сгенерированы нормально распределенные псевдослучайные данные (с использованием Python библиотеки [http://scikit-learn.org/ scikit-learn]):&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
from sklearn.datasets import make_classification&lt;br /&gt;
X1, Y1 = make_classification(n_features=10, n_redundant=2, n_informative=8,&lt;br /&gt;
                             n_clusters_per_class=1, n_classes=100,&lt;br /&gt;
                             n_samples=2000000)&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Для заданной конфигурации эксперимента (&amp;lt;math&amp;gt;n, d, p, k&amp;lt;/math&amp;gt;) и полученных результатов (&amp;lt;math&amp;gt;t, \Tau&amp;lt;/math&amp;gt;)  [[Глоссарий#Производительность|производительность]]  и эффективность реализации расчитывались по формулам:&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
&amp;lt;ul&amp;gt;&amp;lt;li&amp;gt;&amp;lt;math&amp;gt;Performance = \frac{N_{k-means}^{d, n}}{t}\ \ (FLOPS),&amp;lt;/math&amp;gt;&amp;lt;/li&amp;gt;&amp;lt;/ul&amp;gt;&lt;br /&gt;
где &amp;lt;math&amp;gt;N_{k-means}^{d, n}&amp;lt;/math&amp;gt; &amp;amp;ndash; точное число операций с плавающей точкой (операции с памятью, а также целочисленные операции не учитывались), вычисленное в соответствие с разделом [[#Последовательная сложность алгоритма| &amp;quot;Последовательная сложность алгоритма&amp;quot;]];&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
&amp;lt;ul&amp;gt;&amp;lt;li&amp;gt;&amp;lt;math&amp;gt;Efficiency = \frac{100 * Performance}{Performance_{Peak}^{p}}\ \ (%),&amp;lt;/math&amp;gt;&amp;lt;/li&amp;gt;&amp;lt;/ul&amp;gt;&lt;br /&gt;
где &amp;lt;math&amp;gt;Performance_{Peak}^{p}&amp;lt;/math&amp;gt; &amp;amp;ndash; пиковая производительность суперкомпьютера при &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt; процессорах, вычисленная согласно спецификациям Intel&amp;lt;sup&amp;gt;&amp;amp;reg;&amp;lt;/sup&amp;gt; XEON&amp;lt;sup&amp;gt;&amp;amp;reg;&amp;lt;/sup&amp;gt; X5670&amp;lt;ref&amp;gt;&amp;quot;http://ark.intel.com/ru/products/47920/Intel-Xeon-Processor-X5670-12M-Cache-2_93-GHz-6_40-GTs-Intel-QPI&amp;quot;&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Графики зависимости производительности и эффективности параллельной реализации k means от числа векторов для кластеризации (&amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;) и числа процессоров (&amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt;) представлены на рисунках 4 и 5 соответственно.&lt;br /&gt;
&lt;br /&gt;
[[file:Flops.png|thumb|center|800px|Рис. 4. Параллельная реализация k means. График зависимости производительности реализации алгоритма от числа векторов для кластеризации (&amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;) и числа процессоров (&amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt;).]]&lt;br /&gt;
[[file:Efficiency.png|thumb|center|800px|Рис. 5. Параллельная реализация k means. График зависимости эффективности реализации алгоритма от числа векторов для кластеризации (&amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;) и числа процессоров (&amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt;).]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;В результате&amp;lt;/b&amp;gt; экспериментальной оценки были получены следующие оценки эффективности реализации:&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;b&amp;gt;Минимальное&amp;lt;/b&amp;gt; значение: 0.000409 % достигается при &amp;lt;math&amp;gt;n=20&#039;000, p=480&amp;lt;/math&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;b&amp;gt;Максимальное&amp;lt;/b&amp;gt; значение: 0.741119 % достигается при &amp;lt;math&amp;gt;n=300&#039;000, p=1&amp;lt;/math&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
Оценки масштабируемости реализации алгоритма k means:&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;b&amp;gt;По числу процессоров:&amp;lt;/b&amp;gt; -0.002683 &amp;amp;ndash; эффективность убывает с ростом числа процессоров. Данный результат вызван ростом накладных расходов для обеспечения параллельного выполнения алгоритма.&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;b&amp;gt;По размеру задачи:&amp;lt;/b&amp;gt; 0.002779 &amp;amp;ndash; эффективность растет с ростом числа векторов. Данный результат вызван тем, что при увеличении размера задачи, количество вычислений растет по сравнению с временем, затрачиваемым на пересылку данных.&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;b&amp;gt;Общая оценка:&amp;lt;/b&amp;gt; -0.000058 &amp;amp;ndash; можно сделать вывод, что в целом эффективность реализации незначительно уменьшается с ростом размера задачи и числа процессоров.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[https://github.com/serban/kmeans Использованная параллельная реализация алгоритма k means]&lt;br /&gt;
&lt;br /&gt;
=== Динамические характеристики и эффективность реализации алгоритма ===&lt;br /&gt;
=== Выводы для классов архитектур ===&lt;br /&gt;
=== Существующие реализации алгоритма ===&lt;br /&gt;
==== Открытое программное обеспечение ====&lt;br /&gt;
&amp;lt;ol&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;[https://www.icpsr.umich.edu/CrimeStat/ CrimeStat]&amp;lt;/li&amp;gt; Программное обеспечение, созданное для операционных систем Windows, предоставляющее инструменты статистического  и пространственного анализа для решения задачи картирования преступности.&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://juliastats.github.io Julia]&amp;lt;/li&amp;gt; Высокоуровневый высокопроизводительный свободный язык программирования с динамической типизацией, созданный для математических вычислений, содержит реализацию k-means.&lt;br /&gt;
  &amp;lt;li&amp;gt;[https://mahout.apache.org Mahout]&amp;lt;/li&amp;gt; Apache Mahout - Java библиотека для работы с алгоритмами машинного обучения с использованием MapReduce. Содержит реализацию k-means.&lt;br /&gt;
  &amp;lt;li&amp;gt;[https://www.gnu.org/software/octave/ Octave]&amp;lt;/li&amp;gt; Написанная на C++  свободная система для математических вычислений, использующая совместимый с MATLAB язык высокого уровня, содержит реализацию k-means.&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://spark.apache.org/docs/latest/mllib-clustering.html Spark]&amp;lt;/li&amp;gt; Распределенная реализация k-means содержится в библиотеке Mlib для работы с алгоритмами машинного обучения, взаимодействующая с Python библиотекой NumPy и библиотека R.&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://torch.ch Torch]&amp;lt;/li&amp;gt;  MATLAB-подобная библиотека для языка программирования Lua с открытым исходным кодом, предоставляет большое количество алгоритмов для глубинного обучения и научных расчётов. Ядро написано на Си, прикладная часть выполняется на LuaJIT, поддерживается распараллеливание вычислений средствами CUDA и OpenMP. Существуют реализации k-means.&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://www.cs.waikato.ac.nz/ml/weka/ Weka]&amp;lt;/li&amp;gt;  Cвободное программное обеспечение для анализа данных, написанное на Java. Содержит k-means и x-means.&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://accord-framework.net/docs/html/T_Accord_MachineLearning_KMeans.htm Accord.NET]&amp;lt;/li&amp;gt; C# реализация алгоритмов k-means, k-means++, k-modes.&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://docs.opencv.org/3.0-beta/doc/py_tutorials/py_ml/py_kmeans/py_kmeans_opencv/py_kmeans_opencv.html OpenCV]&amp;lt;/li&amp;gt; Написанная на С++ библиотека, направленная в основном на решение задач компьютерного зрения. Содержит реализацию k-means.&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://mlpack.org/ MLPACK]&amp;lt;/li&amp;gt; Масштабируемая С++ библиотека для работы с алгоритмами машинного обучения, содержит реализацию k-means.&lt;br /&gt;
  &amp;lt;li&amp;gt;[https://www.scipy.org/ SciPy]&amp;lt;/li&amp;gt; Библиотека Python, содержит множество реализаций k-means.&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://scikit-learn.org/ scikit-learn]&amp;lt;/li&amp;gt; Библиотека Python, содержит множество реализаций k-means.&lt;br /&gt;
  &amp;lt;li&amp;gt;[https://www.r-bloggers.com/k-means-clustering-in-r/ R]&amp;lt;/li&amp;gt; Язык программирования для статистической обработки данных и работы с графикой, а также свободная программная среда вычислений с открытым исходным кодом в рамках проекта GNU, содержит три реализации k-means.&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://elki.dbs.ifi.lmu.de ELKI]&amp;lt;/li&amp;gt; Java фреймворк, содержащий реализацию k-means, а также множество других алгоритмов кластеризации.&lt;br /&gt;
&amp;lt;/ol&amp;gt;&lt;br /&gt;
==== Проприетарное программное обеспечение  ====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ol&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;[https://www.ayasdi.com/blog/bigdata/topological-data-analysis-of-oil-and-gas-petrophysical-data/ Ayasdi]&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://www.stata.com/features/cluster-analysis/ Stata]&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://mathworld.wolfram.com/K-MeansClusteringAlgorithm.html Mathematica]&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://www.mathworks.com/help/stats/kmeans.html?requestedDomain=www.mathworks.com MATLAB]&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;[https://support.sas.com/rnd/app/stat/procedures/fastclus.html SAS]&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://docs.rapidminer.com/studio/operators/modeling/segmentation/k_means.html RapidMiner]&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;[https://blogs.sap.com/2013/03/28/sap-hana-pal-k-means-algorithm-or-how-to-do-customer-segmentation-for-the-telecommunications-industry/ SAP HANA]&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ol&amp;gt;&lt;br /&gt;
== Литература ==&lt;br /&gt;
&amp;lt;references /&amp;gt;&lt;/div&gt;</summary>
		<author><name>DennZo1993</name></author>
	</entry>
	<entry>
		<id>https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:%D0%91%D1%80%D0%BE%D1%82%D0%B8%D0%BA%D0%BE%D0%B2%D1%81%D0%BA%D0%B0%D1%8F_%D0%94%D0%B0%D0%BD%D1%83%D1%82%D0%B0/%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_k-means&amp;diff=17189</id>
		<title>Участник:Бротиковская Данута/Алгоритм k-means</title>
		<link rel="alternate" type="text/html" href="https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:%D0%91%D1%80%D0%BE%D1%82%D0%B8%D0%BA%D0%BE%D0%B2%D1%81%D0%BA%D0%B0%D1%8F_%D0%94%D0%B0%D0%BD%D1%83%D1%82%D0%B0/%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_k-means&amp;diff=17189"/>
		<updated>2016-11-15T01:59:08Z</updated>

		<summary type="html">&lt;p&gt;DennZo1993: /* Масштабируемость реализации алгоритма */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt; {{Assignment|Zhum}}&lt;br /&gt;
&lt;br /&gt;
{{algorithm&lt;br /&gt;
| name              = Алгоритм k средних (k means)&lt;br /&gt;
| serial_complexity = &amp;lt;math&amp;gt;O(\Tau*k*d*n)&amp;lt;/math&amp;gt;&lt;br /&gt;
| input_data        = &amp;lt;math&amp;gt; d*n &amp;lt;/math&amp;gt;&lt;br /&gt;
| output_data       = &amp;lt;math&amp;gt; n &amp;lt;/math&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
Авторы страницы &amp;lt;b&amp;gt;[[Участник:Бротиковская Данута|Данута Бротиковская]]&amp;lt;/b&amp;gt; и &amp;lt;b&amp;gt;[[Участник:DennZo1993|Денис Зобнин]]&amp;lt;/b&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
Оба автора внесли одинаковый вклад в написание статьи (поиск материалов, изучение статей, заполнение контента статьи), четких разграничений по пунктам статьи сделать невозможно. &lt;br /&gt;
&lt;br /&gt;
== Свойства и структура алгоритма ==&lt;br /&gt;
&lt;br /&gt;
=== Общее описание алгоритма ===&lt;br /&gt;
Алгоритм &amp;lt;b&amp;gt;&amp;lt;i&amp;gt;k средних&amp;lt;/i&amp;gt;&amp;lt;/b&amp;gt; (&amp;lt;b&amp;gt;&amp;lt;i&amp;gt;k means&amp;lt;/i&amp;gt;&amp;lt;/b&amp;gt;) &amp;amp;ndash; неиерархический&amp;lt;ref&amp;gt;&amp;quot;https://ru.wikipedia.org/wiki/Иерархическая_кластеризация&amp;quot;&amp;lt;/ref&amp;gt;, итерационный метод кластеризации&amp;lt;ref&amp;gt;&amp;quot;https://ru.wikipedia.org/wiki/Кластерный_анализ&amp;quot;&amp;lt;/ref&amp;gt;, получивший большую популярность благодаря своей простоте, наглядности реализации и достаточно высокому качеству работы. Был изобретен в 1950-х годах математиком &amp;lt;i&amp;gt;Гуго Штейнгаузом&amp;lt;/i&amp;gt;&amp;lt;ref&amp;gt;Steinhaus, Hugo. &amp;quot;Sur la division des corp materiels en parties.&amp;quot; Bull. Acad. Polon. Sci 1.804 (1956): 801.&amp;lt;/ref&amp;gt; и почти одновременно &amp;lt;i&amp;gt;Стюартом Ллойдом&amp;lt;/i&amp;gt;&amp;lt;ref&amp;gt;Lloyd, S. P. &amp;quot;Least square quantization in PCM. Bell Telephone Laboratories Paper. Published in journal much later: Lloyd, SP: Least squares quantization in PCM.&amp;quot; IEEE Trans. Inform. Theor.(1957/1982).&amp;lt;/ref&amp;gt;. Особую популярность приобрел после публикации работы &amp;lt;i&amp;gt;МакКуина&amp;lt;/i&amp;gt;&amp;lt;ref&amp;gt;MacQueen, James. &amp;quot;Some methods for classification and analysis of multivariate observations.&amp;quot; Proceedings of the fifth Berkeley symposium on mathematical statistics and probability. Vol. 1. No. 14. 1967.&amp;lt;/ref&amp;gt; в 1967.&lt;br /&gt;
&lt;br /&gt;
Алгоритм представляет собой версию EM-алгоритма&amp;lt;ref&amp;gt;&amp;quot;https://ru.wikipedia.org/wiki/EM-алгоритм&amp;quot;&amp;lt;/ref&amp;gt;, применяемого также для разделения смеси гауссиан. Основная идея &amp;lt;i&amp;gt;k means&amp;lt;/i&amp;gt; заключается в том, что данные произвольно разбиваются на кластеры, после чего итеративно перевычисляется центр масс для каждого кластера, полученного на предыдущем шаге, затем векторы разбиваются на кластеры вновь в соответствии с тем, какой из новых центров оказался ближе по выбранной метрике.&lt;br /&gt;
&lt;br /&gt;
Цель алгоритма заключается в разделении &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; наблюдений на &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластеров таким образом, чтобы каждое наблюдение принадлежало ровно одному кластеру, расположенному на наименьшем расстоянии от наблюдения.&lt;br /&gt;
&lt;br /&gt;
=== Математическое описание алгоритма ===&lt;br /&gt;
&amp;lt;b&amp;gt;&amp;lt;u&amp;gt;Дано:&amp;lt;/u&amp;gt;&amp;lt;/b&amp;gt;&lt;br /&gt;
* набор из &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; наблюдений &amp;lt;math&amp;gt;X=\{\mathbf{x}_1, \mathbf{x}_2, ..., \mathbf{x}_n\}, \mathbf{x}_i \in \mathbb{R}^d, i=\overline{1, n}&amp;lt;/math&amp;gt;;&lt;br /&gt;
* &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; - требуемое число кластеров, &amp;lt;math&amp;gt;k \in \mathbb{N}, k \leq n&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;&amp;lt;u&amp;gt;Требуется:&amp;lt;/u&amp;gt;&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Разделить множество наблюдений &amp;lt;math&amp;gt;X&amp;lt;/math&amp;gt; на &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластеров &amp;lt;math&amp;gt;S_1, S_2, ..., S_k&amp;lt;/math&amp;gt;:&lt;br /&gt;
*   &amp;lt;math&amp;gt;S_i \cap S_j= \varnothing, \quad i \ne j&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
*   &amp;lt;math&amp;gt;\bigcup_{i=1}^{k} S_i = X&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;&amp;lt;u&amp;gt;Действие алгоритма:&amp;lt;/u&amp;gt;&amp;lt;/b&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;Алгоритм &amp;lt;i&amp;gt;k means&amp;lt;/i&amp;gt; разбивает набор &amp;lt;math&amp;gt;X&amp;lt;/math&amp;gt; на &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; наборов &amp;lt;math&amp;gt;S_1, S_2, ..., S_k,&amp;lt;/math&amp;gt; таким образом, чтобы минимизировать сумму квадратов расстояний от каждой точки кластера до его центра (центр масс кластера). Введем обозначение, &amp;lt;math&amp;gt;S=\{S_1, S_2, ..., S_k\}&amp;lt;/math&amp;gt;. Тогда действие алгоритма &amp;lt;i&amp;gt;k means&amp;lt;/i&amp;gt; равносильно поиску:&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;table style=&amp;quot;width:100%&amp;quot;&amp;gt;&lt;br /&gt;
  &amp;lt;tr&amp;gt;&lt;br /&gt;
    &amp;lt;td align=&amp;quot;center&amp;quot; width=&amp;quot;90%&amp;quot;&amp;gt;&amp;lt;math&amp;gt;\arg\min_{S} \sum\limits_{i=1}^k \sum\limits_{\mathbf{x} \in S_i} \rho(\mathbf{x}, \mathbf{\mu}_i )^2,&amp;lt;/math&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;td align=&amp;quot;right&amp;quot;&amp;gt;&amp;lt;math&amp;gt;(1)&amp;lt;/math&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;/table&amp;gt;&lt;br /&gt;
где &amp;lt;math&amp;gt;\mathbf{\mu}_i&amp;lt;/math&amp;gt; &amp;amp;ndash; центры кластеров, &amp;lt;math&amp;gt;i=\overline{1,k}, \quad \rho(\mathbf{x}, \mathbf{\mu}_i)&amp;lt;/math&amp;gt; &amp;amp;ndash; функция расстояния между &amp;lt;math&amp;gt;\mathbf{x}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\mu_i&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;&amp;lt;u&amp;gt;Шаги алгоритма: &amp;lt;/u&amp;gt;&amp;lt;/b&amp;gt;&lt;br /&gt;
&amp;lt;ol&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&lt;br /&gt;
    &amp;lt;b&amp;gt;Начальный шаг: инициализация кластеров&amp;lt;/b&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;Выбирается произвольное множество точек &amp;lt;math&amp;gt;\mu_i, i=\overline{1,k}&amp;lt;/math&amp;gt;, рассматриваемых как начальные центры кластеров: &amp;lt;math&amp;gt;\mu_i^{(0)} = \mu_i, \quad i=\overline{1, k}&amp;lt;/math&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
  &amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&lt;br /&gt;
    &amp;lt;b&amp;gt;Распределение векторов по кластерам&amp;lt;/b&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Шаг&amp;lt;/b&amp;gt; &amp;lt;math&amp;gt;t: \forall \mathbf{x}_i \in X, i=\overline{1,n}: \mathbf{x}_i \in S_j \iff  j=\arg\min_{k}\rho(\mathbf{x}_i,\mathbf{\mu}_k^{(t-1)})^2&amp;lt;/math&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
  &amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&lt;br /&gt;
    &amp;lt;b&amp;gt;Пересчет центров кластеров&amp;lt;/b&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Шаг &amp;lt;/b&amp;gt; &amp;lt;math&amp;gt;t: \forall i=\overline{1,k}:  \mu_i^{(t)} = \cfrac{1}{|S_i|}\sum_{\mathbf{x}\in S_i}\mathbf{x}&amp;lt;/math&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
  &amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&lt;br /&gt;
    &amp;lt;b&amp;gt;Проверка условия останова:&amp;lt;/b&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
    &#039;&#039;&#039;if&#039;&#039;&#039; &amp;lt;math&amp;gt;\exist i\in \overline{1,k}: \mu_i^{(t)} \ne \mu_i^{(t-1)}&amp;lt;/math&amp;gt; &#039;&#039;&#039;then&#039;&#039;&#039;&lt;br /&gt;
        t = t + 1;&lt;br /&gt;
        goto 2;&lt;br /&gt;
    &#039;&#039;&#039;else&#039;&#039;&#039;&lt;br /&gt;
        &#039;&#039;&#039;stop&#039;&#039;&#039;&lt;br /&gt;
  &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ol&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Вычислительное ядро алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Вычислительным ядром являются шаги 2 и 3 приведенного выше алгоритма: &amp;lt;b&amp;gt;&amp;lt;i&amp;gt;распределение векторов по кластерам&amp;lt;/i&amp;gt;&amp;lt;/b&amp;gt; и &amp;lt;b&amp;gt;&amp;lt;i&amp;gt;пересчет центров кластеров&amp;lt;/i&amp;gt;&amp;lt;/b&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;&amp;lt;i&amp;gt;Распределение векторов&amp;lt;/i&amp;gt;&amp;lt;/b&amp;gt; по кластерам предполагает вычисление расстояний между каждым вектором &amp;lt;math&amp;gt;\mathbf{x}_i \in X, i= \overline{1,n}&amp;lt;/math&amp;gt; и центрами кластера &amp;lt;math&amp;gt;\mathbf{\mu}_j, j= \overline{1,k}&amp;lt;/math&amp;gt;. Таким образом, данный шаг предполагает &amp;lt;math&amp;gt;k*n&amp;lt;/math&amp;gt; вычислений расстояний между d-мерными векторами. &lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;&amp;lt;i&amp;gt;Пересчет центров кластеров&amp;lt;/i&amp;gt;&amp;lt;/b&amp;gt; предполагает &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; вычислений центров масс &amp;lt;math&amp;gt;\mathbf{\mu}_i&amp;lt;/math&amp;gt; множеств &amp;lt;math&amp;gt;S_i, i=\overline{1,k}&amp;lt;/math&amp;gt; представленных выражением в шаге 3 представленного выше алгоритма.&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Макроструктура алгоритма ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Инициализация центров масс &amp;lt;math&amp;gt;\mu_1, ..., \mu_k&amp;lt;/math&amp;gt;&amp;lt;/b&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
Наиболее распространенными являются следующие стратегии:&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&lt;br /&gt;
    &amp;lt;b&amp;gt;Метод Forgy&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;В качестве начальных значений &amp;lt;math&amp;gt;\mu_1, ..., \mu_k&amp;lt;/math&amp;gt; берутся случайно выбранные векторы.&lt;br /&gt;
  &amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&lt;br /&gt;
    &amp;lt;b&amp;gt;Метод случайно разделения (Random Partitioning)&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;Для каждого вектора &amp;lt;math&amp;gt;\mathbf{x}_i \in X, i=\overline{1, n}&amp;lt;/math&amp;gt; выбирается случайным образом кластер &amp;lt;math&amp;gt;S_1, ..., S_k&amp;lt;/math&amp;gt;, после чего для каждого полученного кластера вычисляются значения &amp;lt;math&amp;gt;\mu_1, ..., \mu_k&amp;lt;/math&amp;gt;.&lt;br /&gt;
  &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Распределение векторов по кластерам&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Для этого шага алгоритма между векторами &amp;lt;math&amp;gt;\mathbf{x}_i \in X, i=\overline{1, n}&amp;lt;/math&amp;gt; и центрами кластеров &amp;lt;math&amp;gt;\mu_1, ..., \mu_k&amp;lt;/math&amp;gt; вычисляются &amp;lt;b&amp;gt;расстояния&amp;lt;/b&amp;gt; по формуле (как правило, используется Евлидово расстояние):&lt;br /&gt;
&amp;lt;table style=&amp;quot;width:100%&amp;quot;&amp;gt;&lt;br /&gt;
  &amp;lt;tr&amp;gt;&lt;br /&gt;
    &amp;lt;td align=&amp;quot;center&amp;quot; width=&amp;quot;90%&amp;quot;&amp;gt;&amp;lt;math&amp;gt; \mathbf{v}_1, \mathbf{v}_2 \in \mathbb{R}^d,  \quad \rho(\mathbf{v}_1, \mathbf{v}_2) = \lVert \mathbf{v}_1- \mathbf{v}_2 \rVert= \sqrt{\sum_{i=1}^{d}(\mathbf{v}_{1,i} - \mathbf{v}_{2,i})^2}&amp;lt;/math&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;td align=&amp;quot;right&amp;quot;&amp;gt;&amp;lt;math&amp;gt;(2)&amp;lt;/math&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;/table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Пересчет центров кластеров&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Для этого шага алгоритма производится пересчет центров кластера по &amp;lt;b&amp;gt;формуле вычисления центра масс&amp;lt;/b&amp;gt;:&lt;br /&gt;
&amp;lt;table style=&amp;quot;width:100%&amp;quot;&amp;gt;&lt;br /&gt;
  &amp;lt;tr&amp;gt;&lt;br /&gt;
    &amp;lt;td align=&amp;quot;center&amp;quot; width=&amp;quot;90%&amp;quot;&amp;gt;&amp;lt;math&amp;gt; \mu = \cfrac{1}{|S|}\sum_{\mathbf{x}\in S}\mathbf{x}&amp;lt;/math&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;td align=&amp;quot;right&amp;quot;&amp;gt;&amp;lt;math&amp;gt;(3)&amp;lt;/math&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;/table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Схема реализации последовательного алгоритма ===&lt;br /&gt;
&lt;br /&gt;
 &#039;&#039;&#039;algorithm&#039;&#039;&#039; k-means &#039;&#039;&#039;is&#039;&#039;&#039;&lt;br /&gt;
     &#039;&#039;&#039;1.&#039;&#039;&#039; Инициализировать центры кластеров &amp;lt;math&amp;gt;\mathbf{\mu}_i^{(1)}, i=\overline{1,k}&amp;lt;/math&amp;gt;&lt;br /&gt;
     &#039;&#039;&#039;2.&#039;&#039;&#039; &amp;lt;math&amp;gt;t \leftarrow 1&amp;lt;/math&amp;gt;&lt;br /&gt;
     &#039;&#039;&#039;3.&#039;&#039;&#039; &#039;&#039;&#039;Распределение по кластерам&#039;&#039;&#039;&amp;lt;br&amp;gt;&lt;br /&gt;
        &amp;lt;math&amp;gt;S_i^{(t)}=\{\mathbf{x}_p: \lVert\mathbf{x}_p-\mathbf{\mu}_i^{(t)}\rVert^2 \leq \lVert\mathbf{x}_p-\mathbf{\mu}_j^{(t)}\rVert^2 \quad \forall j=\overline{1,k}\},&amp;lt;/math&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
        где каждый вектор &amp;lt;math&amp;gt;\mathbf{x}_p&amp;lt;/math&amp;gt; соотносится единственному кластеру &amp;lt;math&amp;gt;S^{(t)}&amp;lt;/math&amp;gt;&lt;br /&gt;
     &#039;&#039;&#039;4.&#039;&#039;&#039; &#039;&#039;&#039;Обновление центров кластеров&#039;&#039;&#039;&amp;lt;br&amp;gt;&lt;br /&gt;
        &amp;lt;math&amp;gt;\mathbf{\mu}_i^{(t+1)} = \frac{1}{|S^{(t)}_i|} \sum_{\mathbf{x}_j \in S^{(t)}_i} \mathbf{x}_j &amp;lt;/math&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
     &#039;&#039;&#039;5.&#039;&#039;&#039; &#039;&#039;&#039;if&#039;&#039;&#039; &amp;lt;math&amp;gt;\exist i \in \overline{1,k}: \mathbf{\mu}_i^{(t+1)} \ne \mathbf{\mu}_i^{(t)}&amp;lt;/math&amp;gt; &#039;&#039;&#039;then&#039;&#039;&#039;&lt;br /&gt;
            t = t + 1;&lt;br /&gt;
            goto &#039;&#039;&#039;3&#039;&#039;&#039;;&lt;br /&gt;
        &#039;&#039;&#039;else&#039;&#039;&#039;&lt;br /&gt;
            &#039;&#039;&#039;stop&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
=== Последовательная сложность алгоритма===&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding-bottom: 20px&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;Обозначим &amp;lt;math&amp;gt;\Theta_{centroid}^{d, m}&amp;lt;/math&amp;gt; временную сложность вычисления центорида кластера, число элементов которого равна &amp;lt;math&amp;gt;m&amp;lt;/math&amp;gt;,  в d-мерном пространстве.&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;Аналогично  &amp;lt;math&amp;gt;\Theta_{distance}^d&amp;lt;/math&amp;gt; &amp;amp;ndash; временная сложность вычисления расстояния между двумя d-мерными векторами.&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding-bottom: 20px&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;Сложность шага инициализации &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластеров мощности &amp;lt;math&amp;gt;m&amp;lt;/math&amp;gt; в d-мерном пространстве &amp;amp;ndash; &amp;lt;math&amp;gt;\Theta_{init}^{k, d, m}&amp;lt;/math&amp;gt;&amp;lt;/b&amp;gt;&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;i&amp;gt;Стратерия Forgy&amp;lt;/i&amp;gt;: вычисления не требуются, &amp;lt;math&amp;gt;\Theta_{init}^{k, d, m} = 0&amp;lt;/math&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;i&amp;gt;Стратегия случайного разбиения&amp;lt;/i&amp;gt;: вычисление центров &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластеров,  &amp;lt;math&amp;gt;\Theta_{init}^{k, d, m} = k*\Theta_{centroid}^{d, m}, m \le n&amp;lt;/math&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding-bottom: 20px&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Cложность шага распределения d мерных векторов по &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластерам &amp;amp;ndash; &amp;lt;math&amp;gt;\Theta_{distribute}^{k, d}&amp;lt;/math&amp;gt;&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
На этом шаге для каждого вектора &amp;lt;math&amp;gt;\mathbf{x}_i \in X, i=\overline{1, n}&amp;lt;/math&amp;gt; вычисляется k расстояний до центров кластеров &amp;lt;math&amp;gt;\mathbf{\mu}_1, ...\mathbf{\mu}_k&amp;lt;/math&amp;gt;&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p align=&amp;quot;center&amp;quot;&amp;gt;&lt;br /&gt;
  &amp;lt;math&amp;gt;\Theta_{distribute}^{k, d} = n*k*\Theta_{distance}^d&amp;lt;/math&amp;gt;&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding-bottom: 20px&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;Сложность шага пересчета центров &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластеров размера &amp;lt;math&amp;gt;m&amp;lt;/math&amp;gt; в d-мерном пространстве &amp;amp;ndash; &amp;lt;math&amp;gt;\Theta_{recenter}^{k, d, m}&amp;lt;/math&amp;gt;&amp;lt;/b&amp;gt;&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;На этом шаге вычисляется &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; центров кластеров &amp;lt;math&amp;gt;\mathbf{\mu}_1, ...\mathbf{\mu}_k&amp;lt;/math&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p align=&amp;quot;center&amp;quot;&amp;gt;&amp;lt;math&amp;gt;\Theta_{recenter}^{k, d, m} = k*\Theta_{centroid}^{d, m}&amp;lt;/math&amp;gt; &amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding-bottom: 20px&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Рассчитаем &amp;lt;math&amp;gt;\Theta_{centroid}^{d, m}&amp;lt;/math&amp;gt; для кластера, число элементов которого равно &amp;lt;math&amp;gt;m&amp;lt;/math&amp;gt;&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p align=&amp;quot;center&amp;quot;&amp;gt;&amp;lt;math&amp;gt;\Theta_{centroid}^{d, m}&amp;lt;/math&amp;gt; = &amp;lt;math&amp;gt;m * d&amp;lt;/math&amp;gt; сложений + &amp;lt;math&amp;gt;d&amp;lt;/math&amp;gt; делений &amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding-bottom: 20px&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Рассчитаем &amp;lt;math&amp;gt;\Theta_{distance}^d&amp;lt;/math&amp;gt; в соответствие с формулой &amp;lt;math&amp;gt;(2)&amp;lt;/math&amp;gt;&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p align=&amp;quot;center&amp;quot;&amp;gt;&amp;lt;math&amp;gt;\Theta_{distance}^d&amp;lt;/math&amp;gt; = &amp;lt;math&amp;gt;d&amp;lt;/math&amp;gt; вычитаний + &amp;lt;math&amp;gt;d&amp;lt;/math&amp;gt; умножений + &amp;lt;math&amp;gt;(d-1)&amp;lt;/math&amp;gt; сложение&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding-bottom: 20px&amp;quot;&amp;gt;&lt;br /&gt;
  &amp;lt;p&amp;gt;Предположим, что алгоритм сошелся за &amp;lt;math&amp;gt;\Tau&amp;lt;/math&amp;gt; итераций, тогда временная сложность алгоритма &amp;lt;math&amp;gt;\Theta_{k-means}^{d, n}&amp;lt;/math&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
  &amp;lt;p align=&amp;quot;center&amp;quot;&amp;gt;&amp;lt;b&amp;gt;&amp;lt;math&amp;gt;\Theta_{k-means}^{d, n} \le \Theta_{init}^{k, d, n} + \Tau*(\Theta_{distribute}^{k, d} + \Theta_{recenter}^{k, d, n})&amp;lt;/math&amp;gt;&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding-bottom: 5px&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;Операции сложения/вычитания:&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p align=&amp;quot;center&amp;quot;&amp;gt;&amp;lt;b&amp;gt;&amp;lt;math&amp;gt;\Theta_{k-means}^{d, n} \le k*n*d+ \Tau*(k*n*(2d-1) + k*n*d) = k*n*d+ \Tau*(k*n*(3d-1)) \thicksim O(\Tau*k*d*n)&amp;lt;/math&amp;gt;&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding-bottom: 20px&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;Операции умножения/деления:&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p align=&amp;quot;center&amp;quot;&amp;gt;&amp;lt;b&amp;gt;&amp;lt;math&amp;gt;\Theta_{k-means}^{d, n} \le k*d + \Tau*(k*n*d + k*d) = k*d + \Tau * k*d*(n+1) \thicksim O(\Tau*k*d*n) &amp;lt;/math&amp;gt;&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding-bottom: 20px&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;Получаем, что &amp;lt;b&amp;gt;временная сложность&amp;lt;/b&amp;gt; алгоритма &amp;lt;b&amp;gt;k means&amp;lt;/b&amp;gt; кластеризации &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; &amp;lt;b&amp;gt;d-мерных&amp;lt;/b&amp;gt; векторов на &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластеров за &amp;lt;math&amp;gt;\Tau&amp;lt;/math&amp;gt; итераций:&amp;lt;/p&amp;gt;&lt;br /&gt;
 &amp;lt;p align=&amp;quot;center&amp;quot;&amp;gt;&amp;lt;b&amp;gt;&amp;lt;math&amp;gt; \Theta_{k-means}^{d, n} \thicksim O(\Tau*k*d*n) &amp;lt;/math&amp;gt;&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Информационный граф ===&lt;br /&gt;
&lt;br /&gt;
Рассмотрим информационный граф алгоритма. Алгоритм &amp;lt;i&amp;gt;k means&amp;lt;/i&amp;gt; начинается с этапа инициализации, после которого следуют итерации, на каждой из которых выполняется два последовательных шага (см. [[#Схема реализации последовательного алгоритма|&amp;quot;Схема реализации последовательного алгоритма&amp;quot;]]): &lt;br /&gt;
* распределение векторов по кластерам&lt;br /&gt;
* перерасчет центров кластеров&lt;br /&gt;
&lt;br /&gt;
Поскольку основная часть вычислений приходится на шаги итераций, распишем информационные графы данных шагов.&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Распределение векторов по кластерам&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
Информационный граф шага распределения векторов по кластерам представлен на &#039;&#039;рисунке 1&#039;&#039;. Исходами данного графа является исходные векторы &amp;lt;math&amp;gt;\mathbf{x}_1, ..., \mathbf{x}_n&amp;lt;/math&amp;gt;, а также центры кластеров &amp;lt;math&amp;gt;\mathbf{\mu}_1, ... \mathbf{\mu}_k&amp;lt;/math&amp;gt;, вычисленные ранее (на шаге инициализации, если рассматривается первая итерация алгоритма, или на шаге пересчета центров кластеров предыдущей итерации в противном случае). Каждая пара векторов данных &amp;lt;math&amp;gt;\mathbf{x}_i, i=\overline{1,n}&amp;lt;/math&amp;gt; и центров кластера &amp;lt;math&amp;gt;\mathbf{\mu}_j, j=\overline{1, k}&amp;lt;/math&amp;gt; : (&amp;lt;math&amp;gt;\mathbf{x}_i&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;\mathbf{\mu}_j&amp;lt;/math&amp;gt;) подаются на независимые узлы &amp;lt;i&amp;gt;&amp;quot;d&amp;quot;&amp;lt;/i&amp;gt; вычисления расстояния между векторами (более подробная схема вычисления расстояния представлена далее, &#039;&#039;рисунок 2&#039;&#039;). Далее узлы вычисления расстояния &amp;lt;i&amp;gt;&amp;quot;d&amp;quot;&amp;lt;/i&amp;gt;, соответствующие одному и тому же исходному вектору &amp;lt;math&amp;gt;\mathbf{x}_i&amp;lt;/math&amp;gt; передаются на один узел &amp;lt;i&amp;gt;&amp;quot;m&amp;quot;&amp;lt;/i&amp;gt;, где далее происходит вычисление новой метки кластера для каждого вектора &amp;lt;math&amp;gt;\mathbf{x}_i&amp;lt;/math&amp;gt; (берется кластер с минимальным результатом вычисления расстояния). На выходе графа выдаются метки кластеров , &amp;lt;math&amp;gt;L_1, ..., L_n&amp;lt;/math&amp;gt;, такие что &amp;lt;math&amp;gt;\forall \mathbf{x}_i, i=\overline{1, n}, \mathbf{x}_i \in S_j \Leftrightarrow L_i = j&amp;lt;/math&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
[[file:Clusterization.png|thumb|center|800px|Рис. 1. Схема распределения векторов по кластерам. &#039;&#039;d&#039;&#039; &amp;amp;ndash; вычисление расстояния между векторами; &#039;&#039;m&#039;&#039; &amp;amp;ndash; вычисление минимума.]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Вычисление расстояния между векторами&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
Подробная схема вычисления расстояния между векторами &amp;lt;math&amp;gt;\mathbf{x}_i, \mathbf{\mu}_j&amp;lt;/math&amp;gt; представлена на &#039;&#039;рисунке 2&#039;&#039;. Как показано на графе, узел вычисления расстояния между векторами &amp;lt;i&amp;gt;&amp;quot;d&amp;quot;&amp;lt;/i&amp;gt; состоит из шага взятия разности между векторами (узел &amp;quot;&amp;lt;math&amp;gt;-&amp;lt;/math&amp;gt;&amp;quot;) и взятия нормы получившегося вектора разности (узел &amp;quot;&amp;lt;math&amp;gt;||\cdot||^2&amp;lt;/math&amp;gt;&amp;quot;). Более подробно, вычисление расстояния между векторами &amp;lt;math&amp;gt;\mathbf{x}_i = {x_{i1,}, ...,{x_{in}}}, \mathbf{\mu}_j = {\mu_{j1}, ...,\mu_{jn}}&amp;lt;/math&amp;gt; может быть представлено как вычисление разности между каждой парой компонент &amp;lt;math&amp;gt;(x_{iz}, \mu_{jz}), z=\overline{1, d}&amp;lt;/math&amp;gt; (узел &amp;quot;&amp;lt;math&amp;gt;-&amp;lt;/math&amp;gt;&amp;quot;), далее возведение в квадрат для каждого узла &amp;quot;&amp;lt;math&amp;gt;-&amp;lt;/math&amp;gt;&amp;quot; (узел &amp;quot;&amp;lt;math&amp;gt;()^2&amp;lt;/math&amp;gt;&amp;quot;) и суммирования выходов всех узлов &amp;quot;&amp;lt;math&amp;gt;()^2&amp;lt;/math&amp;gt;&amp;quot; (узел &amp;quot;&amp;lt;math&amp;gt;+&amp;lt;/math&amp;gt;&amp;quot;).  &lt;br /&gt;
&lt;br /&gt;
[[file:dist_calc.png|thumb|center|800px|Рис. 2. Схема вычисления расстояния между вектором и центром кластера.]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Пересчет центров кластеров&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
Информационный граф шага пересчета центров кластеров представлен на &#039;&#039;рисунке 3&#039;&#039;. Исходами данного графа является исходные векторы &amp;lt;math&amp;gt;\mathbf{x}_1, ..., \mathbf{x}_n&amp;lt;/math&amp;gt;, а также им соответствующие метки кластера, &amp;lt;math&amp;gt;L_1, ..., L_n&amp;lt;/math&amp;gt;, такие что &amp;lt;math&amp;gt;\forall x_i, i=\overline{1, n}, \mathbf{x}_i \in S_j \Leftrightarrow L_i = j&amp;lt;/math&amp;gt;, вычисленные на этапе распределения векторов по кластерам. Все векторы &amp;lt;math&amp;gt;\mathbf{x}_1, ..., \mathbf{x}_n&amp;lt;/math&amp;gt; подаются в узлы &amp;lt;math&amp;gt;+_1, ...+_k&amp;lt;/math&amp;gt;, каждый узел &amp;lt;math&amp;gt;+_m, m = \overline{1,k}&amp;lt;/math&amp;gt; соответствует операции сложения векторов кластера с номером &amp;lt;math&amp;gt;m&amp;lt;/math&amp;gt;. Метки кластера &amp;lt;math&amp;gt;L_1, ..., L_n&amp;lt;/math&amp;gt; также совместно передаются на узлы &amp;lt;math&amp;gt;S_m, m = \overline{1,k}&amp;lt;/math&amp;gt;, на каждом из которых вычисляется количество векторов в соответствующем кластере (количество меток с соответствующим значением). Далее каждая пара выходов узлов &amp;lt;math&amp;gt;+_m&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;S_m&amp;lt;/math&amp;gt; подается на узел &amp;quot;&amp;lt;math&amp;gt;/&amp;lt;/math&amp;gt;&amp;quot;, где производится деление суммы векторов кластера на количество элементов в нем. Значения, вычисленные на узлах &amp;quot;&amp;lt;math&amp;gt;/&amp;lt;/math&amp;gt;&amp;quot;, присваиваются новым центрам кластеров (выходные значения графа).&lt;br /&gt;
&lt;br /&gt;
[[file:Recluster.png|thumb|center|800px|Рис. 3. Схема пересчета центров кластеров]]&lt;br /&gt;
&lt;br /&gt;
=== Ресурс параллелизма алгоритма ===&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
Работа алгоритма состоит из &amp;lt;math&amp;gt;\Tau&amp;lt;/math&amp;gt; итераций, в каждой из которых происходит &amp;lt;b&amp;gt;распределение d-мерных векторов по &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластерам&amp;lt;/b&amp;gt;, а также &amp;lt;b&amp;gt;пересчет центров кластеров в d-мерном пространстве&amp;lt;/b&amp;gt;. В шаге &amp;lt;b&amp;gt;распределения d-мерных векторов по &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластерам&amp;lt;/b&amp;gt; расстояния между вектором и центрами кластеров вычисляются независимо (отсутствуют информационные зависимости). &amp;lt;b&amp;gt;Центры масс кластеров&amp;lt;/b&amp;gt; также пересчитываются независимо друг от друга. Таким образом, имеет место [[глоссарий#Массовый параллелизм|&#039;&#039;массовый параллелизм&#039;&#039;]]. Вычислим параллельную сложность &amp;lt;math&amp;gt;\Psi_*&amp;lt;/math&amp;gt; каждого из шагов, а также параллельную сложность всего алгоритма, &amp;lt;math&amp;gt;\Psi_{k-means}&amp;lt;/math&amp;gt;. Будем исходить из предположения, что может быть использовано любое необходимое число потоков.&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Распределение d-мерных векторов по &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластерам&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;  &lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
Поскольку на данном шаге для каждой пары векторов &amp;lt;math&amp;gt;\mathbf{x}_i, i=\overline{1,n}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\mathbf{\mu}_j, j=\overline{1,k}&amp;lt;/math&amp;gt; операции вычисления расстояния не зависят друг от друга, они могут выполняться параллельно. Тогда, разделив все вычисление расстояний на &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; потоков, получим, что в каждом потоке будет выполняться только одна операция вычисления расстояния между векторами размерности d. При этом каждому вычислительному потоку передаются координаты центров всех кластеров &amp;lt;math&amp;gt;\mathbf{\mu}_1, ..., \mathbf{\mu}_k&amp;lt;/math&amp;gt;. Таким образом, параллельная сложность данного шага определяется &amp;lt;i&amp;gt; сложностью параллельной операции вычисления расстояния между d-мерными векторами&amp;lt;/i&amp;gt;, &amp;lt;math&amp;gt;\Psi_{distance}^d&amp;lt;/math&amp;gt;  и &amp;lt;i&amp;gt;сложностью определения наиболее близкого кластера&amp;lt;/i&amp;gt; (паралельное взятие минимума по расстояниям), &amp;lt;math&amp;gt;\Psi_{min}^k&amp;lt;/math&amp;gt;. Для оценки &amp;lt;math&amp;gt;\Psi_{distance}^d&amp;lt;/math&amp;gt; воспользуемся  [[Нахождение_частных_сумм_элементов_массива_сдваиванием | параллельной реализацией нахождения частичной суммы элементов массива путем сдваивания]]. Аналогично, &amp;lt;math&amp;gt;\Psi_{min}^k = log(k)&amp;lt;/math&amp;gt;. В результате, &amp;lt;math&amp;gt;\Psi_{distance}^d = O(log(d))&amp;lt;/math&amp;gt;.   Таким образом: &lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p align=&amp;quot;center&amp;quot;&amp;gt;&amp;lt;math&amp;gt;\Psi_{distribute}^{k, d}  = \Psi_{distance}^d + \Psi_{min}^k = O(log(d))+O(log(k)) = O(log(k*d))&amp;lt;/math&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Пересчет центров кластеров в d-мерном пространстве&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
Поскольку на данном шаге для каждого из &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластеров центр масс может быть вычислен независимо, данные операции могут быть выполнены в отдельных потоках. Таким образом, параллельная сложность данного шага, &amp;lt;math&amp;gt;\Psi_{recenter}^{k, d}&amp;lt;/math&amp;gt;,  будет определяться &amp;lt;i&amp;gt;параллельной сложностью вычисления одного центра масс кластера размера &amp;lt;math&amp;gt;m&amp;lt;/math&amp;gt;&amp;lt;/i&amp;gt;, &amp;lt;math&amp;gt;\Psi_{recenter}^{k, d}&amp;lt;/math&amp;gt;,  а так как &amp;lt;math&amp;gt;m \le n \Rightarrow \Psi_{recenter}^{d, m} \le \Psi_{recenter}^{d, n}&amp;lt;/math&amp;gt;. Сложность вычисления центра масс кластера d-мерных векторов размера n аналогично предыдущим вычислениям равна &amp;lt;math&amp;gt;O(log(n))&amp;lt;/math&amp;gt;. Тогда:  &lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p align=&amp;quot;center&amp;quot;&amp;gt;&amp;lt;math&amp;gt;\Psi_{recenter}^{k, d}  \le \Psi_{recenter}^{d, n} = O(log(n))&amp;lt;/math&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Общая параллельная сложность алгоритма&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
На каждой итерации необходимо обновление центров кластеров, которые будут использованы на следующей итерации. Таким образом, итерационный процесс выполняется последовательно&amp;lt;ref&amp;gt;Zhao, Weizhong, Huifang Ma, and Qing He. &amp;quot;Parallel k-means clustering based on mapreduce.&amp;quot; IEEE International Conference on Cloud Computing. Springer Berlin Heidelberg, 2009.&amp;lt;/ref&amp;gt;. Тогда, поскольку сложность каждой итерации  определяется &amp;lt;math&amp;gt;\Psi_{distribute}^{k, d}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\Psi_{recenter}&amp;lt;/math&amp;gt;, сложность всего алгоритма, &amp;lt;math&amp;gt;\Psi_{k-means}&amp;lt;/math&amp;gt; в предположении, что было сделано &amp;lt;math&amp;gt;\Tau&amp;lt;/math&amp;gt; операций определяется выражением&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p align=&amp;quot;center&amp;quot;&amp;gt;&amp;lt;math&amp;gt;\Psi_{k-means} \approx \Tau * (\Psi_{distribute}^{k, d} + \Psi_{recenter}^{k, d}) \le \Tau * O(log(k*d*n))&amp;lt;/math&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Входные и выходные данные алгоритма ===&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;Входные данные&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;Матрица из &amp;lt;math&amp;gt;n*d&amp;lt;/math&amp;gt; элементов &amp;lt;math&amp;gt;x_{i, j} \in \mathbb{R}, i=\overline{1, n}, j=\overline{1, d}&amp;lt;/math&amp;gt;&amp;amp;ndash; координат векторов (наблюдений).&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;Целое положительное число &amp;lt;math&amp;gt;k, k \le n&amp;lt;/math&amp;gt; &amp;amp;ndash; количество кластеров.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;Объем входных данных&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;math&amp;gt;1&amp;lt;/math&amp;gt; целое число + &amp;lt;math&amp;gt;n*d&amp;lt;/math&amp;gt; вещественных чисел (при условии, что координаты &amp;amp;ndash; вещественные числа).&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;Выходные данные&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; целых положительных чисел &amp;lt;math&amp;gt;L_1, ..., L_n&amp;lt;/math&amp;gt;&amp;amp;ndash; номера кластеров, соотвествующие каждому вектору (при условии, что нумерация кластеров начинается с &amp;lt;math&amp;gt;1&amp;lt;/math&amp;gt;).&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;Объем выходных данных&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; целых положительных чисел.&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Свойства алгоритма ===&lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;[[глоссарий#Вычислительная мощность|&#039;&#039;Вычислительная мощность&#039;&#039;]]&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
Вычислительная мощность алгоритма &amp;lt;i&amp;gt;k means&amp;lt;/i&amp;gt; равна &amp;lt;math&amp;gt;\frac{k*d*n*\Tau}{n*d} = k*\Tau &amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; &amp;amp;ndash; число кластеров, &amp;lt;math&amp;gt;\Tau&amp;lt;/math&amp;gt; &amp;amp;ndash; число итераций алгоритма.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;[[глоссарий#Детерминированность |&#039;&#039;Детерминированность&#039;&#039;]] и [[глоссарий#Устойчивость |&#039;&#039;Устойчивость&#039;&#039;]] &amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
Алгоритм &amp;lt;i&amp;gt;k means&amp;lt;/i&amp;gt; является итерационным. Количество итераций алгоритма в общем случае не фиксируется и зависит от начального расположения объектов в пространстве, параметра &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt;, а также от начального приближения центров кластеров, &amp;lt;math&amp;gt;\mu_1, ..., \mu_k&amp;lt;/math&amp;gt;. В результате этого может варьироваться результат работы алгоритма. При неудачном выборе начальных параметров итерационный процесс может сойтись к локальному оптимуму&amp;lt;ref&amp;gt;Von Luxburg, Ulrike. Clustering Stability. Now Publishers Inc, 2010.&amp;lt;/ref&amp;gt;. По этим причинам алгоритм не является ни &amp;lt;b&amp;gt;детермирированным&amp;lt;/b&amp;gt;, ни &amp;lt;b&amp;gt;устойчивым&amp;lt;/b&amp;gt;.&lt;br /&gt;
 &lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Соотношение последовательной и параллельной сложности алгоритма&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\frac{\Theta_{k-means}}{\Psi_{k-means}} = \frac{O(\Tau*k*d*n)}{O(\Tau*log(k*d*n))}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Сильные стороны алгоритма&amp;lt;/b&amp;gt;:&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;i&amp;gt;Сравнительно высокая эффективность при простоте реализации&amp;lt;/i&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;i&amp;gt;Высокое качество кластеризации&amp;lt;/i&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;i&amp;gt;Возможность распараллеливания&amp;lt;/i&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;i&amp;gt;Существование множества модификаций&amp;lt;/i&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;Недостатки алгоритма&amp;lt;/b&amp;gt;&amp;lt;ref&amp;gt;Ortega, Joaquín Pérez, Ma Del Rocío Boone Rojas, and María J. Somodevilla. &amp;quot;Research issues on K-means Algorithm: An Experimental Trial Using Matlab.&amp;quot;&amp;lt;/ref&amp;gt;:&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;i&amp;gt;Количество кластеров является параметром алгоритма&amp;lt;/i&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;&amp;lt;i&amp;gt;Чувствительность к начальным условиям&amp;lt;/i&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;Инициализация центров кластеров в значительной степени влияет на результат кластеризации.&amp;lt;/p&amp;gt;&lt;br /&gt;
  &amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;&amp;lt;i&amp;gt;Чувствительность к выбросам и шумам&amp;lt;/i&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;Выбросы, далекие от центров настоящих кластеров, все равно учитываются при вычислении их центров.&amp;lt;/p&amp;gt;&lt;br /&gt;
  &amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;&amp;lt;i&amp;gt;Возможность сходимости к локальному оптимуму&amp;lt;/i&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;Итеративный подход не дает гарантии сходимости к оптимальному решению.&amp;lt;/p&amp;gt;&lt;br /&gt;
  &amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;&amp;lt;i&amp;gt;Использование понятия &amp;quot;среднего&amp;quot;&amp;lt;/i&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;Алгоритм неприменим к данным, для которых не определено понятие &amp;quot;среднего&amp;quot;, например, категориальным данным.&amp;lt;/p&amp;gt;&lt;br /&gt;
  &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&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;
Исследование масштабируемости параллельной реализации алгоритма k means проводилось на суперкомпьютере &amp;quot;Ломоносов&amp;quot;. Алгоритм реализован на языке C с использованием средств MPI.&lt;br /&gt;
Для исследования масштабируемости проводилось множество запусков программы с разным значением параметра (количество векторов для кластеризации), а также с различным числом процессоров. Фиксировались результаты запусков &amp;amp;ndash; время работы &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt; и количество произведенных итераций алгоритма &amp;lt;math&amp;gt;\Tau&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Параметры запусков для экспериментальной оценки:&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;Значения &amp;lt;b&amp;gt;количества векторов&amp;lt;/b&amp;gt; &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;: 20&#039;000, 30&#039;000, 50&#039;000, 100&#039;000, 200&#039;000, 300&#039;000, 500&#039;000, 700&#039;000, 1&#039;000&#039;000, 1&#039;500&#039;000, 2&#039;000&#039;000.&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;Значения &amp;lt;b&amp;gt;количества процессоров&amp;lt;/b&amp;gt; &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt;: 1, 8, 16, 32, 64, 128, 160, 192, 224, 256, 288, 320, 352, 384, 416, 448, 480, 512.&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;Значение &amp;lt;b&amp;gt;количества кластеров&amp;lt;/b&amp;gt; &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt;: 100.&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;Значение &amp;lt;b&amp;gt;размерности векторов&amp;lt;/b&amp;gt; &amp;lt;math&amp;gt;d&amp;lt;/math&amp;gt;: 10.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Для проведения экспериментов были сгенерированы нормально распределенные псевдослучайные данные (с использованием Python библиотеки [http://scikit-learn.org/ scikit-learn]):&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
from sklearn.datasets import make_classification&lt;br /&gt;
X1, Y1 = make_classification(n_features=10, n_redundant=2, n_informative=8,&lt;br /&gt;
                             n_clusters_per_class=1, n_classes=100,&lt;br /&gt;
                             n_samples=2000000)&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Графики производительности и эффективности реализации представлены на рисунках 4 и 5 соответственно.&lt;br /&gt;
&lt;br /&gt;
[[file:Flops.png|thumb|center|800px|Рис. 4. График производительности реализации алгоритма.]]&lt;br /&gt;
&lt;br /&gt;
[[file:Efficiency.png|thumb|center|800px|Рис. 5. График эффективности реализации алгоритма.]]&lt;br /&gt;
&lt;br /&gt;
Для заданной конфигурации эксперимента (&amp;lt;math&amp;gt;n, d, p, k&amp;lt;/math&amp;gt;) и полученных результатах (&amp;lt;math&amp;gt;t, \Tau&amp;lt;/math&amp;gt;) производительность и эффективность реализации расчитывались по формулам (см. [[#Последовательная сложность алгоритма| последовательная сложность алгоритма]]):&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
&amp;lt;ul&amp;gt;&amp;lt;li&amp;gt;&amp;lt;math&amp;gt;Performance = \frac{\Theta_{k-means}^{d, n}}{t}\ \ FLOPS&amp;lt;/math&amp;gt;&amp;lt;/li&amp;gt;&amp;lt;/ul&amp;gt;&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
&amp;lt;ul&amp;gt;&amp;lt;li&amp;gt;&amp;lt;math&amp;gt;Efficiency = \frac{100 * Performance}{Performance_{Peak}^{p}}\ \ %,&amp;lt;/math&amp;gt;&amp;lt;/li&amp;gt;&amp;lt;/ul&amp;gt;&lt;br /&gt;
где &amp;lt;math&amp;gt;Performance_{Peak}^{p}&amp;lt;/math&amp;gt; &amp;amp;ndash; пиковая производительность суперкомпьютера при &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt; процессорах, вычисленная согласно спецификациям Intel&amp;lt;sup&amp;gt;&amp;amp;reg;&amp;lt;/sup&amp;gt; XEON&amp;lt;sup&amp;gt;&amp;amp;reg;&amp;lt;/sup&amp;gt; X5670&amp;lt;ref&amp;gt;&amp;quot;http://ark.intel.com/ru/products/47920/Intel-Xeon-Processor-X5670-12M-Cache-2_93-GHz-6_40-GTs-Intel-QPI&amp;quot;&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;В результате&amp;lt;/b&amp;gt; экспериментальной оценки были получены следующие оценки эффективности реализации:&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;b&amp;gt;Минимальное&amp;lt;/b&amp;gt; значение: 0.000409 % достигается при &amp;lt;math&amp;gt;n=20&#039;000, p=480&amp;lt;/math&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;b&amp;gt;Максимальное&amp;lt;/b&amp;gt; значение: 0.741119 % достигается при &amp;lt;math&amp;gt;n=300&#039;000, p=1&amp;lt;/math&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
Оценки масштабируемости реализации алгоритма k means:&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;b&amp;gt;По числу процессоров:&amp;lt;/b&amp;gt; -0.002683 &amp;amp;ndash; эффективность убывает с ростом числа процессоров.&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;b&amp;gt;По размеру задачи:&amp;lt;/b&amp;gt; 0.002779 &amp;amp;ndash; эффективность растет с ростом числа векторов.&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;b&amp;gt;Общая оценка:&amp;lt;/b&amp;gt; -0.000058 &amp;amp;ndash; можно сделать вывод, что в целом эффективность реализации незначительно уменьшается.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[https://github.com/serban/kmeans Использованная реализация алгоритма k means]&lt;br /&gt;
&lt;br /&gt;
=== Динамические характеристики и эффективность реализации алгоритма ===&lt;br /&gt;
=== Выводы для классов архитектур ===&lt;br /&gt;
=== Существующие реализации алгоритма ===&lt;br /&gt;
==== Открытое программное обеспечение ====&lt;br /&gt;
&amp;lt;ol&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;[https://www.icpsr.umich.edu/CrimeStat/ CrimeStat]&amp;lt;/li&amp;gt; Программное обеспечение, созданное для операционных систем Windows, предоставляющее инструменты статистического  и пространственного анализа для решения задачи картирования преступности.&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://juliastats.github.io Julia]&amp;lt;/li&amp;gt; Высокоуровневый высокопроизводительный свободный язык программирования с динамической типизацией, созданный для математических вычислений, содержит реализацию k-means.&lt;br /&gt;
  &amp;lt;li&amp;gt;[https://mahout.apache.org Mahout]&amp;lt;/li&amp;gt; Apache Mahout - Java библиотека для работы с алгоритмами машинного обучения с использованием MapReduce. Содержит реализацию k-means.&lt;br /&gt;
  &amp;lt;li&amp;gt;[https://www.gnu.org/software/octave/ Octave]&amp;lt;/li&amp;gt; Написанная на C++  свободная система для математических вычислений, использующая совместимый с MATLAB язык высокого уровня, содержит реализацию k-means.&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://spark.apache.org/docs/latest/mllib-clustering.html Spark]&amp;lt;/li&amp;gt; Распределенная реализация k-means содержится в библиотеке Mlib для работы с алгоритмами машинного обучения, взаимодействующая с Python библиотекой NumPy и библиотека R.&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://torch.ch Torch]&amp;lt;/li&amp;gt;  MATLAB-подобная библиотека для языка программирования Lua с открытым исходным кодом, предоставляет большое количество алгоритмов для глубинного обучения и научных расчётов. Ядро написано на Си, прикладная часть выполняется на LuaJIT, поддерживается распараллеливание вычислений средствами CUDA и OpenMP. Существуют реализации k-means.&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://www.cs.waikato.ac.nz/ml/weka/ Weka]&amp;lt;/li&amp;gt;  Cвободное программное обеспечение для анализа данных, написанное на Java. Содержит k-means и x-means.&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://accord-framework.net/docs/html/T_Accord_MachineLearning_KMeans.htm Accord.NET]&amp;lt;/li&amp;gt; C# реализация алгоритмов k-means, k-means++, k-modes.&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://docs.opencv.org/3.0-beta/doc/py_tutorials/py_ml/py_kmeans/py_kmeans_opencv/py_kmeans_opencv.html OpenCV]&amp;lt;/li&amp;gt; Написанная на С++ библиотека, направленная в основном на решение задач компьютерного зрения. Содержит реализацию k-means.&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://mlpack.org/ MLPACK]&amp;lt;/li&amp;gt; Масштабируемая С++ библиотека для работы с алгоритмами машинного обучения, содержит реализацию k-means.&lt;br /&gt;
  &amp;lt;li&amp;gt;[https://www.scipy.org/ SciPy]&amp;lt;/li&amp;gt; Библиотека Python, содержит множество реализаций k-means.&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://scikit-learn.org/ scikit-learn]&amp;lt;/li&amp;gt; Библиотека Python, содержит множество реализаций k-means.&lt;br /&gt;
  &amp;lt;li&amp;gt;[https://www.r-bloggers.com/k-means-clustering-in-r/ R]&amp;lt;/li&amp;gt; Язык программирования для статистической обработки данных и работы с графикой, а также свободная программная среда вычислений с открытым исходным кодом в рамках проекта GNU, содержит три реализации k-means.&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://elki.dbs.ifi.lmu.de ELKI]&amp;lt;/li&amp;gt; Java фреймворк, содержащий реализацию k-means, а также множество других алгоритмов кластеризации.&lt;br /&gt;
&amp;lt;/ol&amp;gt;&lt;br /&gt;
==== Проприетарное программное обеспечение  ====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ol&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;[https://www.ayasdi.com/blog/bigdata/topological-data-analysis-of-oil-and-gas-petrophysical-data/ Ayasdi]&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://www.stata.com/features/cluster-analysis/ Stata]&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://mathworld.wolfram.com/K-MeansClusteringAlgorithm.html Mathematica]&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://www.mathworks.com/help/stats/kmeans.html?requestedDomain=www.mathworks.com MATLAB]&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;[https://support.sas.com/rnd/app/stat/procedures/fastclus.html SAS]&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://docs.rapidminer.com/studio/operators/modeling/segmentation/k_means.html RapidMiner]&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;[https://blogs.sap.com/2013/03/28/sap-hana-pal-k-means-algorithm-or-how-to-do-customer-segmentation-for-the-telecommunications-industry/ SAP HANA]&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ol&amp;gt;&lt;br /&gt;
== Литература ==&lt;br /&gt;
&amp;lt;references /&amp;gt;&lt;/div&gt;</summary>
		<author><name>DennZo1993</name></author>
	</entry>
	<entry>
		<id>https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:%D0%91%D1%80%D0%BE%D1%82%D0%B8%D0%BA%D0%BE%D0%B2%D1%81%D0%BA%D0%B0%D1%8F_%D0%94%D0%B0%D0%BD%D1%83%D1%82%D0%B0/%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_k-means&amp;diff=17188</id>
		<title>Участник:Бротиковская Данута/Алгоритм k-means</title>
		<link rel="alternate" type="text/html" href="https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:%D0%91%D1%80%D0%BE%D1%82%D0%B8%D0%BA%D0%BE%D0%B2%D1%81%D0%BA%D0%B0%D1%8F_%D0%94%D0%B0%D0%BD%D1%83%D1%82%D0%B0/%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_k-means&amp;diff=17188"/>
		<updated>2016-11-15T01:57:16Z</updated>

		<summary type="html">&lt;p&gt;DennZo1993: /* Масштабируемость реализации алгоритма */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt; {{Assignment|Zhum}}&lt;br /&gt;
&lt;br /&gt;
{{algorithm&lt;br /&gt;
| name              = Алгоритм k средних (k means)&lt;br /&gt;
| serial_complexity = &amp;lt;math&amp;gt;O(\Tau*k*d*n)&amp;lt;/math&amp;gt;&lt;br /&gt;
| input_data        = &amp;lt;math&amp;gt; d*n &amp;lt;/math&amp;gt;&lt;br /&gt;
| output_data       = &amp;lt;math&amp;gt; n &amp;lt;/math&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
Авторы страницы &amp;lt;b&amp;gt;[[Участник:Бротиковская Данута|Данута Бротиковская]]&amp;lt;/b&amp;gt; и &amp;lt;b&amp;gt;[[Участник:DennZo1993|Денис Зобнин]]&amp;lt;/b&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
Оба автора внесли одинаковый вклад в написание статьи (поиск материалов, изучение статей, заполнение контента статьи), четких разграничений по пунктам статьи сделать невозможно. &lt;br /&gt;
&lt;br /&gt;
== Свойства и структура алгоритма ==&lt;br /&gt;
&lt;br /&gt;
=== Общее описание алгоритма ===&lt;br /&gt;
Алгоритм &amp;lt;b&amp;gt;&amp;lt;i&amp;gt;k средних&amp;lt;/i&amp;gt;&amp;lt;/b&amp;gt; (&amp;lt;b&amp;gt;&amp;lt;i&amp;gt;k means&amp;lt;/i&amp;gt;&amp;lt;/b&amp;gt;) &amp;amp;ndash; неиерархический&amp;lt;ref&amp;gt;&amp;quot;https://ru.wikipedia.org/wiki/Иерархическая_кластеризация&amp;quot;&amp;lt;/ref&amp;gt;, итерационный метод кластеризации&amp;lt;ref&amp;gt;&amp;quot;https://ru.wikipedia.org/wiki/Кластерный_анализ&amp;quot;&amp;lt;/ref&amp;gt;, получивший большую популярность благодаря своей простоте, наглядности реализации и достаточно высокому качеству работы. Был изобретен в 1950-х годах математиком &amp;lt;i&amp;gt;Гуго Штейнгаузом&amp;lt;/i&amp;gt;&amp;lt;ref&amp;gt;Steinhaus, Hugo. &amp;quot;Sur la division des corp materiels en parties.&amp;quot; Bull. Acad. Polon. Sci 1.804 (1956): 801.&amp;lt;/ref&amp;gt; и почти одновременно &amp;lt;i&amp;gt;Стюартом Ллойдом&amp;lt;/i&amp;gt;&amp;lt;ref&amp;gt;Lloyd, S. P. &amp;quot;Least square quantization in PCM. Bell Telephone Laboratories Paper. Published in journal much later: Lloyd, SP: Least squares quantization in PCM.&amp;quot; IEEE Trans. Inform. Theor.(1957/1982).&amp;lt;/ref&amp;gt;. Особую популярность приобрел после публикации работы &amp;lt;i&amp;gt;МакКуина&amp;lt;/i&amp;gt;&amp;lt;ref&amp;gt;MacQueen, James. &amp;quot;Some methods for classification and analysis of multivariate observations.&amp;quot; Proceedings of the fifth Berkeley symposium on mathematical statistics and probability. Vol. 1. No. 14. 1967.&amp;lt;/ref&amp;gt; в 1967.&lt;br /&gt;
&lt;br /&gt;
Алгоритм представляет собой версию EM-алгоритма&amp;lt;ref&amp;gt;&amp;quot;https://ru.wikipedia.org/wiki/EM-алгоритм&amp;quot;&amp;lt;/ref&amp;gt;, применяемого также для разделения смеси гауссиан. Основная идея &amp;lt;i&amp;gt;k means&amp;lt;/i&amp;gt; заключается в том, что данные произвольно разбиваются на кластеры, после чего итеративно перевычисляется центр масс для каждого кластера, полученного на предыдущем шаге, затем векторы разбиваются на кластеры вновь в соответствии с тем, какой из новых центров оказался ближе по выбранной метрике.&lt;br /&gt;
&lt;br /&gt;
Цель алгоритма заключается в разделении &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; наблюдений на &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластеров таким образом, чтобы каждое наблюдение принадлежало ровно одному кластеру, расположенному на наименьшем расстоянии от наблюдения.&lt;br /&gt;
&lt;br /&gt;
=== Математическое описание алгоритма ===&lt;br /&gt;
&amp;lt;b&amp;gt;&amp;lt;u&amp;gt;Дано:&amp;lt;/u&amp;gt;&amp;lt;/b&amp;gt;&lt;br /&gt;
* набор из &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; наблюдений &amp;lt;math&amp;gt;X=\{\mathbf{x}_1, \mathbf{x}_2, ..., \mathbf{x}_n\}, \mathbf{x}_i \in \mathbb{R}^d, i=\overline{1, n}&amp;lt;/math&amp;gt;;&lt;br /&gt;
* &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; - требуемое число кластеров, &amp;lt;math&amp;gt;k \in \mathbb{N}, k \leq n&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;&amp;lt;u&amp;gt;Требуется:&amp;lt;/u&amp;gt;&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Разделить множество наблюдений &amp;lt;math&amp;gt;X&amp;lt;/math&amp;gt; на &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластеров &amp;lt;math&amp;gt;S_1, S_2, ..., S_k&amp;lt;/math&amp;gt;:&lt;br /&gt;
*   &amp;lt;math&amp;gt;S_i \cap S_j= \varnothing, \quad i \ne j&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
*   &amp;lt;math&amp;gt;\bigcup_{i=1}^{k} S_i = X&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;&amp;lt;u&amp;gt;Действие алгоритма:&amp;lt;/u&amp;gt;&amp;lt;/b&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;Алгоритм &amp;lt;i&amp;gt;k means&amp;lt;/i&amp;gt; разбивает набор &amp;lt;math&amp;gt;X&amp;lt;/math&amp;gt; на &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; наборов &amp;lt;math&amp;gt;S_1, S_2, ..., S_k,&amp;lt;/math&amp;gt; таким образом, чтобы минимизировать сумму квадратов расстояний от каждой точки кластера до его центра (центр масс кластера). Введем обозначение, &amp;lt;math&amp;gt;S=\{S_1, S_2, ..., S_k\}&amp;lt;/math&amp;gt;. Тогда действие алгоритма &amp;lt;i&amp;gt;k means&amp;lt;/i&amp;gt; равносильно поиску:&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;table style=&amp;quot;width:100%&amp;quot;&amp;gt;&lt;br /&gt;
  &amp;lt;tr&amp;gt;&lt;br /&gt;
    &amp;lt;td align=&amp;quot;center&amp;quot; width=&amp;quot;90%&amp;quot;&amp;gt;&amp;lt;math&amp;gt;\arg\min_{S} \sum\limits_{i=1}^k \sum\limits_{\mathbf{x} \in S_i} \rho(\mathbf{x}, \mathbf{\mu}_i )^2,&amp;lt;/math&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;td align=&amp;quot;right&amp;quot;&amp;gt;&amp;lt;math&amp;gt;(1)&amp;lt;/math&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;/table&amp;gt;&lt;br /&gt;
где &amp;lt;math&amp;gt;\mathbf{\mu}_i&amp;lt;/math&amp;gt; &amp;amp;ndash; центры кластеров, &amp;lt;math&amp;gt;i=\overline{1,k}, \quad \rho(\mathbf{x}, \mathbf{\mu}_i)&amp;lt;/math&amp;gt; &amp;amp;ndash; функция расстояния между &amp;lt;math&amp;gt;\mathbf{x}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\mu_i&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;&amp;lt;u&amp;gt;Шаги алгоритма: &amp;lt;/u&amp;gt;&amp;lt;/b&amp;gt;&lt;br /&gt;
&amp;lt;ol&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&lt;br /&gt;
    &amp;lt;b&amp;gt;Начальный шаг: инициализация кластеров&amp;lt;/b&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;Выбирается произвольное множество точек &amp;lt;math&amp;gt;\mu_i, i=\overline{1,k}&amp;lt;/math&amp;gt;, рассматриваемых как начальные центры кластеров: &amp;lt;math&amp;gt;\mu_i^{(0)} = \mu_i, \quad i=\overline{1, k}&amp;lt;/math&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
  &amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&lt;br /&gt;
    &amp;lt;b&amp;gt;Распределение векторов по кластерам&amp;lt;/b&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Шаг&amp;lt;/b&amp;gt; &amp;lt;math&amp;gt;t: \forall \mathbf{x}_i \in X, i=\overline{1,n}: \mathbf{x}_i \in S_j \iff  j=\arg\min_{k}\rho(\mathbf{x}_i,\mathbf{\mu}_k^{(t-1)})^2&amp;lt;/math&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
  &amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&lt;br /&gt;
    &amp;lt;b&amp;gt;Пересчет центров кластеров&amp;lt;/b&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Шаг &amp;lt;/b&amp;gt; &amp;lt;math&amp;gt;t: \forall i=\overline{1,k}:  \mu_i^{(t)} = \cfrac{1}{|S_i|}\sum_{\mathbf{x}\in S_i}\mathbf{x}&amp;lt;/math&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
  &amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&lt;br /&gt;
    &amp;lt;b&amp;gt;Проверка условия останова:&amp;lt;/b&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
    &#039;&#039;&#039;if&#039;&#039;&#039; &amp;lt;math&amp;gt;\exist i\in \overline{1,k}: \mu_i^{(t)} \ne \mu_i^{(t-1)}&amp;lt;/math&amp;gt; &#039;&#039;&#039;then&#039;&#039;&#039;&lt;br /&gt;
        t = t + 1;&lt;br /&gt;
        goto 2;&lt;br /&gt;
    &#039;&#039;&#039;else&#039;&#039;&#039;&lt;br /&gt;
        &#039;&#039;&#039;stop&#039;&#039;&#039;&lt;br /&gt;
  &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ol&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Вычислительное ядро алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Вычислительным ядром являются шаги 2 и 3 приведенного выше алгоритма: &amp;lt;b&amp;gt;&amp;lt;i&amp;gt;распределение векторов по кластерам&amp;lt;/i&amp;gt;&amp;lt;/b&amp;gt; и &amp;lt;b&amp;gt;&amp;lt;i&amp;gt;пересчет центров кластеров&amp;lt;/i&amp;gt;&amp;lt;/b&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;&amp;lt;i&amp;gt;Распределение векторов&amp;lt;/i&amp;gt;&amp;lt;/b&amp;gt; по кластерам предполагает вычисление расстояний между каждым вектором &amp;lt;math&amp;gt;\mathbf{x}_i \in X, i= \overline{1,n}&amp;lt;/math&amp;gt; и центрами кластера &amp;lt;math&amp;gt;\mathbf{\mu}_j, j= \overline{1,k}&amp;lt;/math&amp;gt;. Таким образом, данный шаг предполагает &amp;lt;math&amp;gt;k*n&amp;lt;/math&amp;gt; вычислений расстояний между d-мерными векторами. &lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;&amp;lt;i&amp;gt;Пересчет центров кластеров&amp;lt;/i&amp;gt;&amp;lt;/b&amp;gt; предполагает &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; вычислений центров масс &amp;lt;math&amp;gt;\mathbf{\mu}_i&amp;lt;/math&amp;gt; множеств &amp;lt;math&amp;gt;S_i, i=\overline{1,k}&amp;lt;/math&amp;gt; представленных выражением в шаге 3 представленного выше алгоритма.&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Макроструктура алгоритма ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Инициализация центров масс &amp;lt;math&amp;gt;\mu_1, ..., \mu_k&amp;lt;/math&amp;gt;&amp;lt;/b&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
Наиболее распространенными являются следующие стратегии:&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&lt;br /&gt;
    &amp;lt;b&amp;gt;Метод Forgy&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;В качестве начальных значений &amp;lt;math&amp;gt;\mu_1, ..., \mu_k&amp;lt;/math&amp;gt; берутся случайно выбранные векторы.&lt;br /&gt;
  &amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&lt;br /&gt;
    &amp;lt;b&amp;gt;Метод случайно разделения (Random Partitioning)&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;Для каждого вектора &amp;lt;math&amp;gt;\mathbf{x}_i \in X, i=\overline{1, n}&amp;lt;/math&amp;gt; выбирается случайным образом кластер &amp;lt;math&amp;gt;S_1, ..., S_k&amp;lt;/math&amp;gt;, после чего для каждого полученного кластера вычисляются значения &amp;lt;math&amp;gt;\mu_1, ..., \mu_k&amp;lt;/math&amp;gt;.&lt;br /&gt;
  &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Распределение векторов по кластерам&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Для этого шага алгоритма между векторами &amp;lt;math&amp;gt;\mathbf{x}_i \in X, i=\overline{1, n}&amp;lt;/math&amp;gt; и центрами кластеров &amp;lt;math&amp;gt;\mu_1, ..., \mu_k&amp;lt;/math&amp;gt; вычисляются &amp;lt;b&amp;gt;расстояния&amp;lt;/b&amp;gt; по формуле (как правило, используется Евлидово расстояние):&lt;br /&gt;
&amp;lt;table style=&amp;quot;width:100%&amp;quot;&amp;gt;&lt;br /&gt;
  &amp;lt;tr&amp;gt;&lt;br /&gt;
    &amp;lt;td align=&amp;quot;center&amp;quot; width=&amp;quot;90%&amp;quot;&amp;gt;&amp;lt;math&amp;gt; \mathbf{v}_1, \mathbf{v}_2 \in \mathbb{R}^d,  \quad \rho(\mathbf{v}_1, \mathbf{v}_2) = \lVert \mathbf{v}_1- \mathbf{v}_2 \rVert= \sqrt{\sum_{i=1}^{d}(\mathbf{v}_{1,i} - \mathbf{v}_{2,i})^2}&amp;lt;/math&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;td align=&amp;quot;right&amp;quot;&amp;gt;&amp;lt;math&amp;gt;(2)&amp;lt;/math&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;/table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Пересчет центров кластеров&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Для этого шага алгоритма производится пересчет центров кластера по &amp;lt;b&amp;gt;формуле вычисления центра масс&amp;lt;/b&amp;gt;:&lt;br /&gt;
&amp;lt;table style=&amp;quot;width:100%&amp;quot;&amp;gt;&lt;br /&gt;
  &amp;lt;tr&amp;gt;&lt;br /&gt;
    &amp;lt;td align=&amp;quot;center&amp;quot; width=&amp;quot;90%&amp;quot;&amp;gt;&amp;lt;math&amp;gt; \mu = \cfrac{1}{|S|}\sum_{\mathbf{x}\in S}\mathbf{x}&amp;lt;/math&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;td align=&amp;quot;right&amp;quot;&amp;gt;&amp;lt;math&amp;gt;(3)&amp;lt;/math&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;/table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Схема реализации последовательного алгоритма ===&lt;br /&gt;
&lt;br /&gt;
 &#039;&#039;&#039;algorithm&#039;&#039;&#039; k-means &#039;&#039;&#039;is&#039;&#039;&#039;&lt;br /&gt;
     &#039;&#039;&#039;1.&#039;&#039;&#039; Инициализировать центры кластеров &amp;lt;math&amp;gt;\mathbf{\mu}_i^{(1)}, i=\overline{1,k}&amp;lt;/math&amp;gt;&lt;br /&gt;
     &#039;&#039;&#039;2.&#039;&#039;&#039; &amp;lt;math&amp;gt;t \leftarrow 1&amp;lt;/math&amp;gt;&lt;br /&gt;
     &#039;&#039;&#039;3.&#039;&#039;&#039; &#039;&#039;&#039;Распределение по кластерам&#039;&#039;&#039;&amp;lt;br&amp;gt;&lt;br /&gt;
        &amp;lt;math&amp;gt;S_i^{(t)}=\{\mathbf{x}_p: \lVert\mathbf{x}_p-\mathbf{\mu}_i^{(t)}\rVert^2 \leq \lVert\mathbf{x}_p-\mathbf{\mu}_j^{(t)}\rVert^2 \quad \forall j=\overline{1,k}\},&amp;lt;/math&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
        где каждый вектор &amp;lt;math&amp;gt;\mathbf{x}_p&amp;lt;/math&amp;gt; соотносится единственному кластеру &amp;lt;math&amp;gt;S^{(t)}&amp;lt;/math&amp;gt;&lt;br /&gt;
     &#039;&#039;&#039;4.&#039;&#039;&#039; &#039;&#039;&#039;Обновление центров кластеров&#039;&#039;&#039;&amp;lt;br&amp;gt;&lt;br /&gt;
        &amp;lt;math&amp;gt;\mathbf{\mu}_i^{(t+1)} = \frac{1}{|S^{(t)}_i|} \sum_{\mathbf{x}_j \in S^{(t)}_i} \mathbf{x}_j &amp;lt;/math&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
     &#039;&#039;&#039;5.&#039;&#039;&#039; &#039;&#039;&#039;if&#039;&#039;&#039; &amp;lt;math&amp;gt;\exist i \in \overline{1,k}: \mathbf{\mu}_i^{(t+1)} \ne \mathbf{\mu}_i^{(t)}&amp;lt;/math&amp;gt; &#039;&#039;&#039;then&#039;&#039;&#039;&lt;br /&gt;
            t = t + 1;&lt;br /&gt;
            goto &#039;&#039;&#039;3&#039;&#039;&#039;;&lt;br /&gt;
        &#039;&#039;&#039;else&#039;&#039;&#039;&lt;br /&gt;
            &#039;&#039;&#039;stop&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
=== Последовательная сложность алгоритма===&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding-bottom: 20px&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;Обозначим &amp;lt;math&amp;gt;\Theta_{centroid}^{d, m}&amp;lt;/math&amp;gt; временную сложность вычисления центорида кластера, число элементов которого равна &amp;lt;math&amp;gt;m&amp;lt;/math&amp;gt;,  в d-мерном пространстве.&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;Аналогично  &amp;lt;math&amp;gt;\Theta_{distance}^d&amp;lt;/math&amp;gt; &amp;amp;ndash; временная сложность вычисления расстояния между двумя d-мерными векторами.&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding-bottom: 20px&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;Сложность шага инициализации &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластеров мощности &amp;lt;math&amp;gt;m&amp;lt;/math&amp;gt; в d-мерном пространстве &amp;amp;ndash; &amp;lt;math&amp;gt;\Theta_{init}^{k, d, m}&amp;lt;/math&amp;gt;&amp;lt;/b&amp;gt;&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;i&amp;gt;Стратерия Forgy&amp;lt;/i&amp;gt;: вычисления не требуются, &amp;lt;math&amp;gt;\Theta_{init}^{k, d, m} = 0&amp;lt;/math&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;i&amp;gt;Стратегия случайного разбиения&amp;lt;/i&amp;gt;: вычисление центров &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластеров,  &amp;lt;math&amp;gt;\Theta_{init}^{k, d, m} = k*\Theta_{centroid}^{d, m}, m \le n&amp;lt;/math&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding-bottom: 20px&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Cложность шага распределения d мерных векторов по &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластерам &amp;amp;ndash; &amp;lt;math&amp;gt;\Theta_{distribute}^{k, d}&amp;lt;/math&amp;gt;&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
На этом шаге для каждого вектора &amp;lt;math&amp;gt;\mathbf{x}_i \in X, i=\overline{1, n}&amp;lt;/math&amp;gt; вычисляется k расстояний до центров кластеров &amp;lt;math&amp;gt;\mathbf{\mu}_1, ...\mathbf{\mu}_k&amp;lt;/math&amp;gt;&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p align=&amp;quot;center&amp;quot;&amp;gt;&lt;br /&gt;
  &amp;lt;math&amp;gt;\Theta_{distribute}^{k, d} = n*k*\Theta_{distance}^d&amp;lt;/math&amp;gt;&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding-bottom: 20px&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;Сложность шага пересчета центров &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластеров размера &amp;lt;math&amp;gt;m&amp;lt;/math&amp;gt; в d-мерном пространстве &amp;amp;ndash; &amp;lt;math&amp;gt;\Theta_{recenter}^{k, d, m}&amp;lt;/math&amp;gt;&amp;lt;/b&amp;gt;&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;На этом шаге вычисляется &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; центров кластеров &amp;lt;math&amp;gt;\mathbf{\mu}_1, ...\mathbf{\mu}_k&amp;lt;/math&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p align=&amp;quot;center&amp;quot;&amp;gt;&amp;lt;math&amp;gt;\Theta_{recenter}^{k, d, m} = k*\Theta_{centroid}^{d, m}&amp;lt;/math&amp;gt; &amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding-bottom: 20px&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Рассчитаем &amp;lt;math&amp;gt;\Theta_{centroid}^{d, m}&amp;lt;/math&amp;gt; для кластера, число элементов которого равно &amp;lt;math&amp;gt;m&amp;lt;/math&amp;gt;&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p align=&amp;quot;center&amp;quot;&amp;gt;&amp;lt;math&amp;gt;\Theta_{centroid}^{d, m}&amp;lt;/math&amp;gt; = &amp;lt;math&amp;gt;m * d&amp;lt;/math&amp;gt; сложений + &amp;lt;math&amp;gt;d&amp;lt;/math&amp;gt; делений &amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding-bottom: 20px&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Рассчитаем &amp;lt;math&amp;gt;\Theta_{distance}^d&amp;lt;/math&amp;gt; в соответствие с формулой &amp;lt;math&amp;gt;(2)&amp;lt;/math&amp;gt;&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p align=&amp;quot;center&amp;quot;&amp;gt;&amp;lt;math&amp;gt;\Theta_{distance}^d&amp;lt;/math&amp;gt; = &amp;lt;math&amp;gt;d&amp;lt;/math&amp;gt; вычитаний + &amp;lt;math&amp;gt;d&amp;lt;/math&amp;gt; умножений + &amp;lt;math&amp;gt;(d-1)&amp;lt;/math&amp;gt; сложение&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding-bottom: 20px&amp;quot;&amp;gt;&lt;br /&gt;
  &amp;lt;p&amp;gt;Предположим, что алгоритм сошелся за &amp;lt;math&amp;gt;\Tau&amp;lt;/math&amp;gt; итераций, тогда временная сложность алгоритма &amp;lt;math&amp;gt;\Theta_{k-means}^{d, n}&amp;lt;/math&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
  &amp;lt;p align=&amp;quot;center&amp;quot;&amp;gt;&amp;lt;b&amp;gt;&amp;lt;math&amp;gt;\Theta_{k-means}^{d, n} \le \Theta_{init}^{k, d, n} + \Tau*(\Theta_{distribute}^{k, d} + \Theta_{recenter}^{k, d, n})&amp;lt;/math&amp;gt;&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding-bottom: 5px&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;Операции сложения/вычитания:&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p align=&amp;quot;center&amp;quot;&amp;gt;&amp;lt;b&amp;gt;&amp;lt;math&amp;gt;\Theta_{k-means}^{d, n} \le k*n*d+ \Tau*(k*n*(2d-1) + k*n*d) = k*n*d+ \Tau*(k*n*(3d-1)) \thicksim O(\Tau*k*d*n)&amp;lt;/math&amp;gt;&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding-bottom: 20px&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;Операции умножения/деления:&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p align=&amp;quot;center&amp;quot;&amp;gt;&amp;lt;b&amp;gt;&amp;lt;math&amp;gt;\Theta_{k-means}^{d, n} \le k*d + \Tau*(k*n*d + k*d) = k*d + \Tau * k*d*(n+1) \thicksim O(\Tau*k*d*n) &amp;lt;/math&amp;gt;&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding-bottom: 20px&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;Получаем, что &amp;lt;b&amp;gt;временная сложность&amp;lt;/b&amp;gt; алгоритма &amp;lt;b&amp;gt;k means&amp;lt;/b&amp;gt; кластеризации &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; &amp;lt;b&amp;gt;d-мерных&amp;lt;/b&amp;gt; векторов на &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластеров за &amp;lt;math&amp;gt;\Tau&amp;lt;/math&amp;gt; итераций:&amp;lt;/p&amp;gt;&lt;br /&gt;
 &amp;lt;p align=&amp;quot;center&amp;quot;&amp;gt;&amp;lt;b&amp;gt;&amp;lt;math&amp;gt; \Theta_{k-means}^{d, n} \thicksim O(\Tau*k*d*n) &amp;lt;/math&amp;gt;&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Информационный граф ===&lt;br /&gt;
&lt;br /&gt;
Рассмотрим информационный граф алгоритма. Алгоритм &amp;lt;i&amp;gt;k means&amp;lt;/i&amp;gt; начинается с этапа инициализации, после которого следуют итерации, на каждой из которых выполняется два последовательных шага (см. [[#Схема реализации последовательного алгоритма|&amp;quot;Схема реализации последовательного алгоритма&amp;quot;]]): &lt;br /&gt;
* распределение векторов по кластерам&lt;br /&gt;
* перерасчет центров кластеров&lt;br /&gt;
&lt;br /&gt;
Поскольку основная часть вычислений приходится на шаги итераций, распишем информационные графы данных шагов.&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Распределение векторов по кластерам&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
Информационный граф шага распределения векторов по кластерам представлен на &#039;&#039;рисунке 1&#039;&#039;. Исходами данного графа является исходные векторы &amp;lt;math&amp;gt;\mathbf{x}_1, ..., \mathbf{x}_n&amp;lt;/math&amp;gt;, а также центры кластеров &amp;lt;math&amp;gt;\mathbf{\mu}_1, ... \mathbf{\mu}_k&amp;lt;/math&amp;gt;, вычисленные ранее (на шаге инициализации, если рассматривается первая итерация алгоритма, или на шаге пересчета центров кластеров предыдущей итерации в противном случае). Каждая пара векторов данных &amp;lt;math&amp;gt;\mathbf{x}_i, i=\overline{1,n}&amp;lt;/math&amp;gt; и центров кластера &amp;lt;math&amp;gt;\mathbf{\mu}_j, j=\overline{1, k}&amp;lt;/math&amp;gt; : (&amp;lt;math&amp;gt;\mathbf{x}_i&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;\mathbf{\mu}_j&amp;lt;/math&amp;gt;) подаются на независимые узлы &amp;lt;i&amp;gt;&amp;quot;d&amp;quot;&amp;lt;/i&amp;gt; вычисления расстояния между векторами (более подробная схема вычисления расстояния представлена далее, &#039;&#039;рисунок 2&#039;&#039;). Далее узлы вычисления расстояния &amp;lt;i&amp;gt;&amp;quot;d&amp;quot;&amp;lt;/i&amp;gt;, соответствующие одному и тому же исходному вектору &amp;lt;math&amp;gt;\mathbf{x}_i&amp;lt;/math&amp;gt; передаются на один узел &amp;lt;i&amp;gt;&amp;quot;m&amp;quot;&amp;lt;/i&amp;gt;, где далее происходит вычисление новой метки кластера для каждого вектора &amp;lt;math&amp;gt;\mathbf{x}_i&amp;lt;/math&amp;gt; (берется кластер с минимальным результатом вычисления расстояния). На выходе графа выдаются метки кластеров , &amp;lt;math&amp;gt;L_1, ..., L_n&amp;lt;/math&amp;gt;, такие что &amp;lt;math&amp;gt;\forall \mathbf{x}_i, i=\overline{1, n}, \mathbf{x}_i \in S_j \Leftrightarrow L_i = j&amp;lt;/math&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
[[file:Clusterization.png|thumb|center|800px|Рис. 1. Схема распределения векторов по кластерам. &#039;&#039;d&#039;&#039; &amp;amp;ndash; вычисление расстояния между векторами; &#039;&#039;m&#039;&#039; &amp;amp;ndash; вычисление минимума.]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Вычисление расстояния между векторами&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
Подробная схема вычисления расстояния между векторами &amp;lt;math&amp;gt;\mathbf{x}_i, \mathbf{\mu}_j&amp;lt;/math&amp;gt; представлена на &#039;&#039;рисунке 2&#039;&#039;. Как показано на графе, узел вычисления расстояния между векторами &amp;lt;i&amp;gt;&amp;quot;d&amp;quot;&amp;lt;/i&amp;gt; состоит из шага взятия разности между векторами (узел &amp;quot;&amp;lt;math&amp;gt;-&amp;lt;/math&amp;gt;&amp;quot;) и взятия нормы получившегося вектора разности (узел &amp;quot;&amp;lt;math&amp;gt;||\cdot||^2&amp;lt;/math&amp;gt;&amp;quot;). Более подробно, вычисление расстояния между векторами &amp;lt;math&amp;gt;\mathbf{x}_i = {x_{i1,}, ...,{x_{in}}}, \mathbf{\mu}_j = {\mu_{j1}, ...,\mu_{jn}}&amp;lt;/math&amp;gt; может быть представлено как вычисление разности между каждой парой компонент &amp;lt;math&amp;gt;(x_{iz}, \mu_{jz}), z=\overline{1, d}&amp;lt;/math&amp;gt; (узел &amp;quot;&amp;lt;math&amp;gt;-&amp;lt;/math&amp;gt;&amp;quot;), далее возведение в квадрат для каждого узла &amp;quot;&amp;lt;math&amp;gt;-&amp;lt;/math&amp;gt;&amp;quot; (узел &amp;quot;&amp;lt;math&amp;gt;()^2&amp;lt;/math&amp;gt;&amp;quot;) и суммирования выходов всех узлов &amp;quot;&amp;lt;math&amp;gt;()^2&amp;lt;/math&amp;gt;&amp;quot; (узел &amp;quot;&amp;lt;math&amp;gt;+&amp;lt;/math&amp;gt;&amp;quot;).  &lt;br /&gt;
&lt;br /&gt;
[[file:dist_calc.png|thumb|center|800px|Рис. 2. Схема вычисления расстояния между вектором и центром кластера.]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Пересчет центров кластеров&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
Информационный граф шага пересчета центров кластеров представлен на &#039;&#039;рисунке 3&#039;&#039;. Исходами данного графа является исходные векторы &amp;lt;math&amp;gt;\mathbf{x}_1, ..., \mathbf{x}_n&amp;lt;/math&amp;gt;, а также им соответствующие метки кластера, &amp;lt;math&amp;gt;L_1, ..., L_n&amp;lt;/math&amp;gt;, такие что &amp;lt;math&amp;gt;\forall x_i, i=\overline{1, n}, \mathbf{x}_i \in S_j \Leftrightarrow L_i = j&amp;lt;/math&amp;gt;, вычисленные на этапе распределения векторов по кластерам. Все векторы &amp;lt;math&amp;gt;\mathbf{x}_1, ..., \mathbf{x}_n&amp;lt;/math&amp;gt; подаются в узлы &amp;lt;math&amp;gt;+_1, ...+_k&amp;lt;/math&amp;gt;, каждый узел &amp;lt;math&amp;gt;+_m, m = \overline{1,k}&amp;lt;/math&amp;gt; соответствует операции сложения векторов кластера с номером &amp;lt;math&amp;gt;m&amp;lt;/math&amp;gt;. Метки кластера &amp;lt;math&amp;gt;L_1, ..., L_n&amp;lt;/math&amp;gt; также совместно передаются на узлы &amp;lt;math&amp;gt;S_m, m = \overline{1,k}&amp;lt;/math&amp;gt;, на каждом из которых вычисляется количество векторов в соответствующем кластере (количество меток с соответствующим значением). Далее каждая пара выходов узлов &amp;lt;math&amp;gt;+_m&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;S_m&amp;lt;/math&amp;gt; подается на узел &amp;quot;&amp;lt;math&amp;gt;/&amp;lt;/math&amp;gt;&amp;quot;, где производится деление суммы векторов кластера на количество элементов в нем. Значения, вычисленные на узлах &amp;quot;&amp;lt;math&amp;gt;/&amp;lt;/math&amp;gt;&amp;quot;, присваиваются новым центрам кластеров (выходные значения графа).&lt;br /&gt;
&lt;br /&gt;
[[file:Recluster.png|thumb|center|800px|Рис. 3. Схема пересчета центров кластеров]]&lt;br /&gt;
&lt;br /&gt;
=== Ресурс параллелизма алгоритма ===&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
Работа алгоритма состоит из &amp;lt;math&amp;gt;\Tau&amp;lt;/math&amp;gt; итераций, в каждой из которых происходит &amp;lt;b&amp;gt;распределение d-мерных векторов по &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластерам&amp;lt;/b&amp;gt;, а также &amp;lt;b&amp;gt;пересчет центров кластеров в d-мерном пространстве&amp;lt;/b&amp;gt;. В шаге &amp;lt;b&amp;gt;распределения d-мерных векторов по &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластерам&amp;lt;/b&amp;gt; расстояния между вектором и центрами кластеров вычисляются независимо (отсутствуют информационные зависимости). &amp;lt;b&amp;gt;Центры масс кластеров&amp;lt;/b&amp;gt; также пересчитываются независимо друг от друга. Таким образом, имеет место [[глоссарий#Массовый параллелизм|&#039;&#039;массовый параллелизм&#039;&#039;]]. Вычислим параллельную сложность &amp;lt;math&amp;gt;\Psi_*&amp;lt;/math&amp;gt; каждого из шагов, а также параллельную сложность всего алгоритма, &amp;lt;math&amp;gt;\Psi_{k-means}&amp;lt;/math&amp;gt;. Будем исходить из предположения, что может быть использовано любое необходимое число потоков.&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Распределение d-мерных векторов по &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластерам&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;  &lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
Поскольку на данном шаге для каждой пары векторов &amp;lt;math&amp;gt;\mathbf{x}_i, i=\overline{1,n}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\mathbf{\mu}_j, j=\overline{1,k}&amp;lt;/math&amp;gt; операции вычисления расстояния не зависят друг от друга, они могут выполняться параллельно. Тогда, разделив все вычисление расстояний на &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; потоков, получим, что в каждом потоке будет выполняться только одна операция вычисления расстояния между векторами размерности d. При этом каждому вычислительному потоку передаются координаты центров всех кластеров &amp;lt;math&amp;gt;\mathbf{\mu}_1, ..., \mathbf{\mu}_k&amp;lt;/math&amp;gt;. Таким образом, параллельная сложность данного шага определяется &amp;lt;i&amp;gt; сложностью параллельной операции вычисления расстояния между d-мерными векторами&amp;lt;/i&amp;gt;, &amp;lt;math&amp;gt;\Psi_{distance}^d&amp;lt;/math&amp;gt;  и &amp;lt;i&amp;gt;сложностью определения наиболее близкого кластера&amp;lt;/i&amp;gt; (паралельное взятие минимума по расстояниям), &amp;lt;math&amp;gt;\Psi_{min}^k&amp;lt;/math&amp;gt;. Для оценки &amp;lt;math&amp;gt;\Psi_{distance}^d&amp;lt;/math&amp;gt; воспользуемся  [[Нахождение_частных_сумм_элементов_массива_сдваиванием | параллельной реализацией нахождения частичной суммы элементов массива путем сдваивания]]. Аналогично, &amp;lt;math&amp;gt;\Psi_{min}^k = log(k)&amp;lt;/math&amp;gt;. В результате, &amp;lt;math&amp;gt;\Psi_{distance}^d = O(log(d))&amp;lt;/math&amp;gt;.   Таким образом: &lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p align=&amp;quot;center&amp;quot;&amp;gt;&amp;lt;math&amp;gt;\Psi_{distribute}^{k, d}  = \Psi_{distance}^d + \Psi_{min}^k = O(log(d))+O(log(k)) = O(log(k*d))&amp;lt;/math&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Пересчет центров кластеров в d-мерном пространстве&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
Поскольку на данном шаге для каждого из &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластеров центр масс может быть вычислен независимо, данные операции могут быть выполнены в отдельных потоках. Таким образом, параллельная сложность данного шага, &amp;lt;math&amp;gt;\Psi_{recenter}^{k, d}&amp;lt;/math&amp;gt;,  будет определяться &amp;lt;i&amp;gt;параллельной сложностью вычисления одного центра масс кластера размера &amp;lt;math&amp;gt;m&amp;lt;/math&amp;gt;&amp;lt;/i&amp;gt;, &amp;lt;math&amp;gt;\Psi_{recenter}^{k, d}&amp;lt;/math&amp;gt;,  а так как &amp;lt;math&amp;gt;m \le n \Rightarrow \Psi_{recenter}^{d, m} \le \Psi_{recenter}^{d, n}&amp;lt;/math&amp;gt;. Сложность вычисления центра масс кластера d-мерных векторов размера n аналогично предыдущим вычислениям равна &amp;lt;math&amp;gt;O(log(n))&amp;lt;/math&amp;gt;. Тогда:  &lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p align=&amp;quot;center&amp;quot;&amp;gt;&amp;lt;math&amp;gt;\Psi_{recenter}^{k, d}  \le \Psi_{recenter}^{d, n} = O(log(n))&amp;lt;/math&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Общая параллельная сложность алгоритма&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
На каждой итерации необходимо обновление центров кластеров, которые будут использованы на следующей итерации. Таким образом, итерационный процесс выполняется последовательно&amp;lt;ref&amp;gt;Zhao, Weizhong, Huifang Ma, and Qing He. &amp;quot;Parallel k-means clustering based on mapreduce.&amp;quot; IEEE International Conference on Cloud Computing. Springer Berlin Heidelberg, 2009.&amp;lt;/ref&amp;gt;. Тогда, поскольку сложность каждой итерации  определяется &amp;lt;math&amp;gt;\Psi_{distribute}^{k, d}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\Psi_{recenter}&amp;lt;/math&amp;gt;, сложность всего алгоритма, &amp;lt;math&amp;gt;\Psi_{k-means}&amp;lt;/math&amp;gt; в предположении, что было сделано &amp;lt;math&amp;gt;\Tau&amp;lt;/math&amp;gt; операций определяется выражением&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p align=&amp;quot;center&amp;quot;&amp;gt;&amp;lt;math&amp;gt;\Psi_{k-means} \approx \Tau * (\Psi_{distribute}^{k, d} + \Psi_{recenter}^{k, d}) \le \Tau * O(log(k*d*n))&amp;lt;/math&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Входные и выходные данные алгоритма ===&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;Входные данные&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;Матрица из &amp;lt;math&amp;gt;n*d&amp;lt;/math&amp;gt; элементов &amp;lt;math&amp;gt;x_{i, j} \in \mathbb{R}, i=\overline{1, n}, j=\overline{1, d}&amp;lt;/math&amp;gt;&amp;amp;ndash; координат векторов (наблюдений).&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;Целое положительное число &amp;lt;math&amp;gt;k, k \le n&amp;lt;/math&amp;gt; &amp;amp;ndash; количество кластеров.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;Объем входных данных&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;math&amp;gt;1&amp;lt;/math&amp;gt; целое число + &amp;lt;math&amp;gt;n*d&amp;lt;/math&amp;gt; вещественных чисел (при условии, что координаты &amp;amp;ndash; вещественные числа).&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;Выходные данные&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; целых положительных чисел &amp;lt;math&amp;gt;L_1, ..., L_n&amp;lt;/math&amp;gt;&amp;amp;ndash; номера кластеров, соотвествующие каждому вектору (при условии, что нумерация кластеров начинается с &amp;lt;math&amp;gt;1&amp;lt;/math&amp;gt;).&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;Объем выходных данных&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; целых положительных чисел.&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Свойства алгоритма ===&lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;[[глоссарий#Вычислительная мощность|&#039;&#039;Вычислительная мощность&#039;&#039;]]&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
Вычислительная мощность алгоритма &amp;lt;i&amp;gt;k means&amp;lt;/i&amp;gt; равна &amp;lt;math&amp;gt;\frac{k*d*n*\Tau}{n*d} = k*\Tau &amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; &amp;amp;ndash; число кластеров, &amp;lt;math&amp;gt;\Tau&amp;lt;/math&amp;gt; &amp;amp;ndash; число итераций алгоритма.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;[[глоссарий#Детерминированность |&#039;&#039;Детерминированность&#039;&#039;]] и [[глоссарий#Устойчивость |&#039;&#039;Устойчивость&#039;&#039;]] &amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
Алгоритм &amp;lt;i&amp;gt;k means&amp;lt;/i&amp;gt; является итерационным. Количество итераций алгоритма в общем случае не фиксируется и зависит от начального расположения объектов в пространстве, параметра &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt;, а также от начального приближения центров кластеров, &amp;lt;math&amp;gt;\mu_1, ..., \mu_k&amp;lt;/math&amp;gt;. В результате этого может варьироваться результат работы алгоритма. При неудачном выборе начальных параметров итерационный процесс может сойтись к локальному оптимуму&amp;lt;ref&amp;gt;Von Luxburg, Ulrike. Clustering Stability. Now Publishers Inc, 2010.&amp;lt;/ref&amp;gt;. По этим причинам алгоритм не является ни &amp;lt;b&amp;gt;детермирированным&amp;lt;/b&amp;gt;, ни &amp;lt;b&amp;gt;устойчивым&amp;lt;/b&amp;gt;.&lt;br /&gt;
 &lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Соотношение последовательной и параллельной сложности алгоритма&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\frac{\Theta_{k-means}}{\Psi_{k-means}} = \frac{O(\Tau*k*d*n)}{O(\Tau*log(k*d*n))}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Сильные стороны алгоритма&amp;lt;/b&amp;gt;:&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;i&amp;gt;Сравнительно высокая эффективность при простоте реализации&amp;lt;/i&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;i&amp;gt;Высокое качество кластеризации&amp;lt;/i&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;i&amp;gt;Возможность распараллеливания&amp;lt;/i&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;i&amp;gt;Существование множества модификаций&amp;lt;/i&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;Недостатки алгоритма&amp;lt;/b&amp;gt;&amp;lt;ref&amp;gt;Ortega, Joaquín Pérez, Ma Del Rocío Boone Rojas, and María J. Somodevilla. &amp;quot;Research issues on K-means Algorithm: An Experimental Trial Using Matlab.&amp;quot;&amp;lt;/ref&amp;gt;:&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;i&amp;gt;Количество кластеров является параметром алгоритма&amp;lt;/i&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;&amp;lt;i&amp;gt;Чувствительность к начальным условиям&amp;lt;/i&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;Инициализация центров кластеров в значительной степени влияет на результат кластеризации.&amp;lt;/p&amp;gt;&lt;br /&gt;
  &amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;&amp;lt;i&amp;gt;Чувствительность к выбросам и шумам&amp;lt;/i&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;Выбросы, далекие от центров настоящих кластеров, все равно учитываются при вычислении их центров.&amp;lt;/p&amp;gt;&lt;br /&gt;
  &amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;&amp;lt;i&amp;gt;Возможность сходимости к локальному оптимуму&amp;lt;/i&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;Итеративный подход не дает гарантии сходимости к оптимальному решению.&amp;lt;/p&amp;gt;&lt;br /&gt;
  &amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;&amp;lt;i&amp;gt;Использование понятия &amp;quot;среднего&amp;quot;&amp;lt;/i&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;Алгоритм неприменим к данным, для которых не определено понятие &amp;quot;среднего&amp;quot;, например, категориальным данным.&amp;lt;/p&amp;gt;&lt;br /&gt;
  &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&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;
Исследование масштабируемости параллельной реализации алгоритма k means проводилось на суперкомпьютере &amp;quot;Ломоносов&amp;quot;. Алгоритм реализован на языке C с использованием средств MPI.&lt;br /&gt;
Для исследования масштабируемости проводилось множество запусков программы с разным значением параметра (количество векторов для кластеризации), а также с различным числом процессоров. Фиксировались результаты запусков &amp;amp;ndash; время работы &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt; и количество произведенных итераций алгоритма &amp;lt;math&amp;gt;\Tau&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Параметры запусков для экспериментальной оценки:&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;Значения &amp;lt;b&amp;gt;количества векторов&amp;lt;/b&amp;gt; &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;: 20&#039;000, 30&#039;000, 50&#039;000, 100&#039;000, 200&#039;000, 300&#039;000, 500&#039;000, 700&#039;000, 1&#039;000&#039;000, 1&#039;500&#039;000, 2&#039;000&#039;000.&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;Значения &amp;lt;b&amp;gt;количества процессоров&amp;lt;/b&amp;gt; &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt;: 1, 8, 16, 32, 64, 128, 160, 192, 224, 256, 288, 320, 352, 384, 416, 448, 480, 512.&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;Значение &amp;lt;b&amp;gt;количества кластеров&amp;lt;/b&amp;gt; &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt;: 100.&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;Значение &amp;lt;b&amp;gt;размерности векторов&amp;lt;/b&amp;gt; &amp;lt;math&amp;gt;d&amp;lt;/math&amp;gt;: 10.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Для проведения экспериментов были сгенерированы нормально распределенные псевдослучайные данные (с использованием Python библиотеки scikit-learn):&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
from sklearn.datasets import make_classification&lt;br /&gt;
X1, Y1 = make_classification(n_features=10, n_redundant=2, n_informative=8,&lt;br /&gt;
                             n_clusters_per_class=1, n_classes=100,&lt;br /&gt;
                             n_samples=2000000)&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Графики производительности и эффективности реализации представлены на рисунках 4 и 5 соответственно.&lt;br /&gt;
&lt;br /&gt;
[[file:Flops.png|thumb|center|800px|Рис. 4. График производительности реализации алгоритма.]]&lt;br /&gt;
&lt;br /&gt;
[[file:Efficiency.png|thumb|center|800px|Рис. 5. График эффективности реализации алгоритма.]]&lt;br /&gt;
&lt;br /&gt;
Для заданной конфигурации эксперимента (&amp;lt;math&amp;gt;n, d, p, k&amp;lt;/math&amp;gt;) и полученных результатах (&amp;lt;math&amp;gt;t, \Tau&amp;lt;/math&amp;gt;) производительность и эффективность реализации расчитывались по формулам (см. [[#Последовательная сложность алгоритма| последовательная сложность алгоритма]]):&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
&amp;lt;ul&amp;gt;&amp;lt;li&amp;gt;&amp;lt;math&amp;gt;Performance = \frac{\Theta_{k-means}^{d, n}}{t}\ \ FLOPS&amp;lt;/math&amp;gt;&amp;lt;/li&amp;gt;&amp;lt;/ul&amp;gt;&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
&amp;lt;ul&amp;gt;&amp;lt;li&amp;gt;&amp;lt;math&amp;gt;Efficiency = \frac{100 * Performance}{Performance_{Peak}^{p}}\ \ %,&amp;lt;/math&amp;gt;&amp;lt;/li&amp;gt;&amp;lt;/ul&amp;gt;&lt;br /&gt;
где &amp;lt;math&amp;gt;Performance_{Peak}^{p}&amp;lt;/math&amp;gt; &amp;amp;ndash; пиковая производительность суперкомпьютера при &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt; процессорах, вычисленная согласно спецификациям Intel&amp;lt;sup&amp;gt;&amp;amp;reg;&amp;lt;/sup&amp;gt; XEON&amp;lt;sup&amp;gt;&amp;amp;reg;&amp;lt;/sup&amp;gt; X5670&amp;lt;ref&amp;gt;&amp;quot;http://ark.intel.com/ru/products/47920/Intel-Xeon-Processor-X5670-12M-Cache-2_93-GHz-6_40-GTs-Intel-QPI&amp;quot;&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;В результате&amp;lt;/b&amp;gt; экспериментальной оценки были получены следующие оценки эффективности реализации:&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;b&amp;gt;Минимальное&amp;lt;/b&amp;gt; значение: 0.000409 % достигается при &amp;lt;math&amp;gt;n=20&#039;000, p=480&amp;lt;/math&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;b&amp;gt;Максимальное&amp;lt;/b&amp;gt; значение: 0.741119 % достигается при &amp;lt;math&amp;gt;n=300&#039;000, p=1&amp;lt;/math&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
Оценки масштабируемости реализации алгоритма k means:&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;b&amp;gt;По числу процессоров:&amp;lt;/b&amp;gt; -0.002683 &amp;amp;ndash; эффективность убывает с ростом числа процессоров.&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;b&amp;gt;По размеру задачи:&amp;lt;/b&amp;gt; 0.002779 &amp;amp;ndash; эффективность растет с ростом числа векторов.&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;b&amp;gt;Общая оценка:&amp;lt;/b&amp;gt; -0.000058 &amp;amp;ndash; можно сделать вывод, что в целом эффективность реализации незначительно уменьшается.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[https://github.com/serban/kmeans Использованная реализация алгоритма k means]&lt;br /&gt;
&lt;br /&gt;
=== Динамические характеристики и эффективность реализации алгоритма ===&lt;br /&gt;
=== Выводы для классов архитектур ===&lt;br /&gt;
=== Существующие реализации алгоритма ===&lt;br /&gt;
==== Открытое программное обеспечение ====&lt;br /&gt;
&amp;lt;ol&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;[https://www.icpsr.umich.edu/CrimeStat/ CrimeStat]&amp;lt;/li&amp;gt; Программное обеспечение, созданное для операционных систем Windows, предоставляющее инструменты статистического  и пространственного анализа для решения задачи картирования преступности.&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://juliastats.github.io Julia]&amp;lt;/li&amp;gt; Высокоуровневый высокопроизводительный свободный язык программирования с динамической типизацией, созданный для математических вычислений, содержит реализацию k-means.&lt;br /&gt;
  &amp;lt;li&amp;gt;[https://mahout.apache.org Mahout]&amp;lt;/li&amp;gt; Apache Mahout - Java библиотека для работы с алгоритмами машинного обучения с использованием MapReduce. Содержит реализацию k-means.&lt;br /&gt;
  &amp;lt;li&amp;gt;[https://www.gnu.org/software/octave/ Octave]&amp;lt;/li&amp;gt; Написанная на C++  свободная система для математических вычислений, использующая совместимый с MATLAB язык высокого уровня, содержит реализацию k-means.&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://spark.apache.org/docs/latest/mllib-clustering.html Spark]&amp;lt;/li&amp;gt; Распределенная реализация k-means содержится в библиотеке Mlib для работы с алгоритмами машинного обучения, взаимодействующая с Python библиотекой NumPy и библиотека R.&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://torch.ch Torch]&amp;lt;/li&amp;gt;  MATLAB-подобная библиотека для языка программирования Lua с открытым исходным кодом, предоставляет большое количество алгоритмов для глубинного обучения и научных расчётов. Ядро написано на Си, прикладная часть выполняется на LuaJIT, поддерживается распараллеливание вычислений средствами CUDA и OpenMP. Существуют реализации k-means.&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://www.cs.waikato.ac.nz/ml/weka/ Weka]&amp;lt;/li&amp;gt;  Cвободное программное обеспечение для анализа данных, написанное на Java. Содержит k-means и x-means.&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://accord-framework.net/docs/html/T_Accord_MachineLearning_KMeans.htm Accord.NET]&amp;lt;/li&amp;gt; C# реализация алгоритмов k-means, k-means++, k-modes.&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://docs.opencv.org/3.0-beta/doc/py_tutorials/py_ml/py_kmeans/py_kmeans_opencv/py_kmeans_opencv.html OpenCV]&amp;lt;/li&amp;gt; Написанная на С++ библиотека, направленная в основном на решение задач компьютерного зрения. Содержит реализацию k-means.&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://mlpack.org/ MLPACK]&amp;lt;/li&amp;gt; Масштабируемая С++ библиотека для работы с алгоритмами машинного обучения, содержит реализацию k-means.&lt;br /&gt;
  &amp;lt;li&amp;gt;[https://www.scipy.org/ SciPy]&amp;lt;/li&amp;gt; Библиотека Python, содержит множество реализаций k-means.&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://scikit-learn.org/ scikit-learn]&amp;lt;/li&amp;gt; Библиотека Python, содержит множество реализаций k-means.&lt;br /&gt;
  &amp;lt;li&amp;gt;[https://www.r-bloggers.com/k-means-clustering-in-r/ R]&amp;lt;/li&amp;gt; Язык программирования для статистической обработки данных и работы с графикой, а также свободная программная среда вычислений с открытым исходным кодом в рамках проекта GNU, содержит три реализации k-means.&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://elki.dbs.ifi.lmu.de ELKI]&amp;lt;/li&amp;gt; Java фреймворк, содержащий реализацию k-means, а также множество других алгоритмов кластеризации.&lt;br /&gt;
&amp;lt;/ol&amp;gt;&lt;br /&gt;
==== Проприетарное программное обеспечение  ====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ol&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;[https://www.ayasdi.com/blog/bigdata/topological-data-analysis-of-oil-and-gas-petrophysical-data/ Ayasdi]&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://www.stata.com/features/cluster-analysis/ Stata]&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://mathworld.wolfram.com/K-MeansClusteringAlgorithm.html Mathematica]&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://www.mathworks.com/help/stats/kmeans.html?requestedDomain=www.mathworks.com MATLAB]&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;[https://support.sas.com/rnd/app/stat/procedures/fastclus.html SAS]&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://docs.rapidminer.com/studio/operators/modeling/segmentation/k_means.html RapidMiner]&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;[https://blogs.sap.com/2013/03/28/sap-hana-pal-k-means-algorithm-or-how-to-do-customer-segmentation-for-the-telecommunications-industry/ SAP HANA]&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ol&amp;gt;&lt;br /&gt;
== Литература ==&lt;br /&gt;
&amp;lt;references /&amp;gt;&lt;/div&gt;</summary>
		<author><name>DennZo1993</name></author>
	</entry>
	<entry>
		<id>https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:%D0%91%D1%80%D0%BE%D1%82%D0%B8%D0%BA%D0%BE%D0%B2%D1%81%D0%BA%D0%B0%D1%8F_%D0%94%D0%B0%D0%BD%D1%83%D1%82%D0%B0/%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_k-means&amp;diff=17187</id>
		<title>Участник:Бротиковская Данута/Алгоритм k-means</title>
		<link rel="alternate" type="text/html" href="https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:%D0%91%D1%80%D0%BE%D1%82%D0%B8%D0%BA%D0%BE%D0%B2%D1%81%D0%BA%D0%B0%D1%8F_%D0%94%D0%B0%D0%BD%D1%83%D1%82%D0%B0/%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_k-means&amp;diff=17187"/>
		<updated>2016-11-15T01:55:04Z</updated>

		<summary type="html">&lt;p&gt;DennZo1993: /* Масштабируемость реализации алгоритма */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt; {{Assignment|Zhum}}&lt;br /&gt;
&lt;br /&gt;
{{algorithm&lt;br /&gt;
| name              = Алгоритм k средних (k means)&lt;br /&gt;
| serial_complexity = &amp;lt;math&amp;gt;O(\Tau*k*d*n)&amp;lt;/math&amp;gt;&lt;br /&gt;
| input_data        = &amp;lt;math&amp;gt; d*n &amp;lt;/math&amp;gt;&lt;br /&gt;
| output_data       = &amp;lt;math&amp;gt; n &amp;lt;/math&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
Авторы страницы &amp;lt;b&amp;gt;[[Участник:Бротиковская Данута|Данута Бротиковская]]&amp;lt;/b&amp;gt; и &amp;lt;b&amp;gt;[[Участник:DennZo1993|Денис Зобнин]]&amp;lt;/b&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
Оба автора внесли одинаковый вклад в написание статьи (поиск материалов, изучение статей, заполнение контента статьи), четких разграничений по пунктам статьи сделать невозможно. &lt;br /&gt;
&lt;br /&gt;
== Свойства и структура алгоритма ==&lt;br /&gt;
&lt;br /&gt;
=== Общее описание алгоритма ===&lt;br /&gt;
Алгоритм &amp;lt;b&amp;gt;&amp;lt;i&amp;gt;k средних&amp;lt;/i&amp;gt;&amp;lt;/b&amp;gt; (&amp;lt;b&amp;gt;&amp;lt;i&amp;gt;k means&amp;lt;/i&amp;gt;&amp;lt;/b&amp;gt;) &amp;amp;ndash; неиерархический&amp;lt;ref&amp;gt;&amp;quot;https://ru.wikipedia.org/wiki/Иерархическая_кластеризация&amp;quot;&amp;lt;/ref&amp;gt;, итерационный метод кластеризации&amp;lt;ref&amp;gt;&amp;quot;https://ru.wikipedia.org/wiki/Кластерный_анализ&amp;quot;&amp;lt;/ref&amp;gt;, получивший большую популярность благодаря своей простоте, наглядности реализации и достаточно высокому качеству работы. Был изобретен в 1950-х годах математиком &amp;lt;i&amp;gt;Гуго Штейнгаузом&amp;lt;/i&amp;gt;&amp;lt;ref&amp;gt;Steinhaus, Hugo. &amp;quot;Sur la division des corp materiels en parties.&amp;quot; Bull. Acad. Polon. Sci 1.804 (1956): 801.&amp;lt;/ref&amp;gt; и почти одновременно &amp;lt;i&amp;gt;Стюартом Ллойдом&amp;lt;/i&amp;gt;&amp;lt;ref&amp;gt;Lloyd, S. P. &amp;quot;Least square quantization in PCM. Bell Telephone Laboratories Paper. Published in journal much later: Lloyd, SP: Least squares quantization in PCM.&amp;quot; IEEE Trans. Inform. Theor.(1957/1982).&amp;lt;/ref&amp;gt;. Особую популярность приобрел после публикации работы &amp;lt;i&amp;gt;МакКуина&amp;lt;/i&amp;gt;&amp;lt;ref&amp;gt;MacQueen, James. &amp;quot;Some methods for classification and analysis of multivariate observations.&amp;quot; Proceedings of the fifth Berkeley symposium on mathematical statistics and probability. Vol. 1. No. 14. 1967.&amp;lt;/ref&amp;gt; в 1967.&lt;br /&gt;
&lt;br /&gt;
Алгоритм представляет собой версию EM-алгоритма&amp;lt;ref&amp;gt;&amp;quot;https://ru.wikipedia.org/wiki/EM-алгоритм&amp;quot;&amp;lt;/ref&amp;gt;, применяемого также для разделения смеси гауссиан. Основная идея &amp;lt;i&amp;gt;k means&amp;lt;/i&amp;gt; заключается в том, что данные произвольно разбиваются на кластеры, после чего итеративно перевычисляется центр масс для каждого кластера, полученного на предыдущем шаге, затем векторы разбиваются на кластеры вновь в соответствии с тем, какой из новых центров оказался ближе по выбранной метрике.&lt;br /&gt;
&lt;br /&gt;
Цель алгоритма заключается в разделении &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; наблюдений на &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластеров таким образом, чтобы каждое наблюдение принадлежало ровно одному кластеру, расположенному на наименьшем расстоянии от наблюдения.&lt;br /&gt;
&lt;br /&gt;
=== Математическое описание алгоритма ===&lt;br /&gt;
&amp;lt;b&amp;gt;&amp;lt;u&amp;gt;Дано:&amp;lt;/u&amp;gt;&amp;lt;/b&amp;gt;&lt;br /&gt;
* набор из &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; наблюдений &amp;lt;math&amp;gt;X=\{\mathbf{x}_1, \mathbf{x}_2, ..., \mathbf{x}_n\}, \mathbf{x}_i \in \mathbb{R}^d, i=\overline{1, n}&amp;lt;/math&amp;gt;;&lt;br /&gt;
* &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; - требуемое число кластеров, &amp;lt;math&amp;gt;k \in \mathbb{N}, k \leq n&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;&amp;lt;u&amp;gt;Требуется:&amp;lt;/u&amp;gt;&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Разделить множество наблюдений &amp;lt;math&amp;gt;X&amp;lt;/math&amp;gt; на &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластеров &amp;lt;math&amp;gt;S_1, S_2, ..., S_k&amp;lt;/math&amp;gt;:&lt;br /&gt;
*   &amp;lt;math&amp;gt;S_i \cap S_j= \varnothing, \quad i \ne j&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
*   &amp;lt;math&amp;gt;\bigcup_{i=1}^{k} S_i = X&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;&amp;lt;u&amp;gt;Действие алгоритма:&amp;lt;/u&amp;gt;&amp;lt;/b&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;Алгоритм &amp;lt;i&amp;gt;k means&amp;lt;/i&amp;gt; разбивает набор &amp;lt;math&amp;gt;X&amp;lt;/math&amp;gt; на &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; наборов &amp;lt;math&amp;gt;S_1, S_2, ..., S_k,&amp;lt;/math&amp;gt; таким образом, чтобы минимизировать сумму квадратов расстояний от каждой точки кластера до его центра (центр масс кластера). Введем обозначение, &amp;lt;math&amp;gt;S=\{S_1, S_2, ..., S_k\}&amp;lt;/math&amp;gt;. Тогда действие алгоритма &amp;lt;i&amp;gt;k means&amp;lt;/i&amp;gt; равносильно поиску:&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;table style=&amp;quot;width:100%&amp;quot;&amp;gt;&lt;br /&gt;
  &amp;lt;tr&amp;gt;&lt;br /&gt;
    &amp;lt;td align=&amp;quot;center&amp;quot; width=&amp;quot;90%&amp;quot;&amp;gt;&amp;lt;math&amp;gt;\arg\min_{S} \sum\limits_{i=1}^k \sum\limits_{\mathbf{x} \in S_i} \rho(\mathbf{x}, \mathbf{\mu}_i )^2,&amp;lt;/math&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;td align=&amp;quot;right&amp;quot;&amp;gt;&amp;lt;math&amp;gt;(1)&amp;lt;/math&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;/table&amp;gt;&lt;br /&gt;
где &amp;lt;math&amp;gt;\mathbf{\mu}_i&amp;lt;/math&amp;gt; &amp;amp;ndash; центры кластеров, &amp;lt;math&amp;gt;i=\overline{1,k}, \quad \rho(\mathbf{x}, \mathbf{\mu}_i)&amp;lt;/math&amp;gt; &amp;amp;ndash; функция расстояния между &amp;lt;math&amp;gt;\mathbf{x}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\mu_i&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;&amp;lt;u&amp;gt;Шаги алгоритма: &amp;lt;/u&amp;gt;&amp;lt;/b&amp;gt;&lt;br /&gt;
&amp;lt;ol&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&lt;br /&gt;
    &amp;lt;b&amp;gt;Начальный шаг: инициализация кластеров&amp;lt;/b&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;Выбирается произвольное множество точек &amp;lt;math&amp;gt;\mu_i, i=\overline{1,k}&amp;lt;/math&amp;gt;, рассматриваемых как начальные центры кластеров: &amp;lt;math&amp;gt;\mu_i^{(0)} = \mu_i, \quad i=\overline{1, k}&amp;lt;/math&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
  &amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&lt;br /&gt;
    &amp;lt;b&amp;gt;Распределение векторов по кластерам&amp;lt;/b&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Шаг&amp;lt;/b&amp;gt; &amp;lt;math&amp;gt;t: \forall \mathbf{x}_i \in X, i=\overline{1,n}: \mathbf{x}_i \in S_j \iff  j=\arg\min_{k}\rho(\mathbf{x}_i,\mathbf{\mu}_k^{(t-1)})^2&amp;lt;/math&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
  &amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&lt;br /&gt;
    &amp;lt;b&amp;gt;Пересчет центров кластеров&amp;lt;/b&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Шаг &amp;lt;/b&amp;gt; &amp;lt;math&amp;gt;t: \forall i=\overline{1,k}:  \mu_i^{(t)} = \cfrac{1}{|S_i|}\sum_{\mathbf{x}\in S_i}\mathbf{x}&amp;lt;/math&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
  &amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&lt;br /&gt;
    &amp;lt;b&amp;gt;Проверка условия останова:&amp;lt;/b&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
    &#039;&#039;&#039;if&#039;&#039;&#039; &amp;lt;math&amp;gt;\exist i\in \overline{1,k}: \mu_i^{(t)} \ne \mu_i^{(t-1)}&amp;lt;/math&amp;gt; &#039;&#039;&#039;then&#039;&#039;&#039;&lt;br /&gt;
        t = t + 1;&lt;br /&gt;
        goto 2;&lt;br /&gt;
    &#039;&#039;&#039;else&#039;&#039;&#039;&lt;br /&gt;
        &#039;&#039;&#039;stop&#039;&#039;&#039;&lt;br /&gt;
  &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ol&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Вычислительное ядро алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Вычислительным ядром являются шаги 2 и 3 приведенного выше алгоритма: &amp;lt;b&amp;gt;&amp;lt;i&amp;gt;распределение векторов по кластерам&amp;lt;/i&amp;gt;&amp;lt;/b&amp;gt; и &amp;lt;b&amp;gt;&amp;lt;i&amp;gt;пересчет центров кластеров&amp;lt;/i&amp;gt;&amp;lt;/b&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;&amp;lt;i&amp;gt;Распределение векторов&amp;lt;/i&amp;gt;&amp;lt;/b&amp;gt; по кластерам предполагает вычисление расстояний между каждым вектором &amp;lt;math&amp;gt;\mathbf{x}_i \in X, i= \overline{1,n}&amp;lt;/math&amp;gt; и центрами кластера &amp;lt;math&amp;gt;\mathbf{\mu}_j, j= \overline{1,k}&amp;lt;/math&amp;gt;. Таким образом, данный шаг предполагает &amp;lt;math&amp;gt;k*n&amp;lt;/math&amp;gt; вычислений расстояний между d-мерными векторами. &lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;&amp;lt;i&amp;gt;Пересчет центров кластеров&amp;lt;/i&amp;gt;&amp;lt;/b&amp;gt; предполагает &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; вычислений центров масс &amp;lt;math&amp;gt;\mathbf{\mu}_i&amp;lt;/math&amp;gt; множеств &amp;lt;math&amp;gt;S_i, i=\overline{1,k}&amp;lt;/math&amp;gt; представленных выражением в шаге 3 представленного выше алгоритма.&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Макроструктура алгоритма ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Инициализация центров масс &amp;lt;math&amp;gt;\mu_1, ..., \mu_k&amp;lt;/math&amp;gt;&amp;lt;/b&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
Наиболее распространенными являются следующие стратегии:&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&lt;br /&gt;
    &amp;lt;b&amp;gt;Метод Forgy&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;В качестве начальных значений &amp;lt;math&amp;gt;\mu_1, ..., \mu_k&amp;lt;/math&amp;gt; берутся случайно выбранные векторы.&lt;br /&gt;
  &amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&lt;br /&gt;
    &amp;lt;b&amp;gt;Метод случайно разделения (Random Partitioning)&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;Для каждого вектора &amp;lt;math&amp;gt;\mathbf{x}_i \in X, i=\overline{1, n}&amp;lt;/math&amp;gt; выбирается случайным образом кластер &amp;lt;math&amp;gt;S_1, ..., S_k&amp;lt;/math&amp;gt;, после чего для каждого полученного кластера вычисляются значения &amp;lt;math&amp;gt;\mu_1, ..., \mu_k&amp;lt;/math&amp;gt;.&lt;br /&gt;
  &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Распределение векторов по кластерам&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Для этого шага алгоритма между векторами &amp;lt;math&amp;gt;\mathbf{x}_i \in X, i=\overline{1, n}&amp;lt;/math&amp;gt; и центрами кластеров &amp;lt;math&amp;gt;\mu_1, ..., \mu_k&amp;lt;/math&amp;gt; вычисляются &amp;lt;b&amp;gt;расстояния&amp;lt;/b&amp;gt; по формуле (как правило, используется Евлидово расстояние):&lt;br /&gt;
&amp;lt;table style=&amp;quot;width:100%&amp;quot;&amp;gt;&lt;br /&gt;
  &amp;lt;tr&amp;gt;&lt;br /&gt;
    &amp;lt;td align=&amp;quot;center&amp;quot; width=&amp;quot;90%&amp;quot;&amp;gt;&amp;lt;math&amp;gt; \mathbf{v}_1, \mathbf{v}_2 \in \mathbb{R}^d,  \quad \rho(\mathbf{v}_1, \mathbf{v}_2) = \lVert \mathbf{v}_1- \mathbf{v}_2 \rVert= \sqrt{\sum_{i=1}^{d}(\mathbf{v}_{1,i} - \mathbf{v}_{2,i})^2}&amp;lt;/math&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;td align=&amp;quot;right&amp;quot;&amp;gt;&amp;lt;math&amp;gt;(2)&amp;lt;/math&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;/table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Пересчет центров кластеров&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Для этого шага алгоритма производится пересчет центров кластера по &amp;lt;b&amp;gt;формуле вычисления центра масс&amp;lt;/b&amp;gt;:&lt;br /&gt;
&amp;lt;table style=&amp;quot;width:100%&amp;quot;&amp;gt;&lt;br /&gt;
  &amp;lt;tr&amp;gt;&lt;br /&gt;
    &amp;lt;td align=&amp;quot;center&amp;quot; width=&amp;quot;90%&amp;quot;&amp;gt;&amp;lt;math&amp;gt; \mu = \cfrac{1}{|S|}\sum_{\mathbf{x}\in S}\mathbf{x}&amp;lt;/math&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;td align=&amp;quot;right&amp;quot;&amp;gt;&amp;lt;math&amp;gt;(3)&amp;lt;/math&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;/table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Схема реализации последовательного алгоритма ===&lt;br /&gt;
&lt;br /&gt;
 &#039;&#039;&#039;algorithm&#039;&#039;&#039; k-means &#039;&#039;&#039;is&#039;&#039;&#039;&lt;br /&gt;
     &#039;&#039;&#039;1.&#039;&#039;&#039; Инициализировать центры кластеров &amp;lt;math&amp;gt;\mathbf{\mu}_i^{(1)}, i=\overline{1,k}&amp;lt;/math&amp;gt;&lt;br /&gt;
     &#039;&#039;&#039;2.&#039;&#039;&#039; &amp;lt;math&amp;gt;t \leftarrow 1&amp;lt;/math&amp;gt;&lt;br /&gt;
     &#039;&#039;&#039;3.&#039;&#039;&#039; &#039;&#039;&#039;Распределение по кластерам&#039;&#039;&#039;&amp;lt;br&amp;gt;&lt;br /&gt;
        &amp;lt;math&amp;gt;S_i^{(t)}=\{\mathbf{x}_p: \lVert\mathbf{x}_p-\mathbf{\mu}_i^{(t)}\rVert^2 \leq \lVert\mathbf{x}_p-\mathbf{\mu}_j^{(t)}\rVert^2 \quad \forall j=\overline{1,k}\},&amp;lt;/math&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
        где каждый вектор &amp;lt;math&amp;gt;\mathbf{x}_p&amp;lt;/math&amp;gt; соотносится единственному кластеру &amp;lt;math&amp;gt;S^{(t)}&amp;lt;/math&amp;gt;&lt;br /&gt;
     &#039;&#039;&#039;4.&#039;&#039;&#039; &#039;&#039;&#039;Обновление центров кластеров&#039;&#039;&#039;&amp;lt;br&amp;gt;&lt;br /&gt;
        &amp;lt;math&amp;gt;\mathbf{\mu}_i^{(t+1)} = \frac{1}{|S^{(t)}_i|} \sum_{\mathbf{x}_j \in S^{(t)}_i} \mathbf{x}_j &amp;lt;/math&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
     &#039;&#039;&#039;5.&#039;&#039;&#039; &#039;&#039;&#039;if&#039;&#039;&#039; &amp;lt;math&amp;gt;\exist i \in \overline{1,k}: \mathbf{\mu}_i^{(t+1)} \ne \mathbf{\mu}_i^{(t)}&amp;lt;/math&amp;gt; &#039;&#039;&#039;then&#039;&#039;&#039;&lt;br /&gt;
            t = t + 1;&lt;br /&gt;
            goto &#039;&#039;&#039;3&#039;&#039;&#039;;&lt;br /&gt;
        &#039;&#039;&#039;else&#039;&#039;&#039;&lt;br /&gt;
            &#039;&#039;&#039;stop&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
=== Последовательная сложность алгоритма===&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding-bottom: 20px&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;Обозначим &amp;lt;math&amp;gt;\Theta_{centroid}^{d, m}&amp;lt;/math&amp;gt; временную сложность вычисления центорида кластера, число элементов которого равна &amp;lt;math&amp;gt;m&amp;lt;/math&amp;gt;,  в d-мерном пространстве.&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;Аналогично  &amp;lt;math&amp;gt;\Theta_{distance}^d&amp;lt;/math&amp;gt; &amp;amp;ndash; временная сложность вычисления расстояния между двумя d-мерными векторами.&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding-bottom: 20px&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;Сложность шага инициализации &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластеров мощности &amp;lt;math&amp;gt;m&amp;lt;/math&amp;gt; в d-мерном пространстве &amp;amp;ndash; &amp;lt;math&amp;gt;\Theta_{init}^{k, d, m}&amp;lt;/math&amp;gt;&amp;lt;/b&amp;gt;&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;i&amp;gt;Стратерия Forgy&amp;lt;/i&amp;gt;: вычисления не требуются, &amp;lt;math&amp;gt;\Theta_{init}^{k, d, m} = 0&amp;lt;/math&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;i&amp;gt;Стратегия случайного разбиения&amp;lt;/i&amp;gt;: вычисление центров &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластеров,  &amp;lt;math&amp;gt;\Theta_{init}^{k, d, m} = k*\Theta_{centroid}^{d, m}, m \le n&amp;lt;/math&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding-bottom: 20px&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Cложность шага распределения d мерных векторов по &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластерам &amp;amp;ndash; &amp;lt;math&amp;gt;\Theta_{distribute}^{k, d}&amp;lt;/math&amp;gt;&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
На этом шаге для каждого вектора &amp;lt;math&amp;gt;\mathbf{x}_i \in X, i=\overline{1, n}&amp;lt;/math&amp;gt; вычисляется k расстояний до центров кластеров &amp;lt;math&amp;gt;\mathbf{\mu}_1, ...\mathbf{\mu}_k&amp;lt;/math&amp;gt;&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p align=&amp;quot;center&amp;quot;&amp;gt;&lt;br /&gt;
  &amp;lt;math&amp;gt;\Theta_{distribute}^{k, d} = n*k*\Theta_{distance}^d&amp;lt;/math&amp;gt;&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding-bottom: 20px&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;Сложность шага пересчета центров &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластеров размера &amp;lt;math&amp;gt;m&amp;lt;/math&amp;gt; в d-мерном пространстве &amp;amp;ndash; &amp;lt;math&amp;gt;\Theta_{recenter}^{k, d, m}&amp;lt;/math&amp;gt;&amp;lt;/b&amp;gt;&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;На этом шаге вычисляется &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; центров кластеров &amp;lt;math&amp;gt;\mathbf{\mu}_1, ...\mathbf{\mu}_k&amp;lt;/math&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p align=&amp;quot;center&amp;quot;&amp;gt;&amp;lt;math&amp;gt;\Theta_{recenter}^{k, d, m} = k*\Theta_{centroid}^{d, m}&amp;lt;/math&amp;gt; &amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding-bottom: 20px&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Рассчитаем &amp;lt;math&amp;gt;\Theta_{centroid}^{d, m}&amp;lt;/math&amp;gt; для кластера, число элементов которого равно &amp;lt;math&amp;gt;m&amp;lt;/math&amp;gt;&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p align=&amp;quot;center&amp;quot;&amp;gt;&amp;lt;math&amp;gt;\Theta_{centroid}^{d, m}&amp;lt;/math&amp;gt; = &amp;lt;math&amp;gt;m * d&amp;lt;/math&amp;gt; сложений + &amp;lt;math&amp;gt;d&amp;lt;/math&amp;gt; делений &amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding-bottom: 20px&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Рассчитаем &amp;lt;math&amp;gt;\Theta_{distance}^d&amp;lt;/math&amp;gt; в соответствие с формулой &amp;lt;math&amp;gt;(2)&amp;lt;/math&amp;gt;&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p align=&amp;quot;center&amp;quot;&amp;gt;&amp;lt;math&amp;gt;\Theta_{distance}^d&amp;lt;/math&amp;gt; = &amp;lt;math&amp;gt;d&amp;lt;/math&amp;gt; вычитаний + &amp;lt;math&amp;gt;d&amp;lt;/math&amp;gt; умножений + &amp;lt;math&amp;gt;(d-1)&amp;lt;/math&amp;gt; сложение&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding-bottom: 20px&amp;quot;&amp;gt;&lt;br /&gt;
  &amp;lt;p&amp;gt;Предположим, что алгоритм сошелся за &amp;lt;math&amp;gt;\Tau&amp;lt;/math&amp;gt; итераций, тогда временная сложность алгоритма &amp;lt;math&amp;gt;\Theta_{k-means}^{d, n}&amp;lt;/math&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
  &amp;lt;p align=&amp;quot;center&amp;quot;&amp;gt;&amp;lt;b&amp;gt;&amp;lt;math&amp;gt;\Theta_{k-means}^{d, n} \le \Theta_{init}^{k, d, n} + \Tau*(\Theta_{distribute}^{k, d} + \Theta_{recenter}^{k, d, n})&amp;lt;/math&amp;gt;&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding-bottom: 5px&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;Операции сложения/вычитания:&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p align=&amp;quot;center&amp;quot;&amp;gt;&amp;lt;b&amp;gt;&amp;lt;math&amp;gt;\Theta_{k-means}^{d, n} \le k*n*d+ \Tau*(k*n*(2d-1) + k*n*d) = k*n*d+ \Tau*(k*n*(3d-1)) \thicksim O(\Tau*k*d*n)&amp;lt;/math&amp;gt;&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding-bottom: 20px&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;Операции умножения/деления:&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p align=&amp;quot;center&amp;quot;&amp;gt;&amp;lt;b&amp;gt;&amp;lt;math&amp;gt;\Theta_{k-means}^{d, n} \le k*d + \Tau*(k*n*d + k*d) = k*d + \Tau * k*d*(n+1) \thicksim O(\Tau*k*d*n) &amp;lt;/math&amp;gt;&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding-bottom: 20px&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;Получаем, что &amp;lt;b&amp;gt;временная сложность&amp;lt;/b&amp;gt; алгоритма &amp;lt;b&amp;gt;k means&amp;lt;/b&amp;gt; кластеризации &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; &amp;lt;b&amp;gt;d-мерных&amp;lt;/b&amp;gt; векторов на &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластеров за &amp;lt;math&amp;gt;\Tau&amp;lt;/math&amp;gt; итераций:&amp;lt;/p&amp;gt;&lt;br /&gt;
 &amp;lt;p align=&amp;quot;center&amp;quot;&amp;gt;&amp;lt;b&amp;gt;&amp;lt;math&amp;gt; \Theta_{k-means}^{d, n} \thicksim O(\Tau*k*d*n) &amp;lt;/math&amp;gt;&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Информационный граф ===&lt;br /&gt;
&lt;br /&gt;
Рассмотрим информационный граф алгоритма. Алгоритм &amp;lt;i&amp;gt;k means&amp;lt;/i&amp;gt; начинается с этапа инициализации, после которого следуют итерации, на каждой из которых выполняется два последовательных шага (см. [[#Схема реализации последовательного алгоритма|&amp;quot;Схема реализации последовательного алгоритма&amp;quot;]]): &lt;br /&gt;
* распределение векторов по кластерам&lt;br /&gt;
* перерасчет центров кластеров&lt;br /&gt;
&lt;br /&gt;
Поскольку основная часть вычислений приходится на шаги итераций, распишем информационные графы данных шагов.&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Распределение векторов по кластерам&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
Информационный граф шага распределения векторов по кластерам представлен на &#039;&#039;рисунке 1&#039;&#039;. Исходами данного графа является исходные векторы &amp;lt;math&amp;gt;\mathbf{x}_1, ..., \mathbf{x}_n&amp;lt;/math&amp;gt;, а также центры кластеров &amp;lt;math&amp;gt;\mathbf{\mu}_1, ... \mathbf{\mu}_k&amp;lt;/math&amp;gt;, вычисленные ранее (на шаге инициализации, если рассматривается первая итерация алгоритма, или на шаге пересчета центров кластеров предыдущей итерации в противном случае). Каждая пара векторов данных &amp;lt;math&amp;gt;\mathbf{x}_i, i=\overline{1,n}&amp;lt;/math&amp;gt; и центров кластера &amp;lt;math&amp;gt;\mathbf{\mu}_j, j=\overline{1, k}&amp;lt;/math&amp;gt; : (&amp;lt;math&amp;gt;\mathbf{x}_i&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;\mathbf{\mu}_j&amp;lt;/math&amp;gt;) подаются на независимые узлы &amp;lt;i&amp;gt;&amp;quot;d&amp;quot;&amp;lt;/i&amp;gt; вычисления расстояния между векторами (более подробная схема вычисления расстояния представлена далее, &#039;&#039;рисунок 2&#039;&#039;). Далее узлы вычисления расстояния &amp;lt;i&amp;gt;&amp;quot;d&amp;quot;&amp;lt;/i&amp;gt;, соответствующие одному и тому же исходному вектору &amp;lt;math&amp;gt;\mathbf{x}_i&amp;lt;/math&amp;gt; передаются на один узел &amp;lt;i&amp;gt;&amp;quot;m&amp;quot;&amp;lt;/i&amp;gt;, где далее происходит вычисление новой метки кластера для каждого вектора &amp;lt;math&amp;gt;\mathbf{x}_i&amp;lt;/math&amp;gt; (берется кластер с минимальным результатом вычисления расстояния). На выходе графа выдаются метки кластеров , &amp;lt;math&amp;gt;L_1, ..., L_n&amp;lt;/math&amp;gt;, такие что &amp;lt;math&amp;gt;\forall \mathbf{x}_i, i=\overline{1, n}, \mathbf{x}_i \in S_j \Leftrightarrow L_i = j&amp;lt;/math&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
[[file:Clusterization.png|thumb|center|800px|Рис. 1. Схема распределения векторов по кластерам. &#039;&#039;d&#039;&#039; &amp;amp;ndash; вычисление расстояния между векторами; &#039;&#039;m&#039;&#039; &amp;amp;ndash; вычисление минимума.]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Вычисление расстояния между векторами&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
Подробная схема вычисления расстояния между векторами &amp;lt;math&amp;gt;\mathbf{x}_i, \mathbf{\mu}_j&amp;lt;/math&amp;gt; представлена на &#039;&#039;рисунке 2&#039;&#039;. Как показано на графе, узел вычисления расстояния между векторами &amp;lt;i&amp;gt;&amp;quot;d&amp;quot;&amp;lt;/i&amp;gt; состоит из шага взятия разности между векторами (узел &amp;quot;&amp;lt;math&amp;gt;-&amp;lt;/math&amp;gt;&amp;quot;) и взятия нормы получившегося вектора разности (узел &amp;quot;&amp;lt;math&amp;gt;||\cdot||^2&amp;lt;/math&amp;gt;&amp;quot;). Более подробно, вычисление расстояния между векторами &amp;lt;math&amp;gt;\mathbf{x}_i = {x_{i1,}, ...,{x_{in}}}, \mathbf{\mu}_j = {\mu_{j1}, ...,\mu_{jn}}&amp;lt;/math&amp;gt; может быть представлено как вычисление разности между каждой парой компонент &amp;lt;math&amp;gt;(x_{iz}, \mu_{jz}), z=\overline{1, d}&amp;lt;/math&amp;gt; (узел &amp;quot;&amp;lt;math&amp;gt;-&amp;lt;/math&amp;gt;&amp;quot;), далее возведение в квадрат для каждого узла &amp;quot;&amp;lt;math&amp;gt;-&amp;lt;/math&amp;gt;&amp;quot; (узел &amp;quot;&amp;lt;math&amp;gt;()^2&amp;lt;/math&amp;gt;&amp;quot;) и суммирования выходов всех узлов &amp;quot;&amp;lt;math&amp;gt;()^2&amp;lt;/math&amp;gt;&amp;quot; (узел &amp;quot;&amp;lt;math&amp;gt;+&amp;lt;/math&amp;gt;&amp;quot;).  &lt;br /&gt;
&lt;br /&gt;
[[file:dist_calc.png|thumb|center|800px|Рис. 2. Схема вычисления расстояния между вектором и центром кластера.]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Пересчет центров кластеров&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
Информационный граф шага пересчета центров кластеров представлен на &#039;&#039;рисунке 3&#039;&#039;. Исходами данного графа является исходные векторы &amp;lt;math&amp;gt;\mathbf{x}_1, ..., \mathbf{x}_n&amp;lt;/math&amp;gt;, а также им соответствующие метки кластера, &amp;lt;math&amp;gt;L_1, ..., L_n&amp;lt;/math&amp;gt;, такие что &amp;lt;math&amp;gt;\forall x_i, i=\overline{1, n}, \mathbf{x}_i \in S_j \Leftrightarrow L_i = j&amp;lt;/math&amp;gt;, вычисленные на этапе распределения векторов по кластерам. Все векторы &amp;lt;math&amp;gt;\mathbf{x}_1, ..., \mathbf{x}_n&amp;lt;/math&amp;gt; подаются в узлы &amp;lt;math&amp;gt;+_1, ...+_k&amp;lt;/math&amp;gt;, каждый узел &amp;lt;math&amp;gt;+_m, m = \overline{1,k}&amp;lt;/math&amp;gt; соответствует операции сложения векторов кластера с номером &amp;lt;math&amp;gt;m&amp;lt;/math&amp;gt;. Метки кластера &amp;lt;math&amp;gt;L_1, ..., L_n&amp;lt;/math&amp;gt; также совместно передаются на узлы &amp;lt;math&amp;gt;S_m, m = \overline{1,k}&amp;lt;/math&amp;gt;, на каждом из которых вычисляется количество векторов в соответствующем кластере (количество меток с соответствующим значением). Далее каждая пара выходов узлов &amp;lt;math&amp;gt;+_m&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;S_m&amp;lt;/math&amp;gt; подается на узел &amp;quot;&amp;lt;math&amp;gt;/&amp;lt;/math&amp;gt;&amp;quot;, где производится деление суммы векторов кластера на количество элементов в нем. Значения, вычисленные на узлах &amp;quot;&amp;lt;math&amp;gt;/&amp;lt;/math&amp;gt;&amp;quot;, присваиваются новым центрам кластеров (выходные значения графа).&lt;br /&gt;
&lt;br /&gt;
[[file:Recluster.png|thumb|center|800px|Рис. 3. Схема пересчета центров кластеров]]&lt;br /&gt;
&lt;br /&gt;
=== Ресурс параллелизма алгоритма ===&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
Работа алгоритма состоит из &amp;lt;math&amp;gt;\Tau&amp;lt;/math&amp;gt; итераций, в каждой из которых происходит &amp;lt;b&amp;gt;распределение d-мерных векторов по &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластерам&amp;lt;/b&amp;gt;, а также &amp;lt;b&amp;gt;пересчет центров кластеров в d-мерном пространстве&amp;lt;/b&amp;gt;. В шаге &amp;lt;b&amp;gt;распределения d-мерных векторов по &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластерам&amp;lt;/b&amp;gt; расстояния между вектором и центрами кластеров вычисляются независимо (отсутствуют информационные зависимости). &amp;lt;b&amp;gt;Центры масс кластеров&amp;lt;/b&amp;gt; также пересчитываются независимо друг от друга. Таким образом, имеет место [[глоссарий#Массовый параллелизм|&#039;&#039;массовый параллелизм&#039;&#039;]]. Вычислим параллельную сложность &amp;lt;math&amp;gt;\Psi_*&amp;lt;/math&amp;gt; каждого из шагов, а также параллельную сложность всего алгоритма, &amp;lt;math&amp;gt;\Psi_{k-means}&amp;lt;/math&amp;gt;. Будем исходить из предположения, что может быть использовано любое необходимое число потоков.&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Распределение d-мерных векторов по &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластерам&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;  &lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
Поскольку на данном шаге для каждой пары векторов &amp;lt;math&amp;gt;\mathbf{x}_i, i=\overline{1,n}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\mathbf{\mu}_j, j=\overline{1,k}&amp;lt;/math&amp;gt; операции вычисления расстояния не зависят друг от друга, они могут выполняться параллельно. Тогда, разделив все вычисление расстояний на &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; потоков, получим, что в каждом потоке будет выполняться только одна операция вычисления расстояния между векторами размерности d. При этом каждому вычислительному потоку передаются координаты центров всех кластеров &amp;lt;math&amp;gt;\mathbf{\mu}_1, ..., \mathbf{\mu}_k&amp;lt;/math&amp;gt;. Таким образом, параллельная сложность данного шага определяется &amp;lt;i&amp;gt; сложностью параллельной операции вычисления расстояния между d-мерными векторами&amp;lt;/i&amp;gt;, &amp;lt;math&amp;gt;\Psi_{distance}^d&amp;lt;/math&amp;gt;  и &amp;lt;i&amp;gt;сложностью определения наиболее близкого кластера&amp;lt;/i&amp;gt; (паралельное взятие минимума по расстояниям), &amp;lt;math&amp;gt;\Psi_{min}^k&amp;lt;/math&amp;gt;. Для оценки &amp;lt;math&amp;gt;\Psi_{distance}^d&amp;lt;/math&amp;gt; воспользуемся  [[Нахождение_частных_сумм_элементов_массива_сдваиванием | параллельной реализацией нахождения частичной суммы элементов массива путем сдваивания]]. Аналогично, &amp;lt;math&amp;gt;\Psi_{min}^k = log(k)&amp;lt;/math&amp;gt;. В результате, &amp;lt;math&amp;gt;\Psi_{distance}^d = O(log(d))&amp;lt;/math&amp;gt;.   Таким образом: &lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p align=&amp;quot;center&amp;quot;&amp;gt;&amp;lt;math&amp;gt;\Psi_{distribute}^{k, d}  = \Psi_{distance}^d + \Psi_{min}^k = O(log(d))+O(log(k)) = O(log(k*d))&amp;lt;/math&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Пересчет центров кластеров в d-мерном пространстве&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
Поскольку на данном шаге для каждого из &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластеров центр масс может быть вычислен независимо, данные операции могут быть выполнены в отдельных потоках. Таким образом, параллельная сложность данного шага, &amp;lt;math&amp;gt;\Psi_{recenter}^{k, d}&amp;lt;/math&amp;gt;,  будет определяться &amp;lt;i&amp;gt;параллельной сложностью вычисления одного центра масс кластера размера &amp;lt;math&amp;gt;m&amp;lt;/math&amp;gt;&amp;lt;/i&amp;gt;, &amp;lt;math&amp;gt;\Psi_{recenter}^{k, d}&amp;lt;/math&amp;gt;,  а так как &amp;lt;math&amp;gt;m \le n \Rightarrow \Psi_{recenter}^{d, m} \le \Psi_{recenter}^{d, n}&amp;lt;/math&amp;gt;. Сложность вычисления центра масс кластера d-мерных векторов размера n аналогично предыдущим вычислениям равна &amp;lt;math&amp;gt;O(log(n))&amp;lt;/math&amp;gt;. Тогда:  &lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p align=&amp;quot;center&amp;quot;&amp;gt;&amp;lt;math&amp;gt;\Psi_{recenter}^{k, d}  \le \Psi_{recenter}^{d, n} = O(log(n))&amp;lt;/math&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Общая параллельная сложность алгоритма&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
На каждой итерации необходимо обновление центров кластеров, которые будут использованы на следующей итерации. Таким образом, итерационный процесс выполняется последовательно&amp;lt;ref&amp;gt;Zhao, Weizhong, Huifang Ma, and Qing He. &amp;quot;Parallel k-means clustering based on mapreduce.&amp;quot; IEEE International Conference on Cloud Computing. Springer Berlin Heidelberg, 2009.&amp;lt;/ref&amp;gt;. Тогда, поскольку сложность каждой итерации  определяется &amp;lt;math&amp;gt;\Psi_{distribute}^{k, d}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\Psi_{recenter}&amp;lt;/math&amp;gt;, сложность всего алгоритма, &amp;lt;math&amp;gt;\Psi_{k-means}&amp;lt;/math&amp;gt; в предположении, что было сделано &amp;lt;math&amp;gt;\Tau&amp;lt;/math&amp;gt; операций определяется выражением&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p align=&amp;quot;center&amp;quot;&amp;gt;&amp;lt;math&amp;gt;\Psi_{k-means} \approx \Tau * (\Psi_{distribute}^{k, d} + \Psi_{recenter}^{k, d}) \le \Tau * O(log(k*d*n))&amp;lt;/math&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Входные и выходные данные алгоритма ===&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;Входные данные&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;Матрица из &amp;lt;math&amp;gt;n*d&amp;lt;/math&amp;gt; элементов &amp;lt;math&amp;gt;x_{i, j} \in \mathbb{R}, i=\overline{1, n}, j=\overline{1, d}&amp;lt;/math&amp;gt;&amp;amp;ndash; координат векторов (наблюдений).&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;Целое положительное число &amp;lt;math&amp;gt;k, k \le n&amp;lt;/math&amp;gt; &amp;amp;ndash; количество кластеров.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;Объем входных данных&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;math&amp;gt;1&amp;lt;/math&amp;gt; целое число + &amp;lt;math&amp;gt;n*d&amp;lt;/math&amp;gt; вещественных чисел (при условии, что координаты &amp;amp;ndash; вещественные числа).&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;Выходные данные&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; целых положительных чисел &amp;lt;math&amp;gt;L_1, ..., L_n&amp;lt;/math&amp;gt;&amp;amp;ndash; номера кластеров, соотвествующие каждому вектору (при условии, что нумерация кластеров начинается с &amp;lt;math&amp;gt;1&amp;lt;/math&amp;gt;).&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;Объем выходных данных&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; целых положительных чисел.&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Свойства алгоритма ===&lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;[[глоссарий#Вычислительная мощность|&#039;&#039;Вычислительная мощность&#039;&#039;]]&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
Вычислительная мощность алгоритма &amp;lt;i&amp;gt;k means&amp;lt;/i&amp;gt; равна &amp;lt;math&amp;gt;\frac{k*d*n*\Tau}{n*d} = k*\Tau &amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; &amp;amp;ndash; число кластеров, &amp;lt;math&amp;gt;\Tau&amp;lt;/math&amp;gt; &amp;amp;ndash; число итераций алгоритма.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;[[глоссарий#Детерминированность |&#039;&#039;Детерминированность&#039;&#039;]] и [[глоссарий#Устойчивость |&#039;&#039;Устойчивость&#039;&#039;]] &amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
Алгоритм &amp;lt;i&amp;gt;k means&amp;lt;/i&amp;gt; является итерационным. Количество итераций алгоритма в общем случае не фиксируется и зависит от начального расположения объектов в пространстве, параметра &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt;, а также от начального приближения центров кластеров, &amp;lt;math&amp;gt;\mu_1, ..., \mu_k&amp;lt;/math&amp;gt;. В результате этого может варьироваться результат работы алгоритма. При неудачном выборе начальных параметров итерационный процесс может сойтись к локальному оптимуму&amp;lt;ref&amp;gt;Von Luxburg, Ulrike. Clustering Stability. Now Publishers Inc, 2010.&amp;lt;/ref&amp;gt;. По этим причинам алгоритм не является ни &amp;lt;b&amp;gt;детермирированным&amp;lt;/b&amp;gt;, ни &amp;lt;b&amp;gt;устойчивым&amp;lt;/b&amp;gt;.&lt;br /&gt;
 &lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Соотношение последовательной и параллельной сложности алгоритма&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\frac{\Theta_{k-means}}{\Psi_{k-means}} = \frac{O(\Tau*k*d*n)}{O(\Tau*log(k*d*n))}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Сильные стороны алгоритма&amp;lt;/b&amp;gt;:&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;i&amp;gt;Сравнительно высокая эффективность при простоте реализации&amp;lt;/i&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;i&amp;gt;Высокое качество кластеризации&amp;lt;/i&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;i&amp;gt;Возможность распараллеливания&amp;lt;/i&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;i&amp;gt;Существование множества модификаций&amp;lt;/i&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;Недостатки алгоритма&amp;lt;/b&amp;gt;&amp;lt;ref&amp;gt;Ortega, Joaquín Pérez, Ma Del Rocío Boone Rojas, and María J. Somodevilla. &amp;quot;Research issues on K-means Algorithm: An Experimental Trial Using Matlab.&amp;quot;&amp;lt;/ref&amp;gt;:&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;i&amp;gt;Количество кластеров является параметром алгоритма&amp;lt;/i&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;&amp;lt;i&amp;gt;Чувствительность к начальным условиям&amp;lt;/i&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;Инициализация центров кластеров в значительной степени влияет на результат кластеризации.&amp;lt;/p&amp;gt;&lt;br /&gt;
  &amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;&amp;lt;i&amp;gt;Чувствительность к выбросам и шумам&amp;lt;/i&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;Выбросы, далекие от центров настоящих кластеров, все равно учитываются при вычислении их центров.&amp;lt;/p&amp;gt;&lt;br /&gt;
  &amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;&amp;lt;i&amp;gt;Возможность сходимости к локальному оптимуму&amp;lt;/i&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;Итеративный подход не дает гарантии сходимости к оптимальному решению.&amp;lt;/p&amp;gt;&lt;br /&gt;
  &amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;&amp;lt;i&amp;gt;Использование понятия &amp;quot;среднего&amp;quot;&amp;lt;/i&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;Алгоритм неприменим к данным, для которых не определено понятие &amp;quot;среднего&amp;quot;, например, категориальным данным.&amp;lt;/p&amp;gt;&lt;br /&gt;
  &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&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;
Исследование масштабируемости параллельной реализации алгоритма k means проводилось на суперкомпьютере &amp;quot;Ломоносов&amp;quot;. Алгоритм реализован на языке C с использованием средств MPI.&lt;br /&gt;
Для исследования масштабируемости проводилось множество запусков программы с разным значением параметра (количество векторов для кластеризации), а также с различным числом процессоров. Фиксировались результаты запусков &amp;amp;ndash; время работы &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt; и количество произведенных итераций алгоритма &amp;lt;math&amp;gt;\Tau&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Параметры запусков для экспериментальной оценки:&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;Значения &amp;lt;b&amp;gt;количества векторов&amp;lt;/b&amp;gt; &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;: 20&#039;000, 30&#039;000, 50&#039;000, 100&#039;000, 200&#039;000, 300&#039;000, 500&#039;000, 700&#039;000, 1&#039;000&#039;000, 1&#039;500&#039;000, 2&#039;000&#039;000.&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;Значения &amp;lt;b&amp;gt;количества процессоров&amp;lt;/b&amp;gt; &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt;: 1, 8, 16, 32, 64, 128, 160, 192, 224, 256, 288, 320, 352, 384, 416, 448, 480, 512.&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;Значение &amp;lt;b&amp;gt;количества кластеров&amp;lt;/b&amp;gt; &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt;: 100.&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;Значение &amp;lt;b&amp;gt;размерности векторов&amp;lt;/b&amp;gt; &amp;lt;math&amp;gt;d&amp;lt;/math&amp;gt;: 10.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Для проведения экспериментов были сгенерированы нормально распределенные псевдослучайные данные (с использованием Python библиотеки scikit-learn):&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
from sklearn.datasets import make_classification&lt;br /&gt;
X1, Y1 = make_classification(n_features=10, n_redundant=2, n_informative=8,&lt;br /&gt;
                             n_clusters_per_class=1, n_classes=100,&lt;br /&gt;
                             n_samples=2000000)&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Графики производительности и эффективности реализации представлены на рисунках 4 и 5 соответственно.&lt;br /&gt;
&lt;br /&gt;
[[file:Flops.png|thumb|center|800px|Рис. 4. График производительности реализации алгоритма.]]&lt;br /&gt;
&lt;br /&gt;
[[file:Efficiency.png|thumb|center|800px|Рис. 5. График эффективности реализации алгоритма.]]&lt;br /&gt;
&lt;br /&gt;
Для заданной конфигурации эксперимента (&amp;lt;math&amp;gt;n, d, p, k&amp;lt;/math&amp;gt;) и полученных результатах (&amp;lt;math&amp;gt;t, \Tau&amp;lt;/math&amp;gt;) производительность и эффективность реализации расчитывались по формулам (см. [[#Последовательная сложность алгоритма| последовательная сложность алгоритма]]):&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
&amp;lt;ul&amp;gt;&amp;lt;li&amp;gt;&amp;lt;math&amp;gt;Performance = \frac{\Theta_{k-means}^{d, n}}{t}\ \ FLOPS&amp;lt;/math&amp;gt;&amp;lt;/li&amp;gt;&amp;lt;/ul&amp;gt;&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
&amp;lt;ul&amp;gt;&amp;lt;li&amp;gt;&amp;lt;math&amp;gt;Efficiency = \frac{100 * Performance}{Performance_{Peak}^{p}}\ \ %,&amp;lt;/math&amp;gt;&amp;lt;/li&amp;gt;&amp;lt;/ul&amp;gt;&lt;br /&gt;
где &amp;lt;math&amp;gt;Performance_{Peak}^{p}&amp;lt;/math&amp;gt; &amp;amp;ndash; пиковая производительность суперкомпьютера при &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt; процессорах, вычисленная согласно спецификациям Intel&amp;lt;sup&amp;gt;&amp;amp;reg;&amp;lt;/sup&amp;gt; XEON&amp;lt;sup&amp;gt;&amp;amp;reg;&amp;lt;/sup&amp;gt; X5670&amp;lt;ref&amp;gt;&amp;quot;http://ark.intel.com/ru/products/47920/Intel-Xeon-Processor-X5670-12M-Cache-2_93-GHz-6_40-GTs-Intel-QPI&amp;quot;&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;В результате&amp;lt;/b&amp;gt; экспериментальной оценки были получены следующие оценки эффективности реализации:&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;b&amp;gt;Минимальное&amp;lt;/b&amp;gt; значение: 0.000409 % достигается при &amp;lt;math&amp;gt;n=20&#039;000, p=480&amp;lt;/math&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;b&amp;gt;Максимальное&amp;lt;/b&amp;gt; значение: 0.741119 % достигается при &amp;lt;math&amp;gt;n=300&#039;000, p=1&amp;lt;/math&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
Оценки масштабируемости реализации алгоритма k means:&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;b&amp;gt;По числу процессоров:&amp;lt;/b&amp;gt; -0.002683 &amp;amp;ndash; эффективность убывает с ростом числа процессоров.&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;b&amp;gt;По размеру задачи:&amp;lt;/b&amp;gt; 0.002779 &amp;amp;ndash; эффективность растет с ростом числа векторов.&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;b&amp;gt;Общая оценка:&amp;lt;/b&amp;gt; -0.000058 &amp;amp;ndash; можно сделать вывод, что в целом эффективность реализации незначительно уменьшается.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Динамические характеристики и эффективность реализации алгоритма ===&lt;br /&gt;
=== Выводы для классов архитектур ===&lt;br /&gt;
=== Существующие реализации алгоритма ===&lt;br /&gt;
==== Открытое программное обеспечение ====&lt;br /&gt;
&amp;lt;ol&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;[https://www.icpsr.umich.edu/CrimeStat/ CrimeStat]&amp;lt;/li&amp;gt; Программное обеспечение, созданное для операционных систем Windows, предоставляющее инструменты статистического  и пространственного анализа для решения задачи картирования преступности.&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://juliastats.github.io Julia]&amp;lt;/li&amp;gt; Высокоуровневый высокопроизводительный свободный язык программирования с динамической типизацией, созданный для математических вычислений, содержит реализацию k-means.&lt;br /&gt;
  &amp;lt;li&amp;gt;[https://mahout.apache.org Mahout]&amp;lt;/li&amp;gt; Apache Mahout - Java библиотека для работы с алгоритмами машинного обучения с использованием MapReduce. Содержит реализацию k-means.&lt;br /&gt;
  &amp;lt;li&amp;gt;[https://www.gnu.org/software/octave/ Octave]&amp;lt;/li&amp;gt; Написанная на C++  свободная система для математических вычислений, использующая совместимый с MATLAB язык высокого уровня, содержит реализацию k-means.&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://spark.apache.org/docs/latest/mllib-clustering.html Spark]&amp;lt;/li&amp;gt; Распределенная реализация k-means содержится в библиотеке Mlib для работы с алгоритмами машинного обучения, взаимодействующая с Python библиотекой NumPy и библиотека R.&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://torch.ch Torch]&amp;lt;/li&amp;gt;  MATLAB-подобная библиотека для языка программирования Lua с открытым исходным кодом, предоставляет большое количество алгоритмов для глубинного обучения и научных расчётов. Ядро написано на Си, прикладная часть выполняется на LuaJIT, поддерживается распараллеливание вычислений средствами CUDA и OpenMP. Существуют реализации k-means.&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://www.cs.waikato.ac.nz/ml/weka/ Weka]&amp;lt;/li&amp;gt;  Cвободное программное обеспечение для анализа данных, написанное на Java. Содержит k-means и x-means.&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://accord-framework.net/docs/html/T_Accord_MachineLearning_KMeans.htm Accord.NET]&amp;lt;/li&amp;gt; C# реализация алгоритмов k-means, k-means++, k-modes.&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://docs.opencv.org/3.0-beta/doc/py_tutorials/py_ml/py_kmeans/py_kmeans_opencv/py_kmeans_opencv.html OpenCV]&amp;lt;/li&amp;gt; Написанная на С++ библиотека, направленная в основном на решение задач компьютерного зрения. Содержит реализацию k-means.&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://mlpack.org/ MLPACK]&amp;lt;/li&amp;gt; Масштабируемая С++ библиотека для работы с алгоритмами машинного обучения, содержит реализацию k-means.&lt;br /&gt;
  &amp;lt;li&amp;gt;[https://www.scipy.org/ SciPy]&amp;lt;/li&amp;gt; Библиотека Python, содержит множество реализаций k-means.&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://scikit-learn.org/ scikit-learn]&amp;lt;/li&amp;gt; Библиотека Python, содержит множество реализаций k-means.&lt;br /&gt;
  &amp;lt;li&amp;gt;[https://www.r-bloggers.com/k-means-clustering-in-r/ R]&amp;lt;/li&amp;gt; Язык программирования для статистической обработки данных и работы с графикой, а также свободная программная среда вычислений с открытым исходным кодом в рамках проекта GNU, содержит три реализации k-means.&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://elki.dbs.ifi.lmu.de ELKI]&amp;lt;/li&amp;gt; Java фреймворк, содержащий реализацию k-means, а также множество других алгоритмов кластеризации.&lt;br /&gt;
&amp;lt;/ol&amp;gt;&lt;br /&gt;
==== Проприетарное программное обеспечение  ====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ol&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;[https://www.ayasdi.com/blog/bigdata/topological-data-analysis-of-oil-and-gas-petrophysical-data/ Ayasdi]&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://www.stata.com/features/cluster-analysis/ Stata]&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://mathworld.wolfram.com/K-MeansClusteringAlgorithm.html Mathematica]&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://www.mathworks.com/help/stats/kmeans.html?requestedDomain=www.mathworks.com MATLAB]&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;[https://support.sas.com/rnd/app/stat/procedures/fastclus.html SAS]&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://docs.rapidminer.com/studio/operators/modeling/segmentation/k_means.html RapidMiner]&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;[https://blogs.sap.com/2013/03/28/sap-hana-pal-k-means-algorithm-or-how-to-do-customer-segmentation-for-the-telecommunications-industry/ SAP HANA]&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ol&amp;gt;&lt;br /&gt;
== Литература ==&lt;br /&gt;
&amp;lt;references /&amp;gt;&lt;/div&gt;</summary>
		<author><name>DennZo1993</name></author>
	</entry>
	<entry>
		<id>https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:%D0%91%D1%80%D0%BE%D1%82%D0%B8%D0%BA%D0%BE%D0%B2%D1%81%D0%BA%D0%B0%D1%8F_%D0%94%D0%B0%D0%BD%D1%83%D1%82%D0%B0/%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_k-means&amp;diff=17186</id>
		<title>Участник:Бротиковская Данута/Алгоритм k-means</title>
		<link rel="alternate" type="text/html" href="https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:%D0%91%D1%80%D0%BE%D1%82%D0%B8%D0%BA%D0%BE%D0%B2%D1%81%D0%BA%D0%B0%D1%8F_%D0%94%D0%B0%D0%BD%D1%83%D1%82%D0%B0/%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_k-means&amp;diff=17186"/>
		<updated>2016-11-15T01:54:27Z</updated>

		<summary type="html">&lt;p&gt;DennZo1993: /* Масштабируемость реализации алгоритма */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt; {{Assignment|Zhum}}&lt;br /&gt;
&lt;br /&gt;
{{algorithm&lt;br /&gt;
| name              = Алгоритм k средних (k means)&lt;br /&gt;
| serial_complexity = &amp;lt;math&amp;gt;O(\Tau*k*d*n)&amp;lt;/math&amp;gt;&lt;br /&gt;
| input_data        = &amp;lt;math&amp;gt; d*n &amp;lt;/math&amp;gt;&lt;br /&gt;
| output_data       = &amp;lt;math&amp;gt; n &amp;lt;/math&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
Авторы страницы &amp;lt;b&amp;gt;[[Участник:Бротиковская Данута|Данута Бротиковская]]&amp;lt;/b&amp;gt; и &amp;lt;b&amp;gt;[[Участник:DennZo1993|Денис Зобнин]]&amp;lt;/b&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
Оба автора внесли одинаковый вклад в написание статьи (поиск материалов, изучение статей, заполнение контента статьи), четких разграничений по пунктам статьи сделать невозможно. &lt;br /&gt;
&lt;br /&gt;
== Свойства и структура алгоритма ==&lt;br /&gt;
&lt;br /&gt;
=== Общее описание алгоритма ===&lt;br /&gt;
Алгоритм &amp;lt;b&amp;gt;&amp;lt;i&amp;gt;k средних&amp;lt;/i&amp;gt;&amp;lt;/b&amp;gt; (&amp;lt;b&amp;gt;&amp;lt;i&amp;gt;k means&amp;lt;/i&amp;gt;&amp;lt;/b&amp;gt;) &amp;amp;ndash; неиерархический&amp;lt;ref&amp;gt;&amp;quot;https://ru.wikipedia.org/wiki/Иерархическая_кластеризация&amp;quot;&amp;lt;/ref&amp;gt;, итерационный метод кластеризации&amp;lt;ref&amp;gt;&amp;quot;https://ru.wikipedia.org/wiki/Кластерный_анализ&amp;quot;&amp;lt;/ref&amp;gt;, получивший большую популярность благодаря своей простоте, наглядности реализации и достаточно высокому качеству работы. Был изобретен в 1950-х годах математиком &amp;lt;i&amp;gt;Гуго Штейнгаузом&amp;lt;/i&amp;gt;&amp;lt;ref&amp;gt;Steinhaus, Hugo. &amp;quot;Sur la division des corp materiels en parties.&amp;quot; Bull. Acad. Polon. Sci 1.804 (1956): 801.&amp;lt;/ref&amp;gt; и почти одновременно &amp;lt;i&amp;gt;Стюартом Ллойдом&amp;lt;/i&amp;gt;&amp;lt;ref&amp;gt;Lloyd, S. P. &amp;quot;Least square quantization in PCM. Bell Telephone Laboratories Paper. Published in journal much later: Lloyd, SP: Least squares quantization in PCM.&amp;quot; IEEE Trans. Inform. Theor.(1957/1982).&amp;lt;/ref&amp;gt;. Особую популярность приобрел после публикации работы &amp;lt;i&amp;gt;МакКуина&amp;lt;/i&amp;gt;&amp;lt;ref&amp;gt;MacQueen, James. &amp;quot;Some methods for classification and analysis of multivariate observations.&amp;quot; Proceedings of the fifth Berkeley symposium on mathematical statistics and probability. Vol. 1. No. 14. 1967.&amp;lt;/ref&amp;gt; в 1967.&lt;br /&gt;
&lt;br /&gt;
Алгоритм представляет собой версию EM-алгоритма&amp;lt;ref&amp;gt;&amp;quot;https://ru.wikipedia.org/wiki/EM-алгоритм&amp;quot;&amp;lt;/ref&amp;gt;, применяемого также для разделения смеси гауссиан. Основная идея &amp;lt;i&amp;gt;k means&amp;lt;/i&amp;gt; заключается в том, что данные произвольно разбиваются на кластеры, после чего итеративно перевычисляется центр масс для каждого кластера, полученного на предыдущем шаге, затем векторы разбиваются на кластеры вновь в соответствии с тем, какой из новых центров оказался ближе по выбранной метрике.&lt;br /&gt;
&lt;br /&gt;
Цель алгоритма заключается в разделении &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; наблюдений на &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластеров таким образом, чтобы каждое наблюдение принадлежало ровно одному кластеру, расположенному на наименьшем расстоянии от наблюдения.&lt;br /&gt;
&lt;br /&gt;
=== Математическое описание алгоритма ===&lt;br /&gt;
&amp;lt;b&amp;gt;&amp;lt;u&amp;gt;Дано:&amp;lt;/u&amp;gt;&amp;lt;/b&amp;gt;&lt;br /&gt;
* набор из &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; наблюдений &amp;lt;math&amp;gt;X=\{\mathbf{x}_1, \mathbf{x}_2, ..., \mathbf{x}_n\}, \mathbf{x}_i \in \mathbb{R}^d, i=\overline{1, n}&amp;lt;/math&amp;gt;;&lt;br /&gt;
* &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; - требуемое число кластеров, &amp;lt;math&amp;gt;k \in \mathbb{N}, k \leq n&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;&amp;lt;u&amp;gt;Требуется:&amp;lt;/u&amp;gt;&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Разделить множество наблюдений &amp;lt;math&amp;gt;X&amp;lt;/math&amp;gt; на &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластеров &amp;lt;math&amp;gt;S_1, S_2, ..., S_k&amp;lt;/math&amp;gt;:&lt;br /&gt;
*   &amp;lt;math&amp;gt;S_i \cap S_j= \varnothing, \quad i \ne j&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
*   &amp;lt;math&amp;gt;\bigcup_{i=1}^{k} S_i = X&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;&amp;lt;u&amp;gt;Действие алгоритма:&amp;lt;/u&amp;gt;&amp;lt;/b&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;Алгоритм &amp;lt;i&amp;gt;k means&amp;lt;/i&amp;gt; разбивает набор &amp;lt;math&amp;gt;X&amp;lt;/math&amp;gt; на &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; наборов &amp;lt;math&amp;gt;S_1, S_2, ..., S_k,&amp;lt;/math&amp;gt; таким образом, чтобы минимизировать сумму квадратов расстояний от каждой точки кластера до его центра (центр масс кластера). Введем обозначение, &amp;lt;math&amp;gt;S=\{S_1, S_2, ..., S_k\}&amp;lt;/math&amp;gt;. Тогда действие алгоритма &amp;lt;i&amp;gt;k means&amp;lt;/i&amp;gt; равносильно поиску:&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;table style=&amp;quot;width:100%&amp;quot;&amp;gt;&lt;br /&gt;
  &amp;lt;tr&amp;gt;&lt;br /&gt;
    &amp;lt;td align=&amp;quot;center&amp;quot; width=&amp;quot;90%&amp;quot;&amp;gt;&amp;lt;math&amp;gt;\arg\min_{S} \sum\limits_{i=1}^k \sum\limits_{\mathbf{x} \in S_i} \rho(\mathbf{x}, \mathbf{\mu}_i )^2,&amp;lt;/math&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;td align=&amp;quot;right&amp;quot;&amp;gt;&amp;lt;math&amp;gt;(1)&amp;lt;/math&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;/table&amp;gt;&lt;br /&gt;
где &amp;lt;math&amp;gt;\mathbf{\mu}_i&amp;lt;/math&amp;gt; &amp;amp;ndash; центры кластеров, &amp;lt;math&amp;gt;i=\overline{1,k}, \quad \rho(\mathbf{x}, \mathbf{\mu}_i)&amp;lt;/math&amp;gt; &amp;amp;ndash; функция расстояния между &amp;lt;math&amp;gt;\mathbf{x}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\mu_i&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;&amp;lt;u&amp;gt;Шаги алгоритма: &amp;lt;/u&amp;gt;&amp;lt;/b&amp;gt;&lt;br /&gt;
&amp;lt;ol&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&lt;br /&gt;
    &amp;lt;b&amp;gt;Начальный шаг: инициализация кластеров&amp;lt;/b&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;Выбирается произвольное множество точек &amp;lt;math&amp;gt;\mu_i, i=\overline{1,k}&amp;lt;/math&amp;gt;, рассматриваемых как начальные центры кластеров: &amp;lt;math&amp;gt;\mu_i^{(0)} = \mu_i, \quad i=\overline{1, k}&amp;lt;/math&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
  &amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&lt;br /&gt;
    &amp;lt;b&amp;gt;Распределение векторов по кластерам&amp;lt;/b&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Шаг&amp;lt;/b&amp;gt; &amp;lt;math&amp;gt;t: \forall \mathbf{x}_i \in X, i=\overline{1,n}: \mathbf{x}_i \in S_j \iff  j=\arg\min_{k}\rho(\mathbf{x}_i,\mathbf{\mu}_k^{(t-1)})^2&amp;lt;/math&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
  &amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&lt;br /&gt;
    &amp;lt;b&amp;gt;Пересчет центров кластеров&amp;lt;/b&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Шаг &amp;lt;/b&amp;gt; &amp;lt;math&amp;gt;t: \forall i=\overline{1,k}:  \mu_i^{(t)} = \cfrac{1}{|S_i|}\sum_{\mathbf{x}\in S_i}\mathbf{x}&amp;lt;/math&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
  &amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&lt;br /&gt;
    &amp;lt;b&amp;gt;Проверка условия останова:&amp;lt;/b&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
    &#039;&#039;&#039;if&#039;&#039;&#039; &amp;lt;math&amp;gt;\exist i\in \overline{1,k}: \mu_i^{(t)} \ne \mu_i^{(t-1)}&amp;lt;/math&amp;gt; &#039;&#039;&#039;then&#039;&#039;&#039;&lt;br /&gt;
        t = t + 1;&lt;br /&gt;
        goto 2;&lt;br /&gt;
    &#039;&#039;&#039;else&#039;&#039;&#039;&lt;br /&gt;
        &#039;&#039;&#039;stop&#039;&#039;&#039;&lt;br /&gt;
  &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ol&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Вычислительное ядро алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Вычислительным ядром являются шаги 2 и 3 приведенного выше алгоритма: &amp;lt;b&amp;gt;&amp;lt;i&amp;gt;распределение векторов по кластерам&amp;lt;/i&amp;gt;&amp;lt;/b&amp;gt; и &amp;lt;b&amp;gt;&amp;lt;i&amp;gt;пересчет центров кластеров&amp;lt;/i&amp;gt;&amp;lt;/b&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;&amp;lt;i&amp;gt;Распределение векторов&amp;lt;/i&amp;gt;&amp;lt;/b&amp;gt; по кластерам предполагает вычисление расстояний между каждым вектором &amp;lt;math&amp;gt;\mathbf{x}_i \in X, i= \overline{1,n}&amp;lt;/math&amp;gt; и центрами кластера &amp;lt;math&amp;gt;\mathbf{\mu}_j, j= \overline{1,k}&amp;lt;/math&amp;gt;. Таким образом, данный шаг предполагает &amp;lt;math&amp;gt;k*n&amp;lt;/math&amp;gt; вычислений расстояний между d-мерными векторами. &lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;&amp;lt;i&amp;gt;Пересчет центров кластеров&amp;lt;/i&amp;gt;&amp;lt;/b&amp;gt; предполагает &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; вычислений центров масс &amp;lt;math&amp;gt;\mathbf{\mu}_i&amp;lt;/math&amp;gt; множеств &amp;lt;math&amp;gt;S_i, i=\overline{1,k}&amp;lt;/math&amp;gt; представленных выражением в шаге 3 представленного выше алгоритма.&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Макроструктура алгоритма ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Инициализация центров масс &amp;lt;math&amp;gt;\mu_1, ..., \mu_k&amp;lt;/math&amp;gt;&amp;lt;/b&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
Наиболее распространенными являются следующие стратегии:&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&lt;br /&gt;
    &amp;lt;b&amp;gt;Метод Forgy&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;В качестве начальных значений &amp;lt;math&amp;gt;\mu_1, ..., \mu_k&amp;lt;/math&amp;gt; берутся случайно выбранные векторы.&lt;br /&gt;
  &amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&lt;br /&gt;
    &amp;lt;b&amp;gt;Метод случайно разделения (Random Partitioning)&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;Для каждого вектора &amp;lt;math&amp;gt;\mathbf{x}_i \in X, i=\overline{1, n}&amp;lt;/math&amp;gt; выбирается случайным образом кластер &amp;lt;math&amp;gt;S_1, ..., S_k&amp;lt;/math&amp;gt;, после чего для каждого полученного кластера вычисляются значения &amp;lt;math&amp;gt;\mu_1, ..., \mu_k&amp;lt;/math&amp;gt;.&lt;br /&gt;
  &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Распределение векторов по кластерам&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Для этого шага алгоритма между векторами &amp;lt;math&amp;gt;\mathbf{x}_i \in X, i=\overline{1, n}&amp;lt;/math&amp;gt; и центрами кластеров &amp;lt;math&amp;gt;\mu_1, ..., \mu_k&amp;lt;/math&amp;gt; вычисляются &amp;lt;b&amp;gt;расстояния&amp;lt;/b&amp;gt; по формуле (как правило, используется Евлидово расстояние):&lt;br /&gt;
&amp;lt;table style=&amp;quot;width:100%&amp;quot;&amp;gt;&lt;br /&gt;
  &amp;lt;tr&amp;gt;&lt;br /&gt;
    &amp;lt;td align=&amp;quot;center&amp;quot; width=&amp;quot;90%&amp;quot;&amp;gt;&amp;lt;math&amp;gt; \mathbf{v}_1, \mathbf{v}_2 \in \mathbb{R}^d,  \quad \rho(\mathbf{v}_1, \mathbf{v}_2) = \lVert \mathbf{v}_1- \mathbf{v}_2 \rVert= \sqrt{\sum_{i=1}^{d}(\mathbf{v}_{1,i} - \mathbf{v}_{2,i})^2}&amp;lt;/math&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;td align=&amp;quot;right&amp;quot;&amp;gt;&amp;lt;math&amp;gt;(2)&amp;lt;/math&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;/table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Пересчет центров кластеров&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Для этого шага алгоритма производится пересчет центров кластера по &amp;lt;b&amp;gt;формуле вычисления центра масс&amp;lt;/b&amp;gt;:&lt;br /&gt;
&amp;lt;table style=&amp;quot;width:100%&amp;quot;&amp;gt;&lt;br /&gt;
  &amp;lt;tr&amp;gt;&lt;br /&gt;
    &amp;lt;td align=&amp;quot;center&amp;quot; width=&amp;quot;90%&amp;quot;&amp;gt;&amp;lt;math&amp;gt; \mu = \cfrac{1}{|S|}\sum_{\mathbf{x}\in S}\mathbf{x}&amp;lt;/math&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;td align=&amp;quot;right&amp;quot;&amp;gt;&amp;lt;math&amp;gt;(3)&amp;lt;/math&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;/table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Схема реализации последовательного алгоритма ===&lt;br /&gt;
&lt;br /&gt;
 &#039;&#039;&#039;algorithm&#039;&#039;&#039; k-means &#039;&#039;&#039;is&#039;&#039;&#039;&lt;br /&gt;
     &#039;&#039;&#039;1.&#039;&#039;&#039; Инициализировать центры кластеров &amp;lt;math&amp;gt;\mathbf{\mu}_i^{(1)}, i=\overline{1,k}&amp;lt;/math&amp;gt;&lt;br /&gt;
     &#039;&#039;&#039;2.&#039;&#039;&#039; &amp;lt;math&amp;gt;t \leftarrow 1&amp;lt;/math&amp;gt;&lt;br /&gt;
     &#039;&#039;&#039;3.&#039;&#039;&#039; &#039;&#039;&#039;Распределение по кластерам&#039;&#039;&#039;&amp;lt;br&amp;gt;&lt;br /&gt;
        &amp;lt;math&amp;gt;S_i^{(t)}=\{\mathbf{x}_p: \lVert\mathbf{x}_p-\mathbf{\mu}_i^{(t)}\rVert^2 \leq \lVert\mathbf{x}_p-\mathbf{\mu}_j^{(t)}\rVert^2 \quad \forall j=\overline{1,k}\},&amp;lt;/math&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
        где каждый вектор &amp;lt;math&amp;gt;\mathbf{x}_p&amp;lt;/math&amp;gt; соотносится единственному кластеру &amp;lt;math&amp;gt;S^{(t)}&amp;lt;/math&amp;gt;&lt;br /&gt;
     &#039;&#039;&#039;4.&#039;&#039;&#039; &#039;&#039;&#039;Обновление центров кластеров&#039;&#039;&#039;&amp;lt;br&amp;gt;&lt;br /&gt;
        &amp;lt;math&amp;gt;\mathbf{\mu}_i^{(t+1)} = \frac{1}{|S^{(t)}_i|} \sum_{\mathbf{x}_j \in S^{(t)}_i} \mathbf{x}_j &amp;lt;/math&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
     &#039;&#039;&#039;5.&#039;&#039;&#039; &#039;&#039;&#039;if&#039;&#039;&#039; &amp;lt;math&amp;gt;\exist i \in \overline{1,k}: \mathbf{\mu}_i^{(t+1)} \ne \mathbf{\mu}_i^{(t)}&amp;lt;/math&amp;gt; &#039;&#039;&#039;then&#039;&#039;&#039;&lt;br /&gt;
            t = t + 1;&lt;br /&gt;
            goto &#039;&#039;&#039;3&#039;&#039;&#039;;&lt;br /&gt;
        &#039;&#039;&#039;else&#039;&#039;&#039;&lt;br /&gt;
            &#039;&#039;&#039;stop&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
=== Последовательная сложность алгоритма===&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding-bottom: 20px&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;Обозначим &amp;lt;math&amp;gt;\Theta_{centroid}^{d, m}&amp;lt;/math&amp;gt; временную сложность вычисления центорида кластера, число элементов которого равна &amp;lt;math&amp;gt;m&amp;lt;/math&amp;gt;,  в d-мерном пространстве.&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;Аналогично  &amp;lt;math&amp;gt;\Theta_{distance}^d&amp;lt;/math&amp;gt; &amp;amp;ndash; временная сложность вычисления расстояния между двумя d-мерными векторами.&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding-bottom: 20px&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;Сложность шага инициализации &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластеров мощности &amp;lt;math&amp;gt;m&amp;lt;/math&amp;gt; в d-мерном пространстве &amp;amp;ndash; &amp;lt;math&amp;gt;\Theta_{init}^{k, d, m}&amp;lt;/math&amp;gt;&amp;lt;/b&amp;gt;&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;i&amp;gt;Стратерия Forgy&amp;lt;/i&amp;gt;: вычисления не требуются, &amp;lt;math&amp;gt;\Theta_{init}^{k, d, m} = 0&amp;lt;/math&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;i&amp;gt;Стратегия случайного разбиения&amp;lt;/i&amp;gt;: вычисление центров &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластеров,  &amp;lt;math&amp;gt;\Theta_{init}^{k, d, m} = k*\Theta_{centroid}^{d, m}, m \le n&amp;lt;/math&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding-bottom: 20px&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Cложность шага распределения d мерных векторов по &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластерам &amp;amp;ndash; &amp;lt;math&amp;gt;\Theta_{distribute}^{k, d}&amp;lt;/math&amp;gt;&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
На этом шаге для каждого вектора &amp;lt;math&amp;gt;\mathbf{x}_i \in X, i=\overline{1, n}&amp;lt;/math&amp;gt; вычисляется k расстояний до центров кластеров &amp;lt;math&amp;gt;\mathbf{\mu}_1, ...\mathbf{\mu}_k&amp;lt;/math&amp;gt;&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p align=&amp;quot;center&amp;quot;&amp;gt;&lt;br /&gt;
  &amp;lt;math&amp;gt;\Theta_{distribute}^{k, d} = n*k*\Theta_{distance}^d&amp;lt;/math&amp;gt;&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding-bottom: 20px&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;Сложность шага пересчета центров &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластеров размера &amp;lt;math&amp;gt;m&amp;lt;/math&amp;gt; в d-мерном пространстве &amp;amp;ndash; &amp;lt;math&amp;gt;\Theta_{recenter}^{k, d, m}&amp;lt;/math&amp;gt;&amp;lt;/b&amp;gt;&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;На этом шаге вычисляется &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; центров кластеров &amp;lt;math&amp;gt;\mathbf{\mu}_1, ...\mathbf{\mu}_k&amp;lt;/math&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p align=&amp;quot;center&amp;quot;&amp;gt;&amp;lt;math&amp;gt;\Theta_{recenter}^{k, d, m} = k*\Theta_{centroid}^{d, m}&amp;lt;/math&amp;gt; &amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding-bottom: 20px&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Рассчитаем &amp;lt;math&amp;gt;\Theta_{centroid}^{d, m}&amp;lt;/math&amp;gt; для кластера, число элементов которого равно &amp;lt;math&amp;gt;m&amp;lt;/math&amp;gt;&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p align=&amp;quot;center&amp;quot;&amp;gt;&amp;lt;math&amp;gt;\Theta_{centroid}^{d, m}&amp;lt;/math&amp;gt; = &amp;lt;math&amp;gt;m * d&amp;lt;/math&amp;gt; сложений + &amp;lt;math&amp;gt;d&amp;lt;/math&amp;gt; делений &amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding-bottom: 20px&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Рассчитаем &amp;lt;math&amp;gt;\Theta_{distance}^d&amp;lt;/math&amp;gt; в соответствие с формулой &amp;lt;math&amp;gt;(2)&amp;lt;/math&amp;gt;&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p align=&amp;quot;center&amp;quot;&amp;gt;&amp;lt;math&amp;gt;\Theta_{distance}^d&amp;lt;/math&amp;gt; = &amp;lt;math&amp;gt;d&amp;lt;/math&amp;gt; вычитаний + &amp;lt;math&amp;gt;d&amp;lt;/math&amp;gt; умножений + &amp;lt;math&amp;gt;(d-1)&amp;lt;/math&amp;gt; сложение&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding-bottom: 20px&amp;quot;&amp;gt;&lt;br /&gt;
  &amp;lt;p&amp;gt;Предположим, что алгоритм сошелся за &amp;lt;math&amp;gt;\Tau&amp;lt;/math&amp;gt; итераций, тогда временная сложность алгоритма &amp;lt;math&amp;gt;\Theta_{k-means}^{d, n}&amp;lt;/math&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
  &amp;lt;p align=&amp;quot;center&amp;quot;&amp;gt;&amp;lt;b&amp;gt;&amp;lt;math&amp;gt;\Theta_{k-means}^{d, n} \le \Theta_{init}^{k, d, n} + \Tau*(\Theta_{distribute}^{k, d} + \Theta_{recenter}^{k, d, n})&amp;lt;/math&amp;gt;&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding-bottom: 5px&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;Операции сложения/вычитания:&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p align=&amp;quot;center&amp;quot;&amp;gt;&amp;lt;b&amp;gt;&amp;lt;math&amp;gt;\Theta_{k-means}^{d, n} \le k*n*d+ \Tau*(k*n*(2d-1) + k*n*d) = k*n*d+ \Tau*(k*n*(3d-1)) \thicksim O(\Tau*k*d*n)&amp;lt;/math&amp;gt;&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding-bottom: 20px&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;Операции умножения/деления:&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p align=&amp;quot;center&amp;quot;&amp;gt;&amp;lt;b&amp;gt;&amp;lt;math&amp;gt;\Theta_{k-means}^{d, n} \le k*d + \Tau*(k*n*d + k*d) = k*d + \Tau * k*d*(n+1) \thicksim O(\Tau*k*d*n) &amp;lt;/math&amp;gt;&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding-bottom: 20px&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;Получаем, что &amp;lt;b&amp;gt;временная сложность&amp;lt;/b&amp;gt; алгоритма &amp;lt;b&amp;gt;k means&amp;lt;/b&amp;gt; кластеризации &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; &amp;lt;b&amp;gt;d-мерных&amp;lt;/b&amp;gt; векторов на &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластеров за &amp;lt;math&amp;gt;\Tau&amp;lt;/math&amp;gt; итераций:&amp;lt;/p&amp;gt;&lt;br /&gt;
 &amp;lt;p align=&amp;quot;center&amp;quot;&amp;gt;&amp;lt;b&amp;gt;&amp;lt;math&amp;gt; \Theta_{k-means}^{d, n} \thicksim O(\Tau*k*d*n) &amp;lt;/math&amp;gt;&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Информационный граф ===&lt;br /&gt;
&lt;br /&gt;
Рассмотрим информационный граф алгоритма. Алгоритм &amp;lt;i&amp;gt;k means&amp;lt;/i&amp;gt; начинается с этапа инициализации, после которого следуют итерации, на каждой из которых выполняется два последовательных шага (см. [[#Схема реализации последовательного алгоритма|&amp;quot;Схема реализации последовательного алгоритма&amp;quot;]]): &lt;br /&gt;
* распределение векторов по кластерам&lt;br /&gt;
* перерасчет центров кластеров&lt;br /&gt;
&lt;br /&gt;
Поскольку основная часть вычислений приходится на шаги итераций, распишем информационные графы данных шагов.&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Распределение векторов по кластерам&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
Информационный граф шага распределения векторов по кластерам представлен на &#039;&#039;рисунке 1&#039;&#039;. Исходами данного графа является исходные векторы &amp;lt;math&amp;gt;\mathbf{x}_1, ..., \mathbf{x}_n&amp;lt;/math&amp;gt;, а также центры кластеров &amp;lt;math&amp;gt;\mathbf{\mu}_1, ... \mathbf{\mu}_k&amp;lt;/math&amp;gt;, вычисленные ранее (на шаге инициализации, если рассматривается первая итерация алгоритма, или на шаге пересчета центров кластеров предыдущей итерации в противном случае). Каждая пара векторов данных &amp;lt;math&amp;gt;\mathbf{x}_i, i=\overline{1,n}&amp;lt;/math&amp;gt; и центров кластера &amp;lt;math&amp;gt;\mathbf{\mu}_j, j=\overline{1, k}&amp;lt;/math&amp;gt; : (&amp;lt;math&amp;gt;\mathbf{x}_i&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;\mathbf{\mu}_j&amp;lt;/math&amp;gt;) подаются на независимые узлы &amp;lt;i&amp;gt;&amp;quot;d&amp;quot;&amp;lt;/i&amp;gt; вычисления расстояния между векторами (более подробная схема вычисления расстояния представлена далее, &#039;&#039;рисунок 2&#039;&#039;). Далее узлы вычисления расстояния &amp;lt;i&amp;gt;&amp;quot;d&amp;quot;&amp;lt;/i&amp;gt;, соответствующие одному и тому же исходному вектору &amp;lt;math&amp;gt;\mathbf{x}_i&amp;lt;/math&amp;gt; передаются на один узел &amp;lt;i&amp;gt;&amp;quot;m&amp;quot;&amp;lt;/i&amp;gt;, где далее происходит вычисление новой метки кластера для каждого вектора &amp;lt;math&amp;gt;\mathbf{x}_i&amp;lt;/math&amp;gt; (берется кластер с минимальным результатом вычисления расстояния). На выходе графа выдаются метки кластеров , &amp;lt;math&amp;gt;L_1, ..., L_n&amp;lt;/math&amp;gt;, такие что &amp;lt;math&amp;gt;\forall \mathbf{x}_i, i=\overline{1, n}, \mathbf{x}_i \in S_j \Leftrightarrow L_i = j&amp;lt;/math&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
[[file:Clusterization.png|thumb|center|800px|Рис. 1. Схема распределения векторов по кластерам. &#039;&#039;d&#039;&#039; &amp;amp;ndash; вычисление расстояния между векторами; &#039;&#039;m&#039;&#039; &amp;amp;ndash; вычисление минимума.]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Вычисление расстояния между векторами&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
Подробная схема вычисления расстояния между векторами &amp;lt;math&amp;gt;\mathbf{x}_i, \mathbf{\mu}_j&amp;lt;/math&amp;gt; представлена на &#039;&#039;рисунке 2&#039;&#039;. Как показано на графе, узел вычисления расстояния между векторами &amp;lt;i&amp;gt;&amp;quot;d&amp;quot;&amp;lt;/i&amp;gt; состоит из шага взятия разности между векторами (узел &amp;quot;&amp;lt;math&amp;gt;-&amp;lt;/math&amp;gt;&amp;quot;) и взятия нормы получившегося вектора разности (узел &amp;quot;&amp;lt;math&amp;gt;||\cdot||^2&amp;lt;/math&amp;gt;&amp;quot;). Более подробно, вычисление расстояния между векторами &amp;lt;math&amp;gt;\mathbf{x}_i = {x_{i1,}, ...,{x_{in}}}, \mathbf{\mu}_j = {\mu_{j1}, ...,\mu_{jn}}&amp;lt;/math&amp;gt; может быть представлено как вычисление разности между каждой парой компонент &amp;lt;math&amp;gt;(x_{iz}, \mu_{jz}), z=\overline{1, d}&amp;lt;/math&amp;gt; (узел &amp;quot;&amp;lt;math&amp;gt;-&amp;lt;/math&amp;gt;&amp;quot;), далее возведение в квадрат для каждого узла &amp;quot;&amp;lt;math&amp;gt;-&amp;lt;/math&amp;gt;&amp;quot; (узел &amp;quot;&amp;lt;math&amp;gt;()^2&amp;lt;/math&amp;gt;&amp;quot;) и суммирования выходов всех узлов &amp;quot;&amp;lt;math&amp;gt;()^2&amp;lt;/math&amp;gt;&amp;quot; (узел &amp;quot;&amp;lt;math&amp;gt;+&amp;lt;/math&amp;gt;&amp;quot;).  &lt;br /&gt;
&lt;br /&gt;
[[file:dist_calc.png|thumb|center|800px|Рис. 2. Схема вычисления расстояния между вектором и центром кластера.]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Пересчет центров кластеров&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
Информационный граф шага пересчета центров кластеров представлен на &#039;&#039;рисунке 3&#039;&#039;. Исходами данного графа является исходные векторы &amp;lt;math&amp;gt;\mathbf{x}_1, ..., \mathbf{x}_n&amp;lt;/math&amp;gt;, а также им соответствующие метки кластера, &amp;lt;math&amp;gt;L_1, ..., L_n&amp;lt;/math&amp;gt;, такие что &amp;lt;math&amp;gt;\forall x_i, i=\overline{1, n}, \mathbf{x}_i \in S_j \Leftrightarrow L_i = j&amp;lt;/math&amp;gt;, вычисленные на этапе распределения векторов по кластерам. Все векторы &amp;lt;math&amp;gt;\mathbf{x}_1, ..., \mathbf{x}_n&amp;lt;/math&amp;gt; подаются в узлы &amp;lt;math&amp;gt;+_1, ...+_k&amp;lt;/math&amp;gt;, каждый узел &amp;lt;math&amp;gt;+_m, m = \overline{1,k}&amp;lt;/math&amp;gt; соответствует операции сложения векторов кластера с номером &amp;lt;math&amp;gt;m&amp;lt;/math&amp;gt;. Метки кластера &amp;lt;math&amp;gt;L_1, ..., L_n&amp;lt;/math&amp;gt; также совместно передаются на узлы &amp;lt;math&amp;gt;S_m, m = \overline{1,k}&amp;lt;/math&amp;gt;, на каждом из которых вычисляется количество векторов в соответствующем кластере (количество меток с соответствующим значением). Далее каждая пара выходов узлов &amp;lt;math&amp;gt;+_m&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;S_m&amp;lt;/math&amp;gt; подается на узел &amp;quot;&amp;lt;math&amp;gt;/&amp;lt;/math&amp;gt;&amp;quot;, где производится деление суммы векторов кластера на количество элементов в нем. Значения, вычисленные на узлах &amp;quot;&amp;lt;math&amp;gt;/&amp;lt;/math&amp;gt;&amp;quot;, присваиваются новым центрам кластеров (выходные значения графа).&lt;br /&gt;
&lt;br /&gt;
[[file:Recluster.png|thumb|center|800px|Рис. 3. Схема пересчета центров кластеров]]&lt;br /&gt;
&lt;br /&gt;
=== Ресурс параллелизма алгоритма ===&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
Работа алгоритма состоит из &amp;lt;math&amp;gt;\Tau&amp;lt;/math&amp;gt; итераций, в каждой из которых происходит &amp;lt;b&amp;gt;распределение d-мерных векторов по &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластерам&amp;lt;/b&amp;gt;, а также &amp;lt;b&amp;gt;пересчет центров кластеров в d-мерном пространстве&amp;lt;/b&amp;gt;. В шаге &amp;lt;b&amp;gt;распределения d-мерных векторов по &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластерам&amp;lt;/b&amp;gt; расстояния между вектором и центрами кластеров вычисляются независимо (отсутствуют информационные зависимости). &amp;lt;b&amp;gt;Центры масс кластеров&amp;lt;/b&amp;gt; также пересчитываются независимо друг от друга. Таким образом, имеет место [[глоссарий#Массовый параллелизм|&#039;&#039;массовый параллелизм&#039;&#039;]]. Вычислим параллельную сложность &amp;lt;math&amp;gt;\Psi_*&amp;lt;/math&amp;gt; каждого из шагов, а также параллельную сложность всего алгоритма, &amp;lt;math&amp;gt;\Psi_{k-means}&amp;lt;/math&amp;gt;. Будем исходить из предположения, что может быть использовано любое необходимое число потоков.&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Распределение d-мерных векторов по &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластерам&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;  &lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
Поскольку на данном шаге для каждой пары векторов &amp;lt;math&amp;gt;\mathbf{x}_i, i=\overline{1,n}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\mathbf{\mu}_j, j=\overline{1,k}&amp;lt;/math&amp;gt; операции вычисления расстояния не зависят друг от друга, они могут выполняться параллельно. Тогда, разделив все вычисление расстояний на &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; потоков, получим, что в каждом потоке будет выполняться только одна операция вычисления расстояния между векторами размерности d. При этом каждому вычислительному потоку передаются координаты центров всех кластеров &amp;lt;math&amp;gt;\mathbf{\mu}_1, ..., \mathbf{\mu}_k&amp;lt;/math&amp;gt;. Таким образом, параллельная сложность данного шага определяется &amp;lt;i&amp;gt; сложностью параллельной операции вычисления расстояния между d-мерными векторами&amp;lt;/i&amp;gt;, &amp;lt;math&amp;gt;\Psi_{distance}^d&amp;lt;/math&amp;gt;  и &amp;lt;i&amp;gt;сложностью определения наиболее близкого кластера&amp;lt;/i&amp;gt; (паралельное взятие минимума по расстояниям), &amp;lt;math&amp;gt;\Psi_{min}^k&amp;lt;/math&amp;gt;. Для оценки &amp;lt;math&amp;gt;\Psi_{distance}^d&amp;lt;/math&amp;gt; воспользуемся  [[Нахождение_частных_сумм_элементов_массива_сдваиванием | параллельной реализацией нахождения частичной суммы элементов массива путем сдваивания]]. Аналогично, &amp;lt;math&amp;gt;\Psi_{min}^k = log(k)&amp;lt;/math&amp;gt;. В результате, &amp;lt;math&amp;gt;\Psi_{distance}^d = O(log(d))&amp;lt;/math&amp;gt;.   Таким образом: &lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p align=&amp;quot;center&amp;quot;&amp;gt;&amp;lt;math&amp;gt;\Psi_{distribute}^{k, d}  = \Psi_{distance}^d + \Psi_{min}^k = O(log(d))+O(log(k)) = O(log(k*d))&amp;lt;/math&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Пересчет центров кластеров в d-мерном пространстве&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
Поскольку на данном шаге для каждого из &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластеров центр масс может быть вычислен независимо, данные операции могут быть выполнены в отдельных потоках. Таким образом, параллельная сложность данного шага, &amp;lt;math&amp;gt;\Psi_{recenter}^{k, d}&amp;lt;/math&amp;gt;,  будет определяться &amp;lt;i&amp;gt;параллельной сложностью вычисления одного центра масс кластера размера &amp;lt;math&amp;gt;m&amp;lt;/math&amp;gt;&amp;lt;/i&amp;gt;, &amp;lt;math&amp;gt;\Psi_{recenter}^{k, d}&amp;lt;/math&amp;gt;,  а так как &amp;lt;math&amp;gt;m \le n \Rightarrow \Psi_{recenter}^{d, m} \le \Psi_{recenter}^{d, n}&amp;lt;/math&amp;gt;. Сложность вычисления центра масс кластера d-мерных векторов размера n аналогично предыдущим вычислениям равна &amp;lt;math&amp;gt;O(log(n))&amp;lt;/math&amp;gt;. Тогда:  &lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p align=&amp;quot;center&amp;quot;&amp;gt;&amp;lt;math&amp;gt;\Psi_{recenter}^{k, d}  \le \Psi_{recenter}^{d, n} = O(log(n))&amp;lt;/math&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Общая параллельная сложность алгоритма&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
На каждой итерации необходимо обновление центров кластеров, которые будут использованы на следующей итерации. Таким образом, итерационный процесс выполняется последовательно&amp;lt;ref&amp;gt;Zhao, Weizhong, Huifang Ma, and Qing He. &amp;quot;Parallel k-means clustering based on mapreduce.&amp;quot; IEEE International Conference on Cloud Computing. Springer Berlin Heidelberg, 2009.&amp;lt;/ref&amp;gt;. Тогда, поскольку сложность каждой итерации  определяется &amp;lt;math&amp;gt;\Psi_{distribute}^{k, d}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\Psi_{recenter}&amp;lt;/math&amp;gt;, сложность всего алгоритма, &amp;lt;math&amp;gt;\Psi_{k-means}&amp;lt;/math&amp;gt; в предположении, что было сделано &amp;lt;math&amp;gt;\Tau&amp;lt;/math&amp;gt; операций определяется выражением&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p align=&amp;quot;center&amp;quot;&amp;gt;&amp;lt;math&amp;gt;\Psi_{k-means} \approx \Tau * (\Psi_{distribute}^{k, d} + \Psi_{recenter}^{k, d}) \le \Tau * O(log(k*d*n))&amp;lt;/math&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Входные и выходные данные алгоритма ===&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;Входные данные&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;Матрица из &amp;lt;math&amp;gt;n*d&amp;lt;/math&amp;gt; элементов &amp;lt;math&amp;gt;x_{i, j} \in \mathbb{R}, i=\overline{1, n}, j=\overline{1, d}&amp;lt;/math&amp;gt;&amp;amp;ndash; координат векторов (наблюдений).&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;Целое положительное число &amp;lt;math&amp;gt;k, k \le n&amp;lt;/math&amp;gt; &amp;amp;ndash; количество кластеров.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;Объем входных данных&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;math&amp;gt;1&amp;lt;/math&amp;gt; целое число + &amp;lt;math&amp;gt;n*d&amp;lt;/math&amp;gt; вещественных чисел (при условии, что координаты &amp;amp;ndash; вещественные числа).&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;Выходные данные&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; целых положительных чисел &amp;lt;math&amp;gt;L_1, ..., L_n&amp;lt;/math&amp;gt;&amp;amp;ndash; номера кластеров, соотвествующие каждому вектору (при условии, что нумерация кластеров начинается с &amp;lt;math&amp;gt;1&amp;lt;/math&amp;gt;).&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;Объем выходных данных&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; целых положительных чисел.&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Свойства алгоритма ===&lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;[[глоссарий#Вычислительная мощность|&#039;&#039;Вычислительная мощность&#039;&#039;]]&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
Вычислительная мощность алгоритма &amp;lt;i&amp;gt;k means&amp;lt;/i&amp;gt; равна &amp;lt;math&amp;gt;\frac{k*d*n*\Tau}{n*d} = k*\Tau &amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; &amp;amp;ndash; число кластеров, &amp;lt;math&amp;gt;\Tau&amp;lt;/math&amp;gt; &amp;amp;ndash; число итераций алгоритма.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;[[глоссарий#Детерминированность |&#039;&#039;Детерминированность&#039;&#039;]] и [[глоссарий#Устойчивость |&#039;&#039;Устойчивость&#039;&#039;]] &amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
Алгоритм &amp;lt;i&amp;gt;k means&amp;lt;/i&amp;gt; является итерационным. Количество итераций алгоритма в общем случае не фиксируется и зависит от начального расположения объектов в пространстве, параметра &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt;, а также от начального приближения центров кластеров, &amp;lt;math&amp;gt;\mu_1, ..., \mu_k&amp;lt;/math&amp;gt;. В результате этого может варьироваться результат работы алгоритма. При неудачном выборе начальных параметров итерационный процесс может сойтись к локальному оптимуму&amp;lt;ref&amp;gt;Von Luxburg, Ulrike. Clustering Stability. Now Publishers Inc, 2010.&amp;lt;/ref&amp;gt;. По этим причинам алгоритм не является ни &amp;lt;b&amp;gt;детермирированным&amp;lt;/b&amp;gt;, ни &amp;lt;b&amp;gt;устойчивым&amp;lt;/b&amp;gt;.&lt;br /&gt;
 &lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Соотношение последовательной и параллельной сложности алгоритма&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\frac{\Theta_{k-means}}{\Psi_{k-means}} = \frac{O(\Tau*k*d*n)}{O(\Tau*log(k*d*n))}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Сильные стороны алгоритма&amp;lt;/b&amp;gt;:&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;i&amp;gt;Сравнительно высокая эффективность при простоте реализации&amp;lt;/i&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;i&amp;gt;Высокое качество кластеризации&amp;lt;/i&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;i&amp;gt;Возможность распараллеливания&amp;lt;/i&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;i&amp;gt;Существование множества модификаций&amp;lt;/i&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;Недостатки алгоритма&amp;lt;/b&amp;gt;&amp;lt;ref&amp;gt;Ortega, Joaquín Pérez, Ma Del Rocío Boone Rojas, and María J. Somodevilla. &amp;quot;Research issues on K-means Algorithm: An Experimental Trial Using Matlab.&amp;quot;&amp;lt;/ref&amp;gt;:&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;i&amp;gt;Количество кластеров является параметром алгоритма&amp;lt;/i&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;&amp;lt;i&amp;gt;Чувствительность к начальным условиям&amp;lt;/i&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;Инициализация центров кластеров в значительной степени влияет на результат кластеризации.&amp;lt;/p&amp;gt;&lt;br /&gt;
  &amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;&amp;lt;i&amp;gt;Чувствительность к выбросам и шумам&amp;lt;/i&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;Выбросы, далекие от центров настоящих кластеров, все равно учитываются при вычислении их центров.&amp;lt;/p&amp;gt;&lt;br /&gt;
  &amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;&amp;lt;i&amp;gt;Возможность сходимости к локальному оптимуму&amp;lt;/i&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;Итеративный подход не дает гарантии сходимости к оптимальному решению.&amp;lt;/p&amp;gt;&lt;br /&gt;
  &amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;&amp;lt;i&amp;gt;Использование понятия &amp;quot;среднего&amp;quot;&amp;lt;/i&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;Алгоритм неприменим к данным, для которых не определено понятие &amp;quot;среднего&amp;quot;, например, категориальным данным.&amp;lt;/p&amp;gt;&lt;br /&gt;
  &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&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;
Исследование масштабируемости параллельной реализации алгоритма k means проводилось на суперкомпьютере &amp;quot;Ломоносов&amp;quot;. Алгоритм реализован на языке C с использованием средств MPI.&lt;br /&gt;
Для исследования масштабируемости проводилось множество запусков программы с разным значением параметра (количество векторов для кластеризации), а также с различным числом процессоров. Фиксировались результаты запусков &amp;amp;ndash; время работы &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt; и количество произведенных итераций алгоритма &amp;lt;math&amp;gt;\Tau&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Параметры запусков для экспериментальной оценки:&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;Значения &amp;lt;b&amp;gt;количества векторов&amp;lt;/b&amp;gt; &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;: 20&#039;000, 30&#039;000, 50&#039;000, 100&#039;000, 200&#039;000, 300&#039;000, 500&#039;000, 700&#039;000, 1&#039;000&#039;000, 1&#039;500&#039;000, 2&#039;000&#039;000.&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;Значения &amp;lt;b&amp;gt;количества процессоров&amp;lt;/b&amp;gt; &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt;: 1, 8, 16, 32, 64, 128, 160, 192, 224, 256, 288, 320, 352, 384, 416, 448, 480, 512.&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;Значение &amp;lt;b&amp;gt;количества кластеров&amp;lt;/b&amp;gt; &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt;: 100.&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;Значение &amp;lt;b&amp;gt;размерности векторов&amp;lt;/b&amp;gt; &amp;lt;math&amp;gt;d&amp;lt;/math&amp;gt;: 10.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Для проведения экспериментов были сгенерированы нормально распределенные псевдослучайные данные (с использованием Python библиотеки scikit-learn):&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
from sklearn.datasets import make_classification&lt;br /&gt;
X1, Y1 = make_classification(n_features=10, n_redundant=2, n_informative=8,&lt;br /&gt;
                             n_clusters_per_class=1, n_classes=110,&lt;br /&gt;
                             n_samples=2000000)&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Графики производительности и эффективности реализации представлены на рисунках 4 и 5 соответственно.&lt;br /&gt;
&lt;br /&gt;
[[file:Flops.png|thumb|center|800px|Рис. 4. График производительности реализации алгоритма.]]&lt;br /&gt;
&lt;br /&gt;
[[file:Efficiency.png|thumb|center|800px|Рис. 5. График эффективности реализации алгоритма.]]&lt;br /&gt;
&lt;br /&gt;
Для заданной конфигурации эксперимента (&amp;lt;math&amp;gt;n, d, p, k&amp;lt;/math&amp;gt;) и полученных результатах (&amp;lt;math&amp;gt;t, \Tau&amp;lt;/math&amp;gt;) производительность и эффективность реализации расчитывались по формулам (см. [[#Последовательная сложность алгоритма| последовательная сложность алгоритма]]):&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
&amp;lt;ul&amp;gt;&amp;lt;li&amp;gt;&amp;lt;math&amp;gt;Performance = \frac{\Theta_{k-means}^{d, n}}{t}\ \ FLOPS&amp;lt;/math&amp;gt;&amp;lt;/li&amp;gt;&amp;lt;/ul&amp;gt;&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
&amp;lt;ul&amp;gt;&amp;lt;li&amp;gt;&amp;lt;math&amp;gt;Efficiency = \frac{100 * Performance}{Performance_{Peak}^{p}}\ \ %,&amp;lt;/math&amp;gt;&amp;lt;/li&amp;gt;&amp;lt;/ul&amp;gt;&lt;br /&gt;
где &amp;lt;math&amp;gt;Performance_{Peak}^{p}&amp;lt;/math&amp;gt; &amp;amp;ndash; пиковая производительность суперкомпьютера при &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt; процессорах, вычисленная согласно спецификациям Intel&amp;lt;sup&amp;gt;&amp;amp;reg;&amp;lt;/sup&amp;gt; XEON&amp;lt;sup&amp;gt;&amp;amp;reg;&amp;lt;/sup&amp;gt; X5670&amp;lt;ref&amp;gt;&amp;quot;http://ark.intel.com/ru/products/47920/Intel-Xeon-Processor-X5670-12M-Cache-2_93-GHz-6_40-GTs-Intel-QPI&amp;quot;&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;В результате&amp;lt;/b&amp;gt; экспериментальной оценки были получены следующие оценки эффективности реализации:&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;b&amp;gt;Минимальное&amp;lt;/b&amp;gt; значение: 0.000409 % достигается при &amp;lt;math&amp;gt;n=20&#039;000, p=480&amp;lt;/math&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;b&amp;gt;Максимальное&amp;lt;/b&amp;gt; значение: 0.741119 % достигается при &amp;lt;math&amp;gt;n=300&#039;000, p=1&amp;lt;/math&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
Оценки масштабируемости реализации алгоритма k means:&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;b&amp;gt;По числу процессоров:&amp;lt;/b&amp;gt; -0.002683 &amp;amp;ndash; эффективность убывает с ростом числа процессоров.&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;b&amp;gt;По размеру задачи:&amp;lt;/b&amp;gt; 0.002779 &amp;amp;ndash; эффективность растет с ростом числа векторов.&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;b&amp;gt;Общая оценка:&amp;lt;/b&amp;gt; -0.000058 &amp;amp;ndash; можно сделать вывод, что в целом эффективность реализации незначительно уменьшается.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Динамические характеристики и эффективность реализации алгоритма ===&lt;br /&gt;
=== Выводы для классов архитектур ===&lt;br /&gt;
=== Существующие реализации алгоритма ===&lt;br /&gt;
==== Открытое программное обеспечение ====&lt;br /&gt;
&amp;lt;ol&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;[https://www.icpsr.umich.edu/CrimeStat/ CrimeStat]&amp;lt;/li&amp;gt; Программное обеспечение, созданное для операционных систем Windows, предоставляющее инструменты статистического  и пространственного анализа для решения задачи картирования преступности.&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://juliastats.github.io Julia]&amp;lt;/li&amp;gt; Высокоуровневый высокопроизводительный свободный язык программирования с динамической типизацией, созданный для математических вычислений, содержит реализацию k-means.&lt;br /&gt;
  &amp;lt;li&amp;gt;[https://mahout.apache.org Mahout]&amp;lt;/li&amp;gt; Apache Mahout - Java библиотека для работы с алгоритмами машинного обучения с использованием MapReduce. Содержит реализацию k-means.&lt;br /&gt;
  &amp;lt;li&amp;gt;[https://www.gnu.org/software/octave/ Octave]&amp;lt;/li&amp;gt; Написанная на C++  свободная система для математических вычислений, использующая совместимый с MATLAB язык высокого уровня, содержит реализацию k-means.&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://spark.apache.org/docs/latest/mllib-clustering.html Spark]&amp;lt;/li&amp;gt; Распределенная реализация k-means содержится в библиотеке Mlib для работы с алгоритмами машинного обучения, взаимодействующая с Python библиотекой NumPy и библиотека R.&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://torch.ch Torch]&amp;lt;/li&amp;gt;  MATLAB-подобная библиотека для языка программирования Lua с открытым исходным кодом, предоставляет большое количество алгоритмов для глубинного обучения и научных расчётов. Ядро написано на Си, прикладная часть выполняется на LuaJIT, поддерживается распараллеливание вычислений средствами CUDA и OpenMP. Существуют реализации k-means.&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://www.cs.waikato.ac.nz/ml/weka/ Weka]&amp;lt;/li&amp;gt;  Cвободное программное обеспечение для анализа данных, написанное на Java. Содержит k-means и x-means.&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://accord-framework.net/docs/html/T_Accord_MachineLearning_KMeans.htm Accord.NET]&amp;lt;/li&amp;gt; C# реализация алгоритмов k-means, k-means++, k-modes.&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://docs.opencv.org/3.0-beta/doc/py_tutorials/py_ml/py_kmeans/py_kmeans_opencv/py_kmeans_opencv.html OpenCV]&amp;lt;/li&amp;gt; Написанная на С++ библиотека, направленная в основном на решение задач компьютерного зрения. Содержит реализацию k-means.&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://mlpack.org/ MLPACK]&amp;lt;/li&amp;gt; Масштабируемая С++ библиотека для работы с алгоритмами машинного обучения, содержит реализацию k-means.&lt;br /&gt;
  &amp;lt;li&amp;gt;[https://www.scipy.org/ SciPy]&amp;lt;/li&amp;gt; Библиотека Python, содержит множество реализаций k-means.&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://scikit-learn.org/ scikit-learn]&amp;lt;/li&amp;gt; Библиотека Python, содержит множество реализаций k-means.&lt;br /&gt;
  &amp;lt;li&amp;gt;[https://www.r-bloggers.com/k-means-clustering-in-r/ R]&amp;lt;/li&amp;gt; Язык программирования для статистической обработки данных и работы с графикой, а также свободная программная среда вычислений с открытым исходным кодом в рамках проекта GNU, содержит три реализации k-means.&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://elki.dbs.ifi.lmu.de ELKI]&amp;lt;/li&amp;gt; Java фреймворк, содержащий реализацию k-means, а также множество других алгоритмов кластеризации.&lt;br /&gt;
&amp;lt;/ol&amp;gt;&lt;br /&gt;
==== Проприетарное программное обеспечение  ====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ol&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;[https://www.ayasdi.com/blog/bigdata/topological-data-analysis-of-oil-and-gas-petrophysical-data/ Ayasdi]&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://www.stata.com/features/cluster-analysis/ Stata]&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://mathworld.wolfram.com/K-MeansClusteringAlgorithm.html Mathematica]&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://www.mathworks.com/help/stats/kmeans.html?requestedDomain=www.mathworks.com MATLAB]&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;[https://support.sas.com/rnd/app/stat/procedures/fastclus.html SAS]&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://docs.rapidminer.com/studio/operators/modeling/segmentation/k_means.html RapidMiner]&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;[https://blogs.sap.com/2013/03/28/sap-hana-pal-k-means-algorithm-or-how-to-do-customer-segmentation-for-the-telecommunications-industry/ SAP HANA]&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ol&amp;gt;&lt;br /&gt;
== Литература ==&lt;br /&gt;
&amp;lt;references /&amp;gt;&lt;/div&gt;</summary>
		<author><name>DennZo1993</name></author>
	</entry>
	<entry>
		<id>https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:%D0%91%D1%80%D0%BE%D1%82%D0%B8%D0%BA%D0%BE%D0%B2%D1%81%D0%BA%D0%B0%D1%8F_%D0%94%D0%B0%D0%BD%D1%83%D1%82%D0%B0/%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_k-means&amp;diff=17185</id>
		<title>Участник:Бротиковская Данута/Алгоритм k-means</title>
		<link rel="alternate" type="text/html" href="https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:%D0%91%D1%80%D0%BE%D1%82%D0%B8%D0%BA%D0%BE%D0%B2%D1%81%D0%BA%D0%B0%D1%8F_%D0%94%D0%B0%D0%BD%D1%83%D1%82%D0%B0/%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_k-means&amp;diff=17185"/>
		<updated>2016-11-15T01:52:00Z</updated>

		<summary type="html">&lt;p&gt;DennZo1993: /* Масштабируемость реализации алгоритма */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt; {{Assignment|Zhum}}&lt;br /&gt;
&lt;br /&gt;
{{algorithm&lt;br /&gt;
| name              = Алгоритм k средних (k means)&lt;br /&gt;
| serial_complexity = &amp;lt;math&amp;gt;O(\Tau*k*d*n)&amp;lt;/math&amp;gt;&lt;br /&gt;
| input_data        = &amp;lt;math&amp;gt; d*n &amp;lt;/math&amp;gt;&lt;br /&gt;
| output_data       = &amp;lt;math&amp;gt; n &amp;lt;/math&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
Авторы страницы &amp;lt;b&amp;gt;[[Участник:Бротиковская Данута|Данута Бротиковская]]&amp;lt;/b&amp;gt; и &amp;lt;b&amp;gt;[[Участник:DennZo1993|Денис Зобнин]]&amp;lt;/b&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
Оба автора внесли одинаковый вклад в написание статьи (поиск материалов, изучение статей, заполнение контента статьи), четких разграничений по пунктам статьи сделать невозможно. &lt;br /&gt;
&lt;br /&gt;
== Свойства и структура алгоритма ==&lt;br /&gt;
&lt;br /&gt;
=== Общее описание алгоритма ===&lt;br /&gt;
Алгоритм &amp;lt;b&amp;gt;&amp;lt;i&amp;gt;k средних&amp;lt;/i&amp;gt;&amp;lt;/b&amp;gt; (&amp;lt;b&amp;gt;&amp;lt;i&amp;gt;k means&amp;lt;/i&amp;gt;&amp;lt;/b&amp;gt;) &amp;amp;ndash; неиерархический&amp;lt;ref&amp;gt;&amp;quot;https://ru.wikipedia.org/wiki/Иерархическая_кластеризация&amp;quot;&amp;lt;/ref&amp;gt;, итерационный метод кластеризации&amp;lt;ref&amp;gt;&amp;quot;https://ru.wikipedia.org/wiki/Кластерный_анализ&amp;quot;&amp;lt;/ref&amp;gt;, получивший большую популярность благодаря своей простоте, наглядности реализации и достаточно высокому качеству работы. Был изобретен в 1950-х годах математиком &amp;lt;i&amp;gt;Гуго Штейнгаузом&amp;lt;/i&amp;gt;&amp;lt;ref&amp;gt;Steinhaus, Hugo. &amp;quot;Sur la division des corp materiels en parties.&amp;quot; Bull. Acad. Polon. Sci 1.804 (1956): 801.&amp;lt;/ref&amp;gt; и почти одновременно &amp;lt;i&amp;gt;Стюартом Ллойдом&amp;lt;/i&amp;gt;&amp;lt;ref&amp;gt;Lloyd, S. P. &amp;quot;Least square quantization in PCM. Bell Telephone Laboratories Paper. Published in journal much later: Lloyd, SP: Least squares quantization in PCM.&amp;quot; IEEE Trans. Inform. Theor.(1957/1982).&amp;lt;/ref&amp;gt;. Особую популярность приобрел после публикации работы &amp;lt;i&amp;gt;МакКуина&amp;lt;/i&amp;gt;&amp;lt;ref&amp;gt;MacQueen, James. &amp;quot;Some methods for classification and analysis of multivariate observations.&amp;quot; Proceedings of the fifth Berkeley symposium on mathematical statistics and probability. Vol. 1. No. 14. 1967.&amp;lt;/ref&amp;gt; в 1967.&lt;br /&gt;
&lt;br /&gt;
Алгоритм представляет собой версию EM-алгоритма&amp;lt;ref&amp;gt;&amp;quot;https://ru.wikipedia.org/wiki/EM-алгоритм&amp;quot;&amp;lt;/ref&amp;gt;, применяемого также для разделения смеси гауссиан. Основная идея &amp;lt;i&amp;gt;k means&amp;lt;/i&amp;gt; заключается в том, что данные произвольно разбиваются на кластеры, после чего итеративно перевычисляется центр масс для каждого кластера, полученного на предыдущем шаге, затем векторы разбиваются на кластеры вновь в соответствии с тем, какой из новых центров оказался ближе по выбранной метрике.&lt;br /&gt;
&lt;br /&gt;
Цель алгоритма заключается в разделении &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; наблюдений на &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластеров таким образом, чтобы каждое наблюдение принадлежало ровно одному кластеру, расположенному на наименьшем расстоянии от наблюдения.&lt;br /&gt;
&lt;br /&gt;
=== Математическое описание алгоритма ===&lt;br /&gt;
&amp;lt;b&amp;gt;&amp;lt;u&amp;gt;Дано:&amp;lt;/u&amp;gt;&amp;lt;/b&amp;gt;&lt;br /&gt;
* набор из &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; наблюдений &amp;lt;math&amp;gt;X=\{\mathbf{x}_1, \mathbf{x}_2, ..., \mathbf{x}_n\}, \mathbf{x}_i \in \mathbb{R}^d, i=\overline{1, n}&amp;lt;/math&amp;gt;;&lt;br /&gt;
* &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; - требуемое число кластеров, &amp;lt;math&amp;gt;k \in \mathbb{N}, k \leq n&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;&amp;lt;u&amp;gt;Требуется:&amp;lt;/u&amp;gt;&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Разделить множество наблюдений &amp;lt;math&amp;gt;X&amp;lt;/math&amp;gt; на &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластеров &amp;lt;math&amp;gt;S_1, S_2, ..., S_k&amp;lt;/math&amp;gt;:&lt;br /&gt;
*   &amp;lt;math&amp;gt;S_i \cap S_j= \varnothing, \quad i \ne j&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
*   &amp;lt;math&amp;gt;\bigcup_{i=1}^{k} S_i = X&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;&amp;lt;u&amp;gt;Действие алгоритма:&amp;lt;/u&amp;gt;&amp;lt;/b&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;Алгоритм &amp;lt;i&amp;gt;k means&amp;lt;/i&amp;gt; разбивает набор &amp;lt;math&amp;gt;X&amp;lt;/math&amp;gt; на &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; наборов &amp;lt;math&amp;gt;S_1, S_2, ..., S_k,&amp;lt;/math&amp;gt; таким образом, чтобы минимизировать сумму квадратов расстояний от каждой точки кластера до его центра (центр масс кластера). Введем обозначение, &amp;lt;math&amp;gt;S=\{S_1, S_2, ..., S_k\}&amp;lt;/math&amp;gt;. Тогда действие алгоритма &amp;lt;i&amp;gt;k means&amp;lt;/i&amp;gt; равносильно поиску:&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;table style=&amp;quot;width:100%&amp;quot;&amp;gt;&lt;br /&gt;
  &amp;lt;tr&amp;gt;&lt;br /&gt;
    &amp;lt;td align=&amp;quot;center&amp;quot; width=&amp;quot;90%&amp;quot;&amp;gt;&amp;lt;math&amp;gt;\arg\min_{S} \sum\limits_{i=1}^k \sum\limits_{\mathbf{x} \in S_i} \rho(\mathbf{x}, \mathbf{\mu}_i )^2,&amp;lt;/math&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;td align=&amp;quot;right&amp;quot;&amp;gt;&amp;lt;math&amp;gt;(1)&amp;lt;/math&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;/table&amp;gt;&lt;br /&gt;
где &amp;lt;math&amp;gt;\mathbf{\mu}_i&amp;lt;/math&amp;gt; &amp;amp;ndash; центры кластеров, &amp;lt;math&amp;gt;i=\overline{1,k}, \quad \rho(\mathbf{x}, \mathbf{\mu}_i)&amp;lt;/math&amp;gt; &amp;amp;ndash; функция расстояния между &amp;lt;math&amp;gt;\mathbf{x}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\mu_i&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;&amp;lt;u&amp;gt;Шаги алгоритма: &amp;lt;/u&amp;gt;&amp;lt;/b&amp;gt;&lt;br /&gt;
&amp;lt;ol&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&lt;br /&gt;
    &amp;lt;b&amp;gt;Начальный шаг: инициализация кластеров&amp;lt;/b&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;Выбирается произвольное множество точек &amp;lt;math&amp;gt;\mu_i, i=\overline{1,k}&amp;lt;/math&amp;gt;, рассматриваемых как начальные центры кластеров: &amp;lt;math&amp;gt;\mu_i^{(0)} = \mu_i, \quad i=\overline{1, k}&amp;lt;/math&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
  &amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&lt;br /&gt;
    &amp;lt;b&amp;gt;Распределение векторов по кластерам&amp;lt;/b&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Шаг&amp;lt;/b&amp;gt; &amp;lt;math&amp;gt;t: \forall \mathbf{x}_i \in X, i=\overline{1,n}: \mathbf{x}_i \in S_j \iff  j=\arg\min_{k}\rho(\mathbf{x}_i,\mathbf{\mu}_k^{(t-1)})^2&amp;lt;/math&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
  &amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&lt;br /&gt;
    &amp;lt;b&amp;gt;Пересчет центров кластеров&amp;lt;/b&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Шаг &amp;lt;/b&amp;gt; &amp;lt;math&amp;gt;t: \forall i=\overline{1,k}:  \mu_i^{(t)} = \cfrac{1}{|S_i|}\sum_{\mathbf{x}\in S_i}\mathbf{x}&amp;lt;/math&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
  &amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&lt;br /&gt;
    &amp;lt;b&amp;gt;Проверка условия останова:&amp;lt;/b&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
    &#039;&#039;&#039;if&#039;&#039;&#039; &amp;lt;math&amp;gt;\exist i\in \overline{1,k}: \mu_i^{(t)} \ne \mu_i^{(t-1)}&amp;lt;/math&amp;gt; &#039;&#039;&#039;then&#039;&#039;&#039;&lt;br /&gt;
        t = t + 1;&lt;br /&gt;
        goto 2;&lt;br /&gt;
    &#039;&#039;&#039;else&#039;&#039;&#039;&lt;br /&gt;
        &#039;&#039;&#039;stop&#039;&#039;&#039;&lt;br /&gt;
  &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ol&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Вычислительное ядро алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Вычислительным ядром являются шаги 2 и 3 приведенного выше алгоритма: &amp;lt;b&amp;gt;&amp;lt;i&amp;gt;распределение векторов по кластерам&amp;lt;/i&amp;gt;&amp;lt;/b&amp;gt; и &amp;lt;b&amp;gt;&amp;lt;i&amp;gt;пересчет центров кластеров&amp;lt;/i&amp;gt;&amp;lt;/b&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;&amp;lt;i&amp;gt;Распределение векторов&amp;lt;/i&amp;gt;&amp;lt;/b&amp;gt; по кластерам предполагает вычисление расстояний между каждым вектором &amp;lt;math&amp;gt;\mathbf{x}_i \in X, i= \overline{1,n}&amp;lt;/math&amp;gt; и центрами кластера &amp;lt;math&amp;gt;\mathbf{\mu}_j, j= \overline{1,k}&amp;lt;/math&amp;gt;. Таким образом, данный шаг предполагает &amp;lt;math&amp;gt;k*n&amp;lt;/math&amp;gt; вычислений расстояний между d-мерными векторами. &lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;&amp;lt;i&amp;gt;Пересчет центров кластеров&amp;lt;/i&amp;gt;&amp;lt;/b&amp;gt; предполагает &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; вычислений центров масс &amp;lt;math&amp;gt;\mathbf{\mu}_i&amp;lt;/math&amp;gt; множеств &amp;lt;math&amp;gt;S_i, i=\overline{1,k}&amp;lt;/math&amp;gt; представленных выражением в шаге 3 представленного выше алгоритма.&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Макроструктура алгоритма ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Инициализация центров масс &amp;lt;math&amp;gt;\mu_1, ..., \mu_k&amp;lt;/math&amp;gt;&amp;lt;/b&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
Наиболее распространенными являются следующие стратегии:&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&lt;br /&gt;
    &amp;lt;b&amp;gt;Метод Forgy&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;В качестве начальных значений &amp;lt;math&amp;gt;\mu_1, ..., \mu_k&amp;lt;/math&amp;gt; берутся случайно выбранные векторы.&lt;br /&gt;
  &amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&lt;br /&gt;
    &amp;lt;b&amp;gt;Метод случайно разделения (Random Partitioning)&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;Для каждого вектора &amp;lt;math&amp;gt;\mathbf{x}_i \in X, i=\overline{1, n}&amp;lt;/math&amp;gt; выбирается случайным образом кластер &amp;lt;math&amp;gt;S_1, ..., S_k&amp;lt;/math&amp;gt;, после чего для каждого полученного кластера вычисляются значения &amp;lt;math&amp;gt;\mu_1, ..., \mu_k&amp;lt;/math&amp;gt;.&lt;br /&gt;
  &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Распределение векторов по кластерам&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Для этого шага алгоритма между векторами &amp;lt;math&amp;gt;\mathbf{x}_i \in X, i=\overline{1, n}&amp;lt;/math&amp;gt; и центрами кластеров &amp;lt;math&amp;gt;\mu_1, ..., \mu_k&amp;lt;/math&amp;gt; вычисляются &amp;lt;b&amp;gt;расстояния&amp;lt;/b&amp;gt; по формуле (как правило, используется Евлидово расстояние):&lt;br /&gt;
&amp;lt;table style=&amp;quot;width:100%&amp;quot;&amp;gt;&lt;br /&gt;
  &amp;lt;tr&amp;gt;&lt;br /&gt;
    &amp;lt;td align=&amp;quot;center&amp;quot; width=&amp;quot;90%&amp;quot;&amp;gt;&amp;lt;math&amp;gt; \mathbf{v}_1, \mathbf{v}_2 \in \mathbb{R}^d,  \quad \rho(\mathbf{v}_1, \mathbf{v}_2) = \lVert \mathbf{v}_1- \mathbf{v}_2 \rVert= \sqrt{\sum_{i=1}^{d}(\mathbf{v}_{1,i} - \mathbf{v}_{2,i})^2}&amp;lt;/math&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;td align=&amp;quot;right&amp;quot;&amp;gt;&amp;lt;math&amp;gt;(2)&amp;lt;/math&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;/table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Пересчет центров кластеров&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Для этого шага алгоритма производится пересчет центров кластера по &amp;lt;b&amp;gt;формуле вычисления центра масс&amp;lt;/b&amp;gt;:&lt;br /&gt;
&amp;lt;table style=&amp;quot;width:100%&amp;quot;&amp;gt;&lt;br /&gt;
  &amp;lt;tr&amp;gt;&lt;br /&gt;
    &amp;lt;td align=&amp;quot;center&amp;quot; width=&amp;quot;90%&amp;quot;&amp;gt;&amp;lt;math&amp;gt; \mu = \cfrac{1}{|S|}\sum_{\mathbf{x}\in S}\mathbf{x}&amp;lt;/math&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;td align=&amp;quot;right&amp;quot;&amp;gt;&amp;lt;math&amp;gt;(3)&amp;lt;/math&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;/table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Схема реализации последовательного алгоритма ===&lt;br /&gt;
&lt;br /&gt;
 &#039;&#039;&#039;algorithm&#039;&#039;&#039; k-means &#039;&#039;&#039;is&#039;&#039;&#039;&lt;br /&gt;
     &#039;&#039;&#039;1.&#039;&#039;&#039; Инициализировать центры кластеров &amp;lt;math&amp;gt;\mathbf{\mu}_i^{(1)}, i=\overline{1,k}&amp;lt;/math&amp;gt;&lt;br /&gt;
     &#039;&#039;&#039;2.&#039;&#039;&#039; &amp;lt;math&amp;gt;t \leftarrow 1&amp;lt;/math&amp;gt;&lt;br /&gt;
     &#039;&#039;&#039;3.&#039;&#039;&#039; &#039;&#039;&#039;Распределение по кластерам&#039;&#039;&#039;&amp;lt;br&amp;gt;&lt;br /&gt;
        &amp;lt;math&amp;gt;S_i^{(t)}=\{\mathbf{x}_p: \lVert\mathbf{x}_p-\mathbf{\mu}_i^{(t)}\rVert^2 \leq \lVert\mathbf{x}_p-\mathbf{\mu}_j^{(t)}\rVert^2 \quad \forall j=\overline{1,k}\},&amp;lt;/math&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
        где каждый вектор &amp;lt;math&amp;gt;\mathbf{x}_p&amp;lt;/math&amp;gt; соотносится единственному кластеру &amp;lt;math&amp;gt;S^{(t)}&amp;lt;/math&amp;gt;&lt;br /&gt;
     &#039;&#039;&#039;4.&#039;&#039;&#039; &#039;&#039;&#039;Обновление центров кластеров&#039;&#039;&#039;&amp;lt;br&amp;gt;&lt;br /&gt;
        &amp;lt;math&amp;gt;\mathbf{\mu}_i^{(t+1)} = \frac{1}{|S^{(t)}_i|} \sum_{\mathbf{x}_j \in S^{(t)}_i} \mathbf{x}_j &amp;lt;/math&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
     &#039;&#039;&#039;5.&#039;&#039;&#039; &#039;&#039;&#039;if&#039;&#039;&#039; &amp;lt;math&amp;gt;\exist i \in \overline{1,k}: \mathbf{\mu}_i^{(t+1)} \ne \mathbf{\mu}_i^{(t)}&amp;lt;/math&amp;gt; &#039;&#039;&#039;then&#039;&#039;&#039;&lt;br /&gt;
            t = t + 1;&lt;br /&gt;
            goto &#039;&#039;&#039;3&#039;&#039;&#039;;&lt;br /&gt;
        &#039;&#039;&#039;else&#039;&#039;&#039;&lt;br /&gt;
            &#039;&#039;&#039;stop&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
=== Последовательная сложность алгоритма===&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding-bottom: 20px&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;Обозначим &amp;lt;math&amp;gt;\Theta_{centroid}^{d, m}&amp;lt;/math&amp;gt; временную сложность вычисления центорида кластера, число элементов которого равна &amp;lt;math&amp;gt;m&amp;lt;/math&amp;gt;,  в d-мерном пространстве.&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;Аналогично  &amp;lt;math&amp;gt;\Theta_{distance}^d&amp;lt;/math&amp;gt; &amp;amp;ndash; временная сложность вычисления расстояния между двумя d-мерными векторами.&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding-bottom: 20px&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;Сложность шага инициализации &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластеров мощности &amp;lt;math&amp;gt;m&amp;lt;/math&amp;gt; в d-мерном пространстве &amp;amp;ndash; &amp;lt;math&amp;gt;\Theta_{init}^{k, d, m}&amp;lt;/math&amp;gt;&amp;lt;/b&amp;gt;&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;i&amp;gt;Стратерия Forgy&amp;lt;/i&amp;gt;: вычисления не требуются, &amp;lt;math&amp;gt;\Theta_{init}^{k, d, m} = 0&amp;lt;/math&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;i&amp;gt;Стратегия случайного разбиения&amp;lt;/i&amp;gt;: вычисление центров &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластеров,  &amp;lt;math&amp;gt;\Theta_{init}^{k, d, m} = k*\Theta_{centroid}^{d, m}, m \le n&amp;lt;/math&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding-bottom: 20px&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Cложность шага распределения d мерных векторов по &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластерам &amp;amp;ndash; &amp;lt;math&amp;gt;\Theta_{distribute}^{k, d}&amp;lt;/math&amp;gt;&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
На этом шаге для каждого вектора &amp;lt;math&amp;gt;\mathbf{x}_i \in X, i=\overline{1, n}&amp;lt;/math&amp;gt; вычисляется k расстояний до центров кластеров &amp;lt;math&amp;gt;\mathbf{\mu}_1, ...\mathbf{\mu}_k&amp;lt;/math&amp;gt;&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p align=&amp;quot;center&amp;quot;&amp;gt;&lt;br /&gt;
  &amp;lt;math&amp;gt;\Theta_{distribute}^{k, d} = n*k*\Theta_{distance}^d&amp;lt;/math&amp;gt;&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding-bottom: 20px&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;Сложность шага пересчета центров &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластеров размера &amp;lt;math&amp;gt;m&amp;lt;/math&amp;gt; в d-мерном пространстве &amp;amp;ndash; &amp;lt;math&amp;gt;\Theta_{recenter}^{k, d, m}&amp;lt;/math&amp;gt;&amp;lt;/b&amp;gt;&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;На этом шаге вычисляется &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; центров кластеров &amp;lt;math&amp;gt;\mathbf{\mu}_1, ...\mathbf{\mu}_k&amp;lt;/math&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p align=&amp;quot;center&amp;quot;&amp;gt;&amp;lt;math&amp;gt;\Theta_{recenter}^{k, d, m} = k*\Theta_{centroid}^{d, m}&amp;lt;/math&amp;gt; &amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding-bottom: 20px&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Рассчитаем &amp;lt;math&amp;gt;\Theta_{centroid}^{d, m}&amp;lt;/math&amp;gt; для кластера, число элементов которого равно &amp;lt;math&amp;gt;m&amp;lt;/math&amp;gt;&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p align=&amp;quot;center&amp;quot;&amp;gt;&amp;lt;math&amp;gt;\Theta_{centroid}^{d, m}&amp;lt;/math&amp;gt; = &amp;lt;math&amp;gt;m * d&amp;lt;/math&amp;gt; сложений + &amp;lt;math&amp;gt;d&amp;lt;/math&amp;gt; делений &amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding-bottom: 20px&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Рассчитаем &amp;lt;math&amp;gt;\Theta_{distance}^d&amp;lt;/math&amp;gt; в соответствие с формулой &amp;lt;math&amp;gt;(2)&amp;lt;/math&amp;gt;&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p align=&amp;quot;center&amp;quot;&amp;gt;&amp;lt;math&amp;gt;\Theta_{distance}^d&amp;lt;/math&amp;gt; = &amp;lt;math&amp;gt;d&amp;lt;/math&amp;gt; вычитаний + &amp;lt;math&amp;gt;d&amp;lt;/math&amp;gt; умножений + &amp;lt;math&amp;gt;(d-1)&amp;lt;/math&amp;gt; сложение&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding-bottom: 20px&amp;quot;&amp;gt;&lt;br /&gt;
  &amp;lt;p&amp;gt;Предположим, что алгоритм сошелся за &amp;lt;math&amp;gt;\Tau&amp;lt;/math&amp;gt; итераций, тогда временная сложность алгоритма &amp;lt;math&amp;gt;\Theta_{k-means}^{d, n}&amp;lt;/math&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
  &amp;lt;p align=&amp;quot;center&amp;quot;&amp;gt;&amp;lt;b&amp;gt;&amp;lt;math&amp;gt;\Theta_{k-means}^{d, n} \le \Theta_{init}^{k, d, n} + \Tau*(\Theta_{distribute}^{k, d} + \Theta_{recenter}^{k, d, n})&amp;lt;/math&amp;gt;&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding-bottom: 5px&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;Операции сложения/вычитания:&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p align=&amp;quot;center&amp;quot;&amp;gt;&amp;lt;b&amp;gt;&amp;lt;math&amp;gt;\Theta_{k-means}^{d, n} \le k*n*d+ \Tau*(k*n*(2d-1) + k*n*d) = k*n*d+ \Tau*(k*n*(3d-1)) \thicksim O(\Tau*k*d*n)&amp;lt;/math&amp;gt;&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding-bottom: 20px&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;Операции умножения/деления:&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p align=&amp;quot;center&amp;quot;&amp;gt;&amp;lt;b&amp;gt;&amp;lt;math&amp;gt;\Theta_{k-means}^{d, n} \le k*d + \Tau*(k*n*d + k*d) = k*d + \Tau * k*d*(n+1) \thicksim O(\Tau*k*d*n) &amp;lt;/math&amp;gt;&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding-bottom: 20px&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;Получаем, что &amp;lt;b&amp;gt;временная сложность&amp;lt;/b&amp;gt; алгоритма &amp;lt;b&amp;gt;k means&amp;lt;/b&amp;gt; кластеризации &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; &amp;lt;b&amp;gt;d-мерных&amp;lt;/b&amp;gt; векторов на &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластеров за &amp;lt;math&amp;gt;\Tau&amp;lt;/math&amp;gt; итераций:&amp;lt;/p&amp;gt;&lt;br /&gt;
 &amp;lt;p align=&amp;quot;center&amp;quot;&amp;gt;&amp;lt;b&amp;gt;&amp;lt;math&amp;gt; \Theta_{k-means}^{d, n} \thicksim O(\Tau*k*d*n) &amp;lt;/math&amp;gt;&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Информационный граф ===&lt;br /&gt;
&lt;br /&gt;
Рассмотрим информационный граф алгоритма. Алгоритм &amp;lt;i&amp;gt;k means&amp;lt;/i&amp;gt; начинается с этапа инициализации, после которого следуют итерации, на каждой из которых выполняется два последовательных шага (см. [[#Схема реализации последовательного алгоритма|&amp;quot;Схема реализации последовательного алгоритма&amp;quot;]]): &lt;br /&gt;
* распределение векторов по кластерам&lt;br /&gt;
* перерасчет центров кластеров&lt;br /&gt;
&lt;br /&gt;
Поскольку основная часть вычислений приходится на шаги итераций, распишем информационные графы данных шагов.&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Распределение векторов по кластерам&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
Информационный граф шага распределения векторов по кластерам представлен на &#039;&#039;рисунке 1&#039;&#039;. Исходами данного графа является исходные векторы &amp;lt;math&amp;gt;\mathbf{x}_1, ..., \mathbf{x}_n&amp;lt;/math&amp;gt;, а также центры кластеров &amp;lt;math&amp;gt;\mathbf{\mu}_1, ... \mathbf{\mu}_k&amp;lt;/math&amp;gt;, вычисленные ранее (на шаге инициализации, если рассматривается первая итерация алгоритма, или на шаге пересчета центров кластеров предыдущей итерации в противном случае). Каждая пара векторов данных &amp;lt;math&amp;gt;\mathbf{x}_i, i=\overline{1,n}&amp;lt;/math&amp;gt; и центров кластера &amp;lt;math&amp;gt;\mathbf{\mu}_j, j=\overline{1, k}&amp;lt;/math&amp;gt; : (&amp;lt;math&amp;gt;\mathbf{x}_i&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;\mathbf{\mu}_j&amp;lt;/math&amp;gt;) подаются на независимые узлы &amp;lt;i&amp;gt;&amp;quot;d&amp;quot;&amp;lt;/i&amp;gt; вычисления расстояния между векторами (более подробная схема вычисления расстояния представлена далее, &#039;&#039;рисунок 2&#039;&#039;). Далее узлы вычисления расстояния &amp;lt;i&amp;gt;&amp;quot;d&amp;quot;&amp;lt;/i&amp;gt;, соответствующие одному и тому же исходному вектору &amp;lt;math&amp;gt;\mathbf{x}_i&amp;lt;/math&amp;gt; передаются на один узел &amp;lt;i&amp;gt;&amp;quot;m&amp;quot;&amp;lt;/i&amp;gt;, где далее происходит вычисление новой метки кластера для каждого вектора &amp;lt;math&amp;gt;\mathbf{x}_i&amp;lt;/math&amp;gt; (берется кластер с минимальным результатом вычисления расстояния). На выходе графа выдаются метки кластеров , &amp;lt;math&amp;gt;L_1, ..., L_n&amp;lt;/math&amp;gt;, такие что &amp;lt;math&amp;gt;\forall \mathbf{x}_i, i=\overline{1, n}, \mathbf{x}_i \in S_j \Leftrightarrow L_i = j&amp;lt;/math&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
[[file:Clusterization.png|thumb|center|800px|Рис. 1. Схема распределения векторов по кластерам. &#039;&#039;d&#039;&#039; &amp;amp;ndash; вычисление расстояния между векторами; &#039;&#039;m&#039;&#039; &amp;amp;ndash; вычисление минимума.]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Вычисление расстояния между векторами&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
Подробная схема вычисления расстояния между векторами &amp;lt;math&amp;gt;\mathbf{x}_i, \mathbf{\mu}_j&amp;lt;/math&amp;gt; представлена на &#039;&#039;рисунке 2&#039;&#039;. Как показано на графе, узел вычисления расстояния между векторами &amp;lt;i&amp;gt;&amp;quot;d&amp;quot;&amp;lt;/i&amp;gt; состоит из шага взятия разности между векторами (узел &amp;quot;&amp;lt;math&amp;gt;-&amp;lt;/math&amp;gt;&amp;quot;) и взятия нормы получившегося вектора разности (узел &amp;quot;&amp;lt;math&amp;gt;||\cdot||^2&amp;lt;/math&amp;gt;&amp;quot;). Более подробно, вычисление расстояния между векторами &amp;lt;math&amp;gt;\mathbf{x}_i = {x_{i1,}, ...,{x_{in}}}, \mathbf{\mu}_j = {\mu_{j1}, ...,\mu_{jn}}&amp;lt;/math&amp;gt; может быть представлено как вычисление разности между каждой парой компонент &amp;lt;math&amp;gt;(x_{iz}, \mu_{jz}), z=\overline{1, d}&amp;lt;/math&amp;gt; (узел &amp;quot;&amp;lt;math&amp;gt;-&amp;lt;/math&amp;gt;&amp;quot;), далее возведение в квадрат для каждого узла &amp;quot;&amp;lt;math&amp;gt;-&amp;lt;/math&amp;gt;&amp;quot; (узел &amp;quot;&amp;lt;math&amp;gt;()^2&amp;lt;/math&amp;gt;&amp;quot;) и суммирования выходов всех узлов &amp;quot;&amp;lt;math&amp;gt;()^2&amp;lt;/math&amp;gt;&amp;quot; (узел &amp;quot;&amp;lt;math&amp;gt;+&amp;lt;/math&amp;gt;&amp;quot;).  &lt;br /&gt;
&lt;br /&gt;
[[file:dist_calc.png|thumb|center|800px|Рис. 2. Схема вычисления расстояния между вектором и центром кластера.]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Пересчет центров кластеров&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
Информационный граф шага пересчета центров кластеров представлен на &#039;&#039;рисунке 3&#039;&#039;. Исходами данного графа является исходные векторы &amp;lt;math&amp;gt;\mathbf{x}_1, ..., \mathbf{x}_n&amp;lt;/math&amp;gt;, а также им соответствующие метки кластера, &amp;lt;math&amp;gt;L_1, ..., L_n&amp;lt;/math&amp;gt;, такие что &amp;lt;math&amp;gt;\forall x_i, i=\overline{1, n}, \mathbf{x}_i \in S_j \Leftrightarrow L_i = j&amp;lt;/math&amp;gt;, вычисленные на этапе распределения векторов по кластерам. Все векторы &amp;lt;math&amp;gt;\mathbf{x}_1, ..., \mathbf{x}_n&amp;lt;/math&amp;gt; подаются в узлы &amp;lt;math&amp;gt;+_1, ...+_k&amp;lt;/math&amp;gt;, каждый узел &amp;lt;math&amp;gt;+_m, m = \overline{1,k}&amp;lt;/math&amp;gt; соответствует операции сложения векторов кластера с номером &amp;lt;math&amp;gt;m&amp;lt;/math&amp;gt;. Метки кластера &amp;lt;math&amp;gt;L_1, ..., L_n&amp;lt;/math&amp;gt; также совместно передаются на узлы &amp;lt;math&amp;gt;S_m, m = \overline{1,k}&amp;lt;/math&amp;gt;, на каждом из которых вычисляется количество векторов в соответствующем кластере (количество меток с соответствующим значением). Далее каждая пара выходов узлов &amp;lt;math&amp;gt;+_m&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;S_m&amp;lt;/math&amp;gt; подается на узел &amp;quot;&amp;lt;math&amp;gt;/&amp;lt;/math&amp;gt;&amp;quot;, где производится деление суммы векторов кластера на количество элементов в нем. Значения, вычисленные на узлах &amp;quot;&amp;lt;math&amp;gt;/&amp;lt;/math&amp;gt;&amp;quot;, присваиваются новым центрам кластеров (выходные значения графа).&lt;br /&gt;
&lt;br /&gt;
[[file:Recluster.png|thumb|center|800px|Рис. 3. Схема пересчета центров кластеров]]&lt;br /&gt;
&lt;br /&gt;
=== Ресурс параллелизма алгоритма ===&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
Работа алгоритма состоит из &amp;lt;math&amp;gt;\Tau&amp;lt;/math&amp;gt; итераций, в каждой из которых происходит &amp;lt;b&amp;gt;распределение d-мерных векторов по &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластерам&amp;lt;/b&amp;gt;, а также &amp;lt;b&amp;gt;пересчет центров кластеров в d-мерном пространстве&amp;lt;/b&amp;gt;. В шаге &amp;lt;b&amp;gt;распределения d-мерных векторов по &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластерам&amp;lt;/b&amp;gt; расстояния между вектором и центрами кластеров вычисляются независимо (отсутствуют информационные зависимости). &amp;lt;b&amp;gt;Центры масс кластеров&amp;lt;/b&amp;gt; также пересчитываются независимо друг от друга. Таким образом, имеет место [[глоссарий#Массовый параллелизм|&#039;&#039;массовый параллелизм&#039;&#039;]]. Вычислим параллельную сложность &amp;lt;math&amp;gt;\Psi_*&amp;lt;/math&amp;gt; каждого из шагов, а также параллельную сложность всего алгоритма, &amp;lt;math&amp;gt;\Psi_{k-means}&amp;lt;/math&amp;gt;. Будем исходить из предположения, что может быть использовано любое необходимое число потоков.&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Распределение d-мерных векторов по &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластерам&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;  &lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
Поскольку на данном шаге для каждой пары векторов &amp;lt;math&amp;gt;\mathbf{x}_i, i=\overline{1,n}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\mathbf{\mu}_j, j=\overline{1,k}&amp;lt;/math&amp;gt; операции вычисления расстояния не зависят друг от друга, они могут выполняться параллельно. Тогда, разделив все вычисление расстояний на &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; потоков, получим, что в каждом потоке будет выполняться только одна операция вычисления расстояния между векторами размерности d. При этом каждому вычислительному потоку передаются координаты центров всех кластеров &amp;lt;math&amp;gt;\mathbf{\mu}_1, ..., \mathbf{\mu}_k&amp;lt;/math&amp;gt;. Таким образом, параллельная сложность данного шага определяется &amp;lt;i&amp;gt; сложностью параллельной операции вычисления расстояния между d-мерными векторами&amp;lt;/i&amp;gt;, &amp;lt;math&amp;gt;\Psi_{distance}^d&amp;lt;/math&amp;gt;  и &amp;lt;i&amp;gt;сложностью определения наиболее близкого кластера&amp;lt;/i&amp;gt; (паралельное взятие минимума по расстояниям), &amp;lt;math&amp;gt;\Psi_{min}^k&amp;lt;/math&amp;gt;. Для оценки &amp;lt;math&amp;gt;\Psi_{distance}^d&amp;lt;/math&amp;gt; воспользуемся  [[Нахождение_частных_сумм_элементов_массива_сдваиванием | параллельной реализацией нахождения частичной суммы элементов массива путем сдваивания]]. Аналогично, &amp;lt;math&amp;gt;\Psi_{min}^k = log(k)&amp;lt;/math&amp;gt;. В результате, &amp;lt;math&amp;gt;\Psi_{distance}^d = O(log(d))&amp;lt;/math&amp;gt;.   Таким образом: &lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p align=&amp;quot;center&amp;quot;&amp;gt;&amp;lt;math&amp;gt;\Psi_{distribute}^{k, d}  = \Psi_{distance}^d + \Psi_{min}^k = O(log(d))+O(log(k)) = O(log(k*d))&amp;lt;/math&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Пересчет центров кластеров в d-мерном пространстве&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
Поскольку на данном шаге для каждого из &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластеров центр масс может быть вычислен независимо, данные операции могут быть выполнены в отдельных потоках. Таким образом, параллельная сложность данного шага, &amp;lt;math&amp;gt;\Psi_{recenter}^{k, d}&amp;lt;/math&amp;gt;,  будет определяться &amp;lt;i&amp;gt;параллельной сложностью вычисления одного центра масс кластера размера &amp;lt;math&amp;gt;m&amp;lt;/math&amp;gt;&amp;lt;/i&amp;gt;, &amp;lt;math&amp;gt;\Psi_{recenter}^{k, d}&amp;lt;/math&amp;gt;,  а так как &amp;lt;math&amp;gt;m \le n \Rightarrow \Psi_{recenter}^{d, m} \le \Psi_{recenter}^{d, n}&amp;lt;/math&amp;gt;. Сложность вычисления центра масс кластера d-мерных векторов размера n аналогично предыдущим вычислениям равна &amp;lt;math&amp;gt;O(log(n))&amp;lt;/math&amp;gt;. Тогда:  &lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p align=&amp;quot;center&amp;quot;&amp;gt;&amp;lt;math&amp;gt;\Psi_{recenter}^{k, d}  \le \Psi_{recenter}^{d, n} = O(log(n))&amp;lt;/math&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Общая параллельная сложность алгоритма&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
На каждой итерации необходимо обновление центров кластеров, которые будут использованы на следующей итерации. Таким образом, итерационный процесс выполняется последовательно&amp;lt;ref&amp;gt;Zhao, Weizhong, Huifang Ma, and Qing He. &amp;quot;Parallel k-means clustering based on mapreduce.&amp;quot; IEEE International Conference on Cloud Computing. Springer Berlin Heidelberg, 2009.&amp;lt;/ref&amp;gt;. Тогда, поскольку сложность каждой итерации  определяется &amp;lt;math&amp;gt;\Psi_{distribute}^{k, d}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\Psi_{recenter}&amp;lt;/math&amp;gt;, сложность всего алгоритма, &amp;lt;math&amp;gt;\Psi_{k-means}&amp;lt;/math&amp;gt; в предположении, что было сделано &amp;lt;math&amp;gt;\Tau&amp;lt;/math&amp;gt; операций определяется выражением&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p align=&amp;quot;center&amp;quot;&amp;gt;&amp;lt;math&amp;gt;\Psi_{k-means} \approx \Tau * (\Psi_{distribute}^{k, d} + \Psi_{recenter}^{k, d}) \le \Tau * O(log(k*d*n))&amp;lt;/math&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Входные и выходные данные алгоритма ===&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;Входные данные&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;Матрица из &amp;lt;math&amp;gt;n*d&amp;lt;/math&amp;gt; элементов &amp;lt;math&amp;gt;x_{i, j} \in \mathbb{R}, i=\overline{1, n}, j=\overline{1, d}&amp;lt;/math&amp;gt;&amp;amp;ndash; координат векторов (наблюдений).&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;Целое положительное число &amp;lt;math&amp;gt;k, k \le n&amp;lt;/math&amp;gt; &amp;amp;ndash; количество кластеров.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;Объем входных данных&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;math&amp;gt;1&amp;lt;/math&amp;gt; целое число + &amp;lt;math&amp;gt;n*d&amp;lt;/math&amp;gt; вещественных чисел (при условии, что координаты &amp;amp;ndash; вещественные числа).&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;Выходные данные&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; целых положительных чисел &amp;lt;math&amp;gt;L_1, ..., L_n&amp;lt;/math&amp;gt;&amp;amp;ndash; номера кластеров, соотвествующие каждому вектору (при условии, что нумерация кластеров начинается с &amp;lt;math&amp;gt;1&amp;lt;/math&amp;gt;).&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;Объем выходных данных&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; целых положительных чисел.&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Свойства алгоритма ===&lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;[[глоссарий#Вычислительная мощность|&#039;&#039;Вычислительная мощность&#039;&#039;]]&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
Вычислительная мощность алгоритма &amp;lt;i&amp;gt;k means&amp;lt;/i&amp;gt; равна &amp;lt;math&amp;gt;\frac{k*d*n*\Tau}{n*d} = k*\Tau &amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; &amp;amp;ndash; число кластеров, &amp;lt;math&amp;gt;\Tau&amp;lt;/math&amp;gt; &amp;amp;ndash; число итераций алгоритма.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;[[глоссарий#Детерминированность |&#039;&#039;Детерминированность&#039;&#039;]] и [[глоссарий#Устойчивость |&#039;&#039;Устойчивость&#039;&#039;]] &amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
Алгоритм &amp;lt;i&amp;gt;k means&amp;lt;/i&amp;gt; является итерационным. Количество итераций алгоритма в общем случае не фиксируется и зависит от начального расположения объектов в пространстве, параметра &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt;, а также от начального приближения центров кластеров, &amp;lt;math&amp;gt;\mu_1, ..., \mu_k&amp;lt;/math&amp;gt;. В результате этого может варьироваться результат работы алгоритма. При неудачном выборе начальных параметров итерационный процесс может сойтись к локальному оптимуму&amp;lt;ref&amp;gt;Von Luxburg, Ulrike. Clustering Stability. Now Publishers Inc, 2010.&amp;lt;/ref&amp;gt;. По этим причинам алгоритм не является ни &amp;lt;b&amp;gt;детермирированным&amp;lt;/b&amp;gt;, ни &amp;lt;b&amp;gt;устойчивым&amp;lt;/b&amp;gt;.&lt;br /&gt;
 &lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Соотношение последовательной и параллельной сложности алгоритма&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\frac{\Theta_{k-means}}{\Psi_{k-means}} = \frac{O(\Tau*k*d*n)}{O(\Tau*log(k*d*n))}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Сильные стороны алгоритма&amp;lt;/b&amp;gt;:&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;i&amp;gt;Сравнительно высокая эффективность при простоте реализации&amp;lt;/i&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;i&amp;gt;Высокое качество кластеризации&amp;lt;/i&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;i&amp;gt;Возможность распараллеливания&amp;lt;/i&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;i&amp;gt;Существование множества модификаций&amp;lt;/i&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;Недостатки алгоритма&amp;lt;/b&amp;gt;&amp;lt;ref&amp;gt;Ortega, Joaquín Pérez, Ma Del Rocío Boone Rojas, and María J. Somodevilla. &amp;quot;Research issues on K-means Algorithm: An Experimental Trial Using Matlab.&amp;quot;&amp;lt;/ref&amp;gt;:&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;i&amp;gt;Количество кластеров является параметром алгоритма&amp;lt;/i&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;&amp;lt;i&amp;gt;Чувствительность к начальным условиям&amp;lt;/i&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;Инициализация центров кластеров в значительной степени влияет на результат кластеризации.&amp;lt;/p&amp;gt;&lt;br /&gt;
  &amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;&amp;lt;i&amp;gt;Чувствительность к выбросам и шумам&amp;lt;/i&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;Выбросы, далекие от центров настоящих кластеров, все равно учитываются при вычислении их центров.&amp;lt;/p&amp;gt;&lt;br /&gt;
  &amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;&amp;lt;i&amp;gt;Возможность сходимости к локальному оптимуму&amp;lt;/i&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;Итеративный подход не дает гарантии сходимости к оптимальному решению.&amp;lt;/p&amp;gt;&lt;br /&gt;
  &amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;&amp;lt;i&amp;gt;Использование понятия &amp;quot;среднего&amp;quot;&amp;lt;/i&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;Алгоритм неприменим к данным, для которых не определено понятие &amp;quot;среднего&amp;quot;, например, категориальным данным.&amp;lt;/p&amp;gt;&lt;br /&gt;
  &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&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;
Исследование масштабируемости параллельной реализации алгоритма k means проводилось на суперкомпьютере &amp;quot;Ломоносов&amp;quot;. Алгоритм реализован на языке C с использованием средств MPI.&lt;br /&gt;
Для исследования масштабируемости проводилось множество запусков программы с разным значением параметра (количество векторов для кластеризации), а также с различным числом процессоров. Фиксировались результаты запусков &amp;amp;ndash; время работы &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt; и количество произведенных итераций алгоритма &amp;lt;math&amp;gt;\Tau&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Параметры запусков для экспериментальной оценки:&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;Значения &amp;lt;b&amp;gt;количества векторов&amp;lt;/b&amp;gt; &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;: 20&#039;000, 30&#039;000, 50&#039;000, 100&#039;000, 200&#039;000, 300&#039;000, 500&#039;000, 700&#039;000, 1&#039;000&#039;000, 1&#039;500&#039;000, 2&#039;000&#039;000.&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;Значения &amp;lt;b&amp;gt;количества процессоров&amp;lt;/b&amp;gt; &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt;: 1, 8, 16, 32, 64, 128, 160, 192, 224, 256, 288, 320, 352, 384, 416, 448, 480, 512.&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;Значение &amp;lt;b&amp;gt;количества кластеров&amp;lt;/b&amp;gt; &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt;: 100.&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;Значение &amp;lt;b&amp;gt;размерности векторов&amp;lt;/b&amp;gt; &amp;lt;math&amp;gt;d&amp;lt;/math&amp;gt;: 10.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Для проведения экспериментов были сгенерированы нормально распределенные псевдослучайные данные (с использованием Python библиотеки scikit-learn):&lt;br /&gt;
 from sklearn.datasets import make_classification&lt;br /&gt;
 X1, Y1 = make_classification(n_features=10, n_redundant=2, n_informative=8,&lt;br /&gt;
                              n_clusters_per_class=1, n_classes=110,&lt;br /&gt;
                              n_samples=1500000)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Графики производительности и эффективности реализации представлены на рисунках 4 и 5 соответственно.&lt;br /&gt;
&lt;br /&gt;
[[file:Flops.png|thumb|center|800px|Рис. 4. График производительности реализации алгоритма.]]&lt;br /&gt;
&lt;br /&gt;
[[file:Efficiency.png|thumb|center|800px|Рис. 5. График эффективности реализации алгоритма.]]&lt;br /&gt;
&lt;br /&gt;
Для заданной конфигурации эксперимента (&amp;lt;math&amp;gt;n, d, p, k&amp;lt;/math&amp;gt;) и полученных результатах (&amp;lt;math&amp;gt;t, \Tau&amp;lt;/math&amp;gt;) производительность и эффективность реализации расчитывались по формулам (см. [[#Последовательная сложность алгоритма| последовательная сложность алгоритма]]):&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
&amp;lt;ul&amp;gt;&amp;lt;li&amp;gt;&amp;lt;math&amp;gt;Performance = \frac{\Theta_{k-means}^{d, n}}{t}\ \ FLOPS&amp;lt;/math&amp;gt;&amp;lt;/li&amp;gt;&amp;lt;/ul&amp;gt;&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
&amp;lt;ul&amp;gt;&amp;lt;li&amp;gt;&amp;lt;math&amp;gt;Efficiency = \frac{100 * Performance}{Performance_{Peak}^{p}}\ \ %,&amp;lt;/math&amp;gt;&amp;lt;/li&amp;gt;&amp;lt;/ul&amp;gt;&lt;br /&gt;
где &amp;lt;math&amp;gt;Performance_{Peak}^{p}&amp;lt;/math&amp;gt; &amp;amp;ndash; пиковая производительность суперкомпьютера при &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt; процессорах, вычисленная согласно спецификациям Intel&amp;lt;sup&amp;gt;&amp;amp;reg;&amp;lt;/sup&amp;gt; XEON&amp;lt;sup&amp;gt;&amp;amp;reg;&amp;lt;/sup&amp;gt; X5670&amp;lt;ref&amp;gt;&amp;quot;http://ark.intel.com/ru/products/47920/Intel-Xeon-Processor-X5670-12M-Cache-2_93-GHz-6_40-GTs-Intel-QPI&amp;quot;&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;В результате&amp;lt;/b&amp;gt; экспериментальной оценки были получены следующие оценки эффективности реализации:&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;b&amp;gt;Минимальное&amp;lt;/b&amp;gt; значение: 0.000409 % достигается при &amp;lt;math&amp;gt;n=20&#039;000, p=480&amp;lt;/math&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;b&amp;gt;Максимальное&amp;lt;/b&amp;gt; значение: 0.741119 % достигается при &amp;lt;math&amp;gt;n=300&#039;000, p=1&amp;lt;/math&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
Оценки масштабируемости реализации алгоритма k means:&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;b&amp;gt;По числу процессоров:&amp;lt;/b&amp;gt; -0.002683 &amp;amp;ndash; эффективность убывает с ростом числа процессоров.&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;b&amp;gt;По размеру задачи:&amp;lt;/b&amp;gt; 0.002779 &amp;amp;ndash; эффективность растет с ростом числа векторов.&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;b&amp;gt;Общая оценка:&amp;lt;/b&amp;gt; -0.000058 &amp;amp;ndash; можно сделать вывод, что в целом эффективность реализации незначительно уменьшается.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Динамические характеристики и эффективность реализации алгоритма ===&lt;br /&gt;
=== Выводы для классов архитектур ===&lt;br /&gt;
=== Существующие реализации алгоритма ===&lt;br /&gt;
==== Открытое программное обеспечение ====&lt;br /&gt;
&amp;lt;ol&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;[https://www.icpsr.umich.edu/CrimeStat/ CrimeStat]&amp;lt;/li&amp;gt; Программное обеспечение, созданное для операционных систем Windows, предоставляющее инструменты статистического  и пространственного анализа для решения задачи картирования преступности.&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://juliastats.github.io Julia]&amp;lt;/li&amp;gt; Высокоуровневый высокопроизводительный свободный язык программирования с динамической типизацией, созданный для математических вычислений, содержит реализацию k-means.&lt;br /&gt;
  &amp;lt;li&amp;gt;[https://mahout.apache.org Mahout]&amp;lt;/li&amp;gt; Apache Mahout - Java библиотека для работы с алгоритмами машинного обучения с использованием MapReduce. Содержит реализацию k-means.&lt;br /&gt;
  &amp;lt;li&amp;gt;[https://www.gnu.org/software/octave/ Octave]&amp;lt;/li&amp;gt; Написанная на C++  свободная система для математических вычислений, использующая совместимый с MATLAB язык высокого уровня, содержит реализацию k-means.&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://spark.apache.org/docs/latest/mllib-clustering.html Spark]&amp;lt;/li&amp;gt; Распределенная реализация k-means содержится в библиотеке Mlib для работы с алгоритмами машинного обучения, взаимодействующая с Python библиотекой NumPy и библиотека R.&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://torch.ch Torch]&amp;lt;/li&amp;gt;  MATLAB-подобная библиотека для языка программирования Lua с открытым исходным кодом, предоставляет большое количество алгоритмов для глубинного обучения и научных расчётов. Ядро написано на Си, прикладная часть выполняется на LuaJIT, поддерживается распараллеливание вычислений средствами CUDA и OpenMP. Существуют реализации k-means.&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://www.cs.waikato.ac.nz/ml/weka/ Weka]&amp;lt;/li&amp;gt;  Cвободное программное обеспечение для анализа данных, написанное на Java. Содержит k-means и x-means.&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://accord-framework.net/docs/html/T_Accord_MachineLearning_KMeans.htm Accord.NET]&amp;lt;/li&amp;gt; C# реализация алгоритмов k-means, k-means++, k-modes.&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://docs.opencv.org/3.0-beta/doc/py_tutorials/py_ml/py_kmeans/py_kmeans_opencv/py_kmeans_opencv.html OpenCV]&amp;lt;/li&amp;gt; Написанная на С++ библиотека, направленная в основном на решение задач компьютерного зрения. Содержит реализацию k-means.&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://mlpack.org/ MLPACK]&amp;lt;/li&amp;gt; Масштабируемая С++ библиотека для работы с алгоритмами машинного обучения, содержит реализацию k-means.&lt;br /&gt;
  &amp;lt;li&amp;gt;[https://www.scipy.org/ SciPy]&amp;lt;/li&amp;gt; Библиотека Python, содержит множество реализаций k-means.&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://scikit-learn.org/ scikit-learn]&amp;lt;/li&amp;gt; Библиотека Python, содержит множество реализаций k-means.&lt;br /&gt;
  &amp;lt;li&amp;gt;[https://www.r-bloggers.com/k-means-clustering-in-r/ R]&amp;lt;/li&amp;gt; Язык программирования для статистической обработки данных и работы с графикой, а также свободная программная среда вычислений с открытым исходным кодом в рамках проекта GNU, содержит три реализации k-means.&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://elki.dbs.ifi.lmu.de ELKI]&amp;lt;/li&amp;gt; Java фреймворк, содержащий реализацию k-means, а также множество других алгоритмов кластеризации.&lt;br /&gt;
&amp;lt;/ol&amp;gt;&lt;br /&gt;
==== Проприетарное программное обеспечение  ====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ol&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;[https://www.ayasdi.com/blog/bigdata/topological-data-analysis-of-oil-and-gas-petrophysical-data/ Ayasdi]&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://www.stata.com/features/cluster-analysis/ Stata]&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://mathworld.wolfram.com/K-MeansClusteringAlgorithm.html Mathematica]&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://www.mathworks.com/help/stats/kmeans.html?requestedDomain=www.mathworks.com MATLAB]&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;[https://support.sas.com/rnd/app/stat/procedures/fastclus.html SAS]&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://docs.rapidminer.com/studio/operators/modeling/segmentation/k_means.html RapidMiner]&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;[https://blogs.sap.com/2013/03/28/sap-hana-pal-k-means-algorithm-or-how-to-do-customer-segmentation-for-the-telecommunications-industry/ SAP HANA]&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ol&amp;gt;&lt;br /&gt;
== Литература ==&lt;br /&gt;
&amp;lt;references /&amp;gt;&lt;/div&gt;</summary>
		<author><name>DennZo1993</name></author>
	</entry>
	<entry>
		<id>https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:%D0%91%D1%80%D0%BE%D1%82%D0%B8%D0%BA%D0%BE%D0%B2%D1%81%D0%BA%D0%B0%D1%8F_%D0%94%D0%B0%D0%BD%D1%83%D1%82%D0%B0/%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_k-means&amp;diff=17184</id>
		<title>Участник:Бротиковская Данута/Алгоритм k-means</title>
		<link rel="alternate" type="text/html" href="https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:%D0%91%D1%80%D0%BE%D1%82%D0%B8%D0%BA%D0%BE%D0%B2%D1%81%D0%BA%D0%B0%D1%8F_%D0%94%D0%B0%D0%BD%D1%83%D1%82%D0%B0/%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_k-means&amp;diff=17184"/>
		<updated>2016-11-15T01:45:09Z</updated>

		<summary type="html">&lt;p&gt;DennZo1993: /* Масштабируемость реализации алгоритма */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt; {{Assignment|Zhum}}&lt;br /&gt;
&lt;br /&gt;
{{algorithm&lt;br /&gt;
| name              = Алгоритм k средних (k means)&lt;br /&gt;
| serial_complexity = &amp;lt;math&amp;gt;O(\Tau*k*d*n)&amp;lt;/math&amp;gt;&lt;br /&gt;
| input_data        = &amp;lt;math&amp;gt; d*n &amp;lt;/math&amp;gt;&lt;br /&gt;
| output_data       = &amp;lt;math&amp;gt; n &amp;lt;/math&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
Авторы страницы &amp;lt;b&amp;gt;[[Участник:Бротиковская Данута|Данута Бротиковская]]&amp;lt;/b&amp;gt; и &amp;lt;b&amp;gt;[[Участник:DennZo1993|Денис Зобнин]]&amp;lt;/b&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
Оба автора внесли одинаковый вклад в написание статьи (поиск материалов, изучение статей, заполнение контента статьи), четких разграничений по пунктам статьи сделать невозможно. &lt;br /&gt;
&lt;br /&gt;
== Свойства и структура алгоритма ==&lt;br /&gt;
&lt;br /&gt;
=== Общее описание алгоритма ===&lt;br /&gt;
Алгоритм &amp;lt;b&amp;gt;&amp;lt;i&amp;gt;k средних&amp;lt;/i&amp;gt;&amp;lt;/b&amp;gt; (&amp;lt;b&amp;gt;&amp;lt;i&amp;gt;k means&amp;lt;/i&amp;gt;&amp;lt;/b&amp;gt;) &amp;amp;ndash; неиерархический&amp;lt;ref&amp;gt;&amp;quot;https://ru.wikipedia.org/wiki/Иерархическая_кластеризация&amp;quot;&amp;lt;/ref&amp;gt;, итерационный метод кластеризации&amp;lt;ref&amp;gt;&amp;quot;https://ru.wikipedia.org/wiki/Кластерный_анализ&amp;quot;&amp;lt;/ref&amp;gt;, получивший большую популярность благодаря своей простоте, наглядности реализации и достаточно высокому качеству работы. Был изобретен в 1950-х годах математиком &amp;lt;i&amp;gt;Гуго Штейнгаузом&amp;lt;/i&amp;gt;&amp;lt;ref&amp;gt;Steinhaus, Hugo. &amp;quot;Sur la division des corp materiels en parties.&amp;quot; Bull. Acad. Polon. Sci 1.804 (1956): 801.&amp;lt;/ref&amp;gt; и почти одновременно &amp;lt;i&amp;gt;Стюартом Ллойдом&amp;lt;/i&amp;gt;&amp;lt;ref&amp;gt;Lloyd, S. P. &amp;quot;Least square quantization in PCM. Bell Telephone Laboratories Paper. Published in journal much later: Lloyd, SP: Least squares quantization in PCM.&amp;quot; IEEE Trans. Inform. Theor.(1957/1982).&amp;lt;/ref&amp;gt;. Особую популярность приобрел после публикации работы &amp;lt;i&amp;gt;МакКуина&amp;lt;/i&amp;gt;&amp;lt;ref&amp;gt;MacQueen, James. &amp;quot;Some methods for classification and analysis of multivariate observations.&amp;quot; Proceedings of the fifth Berkeley symposium on mathematical statistics and probability. Vol. 1. No. 14. 1967.&amp;lt;/ref&amp;gt; в 1967.&lt;br /&gt;
&lt;br /&gt;
Алгоритм представляет собой версию EM-алгоритма&amp;lt;ref&amp;gt;&amp;quot;https://ru.wikipedia.org/wiki/EM-алгоритм&amp;quot;&amp;lt;/ref&amp;gt;, применяемого также для разделения смеси гауссиан. Основная идея &amp;lt;i&amp;gt;k means&amp;lt;/i&amp;gt; заключается в том, что данные произвольно разбиваются на кластеры, после чего итеративно перевычисляется центр масс для каждого кластера, полученного на предыдущем шаге, затем векторы разбиваются на кластеры вновь в соответствии с тем, какой из новых центров оказался ближе по выбранной метрике.&lt;br /&gt;
&lt;br /&gt;
Цель алгоритма заключается в разделении &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; наблюдений на &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластеров таким образом, чтобы каждое наблюдение принадлежало ровно одному кластеру, расположенному на наименьшем расстоянии от наблюдения.&lt;br /&gt;
&lt;br /&gt;
=== Математическое описание алгоритма ===&lt;br /&gt;
&amp;lt;b&amp;gt;&amp;lt;u&amp;gt;Дано:&amp;lt;/u&amp;gt;&amp;lt;/b&amp;gt;&lt;br /&gt;
* набор из &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; наблюдений &amp;lt;math&amp;gt;X=\{\mathbf{x}_1, \mathbf{x}_2, ..., \mathbf{x}_n\}, \mathbf{x}_i \in \mathbb{R}^d, i=\overline{1, n}&amp;lt;/math&amp;gt;;&lt;br /&gt;
* &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; - требуемое число кластеров, &amp;lt;math&amp;gt;k \in \mathbb{N}, k \leq n&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;&amp;lt;u&amp;gt;Требуется:&amp;lt;/u&amp;gt;&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Разделить множество наблюдений &amp;lt;math&amp;gt;X&amp;lt;/math&amp;gt; на &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластеров &amp;lt;math&amp;gt;S_1, S_2, ..., S_k&amp;lt;/math&amp;gt;:&lt;br /&gt;
*   &amp;lt;math&amp;gt;S_i \cap S_j= \varnothing, \quad i \ne j&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
*   &amp;lt;math&amp;gt;\bigcup_{i=1}^{k} S_i = X&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;&amp;lt;u&amp;gt;Действие алгоритма:&amp;lt;/u&amp;gt;&amp;lt;/b&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;Алгоритм &amp;lt;i&amp;gt;k means&amp;lt;/i&amp;gt; разбивает набор &amp;lt;math&amp;gt;X&amp;lt;/math&amp;gt; на &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; наборов &amp;lt;math&amp;gt;S_1, S_2, ..., S_k,&amp;lt;/math&amp;gt; таким образом, чтобы минимизировать сумму квадратов расстояний от каждой точки кластера до его центра (центр масс кластера). Введем обозначение, &amp;lt;math&amp;gt;S=\{S_1, S_2, ..., S_k\}&amp;lt;/math&amp;gt;. Тогда действие алгоритма &amp;lt;i&amp;gt;k means&amp;lt;/i&amp;gt; равносильно поиску:&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;table style=&amp;quot;width:100%&amp;quot;&amp;gt;&lt;br /&gt;
  &amp;lt;tr&amp;gt;&lt;br /&gt;
    &amp;lt;td align=&amp;quot;center&amp;quot; width=&amp;quot;90%&amp;quot;&amp;gt;&amp;lt;math&amp;gt;\arg\min_{S} \sum\limits_{i=1}^k \sum\limits_{\mathbf{x} \in S_i} \rho(\mathbf{x}, \mathbf{\mu}_i )^2,&amp;lt;/math&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;td align=&amp;quot;right&amp;quot;&amp;gt;&amp;lt;math&amp;gt;(1)&amp;lt;/math&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;/table&amp;gt;&lt;br /&gt;
где &amp;lt;math&amp;gt;\mathbf{\mu}_i&amp;lt;/math&amp;gt; &amp;amp;ndash; центры кластеров, &amp;lt;math&amp;gt;i=\overline{1,k}, \quad \rho(\mathbf{x}, \mathbf{\mu}_i)&amp;lt;/math&amp;gt; &amp;amp;ndash; функция расстояния между &amp;lt;math&amp;gt;\mathbf{x}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\mu_i&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;&amp;lt;u&amp;gt;Шаги алгоритма: &amp;lt;/u&amp;gt;&amp;lt;/b&amp;gt;&lt;br /&gt;
&amp;lt;ol&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&lt;br /&gt;
    &amp;lt;b&amp;gt;Начальный шаг: инициализация кластеров&amp;lt;/b&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;Выбирается произвольное множество точек &amp;lt;math&amp;gt;\mu_i, i=\overline{1,k}&amp;lt;/math&amp;gt;, рассматриваемых как начальные центры кластеров: &amp;lt;math&amp;gt;\mu_i^{(0)} = \mu_i, \quad i=\overline{1, k}&amp;lt;/math&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
  &amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&lt;br /&gt;
    &amp;lt;b&amp;gt;Распределение векторов по кластерам&amp;lt;/b&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Шаг&amp;lt;/b&amp;gt; &amp;lt;math&amp;gt;t: \forall \mathbf{x}_i \in X, i=\overline{1,n}: \mathbf{x}_i \in S_j \iff  j=\arg\min_{k}\rho(\mathbf{x}_i,\mathbf{\mu}_k^{(t-1)})^2&amp;lt;/math&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
  &amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&lt;br /&gt;
    &amp;lt;b&amp;gt;Пересчет центров кластеров&amp;lt;/b&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Шаг &amp;lt;/b&amp;gt; &amp;lt;math&amp;gt;t: \forall i=\overline{1,k}:  \mu_i^{(t)} = \cfrac{1}{|S_i|}\sum_{\mathbf{x}\in S_i}\mathbf{x}&amp;lt;/math&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
  &amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&lt;br /&gt;
    &amp;lt;b&amp;gt;Проверка условия останова:&amp;lt;/b&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
    &#039;&#039;&#039;if&#039;&#039;&#039; &amp;lt;math&amp;gt;\exist i\in \overline{1,k}: \mu_i^{(t)} \ne \mu_i^{(t-1)}&amp;lt;/math&amp;gt; &#039;&#039;&#039;then&#039;&#039;&#039;&lt;br /&gt;
        t = t + 1;&lt;br /&gt;
        goto 2;&lt;br /&gt;
    &#039;&#039;&#039;else&#039;&#039;&#039;&lt;br /&gt;
        &#039;&#039;&#039;stop&#039;&#039;&#039;&lt;br /&gt;
  &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ol&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Вычислительное ядро алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Вычислительным ядром являются шаги 2 и 3 приведенного выше алгоритма: &amp;lt;b&amp;gt;&amp;lt;i&amp;gt;распределение векторов по кластерам&amp;lt;/i&amp;gt;&amp;lt;/b&amp;gt; и &amp;lt;b&amp;gt;&amp;lt;i&amp;gt;пересчет центров кластеров&amp;lt;/i&amp;gt;&amp;lt;/b&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;&amp;lt;i&amp;gt;Распределение векторов&amp;lt;/i&amp;gt;&amp;lt;/b&amp;gt; по кластерам предполагает вычисление расстояний между каждым вектором &amp;lt;math&amp;gt;\mathbf{x}_i \in X, i= \overline{1,n}&amp;lt;/math&amp;gt; и центрами кластера &amp;lt;math&amp;gt;\mathbf{\mu}_j, j= \overline{1,k}&amp;lt;/math&amp;gt;. Таким образом, данный шаг предполагает &amp;lt;math&amp;gt;k*n&amp;lt;/math&amp;gt; вычислений расстояний между d-мерными векторами. &lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;&amp;lt;i&amp;gt;Пересчет центров кластеров&amp;lt;/i&amp;gt;&amp;lt;/b&amp;gt; предполагает &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; вычислений центров масс &amp;lt;math&amp;gt;\mathbf{\mu}_i&amp;lt;/math&amp;gt; множеств &amp;lt;math&amp;gt;S_i, i=\overline{1,k}&amp;lt;/math&amp;gt; представленных выражением в шаге 3 представленного выше алгоритма.&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Макроструктура алгоритма ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Инициализация центров масс &amp;lt;math&amp;gt;\mu_1, ..., \mu_k&amp;lt;/math&amp;gt;&amp;lt;/b&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
Наиболее распространенными являются следующие стратегии:&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&lt;br /&gt;
    &amp;lt;b&amp;gt;Метод Forgy&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;В качестве начальных значений &amp;lt;math&amp;gt;\mu_1, ..., \mu_k&amp;lt;/math&amp;gt; берутся случайно выбранные векторы.&lt;br /&gt;
  &amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&lt;br /&gt;
    &amp;lt;b&amp;gt;Метод случайно разделения (Random Partitioning)&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;Для каждого вектора &amp;lt;math&amp;gt;\mathbf{x}_i \in X, i=\overline{1, n}&amp;lt;/math&amp;gt; выбирается случайным образом кластер &amp;lt;math&amp;gt;S_1, ..., S_k&amp;lt;/math&amp;gt;, после чего для каждого полученного кластера вычисляются значения &amp;lt;math&amp;gt;\mu_1, ..., \mu_k&amp;lt;/math&amp;gt;.&lt;br /&gt;
  &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Распределение векторов по кластерам&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Для этого шага алгоритма между векторами &amp;lt;math&amp;gt;\mathbf{x}_i \in X, i=\overline{1, n}&amp;lt;/math&amp;gt; и центрами кластеров &amp;lt;math&amp;gt;\mu_1, ..., \mu_k&amp;lt;/math&amp;gt; вычисляются &amp;lt;b&amp;gt;расстояния&amp;lt;/b&amp;gt; по формуле (как правило, используется Евлидово расстояние):&lt;br /&gt;
&amp;lt;table style=&amp;quot;width:100%&amp;quot;&amp;gt;&lt;br /&gt;
  &amp;lt;tr&amp;gt;&lt;br /&gt;
    &amp;lt;td align=&amp;quot;center&amp;quot; width=&amp;quot;90%&amp;quot;&amp;gt;&amp;lt;math&amp;gt; \mathbf{v}_1, \mathbf{v}_2 \in \mathbb{R}^d,  \quad \rho(\mathbf{v}_1, \mathbf{v}_2) = \lVert \mathbf{v}_1- \mathbf{v}_2 \rVert= \sqrt{\sum_{i=1}^{d}(\mathbf{v}_{1,i} - \mathbf{v}_{2,i})^2}&amp;lt;/math&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;td align=&amp;quot;right&amp;quot;&amp;gt;&amp;lt;math&amp;gt;(2)&amp;lt;/math&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;/table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Пересчет центров кластеров&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Для этого шага алгоритма производится пересчет центров кластера по &amp;lt;b&amp;gt;формуле вычисления центра масс&amp;lt;/b&amp;gt;:&lt;br /&gt;
&amp;lt;table style=&amp;quot;width:100%&amp;quot;&amp;gt;&lt;br /&gt;
  &amp;lt;tr&amp;gt;&lt;br /&gt;
    &amp;lt;td align=&amp;quot;center&amp;quot; width=&amp;quot;90%&amp;quot;&amp;gt;&amp;lt;math&amp;gt; \mu = \cfrac{1}{|S|}\sum_{\mathbf{x}\in S}\mathbf{x}&amp;lt;/math&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;td align=&amp;quot;right&amp;quot;&amp;gt;&amp;lt;math&amp;gt;(3)&amp;lt;/math&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;/table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Схема реализации последовательного алгоритма ===&lt;br /&gt;
&lt;br /&gt;
 &#039;&#039;&#039;algorithm&#039;&#039;&#039; k-means &#039;&#039;&#039;is&#039;&#039;&#039;&lt;br /&gt;
     &#039;&#039;&#039;1.&#039;&#039;&#039; Инициализировать центры кластеров &amp;lt;math&amp;gt;\mathbf{\mu}_i^{(1)}, i=\overline{1,k}&amp;lt;/math&amp;gt;&lt;br /&gt;
     &#039;&#039;&#039;2.&#039;&#039;&#039; &amp;lt;math&amp;gt;t \leftarrow 1&amp;lt;/math&amp;gt;&lt;br /&gt;
     &#039;&#039;&#039;3.&#039;&#039;&#039; &#039;&#039;&#039;Распределение по кластерам&#039;&#039;&#039;&amp;lt;br&amp;gt;&lt;br /&gt;
        &amp;lt;math&amp;gt;S_i^{(t)}=\{\mathbf{x}_p: \lVert\mathbf{x}_p-\mathbf{\mu}_i^{(t)}\rVert^2 \leq \lVert\mathbf{x}_p-\mathbf{\mu}_j^{(t)}\rVert^2 \quad \forall j=\overline{1,k}\},&amp;lt;/math&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
        где каждый вектор &amp;lt;math&amp;gt;\mathbf{x}_p&amp;lt;/math&amp;gt; соотносится единственному кластеру &amp;lt;math&amp;gt;S^{(t)}&amp;lt;/math&amp;gt;&lt;br /&gt;
     &#039;&#039;&#039;4.&#039;&#039;&#039; &#039;&#039;&#039;Обновление центров кластеров&#039;&#039;&#039;&amp;lt;br&amp;gt;&lt;br /&gt;
        &amp;lt;math&amp;gt;\mathbf{\mu}_i^{(t+1)} = \frac{1}{|S^{(t)}_i|} \sum_{\mathbf{x}_j \in S^{(t)}_i} \mathbf{x}_j &amp;lt;/math&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
     &#039;&#039;&#039;5.&#039;&#039;&#039; &#039;&#039;&#039;if&#039;&#039;&#039; &amp;lt;math&amp;gt;\exist i \in \overline{1,k}: \mathbf{\mu}_i^{(t+1)} \ne \mathbf{\mu}_i^{(t)}&amp;lt;/math&amp;gt; &#039;&#039;&#039;then&#039;&#039;&#039;&lt;br /&gt;
            t = t + 1;&lt;br /&gt;
            goto &#039;&#039;&#039;3&#039;&#039;&#039;;&lt;br /&gt;
        &#039;&#039;&#039;else&#039;&#039;&#039;&lt;br /&gt;
            &#039;&#039;&#039;stop&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
=== Последовательная сложность алгоритма===&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding-bottom: 20px&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;Обозначим &amp;lt;math&amp;gt;\Theta_{centroid}^{d, m}&amp;lt;/math&amp;gt; временную сложность вычисления центорида кластера, число элементов которого равна &amp;lt;math&amp;gt;m&amp;lt;/math&amp;gt;,  в d-мерном пространстве.&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;Аналогично  &amp;lt;math&amp;gt;\Theta_{distance}^d&amp;lt;/math&amp;gt; &amp;amp;ndash; временная сложность вычисления расстояния между двумя d-мерными векторами.&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding-bottom: 20px&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;Сложность шага инициализации &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластеров мощности &amp;lt;math&amp;gt;m&amp;lt;/math&amp;gt; в d-мерном пространстве &amp;amp;ndash; &amp;lt;math&amp;gt;\Theta_{init}^{k, d, m}&amp;lt;/math&amp;gt;&amp;lt;/b&amp;gt;&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;i&amp;gt;Стратерия Forgy&amp;lt;/i&amp;gt;: вычисления не требуются, &amp;lt;math&amp;gt;\Theta_{init}^{k, d, m} = 0&amp;lt;/math&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;i&amp;gt;Стратегия случайного разбиения&amp;lt;/i&amp;gt;: вычисление центров &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластеров,  &amp;lt;math&amp;gt;\Theta_{init}^{k, d, m} = k*\Theta_{centroid}^{d, m}, m \le n&amp;lt;/math&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding-bottom: 20px&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Cложность шага распределения d мерных векторов по &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластерам &amp;amp;ndash; &amp;lt;math&amp;gt;\Theta_{distribute}^{k, d}&amp;lt;/math&amp;gt;&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
На этом шаге для каждого вектора &amp;lt;math&amp;gt;\mathbf{x}_i \in X, i=\overline{1, n}&amp;lt;/math&amp;gt; вычисляется k расстояний до центров кластеров &amp;lt;math&amp;gt;\mathbf{\mu}_1, ...\mathbf{\mu}_k&amp;lt;/math&amp;gt;&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p align=&amp;quot;center&amp;quot;&amp;gt;&lt;br /&gt;
  &amp;lt;math&amp;gt;\Theta_{distribute}^{k, d} = n*k*\Theta_{distance}^d&amp;lt;/math&amp;gt;&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding-bottom: 20px&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;Сложность шага пересчета центров &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластеров размера &amp;lt;math&amp;gt;m&amp;lt;/math&amp;gt; в d-мерном пространстве &amp;amp;ndash; &amp;lt;math&amp;gt;\Theta_{recenter}^{k, d, m}&amp;lt;/math&amp;gt;&amp;lt;/b&amp;gt;&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;На этом шаге вычисляется &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; центров кластеров &amp;lt;math&amp;gt;\mathbf{\mu}_1, ...\mathbf{\mu}_k&amp;lt;/math&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p align=&amp;quot;center&amp;quot;&amp;gt;&amp;lt;math&amp;gt;\Theta_{recenter}^{k, d, m} = k*\Theta_{centroid}^{d, m}&amp;lt;/math&amp;gt; &amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding-bottom: 20px&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Рассчитаем &amp;lt;math&amp;gt;\Theta_{centroid}^{d, m}&amp;lt;/math&amp;gt; для кластера, число элементов которого равно &amp;lt;math&amp;gt;m&amp;lt;/math&amp;gt;&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p align=&amp;quot;center&amp;quot;&amp;gt;&amp;lt;math&amp;gt;\Theta_{centroid}^{d, m}&amp;lt;/math&amp;gt; = &amp;lt;math&amp;gt;m * d&amp;lt;/math&amp;gt; сложений + &amp;lt;math&amp;gt;d&amp;lt;/math&amp;gt; делений &amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding-bottom: 20px&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Рассчитаем &amp;lt;math&amp;gt;\Theta_{distance}^d&amp;lt;/math&amp;gt; в соответствие с формулой &amp;lt;math&amp;gt;(2)&amp;lt;/math&amp;gt;&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p align=&amp;quot;center&amp;quot;&amp;gt;&amp;lt;math&amp;gt;\Theta_{distance}^d&amp;lt;/math&amp;gt; = &amp;lt;math&amp;gt;d&amp;lt;/math&amp;gt; вычитаний + &amp;lt;math&amp;gt;d&amp;lt;/math&amp;gt; умножений + &amp;lt;math&amp;gt;(d-1)&amp;lt;/math&amp;gt; сложение&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding-bottom: 20px&amp;quot;&amp;gt;&lt;br /&gt;
  &amp;lt;p&amp;gt;Предположим, что алгоритм сошелся за &amp;lt;math&amp;gt;\Tau&amp;lt;/math&amp;gt; итераций, тогда временная сложность алгоритма &amp;lt;math&amp;gt;\Theta_{k-means}^{d, n}&amp;lt;/math&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
  &amp;lt;p align=&amp;quot;center&amp;quot;&amp;gt;&amp;lt;b&amp;gt;&amp;lt;math&amp;gt;\Theta_{k-means}^{d, n} \le \Theta_{init}^{k, d, n} + \Tau*(\Theta_{distribute}^{k, d} + \Theta_{recenter}^{k, d, n})&amp;lt;/math&amp;gt;&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding-bottom: 5px&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;Операции сложения/вычитания:&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p align=&amp;quot;center&amp;quot;&amp;gt;&amp;lt;b&amp;gt;&amp;lt;math&amp;gt;\Theta_{k-means}^{d, n} \le k*n*d+ \Tau*(k*n*(2d-1) + k*n*d) = k*n*d+ \Tau*(k*n*(3d-1)) \thicksim O(\Tau*k*d*n)&amp;lt;/math&amp;gt;&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding-bottom: 20px&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;Операции умножения/деления:&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p align=&amp;quot;center&amp;quot;&amp;gt;&amp;lt;b&amp;gt;&amp;lt;math&amp;gt;\Theta_{k-means}^{d, n} \le k*d + \Tau*(k*n*d + k*d) = k*d + \Tau * k*d*(n+1) \thicksim O(\Tau*k*d*n) &amp;lt;/math&amp;gt;&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding-bottom: 20px&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;Получаем, что &amp;lt;b&amp;gt;временная сложность&amp;lt;/b&amp;gt; алгоритма &amp;lt;b&amp;gt;k means&amp;lt;/b&amp;gt; кластеризации &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; &amp;lt;b&amp;gt;d-мерных&amp;lt;/b&amp;gt; векторов на &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластеров за &amp;lt;math&amp;gt;\Tau&amp;lt;/math&amp;gt; итераций:&amp;lt;/p&amp;gt;&lt;br /&gt;
 &amp;lt;p align=&amp;quot;center&amp;quot;&amp;gt;&amp;lt;b&amp;gt;&amp;lt;math&amp;gt; \Theta_{k-means}^{d, n} \thicksim O(\Tau*k*d*n) &amp;lt;/math&amp;gt;&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Информационный граф ===&lt;br /&gt;
&lt;br /&gt;
Рассмотрим информационный граф алгоритма. Алгоритм &amp;lt;i&amp;gt;k means&amp;lt;/i&amp;gt; начинается с этапа инициализации, после которого следуют итерации, на каждой из которых выполняется два последовательных шага (см. [[#Схема реализации последовательного алгоритма|&amp;quot;Схема реализации последовательного алгоритма&amp;quot;]]): &lt;br /&gt;
* распределение векторов по кластерам&lt;br /&gt;
* перерасчет центров кластеров&lt;br /&gt;
&lt;br /&gt;
Поскольку основная часть вычислений приходится на шаги итераций, распишем информационные графы данных шагов.&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Распределение векторов по кластерам&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
Информационный граф шага распределения векторов по кластерам представлен на &#039;&#039;рисунке 1&#039;&#039;. Исходами данного графа является исходные векторы &amp;lt;math&amp;gt;\mathbf{x}_1, ..., \mathbf{x}_n&amp;lt;/math&amp;gt;, а также центры кластеров &amp;lt;math&amp;gt;\mathbf{\mu}_1, ... \mathbf{\mu}_k&amp;lt;/math&amp;gt;, вычисленные ранее (на шаге инициализации, если рассматривается первая итерация алгоритма, или на шаге пересчета центров кластеров предыдущей итерации в противном случае). Каждая пара векторов данных &amp;lt;math&amp;gt;\mathbf{x}_i, i=\overline{1,n}&amp;lt;/math&amp;gt; и центров кластера &amp;lt;math&amp;gt;\mathbf{\mu}_j, j=\overline{1, k}&amp;lt;/math&amp;gt; : (&amp;lt;math&amp;gt;\mathbf{x}_i&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;\mathbf{\mu}_j&amp;lt;/math&amp;gt;) подаются на независимые узлы &amp;lt;i&amp;gt;&amp;quot;d&amp;quot;&amp;lt;/i&amp;gt; вычисления расстояния между векторами (более подробная схема вычисления расстояния представлена далее, &#039;&#039;рисунок 2&#039;&#039;). Далее узлы вычисления расстояния &amp;lt;i&amp;gt;&amp;quot;d&amp;quot;&amp;lt;/i&amp;gt;, соответствующие одному и тому же исходному вектору &amp;lt;math&amp;gt;\mathbf{x}_i&amp;lt;/math&amp;gt; передаются на один узел &amp;lt;i&amp;gt;&amp;quot;m&amp;quot;&amp;lt;/i&amp;gt;, где далее происходит вычисление новой метки кластера для каждого вектора &amp;lt;math&amp;gt;\mathbf{x}_i&amp;lt;/math&amp;gt; (берется кластер с минимальным результатом вычисления расстояния). На выходе графа выдаются метки кластеров , &amp;lt;math&amp;gt;L_1, ..., L_n&amp;lt;/math&amp;gt;, такие что &amp;lt;math&amp;gt;\forall \mathbf{x}_i, i=\overline{1, n}, \mathbf{x}_i \in S_j \Leftrightarrow L_i = j&amp;lt;/math&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
[[file:Clusterization.png|thumb|center|800px|Рис. 1. Схема распределения векторов по кластерам. &#039;&#039;d&#039;&#039; &amp;amp;ndash; вычисление расстояния между векторами; &#039;&#039;m&#039;&#039; &amp;amp;ndash; вычисление минимума.]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Вычисление расстояния между векторами&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
Подробная схема вычисления расстояния между векторами &amp;lt;math&amp;gt;\mathbf{x}_i, \mathbf{\mu}_j&amp;lt;/math&amp;gt; представлена на &#039;&#039;рисунке 2&#039;&#039;. Как показано на графе, узел вычисления расстояния между векторами &amp;lt;i&amp;gt;&amp;quot;d&amp;quot;&amp;lt;/i&amp;gt; состоит из шага взятия разности между векторами (узел &amp;quot;&amp;lt;math&amp;gt;-&amp;lt;/math&amp;gt;&amp;quot;) и взятия нормы получившегося вектора разности (узел &amp;quot;&amp;lt;math&amp;gt;||\cdot||^2&amp;lt;/math&amp;gt;&amp;quot;). Более подробно, вычисление расстояния между векторами &amp;lt;math&amp;gt;\mathbf{x}_i = {x_{i1,}, ...,{x_{in}}}, \mathbf{\mu}_j = {\mu_{j1}, ...,\mu_{jn}}&amp;lt;/math&amp;gt; может быть представлено как вычисление разности между каждой парой компонент &amp;lt;math&amp;gt;(x_{iz}, \mu_{jz}), z=\overline{1, d}&amp;lt;/math&amp;gt; (узел &amp;quot;&amp;lt;math&amp;gt;-&amp;lt;/math&amp;gt;&amp;quot;), далее возведение в квадрат для каждого узла &amp;quot;&amp;lt;math&amp;gt;-&amp;lt;/math&amp;gt;&amp;quot; (узел &amp;quot;&amp;lt;math&amp;gt;()^2&amp;lt;/math&amp;gt;&amp;quot;) и суммирования выходов всех узлов &amp;quot;&amp;lt;math&amp;gt;()^2&amp;lt;/math&amp;gt;&amp;quot; (узел &amp;quot;&amp;lt;math&amp;gt;+&amp;lt;/math&amp;gt;&amp;quot;).  &lt;br /&gt;
&lt;br /&gt;
[[file:dist_calc.png|thumb|center|800px|Рис. 2. Схема вычисления расстояния между вектором и центром кластера.]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Пересчет центров кластеров&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
Информационный граф шага пересчета центров кластеров представлен на &#039;&#039;рисунке 3&#039;&#039;. Исходами данного графа является исходные векторы &amp;lt;math&amp;gt;\mathbf{x}_1, ..., \mathbf{x}_n&amp;lt;/math&amp;gt;, а также им соответствующие метки кластера, &amp;lt;math&amp;gt;L_1, ..., L_n&amp;lt;/math&amp;gt;, такие что &amp;lt;math&amp;gt;\forall x_i, i=\overline{1, n}, \mathbf{x}_i \in S_j \Leftrightarrow L_i = j&amp;lt;/math&amp;gt;, вычисленные на этапе распределения векторов по кластерам. Все векторы &amp;lt;math&amp;gt;\mathbf{x}_1, ..., \mathbf{x}_n&amp;lt;/math&amp;gt; подаются в узлы &amp;lt;math&amp;gt;+_1, ...+_k&amp;lt;/math&amp;gt;, каждый узел &amp;lt;math&amp;gt;+_m, m = \overline{1,k}&amp;lt;/math&amp;gt; соответствует операции сложения векторов кластера с номером &amp;lt;math&amp;gt;m&amp;lt;/math&amp;gt;. Метки кластера &amp;lt;math&amp;gt;L_1, ..., L_n&amp;lt;/math&amp;gt; также совместно передаются на узлы &amp;lt;math&amp;gt;S_m, m = \overline{1,k}&amp;lt;/math&amp;gt;, на каждом из которых вычисляется количество векторов в соответствующем кластере (количество меток с соответствующим значением). Далее каждая пара выходов узлов &amp;lt;math&amp;gt;+_m&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;S_m&amp;lt;/math&amp;gt; подается на узел &amp;quot;&amp;lt;math&amp;gt;/&amp;lt;/math&amp;gt;&amp;quot;, где производится деление суммы векторов кластера на количество элементов в нем. Значения, вычисленные на узлах &amp;quot;&amp;lt;math&amp;gt;/&amp;lt;/math&amp;gt;&amp;quot;, присваиваются новым центрам кластеров (выходные значения графа).&lt;br /&gt;
&lt;br /&gt;
[[file:Recluster.png|thumb|center|800px|Рис. 3. Схема пересчета центров кластеров]]&lt;br /&gt;
&lt;br /&gt;
=== Ресурс параллелизма алгоритма ===&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
Работа алгоритма состоит из &amp;lt;math&amp;gt;\Tau&amp;lt;/math&amp;gt; итераций, в каждой из которых происходит &amp;lt;b&amp;gt;распределение d-мерных векторов по &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластерам&amp;lt;/b&amp;gt;, а также &amp;lt;b&amp;gt;пересчет центров кластеров в d-мерном пространстве&amp;lt;/b&amp;gt;. В шаге &amp;lt;b&amp;gt;распределения d-мерных векторов по &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластерам&amp;lt;/b&amp;gt; расстояния между вектором и центрами кластеров вычисляются независимо (отсутствуют информационные зависимости). &amp;lt;b&amp;gt;Центры масс кластеров&amp;lt;/b&amp;gt; также пересчитываются независимо друг от друга. Таким образом, имеет место [[глоссарий#Массовый параллелизм|&#039;&#039;массовый параллелизм&#039;&#039;]]. Вычислим параллельную сложность &amp;lt;math&amp;gt;\Psi_*&amp;lt;/math&amp;gt; каждого из шагов, а также параллельную сложность всего алгоритма, &amp;lt;math&amp;gt;\Psi_{k-means}&amp;lt;/math&amp;gt;. Будем исходить из предположения, что может быть использовано любое необходимое число потоков.&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Распределение d-мерных векторов по &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластерам&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;  &lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
Поскольку на данном шаге для каждой пары векторов &amp;lt;math&amp;gt;\mathbf{x}_i, i=\overline{1,n}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\mathbf{\mu}_j, j=\overline{1,k}&amp;lt;/math&amp;gt; операции вычисления расстояния не зависят друг от друга, они могут выполняться параллельно. Тогда, разделив все вычисление расстояний на &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; потоков, получим, что в каждом потоке будет выполняться только одна операция вычисления расстояния между векторами размерности d. При этом каждому вычислительному потоку передаются координаты центров всех кластеров &amp;lt;math&amp;gt;\mathbf{\mu}_1, ..., \mathbf{\mu}_k&amp;lt;/math&amp;gt;. Таким образом, параллельная сложность данного шага определяется &amp;lt;i&amp;gt; сложностью параллельной операции вычисления расстояния между d-мерными векторами&amp;lt;/i&amp;gt;, &amp;lt;math&amp;gt;\Psi_{distance}^d&amp;lt;/math&amp;gt;  и &amp;lt;i&amp;gt;сложностью определения наиболее близкого кластера&amp;lt;/i&amp;gt; (паралельное взятие минимума по расстояниям), &amp;lt;math&amp;gt;\Psi_{min}^k&amp;lt;/math&amp;gt;. Для оценки &amp;lt;math&amp;gt;\Psi_{distance}^d&amp;lt;/math&amp;gt; воспользуемся  [[Нахождение_частных_сумм_элементов_массива_сдваиванием | параллельной реализацией нахождения частичной суммы элементов массива путем сдваивания]]. Аналогично, &amp;lt;math&amp;gt;\Psi_{min}^k = log(k)&amp;lt;/math&amp;gt;. В результате, &amp;lt;math&amp;gt;\Psi_{distance}^d = O(log(d))&amp;lt;/math&amp;gt;.   Таким образом: &lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p align=&amp;quot;center&amp;quot;&amp;gt;&amp;lt;math&amp;gt;\Psi_{distribute}^{k, d}  = \Psi_{distance}^d + \Psi_{min}^k = O(log(d))+O(log(k)) = O(log(k*d))&amp;lt;/math&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Пересчет центров кластеров в d-мерном пространстве&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
Поскольку на данном шаге для каждого из &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластеров центр масс может быть вычислен независимо, данные операции могут быть выполнены в отдельных потоках. Таким образом, параллельная сложность данного шага, &amp;lt;math&amp;gt;\Psi_{recenter}^{k, d}&amp;lt;/math&amp;gt;,  будет определяться &amp;lt;i&amp;gt;параллельной сложностью вычисления одного центра масс кластера размера &amp;lt;math&amp;gt;m&amp;lt;/math&amp;gt;&amp;lt;/i&amp;gt;, &amp;lt;math&amp;gt;\Psi_{recenter}^{k, d}&amp;lt;/math&amp;gt;,  а так как &amp;lt;math&amp;gt;m \le n \Rightarrow \Psi_{recenter}^{d, m} \le \Psi_{recenter}^{d, n}&amp;lt;/math&amp;gt;. Сложность вычисления центра масс кластера d-мерных векторов размера n аналогично предыдущим вычислениям равна &amp;lt;math&amp;gt;O(log(n))&amp;lt;/math&amp;gt;. Тогда:  &lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p align=&amp;quot;center&amp;quot;&amp;gt;&amp;lt;math&amp;gt;\Psi_{recenter}^{k, d}  \le \Psi_{recenter}^{d, n} = O(log(n))&amp;lt;/math&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Общая параллельная сложность алгоритма&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
На каждой итерации необходимо обновление центров кластеров, которые будут использованы на следующей итерации. Таким образом, итерационный процесс выполняется последовательно&amp;lt;ref&amp;gt;Zhao, Weizhong, Huifang Ma, and Qing He. &amp;quot;Parallel k-means clustering based on mapreduce.&amp;quot; IEEE International Conference on Cloud Computing. Springer Berlin Heidelberg, 2009.&amp;lt;/ref&amp;gt;. Тогда, поскольку сложность каждой итерации  определяется &amp;lt;math&amp;gt;\Psi_{distribute}^{k, d}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\Psi_{recenter}&amp;lt;/math&amp;gt;, сложность всего алгоритма, &amp;lt;math&amp;gt;\Psi_{k-means}&amp;lt;/math&amp;gt; в предположении, что было сделано &amp;lt;math&amp;gt;\Tau&amp;lt;/math&amp;gt; операций определяется выражением&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p align=&amp;quot;center&amp;quot;&amp;gt;&amp;lt;math&amp;gt;\Psi_{k-means} \approx \Tau * (\Psi_{distribute}^{k, d} + \Psi_{recenter}^{k, d}) \le \Tau * O(log(k*d*n))&amp;lt;/math&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Входные и выходные данные алгоритма ===&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;Входные данные&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;Матрица из &amp;lt;math&amp;gt;n*d&amp;lt;/math&amp;gt; элементов &amp;lt;math&amp;gt;x_{i, j} \in \mathbb{R}, i=\overline{1, n}, j=\overline{1, d}&amp;lt;/math&amp;gt;&amp;amp;ndash; координат векторов (наблюдений).&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;Целое положительное число &amp;lt;math&amp;gt;k, k \le n&amp;lt;/math&amp;gt; &amp;amp;ndash; количество кластеров.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;Объем входных данных&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;math&amp;gt;1&amp;lt;/math&amp;gt; целое число + &amp;lt;math&amp;gt;n*d&amp;lt;/math&amp;gt; вещественных чисел (при условии, что координаты &amp;amp;ndash; вещественные числа).&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;Выходные данные&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; целых положительных чисел &amp;lt;math&amp;gt;L_1, ..., L_n&amp;lt;/math&amp;gt;&amp;amp;ndash; номера кластеров, соотвествующие каждому вектору (при условии, что нумерация кластеров начинается с &amp;lt;math&amp;gt;1&amp;lt;/math&amp;gt;).&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;Объем выходных данных&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; целых положительных чисел.&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Свойства алгоритма ===&lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;[[глоссарий#Вычислительная мощность|&#039;&#039;Вычислительная мощность&#039;&#039;]]&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
Вычислительная мощность алгоритма &amp;lt;i&amp;gt;k means&amp;lt;/i&amp;gt; равна &amp;lt;math&amp;gt;\frac{k*d*n*\Tau}{n*d} = k*\Tau &amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; &amp;amp;ndash; число кластеров, &amp;lt;math&amp;gt;\Tau&amp;lt;/math&amp;gt; &amp;amp;ndash; число итераций алгоритма.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;[[глоссарий#Детерминированность |&#039;&#039;Детерминированность&#039;&#039;]] и [[глоссарий#Устойчивость |&#039;&#039;Устойчивость&#039;&#039;]] &amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
Алгоритм &amp;lt;i&amp;gt;k means&amp;lt;/i&amp;gt; является итерационным. Количество итераций алгоритма в общем случае не фиксируется и зависит от начального расположения объектов в пространстве, параметра &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt;, а также от начального приближения центров кластеров, &amp;lt;math&amp;gt;\mu_1, ..., \mu_k&amp;lt;/math&amp;gt;. В результате этого может варьироваться результат работы алгоритма. При неудачном выборе начальных параметров итерационный процесс может сойтись к локальному оптимуму&amp;lt;ref&amp;gt;Von Luxburg, Ulrike. Clustering Stability. Now Publishers Inc, 2010.&amp;lt;/ref&amp;gt;. По этим причинам алгоритм не является ни &amp;lt;b&amp;gt;детермирированным&amp;lt;/b&amp;gt;, ни &amp;lt;b&amp;gt;устойчивым&amp;lt;/b&amp;gt;.&lt;br /&gt;
 &lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Соотношение последовательной и параллельной сложности алгоритма&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\frac{\Theta_{k-means}}{\Psi_{k-means}} = \frac{O(\Tau*k*d*n)}{O(\Tau*log(k*d*n))}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Сильные стороны алгоритма&amp;lt;/b&amp;gt;:&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;i&amp;gt;Сравнительно высокая эффективность при простоте реализации&amp;lt;/i&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;i&amp;gt;Высокое качество кластеризации&amp;lt;/i&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;i&amp;gt;Возможность распараллеливания&amp;lt;/i&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;i&amp;gt;Существование множества модификаций&amp;lt;/i&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;Недостатки алгоритма&amp;lt;/b&amp;gt;&amp;lt;ref&amp;gt;Ortega, Joaquín Pérez, Ma Del Rocío Boone Rojas, and María J. Somodevilla. &amp;quot;Research issues on K-means Algorithm: An Experimental Trial Using Matlab.&amp;quot;&amp;lt;/ref&amp;gt;:&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;i&amp;gt;Количество кластеров является параметром алгоритма&amp;lt;/i&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;&amp;lt;i&amp;gt;Чувствительность к начальным условиям&amp;lt;/i&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;Инициализация центров кластеров в значительной степени влияет на результат кластеризации.&amp;lt;/p&amp;gt;&lt;br /&gt;
  &amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;&amp;lt;i&amp;gt;Чувствительность к выбросам и шумам&amp;lt;/i&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;Выбросы, далекие от центров настоящих кластеров, все равно учитываются при вычислении их центров.&amp;lt;/p&amp;gt;&lt;br /&gt;
  &amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;&amp;lt;i&amp;gt;Возможность сходимости к локальному оптимуму&amp;lt;/i&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;Итеративный подход не дает гарантии сходимости к оптимальному решению.&amp;lt;/p&amp;gt;&lt;br /&gt;
  &amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;&amp;lt;i&amp;gt;Использование понятия &amp;quot;среднего&amp;quot;&amp;lt;/i&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;Алгоритм неприменим к данным, для которых не определено понятие &amp;quot;среднего&amp;quot;, например, категориальным данным.&amp;lt;/p&amp;gt;&lt;br /&gt;
  &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&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;
Исследование масштабируемости параллельной реализации алгоритма k means проводилось на суперкомпьютере &amp;quot;Ломоносов&amp;quot;. Алгоритм реализован на языке C с использованием средств MPI.&lt;br /&gt;
Для исследования масштабируемости проводилось множество запусков программы с разным значением параметра (количество векторов для кластеризации), а также с различным числом процессоров. Фиксировались результаты запусков &amp;amp;ndash; время работы &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt; и количество произведенных итераций алгоритма &amp;lt;math&amp;gt;\Tau&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Параметры запусков для экспериментальной оценки:&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;Значения &amp;lt;b&amp;gt;количества векторов&amp;lt;/b&amp;gt; &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;: 20&#039;000, 30&#039;000, 50&#039;000, 100&#039;000, 200&#039;000, 300&#039;000, 500&#039;000, 700&#039;000, 1&#039;000&#039;000, 1&#039;500&#039;000, 2&#039;000&#039;000.&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;Значения &amp;lt;b&amp;gt;количества процессоров&amp;lt;/b&amp;gt; &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt;: 1, 8, 16, 32, 64, 128, 160, 192, 224, 256, 288, 320, 352, 384, 416, 448, 480, 512.&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;Значение &amp;lt;b&amp;gt;количества кластеров&amp;lt;/b&amp;gt; &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt;: 100.&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;Значение &amp;lt;b&amp;gt;размерности векторов&amp;lt;/b&amp;gt; &amp;lt;math&amp;gt;d&amp;lt;/math&amp;gt;: 10.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Графики производительности и эффективности реализации представлены на рисунках 4 и 5 соответственно.&lt;br /&gt;
&lt;br /&gt;
[[file:Flops.png|thumb|center|800px|Рис. 4. График производительности реализации алгоритма.]]&lt;br /&gt;
&lt;br /&gt;
[[file:Efficiency.png|thumb|center|800px|Рис. 5. График эффективности реализации алгоритма.]]&lt;br /&gt;
&lt;br /&gt;
Для заданной конфигурации эксперимента (&amp;lt;math&amp;gt;n, d, p, k&amp;lt;/math&amp;gt;) и полученных результатах (&amp;lt;math&amp;gt;t, \Tau&amp;lt;/math&amp;gt;) производительность и эффективность реализации расчитывались по формулам (см. [[#Последовательная сложность алгоритма| последовательная сложность алгоритма]]):&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
&amp;lt;ul&amp;gt;&amp;lt;li&amp;gt;&amp;lt;math&amp;gt;Performance = \frac{\Theta_{k-means}^{d, n}}{t}\ \ FLOPS&amp;lt;/math&amp;gt;&amp;lt;/li&amp;gt;&amp;lt;/ul&amp;gt;&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
&amp;lt;ul&amp;gt;&amp;lt;li&amp;gt;&amp;lt;math&amp;gt;Efficiency = \frac{100 * Performance}{Performance_{Peak}^{p}}\ \ %,&amp;lt;/math&amp;gt;&amp;lt;/li&amp;gt;&amp;lt;/ul&amp;gt;&lt;br /&gt;
где &amp;lt;math&amp;gt;Performance_{Peak}^{p}&amp;lt;/math&amp;gt; &amp;amp;ndash; пиковая производительность суперкомпьютера при &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt; процессорах, вычисленная согласно спецификациям Intel&amp;lt;sup&amp;gt;&amp;amp;reg;&amp;lt;/sup&amp;gt; XEON&amp;lt;sup&amp;gt;&amp;amp;reg;&amp;lt;/sup&amp;gt; X5670&amp;lt;ref&amp;gt;&amp;quot;http://ark.intel.com/ru/products/47920/Intel-Xeon-Processor-X5670-12M-Cache-2_93-GHz-6_40-GTs-Intel-QPI&amp;quot;&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;В результате&amp;lt;/b&amp;gt; экспериментальной оценки были получены следующие оценки эффективности реализации:&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;b&amp;gt;Минимальное&amp;lt;/b&amp;gt; значение: 0.000409 % достигается при &amp;lt;math&amp;gt;n=20&#039;000, p=480&amp;lt;/math&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;b&amp;gt;Максимальное&amp;lt;/b&amp;gt; значение: 0.741119 % достигается при &amp;lt;math&amp;gt;n=300&#039;000, p=1&amp;lt;/math&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
Оценки масштабируемости реализации алгоритма k means:&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;b&amp;gt;По числу процессоров:&amp;lt;/b&amp;gt; -0.002683 &amp;amp;ndash; эффективность убывает с ростом числа процессоров.&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;b&amp;gt;По размеру задачи:&amp;lt;/b&amp;gt; 0.002779 &amp;amp;ndash; эффективность растет с ростом числа векторов.&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;b&amp;gt;Общая оценка:&amp;lt;/b&amp;gt; -0.000058 &amp;amp;ndash; можно сделать вывод, что в целом эффективность реализации незначительно уменьшается.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Динамические характеристики и эффективность реализации алгоритма ===&lt;br /&gt;
=== Выводы для классов архитектур ===&lt;br /&gt;
=== Существующие реализации алгоритма ===&lt;br /&gt;
==== Открытое программное обеспечение ====&lt;br /&gt;
&amp;lt;ol&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;[https://www.icpsr.umich.edu/CrimeStat/ CrimeStat]&amp;lt;/li&amp;gt; Программное обеспечение, созданное для операционных систем Windows, предоставляющее инструменты статистического  и пространственного анализа для решения задачи картирования преступности.&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://juliastats.github.io Julia]&amp;lt;/li&amp;gt; Высокоуровневый высокопроизводительный свободный язык программирования с динамической типизацией, созданный для математических вычислений, содержит реализацию k-means.&lt;br /&gt;
  &amp;lt;li&amp;gt;[https://mahout.apache.org Mahout]&amp;lt;/li&amp;gt; Apache Mahout - Java библиотека для работы с алгоритмами машинного обучения с использованием MapReduce. Содержит реализацию k-means.&lt;br /&gt;
  &amp;lt;li&amp;gt;[https://www.gnu.org/software/octave/ Octave]&amp;lt;/li&amp;gt; Написанная на C++  свободная система для математических вычислений, использующая совместимый с MATLAB язык высокого уровня, содержит реализацию k-means.&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://spark.apache.org/docs/latest/mllib-clustering.html Spark]&amp;lt;/li&amp;gt; Распределенная реализация k-means содержится в библиотеке Mlib для работы с алгоритмами машинного обучения, взаимодействующая с Python библиотекой NumPy и библиотека R.&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://torch.ch Torch]&amp;lt;/li&amp;gt;  MATLAB-подобная библиотека для языка программирования Lua с открытым исходным кодом, предоставляет большое количество алгоритмов для глубинного обучения и научных расчётов. Ядро написано на Си, прикладная часть выполняется на LuaJIT, поддерживается распараллеливание вычислений средствами CUDA и OpenMP. Существуют реализации k-means.&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://www.cs.waikato.ac.nz/ml/weka/ Weka]&amp;lt;/li&amp;gt;  Cвободное программное обеспечение для анализа данных, написанное на Java. Содержит k-means и x-means.&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://accord-framework.net/docs/html/T_Accord_MachineLearning_KMeans.htm Accord.NET]&amp;lt;/li&amp;gt; C# реализация алгоритмов k-means, k-means++, k-modes.&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://docs.opencv.org/3.0-beta/doc/py_tutorials/py_ml/py_kmeans/py_kmeans_opencv/py_kmeans_opencv.html OpenCV]&amp;lt;/li&amp;gt; Написанная на С++ библиотека, направленная в основном на решение задач компьютерного зрения. Содержит реализацию k-means.&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://mlpack.org/ MLPACK]&amp;lt;/li&amp;gt; Масштабируемая С++ библиотека для работы с алгоритмами машинного обучения, содержит реализацию k-means.&lt;br /&gt;
  &amp;lt;li&amp;gt;[https://www.scipy.org/ SciPy]&amp;lt;/li&amp;gt; Библиотека Python, содержит множество реализаций k-means.&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://scikit-learn.org/ scikit-learn]&amp;lt;/li&amp;gt; Библиотека Python, содержит множество реализаций k-means.&lt;br /&gt;
  &amp;lt;li&amp;gt;[https://www.r-bloggers.com/k-means-clustering-in-r/ R]&amp;lt;/li&amp;gt; Язык программирования для статистической обработки данных и работы с графикой, а также свободная программная среда вычислений с открытым исходным кодом в рамках проекта GNU, содержит три реализации k-means.&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://elki.dbs.ifi.lmu.de ELKI]&amp;lt;/li&amp;gt; Java фреймворк, содержащий реализацию k-means, а также множество других алгоритмов кластеризации.&lt;br /&gt;
&amp;lt;/ol&amp;gt;&lt;br /&gt;
==== Проприетарное программное обеспечение  ====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ol&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;[https://www.ayasdi.com/blog/bigdata/topological-data-analysis-of-oil-and-gas-petrophysical-data/ Ayasdi]&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://www.stata.com/features/cluster-analysis/ Stata]&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://mathworld.wolfram.com/K-MeansClusteringAlgorithm.html Mathematica]&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://www.mathworks.com/help/stats/kmeans.html?requestedDomain=www.mathworks.com MATLAB]&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;[https://support.sas.com/rnd/app/stat/procedures/fastclus.html SAS]&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://docs.rapidminer.com/studio/operators/modeling/segmentation/k_means.html RapidMiner]&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;[https://blogs.sap.com/2013/03/28/sap-hana-pal-k-means-algorithm-or-how-to-do-customer-segmentation-for-the-telecommunications-industry/ SAP HANA]&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ol&amp;gt;&lt;br /&gt;
== Литература ==&lt;br /&gt;
&amp;lt;references /&amp;gt;&lt;/div&gt;</summary>
		<author><name>DennZo1993</name></author>
	</entry>
	<entry>
		<id>https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:%D0%91%D1%80%D0%BE%D1%82%D0%B8%D0%BA%D0%BE%D0%B2%D1%81%D0%BA%D0%B0%D1%8F_%D0%94%D0%B0%D0%BD%D1%83%D1%82%D0%B0/%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_k-means&amp;diff=17183</id>
		<title>Участник:Бротиковская Данута/Алгоритм k-means</title>
		<link rel="alternate" type="text/html" href="https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:%D0%91%D1%80%D0%BE%D1%82%D0%B8%D0%BA%D0%BE%D0%B2%D1%81%D0%BA%D0%B0%D1%8F_%D0%94%D0%B0%D0%BD%D1%83%D1%82%D0%B0/%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_k-means&amp;diff=17183"/>
		<updated>2016-11-15T01:43:52Z</updated>

		<summary type="html">&lt;p&gt;DennZo1993: /* Масштабируемость реализации алгоритма */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt; {{Assignment|Zhum}}&lt;br /&gt;
&lt;br /&gt;
{{algorithm&lt;br /&gt;
| name              = Алгоритм k средних (k means)&lt;br /&gt;
| serial_complexity = &amp;lt;math&amp;gt;O(\Tau*k*d*n)&amp;lt;/math&amp;gt;&lt;br /&gt;
| input_data        = &amp;lt;math&amp;gt; d*n &amp;lt;/math&amp;gt;&lt;br /&gt;
| output_data       = &amp;lt;math&amp;gt; n &amp;lt;/math&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
Авторы страницы &amp;lt;b&amp;gt;[[Участник:Бротиковская Данута|Данута Бротиковская]]&amp;lt;/b&amp;gt; и &amp;lt;b&amp;gt;[[Участник:DennZo1993|Денис Зобнин]]&amp;lt;/b&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
Оба автора внесли одинаковый вклад в написание статьи (поиск материалов, изучение статей, заполнение контента статьи), четких разграничений по пунктам статьи сделать невозможно. &lt;br /&gt;
&lt;br /&gt;
== Свойства и структура алгоритма ==&lt;br /&gt;
&lt;br /&gt;
=== Общее описание алгоритма ===&lt;br /&gt;
Алгоритм &amp;lt;b&amp;gt;&amp;lt;i&amp;gt;k средних&amp;lt;/i&amp;gt;&amp;lt;/b&amp;gt; (&amp;lt;b&amp;gt;&amp;lt;i&amp;gt;k means&amp;lt;/i&amp;gt;&amp;lt;/b&amp;gt;) &amp;amp;ndash; неиерархический&amp;lt;ref&amp;gt;&amp;quot;https://ru.wikipedia.org/wiki/Иерархическая_кластеризация&amp;quot;&amp;lt;/ref&amp;gt;, итерационный метод кластеризации&amp;lt;ref&amp;gt;&amp;quot;https://ru.wikipedia.org/wiki/Кластерный_анализ&amp;quot;&amp;lt;/ref&amp;gt;, получивший большую популярность благодаря своей простоте, наглядности реализации и достаточно высокому качеству работы. Был изобретен в 1950-х годах математиком &amp;lt;i&amp;gt;Гуго Штейнгаузом&amp;lt;/i&amp;gt;&amp;lt;ref&amp;gt;Steinhaus, Hugo. &amp;quot;Sur la division des corp materiels en parties.&amp;quot; Bull. Acad. Polon. Sci 1.804 (1956): 801.&amp;lt;/ref&amp;gt; и почти одновременно &amp;lt;i&amp;gt;Стюартом Ллойдом&amp;lt;/i&amp;gt;&amp;lt;ref&amp;gt;Lloyd, S. P. &amp;quot;Least square quantization in PCM. Bell Telephone Laboratories Paper. Published in journal much later: Lloyd, SP: Least squares quantization in PCM.&amp;quot; IEEE Trans. Inform. Theor.(1957/1982).&amp;lt;/ref&amp;gt;. Особую популярность приобрел после публикации работы &amp;lt;i&amp;gt;МакКуина&amp;lt;/i&amp;gt;&amp;lt;ref&amp;gt;MacQueen, James. &amp;quot;Some methods for classification and analysis of multivariate observations.&amp;quot; Proceedings of the fifth Berkeley symposium on mathematical statistics and probability. Vol. 1. No. 14. 1967.&amp;lt;/ref&amp;gt; в 1967.&lt;br /&gt;
&lt;br /&gt;
Алгоритм представляет собой версию EM-алгоритма&amp;lt;ref&amp;gt;&amp;quot;https://ru.wikipedia.org/wiki/EM-алгоритм&amp;quot;&amp;lt;/ref&amp;gt;, применяемого также для разделения смеси гауссиан. Основная идея &amp;lt;i&amp;gt;k means&amp;lt;/i&amp;gt; заключается в том, что данные произвольно разбиваются на кластеры, после чего итеративно перевычисляется центр масс для каждого кластера, полученного на предыдущем шаге, затем векторы разбиваются на кластеры вновь в соответствии с тем, какой из новых центров оказался ближе по выбранной метрике.&lt;br /&gt;
&lt;br /&gt;
Цель алгоритма заключается в разделении &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; наблюдений на &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластеров таким образом, чтобы каждое наблюдение принадлежало ровно одному кластеру, расположенному на наименьшем расстоянии от наблюдения.&lt;br /&gt;
&lt;br /&gt;
=== Математическое описание алгоритма ===&lt;br /&gt;
&amp;lt;b&amp;gt;&amp;lt;u&amp;gt;Дано:&amp;lt;/u&amp;gt;&amp;lt;/b&amp;gt;&lt;br /&gt;
* набор из &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; наблюдений &amp;lt;math&amp;gt;X=\{\mathbf{x}_1, \mathbf{x}_2, ..., \mathbf{x}_n\}, \mathbf{x}_i \in \mathbb{R}^d, i=\overline{1, n}&amp;lt;/math&amp;gt;;&lt;br /&gt;
* &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; - требуемое число кластеров, &amp;lt;math&amp;gt;k \in \mathbb{N}, k \leq n&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;&amp;lt;u&amp;gt;Требуется:&amp;lt;/u&amp;gt;&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Разделить множество наблюдений &amp;lt;math&amp;gt;X&amp;lt;/math&amp;gt; на &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластеров &amp;lt;math&amp;gt;S_1, S_2, ..., S_k&amp;lt;/math&amp;gt;:&lt;br /&gt;
*   &amp;lt;math&amp;gt;S_i \cap S_j= \varnothing, \quad i \ne j&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
*   &amp;lt;math&amp;gt;\bigcup_{i=1}^{k} S_i = X&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;&amp;lt;u&amp;gt;Действие алгоритма:&amp;lt;/u&amp;gt;&amp;lt;/b&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;Алгоритм &amp;lt;i&amp;gt;k means&amp;lt;/i&amp;gt; разбивает набор &amp;lt;math&amp;gt;X&amp;lt;/math&amp;gt; на &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; наборов &amp;lt;math&amp;gt;S_1, S_2, ..., S_k,&amp;lt;/math&amp;gt; таким образом, чтобы минимизировать сумму квадратов расстояний от каждой точки кластера до его центра (центр масс кластера). Введем обозначение, &amp;lt;math&amp;gt;S=\{S_1, S_2, ..., S_k\}&amp;lt;/math&amp;gt;. Тогда действие алгоритма &amp;lt;i&amp;gt;k means&amp;lt;/i&amp;gt; равносильно поиску:&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;table style=&amp;quot;width:100%&amp;quot;&amp;gt;&lt;br /&gt;
  &amp;lt;tr&amp;gt;&lt;br /&gt;
    &amp;lt;td align=&amp;quot;center&amp;quot; width=&amp;quot;90%&amp;quot;&amp;gt;&amp;lt;math&amp;gt;\arg\min_{S} \sum\limits_{i=1}^k \sum\limits_{\mathbf{x} \in S_i} \rho(\mathbf{x}, \mathbf{\mu}_i )^2,&amp;lt;/math&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;td align=&amp;quot;right&amp;quot;&amp;gt;&amp;lt;math&amp;gt;(1)&amp;lt;/math&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;/table&amp;gt;&lt;br /&gt;
где &amp;lt;math&amp;gt;\mathbf{\mu}_i&amp;lt;/math&amp;gt; &amp;amp;ndash; центры кластеров, &amp;lt;math&amp;gt;i=\overline{1,k}, \quad \rho(\mathbf{x}, \mathbf{\mu}_i)&amp;lt;/math&amp;gt; &amp;amp;ndash; функция расстояния между &amp;lt;math&amp;gt;\mathbf{x}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\mu_i&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;&amp;lt;u&amp;gt;Шаги алгоритма: &amp;lt;/u&amp;gt;&amp;lt;/b&amp;gt;&lt;br /&gt;
&amp;lt;ol&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&lt;br /&gt;
    &amp;lt;b&amp;gt;Начальный шаг: инициализация кластеров&amp;lt;/b&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;Выбирается произвольное множество точек &amp;lt;math&amp;gt;\mu_i, i=\overline{1,k}&amp;lt;/math&amp;gt;, рассматриваемых как начальные центры кластеров: &amp;lt;math&amp;gt;\mu_i^{(0)} = \mu_i, \quad i=\overline{1, k}&amp;lt;/math&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
  &amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&lt;br /&gt;
    &amp;lt;b&amp;gt;Распределение векторов по кластерам&amp;lt;/b&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Шаг&amp;lt;/b&amp;gt; &amp;lt;math&amp;gt;t: \forall \mathbf{x}_i \in X, i=\overline{1,n}: \mathbf{x}_i \in S_j \iff  j=\arg\min_{k}\rho(\mathbf{x}_i,\mathbf{\mu}_k^{(t-1)})^2&amp;lt;/math&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
  &amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&lt;br /&gt;
    &amp;lt;b&amp;gt;Пересчет центров кластеров&amp;lt;/b&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Шаг &amp;lt;/b&amp;gt; &amp;lt;math&amp;gt;t: \forall i=\overline{1,k}:  \mu_i^{(t)} = \cfrac{1}{|S_i|}\sum_{\mathbf{x}\in S_i}\mathbf{x}&amp;lt;/math&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
  &amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&lt;br /&gt;
    &amp;lt;b&amp;gt;Проверка условия останова:&amp;lt;/b&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
    &#039;&#039;&#039;if&#039;&#039;&#039; &amp;lt;math&amp;gt;\exist i\in \overline{1,k}: \mu_i^{(t)} \ne \mu_i^{(t-1)}&amp;lt;/math&amp;gt; &#039;&#039;&#039;then&#039;&#039;&#039;&lt;br /&gt;
        t = t + 1;&lt;br /&gt;
        goto 2;&lt;br /&gt;
    &#039;&#039;&#039;else&#039;&#039;&#039;&lt;br /&gt;
        &#039;&#039;&#039;stop&#039;&#039;&#039;&lt;br /&gt;
  &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ol&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Вычислительное ядро алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Вычислительным ядром являются шаги 2 и 3 приведенного выше алгоритма: &amp;lt;b&amp;gt;&amp;lt;i&amp;gt;распределение векторов по кластерам&amp;lt;/i&amp;gt;&amp;lt;/b&amp;gt; и &amp;lt;b&amp;gt;&amp;lt;i&amp;gt;пересчет центров кластеров&amp;lt;/i&amp;gt;&amp;lt;/b&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;&amp;lt;i&amp;gt;Распределение векторов&amp;lt;/i&amp;gt;&amp;lt;/b&amp;gt; по кластерам предполагает вычисление расстояний между каждым вектором &amp;lt;math&amp;gt;\mathbf{x}_i \in X, i= \overline{1,n}&amp;lt;/math&amp;gt; и центрами кластера &amp;lt;math&amp;gt;\mathbf{\mu}_j, j= \overline{1,k}&amp;lt;/math&amp;gt;. Таким образом, данный шаг предполагает &amp;lt;math&amp;gt;k*n&amp;lt;/math&amp;gt; вычислений расстояний между d-мерными векторами. &lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;&amp;lt;i&amp;gt;Пересчет центров кластеров&amp;lt;/i&amp;gt;&amp;lt;/b&amp;gt; предполагает &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; вычислений центров масс &amp;lt;math&amp;gt;\mathbf{\mu}_i&amp;lt;/math&amp;gt; множеств &amp;lt;math&amp;gt;S_i, i=\overline{1,k}&amp;lt;/math&amp;gt; представленных выражением в шаге 3 представленного выше алгоритма.&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Макроструктура алгоритма ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Инициализация центров масс &amp;lt;math&amp;gt;\mu_1, ..., \mu_k&amp;lt;/math&amp;gt;&amp;lt;/b&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
Наиболее распространенными являются следующие стратегии:&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&lt;br /&gt;
    &amp;lt;b&amp;gt;Метод Forgy&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;В качестве начальных значений &amp;lt;math&amp;gt;\mu_1, ..., \mu_k&amp;lt;/math&amp;gt; берутся случайно выбранные векторы.&lt;br /&gt;
  &amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&lt;br /&gt;
    &amp;lt;b&amp;gt;Метод случайно разделения (Random Partitioning)&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;Для каждого вектора &amp;lt;math&amp;gt;\mathbf{x}_i \in X, i=\overline{1, n}&amp;lt;/math&amp;gt; выбирается случайным образом кластер &amp;lt;math&amp;gt;S_1, ..., S_k&amp;lt;/math&amp;gt;, после чего для каждого полученного кластера вычисляются значения &amp;lt;math&amp;gt;\mu_1, ..., \mu_k&amp;lt;/math&amp;gt;.&lt;br /&gt;
  &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Распределение векторов по кластерам&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Для этого шага алгоритма между векторами &amp;lt;math&amp;gt;\mathbf{x}_i \in X, i=\overline{1, n}&amp;lt;/math&amp;gt; и центрами кластеров &amp;lt;math&amp;gt;\mu_1, ..., \mu_k&amp;lt;/math&amp;gt; вычисляются &amp;lt;b&amp;gt;расстояния&amp;lt;/b&amp;gt; по формуле (как правило, используется Евлидово расстояние):&lt;br /&gt;
&amp;lt;table style=&amp;quot;width:100%&amp;quot;&amp;gt;&lt;br /&gt;
  &amp;lt;tr&amp;gt;&lt;br /&gt;
    &amp;lt;td align=&amp;quot;center&amp;quot; width=&amp;quot;90%&amp;quot;&amp;gt;&amp;lt;math&amp;gt; \mathbf{v}_1, \mathbf{v}_2 \in \mathbb{R}^d,  \quad \rho(\mathbf{v}_1, \mathbf{v}_2) = \lVert \mathbf{v}_1- \mathbf{v}_2 \rVert= \sqrt{\sum_{i=1}^{d}(\mathbf{v}_{1,i} - \mathbf{v}_{2,i})^2}&amp;lt;/math&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;td align=&amp;quot;right&amp;quot;&amp;gt;&amp;lt;math&amp;gt;(2)&amp;lt;/math&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;/table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Пересчет центров кластеров&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Для этого шага алгоритма производится пересчет центров кластера по &amp;lt;b&amp;gt;формуле вычисления центра масс&amp;lt;/b&amp;gt;:&lt;br /&gt;
&amp;lt;table style=&amp;quot;width:100%&amp;quot;&amp;gt;&lt;br /&gt;
  &amp;lt;tr&amp;gt;&lt;br /&gt;
    &amp;lt;td align=&amp;quot;center&amp;quot; width=&amp;quot;90%&amp;quot;&amp;gt;&amp;lt;math&amp;gt; \mu = \cfrac{1}{|S|}\sum_{\mathbf{x}\in S}\mathbf{x}&amp;lt;/math&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;td align=&amp;quot;right&amp;quot;&amp;gt;&amp;lt;math&amp;gt;(3)&amp;lt;/math&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;/table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Схема реализации последовательного алгоритма ===&lt;br /&gt;
&lt;br /&gt;
 &#039;&#039;&#039;algorithm&#039;&#039;&#039; k-means &#039;&#039;&#039;is&#039;&#039;&#039;&lt;br /&gt;
     &#039;&#039;&#039;1.&#039;&#039;&#039; Инициализировать центры кластеров &amp;lt;math&amp;gt;\mathbf{\mu}_i^{(1)}, i=\overline{1,k}&amp;lt;/math&amp;gt;&lt;br /&gt;
     &#039;&#039;&#039;2.&#039;&#039;&#039; &amp;lt;math&amp;gt;t \leftarrow 1&amp;lt;/math&amp;gt;&lt;br /&gt;
     &#039;&#039;&#039;3.&#039;&#039;&#039; &#039;&#039;&#039;Распределение по кластерам&#039;&#039;&#039;&amp;lt;br&amp;gt;&lt;br /&gt;
        &amp;lt;math&amp;gt;S_i^{(t)}=\{\mathbf{x}_p: \lVert\mathbf{x}_p-\mathbf{\mu}_i^{(t)}\rVert^2 \leq \lVert\mathbf{x}_p-\mathbf{\mu}_j^{(t)}\rVert^2 \quad \forall j=\overline{1,k}\},&amp;lt;/math&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
        где каждый вектор &amp;lt;math&amp;gt;\mathbf{x}_p&amp;lt;/math&amp;gt; соотносится единственному кластеру &amp;lt;math&amp;gt;S^{(t)}&amp;lt;/math&amp;gt;&lt;br /&gt;
     &#039;&#039;&#039;4.&#039;&#039;&#039; &#039;&#039;&#039;Обновление центров кластеров&#039;&#039;&#039;&amp;lt;br&amp;gt;&lt;br /&gt;
        &amp;lt;math&amp;gt;\mathbf{\mu}_i^{(t+1)} = \frac{1}{|S^{(t)}_i|} \sum_{\mathbf{x}_j \in S^{(t)}_i} \mathbf{x}_j &amp;lt;/math&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
     &#039;&#039;&#039;5.&#039;&#039;&#039; &#039;&#039;&#039;if&#039;&#039;&#039; &amp;lt;math&amp;gt;\exist i \in \overline{1,k}: \mathbf{\mu}_i^{(t+1)} \ne \mathbf{\mu}_i^{(t)}&amp;lt;/math&amp;gt; &#039;&#039;&#039;then&#039;&#039;&#039;&lt;br /&gt;
            t = t + 1;&lt;br /&gt;
            goto &#039;&#039;&#039;3&#039;&#039;&#039;;&lt;br /&gt;
        &#039;&#039;&#039;else&#039;&#039;&#039;&lt;br /&gt;
            &#039;&#039;&#039;stop&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
=== Последовательная сложность алгоритма===&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding-bottom: 20px&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;Обозначим &amp;lt;math&amp;gt;\Theta_{centroid}^{d, m}&amp;lt;/math&amp;gt; временную сложность вычисления центорида кластера, число элементов которого равна &amp;lt;math&amp;gt;m&amp;lt;/math&amp;gt;,  в d-мерном пространстве.&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;Аналогично  &amp;lt;math&amp;gt;\Theta_{distance}^d&amp;lt;/math&amp;gt; &amp;amp;ndash; временная сложность вычисления расстояния между двумя d-мерными векторами.&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding-bottom: 20px&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;Сложность шага инициализации &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластеров мощности &amp;lt;math&amp;gt;m&amp;lt;/math&amp;gt; в d-мерном пространстве &amp;amp;ndash; &amp;lt;math&amp;gt;\Theta_{init}^{k, d, m}&amp;lt;/math&amp;gt;&amp;lt;/b&amp;gt;&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;i&amp;gt;Стратерия Forgy&amp;lt;/i&amp;gt;: вычисления не требуются, &amp;lt;math&amp;gt;\Theta_{init}^{k, d, m} = 0&amp;lt;/math&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;i&amp;gt;Стратегия случайного разбиения&amp;lt;/i&amp;gt;: вычисление центров &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластеров,  &amp;lt;math&amp;gt;\Theta_{init}^{k, d, m} = k*\Theta_{centroid}^{d, m}, m \le n&amp;lt;/math&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding-bottom: 20px&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Cложность шага распределения d мерных векторов по &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластерам &amp;amp;ndash; &amp;lt;math&amp;gt;\Theta_{distribute}^{k, d}&amp;lt;/math&amp;gt;&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
На этом шаге для каждого вектора &amp;lt;math&amp;gt;\mathbf{x}_i \in X, i=\overline{1, n}&amp;lt;/math&amp;gt; вычисляется k расстояний до центров кластеров &amp;lt;math&amp;gt;\mathbf{\mu}_1, ...\mathbf{\mu}_k&amp;lt;/math&amp;gt;&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p align=&amp;quot;center&amp;quot;&amp;gt;&lt;br /&gt;
  &amp;lt;math&amp;gt;\Theta_{distribute}^{k, d} = n*k*\Theta_{distance}^d&amp;lt;/math&amp;gt;&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding-bottom: 20px&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;Сложность шага пересчета центров &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластеров размера &amp;lt;math&amp;gt;m&amp;lt;/math&amp;gt; в d-мерном пространстве &amp;amp;ndash; &amp;lt;math&amp;gt;\Theta_{recenter}^{k, d, m}&amp;lt;/math&amp;gt;&amp;lt;/b&amp;gt;&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;На этом шаге вычисляется &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; центров кластеров &amp;lt;math&amp;gt;\mathbf{\mu}_1, ...\mathbf{\mu}_k&amp;lt;/math&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p align=&amp;quot;center&amp;quot;&amp;gt;&amp;lt;math&amp;gt;\Theta_{recenter}^{k, d, m} = k*\Theta_{centroid}^{d, m}&amp;lt;/math&amp;gt; &amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding-bottom: 20px&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Рассчитаем &amp;lt;math&amp;gt;\Theta_{centroid}^{d, m}&amp;lt;/math&amp;gt; для кластера, число элементов которого равно &amp;lt;math&amp;gt;m&amp;lt;/math&amp;gt;&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p align=&amp;quot;center&amp;quot;&amp;gt;&amp;lt;math&amp;gt;\Theta_{centroid}^{d, m}&amp;lt;/math&amp;gt; = &amp;lt;math&amp;gt;m * d&amp;lt;/math&amp;gt; сложений + &amp;lt;math&amp;gt;d&amp;lt;/math&amp;gt; делений &amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding-bottom: 20px&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Рассчитаем &amp;lt;math&amp;gt;\Theta_{distance}^d&amp;lt;/math&amp;gt; в соответствие с формулой &amp;lt;math&amp;gt;(2)&amp;lt;/math&amp;gt;&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p align=&amp;quot;center&amp;quot;&amp;gt;&amp;lt;math&amp;gt;\Theta_{distance}^d&amp;lt;/math&amp;gt; = &amp;lt;math&amp;gt;d&amp;lt;/math&amp;gt; вычитаний + &amp;lt;math&amp;gt;d&amp;lt;/math&amp;gt; умножений + &amp;lt;math&amp;gt;(d-1)&amp;lt;/math&amp;gt; сложение&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding-bottom: 20px&amp;quot;&amp;gt;&lt;br /&gt;
  &amp;lt;p&amp;gt;Предположим, что алгоритм сошелся за &amp;lt;math&amp;gt;\Tau&amp;lt;/math&amp;gt; итераций, тогда временная сложность алгоритма &amp;lt;math&amp;gt;\Theta_{k-means}^{d, n}&amp;lt;/math&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
  &amp;lt;p align=&amp;quot;center&amp;quot;&amp;gt;&amp;lt;b&amp;gt;&amp;lt;math&amp;gt;\Theta_{k-means}^{d, n} \le \Theta_{init}^{k, d, n} + \Tau*(\Theta_{distribute}^{k, d} + \Theta_{recenter}^{k, d, n})&amp;lt;/math&amp;gt;&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding-bottom: 5px&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;Операции сложения/вычитания:&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p align=&amp;quot;center&amp;quot;&amp;gt;&amp;lt;b&amp;gt;&amp;lt;math&amp;gt;\Theta_{k-means}^{d, n} \le k*n*d+ \Tau*(k*n*(2d-1) + k*n*d) = k*n*d+ \Tau*(k*n*(3d-1)) \thicksim O(\Tau*k*d*n)&amp;lt;/math&amp;gt;&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding-bottom: 20px&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;Операции умножения/деления:&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p align=&amp;quot;center&amp;quot;&amp;gt;&amp;lt;b&amp;gt;&amp;lt;math&amp;gt;\Theta_{k-means}^{d, n} \le k*d + \Tau*(k*n*d + k*d) = k*d + \Tau * k*d*(n+1) \thicksim O(\Tau*k*d*n) &amp;lt;/math&amp;gt;&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding-bottom: 20px&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;Получаем, что &amp;lt;b&amp;gt;временная сложность&amp;lt;/b&amp;gt; алгоритма &amp;lt;b&amp;gt;k means&amp;lt;/b&amp;gt; кластеризации &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; &amp;lt;b&amp;gt;d-мерных&amp;lt;/b&amp;gt; векторов на &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластеров за &amp;lt;math&amp;gt;\Tau&amp;lt;/math&amp;gt; итераций:&amp;lt;/p&amp;gt;&lt;br /&gt;
 &amp;lt;p align=&amp;quot;center&amp;quot;&amp;gt;&amp;lt;b&amp;gt;&amp;lt;math&amp;gt; \Theta_{k-means}^{d, n} \thicksim O(\Tau*k*d*n) &amp;lt;/math&amp;gt;&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Информационный граф ===&lt;br /&gt;
&lt;br /&gt;
Рассмотрим информационный граф алгоритма. Алгоритм &amp;lt;i&amp;gt;k means&amp;lt;/i&amp;gt; начинается с этапа инициализации, после которого следуют итерации, на каждой из которых выполняется два последовательных шага (см. [[#Схема реализации последовательного алгоритма|&amp;quot;Схема реализации последовательного алгоритма&amp;quot;]]): &lt;br /&gt;
* распределение векторов по кластерам&lt;br /&gt;
* перерасчет центров кластеров&lt;br /&gt;
&lt;br /&gt;
Поскольку основная часть вычислений приходится на шаги итераций, распишем информационные графы данных шагов.&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Распределение векторов по кластерам&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
Информационный граф шага распределения векторов по кластерам представлен на &#039;&#039;рисунке 1&#039;&#039;. Исходами данного графа является исходные векторы &amp;lt;math&amp;gt;\mathbf{x}_1, ..., \mathbf{x}_n&amp;lt;/math&amp;gt;, а также центры кластеров &amp;lt;math&amp;gt;\mathbf{\mu}_1, ... \mathbf{\mu}_k&amp;lt;/math&amp;gt;, вычисленные ранее (на шаге инициализации, если рассматривается первая итерация алгоритма, или на шаге пересчета центров кластеров предыдущей итерации в противном случае). Каждая пара векторов данных &amp;lt;math&amp;gt;\mathbf{x}_i, i=\overline{1,n}&amp;lt;/math&amp;gt; и центров кластера &amp;lt;math&amp;gt;\mathbf{\mu}_j, j=\overline{1, k}&amp;lt;/math&amp;gt; : (&amp;lt;math&amp;gt;\mathbf{x}_i&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;\mathbf{\mu}_j&amp;lt;/math&amp;gt;) подаются на независимые узлы &amp;lt;i&amp;gt;&amp;quot;d&amp;quot;&amp;lt;/i&amp;gt; вычисления расстояния между векторами (более подробная схема вычисления расстояния представлена далее, &#039;&#039;рисунок 2&#039;&#039;). Далее узлы вычисления расстояния &amp;lt;i&amp;gt;&amp;quot;d&amp;quot;&amp;lt;/i&amp;gt;, соответствующие одному и тому же исходному вектору &amp;lt;math&amp;gt;\mathbf{x}_i&amp;lt;/math&amp;gt; передаются на один узел &amp;lt;i&amp;gt;&amp;quot;m&amp;quot;&amp;lt;/i&amp;gt;, где далее происходит вычисление новой метки кластера для каждого вектора &amp;lt;math&amp;gt;\mathbf{x}_i&amp;lt;/math&amp;gt; (берется кластер с минимальным результатом вычисления расстояния). На выходе графа выдаются метки кластеров , &amp;lt;math&amp;gt;L_1, ..., L_n&amp;lt;/math&amp;gt;, такие что &amp;lt;math&amp;gt;\forall \mathbf{x}_i, i=\overline{1, n}, \mathbf{x}_i \in S_j \Leftrightarrow L_i = j&amp;lt;/math&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
[[file:Clusterization.png|thumb|center|800px|Рис. 1. Схема распределения векторов по кластерам. &#039;&#039;d&#039;&#039; &amp;amp;ndash; вычисление расстояния между векторами; &#039;&#039;m&#039;&#039; &amp;amp;ndash; вычисление минимума.]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Вычисление расстояния между векторами&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
Подробная схема вычисления расстояния между векторами &amp;lt;math&amp;gt;\mathbf{x}_i, \mathbf{\mu}_j&amp;lt;/math&amp;gt; представлена на &#039;&#039;рисунке 2&#039;&#039;. Как показано на графе, узел вычисления расстояния между векторами &amp;lt;i&amp;gt;&amp;quot;d&amp;quot;&amp;lt;/i&amp;gt; состоит из шага взятия разности между векторами (узел &amp;quot;&amp;lt;math&amp;gt;-&amp;lt;/math&amp;gt;&amp;quot;) и взятия нормы получившегося вектора разности (узел &amp;quot;&amp;lt;math&amp;gt;||\cdot||^2&amp;lt;/math&amp;gt;&amp;quot;). Более подробно, вычисление расстояния между векторами &amp;lt;math&amp;gt;\mathbf{x}_i = {x_{i1,}, ...,{x_{in}}}, \mathbf{\mu}_j = {\mu_{j1}, ...,\mu_{jn}}&amp;lt;/math&amp;gt; может быть представлено как вычисление разности между каждой парой компонент &amp;lt;math&amp;gt;(x_{iz}, \mu_{jz}), z=\overline{1, d}&amp;lt;/math&amp;gt; (узел &amp;quot;&amp;lt;math&amp;gt;-&amp;lt;/math&amp;gt;&amp;quot;), далее возведение в квадрат для каждого узла &amp;quot;&amp;lt;math&amp;gt;-&amp;lt;/math&amp;gt;&amp;quot; (узел &amp;quot;&amp;lt;math&amp;gt;()^2&amp;lt;/math&amp;gt;&amp;quot;) и суммирования выходов всех узлов &amp;quot;&amp;lt;math&amp;gt;()^2&amp;lt;/math&amp;gt;&amp;quot; (узел &amp;quot;&amp;lt;math&amp;gt;+&amp;lt;/math&amp;gt;&amp;quot;).  &lt;br /&gt;
&lt;br /&gt;
[[file:dist_calc.png|thumb|center|800px|Рис. 2. Схема вычисления расстояния между вектором и центром кластера.]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Пересчет центров кластеров&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
Информационный граф шага пересчета центров кластеров представлен на &#039;&#039;рисунке 3&#039;&#039;. Исходами данного графа является исходные векторы &amp;lt;math&amp;gt;\mathbf{x}_1, ..., \mathbf{x}_n&amp;lt;/math&amp;gt;, а также им соответствующие метки кластера, &amp;lt;math&amp;gt;L_1, ..., L_n&amp;lt;/math&amp;gt;, такие что &amp;lt;math&amp;gt;\forall x_i, i=\overline{1, n}, \mathbf{x}_i \in S_j \Leftrightarrow L_i = j&amp;lt;/math&amp;gt;, вычисленные на этапе распределения векторов по кластерам. Все векторы &amp;lt;math&amp;gt;\mathbf{x}_1, ..., \mathbf{x}_n&amp;lt;/math&amp;gt; подаются в узлы &amp;lt;math&amp;gt;+_1, ...+_k&amp;lt;/math&amp;gt;, каждый узел &amp;lt;math&amp;gt;+_m, m = \overline{1,k}&amp;lt;/math&amp;gt; соответствует операции сложения векторов кластера с номером &amp;lt;math&amp;gt;m&amp;lt;/math&amp;gt;. Метки кластера &amp;lt;math&amp;gt;L_1, ..., L_n&amp;lt;/math&amp;gt; также совместно передаются на узлы &amp;lt;math&amp;gt;S_m, m = \overline{1,k}&amp;lt;/math&amp;gt;, на каждом из которых вычисляется количество векторов в соответствующем кластере (количество меток с соответствующим значением). Далее каждая пара выходов узлов &amp;lt;math&amp;gt;+_m&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;S_m&amp;lt;/math&amp;gt; подается на узел &amp;quot;&amp;lt;math&amp;gt;/&amp;lt;/math&amp;gt;&amp;quot;, где производится деление суммы векторов кластера на количество элементов в нем. Значения, вычисленные на узлах &amp;quot;&amp;lt;math&amp;gt;/&amp;lt;/math&amp;gt;&amp;quot;, присваиваются новым центрам кластеров (выходные значения графа).&lt;br /&gt;
&lt;br /&gt;
[[file:Recluster.png|thumb|center|800px|Рис. 3. Схема пересчета центров кластеров]]&lt;br /&gt;
&lt;br /&gt;
=== Ресурс параллелизма алгоритма ===&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
Работа алгоритма состоит из &amp;lt;math&amp;gt;\Tau&amp;lt;/math&amp;gt; итераций, в каждой из которых происходит &amp;lt;b&amp;gt;распределение d-мерных векторов по &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластерам&amp;lt;/b&amp;gt;, а также &amp;lt;b&amp;gt;пересчет центров кластеров в d-мерном пространстве&amp;lt;/b&amp;gt;. В шаге &amp;lt;b&amp;gt;распределения d-мерных векторов по &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластерам&amp;lt;/b&amp;gt; расстояния между вектором и центрами кластеров вычисляются независимо (отсутствуют информационные зависимости). &amp;lt;b&amp;gt;Центры масс кластеров&amp;lt;/b&amp;gt; также пересчитываются независимо друг от друга. Таким образом, имеет место [[глоссарий#Массовый параллелизм|&#039;&#039;массовый параллелизм&#039;&#039;]]. Вычислим параллельную сложность &amp;lt;math&amp;gt;\Psi_*&amp;lt;/math&amp;gt; каждого из шагов, а также параллельную сложность всего алгоритма, &amp;lt;math&amp;gt;\Psi_{k-means}&amp;lt;/math&amp;gt;. Будем исходить из предположения, что может быть использовано любое необходимое число потоков.&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Распределение d-мерных векторов по &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластерам&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;  &lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
Поскольку на данном шаге для каждой пары векторов &amp;lt;math&amp;gt;\mathbf{x}_i, i=\overline{1,n}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\mathbf{\mu}_j, j=\overline{1,k}&amp;lt;/math&amp;gt; операции вычисления расстояния не зависят друг от друга, они могут выполняться параллельно. Тогда, разделив все вычисление расстояний на &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; потоков, получим, что в каждом потоке будет выполняться только одна операция вычисления расстояния между векторами размерности d. При этом каждому вычислительному потоку передаются координаты центров всех кластеров &amp;lt;math&amp;gt;\mathbf{\mu}_1, ..., \mathbf{\mu}_k&amp;lt;/math&amp;gt;. Таким образом, параллельная сложность данного шага определяется &amp;lt;i&amp;gt; сложностью параллельной операции вычисления расстояния между d-мерными векторами&amp;lt;/i&amp;gt;, &amp;lt;math&amp;gt;\Psi_{distance}^d&amp;lt;/math&amp;gt;  и &amp;lt;i&amp;gt;сложностью определения наиболее близкого кластера&amp;lt;/i&amp;gt; (паралельное взятие минимума по расстояниям), &amp;lt;math&amp;gt;\Psi_{min}^k&amp;lt;/math&amp;gt;. Для оценки &amp;lt;math&amp;gt;\Psi_{distance}^d&amp;lt;/math&amp;gt; воспользуемся  [[Нахождение_частных_сумм_элементов_массива_сдваиванием | параллельной реализацией нахождения частичной суммы элементов массива путем сдваивания]]. Аналогично, &amp;lt;math&amp;gt;\Psi_{min}^k = log(k)&amp;lt;/math&amp;gt;. В результате, &amp;lt;math&amp;gt;\Psi_{distance}^d = O(log(d))&amp;lt;/math&amp;gt;.   Таким образом: &lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p align=&amp;quot;center&amp;quot;&amp;gt;&amp;lt;math&amp;gt;\Psi_{distribute}^{k, d}  = \Psi_{distance}^d + \Psi_{min}^k = O(log(d))+O(log(k)) = O(log(k*d))&amp;lt;/math&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Пересчет центров кластеров в d-мерном пространстве&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
Поскольку на данном шаге для каждого из &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластеров центр масс может быть вычислен независимо, данные операции могут быть выполнены в отдельных потоках. Таким образом, параллельная сложность данного шага, &amp;lt;math&amp;gt;\Psi_{recenter}^{k, d}&amp;lt;/math&amp;gt;,  будет определяться &amp;lt;i&amp;gt;параллельной сложностью вычисления одного центра масс кластера размера &amp;lt;math&amp;gt;m&amp;lt;/math&amp;gt;&amp;lt;/i&amp;gt;, &amp;lt;math&amp;gt;\Psi_{recenter}^{k, d}&amp;lt;/math&amp;gt;,  а так как &amp;lt;math&amp;gt;m \le n \Rightarrow \Psi_{recenter}^{d, m} \le \Psi_{recenter}^{d, n}&amp;lt;/math&amp;gt;. Сложность вычисления центра масс кластера d-мерных векторов размера n аналогично предыдущим вычислениям равна &amp;lt;math&amp;gt;O(log(n))&amp;lt;/math&amp;gt;. Тогда:  &lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p align=&amp;quot;center&amp;quot;&amp;gt;&amp;lt;math&amp;gt;\Psi_{recenter}^{k, d}  \le \Psi_{recenter}^{d, n} = O(log(n))&amp;lt;/math&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Общая параллельная сложность алгоритма&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
На каждой итерации необходимо обновление центров кластеров, которые будут использованы на следующей итерации. Таким образом, итерационный процесс выполняется последовательно&amp;lt;ref&amp;gt;Zhao, Weizhong, Huifang Ma, and Qing He. &amp;quot;Parallel k-means clustering based on mapreduce.&amp;quot; IEEE International Conference on Cloud Computing. Springer Berlin Heidelberg, 2009.&amp;lt;/ref&amp;gt;. Тогда, поскольку сложность каждой итерации  определяется &amp;lt;math&amp;gt;\Psi_{distribute}^{k, d}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\Psi_{recenter}&amp;lt;/math&amp;gt;, сложность всего алгоритма, &amp;lt;math&amp;gt;\Psi_{k-means}&amp;lt;/math&amp;gt; в предположении, что было сделано &amp;lt;math&amp;gt;\Tau&amp;lt;/math&amp;gt; операций определяется выражением&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p align=&amp;quot;center&amp;quot;&amp;gt;&amp;lt;math&amp;gt;\Psi_{k-means} \approx \Tau * (\Psi_{distribute}^{k, d} + \Psi_{recenter}^{k, d}) \le \Tau * O(log(k*d*n))&amp;lt;/math&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Входные и выходные данные алгоритма ===&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;Входные данные&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;Матрица из &amp;lt;math&amp;gt;n*d&amp;lt;/math&amp;gt; элементов &amp;lt;math&amp;gt;x_{i, j} \in \mathbb{R}, i=\overline{1, n}, j=\overline{1, d}&amp;lt;/math&amp;gt;&amp;amp;ndash; координат векторов (наблюдений).&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;Целое положительное число &amp;lt;math&amp;gt;k, k \le n&amp;lt;/math&amp;gt; &amp;amp;ndash; количество кластеров.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;Объем входных данных&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;math&amp;gt;1&amp;lt;/math&amp;gt; целое число + &amp;lt;math&amp;gt;n*d&amp;lt;/math&amp;gt; вещественных чисел (при условии, что координаты &amp;amp;ndash; вещественные числа).&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;Выходные данные&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; целых положительных чисел &amp;lt;math&amp;gt;L_1, ..., L_n&amp;lt;/math&amp;gt;&amp;amp;ndash; номера кластеров, соотвествующие каждому вектору (при условии, что нумерация кластеров начинается с &amp;lt;math&amp;gt;1&amp;lt;/math&amp;gt;).&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;Объем выходных данных&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; целых положительных чисел.&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Свойства алгоритма ===&lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;[[глоссарий#Вычислительная мощность|&#039;&#039;Вычислительная мощность&#039;&#039;]]&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
Вычислительная мощность алгоритма &amp;lt;i&amp;gt;k means&amp;lt;/i&amp;gt; равна &amp;lt;math&amp;gt;\frac{k*d*n*\Tau}{n*d} = k*\Tau &amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; &amp;amp;ndash; число кластеров, &amp;lt;math&amp;gt;\Tau&amp;lt;/math&amp;gt; &amp;amp;ndash; число итераций алгоритма.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;[[глоссарий#Детерминированность |&#039;&#039;Детерминированность&#039;&#039;]] и [[глоссарий#Устойчивость |&#039;&#039;Устойчивость&#039;&#039;]] &amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
Алгоритм &amp;lt;i&amp;gt;k means&amp;lt;/i&amp;gt; является итерационным. Количество итераций алгоритма в общем случае не фиксируется и зависит от начального расположения объектов в пространстве, параметра &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt;, а также от начального приближения центров кластеров, &amp;lt;math&amp;gt;\mu_1, ..., \mu_k&amp;lt;/math&amp;gt;. В результате этого может варьироваться результат работы алгоритма. При неудачном выборе начальных параметров итерационный процесс может сойтись к локальному оптимуму&amp;lt;ref&amp;gt;Von Luxburg, Ulrike. Clustering Stability. Now Publishers Inc, 2010.&amp;lt;/ref&amp;gt;. По этим причинам алгоритм не является ни &amp;lt;b&amp;gt;детермирированным&amp;lt;/b&amp;gt;, ни &amp;lt;b&amp;gt;устойчивым&amp;lt;/b&amp;gt;.&lt;br /&gt;
 &lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Соотношение последовательной и параллельной сложности алгоритма&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\frac{\Theta_{k-means}}{\Psi_{k-means}} = \frac{O(\Tau*k*d*n)}{O(\Tau*log(k*d*n))}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Сильные стороны алгоритма&amp;lt;/b&amp;gt;:&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;i&amp;gt;Сравнительно высокая эффективность при простоте реализации&amp;lt;/i&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;i&amp;gt;Высокое качество кластеризации&amp;lt;/i&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;i&amp;gt;Возможность распараллеливания&amp;lt;/i&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;i&amp;gt;Существование множества модификаций&amp;lt;/i&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;Недостатки алгоритма&amp;lt;/b&amp;gt;&amp;lt;ref&amp;gt;Ortega, Joaquín Pérez, Ma Del Rocío Boone Rojas, and María J. Somodevilla. &amp;quot;Research issues on K-means Algorithm: An Experimental Trial Using Matlab.&amp;quot;&amp;lt;/ref&amp;gt;:&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;i&amp;gt;Количество кластеров является параметром алгоритма&amp;lt;/i&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;&amp;lt;i&amp;gt;Чувствительность к начальным условиям&amp;lt;/i&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;Инициализация центров кластеров в значительной степени влияет на результат кластеризации.&amp;lt;/p&amp;gt;&lt;br /&gt;
  &amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;&amp;lt;i&amp;gt;Чувствительность к выбросам и шумам&amp;lt;/i&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;Выбросы, далекие от центров настоящих кластеров, все равно учитываются при вычислении их центров.&amp;lt;/p&amp;gt;&lt;br /&gt;
  &amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;&amp;lt;i&amp;gt;Возможность сходимости к локальному оптимуму&amp;lt;/i&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;Итеративный подход не дает гарантии сходимости к оптимальному решению.&amp;lt;/p&amp;gt;&lt;br /&gt;
  &amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;&amp;lt;i&amp;gt;Использование понятия &amp;quot;среднего&amp;quot;&amp;lt;/i&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;Алгоритм неприменим к данным, для которых не определено понятие &amp;quot;среднего&amp;quot;, например, категориальным данным.&amp;lt;/p&amp;gt;&lt;br /&gt;
  &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&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;
Исследование масштабируемости параллельной реализации алгоритма k means проводилось на суперкомпьютере &amp;quot;Ломоносов&amp;quot;. Алгоритм реализован на языке C с использованием средств MPI.&lt;br /&gt;
Для исследования масштабируемости проводилось множество запусков программы с разным значением параметра (количество векторов для кластеризации), а также с различным числом процессоров. Фиксировались результаты запусков &amp;amp;ndash; время работы &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt; и количество произведенных итераций алгоритма &amp;lt;math&amp;gt;\Tau&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Параметры запусков для экспериментальной оценки:&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;Значения &amp;lt;b&amp;gt;количества векторов&amp;lt;/b&amp;gt; &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;: 20&#039;000, 30&#039;000, 50&#039;000, 100&#039;000, 200&#039;000, 300&#039;000, 500&#039;000, 700&#039;000, 1&#039;000&#039;000, 1&#039;500&#039;000, 2&#039;000&#039;000.&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;Значения &amp;lt;b&amp;gt;количества процессоров&amp;lt;/b&amp;gt; &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt;: 1, 8, 16, 32, 64, 128, 160, 192, 224, 256, 288, 320, 352, 384, 416, 448, 480, 512.&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;Значение &amp;lt;b&amp;gt;количества кластеров&amp;lt;/b&amp;gt; &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt;: 100.&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;Значение &amp;lt;b&amp;gt;размерности векторов&amp;lt;/b&amp;gt; &amp;lt;math&amp;gt;d&amp;lt;/math&amp;gt;: 10.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Графики производительности и эффективности реализации представлены на рисунках 4 и 5 соответственно.&lt;br /&gt;
&lt;br /&gt;
[[file:Flops.png|thumb|center|800px|Рис. 4. График производительности реализации алгоритма.]]&lt;br /&gt;
&lt;br /&gt;
[[file:Efficiency.png|thumb|center|800px|Рис. 5. График эффективности реализации алгоритма.]]&lt;br /&gt;
&lt;br /&gt;
Для заданной конфигурации эксперимента (&amp;lt;math&amp;gt;n, d, p, k&amp;lt;/math&amp;gt;) и полученных результатах (&amp;lt;math&amp;gt;t, \Tau&amp;lt;/math&amp;gt;) производительность и эффективность реализации расчитывались по формулам (см. [[#Последовательная сложность алгоритма| последовательная сложность алгоритма]]):&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
&amp;lt;ul&amp;gt;&amp;lt;li&amp;gt;&amp;lt;math&amp;gt;Performance = \frac{\Theta_{k-means}^{d, n}}{t}\ \ FLOPS&amp;lt;/math&amp;gt;&amp;lt;/li&amp;gt;&amp;lt;/ul&amp;gt;&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
&amp;lt;ul&amp;gt;&amp;lt;li&amp;gt;&amp;lt;math&amp;gt;Efficiency = \frac{100 * Performance}{Performance_{Peak}^{p}}\ \ %,&amp;lt;/math&amp;gt;&amp;lt;/li&amp;gt;&amp;lt;/ul&amp;gt;&lt;br /&gt;
где &amp;lt;math&amp;gt;Performance_{Peak}^{p}&amp;lt;/math&amp;gt; &amp;amp;ndash; пиковая производительность суперкомпьютера при &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt; процессорах, вычисленная согласно спецификациям Intel&amp;lt;sup&amp;gt;&amp;amp;reg;&amp;lt;/sup&amp;gt; XEON&amp;lt;sup&amp;gt;&amp;amp;reg;&amp;lt;/sup&amp;gt; X5670&amp;lt;ref&amp;gt;&amp;quot;http://ark.intel.com/ru/products/47920/Intel-Xeon-Processor-X5670-12M-Cache-2_93-GHz-6_40-GTs-Intel-QPI&amp;quot;&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;В результате&amp;lt;/b&amp;gt; экспериментальной оценки были получены следующие оценки эффективности реализации:&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;b&amp;gt;Минимальное&amp;lt;/b&amp;gt; значение: 0.000409 % достигается при &amp;lt;math&amp;gt;n=20&#039;000, p=480&amp;lt;/math&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;b&amp;gt;Максимальное&amp;lt;/b&amp;gt; значение: 0.741119 % достигается при &amp;lt;math&amp;gt;n=300&#039;000, p=1&amp;lt;/math&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
Оценки масштабируемости реализации алгоритма k means:&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;b&amp;gt;По числу процессоров:&amp;lt;/b&amp;gt; -0.002683 &amp;amp;ndash; эффективность убывает с ростом числа процессоров.&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;b&amp;gt;По размеру задачи:&amp;lt;/b&amp;gt; 0.002779 &amp;amp;ndash; эффективность растет с ростом числа векторов.&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;b&amp;gt;Общая оценка:&amp;lt;/b&amp;gt; -0.000058 &amp;amp;ndash; можно сделать вывод, что в целом эффективность реализации незначительно уменьшается.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Динамические характеристики и эффективность реализации алгоритма ===&lt;br /&gt;
=== Выводы для классов архитектур ===&lt;br /&gt;
=== Существующие реализации алгоритма ===&lt;br /&gt;
==== Открытое программное обеспечение ====&lt;br /&gt;
&amp;lt;ol&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;[https://www.icpsr.umich.edu/CrimeStat/ CrimeStat]&amp;lt;/li&amp;gt; Программное обеспечение, созданное для операционных систем Windows, предоставляющее инструменты статистического  и пространственного анализа для решения задачи картирования преступности.&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://juliastats.github.io Julia]&amp;lt;/li&amp;gt; Высокоуровневый высокопроизводительный свободный язык программирования с динамической типизацией, созданный для математических вычислений, содержит реализацию k-means.&lt;br /&gt;
  &amp;lt;li&amp;gt;[https://mahout.apache.org Mahout]&amp;lt;/li&amp;gt; Apache Mahout - Java библиотека для работы с алгоритмами машинного обучения с использованием MapReduce. Содержит реализацию k-means.&lt;br /&gt;
  &amp;lt;li&amp;gt;[https://www.gnu.org/software/octave/ Octave]&amp;lt;/li&amp;gt; Написанная на C++  свободная система для математических вычислений, использующая совместимый с MATLAB язык высокого уровня, содержит реализацию k-means.&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://spark.apache.org/docs/latest/mllib-clustering.html Spark]&amp;lt;/li&amp;gt; Распределенная реализация k-means содержится в библиотеке Mlib для работы с алгоритмами машинного обучения, взаимодействующая с Python библиотекой NumPy и библиотека R.&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://torch.ch Torch]&amp;lt;/li&amp;gt;  MATLAB-подобная библиотека для языка программирования Lua с открытым исходным кодом, предоставляет большое количество алгоритмов для глубинного обучения и научных расчётов. Ядро написано на Си, прикладная часть выполняется на LuaJIT, поддерживается распараллеливание вычислений средствами CUDA и OpenMP. Существуют реализации k-means.&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://www.cs.waikato.ac.nz/ml/weka/ Weka]&amp;lt;/li&amp;gt;  Cвободное программное обеспечение для анализа данных, написанное на Java. Содержит k-means и x-means.&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://accord-framework.net/docs/html/T_Accord_MachineLearning_KMeans.htm Accord.NET]&amp;lt;/li&amp;gt; C# реализация алгоритмов k-means, k-means++, k-modes.&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://docs.opencv.org/3.0-beta/doc/py_tutorials/py_ml/py_kmeans/py_kmeans_opencv/py_kmeans_opencv.html OpenCV]&amp;lt;/li&amp;gt; Написанная на С++ библиотека, направленная в основном на решение задач компьютерного зрения. Содержит реализацию k-means.&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://mlpack.org/ MLPACK]&amp;lt;/li&amp;gt; Масштабируемая С++ библиотека для работы с алгоритмами машинного обучения, содержит реализацию k-means.&lt;br /&gt;
  &amp;lt;li&amp;gt;[https://www.scipy.org/ SciPy]&amp;lt;/li&amp;gt; Библиотека Python, содержит множество реализаций k-means.&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://scikit-learn.org/ scikit-learn]&amp;lt;/li&amp;gt; Библиотека Python, содержит множество реализаций k-means.&lt;br /&gt;
  &amp;lt;li&amp;gt;[https://www.r-bloggers.com/k-means-clustering-in-r/ R]&amp;lt;/li&amp;gt; Язык программирования для статистической обработки данных и работы с графикой, а также свободная программная среда вычислений с открытым исходным кодом в рамках проекта GNU, содержит три реализации k-means.&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://elki.dbs.ifi.lmu.de ELKI]&amp;lt;/li&amp;gt; Java фреймворк, содержащий реализацию k-means, а также множество других алгоритмов кластеризации.&lt;br /&gt;
&amp;lt;/ol&amp;gt;&lt;br /&gt;
==== Проприетарное программное обеспечение  ====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ol&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;[https://www.ayasdi.com/blog/bigdata/topological-data-analysis-of-oil-and-gas-petrophysical-data/ Ayasdi]&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://www.stata.com/features/cluster-analysis/ Stata]&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://mathworld.wolfram.com/K-MeansClusteringAlgorithm.html Mathematica]&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://www.mathworks.com/help/stats/kmeans.html?requestedDomain=www.mathworks.com MATLAB]&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;[https://support.sas.com/rnd/app/stat/procedures/fastclus.html SAS]&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://docs.rapidminer.com/studio/operators/modeling/segmentation/k_means.html RapidMiner]&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;[https://blogs.sap.com/2013/03/28/sap-hana-pal-k-means-algorithm-or-how-to-do-customer-segmentation-for-the-telecommunications-industry/ SAP HANA]&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ol&amp;gt;&lt;br /&gt;
== Литература ==&lt;br /&gt;
&amp;lt;references /&amp;gt;&lt;/div&gt;</summary>
		<author><name>DennZo1993</name></author>
	</entry>
	<entry>
		<id>https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:%D0%91%D1%80%D0%BE%D1%82%D0%B8%D0%BA%D0%BE%D0%B2%D1%81%D0%BA%D0%B0%D1%8F_%D0%94%D0%B0%D0%BD%D1%83%D1%82%D0%B0/%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_k-means&amp;diff=17182</id>
		<title>Участник:Бротиковская Данута/Алгоритм k-means</title>
		<link rel="alternate" type="text/html" href="https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:%D0%91%D1%80%D0%BE%D1%82%D0%B8%D0%BA%D0%BE%D0%B2%D1%81%D0%BA%D0%B0%D1%8F_%D0%94%D0%B0%D0%BD%D1%83%D1%82%D0%B0/%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_k-means&amp;diff=17182"/>
		<updated>2016-11-15T01:42:53Z</updated>

		<summary type="html">&lt;p&gt;DennZo1993: /* Масштабируемость реализации алгоритма */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt; {{Assignment|Zhum}}&lt;br /&gt;
&lt;br /&gt;
{{algorithm&lt;br /&gt;
| name              = Алгоритм k средних (k means)&lt;br /&gt;
| serial_complexity = &amp;lt;math&amp;gt;O(\Tau*k*d*n)&amp;lt;/math&amp;gt;&lt;br /&gt;
| input_data        = &amp;lt;math&amp;gt; d*n &amp;lt;/math&amp;gt;&lt;br /&gt;
| output_data       = &amp;lt;math&amp;gt; n &amp;lt;/math&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
Авторы страницы &amp;lt;b&amp;gt;[[Участник:Бротиковская Данута|Данута Бротиковская]]&amp;lt;/b&amp;gt; и &amp;lt;b&amp;gt;[[Участник:DennZo1993|Денис Зобнин]]&amp;lt;/b&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
Оба автора внесли одинаковый вклад в написание статьи (поиск материалов, изучение статей, заполнение контента статьи), четких разграничений по пунктам статьи сделать невозможно. &lt;br /&gt;
&lt;br /&gt;
== Свойства и структура алгоритма ==&lt;br /&gt;
&lt;br /&gt;
=== Общее описание алгоритма ===&lt;br /&gt;
Алгоритм &amp;lt;b&amp;gt;&amp;lt;i&amp;gt;k средних&amp;lt;/i&amp;gt;&amp;lt;/b&amp;gt; (&amp;lt;b&amp;gt;&amp;lt;i&amp;gt;k means&amp;lt;/i&amp;gt;&amp;lt;/b&amp;gt;) &amp;amp;ndash; неиерархический&amp;lt;ref&amp;gt;&amp;quot;https://ru.wikipedia.org/wiki/Иерархическая_кластеризация&amp;quot;&amp;lt;/ref&amp;gt;, итерационный метод кластеризации&amp;lt;ref&amp;gt;&amp;quot;https://ru.wikipedia.org/wiki/Кластерный_анализ&amp;quot;&amp;lt;/ref&amp;gt;, получивший большую популярность благодаря своей простоте, наглядности реализации и достаточно высокому качеству работы. Был изобретен в 1950-х годах математиком &amp;lt;i&amp;gt;Гуго Штейнгаузом&amp;lt;/i&amp;gt;&amp;lt;ref&amp;gt;Steinhaus, Hugo. &amp;quot;Sur la division des corp materiels en parties.&amp;quot; Bull. Acad. Polon. Sci 1.804 (1956): 801.&amp;lt;/ref&amp;gt; и почти одновременно &amp;lt;i&amp;gt;Стюартом Ллойдом&amp;lt;/i&amp;gt;&amp;lt;ref&amp;gt;Lloyd, S. P. &amp;quot;Least square quantization in PCM. Bell Telephone Laboratories Paper. Published in journal much later: Lloyd, SP: Least squares quantization in PCM.&amp;quot; IEEE Trans. Inform. Theor.(1957/1982).&amp;lt;/ref&amp;gt;. Особую популярность приобрел после публикации работы &amp;lt;i&amp;gt;МакКуина&amp;lt;/i&amp;gt;&amp;lt;ref&amp;gt;MacQueen, James. &amp;quot;Some methods for classification and analysis of multivariate observations.&amp;quot; Proceedings of the fifth Berkeley symposium on mathematical statistics and probability. Vol. 1. No. 14. 1967.&amp;lt;/ref&amp;gt; в 1967.&lt;br /&gt;
&lt;br /&gt;
Алгоритм представляет собой версию EM-алгоритма&amp;lt;ref&amp;gt;&amp;quot;https://ru.wikipedia.org/wiki/EM-алгоритм&amp;quot;&amp;lt;/ref&amp;gt;, применяемого также для разделения смеси гауссиан. Основная идея &amp;lt;i&amp;gt;k means&amp;lt;/i&amp;gt; заключается в том, что данные произвольно разбиваются на кластеры, после чего итеративно перевычисляется центр масс для каждого кластера, полученного на предыдущем шаге, затем векторы разбиваются на кластеры вновь в соответствии с тем, какой из новых центров оказался ближе по выбранной метрике.&lt;br /&gt;
&lt;br /&gt;
Цель алгоритма заключается в разделении &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; наблюдений на &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластеров таким образом, чтобы каждое наблюдение принадлежало ровно одному кластеру, расположенному на наименьшем расстоянии от наблюдения.&lt;br /&gt;
&lt;br /&gt;
=== Математическое описание алгоритма ===&lt;br /&gt;
&amp;lt;b&amp;gt;&amp;lt;u&amp;gt;Дано:&amp;lt;/u&amp;gt;&amp;lt;/b&amp;gt;&lt;br /&gt;
* набор из &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; наблюдений &amp;lt;math&amp;gt;X=\{\mathbf{x}_1, \mathbf{x}_2, ..., \mathbf{x}_n\}, \mathbf{x}_i \in \mathbb{R}^d, i=\overline{1, n}&amp;lt;/math&amp;gt;;&lt;br /&gt;
* &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; - требуемое число кластеров, &amp;lt;math&amp;gt;k \in \mathbb{N}, k \leq n&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;&amp;lt;u&amp;gt;Требуется:&amp;lt;/u&amp;gt;&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Разделить множество наблюдений &amp;lt;math&amp;gt;X&amp;lt;/math&amp;gt; на &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластеров &amp;lt;math&amp;gt;S_1, S_2, ..., S_k&amp;lt;/math&amp;gt;:&lt;br /&gt;
*   &amp;lt;math&amp;gt;S_i \cap S_j= \varnothing, \quad i \ne j&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
*   &amp;lt;math&amp;gt;\bigcup_{i=1}^{k} S_i = X&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;&amp;lt;u&amp;gt;Действие алгоритма:&amp;lt;/u&amp;gt;&amp;lt;/b&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;Алгоритм &amp;lt;i&amp;gt;k means&amp;lt;/i&amp;gt; разбивает набор &amp;lt;math&amp;gt;X&amp;lt;/math&amp;gt; на &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; наборов &amp;lt;math&amp;gt;S_1, S_2, ..., S_k,&amp;lt;/math&amp;gt; таким образом, чтобы минимизировать сумму квадратов расстояний от каждой точки кластера до его центра (центр масс кластера). Введем обозначение, &amp;lt;math&amp;gt;S=\{S_1, S_2, ..., S_k\}&amp;lt;/math&amp;gt;. Тогда действие алгоритма &amp;lt;i&amp;gt;k means&amp;lt;/i&amp;gt; равносильно поиску:&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;table style=&amp;quot;width:100%&amp;quot;&amp;gt;&lt;br /&gt;
  &amp;lt;tr&amp;gt;&lt;br /&gt;
    &amp;lt;td align=&amp;quot;center&amp;quot; width=&amp;quot;90%&amp;quot;&amp;gt;&amp;lt;math&amp;gt;\arg\min_{S} \sum\limits_{i=1}^k \sum\limits_{\mathbf{x} \in S_i} \rho(\mathbf{x}, \mathbf{\mu}_i )^2,&amp;lt;/math&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;td align=&amp;quot;right&amp;quot;&amp;gt;&amp;lt;math&amp;gt;(1)&amp;lt;/math&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;/table&amp;gt;&lt;br /&gt;
где &amp;lt;math&amp;gt;\mathbf{\mu}_i&amp;lt;/math&amp;gt; &amp;amp;ndash; центры кластеров, &amp;lt;math&amp;gt;i=\overline{1,k}, \quad \rho(\mathbf{x}, \mathbf{\mu}_i)&amp;lt;/math&amp;gt; &amp;amp;ndash; функция расстояния между &amp;lt;math&amp;gt;\mathbf{x}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\mu_i&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;&amp;lt;u&amp;gt;Шаги алгоритма: &amp;lt;/u&amp;gt;&amp;lt;/b&amp;gt;&lt;br /&gt;
&amp;lt;ol&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&lt;br /&gt;
    &amp;lt;b&amp;gt;Начальный шаг: инициализация кластеров&amp;lt;/b&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;Выбирается произвольное множество точек &amp;lt;math&amp;gt;\mu_i, i=\overline{1,k}&amp;lt;/math&amp;gt;, рассматриваемых как начальные центры кластеров: &amp;lt;math&amp;gt;\mu_i^{(0)} = \mu_i, \quad i=\overline{1, k}&amp;lt;/math&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
  &amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&lt;br /&gt;
    &amp;lt;b&amp;gt;Распределение векторов по кластерам&amp;lt;/b&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Шаг&amp;lt;/b&amp;gt; &amp;lt;math&amp;gt;t: \forall \mathbf{x}_i \in X, i=\overline{1,n}: \mathbf{x}_i \in S_j \iff  j=\arg\min_{k}\rho(\mathbf{x}_i,\mathbf{\mu}_k^{(t-1)})^2&amp;lt;/math&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
  &amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&lt;br /&gt;
    &amp;lt;b&amp;gt;Пересчет центров кластеров&amp;lt;/b&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Шаг &amp;lt;/b&amp;gt; &amp;lt;math&amp;gt;t: \forall i=\overline{1,k}:  \mu_i^{(t)} = \cfrac{1}{|S_i|}\sum_{\mathbf{x}\in S_i}\mathbf{x}&amp;lt;/math&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
  &amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&lt;br /&gt;
    &amp;lt;b&amp;gt;Проверка условия останова:&amp;lt;/b&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
    &#039;&#039;&#039;if&#039;&#039;&#039; &amp;lt;math&amp;gt;\exist i\in \overline{1,k}: \mu_i^{(t)} \ne \mu_i^{(t-1)}&amp;lt;/math&amp;gt; &#039;&#039;&#039;then&#039;&#039;&#039;&lt;br /&gt;
        t = t + 1;&lt;br /&gt;
        goto 2;&lt;br /&gt;
    &#039;&#039;&#039;else&#039;&#039;&#039;&lt;br /&gt;
        &#039;&#039;&#039;stop&#039;&#039;&#039;&lt;br /&gt;
  &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ol&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Вычислительное ядро алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Вычислительным ядром являются шаги 2 и 3 приведенного выше алгоритма: &amp;lt;b&amp;gt;&amp;lt;i&amp;gt;распределение векторов по кластерам&amp;lt;/i&amp;gt;&amp;lt;/b&amp;gt; и &amp;lt;b&amp;gt;&amp;lt;i&amp;gt;пересчет центров кластеров&amp;lt;/i&amp;gt;&amp;lt;/b&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;&amp;lt;i&amp;gt;Распределение векторов&amp;lt;/i&amp;gt;&amp;lt;/b&amp;gt; по кластерам предполагает вычисление расстояний между каждым вектором &amp;lt;math&amp;gt;\mathbf{x}_i \in X, i= \overline{1,n}&amp;lt;/math&amp;gt; и центрами кластера &amp;lt;math&amp;gt;\mathbf{\mu}_j, j= \overline{1,k}&amp;lt;/math&amp;gt;. Таким образом, данный шаг предполагает &amp;lt;math&amp;gt;k*n&amp;lt;/math&amp;gt; вычислений расстояний между d-мерными векторами. &lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;&amp;lt;i&amp;gt;Пересчет центров кластеров&amp;lt;/i&amp;gt;&amp;lt;/b&amp;gt; предполагает &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; вычислений центров масс &amp;lt;math&amp;gt;\mathbf{\mu}_i&amp;lt;/math&amp;gt; множеств &amp;lt;math&amp;gt;S_i, i=\overline{1,k}&amp;lt;/math&amp;gt; представленных выражением в шаге 3 представленного выше алгоритма.&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Макроструктура алгоритма ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Инициализация центров масс &amp;lt;math&amp;gt;\mu_1, ..., \mu_k&amp;lt;/math&amp;gt;&amp;lt;/b&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
Наиболее распространенными являются следующие стратегии:&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&lt;br /&gt;
    &amp;lt;b&amp;gt;Метод Forgy&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;В качестве начальных значений &amp;lt;math&amp;gt;\mu_1, ..., \mu_k&amp;lt;/math&amp;gt; берутся случайно выбранные векторы.&lt;br /&gt;
  &amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&lt;br /&gt;
    &amp;lt;b&amp;gt;Метод случайно разделения (Random Partitioning)&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;Для каждого вектора &amp;lt;math&amp;gt;\mathbf{x}_i \in X, i=\overline{1, n}&amp;lt;/math&amp;gt; выбирается случайным образом кластер &amp;lt;math&amp;gt;S_1, ..., S_k&amp;lt;/math&amp;gt;, после чего для каждого полученного кластера вычисляются значения &amp;lt;math&amp;gt;\mu_1, ..., \mu_k&amp;lt;/math&amp;gt;.&lt;br /&gt;
  &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Распределение векторов по кластерам&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Для этого шага алгоритма между векторами &amp;lt;math&amp;gt;\mathbf{x}_i \in X, i=\overline{1, n}&amp;lt;/math&amp;gt; и центрами кластеров &amp;lt;math&amp;gt;\mu_1, ..., \mu_k&amp;lt;/math&amp;gt; вычисляются &amp;lt;b&amp;gt;расстояния&amp;lt;/b&amp;gt; по формуле (как правило, используется Евлидово расстояние):&lt;br /&gt;
&amp;lt;table style=&amp;quot;width:100%&amp;quot;&amp;gt;&lt;br /&gt;
  &amp;lt;tr&amp;gt;&lt;br /&gt;
    &amp;lt;td align=&amp;quot;center&amp;quot; width=&amp;quot;90%&amp;quot;&amp;gt;&amp;lt;math&amp;gt; \mathbf{v}_1, \mathbf{v}_2 \in \mathbb{R}^d,  \quad \rho(\mathbf{v}_1, \mathbf{v}_2) = \lVert \mathbf{v}_1- \mathbf{v}_2 \rVert= \sqrt{\sum_{i=1}^{d}(\mathbf{v}_{1,i} - \mathbf{v}_{2,i})^2}&amp;lt;/math&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;td align=&amp;quot;right&amp;quot;&amp;gt;&amp;lt;math&amp;gt;(2)&amp;lt;/math&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;/table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Пересчет центров кластеров&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Для этого шага алгоритма производится пересчет центров кластера по &amp;lt;b&amp;gt;формуле вычисления центра масс&amp;lt;/b&amp;gt;:&lt;br /&gt;
&amp;lt;table style=&amp;quot;width:100%&amp;quot;&amp;gt;&lt;br /&gt;
  &amp;lt;tr&amp;gt;&lt;br /&gt;
    &amp;lt;td align=&amp;quot;center&amp;quot; width=&amp;quot;90%&amp;quot;&amp;gt;&amp;lt;math&amp;gt; \mu = \cfrac{1}{|S|}\sum_{\mathbf{x}\in S}\mathbf{x}&amp;lt;/math&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;td align=&amp;quot;right&amp;quot;&amp;gt;&amp;lt;math&amp;gt;(3)&amp;lt;/math&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;/table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Схема реализации последовательного алгоритма ===&lt;br /&gt;
&lt;br /&gt;
 &#039;&#039;&#039;algorithm&#039;&#039;&#039; k-means &#039;&#039;&#039;is&#039;&#039;&#039;&lt;br /&gt;
     &#039;&#039;&#039;1.&#039;&#039;&#039; Инициализировать центры кластеров &amp;lt;math&amp;gt;\mathbf{\mu}_i^{(1)}, i=\overline{1,k}&amp;lt;/math&amp;gt;&lt;br /&gt;
     &#039;&#039;&#039;2.&#039;&#039;&#039; &amp;lt;math&amp;gt;t \leftarrow 1&amp;lt;/math&amp;gt;&lt;br /&gt;
     &#039;&#039;&#039;3.&#039;&#039;&#039; &#039;&#039;&#039;Распределение по кластерам&#039;&#039;&#039;&amp;lt;br&amp;gt;&lt;br /&gt;
        &amp;lt;math&amp;gt;S_i^{(t)}=\{\mathbf{x}_p: \lVert\mathbf{x}_p-\mathbf{\mu}_i^{(t)}\rVert^2 \leq \lVert\mathbf{x}_p-\mathbf{\mu}_j^{(t)}\rVert^2 \quad \forall j=\overline{1,k}\},&amp;lt;/math&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
        где каждый вектор &amp;lt;math&amp;gt;\mathbf{x}_p&amp;lt;/math&amp;gt; соотносится единственному кластеру &amp;lt;math&amp;gt;S^{(t)}&amp;lt;/math&amp;gt;&lt;br /&gt;
     &#039;&#039;&#039;4.&#039;&#039;&#039; &#039;&#039;&#039;Обновление центров кластеров&#039;&#039;&#039;&amp;lt;br&amp;gt;&lt;br /&gt;
        &amp;lt;math&amp;gt;\mathbf{\mu}_i^{(t+1)} = \frac{1}{|S^{(t)}_i|} \sum_{\mathbf{x}_j \in S^{(t)}_i} \mathbf{x}_j &amp;lt;/math&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
     &#039;&#039;&#039;5.&#039;&#039;&#039; &#039;&#039;&#039;if&#039;&#039;&#039; &amp;lt;math&amp;gt;\exist i \in \overline{1,k}: \mathbf{\mu}_i^{(t+1)} \ne \mathbf{\mu}_i^{(t)}&amp;lt;/math&amp;gt; &#039;&#039;&#039;then&#039;&#039;&#039;&lt;br /&gt;
            t = t + 1;&lt;br /&gt;
            goto &#039;&#039;&#039;3&#039;&#039;&#039;;&lt;br /&gt;
        &#039;&#039;&#039;else&#039;&#039;&#039;&lt;br /&gt;
            &#039;&#039;&#039;stop&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
=== Последовательная сложность алгоритма===&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding-bottom: 20px&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;Обозначим &amp;lt;math&amp;gt;\Theta_{centroid}^{d, m}&amp;lt;/math&amp;gt; временную сложность вычисления центорида кластера, число элементов которого равна &amp;lt;math&amp;gt;m&amp;lt;/math&amp;gt;,  в d-мерном пространстве.&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;Аналогично  &amp;lt;math&amp;gt;\Theta_{distance}^d&amp;lt;/math&amp;gt; &amp;amp;ndash; временная сложность вычисления расстояния между двумя d-мерными векторами.&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding-bottom: 20px&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;Сложность шага инициализации &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластеров мощности &amp;lt;math&amp;gt;m&amp;lt;/math&amp;gt; в d-мерном пространстве &amp;amp;ndash; &amp;lt;math&amp;gt;\Theta_{init}^{k, d, m}&amp;lt;/math&amp;gt;&amp;lt;/b&amp;gt;&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;i&amp;gt;Стратерия Forgy&amp;lt;/i&amp;gt;: вычисления не требуются, &amp;lt;math&amp;gt;\Theta_{init}^{k, d, m} = 0&amp;lt;/math&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;i&amp;gt;Стратегия случайного разбиения&amp;lt;/i&amp;gt;: вычисление центров &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластеров,  &amp;lt;math&amp;gt;\Theta_{init}^{k, d, m} = k*\Theta_{centroid}^{d, m}, m \le n&amp;lt;/math&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding-bottom: 20px&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Cложность шага распределения d мерных векторов по &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластерам &amp;amp;ndash; &amp;lt;math&amp;gt;\Theta_{distribute}^{k, d}&amp;lt;/math&amp;gt;&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
На этом шаге для каждого вектора &amp;lt;math&amp;gt;\mathbf{x}_i \in X, i=\overline{1, n}&amp;lt;/math&amp;gt; вычисляется k расстояний до центров кластеров &amp;lt;math&amp;gt;\mathbf{\mu}_1, ...\mathbf{\mu}_k&amp;lt;/math&amp;gt;&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p align=&amp;quot;center&amp;quot;&amp;gt;&lt;br /&gt;
  &amp;lt;math&amp;gt;\Theta_{distribute}^{k, d} = n*k*\Theta_{distance}^d&amp;lt;/math&amp;gt;&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding-bottom: 20px&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;Сложность шага пересчета центров &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластеров размера &amp;lt;math&amp;gt;m&amp;lt;/math&amp;gt; в d-мерном пространстве &amp;amp;ndash; &amp;lt;math&amp;gt;\Theta_{recenter}^{k, d, m}&amp;lt;/math&amp;gt;&amp;lt;/b&amp;gt;&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;На этом шаге вычисляется &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; центров кластеров &amp;lt;math&amp;gt;\mathbf{\mu}_1, ...\mathbf{\mu}_k&amp;lt;/math&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p align=&amp;quot;center&amp;quot;&amp;gt;&amp;lt;math&amp;gt;\Theta_{recenter}^{k, d, m} = k*\Theta_{centroid}^{d, m}&amp;lt;/math&amp;gt; &amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding-bottom: 20px&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Рассчитаем &amp;lt;math&amp;gt;\Theta_{centroid}^{d, m}&amp;lt;/math&amp;gt; для кластера, число элементов которого равно &amp;lt;math&amp;gt;m&amp;lt;/math&amp;gt;&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p align=&amp;quot;center&amp;quot;&amp;gt;&amp;lt;math&amp;gt;\Theta_{centroid}^{d, m}&amp;lt;/math&amp;gt; = &amp;lt;math&amp;gt;m * d&amp;lt;/math&amp;gt; сложений + &amp;lt;math&amp;gt;d&amp;lt;/math&amp;gt; делений &amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding-bottom: 20px&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Рассчитаем &amp;lt;math&amp;gt;\Theta_{distance}^d&amp;lt;/math&amp;gt; в соответствие с формулой &amp;lt;math&amp;gt;(2)&amp;lt;/math&amp;gt;&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p align=&amp;quot;center&amp;quot;&amp;gt;&amp;lt;math&amp;gt;\Theta_{distance}^d&amp;lt;/math&amp;gt; = &amp;lt;math&amp;gt;d&amp;lt;/math&amp;gt; вычитаний + &amp;lt;math&amp;gt;d&amp;lt;/math&amp;gt; умножений + &amp;lt;math&amp;gt;(d-1)&amp;lt;/math&amp;gt; сложение&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding-bottom: 20px&amp;quot;&amp;gt;&lt;br /&gt;
  &amp;lt;p&amp;gt;Предположим, что алгоритм сошелся за &amp;lt;math&amp;gt;\Tau&amp;lt;/math&amp;gt; итераций, тогда временная сложность алгоритма &amp;lt;math&amp;gt;\Theta_{k-means}^{d, n}&amp;lt;/math&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
  &amp;lt;p align=&amp;quot;center&amp;quot;&amp;gt;&amp;lt;b&amp;gt;&amp;lt;math&amp;gt;\Theta_{k-means}^{d, n} \le \Theta_{init}^{k, d, n} + \Tau*(\Theta_{distribute}^{k, d} + \Theta_{recenter}^{k, d, n})&amp;lt;/math&amp;gt;&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding-bottom: 5px&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;Операции сложения/вычитания:&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p align=&amp;quot;center&amp;quot;&amp;gt;&amp;lt;b&amp;gt;&amp;lt;math&amp;gt;\Theta_{k-means}^{d, n} \le k*n*d+ \Tau*(k*n*(2d-1) + k*n*d) = k*n*d+ \Tau*(k*n*(3d-1)) \thicksim O(\Tau*k*d*n)&amp;lt;/math&amp;gt;&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding-bottom: 20px&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;Операции умножения/деления:&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p align=&amp;quot;center&amp;quot;&amp;gt;&amp;lt;b&amp;gt;&amp;lt;math&amp;gt;\Theta_{k-means}^{d, n} \le k*d + \Tau*(k*n*d + k*d) = k*d + \Tau * k*d*(n+1) \thicksim O(\Tau*k*d*n) &amp;lt;/math&amp;gt;&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding-bottom: 20px&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;Получаем, что &amp;lt;b&amp;gt;временная сложность&amp;lt;/b&amp;gt; алгоритма &amp;lt;b&amp;gt;k means&amp;lt;/b&amp;gt; кластеризации &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; &amp;lt;b&amp;gt;d-мерных&amp;lt;/b&amp;gt; векторов на &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластеров за &amp;lt;math&amp;gt;\Tau&amp;lt;/math&amp;gt; итераций:&amp;lt;/p&amp;gt;&lt;br /&gt;
 &amp;lt;p align=&amp;quot;center&amp;quot;&amp;gt;&amp;lt;b&amp;gt;&amp;lt;math&amp;gt; \Theta_{k-means}^{d, n} \thicksim O(\Tau*k*d*n) &amp;lt;/math&amp;gt;&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Информационный граф ===&lt;br /&gt;
&lt;br /&gt;
Рассмотрим информационный граф алгоритма. Алгоритм &amp;lt;i&amp;gt;k means&amp;lt;/i&amp;gt; начинается с этапа инициализации, после которого следуют итерации, на каждой из которых выполняется два последовательных шага (см. [[#Схема реализации последовательного алгоритма|&amp;quot;Схема реализации последовательного алгоритма&amp;quot;]]): &lt;br /&gt;
* распределение векторов по кластерам&lt;br /&gt;
* перерасчет центров кластеров&lt;br /&gt;
&lt;br /&gt;
Поскольку основная часть вычислений приходится на шаги итераций, распишем информационные графы данных шагов.&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Распределение векторов по кластерам&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
Информационный граф шага распределения векторов по кластерам представлен на &#039;&#039;рисунке 1&#039;&#039;. Исходами данного графа является исходные векторы &amp;lt;math&amp;gt;\mathbf{x}_1, ..., \mathbf{x}_n&amp;lt;/math&amp;gt;, а также центры кластеров &amp;lt;math&amp;gt;\mathbf{\mu}_1, ... \mathbf{\mu}_k&amp;lt;/math&amp;gt;, вычисленные ранее (на шаге инициализации, если рассматривается первая итерация алгоритма, или на шаге пересчета центров кластеров предыдущей итерации в противном случае). Каждая пара векторов данных &amp;lt;math&amp;gt;\mathbf{x}_i, i=\overline{1,n}&amp;lt;/math&amp;gt; и центров кластера &amp;lt;math&amp;gt;\mathbf{\mu}_j, j=\overline{1, k}&amp;lt;/math&amp;gt; : (&amp;lt;math&amp;gt;\mathbf{x}_i&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;\mathbf{\mu}_j&amp;lt;/math&amp;gt;) подаются на независимые узлы &amp;lt;i&amp;gt;&amp;quot;d&amp;quot;&amp;lt;/i&amp;gt; вычисления расстояния между векторами (более подробная схема вычисления расстояния представлена далее, &#039;&#039;рисунок 2&#039;&#039;). Далее узлы вычисления расстояния &amp;lt;i&amp;gt;&amp;quot;d&amp;quot;&amp;lt;/i&amp;gt;, соответствующие одному и тому же исходному вектору &amp;lt;math&amp;gt;\mathbf{x}_i&amp;lt;/math&amp;gt; передаются на один узел &amp;lt;i&amp;gt;&amp;quot;m&amp;quot;&amp;lt;/i&amp;gt;, где далее происходит вычисление новой метки кластера для каждого вектора &amp;lt;math&amp;gt;\mathbf{x}_i&amp;lt;/math&amp;gt; (берется кластер с минимальным результатом вычисления расстояния). На выходе графа выдаются метки кластеров , &amp;lt;math&amp;gt;L_1, ..., L_n&amp;lt;/math&amp;gt;, такие что &amp;lt;math&amp;gt;\forall \mathbf{x}_i, i=\overline{1, n}, \mathbf{x}_i \in S_j \Leftrightarrow L_i = j&amp;lt;/math&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
[[file:Clusterization.png|thumb|center|800px|Рис. 1. Схема распределения векторов по кластерам. &#039;&#039;d&#039;&#039; &amp;amp;ndash; вычисление расстояния между векторами; &#039;&#039;m&#039;&#039; &amp;amp;ndash; вычисление минимума.]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Вычисление расстояния между векторами&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
Подробная схема вычисления расстояния между векторами &amp;lt;math&amp;gt;\mathbf{x}_i, \mathbf{\mu}_j&amp;lt;/math&amp;gt; представлена на &#039;&#039;рисунке 2&#039;&#039;. Как показано на графе, узел вычисления расстояния между векторами &amp;lt;i&amp;gt;&amp;quot;d&amp;quot;&amp;lt;/i&amp;gt; состоит из шага взятия разности между векторами (узел &amp;quot;&amp;lt;math&amp;gt;-&amp;lt;/math&amp;gt;&amp;quot;) и взятия нормы получившегося вектора разности (узел &amp;quot;&amp;lt;math&amp;gt;||\cdot||^2&amp;lt;/math&amp;gt;&amp;quot;). Более подробно, вычисление расстояния между векторами &amp;lt;math&amp;gt;\mathbf{x}_i = {x_{i1,}, ...,{x_{in}}}, \mathbf{\mu}_j = {\mu_{j1}, ...,\mu_{jn}}&amp;lt;/math&amp;gt; может быть представлено как вычисление разности между каждой парой компонент &amp;lt;math&amp;gt;(x_{iz}, \mu_{jz}), z=\overline{1, d}&amp;lt;/math&amp;gt; (узел &amp;quot;&amp;lt;math&amp;gt;-&amp;lt;/math&amp;gt;&amp;quot;), далее возведение в квадрат для каждого узла &amp;quot;&amp;lt;math&amp;gt;-&amp;lt;/math&amp;gt;&amp;quot; (узел &amp;quot;&amp;lt;math&amp;gt;()^2&amp;lt;/math&amp;gt;&amp;quot;) и суммирования выходов всех узлов &amp;quot;&amp;lt;math&amp;gt;()^2&amp;lt;/math&amp;gt;&amp;quot; (узел &amp;quot;&amp;lt;math&amp;gt;+&amp;lt;/math&amp;gt;&amp;quot;).  &lt;br /&gt;
&lt;br /&gt;
[[file:dist_calc.png|thumb|center|800px|Рис. 2. Схема вычисления расстояния между вектором и центром кластера.]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Пересчет центров кластеров&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
Информационный граф шага пересчета центров кластеров представлен на &#039;&#039;рисунке 3&#039;&#039;. Исходами данного графа является исходные векторы &amp;lt;math&amp;gt;\mathbf{x}_1, ..., \mathbf{x}_n&amp;lt;/math&amp;gt;, а также им соответствующие метки кластера, &amp;lt;math&amp;gt;L_1, ..., L_n&amp;lt;/math&amp;gt;, такие что &amp;lt;math&amp;gt;\forall x_i, i=\overline{1, n}, \mathbf{x}_i \in S_j \Leftrightarrow L_i = j&amp;lt;/math&amp;gt;, вычисленные на этапе распределения векторов по кластерам. Все векторы &amp;lt;math&amp;gt;\mathbf{x}_1, ..., \mathbf{x}_n&amp;lt;/math&amp;gt; подаются в узлы &amp;lt;math&amp;gt;+_1, ...+_k&amp;lt;/math&amp;gt;, каждый узел &amp;lt;math&amp;gt;+_m, m = \overline{1,k}&amp;lt;/math&amp;gt; соответствует операции сложения векторов кластера с номером &amp;lt;math&amp;gt;m&amp;lt;/math&amp;gt;. Метки кластера &amp;lt;math&amp;gt;L_1, ..., L_n&amp;lt;/math&amp;gt; также совместно передаются на узлы &amp;lt;math&amp;gt;S_m, m = \overline{1,k}&amp;lt;/math&amp;gt;, на каждом из которых вычисляется количество векторов в соответствующем кластере (количество меток с соответствующим значением). Далее каждая пара выходов узлов &amp;lt;math&amp;gt;+_m&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;S_m&amp;lt;/math&amp;gt; подается на узел &amp;quot;&amp;lt;math&amp;gt;/&amp;lt;/math&amp;gt;&amp;quot;, где производится деление суммы векторов кластера на количество элементов в нем. Значения, вычисленные на узлах &amp;quot;&amp;lt;math&amp;gt;/&amp;lt;/math&amp;gt;&amp;quot;, присваиваются новым центрам кластеров (выходные значения графа).&lt;br /&gt;
&lt;br /&gt;
[[file:Recluster.png|thumb|center|800px|Рис. 3. Схема пересчета центров кластеров]]&lt;br /&gt;
&lt;br /&gt;
=== Ресурс параллелизма алгоритма ===&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
Работа алгоритма состоит из &amp;lt;math&amp;gt;\Tau&amp;lt;/math&amp;gt; итераций, в каждой из которых происходит &amp;lt;b&amp;gt;распределение d-мерных векторов по &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластерам&amp;lt;/b&amp;gt;, а также &amp;lt;b&amp;gt;пересчет центров кластеров в d-мерном пространстве&amp;lt;/b&amp;gt;. В шаге &amp;lt;b&amp;gt;распределения d-мерных векторов по &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластерам&amp;lt;/b&amp;gt; расстояния между вектором и центрами кластеров вычисляются независимо (отсутствуют информационные зависимости). &amp;lt;b&amp;gt;Центры масс кластеров&amp;lt;/b&amp;gt; также пересчитываются независимо друг от друга. Таким образом, имеет место [[глоссарий#Массовый параллелизм|&#039;&#039;массовый параллелизм&#039;&#039;]]. Вычислим параллельную сложность &amp;lt;math&amp;gt;\Psi_*&amp;lt;/math&amp;gt; каждого из шагов, а также параллельную сложность всего алгоритма, &amp;lt;math&amp;gt;\Psi_{k-means}&amp;lt;/math&amp;gt;. Будем исходить из предположения, что может быть использовано любое необходимое число потоков.&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Распределение d-мерных векторов по &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластерам&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;  &lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
Поскольку на данном шаге для каждой пары векторов &amp;lt;math&amp;gt;\mathbf{x}_i, i=\overline{1,n}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\mathbf{\mu}_j, j=\overline{1,k}&amp;lt;/math&amp;gt; операции вычисления расстояния не зависят друг от друга, они могут выполняться параллельно. Тогда, разделив все вычисление расстояний на &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; потоков, получим, что в каждом потоке будет выполняться только одна операция вычисления расстояния между векторами размерности d. При этом каждому вычислительному потоку передаются координаты центров всех кластеров &amp;lt;math&amp;gt;\mathbf{\mu}_1, ..., \mathbf{\mu}_k&amp;lt;/math&amp;gt;. Таким образом, параллельная сложность данного шага определяется &amp;lt;i&amp;gt; сложностью параллельной операции вычисления расстояния между d-мерными векторами&amp;lt;/i&amp;gt;, &amp;lt;math&amp;gt;\Psi_{distance}^d&amp;lt;/math&amp;gt;  и &amp;lt;i&amp;gt;сложностью определения наиболее близкого кластера&amp;lt;/i&amp;gt; (паралельное взятие минимума по расстояниям), &amp;lt;math&amp;gt;\Psi_{min}^k&amp;lt;/math&amp;gt;. Для оценки &amp;lt;math&amp;gt;\Psi_{distance}^d&amp;lt;/math&amp;gt; воспользуемся  [[Нахождение_частных_сумм_элементов_массива_сдваиванием | параллельной реализацией нахождения частичной суммы элементов массива путем сдваивания]]. Аналогично, &amp;lt;math&amp;gt;\Psi_{min}^k = log(k)&amp;lt;/math&amp;gt;. В результате, &amp;lt;math&amp;gt;\Psi_{distance}^d = O(log(d))&amp;lt;/math&amp;gt;.   Таким образом: &lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p align=&amp;quot;center&amp;quot;&amp;gt;&amp;lt;math&amp;gt;\Psi_{distribute}^{k, d}  = \Psi_{distance}^d + \Psi_{min}^k = O(log(d))+O(log(k)) = O(log(k*d))&amp;lt;/math&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Пересчет центров кластеров в d-мерном пространстве&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
Поскольку на данном шаге для каждого из &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластеров центр масс может быть вычислен независимо, данные операции могут быть выполнены в отдельных потоках. Таким образом, параллельная сложность данного шага, &amp;lt;math&amp;gt;\Psi_{recenter}^{k, d}&amp;lt;/math&amp;gt;,  будет определяться &amp;lt;i&amp;gt;параллельной сложностью вычисления одного центра масс кластера размера &amp;lt;math&amp;gt;m&amp;lt;/math&amp;gt;&amp;lt;/i&amp;gt;, &amp;lt;math&amp;gt;\Psi_{recenter}^{k, d}&amp;lt;/math&amp;gt;,  а так как &amp;lt;math&amp;gt;m \le n \Rightarrow \Psi_{recenter}^{d, m} \le \Psi_{recenter}^{d, n}&amp;lt;/math&amp;gt;. Сложность вычисления центра масс кластера d-мерных векторов размера n аналогично предыдущим вычислениям равна &amp;lt;math&amp;gt;O(log(n))&amp;lt;/math&amp;gt;. Тогда:  &lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p align=&amp;quot;center&amp;quot;&amp;gt;&amp;lt;math&amp;gt;\Psi_{recenter}^{k, d}  \le \Psi_{recenter}^{d, n} = O(log(n))&amp;lt;/math&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Общая параллельная сложность алгоритма&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
На каждой итерации необходимо обновление центров кластеров, которые будут использованы на следующей итерации. Таким образом, итерационный процесс выполняется последовательно&amp;lt;ref&amp;gt;Zhao, Weizhong, Huifang Ma, and Qing He. &amp;quot;Parallel k-means clustering based on mapreduce.&amp;quot; IEEE International Conference on Cloud Computing. Springer Berlin Heidelberg, 2009.&amp;lt;/ref&amp;gt;. Тогда, поскольку сложность каждой итерации  определяется &amp;lt;math&amp;gt;\Psi_{distribute}^{k, d}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\Psi_{recenter}&amp;lt;/math&amp;gt;, сложность всего алгоритма, &amp;lt;math&amp;gt;\Psi_{k-means}&amp;lt;/math&amp;gt; в предположении, что было сделано &amp;lt;math&amp;gt;\Tau&amp;lt;/math&amp;gt; операций определяется выражением&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p align=&amp;quot;center&amp;quot;&amp;gt;&amp;lt;math&amp;gt;\Psi_{k-means} \approx \Tau * (\Psi_{distribute}^{k, d} + \Psi_{recenter}^{k, d}) \le \Tau * O(log(k*d*n))&amp;lt;/math&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Входные и выходные данные алгоритма ===&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;Входные данные&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;Матрица из &amp;lt;math&amp;gt;n*d&amp;lt;/math&amp;gt; элементов &amp;lt;math&amp;gt;x_{i, j} \in \mathbb{R}, i=\overline{1, n}, j=\overline{1, d}&amp;lt;/math&amp;gt;&amp;amp;ndash; координат векторов (наблюдений).&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;Целое положительное число &amp;lt;math&amp;gt;k, k \le n&amp;lt;/math&amp;gt; &amp;amp;ndash; количество кластеров.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;Объем входных данных&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;math&amp;gt;1&amp;lt;/math&amp;gt; целое число + &amp;lt;math&amp;gt;n*d&amp;lt;/math&amp;gt; вещественных чисел (при условии, что координаты &amp;amp;ndash; вещественные числа).&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;Выходные данные&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; целых положительных чисел &amp;lt;math&amp;gt;L_1, ..., L_n&amp;lt;/math&amp;gt;&amp;amp;ndash; номера кластеров, соотвествующие каждому вектору (при условии, что нумерация кластеров начинается с &amp;lt;math&amp;gt;1&amp;lt;/math&amp;gt;).&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;Объем выходных данных&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; целых положительных чисел.&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Свойства алгоритма ===&lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;[[глоссарий#Вычислительная мощность|&#039;&#039;Вычислительная мощность&#039;&#039;]]&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
Вычислительная мощность алгоритма &amp;lt;i&amp;gt;k means&amp;lt;/i&amp;gt; равна &amp;lt;math&amp;gt;\frac{k*d*n*\Tau}{n*d} = k*\Tau &amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; &amp;amp;ndash; число кластеров, &amp;lt;math&amp;gt;\Tau&amp;lt;/math&amp;gt; &amp;amp;ndash; число итераций алгоритма.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;[[глоссарий#Детерминированность |&#039;&#039;Детерминированность&#039;&#039;]] и [[глоссарий#Устойчивость |&#039;&#039;Устойчивость&#039;&#039;]] &amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
Алгоритм &amp;lt;i&amp;gt;k means&amp;lt;/i&amp;gt; является итерационным. Количество итераций алгоритма в общем случае не фиксируется и зависит от начального расположения объектов в пространстве, параметра &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt;, а также от начального приближения центров кластеров, &amp;lt;math&amp;gt;\mu_1, ..., \mu_k&amp;lt;/math&amp;gt;. В результате этого может варьироваться результат работы алгоритма. При неудачном выборе начальных параметров итерационный процесс может сойтись к локальному оптимуму&amp;lt;ref&amp;gt;Von Luxburg, Ulrike. Clustering Stability. Now Publishers Inc, 2010.&amp;lt;/ref&amp;gt;. По этим причинам алгоритм не является ни &amp;lt;b&amp;gt;детермирированным&amp;lt;/b&amp;gt;, ни &amp;lt;b&amp;gt;устойчивым&amp;lt;/b&amp;gt;.&lt;br /&gt;
 &lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Соотношение последовательной и параллельной сложности алгоритма&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\frac{\Theta_{k-means}}{\Psi_{k-means}} = \frac{O(\Tau*k*d*n)}{O(\Tau*log(k*d*n))}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Сильные стороны алгоритма&amp;lt;/b&amp;gt;:&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;i&amp;gt;Сравнительно высокая эффективность при простоте реализации&amp;lt;/i&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;i&amp;gt;Высокое качество кластеризации&amp;lt;/i&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;i&amp;gt;Возможность распараллеливания&amp;lt;/i&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;i&amp;gt;Существование множества модификаций&amp;lt;/i&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;Недостатки алгоритма&amp;lt;/b&amp;gt;&amp;lt;ref&amp;gt;Ortega, Joaquín Pérez, Ma Del Rocío Boone Rojas, and María J. Somodevilla. &amp;quot;Research issues on K-means Algorithm: An Experimental Trial Using Matlab.&amp;quot;&amp;lt;/ref&amp;gt;:&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;i&amp;gt;Количество кластеров является параметром алгоритма&amp;lt;/i&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;&amp;lt;i&amp;gt;Чувствительность к начальным условиям&amp;lt;/i&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;Инициализация центров кластеров в значительной степени влияет на результат кластеризации.&amp;lt;/p&amp;gt;&lt;br /&gt;
  &amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;&amp;lt;i&amp;gt;Чувствительность к выбросам и шумам&amp;lt;/i&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;Выбросы, далекие от центров настоящих кластеров, все равно учитываются при вычислении их центров.&amp;lt;/p&amp;gt;&lt;br /&gt;
  &amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;&amp;lt;i&amp;gt;Возможность сходимости к локальному оптимуму&amp;lt;/i&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;Итеративный подход не дает гарантии сходимости к оптимальному решению.&amp;lt;/p&amp;gt;&lt;br /&gt;
  &amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;&amp;lt;i&amp;gt;Использование понятия &amp;quot;среднего&amp;quot;&amp;lt;/i&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;Алгоритм неприменим к данным, для которых не определено понятие &amp;quot;среднего&amp;quot;, например, категориальным данным.&amp;lt;/p&amp;gt;&lt;br /&gt;
  &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&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;
Исследование масштабируемости параллельной реализации алгоритма k means проводилось на суперкомпьютере &amp;quot;Ломоносов&amp;quot;. Алгоритм реализован на языке C с использованием средств MPI.&lt;br /&gt;
Для исследования масштабируемости проводилось множество запусков программы с разным значением параметра (количество векторов для кластеризации), а также с различным числом процессоров. Фиксировались результаты запусков &amp;amp;ndash; время работы &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt; и количество произведенных итераций алгоритма &amp;lt;math&amp;gt;\Tau&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Параметры запусков для экспериментальной оценки:&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;Значения &amp;lt;b&amp;gt;количества векторов&amp;lt;/b&amp;gt; &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;: 20&#039;000, 30&#039;000, 50&#039;000, 100&#039;000, 200&#039;000, 300&#039;000, 500&#039;000, 700&#039;000, 1&#039;000&#039;000, 1&#039;500&#039;000, 2&#039;000&#039;000.&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;Значения &amp;lt;b&amp;gt;количества процессоров&amp;lt;/b&amp;gt; &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt;: 1, 8, 16, 32, 64, 128, 160, 192, 224, 256, 288, 320, 352, 384, 416, 448, 480, 512.&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;Значение &amp;lt;b&amp;gt;количества кластеров&amp;lt;/b&amp;gt; &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt;: 100.&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;Значение &amp;lt;b&amp;gt;размерности векторов&amp;lt;/b&amp;gt; &amp;lt;math&amp;gt;d&amp;lt;/math&amp;gt;: 10.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Графики производительности и эффективности реализации представлены на рисунках 4 и 5 соответственно.&lt;br /&gt;
&lt;br /&gt;
[[file:Flops.png|thumb|center|800px|Рис. 4. График производительности реализации алгоритма.]]&lt;br /&gt;
&lt;br /&gt;
[[file:Efficiency.png|thumb|center|800px|Рис. 5. График эффективности реализации алгоритма.]]&lt;br /&gt;
&lt;br /&gt;
Для заданной конфигурации эксперимента (&amp;lt;math&amp;gt;n, d, p, k&amp;lt;/math&amp;gt;) и полученных результатах (&amp;lt;math&amp;gt;t, \Tau&amp;lt;/math&amp;gt;) производительность и эффективность реализации расчитывались по формулам (см. [[#Последовательная сложность алгоритма| последовательная сложность алгоритма]]):&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
&amp;lt;ul&amp;gt;&amp;lt;li&amp;gt;&amp;lt;math&amp;gt;Performance = \frac{\Theta_{k-means}^{d, n}}{t}\ \ FLOPS&amp;lt;/math&amp;gt;&amp;lt;/li&amp;gt;&amp;lt;/ul&amp;gt;&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
&amp;lt;ul&amp;gt;&amp;lt;li&amp;gt;&amp;lt;math&amp;gt;Efficiency = \frac{100 * Performance}{Performance_{Peak}^{p}}\ \ %,&amp;lt;/math&amp;gt;&amp;lt;/li&amp;gt;&amp;lt;/ul&amp;gt;&lt;br /&gt;
где &amp;lt;math&amp;gt;Performance_{Peak}^{p}&amp;lt;/math&amp;gt; &amp;amp;ndash; пиковая производительность суперкомпьютера при &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt; процессорах, вычисленная согласно спецификациям Intel&amp;lt;sup&amp;gt;&amp;amp;reg;&amp;lt;/sup&amp;gt; XEON&amp;lt;sup&amp;gt;&amp;amp;reg;&amp;lt;/sup&amp;gt; X5670&amp;lt;ref&amp;gt;&amp;quot;http://ark.intel.com/ru/products/47920/Intel-Xeon-Processor-X5670-12M-Cache-2_93-GHz-6_40-GTs-Intel-QPI&amp;quot;&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;В результате&amp;lt;/b&amp;gt; экспериментальной оценки были получены следующие оценки эффективности реализации:&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;b&amp;gt;Минимальное&amp;lt;/b&amp;gt; значение: 0.000409 % достигается при &amp;lt;math&amp;gt;n=20&#039;000, p=480&amp;lt;/math&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;b&amp;gt;Максимальное&amp;lt;/b&amp;gt; значение: 0.741119 % достигается при &amp;lt;math&amp;gt;n=300&#039;000, p=1&amp;lt;/math&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
Приведем оценки масштабируемости реализации алгоритма k means:&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;b&amp;gt;По числу процессоров:&amp;lt;/b&amp;gt; -0.002683 &amp;amp;ndash; эффективность убывает с ростом числа процессоров.&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;b&amp;gt;По размеру задачи:&amp;lt;/b&amp;gt; 0.002779 &amp;amp;ndash; эффективность растет с ростом числа векторов.&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;b&amp;gt;Общая оценка:&amp;lt;/b&amp;gt; -0.000058 &amp;amp;ndash; можно сделать вывод, что в целом эффективность реализации незначительно уменьшается.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Динамические характеристики и эффективность реализации алгоритма ===&lt;br /&gt;
=== Выводы для классов архитектур ===&lt;br /&gt;
=== Существующие реализации алгоритма ===&lt;br /&gt;
==== Открытое программное обеспечение ====&lt;br /&gt;
&amp;lt;ol&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;[https://www.icpsr.umich.edu/CrimeStat/ CrimeStat]&amp;lt;/li&amp;gt; Программное обеспечение, созданное для операционных систем Windows, предоставляющее инструменты статистического  и пространственного анализа для решения задачи картирования преступности.&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://juliastats.github.io Julia]&amp;lt;/li&amp;gt; Высокоуровневый высокопроизводительный свободный язык программирования с динамической типизацией, созданный для математических вычислений, содержит реализацию k-means.&lt;br /&gt;
  &amp;lt;li&amp;gt;[https://mahout.apache.org Mahout]&amp;lt;/li&amp;gt; Apache Mahout - Java библиотека для работы с алгоритмами машинного обучения с использованием MapReduce. Содержит реализацию k-means.&lt;br /&gt;
  &amp;lt;li&amp;gt;[https://www.gnu.org/software/octave/ Octave]&amp;lt;/li&amp;gt; Написанная на C++  свободная система для математических вычислений, использующая совместимый с MATLAB язык высокого уровня, содержит реализацию k-means.&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://spark.apache.org/docs/latest/mllib-clustering.html Spark]&amp;lt;/li&amp;gt; Распределенная реализация k-means содержится в библиотеке Mlib для работы с алгоритмами машинного обучения, взаимодействующая с Python библиотекой NumPy и библиотека R.&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://torch.ch Torch]&amp;lt;/li&amp;gt;  MATLAB-подобная библиотека для языка программирования Lua с открытым исходным кодом, предоставляет большое количество алгоритмов для глубинного обучения и научных расчётов. Ядро написано на Си, прикладная часть выполняется на LuaJIT, поддерживается распараллеливание вычислений средствами CUDA и OpenMP. Существуют реализации k-means.&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://www.cs.waikato.ac.nz/ml/weka/ Weka]&amp;lt;/li&amp;gt;  Cвободное программное обеспечение для анализа данных, написанное на Java. Содержит k-means и x-means.&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://accord-framework.net/docs/html/T_Accord_MachineLearning_KMeans.htm Accord.NET]&amp;lt;/li&amp;gt; C# реализация алгоритмов k-means, k-means++, k-modes.&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://docs.opencv.org/3.0-beta/doc/py_tutorials/py_ml/py_kmeans/py_kmeans_opencv/py_kmeans_opencv.html OpenCV]&amp;lt;/li&amp;gt; Написанная на С++ библиотека, направленная в основном на решение задач компьютерного зрения. Содержит реализацию k-means.&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://mlpack.org/ MLPACK]&amp;lt;/li&amp;gt; Масштабируемая С++ библиотека для работы с алгоритмами машинного обучения, содержит реализацию k-means.&lt;br /&gt;
  &amp;lt;li&amp;gt;[https://www.scipy.org/ SciPy]&amp;lt;/li&amp;gt; Библиотека Python, содержит множество реализаций k-means.&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://scikit-learn.org/ scikit-learn]&amp;lt;/li&amp;gt; Библиотека Python, содержит множество реализаций k-means.&lt;br /&gt;
  &amp;lt;li&amp;gt;[https://www.r-bloggers.com/k-means-clustering-in-r/ R]&amp;lt;/li&amp;gt; Язык программирования для статистической обработки данных и работы с графикой, а также свободная программная среда вычислений с открытым исходным кодом в рамках проекта GNU, содержит три реализации k-means.&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://elki.dbs.ifi.lmu.de ELKI]&amp;lt;/li&amp;gt; Java фреймворк, содержащий реализацию k-means, а также множество других алгоритмов кластеризации.&lt;br /&gt;
&amp;lt;/ol&amp;gt;&lt;br /&gt;
==== Проприетарное программное обеспечение  ====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ol&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;[https://www.ayasdi.com/blog/bigdata/topological-data-analysis-of-oil-and-gas-petrophysical-data/ Ayasdi]&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://www.stata.com/features/cluster-analysis/ Stata]&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://mathworld.wolfram.com/K-MeansClusteringAlgorithm.html Mathematica]&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://www.mathworks.com/help/stats/kmeans.html?requestedDomain=www.mathworks.com MATLAB]&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;[https://support.sas.com/rnd/app/stat/procedures/fastclus.html SAS]&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://docs.rapidminer.com/studio/operators/modeling/segmentation/k_means.html RapidMiner]&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;[https://blogs.sap.com/2013/03/28/sap-hana-pal-k-means-algorithm-or-how-to-do-customer-segmentation-for-the-telecommunications-industry/ SAP HANA]&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ol&amp;gt;&lt;br /&gt;
== Литература ==&lt;br /&gt;
&amp;lt;references /&amp;gt;&lt;/div&gt;</summary>
		<author><name>DennZo1993</name></author>
	</entry>
	<entry>
		<id>https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:%D0%91%D1%80%D0%BE%D1%82%D0%B8%D0%BA%D0%BE%D0%B2%D1%81%D0%BA%D0%B0%D1%8F_%D0%94%D0%B0%D0%BD%D1%83%D1%82%D0%B0/%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_k-means&amp;diff=17181</id>
		<title>Участник:Бротиковская Данута/Алгоритм k-means</title>
		<link rel="alternate" type="text/html" href="https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:%D0%91%D1%80%D0%BE%D1%82%D0%B8%D0%BA%D0%BE%D0%B2%D1%81%D0%BA%D0%B0%D1%8F_%D0%94%D0%B0%D0%BD%D1%83%D1%82%D0%B0/%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_k-means&amp;diff=17181"/>
		<updated>2016-11-15T01:42:11Z</updated>

		<summary type="html">&lt;p&gt;DennZo1993: /* Масштабируемость реализации алгоритма */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt; {{Assignment|Zhum}}&lt;br /&gt;
&lt;br /&gt;
{{algorithm&lt;br /&gt;
| name              = Алгоритм k средних (k means)&lt;br /&gt;
| serial_complexity = &amp;lt;math&amp;gt;O(\Tau*k*d*n)&amp;lt;/math&amp;gt;&lt;br /&gt;
| input_data        = &amp;lt;math&amp;gt; d*n &amp;lt;/math&amp;gt;&lt;br /&gt;
| output_data       = &amp;lt;math&amp;gt; n &amp;lt;/math&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
Авторы страницы &amp;lt;b&amp;gt;[[Участник:Бротиковская Данута|Данута Бротиковская]]&amp;lt;/b&amp;gt; и &amp;lt;b&amp;gt;[[Участник:DennZo1993|Денис Зобнин]]&amp;lt;/b&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
Оба автора внесли одинаковый вклад в написание статьи (поиск материалов, изучение статей, заполнение контента статьи), четких разграничений по пунктам статьи сделать невозможно. &lt;br /&gt;
&lt;br /&gt;
== Свойства и структура алгоритма ==&lt;br /&gt;
&lt;br /&gt;
=== Общее описание алгоритма ===&lt;br /&gt;
Алгоритм &amp;lt;b&amp;gt;&amp;lt;i&amp;gt;k средних&amp;lt;/i&amp;gt;&amp;lt;/b&amp;gt; (&amp;lt;b&amp;gt;&amp;lt;i&amp;gt;k means&amp;lt;/i&amp;gt;&amp;lt;/b&amp;gt;) &amp;amp;ndash; неиерархический&amp;lt;ref&amp;gt;&amp;quot;https://ru.wikipedia.org/wiki/Иерархическая_кластеризация&amp;quot;&amp;lt;/ref&amp;gt;, итерационный метод кластеризации&amp;lt;ref&amp;gt;&amp;quot;https://ru.wikipedia.org/wiki/Кластерный_анализ&amp;quot;&amp;lt;/ref&amp;gt;, получивший большую популярность благодаря своей простоте, наглядности реализации и достаточно высокому качеству работы. Был изобретен в 1950-х годах математиком &amp;lt;i&amp;gt;Гуго Штейнгаузом&amp;lt;/i&amp;gt;&amp;lt;ref&amp;gt;Steinhaus, Hugo. &amp;quot;Sur la division des corp materiels en parties.&amp;quot; Bull. Acad. Polon. Sci 1.804 (1956): 801.&amp;lt;/ref&amp;gt; и почти одновременно &amp;lt;i&amp;gt;Стюартом Ллойдом&amp;lt;/i&amp;gt;&amp;lt;ref&amp;gt;Lloyd, S. P. &amp;quot;Least square quantization in PCM. Bell Telephone Laboratories Paper. Published in journal much later: Lloyd, SP: Least squares quantization in PCM.&amp;quot; IEEE Trans. Inform. Theor.(1957/1982).&amp;lt;/ref&amp;gt;. Особую популярность приобрел после публикации работы &amp;lt;i&amp;gt;МакКуина&amp;lt;/i&amp;gt;&amp;lt;ref&amp;gt;MacQueen, James. &amp;quot;Some methods for classification and analysis of multivariate observations.&amp;quot; Proceedings of the fifth Berkeley symposium on mathematical statistics and probability. Vol. 1. No. 14. 1967.&amp;lt;/ref&amp;gt; в 1967.&lt;br /&gt;
&lt;br /&gt;
Алгоритм представляет собой версию EM-алгоритма&amp;lt;ref&amp;gt;&amp;quot;https://ru.wikipedia.org/wiki/EM-алгоритм&amp;quot;&amp;lt;/ref&amp;gt;, применяемого также для разделения смеси гауссиан. Основная идея &amp;lt;i&amp;gt;k means&amp;lt;/i&amp;gt; заключается в том, что данные произвольно разбиваются на кластеры, после чего итеративно перевычисляется центр масс для каждого кластера, полученного на предыдущем шаге, затем векторы разбиваются на кластеры вновь в соответствии с тем, какой из новых центров оказался ближе по выбранной метрике.&lt;br /&gt;
&lt;br /&gt;
Цель алгоритма заключается в разделении &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; наблюдений на &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластеров таким образом, чтобы каждое наблюдение принадлежало ровно одному кластеру, расположенному на наименьшем расстоянии от наблюдения.&lt;br /&gt;
&lt;br /&gt;
=== Математическое описание алгоритма ===&lt;br /&gt;
&amp;lt;b&amp;gt;&amp;lt;u&amp;gt;Дано:&amp;lt;/u&amp;gt;&amp;lt;/b&amp;gt;&lt;br /&gt;
* набор из &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; наблюдений &amp;lt;math&amp;gt;X=\{\mathbf{x}_1, \mathbf{x}_2, ..., \mathbf{x}_n\}, \mathbf{x}_i \in \mathbb{R}^d, i=\overline{1, n}&amp;lt;/math&amp;gt;;&lt;br /&gt;
* &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; - требуемое число кластеров, &amp;lt;math&amp;gt;k \in \mathbb{N}, k \leq n&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;&amp;lt;u&amp;gt;Требуется:&amp;lt;/u&amp;gt;&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Разделить множество наблюдений &amp;lt;math&amp;gt;X&amp;lt;/math&amp;gt; на &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластеров &amp;lt;math&amp;gt;S_1, S_2, ..., S_k&amp;lt;/math&amp;gt;:&lt;br /&gt;
*   &amp;lt;math&amp;gt;S_i \cap S_j= \varnothing, \quad i \ne j&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
*   &amp;lt;math&amp;gt;\bigcup_{i=1}^{k} S_i = X&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;&amp;lt;u&amp;gt;Действие алгоритма:&amp;lt;/u&amp;gt;&amp;lt;/b&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;Алгоритм &amp;lt;i&amp;gt;k means&amp;lt;/i&amp;gt; разбивает набор &amp;lt;math&amp;gt;X&amp;lt;/math&amp;gt; на &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; наборов &amp;lt;math&amp;gt;S_1, S_2, ..., S_k,&amp;lt;/math&amp;gt; таким образом, чтобы минимизировать сумму квадратов расстояний от каждой точки кластера до его центра (центр масс кластера). Введем обозначение, &amp;lt;math&amp;gt;S=\{S_1, S_2, ..., S_k\}&amp;lt;/math&amp;gt;. Тогда действие алгоритма &amp;lt;i&amp;gt;k means&amp;lt;/i&amp;gt; равносильно поиску:&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;table style=&amp;quot;width:100%&amp;quot;&amp;gt;&lt;br /&gt;
  &amp;lt;tr&amp;gt;&lt;br /&gt;
    &amp;lt;td align=&amp;quot;center&amp;quot; width=&amp;quot;90%&amp;quot;&amp;gt;&amp;lt;math&amp;gt;\arg\min_{S} \sum\limits_{i=1}^k \sum\limits_{\mathbf{x} \in S_i} \rho(\mathbf{x}, \mathbf{\mu}_i )^2,&amp;lt;/math&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;td align=&amp;quot;right&amp;quot;&amp;gt;&amp;lt;math&amp;gt;(1)&amp;lt;/math&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;/table&amp;gt;&lt;br /&gt;
где &amp;lt;math&amp;gt;\mathbf{\mu}_i&amp;lt;/math&amp;gt; &amp;amp;ndash; центры кластеров, &amp;lt;math&amp;gt;i=\overline{1,k}, \quad \rho(\mathbf{x}, \mathbf{\mu}_i)&amp;lt;/math&amp;gt; &amp;amp;ndash; функция расстояния между &amp;lt;math&amp;gt;\mathbf{x}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\mu_i&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;&amp;lt;u&amp;gt;Шаги алгоритма: &amp;lt;/u&amp;gt;&amp;lt;/b&amp;gt;&lt;br /&gt;
&amp;lt;ol&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&lt;br /&gt;
    &amp;lt;b&amp;gt;Начальный шаг: инициализация кластеров&amp;lt;/b&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;Выбирается произвольное множество точек &amp;lt;math&amp;gt;\mu_i, i=\overline{1,k}&amp;lt;/math&amp;gt;, рассматриваемых как начальные центры кластеров: &amp;lt;math&amp;gt;\mu_i^{(0)} = \mu_i, \quad i=\overline{1, k}&amp;lt;/math&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
  &amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&lt;br /&gt;
    &amp;lt;b&amp;gt;Распределение векторов по кластерам&amp;lt;/b&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Шаг&amp;lt;/b&amp;gt; &amp;lt;math&amp;gt;t: \forall \mathbf{x}_i \in X, i=\overline{1,n}: \mathbf{x}_i \in S_j \iff  j=\arg\min_{k}\rho(\mathbf{x}_i,\mathbf{\mu}_k^{(t-1)})^2&amp;lt;/math&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
  &amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&lt;br /&gt;
    &amp;lt;b&amp;gt;Пересчет центров кластеров&amp;lt;/b&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Шаг &amp;lt;/b&amp;gt; &amp;lt;math&amp;gt;t: \forall i=\overline{1,k}:  \mu_i^{(t)} = \cfrac{1}{|S_i|}\sum_{\mathbf{x}\in S_i}\mathbf{x}&amp;lt;/math&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
  &amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&lt;br /&gt;
    &amp;lt;b&amp;gt;Проверка условия останова:&amp;lt;/b&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
    &#039;&#039;&#039;if&#039;&#039;&#039; &amp;lt;math&amp;gt;\exist i\in \overline{1,k}: \mu_i^{(t)} \ne \mu_i^{(t-1)}&amp;lt;/math&amp;gt; &#039;&#039;&#039;then&#039;&#039;&#039;&lt;br /&gt;
        t = t + 1;&lt;br /&gt;
        goto 2;&lt;br /&gt;
    &#039;&#039;&#039;else&#039;&#039;&#039;&lt;br /&gt;
        &#039;&#039;&#039;stop&#039;&#039;&#039;&lt;br /&gt;
  &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ol&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Вычислительное ядро алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Вычислительным ядром являются шаги 2 и 3 приведенного выше алгоритма: &amp;lt;b&amp;gt;&amp;lt;i&amp;gt;распределение векторов по кластерам&amp;lt;/i&amp;gt;&amp;lt;/b&amp;gt; и &amp;lt;b&amp;gt;&amp;lt;i&amp;gt;пересчет центров кластеров&amp;lt;/i&amp;gt;&amp;lt;/b&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;&amp;lt;i&amp;gt;Распределение векторов&amp;lt;/i&amp;gt;&amp;lt;/b&amp;gt; по кластерам предполагает вычисление расстояний между каждым вектором &amp;lt;math&amp;gt;\mathbf{x}_i \in X, i= \overline{1,n}&amp;lt;/math&amp;gt; и центрами кластера &amp;lt;math&amp;gt;\mathbf{\mu}_j, j= \overline{1,k}&amp;lt;/math&amp;gt;. Таким образом, данный шаг предполагает &amp;lt;math&amp;gt;k*n&amp;lt;/math&amp;gt; вычислений расстояний между d-мерными векторами. &lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;&amp;lt;i&amp;gt;Пересчет центров кластеров&amp;lt;/i&amp;gt;&amp;lt;/b&amp;gt; предполагает &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; вычислений центров масс &amp;lt;math&amp;gt;\mathbf{\mu}_i&amp;lt;/math&amp;gt; множеств &amp;lt;math&amp;gt;S_i, i=\overline{1,k}&amp;lt;/math&amp;gt; представленных выражением в шаге 3 представленного выше алгоритма.&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Макроструктура алгоритма ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Инициализация центров масс &amp;lt;math&amp;gt;\mu_1, ..., \mu_k&amp;lt;/math&amp;gt;&amp;lt;/b&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
Наиболее распространенными являются следующие стратегии:&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&lt;br /&gt;
    &amp;lt;b&amp;gt;Метод Forgy&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;В качестве начальных значений &amp;lt;math&amp;gt;\mu_1, ..., \mu_k&amp;lt;/math&amp;gt; берутся случайно выбранные векторы.&lt;br /&gt;
  &amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&lt;br /&gt;
    &amp;lt;b&amp;gt;Метод случайно разделения (Random Partitioning)&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;Для каждого вектора &amp;lt;math&amp;gt;\mathbf{x}_i \in X, i=\overline{1, n}&amp;lt;/math&amp;gt; выбирается случайным образом кластер &amp;lt;math&amp;gt;S_1, ..., S_k&amp;lt;/math&amp;gt;, после чего для каждого полученного кластера вычисляются значения &amp;lt;math&amp;gt;\mu_1, ..., \mu_k&amp;lt;/math&amp;gt;.&lt;br /&gt;
  &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Распределение векторов по кластерам&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Для этого шага алгоритма между векторами &amp;lt;math&amp;gt;\mathbf{x}_i \in X, i=\overline{1, n}&amp;lt;/math&amp;gt; и центрами кластеров &amp;lt;math&amp;gt;\mu_1, ..., \mu_k&amp;lt;/math&amp;gt; вычисляются &amp;lt;b&amp;gt;расстояния&amp;lt;/b&amp;gt; по формуле (как правило, используется Евлидово расстояние):&lt;br /&gt;
&amp;lt;table style=&amp;quot;width:100%&amp;quot;&amp;gt;&lt;br /&gt;
  &amp;lt;tr&amp;gt;&lt;br /&gt;
    &amp;lt;td align=&amp;quot;center&amp;quot; width=&amp;quot;90%&amp;quot;&amp;gt;&amp;lt;math&amp;gt; \mathbf{v}_1, \mathbf{v}_2 \in \mathbb{R}^d,  \quad \rho(\mathbf{v}_1, \mathbf{v}_2) = \lVert \mathbf{v}_1- \mathbf{v}_2 \rVert= \sqrt{\sum_{i=1}^{d}(\mathbf{v}_{1,i} - \mathbf{v}_{2,i})^2}&amp;lt;/math&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;td align=&amp;quot;right&amp;quot;&amp;gt;&amp;lt;math&amp;gt;(2)&amp;lt;/math&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;/table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Пересчет центров кластеров&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Для этого шага алгоритма производится пересчет центров кластера по &amp;lt;b&amp;gt;формуле вычисления центра масс&amp;lt;/b&amp;gt;:&lt;br /&gt;
&amp;lt;table style=&amp;quot;width:100%&amp;quot;&amp;gt;&lt;br /&gt;
  &amp;lt;tr&amp;gt;&lt;br /&gt;
    &amp;lt;td align=&amp;quot;center&amp;quot; width=&amp;quot;90%&amp;quot;&amp;gt;&amp;lt;math&amp;gt; \mu = \cfrac{1}{|S|}\sum_{\mathbf{x}\in S}\mathbf{x}&amp;lt;/math&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;td align=&amp;quot;right&amp;quot;&amp;gt;&amp;lt;math&amp;gt;(3)&amp;lt;/math&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;/table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Схема реализации последовательного алгоритма ===&lt;br /&gt;
&lt;br /&gt;
 &#039;&#039;&#039;algorithm&#039;&#039;&#039; k-means &#039;&#039;&#039;is&#039;&#039;&#039;&lt;br /&gt;
     &#039;&#039;&#039;1.&#039;&#039;&#039; Инициализировать центры кластеров &amp;lt;math&amp;gt;\mathbf{\mu}_i^{(1)}, i=\overline{1,k}&amp;lt;/math&amp;gt;&lt;br /&gt;
     &#039;&#039;&#039;2.&#039;&#039;&#039; &amp;lt;math&amp;gt;t \leftarrow 1&amp;lt;/math&amp;gt;&lt;br /&gt;
     &#039;&#039;&#039;3.&#039;&#039;&#039; &#039;&#039;&#039;Распределение по кластерам&#039;&#039;&#039;&amp;lt;br&amp;gt;&lt;br /&gt;
        &amp;lt;math&amp;gt;S_i^{(t)}=\{\mathbf{x}_p: \lVert\mathbf{x}_p-\mathbf{\mu}_i^{(t)}\rVert^2 \leq \lVert\mathbf{x}_p-\mathbf{\mu}_j^{(t)}\rVert^2 \quad \forall j=\overline{1,k}\},&amp;lt;/math&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
        где каждый вектор &amp;lt;math&amp;gt;\mathbf{x}_p&amp;lt;/math&amp;gt; соотносится единственному кластеру &amp;lt;math&amp;gt;S^{(t)}&amp;lt;/math&amp;gt;&lt;br /&gt;
     &#039;&#039;&#039;4.&#039;&#039;&#039; &#039;&#039;&#039;Обновление центров кластеров&#039;&#039;&#039;&amp;lt;br&amp;gt;&lt;br /&gt;
        &amp;lt;math&amp;gt;\mathbf{\mu}_i^{(t+1)} = \frac{1}{|S^{(t)}_i|} \sum_{\mathbf{x}_j \in S^{(t)}_i} \mathbf{x}_j &amp;lt;/math&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
     &#039;&#039;&#039;5.&#039;&#039;&#039; &#039;&#039;&#039;if&#039;&#039;&#039; &amp;lt;math&amp;gt;\exist i \in \overline{1,k}: \mathbf{\mu}_i^{(t+1)} \ne \mathbf{\mu}_i^{(t)}&amp;lt;/math&amp;gt; &#039;&#039;&#039;then&#039;&#039;&#039;&lt;br /&gt;
            t = t + 1;&lt;br /&gt;
            goto &#039;&#039;&#039;3&#039;&#039;&#039;;&lt;br /&gt;
        &#039;&#039;&#039;else&#039;&#039;&#039;&lt;br /&gt;
            &#039;&#039;&#039;stop&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
=== Последовательная сложность алгоритма===&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding-bottom: 20px&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;Обозначим &amp;lt;math&amp;gt;\Theta_{centroid}^{d, m}&amp;lt;/math&amp;gt; временную сложность вычисления центорида кластера, число элементов которого равна &amp;lt;math&amp;gt;m&amp;lt;/math&amp;gt;,  в d-мерном пространстве.&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;Аналогично  &amp;lt;math&amp;gt;\Theta_{distance}^d&amp;lt;/math&amp;gt; &amp;amp;ndash; временная сложность вычисления расстояния между двумя d-мерными векторами.&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding-bottom: 20px&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;Сложность шага инициализации &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластеров мощности &amp;lt;math&amp;gt;m&amp;lt;/math&amp;gt; в d-мерном пространстве &amp;amp;ndash; &amp;lt;math&amp;gt;\Theta_{init}^{k, d, m}&amp;lt;/math&amp;gt;&amp;lt;/b&amp;gt;&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;i&amp;gt;Стратерия Forgy&amp;lt;/i&amp;gt;: вычисления не требуются, &amp;lt;math&amp;gt;\Theta_{init}^{k, d, m} = 0&amp;lt;/math&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;i&amp;gt;Стратегия случайного разбиения&amp;lt;/i&amp;gt;: вычисление центров &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластеров,  &amp;lt;math&amp;gt;\Theta_{init}^{k, d, m} = k*\Theta_{centroid}^{d, m}, m \le n&amp;lt;/math&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding-bottom: 20px&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Cложность шага распределения d мерных векторов по &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластерам &amp;amp;ndash; &amp;lt;math&amp;gt;\Theta_{distribute}^{k, d}&amp;lt;/math&amp;gt;&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
На этом шаге для каждого вектора &amp;lt;math&amp;gt;\mathbf{x}_i \in X, i=\overline{1, n}&amp;lt;/math&amp;gt; вычисляется k расстояний до центров кластеров &amp;lt;math&amp;gt;\mathbf{\mu}_1, ...\mathbf{\mu}_k&amp;lt;/math&amp;gt;&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p align=&amp;quot;center&amp;quot;&amp;gt;&lt;br /&gt;
  &amp;lt;math&amp;gt;\Theta_{distribute}^{k, d} = n*k*\Theta_{distance}^d&amp;lt;/math&amp;gt;&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding-bottom: 20px&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;Сложность шага пересчета центров &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластеров размера &amp;lt;math&amp;gt;m&amp;lt;/math&amp;gt; в d-мерном пространстве &amp;amp;ndash; &amp;lt;math&amp;gt;\Theta_{recenter}^{k, d, m}&amp;lt;/math&amp;gt;&amp;lt;/b&amp;gt;&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;На этом шаге вычисляется &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; центров кластеров &amp;lt;math&amp;gt;\mathbf{\mu}_1, ...\mathbf{\mu}_k&amp;lt;/math&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p align=&amp;quot;center&amp;quot;&amp;gt;&amp;lt;math&amp;gt;\Theta_{recenter}^{k, d, m} = k*\Theta_{centroid}^{d, m}&amp;lt;/math&amp;gt; &amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding-bottom: 20px&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Рассчитаем &amp;lt;math&amp;gt;\Theta_{centroid}^{d, m}&amp;lt;/math&amp;gt; для кластера, число элементов которого равно &amp;lt;math&amp;gt;m&amp;lt;/math&amp;gt;&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p align=&amp;quot;center&amp;quot;&amp;gt;&amp;lt;math&amp;gt;\Theta_{centroid}^{d, m}&amp;lt;/math&amp;gt; = &amp;lt;math&amp;gt;m * d&amp;lt;/math&amp;gt; сложений + &amp;lt;math&amp;gt;d&amp;lt;/math&amp;gt; делений &amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding-bottom: 20px&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Рассчитаем &amp;lt;math&amp;gt;\Theta_{distance}^d&amp;lt;/math&amp;gt; в соответствие с формулой &amp;lt;math&amp;gt;(2)&amp;lt;/math&amp;gt;&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p align=&amp;quot;center&amp;quot;&amp;gt;&amp;lt;math&amp;gt;\Theta_{distance}^d&amp;lt;/math&amp;gt; = &amp;lt;math&amp;gt;d&amp;lt;/math&amp;gt; вычитаний + &amp;lt;math&amp;gt;d&amp;lt;/math&amp;gt; умножений + &amp;lt;math&amp;gt;(d-1)&amp;lt;/math&amp;gt; сложение&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding-bottom: 20px&amp;quot;&amp;gt;&lt;br /&gt;
  &amp;lt;p&amp;gt;Предположим, что алгоритм сошелся за &amp;lt;math&amp;gt;\Tau&amp;lt;/math&amp;gt; итераций, тогда временная сложность алгоритма &amp;lt;math&amp;gt;\Theta_{k-means}^{d, n}&amp;lt;/math&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
  &amp;lt;p align=&amp;quot;center&amp;quot;&amp;gt;&amp;lt;b&amp;gt;&amp;lt;math&amp;gt;\Theta_{k-means}^{d, n} \le \Theta_{init}^{k, d, n} + \Tau*(\Theta_{distribute}^{k, d} + \Theta_{recenter}^{k, d, n})&amp;lt;/math&amp;gt;&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding-bottom: 5px&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;Операции сложения/вычитания:&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p align=&amp;quot;center&amp;quot;&amp;gt;&amp;lt;b&amp;gt;&amp;lt;math&amp;gt;\Theta_{k-means}^{d, n} \le k*n*d+ \Tau*(k*n*(2d-1) + k*n*d) = k*n*d+ \Tau*(k*n*(3d-1)) \thicksim O(\Tau*k*d*n)&amp;lt;/math&amp;gt;&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding-bottom: 20px&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;Операции умножения/деления:&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p align=&amp;quot;center&amp;quot;&amp;gt;&amp;lt;b&amp;gt;&amp;lt;math&amp;gt;\Theta_{k-means}^{d, n} \le k*d + \Tau*(k*n*d + k*d) = k*d + \Tau * k*d*(n+1) \thicksim O(\Tau*k*d*n) &amp;lt;/math&amp;gt;&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding-bottom: 20px&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;Получаем, что &amp;lt;b&amp;gt;временная сложность&amp;lt;/b&amp;gt; алгоритма &amp;lt;b&amp;gt;k means&amp;lt;/b&amp;gt; кластеризации &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; &amp;lt;b&amp;gt;d-мерных&amp;lt;/b&amp;gt; векторов на &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластеров за &amp;lt;math&amp;gt;\Tau&amp;lt;/math&amp;gt; итераций:&amp;lt;/p&amp;gt;&lt;br /&gt;
 &amp;lt;p align=&amp;quot;center&amp;quot;&amp;gt;&amp;lt;b&amp;gt;&amp;lt;math&amp;gt; \Theta_{k-means}^{d, n} \thicksim O(\Tau*k*d*n) &amp;lt;/math&amp;gt;&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Информационный граф ===&lt;br /&gt;
&lt;br /&gt;
Рассмотрим информационный граф алгоритма. Алгоритм &amp;lt;i&amp;gt;k means&amp;lt;/i&amp;gt; начинается с этапа инициализации, после которого следуют итерации, на каждой из которых выполняется два последовательных шага (см. [[#Схема реализации последовательного алгоритма|&amp;quot;Схема реализации последовательного алгоритма&amp;quot;]]): &lt;br /&gt;
* распределение векторов по кластерам&lt;br /&gt;
* перерасчет центров кластеров&lt;br /&gt;
&lt;br /&gt;
Поскольку основная часть вычислений приходится на шаги итераций, распишем информационные графы данных шагов.&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Распределение векторов по кластерам&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
Информационный граф шага распределения векторов по кластерам представлен на &#039;&#039;рисунке 1&#039;&#039;. Исходами данного графа является исходные векторы &amp;lt;math&amp;gt;\mathbf{x}_1, ..., \mathbf{x}_n&amp;lt;/math&amp;gt;, а также центры кластеров &amp;lt;math&amp;gt;\mathbf{\mu}_1, ... \mathbf{\mu}_k&amp;lt;/math&amp;gt;, вычисленные ранее (на шаге инициализации, если рассматривается первая итерация алгоритма, или на шаге пересчета центров кластеров предыдущей итерации в противном случае). Каждая пара векторов данных &amp;lt;math&amp;gt;\mathbf{x}_i, i=\overline{1,n}&amp;lt;/math&amp;gt; и центров кластера &amp;lt;math&amp;gt;\mathbf{\mu}_j, j=\overline{1, k}&amp;lt;/math&amp;gt; : (&amp;lt;math&amp;gt;\mathbf{x}_i&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;\mathbf{\mu}_j&amp;lt;/math&amp;gt;) подаются на независимые узлы &amp;lt;i&amp;gt;&amp;quot;d&amp;quot;&amp;lt;/i&amp;gt; вычисления расстояния между векторами (более подробная схема вычисления расстояния представлена далее, &#039;&#039;рисунок 2&#039;&#039;). Далее узлы вычисления расстояния &amp;lt;i&amp;gt;&amp;quot;d&amp;quot;&amp;lt;/i&amp;gt;, соответствующие одному и тому же исходному вектору &amp;lt;math&amp;gt;\mathbf{x}_i&amp;lt;/math&amp;gt; передаются на один узел &amp;lt;i&amp;gt;&amp;quot;m&amp;quot;&amp;lt;/i&amp;gt;, где далее происходит вычисление новой метки кластера для каждого вектора &amp;lt;math&amp;gt;\mathbf{x}_i&amp;lt;/math&amp;gt; (берется кластер с минимальным результатом вычисления расстояния). На выходе графа выдаются метки кластеров , &amp;lt;math&amp;gt;L_1, ..., L_n&amp;lt;/math&amp;gt;, такие что &amp;lt;math&amp;gt;\forall \mathbf{x}_i, i=\overline{1, n}, \mathbf{x}_i \in S_j \Leftrightarrow L_i = j&amp;lt;/math&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
[[file:Clusterization.png|thumb|center|800px|Рис. 1. Схема распределения векторов по кластерам. &#039;&#039;d&#039;&#039; &amp;amp;ndash; вычисление расстояния между векторами; &#039;&#039;m&#039;&#039; &amp;amp;ndash; вычисление минимума.]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Вычисление расстояния между векторами&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
Подробная схема вычисления расстояния между векторами &amp;lt;math&amp;gt;\mathbf{x}_i, \mathbf{\mu}_j&amp;lt;/math&amp;gt; представлена на &#039;&#039;рисунке 2&#039;&#039;. Как показано на графе, узел вычисления расстояния между векторами &amp;lt;i&amp;gt;&amp;quot;d&amp;quot;&amp;lt;/i&amp;gt; состоит из шага взятия разности между векторами (узел &amp;quot;&amp;lt;math&amp;gt;-&amp;lt;/math&amp;gt;&amp;quot;) и взятия нормы получившегося вектора разности (узел &amp;quot;&amp;lt;math&amp;gt;||\cdot||^2&amp;lt;/math&amp;gt;&amp;quot;). Более подробно, вычисление расстояния между векторами &amp;lt;math&amp;gt;\mathbf{x}_i = {x_{i1,}, ...,{x_{in}}}, \mathbf{\mu}_j = {\mu_{j1}, ...,\mu_{jn}}&amp;lt;/math&amp;gt; может быть представлено как вычисление разности между каждой парой компонент &amp;lt;math&amp;gt;(x_{iz}, \mu_{jz}), z=\overline{1, d}&amp;lt;/math&amp;gt; (узел &amp;quot;&amp;lt;math&amp;gt;-&amp;lt;/math&amp;gt;&amp;quot;), далее возведение в квадрат для каждого узла &amp;quot;&amp;lt;math&amp;gt;-&amp;lt;/math&amp;gt;&amp;quot; (узел &amp;quot;&amp;lt;math&amp;gt;()^2&amp;lt;/math&amp;gt;&amp;quot;) и суммирования выходов всех узлов &amp;quot;&amp;lt;math&amp;gt;()^2&amp;lt;/math&amp;gt;&amp;quot; (узел &amp;quot;&amp;lt;math&amp;gt;+&amp;lt;/math&amp;gt;&amp;quot;).  &lt;br /&gt;
&lt;br /&gt;
[[file:dist_calc.png|thumb|center|800px|Рис. 2. Схема вычисления расстояния между вектором и центром кластера.]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Пересчет центров кластеров&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
Информационный граф шага пересчета центров кластеров представлен на &#039;&#039;рисунке 3&#039;&#039;. Исходами данного графа является исходные векторы &amp;lt;math&amp;gt;\mathbf{x}_1, ..., \mathbf{x}_n&amp;lt;/math&amp;gt;, а также им соответствующие метки кластера, &amp;lt;math&amp;gt;L_1, ..., L_n&amp;lt;/math&amp;gt;, такие что &amp;lt;math&amp;gt;\forall x_i, i=\overline{1, n}, \mathbf{x}_i \in S_j \Leftrightarrow L_i = j&amp;lt;/math&amp;gt;, вычисленные на этапе распределения векторов по кластерам. Все векторы &amp;lt;math&amp;gt;\mathbf{x}_1, ..., \mathbf{x}_n&amp;lt;/math&amp;gt; подаются в узлы &amp;lt;math&amp;gt;+_1, ...+_k&amp;lt;/math&amp;gt;, каждый узел &amp;lt;math&amp;gt;+_m, m = \overline{1,k}&amp;lt;/math&amp;gt; соответствует операции сложения векторов кластера с номером &amp;lt;math&amp;gt;m&amp;lt;/math&amp;gt;. Метки кластера &amp;lt;math&amp;gt;L_1, ..., L_n&amp;lt;/math&amp;gt; также совместно передаются на узлы &amp;lt;math&amp;gt;S_m, m = \overline{1,k}&amp;lt;/math&amp;gt;, на каждом из которых вычисляется количество векторов в соответствующем кластере (количество меток с соответствующим значением). Далее каждая пара выходов узлов &amp;lt;math&amp;gt;+_m&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;S_m&amp;lt;/math&amp;gt; подается на узел &amp;quot;&amp;lt;math&amp;gt;/&amp;lt;/math&amp;gt;&amp;quot;, где производится деление суммы векторов кластера на количество элементов в нем. Значения, вычисленные на узлах &amp;quot;&amp;lt;math&amp;gt;/&amp;lt;/math&amp;gt;&amp;quot;, присваиваются новым центрам кластеров (выходные значения графа).&lt;br /&gt;
&lt;br /&gt;
[[file:Recluster.png|thumb|center|800px|Рис. 3. Схема пересчета центров кластеров]]&lt;br /&gt;
&lt;br /&gt;
=== Ресурс параллелизма алгоритма ===&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
Работа алгоритма состоит из &amp;lt;math&amp;gt;\Tau&amp;lt;/math&amp;gt; итераций, в каждой из которых происходит &amp;lt;b&amp;gt;распределение d-мерных векторов по &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластерам&amp;lt;/b&amp;gt;, а также &amp;lt;b&amp;gt;пересчет центров кластеров в d-мерном пространстве&amp;lt;/b&amp;gt;. В шаге &amp;lt;b&amp;gt;распределения d-мерных векторов по &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластерам&amp;lt;/b&amp;gt; расстояния между вектором и центрами кластеров вычисляются независимо (отсутствуют информационные зависимости). &amp;lt;b&amp;gt;Центры масс кластеров&amp;lt;/b&amp;gt; также пересчитываются независимо друг от друга. Таким образом, имеет место [[глоссарий#Массовый параллелизм|&#039;&#039;массовый параллелизм&#039;&#039;]]. Вычислим параллельную сложность &amp;lt;math&amp;gt;\Psi_*&amp;lt;/math&amp;gt; каждого из шагов, а также параллельную сложность всего алгоритма, &amp;lt;math&amp;gt;\Psi_{k-means}&amp;lt;/math&amp;gt;. Будем исходить из предположения, что может быть использовано любое необходимое число потоков.&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Распределение d-мерных векторов по &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластерам&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;  &lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
Поскольку на данном шаге для каждой пары векторов &amp;lt;math&amp;gt;\mathbf{x}_i, i=\overline{1,n}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\mathbf{\mu}_j, j=\overline{1,k}&amp;lt;/math&amp;gt; операции вычисления расстояния не зависят друг от друга, они могут выполняться параллельно. Тогда, разделив все вычисление расстояний на &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; потоков, получим, что в каждом потоке будет выполняться только одна операция вычисления расстояния между векторами размерности d. При этом каждому вычислительному потоку передаются координаты центров всех кластеров &amp;lt;math&amp;gt;\mathbf{\mu}_1, ..., \mathbf{\mu}_k&amp;lt;/math&amp;gt;. Таким образом, параллельная сложность данного шага определяется &amp;lt;i&amp;gt; сложностью параллельной операции вычисления расстояния между d-мерными векторами&amp;lt;/i&amp;gt;, &amp;lt;math&amp;gt;\Psi_{distance}^d&amp;lt;/math&amp;gt;  и &amp;lt;i&amp;gt;сложностью определения наиболее близкого кластера&amp;lt;/i&amp;gt; (паралельное взятие минимума по расстояниям), &amp;lt;math&amp;gt;\Psi_{min}^k&amp;lt;/math&amp;gt;. Для оценки &amp;lt;math&amp;gt;\Psi_{distance}^d&amp;lt;/math&amp;gt; воспользуемся  [[Нахождение_частных_сумм_элементов_массива_сдваиванием | параллельной реализацией нахождения частичной суммы элементов массива путем сдваивания]]. Аналогично, &amp;lt;math&amp;gt;\Psi_{min}^k = log(k)&amp;lt;/math&amp;gt;. В результате, &amp;lt;math&amp;gt;\Psi_{distance}^d = O(log(d))&amp;lt;/math&amp;gt;.   Таким образом: &lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p align=&amp;quot;center&amp;quot;&amp;gt;&amp;lt;math&amp;gt;\Psi_{distribute}^{k, d}  = \Psi_{distance}^d + \Psi_{min}^k = O(log(d))+O(log(k)) = O(log(k*d))&amp;lt;/math&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Пересчет центров кластеров в d-мерном пространстве&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
Поскольку на данном шаге для каждого из &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластеров центр масс может быть вычислен независимо, данные операции могут быть выполнены в отдельных потоках. Таким образом, параллельная сложность данного шага, &amp;lt;math&amp;gt;\Psi_{recenter}^{k, d}&amp;lt;/math&amp;gt;,  будет определяться &amp;lt;i&amp;gt;параллельной сложностью вычисления одного центра масс кластера размера &amp;lt;math&amp;gt;m&amp;lt;/math&amp;gt;&amp;lt;/i&amp;gt;, &amp;lt;math&amp;gt;\Psi_{recenter}^{k, d}&amp;lt;/math&amp;gt;,  а так как &amp;lt;math&amp;gt;m \le n \Rightarrow \Psi_{recenter}^{d, m} \le \Psi_{recenter}^{d, n}&amp;lt;/math&amp;gt;. Сложность вычисления центра масс кластера d-мерных векторов размера n аналогично предыдущим вычислениям равна &amp;lt;math&amp;gt;O(log(n))&amp;lt;/math&amp;gt;. Тогда:  &lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p align=&amp;quot;center&amp;quot;&amp;gt;&amp;lt;math&amp;gt;\Psi_{recenter}^{k, d}  \le \Psi_{recenter}^{d, n} = O(log(n))&amp;lt;/math&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Общая параллельная сложность алгоритма&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
На каждой итерации необходимо обновление центров кластеров, которые будут использованы на следующей итерации. Таким образом, итерационный процесс выполняется последовательно&amp;lt;ref&amp;gt;Zhao, Weizhong, Huifang Ma, and Qing He. &amp;quot;Parallel k-means clustering based on mapreduce.&amp;quot; IEEE International Conference on Cloud Computing. Springer Berlin Heidelberg, 2009.&amp;lt;/ref&amp;gt;. Тогда, поскольку сложность каждой итерации  определяется &amp;lt;math&amp;gt;\Psi_{distribute}^{k, d}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\Psi_{recenter}&amp;lt;/math&amp;gt;, сложность всего алгоритма, &amp;lt;math&amp;gt;\Psi_{k-means}&amp;lt;/math&amp;gt; в предположении, что было сделано &amp;lt;math&amp;gt;\Tau&amp;lt;/math&amp;gt; операций определяется выражением&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p align=&amp;quot;center&amp;quot;&amp;gt;&amp;lt;math&amp;gt;\Psi_{k-means} \approx \Tau * (\Psi_{distribute}^{k, d} + \Psi_{recenter}^{k, d}) \le \Tau * O(log(k*d*n))&amp;lt;/math&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Входные и выходные данные алгоритма ===&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;Входные данные&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;Матрица из &amp;lt;math&amp;gt;n*d&amp;lt;/math&amp;gt; элементов &amp;lt;math&amp;gt;x_{i, j} \in \mathbb{R}, i=\overline{1, n}, j=\overline{1, d}&amp;lt;/math&amp;gt;&amp;amp;ndash; координат векторов (наблюдений).&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;Целое положительное число &amp;lt;math&amp;gt;k, k \le n&amp;lt;/math&amp;gt; &amp;amp;ndash; количество кластеров.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;Объем входных данных&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;math&amp;gt;1&amp;lt;/math&amp;gt; целое число + &amp;lt;math&amp;gt;n*d&amp;lt;/math&amp;gt; вещественных чисел (при условии, что координаты &amp;amp;ndash; вещественные числа).&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;Выходные данные&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; целых положительных чисел &amp;lt;math&amp;gt;L_1, ..., L_n&amp;lt;/math&amp;gt;&amp;amp;ndash; номера кластеров, соотвествующие каждому вектору (при условии, что нумерация кластеров начинается с &amp;lt;math&amp;gt;1&amp;lt;/math&amp;gt;).&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;Объем выходных данных&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; целых положительных чисел.&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Свойства алгоритма ===&lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;[[глоссарий#Вычислительная мощность|&#039;&#039;Вычислительная мощность&#039;&#039;]]&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
Вычислительная мощность алгоритма &amp;lt;i&amp;gt;k means&amp;lt;/i&amp;gt; равна &amp;lt;math&amp;gt;\frac{k*d*n*\Tau}{n*d} = k*\Tau &amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; &amp;amp;ndash; число кластеров, &amp;lt;math&amp;gt;\Tau&amp;lt;/math&amp;gt; &amp;amp;ndash; число итераций алгоритма.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;[[глоссарий#Детерминированность |&#039;&#039;Детерминированность&#039;&#039;]] и [[глоссарий#Устойчивость |&#039;&#039;Устойчивость&#039;&#039;]] &amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
Алгоритм &amp;lt;i&amp;gt;k means&amp;lt;/i&amp;gt; является итерационным. Количество итераций алгоритма в общем случае не фиксируется и зависит от начального расположения объектов в пространстве, параметра &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt;, а также от начального приближения центров кластеров, &amp;lt;math&amp;gt;\mu_1, ..., \mu_k&amp;lt;/math&amp;gt;. В результате этого может варьироваться результат работы алгоритма. При неудачном выборе начальных параметров итерационный процесс может сойтись к локальному оптимуму&amp;lt;ref&amp;gt;Von Luxburg, Ulrike. Clustering Stability. Now Publishers Inc, 2010.&amp;lt;/ref&amp;gt;. По этим причинам алгоритм не является ни &amp;lt;b&amp;gt;детермирированным&amp;lt;/b&amp;gt;, ни &amp;lt;b&amp;gt;устойчивым&amp;lt;/b&amp;gt;.&lt;br /&gt;
 &lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Соотношение последовательной и параллельной сложности алгоритма&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\frac{\Theta_{k-means}}{\Psi_{k-means}} = \frac{O(\Tau*k*d*n)}{O(\Tau*log(k*d*n))}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Сильные стороны алгоритма&amp;lt;/b&amp;gt;:&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;i&amp;gt;Сравнительно высокая эффективность при простоте реализации&amp;lt;/i&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;i&amp;gt;Высокое качество кластеризации&amp;lt;/i&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;i&amp;gt;Возможность распараллеливания&amp;lt;/i&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;i&amp;gt;Существование множества модификаций&amp;lt;/i&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;Недостатки алгоритма&amp;lt;/b&amp;gt;&amp;lt;ref&amp;gt;Ortega, Joaquín Pérez, Ma Del Rocío Boone Rojas, and María J. Somodevilla. &amp;quot;Research issues on K-means Algorithm: An Experimental Trial Using Matlab.&amp;quot;&amp;lt;/ref&amp;gt;:&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;i&amp;gt;Количество кластеров является параметром алгоритма&amp;lt;/i&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;&amp;lt;i&amp;gt;Чувствительность к начальным условиям&amp;lt;/i&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;Инициализация центров кластеров в значительной степени влияет на результат кластеризации.&amp;lt;/p&amp;gt;&lt;br /&gt;
  &amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;&amp;lt;i&amp;gt;Чувствительность к выбросам и шумам&amp;lt;/i&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;Выбросы, далекие от центров настоящих кластеров, все равно учитываются при вычислении их центров.&amp;lt;/p&amp;gt;&lt;br /&gt;
  &amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;&amp;lt;i&amp;gt;Возможность сходимости к локальному оптимуму&amp;lt;/i&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;Итеративный подход не дает гарантии сходимости к оптимальному решению.&amp;lt;/p&amp;gt;&lt;br /&gt;
  &amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;&amp;lt;i&amp;gt;Использование понятия &amp;quot;среднего&amp;quot;&amp;lt;/i&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;Алгоритм неприменим к данным, для которых не определено понятие &amp;quot;среднего&amp;quot;, например, категориальным данным.&amp;lt;/p&amp;gt;&lt;br /&gt;
  &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&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;
Исследование масштабируемости параллельной реализации алгоритма k means проводилось на суперкомпьютере &amp;quot;Ломоносов&amp;quot;. Алгоритм реализован на языке C с использованием средств MPI.&lt;br /&gt;
Для исследования масштабируемости проводилось множество запусков программы с разным значением параметра (количество векторов для кластеризации), а также с различным числом процессоров. Фиксировались результаты запусков &amp;amp;ndash; время работы &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt; и количество произведенных итераций алгоритма &amp;lt;math&amp;gt;\Tau&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Параметры запусков для экспериментальной оценки:&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;Значения &amp;lt;b&amp;gt;количества векторов&amp;lt;/b&amp;gt; &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;: 20&#039;000, 30&#039;000, 50&#039;000, 100&#039;000, 200&#039;000, 300&#039;000, 500&#039;000, 700&#039;000, 1&#039;000&#039;000, 1&#039;500&#039;000, 2&#039;000&#039;000.&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;Значения &amp;lt;b&amp;gt;количества процессоров&amp;lt;/b&amp;gt; &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt;: 1, 8, 16, 32, 64, 128, 160, 192, 224, 256, 288, 320, 352, 384, 416, 448, 480, 512.&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;Значение &amp;lt;b&amp;gt;количества кластеров&amp;lt;/b&amp;gt; &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt;: 100.&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;Значение &amp;lt;b&amp;gt;размерности векторов&amp;lt;/b&amp;gt; &amp;lt;math&amp;gt;d&amp;lt;/math&amp;gt;: 10.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Графики производительности и эффективности реализации представлены на рисунках 4 и 5 соответственно.&lt;br /&gt;
&lt;br /&gt;
[[file:Flops.png|thumb|center|800px|Рис. 4. График производительности реализации алгоритма.]]&lt;br /&gt;
&lt;br /&gt;
[[file:Efficiency.png|thumb|center|800px|Рис. 5. График эффективности реализации алгоритма.]]&lt;br /&gt;
&lt;br /&gt;
Для заданной конфигурации эксперимента (&amp;lt;math&amp;gt;n, d, p, k&amp;lt;/math&amp;gt;) и полученных результатах (&amp;lt;math&amp;gt;t, \Tau&amp;lt;/math&amp;gt;) производительность и эффективность реализации расчитывались по формулам (см. [[#Последовательная сложность алгоритма| последовательная сложность алгоритма]]):&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
&amp;lt;ul&amp;gt;&amp;lt;li&amp;gt;&amp;lt;math&amp;gt;Performance = \frac{\Theta_{k-means}^{d, n}}{t}\ \ FLOPS&amp;lt;/math&amp;gt;&amp;lt;/li&amp;gt;&amp;lt;/ul&amp;gt;&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
&amp;lt;ul&amp;gt;&amp;lt;li&amp;gt;&amp;lt;math&amp;gt;Efficiency = \frac{100 * Performance}{Performance_{Peak}^{p}}\ \ %,&amp;lt;/math&amp;gt;&amp;lt;/li&amp;gt;&amp;lt;/ul&amp;gt;&lt;br /&gt;
где &amp;lt;math&amp;gt;Performance_{Peak}^{p}&amp;lt;/math&amp;gt; &amp;amp;ndash; пиковая производительность суперкомпьютера при &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt; процессорах, вычисленная согласно спецификациям Intel&amp;lt;sup&amp;gt;&amp;amp;reg;&amp;lt;/sup&amp;gt; XEON&amp;lt;sup&amp;gt;&amp;amp;reg;&amp;lt;/sup&amp;gt; X5670&amp;lt;ref&amp;gt;&amp;quot;http://ark.intel.com/ru/products/47920/Intel-Xeon-Processor-X5670-12M-Cache-2_93-GHz-6_40-GTs-Intel-QPI&amp;quot;&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;В результате&amp;lt;/b&amp;gt; экспериментальной оценки были получены следующие оценки эффективности реализации:&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;b&amp;gt;Минимальное&amp;lt;/b&amp;gt; значение: 0.000409 % достигается при &amp;lt;math&amp;gt;n=20&#039;000, p=480&amp;lt;/math&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;b&amp;gt;Максимальное&amp;lt;/b&amp;gt; значение: 0.741119 % достигается при &amp;lt;math&amp;gt;n=300&#039;000, p=1&amp;lt;/math&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
Приведем оценки масштабируемости реализации алгоритма k means:&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;По числу процессоров: -0.002683 &amp;amp;ndash; эффективность убывает с ростом числа процессоров.&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;По размеру задачи: 0.002779 &amp;amp;ndash; эффективность растет с ростом числа векторов.&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;Общая оценка: -0.000058 &amp;amp;ndash; можно сделать вывод, что в целом эффективность реализации незначительно уменьшается.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Динамические характеристики и эффективность реализации алгоритма ===&lt;br /&gt;
=== Выводы для классов архитектур ===&lt;br /&gt;
=== Существующие реализации алгоритма ===&lt;br /&gt;
==== Открытое программное обеспечение ====&lt;br /&gt;
&amp;lt;ol&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;[https://www.icpsr.umich.edu/CrimeStat/ CrimeStat]&amp;lt;/li&amp;gt; Программное обеспечение, созданное для операционных систем Windows, предоставляющее инструменты статистического  и пространственного анализа для решения задачи картирования преступности.&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://juliastats.github.io Julia]&amp;lt;/li&amp;gt; Высокоуровневый высокопроизводительный свободный язык программирования с динамической типизацией, созданный для математических вычислений, содержит реализацию k-means.&lt;br /&gt;
  &amp;lt;li&amp;gt;[https://mahout.apache.org Mahout]&amp;lt;/li&amp;gt; Apache Mahout - Java библиотека для работы с алгоритмами машинного обучения с использованием MapReduce. Содержит реализацию k-means.&lt;br /&gt;
  &amp;lt;li&amp;gt;[https://www.gnu.org/software/octave/ Octave]&amp;lt;/li&amp;gt; Написанная на C++  свободная система для математических вычислений, использующая совместимый с MATLAB язык высокого уровня, содержит реализацию k-means.&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://spark.apache.org/docs/latest/mllib-clustering.html Spark]&amp;lt;/li&amp;gt; Распределенная реализация k-means содержится в библиотеке Mlib для работы с алгоритмами машинного обучения, взаимодействующая с Python библиотекой NumPy и библиотека R.&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://torch.ch Torch]&amp;lt;/li&amp;gt;  MATLAB-подобная библиотека для языка программирования Lua с открытым исходным кодом, предоставляет большое количество алгоритмов для глубинного обучения и научных расчётов. Ядро написано на Си, прикладная часть выполняется на LuaJIT, поддерживается распараллеливание вычислений средствами CUDA и OpenMP. Существуют реализации k-means.&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://www.cs.waikato.ac.nz/ml/weka/ Weka]&amp;lt;/li&amp;gt;  Cвободное программное обеспечение для анализа данных, написанное на Java. Содержит k-means и x-means.&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://accord-framework.net/docs/html/T_Accord_MachineLearning_KMeans.htm Accord.NET]&amp;lt;/li&amp;gt; C# реализация алгоритмов k-means, k-means++, k-modes.&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://docs.opencv.org/3.0-beta/doc/py_tutorials/py_ml/py_kmeans/py_kmeans_opencv/py_kmeans_opencv.html OpenCV]&amp;lt;/li&amp;gt; Написанная на С++ библиотека, направленная в основном на решение задач компьютерного зрения. Содержит реализацию k-means.&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://mlpack.org/ MLPACK]&amp;lt;/li&amp;gt; Масштабируемая С++ библиотека для работы с алгоритмами машинного обучения, содержит реализацию k-means.&lt;br /&gt;
  &amp;lt;li&amp;gt;[https://www.scipy.org/ SciPy]&amp;lt;/li&amp;gt; Библиотека Python, содержит множество реализаций k-means.&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://scikit-learn.org/ scikit-learn]&amp;lt;/li&amp;gt; Библиотека Python, содержит множество реализаций k-means.&lt;br /&gt;
  &amp;lt;li&amp;gt;[https://www.r-bloggers.com/k-means-clustering-in-r/ R]&amp;lt;/li&amp;gt; Язык программирования для статистической обработки данных и работы с графикой, а также свободная программная среда вычислений с открытым исходным кодом в рамках проекта GNU, содержит три реализации k-means.&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://elki.dbs.ifi.lmu.de ELKI]&amp;lt;/li&amp;gt; Java фреймворк, содержащий реализацию k-means, а также множество других алгоритмов кластеризации.&lt;br /&gt;
&amp;lt;/ol&amp;gt;&lt;br /&gt;
==== Проприетарное программное обеспечение  ====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ol&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;[https://www.ayasdi.com/blog/bigdata/topological-data-analysis-of-oil-and-gas-petrophysical-data/ Ayasdi]&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://www.stata.com/features/cluster-analysis/ Stata]&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://mathworld.wolfram.com/K-MeansClusteringAlgorithm.html Mathematica]&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://www.mathworks.com/help/stats/kmeans.html?requestedDomain=www.mathworks.com MATLAB]&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;[https://support.sas.com/rnd/app/stat/procedures/fastclus.html SAS]&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://docs.rapidminer.com/studio/operators/modeling/segmentation/k_means.html RapidMiner]&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;[https://blogs.sap.com/2013/03/28/sap-hana-pal-k-means-algorithm-or-how-to-do-customer-segmentation-for-the-telecommunications-industry/ SAP HANA]&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ol&amp;gt;&lt;br /&gt;
== Литература ==&lt;br /&gt;
&amp;lt;references /&amp;gt;&lt;/div&gt;</summary>
		<author><name>DennZo1993</name></author>
	</entry>
	<entry>
		<id>https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:%D0%91%D1%80%D0%BE%D1%82%D0%B8%D0%BA%D0%BE%D0%B2%D1%81%D0%BA%D0%B0%D1%8F_%D0%94%D0%B0%D0%BD%D1%83%D1%82%D0%B0/%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_k-means&amp;diff=17180</id>
		<title>Участник:Бротиковская Данута/Алгоритм k-means</title>
		<link rel="alternate" type="text/html" href="https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:%D0%91%D1%80%D0%BE%D1%82%D0%B8%D0%BA%D0%BE%D0%B2%D1%81%D0%BA%D0%B0%D1%8F_%D0%94%D0%B0%D0%BD%D1%83%D1%82%D0%B0/%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_k-means&amp;diff=17180"/>
		<updated>2016-11-15T01:34:18Z</updated>

		<summary type="html">&lt;p&gt;DennZo1993: /* Масштабируемость реализации алгоритма */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt; {{Assignment|Zhum}}&lt;br /&gt;
&lt;br /&gt;
{{algorithm&lt;br /&gt;
| name              = Алгоритм k средних (k means)&lt;br /&gt;
| serial_complexity = &amp;lt;math&amp;gt;O(\Tau*k*d*n)&amp;lt;/math&amp;gt;&lt;br /&gt;
| input_data        = &amp;lt;math&amp;gt; d*n &amp;lt;/math&amp;gt;&lt;br /&gt;
| output_data       = &amp;lt;math&amp;gt; n &amp;lt;/math&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
Авторы страницы &amp;lt;b&amp;gt;[[Участник:Бротиковская Данута|Данута Бротиковская]]&amp;lt;/b&amp;gt; и &amp;lt;b&amp;gt;[[Участник:DennZo1993|Денис Зобнин]]&amp;lt;/b&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
Оба автора внесли одинаковый вклад в написание статьи (поиск материалов, изучение статей, заполнение контента статьи), четких разграничений по пунктам статьи сделать невозможно. &lt;br /&gt;
&lt;br /&gt;
== Свойства и структура алгоритма ==&lt;br /&gt;
&lt;br /&gt;
=== Общее описание алгоритма ===&lt;br /&gt;
Алгоритм &amp;lt;b&amp;gt;&amp;lt;i&amp;gt;k средних&amp;lt;/i&amp;gt;&amp;lt;/b&amp;gt; (&amp;lt;b&amp;gt;&amp;lt;i&amp;gt;k means&amp;lt;/i&amp;gt;&amp;lt;/b&amp;gt;) &amp;amp;ndash; неиерархический&amp;lt;ref&amp;gt;&amp;quot;https://ru.wikipedia.org/wiki/Иерархическая_кластеризация&amp;quot;&amp;lt;/ref&amp;gt;, итерационный метод кластеризации&amp;lt;ref&amp;gt;&amp;quot;https://ru.wikipedia.org/wiki/Кластерный_анализ&amp;quot;&amp;lt;/ref&amp;gt;, получивший большую популярность благодаря своей простоте, наглядности реализации и достаточно высокому качеству работы. Был изобретен в 1950-х годах математиком &amp;lt;i&amp;gt;Гуго Штейнгаузом&amp;lt;/i&amp;gt;&amp;lt;ref&amp;gt;Steinhaus, Hugo. &amp;quot;Sur la division des corp materiels en parties.&amp;quot; Bull. Acad. Polon. Sci 1.804 (1956): 801.&amp;lt;/ref&amp;gt; и почти одновременно &amp;lt;i&amp;gt;Стюартом Ллойдом&amp;lt;/i&amp;gt;&amp;lt;ref&amp;gt;Lloyd, S. P. &amp;quot;Least square quantization in PCM. Bell Telephone Laboratories Paper. Published in journal much later: Lloyd, SP: Least squares quantization in PCM.&amp;quot; IEEE Trans. Inform. Theor.(1957/1982).&amp;lt;/ref&amp;gt;. Особую популярность приобрел после публикации работы &amp;lt;i&amp;gt;МакКуина&amp;lt;/i&amp;gt;&amp;lt;ref&amp;gt;MacQueen, James. &amp;quot;Some methods for classification and analysis of multivariate observations.&amp;quot; Proceedings of the fifth Berkeley symposium on mathematical statistics and probability. Vol. 1. No. 14. 1967.&amp;lt;/ref&amp;gt; в 1967.&lt;br /&gt;
&lt;br /&gt;
Алгоритм представляет собой версию EM-алгоритма&amp;lt;ref&amp;gt;&amp;quot;https://ru.wikipedia.org/wiki/EM-алгоритм&amp;quot;&amp;lt;/ref&amp;gt;, применяемого также для разделения смеси гауссиан. Основная идея &amp;lt;i&amp;gt;k means&amp;lt;/i&amp;gt; заключается в том, что данные произвольно разбиваются на кластеры, после чего итеративно перевычисляется центр масс для каждого кластера, полученного на предыдущем шаге, затем векторы разбиваются на кластеры вновь в соответствии с тем, какой из новых центров оказался ближе по выбранной метрике.&lt;br /&gt;
&lt;br /&gt;
Цель алгоритма заключается в разделении &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; наблюдений на &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластеров таким образом, чтобы каждое наблюдение принадлежало ровно одному кластеру, расположенному на наименьшем расстоянии от наблюдения.&lt;br /&gt;
&lt;br /&gt;
=== Математическое описание алгоритма ===&lt;br /&gt;
&amp;lt;b&amp;gt;&amp;lt;u&amp;gt;Дано:&amp;lt;/u&amp;gt;&amp;lt;/b&amp;gt;&lt;br /&gt;
* набор из &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; наблюдений &amp;lt;math&amp;gt;X=\{\mathbf{x}_1, \mathbf{x}_2, ..., \mathbf{x}_n\}, \mathbf{x}_i \in \mathbb{R}^d, i=\overline{1, n}&amp;lt;/math&amp;gt;;&lt;br /&gt;
* &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; - требуемое число кластеров, &amp;lt;math&amp;gt;k \in \mathbb{N}, k \leq n&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;&amp;lt;u&amp;gt;Требуется:&amp;lt;/u&amp;gt;&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Разделить множество наблюдений &amp;lt;math&amp;gt;X&amp;lt;/math&amp;gt; на &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластеров &amp;lt;math&amp;gt;S_1, S_2, ..., S_k&amp;lt;/math&amp;gt;:&lt;br /&gt;
*   &amp;lt;math&amp;gt;S_i \cap S_j= \varnothing, \quad i \ne j&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
*   &amp;lt;math&amp;gt;\bigcup_{i=1}^{k} S_i = X&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;&amp;lt;u&amp;gt;Действие алгоритма:&amp;lt;/u&amp;gt;&amp;lt;/b&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;Алгоритм &amp;lt;i&amp;gt;k means&amp;lt;/i&amp;gt; разбивает набор &amp;lt;math&amp;gt;X&amp;lt;/math&amp;gt; на &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; наборов &amp;lt;math&amp;gt;S_1, S_2, ..., S_k,&amp;lt;/math&amp;gt; таким образом, чтобы минимизировать сумму квадратов расстояний от каждой точки кластера до его центра (центр масс кластера). Введем обозначение, &amp;lt;math&amp;gt;S=\{S_1, S_2, ..., S_k\}&amp;lt;/math&amp;gt;. Тогда действие алгоритма &amp;lt;i&amp;gt;k means&amp;lt;/i&amp;gt; равносильно поиску:&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;table style=&amp;quot;width:100%&amp;quot;&amp;gt;&lt;br /&gt;
  &amp;lt;tr&amp;gt;&lt;br /&gt;
    &amp;lt;td align=&amp;quot;center&amp;quot; width=&amp;quot;90%&amp;quot;&amp;gt;&amp;lt;math&amp;gt;\arg\min_{S} \sum\limits_{i=1}^k \sum\limits_{\mathbf{x} \in S_i} \rho(\mathbf{x}, \mathbf{\mu}_i )^2,&amp;lt;/math&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;td align=&amp;quot;right&amp;quot;&amp;gt;&amp;lt;math&amp;gt;(1)&amp;lt;/math&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;/table&amp;gt;&lt;br /&gt;
где &amp;lt;math&amp;gt;\mathbf{\mu}_i&amp;lt;/math&amp;gt; &amp;amp;ndash; центры кластеров, &amp;lt;math&amp;gt;i=\overline{1,k}, \quad \rho(\mathbf{x}, \mathbf{\mu}_i)&amp;lt;/math&amp;gt; &amp;amp;ndash; функция расстояния между &amp;lt;math&amp;gt;\mathbf{x}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\mu_i&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;&amp;lt;u&amp;gt;Шаги алгоритма: &amp;lt;/u&amp;gt;&amp;lt;/b&amp;gt;&lt;br /&gt;
&amp;lt;ol&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&lt;br /&gt;
    &amp;lt;b&amp;gt;Начальный шаг: инициализация кластеров&amp;lt;/b&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;Выбирается произвольное множество точек &amp;lt;math&amp;gt;\mu_i, i=\overline{1,k}&amp;lt;/math&amp;gt;, рассматриваемых как начальные центры кластеров: &amp;lt;math&amp;gt;\mu_i^{(0)} = \mu_i, \quad i=\overline{1, k}&amp;lt;/math&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
  &amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&lt;br /&gt;
    &amp;lt;b&amp;gt;Распределение векторов по кластерам&amp;lt;/b&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Шаг&amp;lt;/b&amp;gt; &amp;lt;math&amp;gt;t: \forall \mathbf{x}_i \in X, i=\overline{1,n}: \mathbf{x}_i \in S_j \iff  j=\arg\min_{k}\rho(\mathbf{x}_i,\mathbf{\mu}_k^{(t-1)})^2&amp;lt;/math&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
  &amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&lt;br /&gt;
    &amp;lt;b&amp;gt;Пересчет центров кластеров&amp;lt;/b&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Шаг &amp;lt;/b&amp;gt; &amp;lt;math&amp;gt;t: \forall i=\overline{1,k}:  \mu_i^{(t)} = \cfrac{1}{|S_i|}\sum_{\mathbf{x}\in S_i}\mathbf{x}&amp;lt;/math&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
  &amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&lt;br /&gt;
    &amp;lt;b&amp;gt;Проверка условия останова:&amp;lt;/b&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
    &#039;&#039;&#039;if&#039;&#039;&#039; &amp;lt;math&amp;gt;\exist i\in \overline{1,k}: \mu_i^{(t)} \ne \mu_i^{(t-1)}&amp;lt;/math&amp;gt; &#039;&#039;&#039;then&#039;&#039;&#039;&lt;br /&gt;
        t = t + 1;&lt;br /&gt;
        goto 2;&lt;br /&gt;
    &#039;&#039;&#039;else&#039;&#039;&#039;&lt;br /&gt;
        &#039;&#039;&#039;stop&#039;&#039;&#039;&lt;br /&gt;
  &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ol&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Вычислительное ядро алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Вычислительным ядром являются шаги 2 и 3 приведенного выше алгоритма: &amp;lt;b&amp;gt;&amp;lt;i&amp;gt;распределение векторов по кластерам&amp;lt;/i&amp;gt;&amp;lt;/b&amp;gt; и &amp;lt;b&amp;gt;&amp;lt;i&amp;gt;пересчет центров кластеров&amp;lt;/i&amp;gt;&amp;lt;/b&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;&amp;lt;i&amp;gt;Распределение векторов&amp;lt;/i&amp;gt;&amp;lt;/b&amp;gt; по кластерам предполагает вычисление расстояний между каждым вектором &amp;lt;math&amp;gt;\mathbf{x}_i \in X, i= \overline{1,n}&amp;lt;/math&amp;gt; и центрами кластера &amp;lt;math&amp;gt;\mathbf{\mu}_j, j= \overline{1,k}&amp;lt;/math&amp;gt;. Таким образом, данный шаг предполагает &amp;lt;math&amp;gt;k*n&amp;lt;/math&amp;gt; вычислений расстояний между d-мерными векторами. &lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;&amp;lt;i&amp;gt;Пересчет центров кластеров&amp;lt;/i&amp;gt;&amp;lt;/b&amp;gt; предполагает &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; вычислений центров масс &amp;lt;math&amp;gt;\mathbf{\mu}_i&amp;lt;/math&amp;gt; множеств &amp;lt;math&amp;gt;S_i, i=\overline{1,k}&amp;lt;/math&amp;gt; представленных выражением в шаге 3 представленного выше алгоритма.&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Макроструктура алгоритма ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Инициализация центров масс &amp;lt;math&amp;gt;\mu_1, ..., \mu_k&amp;lt;/math&amp;gt;&amp;lt;/b&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
Наиболее распространенными являются следующие стратегии:&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&lt;br /&gt;
    &amp;lt;b&amp;gt;Метод Forgy&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;В качестве начальных значений &amp;lt;math&amp;gt;\mu_1, ..., \mu_k&amp;lt;/math&amp;gt; берутся случайно выбранные векторы.&lt;br /&gt;
  &amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&lt;br /&gt;
    &amp;lt;b&amp;gt;Метод случайно разделения (Random Partitioning)&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;Для каждого вектора &amp;lt;math&amp;gt;\mathbf{x}_i \in X, i=\overline{1, n}&amp;lt;/math&amp;gt; выбирается случайным образом кластер &amp;lt;math&amp;gt;S_1, ..., S_k&amp;lt;/math&amp;gt;, после чего для каждого полученного кластера вычисляются значения &amp;lt;math&amp;gt;\mu_1, ..., \mu_k&amp;lt;/math&amp;gt;.&lt;br /&gt;
  &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Распределение векторов по кластерам&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Для этого шага алгоритма между векторами &amp;lt;math&amp;gt;\mathbf{x}_i \in X, i=\overline{1, n}&amp;lt;/math&amp;gt; и центрами кластеров &amp;lt;math&amp;gt;\mu_1, ..., \mu_k&amp;lt;/math&amp;gt; вычисляются &amp;lt;b&amp;gt;расстояния&amp;lt;/b&amp;gt; по формуле (как правило, используется Евлидово расстояние):&lt;br /&gt;
&amp;lt;table style=&amp;quot;width:100%&amp;quot;&amp;gt;&lt;br /&gt;
  &amp;lt;tr&amp;gt;&lt;br /&gt;
    &amp;lt;td align=&amp;quot;center&amp;quot; width=&amp;quot;90%&amp;quot;&amp;gt;&amp;lt;math&amp;gt; \mathbf{v}_1, \mathbf{v}_2 \in \mathbb{R}^d,  \quad \rho(\mathbf{v}_1, \mathbf{v}_2) = \lVert \mathbf{v}_1- \mathbf{v}_2 \rVert= \sqrt{\sum_{i=1}^{d}(\mathbf{v}_{1,i} - \mathbf{v}_{2,i})^2}&amp;lt;/math&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;td align=&amp;quot;right&amp;quot;&amp;gt;&amp;lt;math&amp;gt;(2)&amp;lt;/math&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;/table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Пересчет центров кластеров&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Для этого шага алгоритма производится пересчет центров кластера по &amp;lt;b&amp;gt;формуле вычисления центра масс&amp;lt;/b&amp;gt;:&lt;br /&gt;
&amp;lt;table style=&amp;quot;width:100%&amp;quot;&amp;gt;&lt;br /&gt;
  &amp;lt;tr&amp;gt;&lt;br /&gt;
    &amp;lt;td align=&amp;quot;center&amp;quot; width=&amp;quot;90%&amp;quot;&amp;gt;&amp;lt;math&amp;gt; \mu = \cfrac{1}{|S|}\sum_{\mathbf{x}\in S}\mathbf{x}&amp;lt;/math&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;td align=&amp;quot;right&amp;quot;&amp;gt;&amp;lt;math&amp;gt;(3)&amp;lt;/math&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;/table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Схема реализации последовательного алгоритма ===&lt;br /&gt;
&lt;br /&gt;
 &#039;&#039;&#039;algorithm&#039;&#039;&#039; k-means &#039;&#039;&#039;is&#039;&#039;&#039;&lt;br /&gt;
     &#039;&#039;&#039;1.&#039;&#039;&#039; Инициализировать центры кластеров &amp;lt;math&amp;gt;\mathbf{\mu}_i^{(1)}, i=\overline{1,k}&amp;lt;/math&amp;gt;&lt;br /&gt;
     &#039;&#039;&#039;2.&#039;&#039;&#039; &amp;lt;math&amp;gt;t \leftarrow 1&amp;lt;/math&amp;gt;&lt;br /&gt;
     &#039;&#039;&#039;3.&#039;&#039;&#039; &#039;&#039;&#039;Распределение по кластерам&#039;&#039;&#039;&amp;lt;br&amp;gt;&lt;br /&gt;
        &amp;lt;math&amp;gt;S_i^{(t)}=\{\mathbf{x}_p: \lVert\mathbf{x}_p-\mathbf{\mu}_i^{(t)}\rVert^2 \leq \lVert\mathbf{x}_p-\mathbf{\mu}_j^{(t)}\rVert^2 \quad \forall j=\overline{1,k}\},&amp;lt;/math&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
        где каждый вектор &amp;lt;math&amp;gt;\mathbf{x}_p&amp;lt;/math&amp;gt; соотносится единственному кластеру &amp;lt;math&amp;gt;S^{(t)}&amp;lt;/math&amp;gt;&lt;br /&gt;
     &#039;&#039;&#039;4.&#039;&#039;&#039; &#039;&#039;&#039;Обновление центров кластеров&#039;&#039;&#039;&amp;lt;br&amp;gt;&lt;br /&gt;
        &amp;lt;math&amp;gt;\mathbf{\mu}_i^{(t+1)} = \frac{1}{|S^{(t)}_i|} \sum_{\mathbf{x}_j \in S^{(t)}_i} \mathbf{x}_j &amp;lt;/math&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
     &#039;&#039;&#039;5.&#039;&#039;&#039; &#039;&#039;&#039;if&#039;&#039;&#039; &amp;lt;math&amp;gt;\exist i \in \overline{1,k}: \mathbf{\mu}_i^{(t+1)} \ne \mathbf{\mu}_i^{(t)}&amp;lt;/math&amp;gt; &#039;&#039;&#039;then&#039;&#039;&#039;&lt;br /&gt;
            t = t + 1;&lt;br /&gt;
            goto &#039;&#039;&#039;3&#039;&#039;&#039;;&lt;br /&gt;
        &#039;&#039;&#039;else&#039;&#039;&#039;&lt;br /&gt;
            &#039;&#039;&#039;stop&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
=== Последовательная сложность алгоритма===&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding-bottom: 20px&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;Обозначим &amp;lt;math&amp;gt;\Theta_{centroid}^{d, m}&amp;lt;/math&amp;gt; временную сложность вычисления центорида кластера, число элементов которого равна &amp;lt;math&amp;gt;m&amp;lt;/math&amp;gt;,  в d-мерном пространстве.&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;Аналогично  &amp;lt;math&amp;gt;\Theta_{distance}^d&amp;lt;/math&amp;gt; &amp;amp;ndash; временная сложность вычисления расстояния между двумя d-мерными векторами.&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding-bottom: 20px&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;Сложность шага инициализации &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластеров мощности &amp;lt;math&amp;gt;m&amp;lt;/math&amp;gt; в d-мерном пространстве &amp;amp;ndash; &amp;lt;math&amp;gt;\Theta_{init}^{k, d, m}&amp;lt;/math&amp;gt;&amp;lt;/b&amp;gt;&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;i&amp;gt;Стратерия Forgy&amp;lt;/i&amp;gt;: вычисления не требуются, &amp;lt;math&amp;gt;\Theta_{init}^{k, d, m} = 0&amp;lt;/math&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;i&amp;gt;Стратегия случайного разбиения&amp;lt;/i&amp;gt;: вычисление центров &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластеров,  &amp;lt;math&amp;gt;\Theta_{init}^{k, d, m} = k*\Theta_{centroid}^{d, m}, m \le n&amp;lt;/math&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding-bottom: 20px&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Cложность шага распределения d мерных векторов по &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластерам &amp;amp;ndash; &amp;lt;math&amp;gt;\Theta_{distribute}^{k, d}&amp;lt;/math&amp;gt;&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
На этом шаге для каждого вектора &amp;lt;math&amp;gt;\mathbf{x}_i \in X, i=\overline{1, n}&amp;lt;/math&amp;gt; вычисляется k расстояний до центров кластеров &amp;lt;math&amp;gt;\mathbf{\mu}_1, ...\mathbf{\mu}_k&amp;lt;/math&amp;gt;&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p align=&amp;quot;center&amp;quot;&amp;gt;&lt;br /&gt;
  &amp;lt;math&amp;gt;\Theta_{distribute}^{k, d} = n*k*\Theta_{distance}^d&amp;lt;/math&amp;gt;&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding-bottom: 20px&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;Сложность шага пересчета центров &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластеров размера &amp;lt;math&amp;gt;m&amp;lt;/math&amp;gt; в d-мерном пространстве &amp;amp;ndash; &amp;lt;math&amp;gt;\Theta_{recenter}^{k, d, m}&amp;lt;/math&amp;gt;&amp;lt;/b&amp;gt;&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;На этом шаге вычисляется &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; центров кластеров &amp;lt;math&amp;gt;\mathbf{\mu}_1, ...\mathbf{\mu}_k&amp;lt;/math&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p align=&amp;quot;center&amp;quot;&amp;gt;&amp;lt;math&amp;gt;\Theta_{recenter}^{k, d, m} = k*\Theta_{centroid}^{d, m}&amp;lt;/math&amp;gt; &amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding-bottom: 20px&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Рассчитаем &amp;lt;math&amp;gt;\Theta_{centroid}^{d, m}&amp;lt;/math&amp;gt; для кластера, число элементов которого равно &amp;lt;math&amp;gt;m&amp;lt;/math&amp;gt;&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p align=&amp;quot;center&amp;quot;&amp;gt;&amp;lt;math&amp;gt;\Theta_{centroid}^{d, m}&amp;lt;/math&amp;gt; = &amp;lt;math&amp;gt;m * d&amp;lt;/math&amp;gt; сложений + &amp;lt;math&amp;gt;d&amp;lt;/math&amp;gt; делений &amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding-bottom: 20px&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Рассчитаем &amp;lt;math&amp;gt;\Theta_{distance}^d&amp;lt;/math&amp;gt; в соответствие с формулой &amp;lt;math&amp;gt;(2)&amp;lt;/math&amp;gt;&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p align=&amp;quot;center&amp;quot;&amp;gt;&amp;lt;math&amp;gt;\Theta_{distance}^d&amp;lt;/math&amp;gt; = &amp;lt;math&amp;gt;d&amp;lt;/math&amp;gt; вычитаний + &amp;lt;math&amp;gt;d&amp;lt;/math&amp;gt; умножений + &amp;lt;math&amp;gt;(d-1)&amp;lt;/math&amp;gt; сложение&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding-bottom: 20px&amp;quot;&amp;gt;&lt;br /&gt;
  &amp;lt;p&amp;gt;Предположим, что алгоритм сошелся за &amp;lt;math&amp;gt;\Tau&amp;lt;/math&amp;gt; итераций, тогда временная сложность алгоритма &amp;lt;math&amp;gt;\Theta_{k-means}^{d, n}&amp;lt;/math&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
  &amp;lt;p align=&amp;quot;center&amp;quot;&amp;gt;&amp;lt;b&amp;gt;&amp;lt;math&amp;gt;\Theta_{k-means}^{d, n} \le \Theta_{init}^{k, d, n} + \Tau*(\Theta_{distribute}^{k, d} + \Theta_{recenter}^{k, d, n})&amp;lt;/math&amp;gt;&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding-bottom: 5px&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;Операции сложения/вычитания:&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p align=&amp;quot;center&amp;quot;&amp;gt;&amp;lt;b&amp;gt;&amp;lt;math&amp;gt;\Theta_{k-means}^{d, n} \le k*n*d+ \Tau*(k*n*(2d-1) + k*n*d) = k*n*d+ \Tau*(k*n*(3d-1)) \thicksim O(\Tau*k*d*n)&amp;lt;/math&amp;gt;&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding-bottom: 20px&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;Операции умножения/деления:&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p align=&amp;quot;center&amp;quot;&amp;gt;&amp;lt;b&amp;gt;&amp;lt;math&amp;gt;\Theta_{k-means}^{d, n} \le k*d + \Tau*(k*n*d + k*d) = k*d + \Tau * k*d*(n+1) \thicksim O(\Tau*k*d*n) &amp;lt;/math&amp;gt;&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding-bottom: 20px&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;Получаем, что &amp;lt;b&amp;gt;временная сложность&amp;lt;/b&amp;gt; алгоритма &amp;lt;b&amp;gt;k means&amp;lt;/b&amp;gt; кластеризации &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; &amp;lt;b&amp;gt;d-мерных&amp;lt;/b&amp;gt; векторов на &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластеров за &amp;lt;math&amp;gt;\Tau&amp;lt;/math&amp;gt; итераций:&amp;lt;/p&amp;gt;&lt;br /&gt;
 &amp;lt;p align=&amp;quot;center&amp;quot;&amp;gt;&amp;lt;b&amp;gt;&amp;lt;math&amp;gt; \Theta_{k-means}^{d, n} \thicksim O(\Tau*k*d*n) &amp;lt;/math&amp;gt;&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Информационный граф ===&lt;br /&gt;
&lt;br /&gt;
Рассмотрим информационный граф алгоритма. Алгоритм &amp;lt;i&amp;gt;k means&amp;lt;/i&amp;gt; начинается с этапа инициализации, после которого следуют итерации, на каждой из которых выполняется два последовательных шага (см. [[#Схема реализации последовательного алгоритма|&amp;quot;Схема реализации последовательного алгоритма&amp;quot;]]): &lt;br /&gt;
* распределение векторов по кластерам&lt;br /&gt;
* перерасчет центров кластеров&lt;br /&gt;
&lt;br /&gt;
Поскольку основная часть вычислений приходится на шаги итераций, распишем информационные графы данных шагов.&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Распределение векторов по кластерам&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
Информационный граф шага распределения векторов по кластерам представлен на &#039;&#039;рисунке 1&#039;&#039;. Исходами данного графа является исходные векторы &amp;lt;math&amp;gt;\mathbf{x}_1, ..., \mathbf{x}_n&amp;lt;/math&amp;gt;, а также центры кластеров &amp;lt;math&amp;gt;\mathbf{\mu}_1, ... \mathbf{\mu}_k&amp;lt;/math&amp;gt;, вычисленные ранее (на шаге инициализации, если рассматривается первая итерация алгоритма, или на шаге пересчета центров кластеров предыдущей итерации в противном случае). Каждая пара векторов данных &amp;lt;math&amp;gt;\mathbf{x}_i, i=\overline{1,n}&amp;lt;/math&amp;gt; и центров кластера &amp;lt;math&amp;gt;\mathbf{\mu}_j, j=\overline{1, k}&amp;lt;/math&amp;gt; : (&amp;lt;math&amp;gt;\mathbf{x}_i&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;\mathbf{\mu}_j&amp;lt;/math&amp;gt;) подаются на независимые узлы &amp;lt;i&amp;gt;&amp;quot;d&amp;quot;&amp;lt;/i&amp;gt; вычисления расстояния между векторами (более подробная схема вычисления расстояния представлена далее, &#039;&#039;рисунок 2&#039;&#039;). Далее узлы вычисления расстояния &amp;lt;i&amp;gt;&amp;quot;d&amp;quot;&amp;lt;/i&amp;gt;, соответствующие одному и тому же исходному вектору &amp;lt;math&amp;gt;\mathbf{x}_i&amp;lt;/math&amp;gt; передаются на один узел &amp;lt;i&amp;gt;&amp;quot;m&amp;quot;&amp;lt;/i&amp;gt;, где далее происходит вычисление новой метки кластера для каждого вектора &amp;lt;math&amp;gt;\mathbf{x}_i&amp;lt;/math&amp;gt; (берется кластер с минимальным результатом вычисления расстояния). На выходе графа выдаются метки кластеров , &amp;lt;math&amp;gt;L_1, ..., L_n&amp;lt;/math&amp;gt;, такие что &amp;lt;math&amp;gt;\forall \mathbf{x}_i, i=\overline{1, n}, \mathbf{x}_i \in S_j \Leftrightarrow L_i = j&amp;lt;/math&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
[[file:Clusterization.png|thumb|center|800px|Рис. 1. Схема распределения векторов по кластерам. &#039;&#039;d&#039;&#039; &amp;amp;ndash; вычисление расстояния между векторами; &#039;&#039;m&#039;&#039; &amp;amp;ndash; вычисление минимума.]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Вычисление расстояния между векторами&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
Подробная схема вычисления расстояния между векторами &amp;lt;math&amp;gt;\mathbf{x}_i, \mathbf{\mu}_j&amp;lt;/math&amp;gt; представлена на &#039;&#039;рисунке 2&#039;&#039;. Как показано на графе, узел вычисления расстояния между векторами &amp;lt;i&amp;gt;&amp;quot;d&amp;quot;&amp;lt;/i&amp;gt; состоит из шага взятия разности между векторами (узел &amp;quot;&amp;lt;math&amp;gt;-&amp;lt;/math&amp;gt;&amp;quot;) и взятия нормы получившегося вектора разности (узел &amp;quot;&amp;lt;math&amp;gt;||\cdot||^2&amp;lt;/math&amp;gt;&amp;quot;). Более подробно, вычисление расстояния между векторами &amp;lt;math&amp;gt;\mathbf{x}_i = {x_{i1,}, ...,{x_{in}}}, \mathbf{\mu}_j = {\mu_{j1}, ...,\mu_{jn}}&amp;lt;/math&amp;gt; может быть представлено как вычисление разности между каждой парой компонент &amp;lt;math&amp;gt;(x_{iz}, \mu_{jz}), z=\overline{1, d}&amp;lt;/math&amp;gt; (узел &amp;quot;&amp;lt;math&amp;gt;-&amp;lt;/math&amp;gt;&amp;quot;), далее возведение в квадрат для каждого узла &amp;quot;&amp;lt;math&amp;gt;-&amp;lt;/math&amp;gt;&amp;quot; (узел &amp;quot;&amp;lt;math&amp;gt;()^2&amp;lt;/math&amp;gt;&amp;quot;) и суммирования выходов всех узлов &amp;quot;&amp;lt;math&amp;gt;()^2&amp;lt;/math&amp;gt;&amp;quot; (узел &amp;quot;&amp;lt;math&amp;gt;+&amp;lt;/math&amp;gt;&amp;quot;).  &lt;br /&gt;
&lt;br /&gt;
[[file:dist_calc.png|thumb|center|800px|Рис. 2. Схема вычисления расстояния между вектором и центром кластера.]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Пересчет центров кластеров&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
Информационный граф шага пересчета центров кластеров представлен на &#039;&#039;рисунке 3&#039;&#039;. Исходами данного графа является исходные векторы &amp;lt;math&amp;gt;\mathbf{x}_1, ..., \mathbf{x}_n&amp;lt;/math&amp;gt;, а также им соответствующие метки кластера, &amp;lt;math&amp;gt;L_1, ..., L_n&amp;lt;/math&amp;gt;, такие что &amp;lt;math&amp;gt;\forall x_i, i=\overline{1, n}, \mathbf{x}_i \in S_j \Leftrightarrow L_i = j&amp;lt;/math&amp;gt;, вычисленные на этапе распределения векторов по кластерам. Все векторы &amp;lt;math&amp;gt;\mathbf{x}_1, ..., \mathbf{x}_n&amp;lt;/math&amp;gt; подаются в узлы &amp;lt;math&amp;gt;+_1, ...+_k&amp;lt;/math&amp;gt;, каждый узел &amp;lt;math&amp;gt;+_m, m = \overline{1,k}&amp;lt;/math&amp;gt; соответствует операции сложения векторов кластера с номером &amp;lt;math&amp;gt;m&amp;lt;/math&amp;gt;. Метки кластера &amp;lt;math&amp;gt;L_1, ..., L_n&amp;lt;/math&amp;gt; также совместно передаются на узлы &amp;lt;math&amp;gt;S_m, m = \overline{1,k}&amp;lt;/math&amp;gt;, на каждом из которых вычисляется количество векторов в соответствующем кластере (количество меток с соответствующим значением). Далее каждая пара выходов узлов &amp;lt;math&amp;gt;+_m&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;S_m&amp;lt;/math&amp;gt; подается на узел &amp;quot;&amp;lt;math&amp;gt;/&amp;lt;/math&amp;gt;&amp;quot;, где производится деление суммы векторов кластера на количество элементов в нем. Значения, вычисленные на узлах &amp;quot;&amp;lt;math&amp;gt;/&amp;lt;/math&amp;gt;&amp;quot;, присваиваются новым центрам кластеров (выходные значения графа).&lt;br /&gt;
&lt;br /&gt;
[[file:Recluster.png|thumb|center|800px|Рис. 3. Схема пересчета центров кластеров]]&lt;br /&gt;
&lt;br /&gt;
=== Ресурс параллелизма алгоритма ===&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
Работа алгоритма состоит из &amp;lt;math&amp;gt;\Tau&amp;lt;/math&amp;gt; итераций, в каждой из которых происходит &amp;lt;b&amp;gt;распределение d-мерных векторов по &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластерам&amp;lt;/b&amp;gt;, а также &amp;lt;b&amp;gt;пересчет центров кластеров в d-мерном пространстве&amp;lt;/b&amp;gt;. В шаге &amp;lt;b&amp;gt;распределения d-мерных векторов по &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластерам&amp;lt;/b&amp;gt; расстояния между вектором и центрами кластеров вычисляются независимо (отсутствуют информационные зависимости). &amp;lt;b&amp;gt;Центры масс кластеров&amp;lt;/b&amp;gt; также пересчитываются независимо друг от друга. Таким образом, имеет место [[глоссарий#Массовый параллелизм|&#039;&#039;массовый параллелизм&#039;&#039;]]. Вычислим параллельную сложность &amp;lt;math&amp;gt;\Psi_*&amp;lt;/math&amp;gt; каждого из шагов, а также параллельную сложность всего алгоритма, &amp;lt;math&amp;gt;\Psi_{k-means}&amp;lt;/math&amp;gt;. Будем исходить из предположения, что может быть использовано любое необходимое число потоков.&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Распределение d-мерных векторов по &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластерам&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;  &lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
Поскольку на данном шаге для каждой пары векторов &amp;lt;math&amp;gt;\mathbf{x}_i, i=\overline{1,n}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\mathbf{\mu}_j, j=\overline{1,k}&amp;lt;/math&amp;gt; операции вычисления расстояния не зависят друг от друга, они могут выполняться параллельно. Тогда, разделив все вычисление расстояний на &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; потоков, получим, что в каждом потоке будет выполняться только одна операция вычисления расстояния между векторами размерности d. При этом каждому вычислительному потоку передаются координаты центров всех кластеров &amp;lt;math&amp;gt;\mathbf{\mu}_1, ..., \mathbf{\mu}_k&amp;lt;/math&amp;gt;. Таким образом, параллельная сложность данного шага определяется &amp;lt;i&amp;gt; сложностью параллельной операции вычисления расстояния между d-мерными векторами&amp;lt;/i&amp;gt;, &amp;lt;math&amp;gt;\Psi_{distance}^d&amp;lt;/math&amp;gt;  и &amp;lt;i&amp;gt;сложностью определения наиболее близкого кластера&amp;lt;/i&amp;gt; (паралельное взятие минимума по расстояниям), &amp;lt;math&amp;gt;\Psi_{min}^k&amp;lt;/math&amp;gt;. Для оценки &amp;lt;math&amp;gt;\Psi_{distance}^d&amp;lt;/math&amp;gt; воспользуемся  [[Нахождение_частных_сумм_элементов_массива_сдваиванием | параллельной реализацией нахождения частичной суммы элементов массива путем сдваивания]]. Аналогично, &amp;lt;math&amp;gt;\Psi_{min}^k = log(k)&amp;lt;/math&amp;gt;. В результате, &amp;lt;math&amp;gt;\Psi_{distance}^d = O(log(d))&amp;lt;/math&amp;gt;.   Таким образом: &lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p align=&amp;quot;center&amp;quot;&amp;gt;&amp;lt;math&amp;gt;\Psi_{distribute}^{k, d}  = \Psi_{distance}^d + \Psi_{min}^k = O(log(d))+O(log(k)) = O(log(k*d))&amp;lt;/math&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Пересчет центров кластеров в d-мерном пространстве&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
Поскольку на данном шаге для каждого из &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластеров центр масс может быть вычислен независимо, данные операции могут быть выполнены в отдельных потоках. Таким образом, параллельная сложность данного шага, &amp;lt;math&amp;gt;\Psi_{recenter}^{k, d}&amp;lt;/math&amp;gt;,  будет определяться &amp;lt;i&amp;gt;параллельной сложностью вычисления одного центра масс кластера размера &amp;lt;math&amp;gt;m&amp;lt;/math&amp;gt;&amp;lt;/i&amp;gt;, &amp;lt;math&amp;gt;\Psi_{recenter}^{k, d}&amp;lt;/math&amp;gt;,  а так как &amp;lt;math&amp;gt;m \le n \Rightarrow \Psi_{recenter}^{d, m} \le \Psi_{recenter}^{d, n}&amp;lt;/math&amp;gt;. Сложность вычисления центра масс кластера d-мерных векторов размера n аналогично предыдущим вычислениям равна &amp;lt;math&amp;gt;O(log(n))&amp;lt;/math&amp;gt;. Тогда:  &lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p align=&amp;quot;center&amp;quot;&amp;gt;&amp;lt;math&amp;gt;\Psi_{recenter}^{k, d}  \le \Psi_{recenter}^{d, n} = O(log(n))&amp;lt;/math&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Общая параллельная сложность алгоритма&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
На каждой итерации необходимо обновление центров кластеров, которые будут использованы на следующей итерации. Таким образом, итерационный процесс выполняется последовательно&amp;lt;ref&amp;gt;Zhao, Weizhong, Huifang Ma, and Qing He. &amp;quot;Parallel k-means clustering based on mapreduce.&amp;quot; IEEE International Conference on Cloud Computing. Springer Berlin Heidelberg, 2009.&amp;lt;/ref&amp;gt;. Тогда, поскольку сложность каждой итерации  определяется &amp;lt;math&amp;gt;\Psi_{distribute}^{k, d}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\Psi_{recenter}&amp;lt;/math&amp;gt;, сложность всего алгоритма, &amp;lt;math&amp;gt;\Psi_{k-means}&amp;lt;/math&amp;gt; в предположении, что было сделано &amp;lt;math&amp;gt;\Tau&amp;lt;/math&amp;gt; операций определяется выражением&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p align=&amp;quot;center&amp;quot;&amp;gt;&amp;lt;math&amp;gt;\Psi_{k-means} \approx \Tau * (\Psi_{distribute}^{k, d} + \Psi_{recenter}^{k, d}) \le \Tau * O(log(k*d*n))&amp;lt;/math&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Входные и выходные данные алгоритма ===&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;Входные данные&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;Матрица из &amp;lt;math&amp;gt;n*d&amp;lt;/math&amp;gt; элементов &amp;lt;math&amp;gt;x_{i, j} \in \mathbb{R}, i=\overline{1, n}, j=\overline{1, d}&amp;lt;/math&amp;gt;&amp;amp;ndash; координат векторов (наблюдений).&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;Целое положительное число &amp;lt;math&amp;gt;k, k \le n&amp;lt;/math&amp;gt; &amp;amp;ndash; количество кластеров.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;Объем входных данных&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;math&amp;gt;1&amp;lt;/math&amp;gt; целое число + &amp;lt;math&amp;gt;n*d&amp;lt;/math&amp;gt; вещественных чисел (при условии, что координаты &amp;amp;ndash; вещественные числа).&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;Выходные данные&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; целых положительных чисел &amp;lt;math&amp;gt;L_1, ..., L_n&amp;lt;/math&amp;gt;&amp;amp;ndash; номера кластеров, соотвествующие каждому вектору (при условии, что нумерация кластеров начинается с &amp;lt;math&amp;gt;1&amp;lt;/math&amp;gt;).&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;Объем выходных данных&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; целых положительных чисел.&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Свойства алгоритма ===&lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;[[глоссарий#Вычислительная мощность|&#039;&#039;Вычислительная мощность&#039;&#039;]]&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
Вычислительная мощность алгоритма &amp;lt;i&amp;gt;k means&amp;lt;/i&amp;gt; равна &amp;lt;math&amp;gt;\frac{k*d*n*\Tau}{n*d} = k*\Tau &amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; &amp;amp;ndash; число кластеров, &amp;lt;math&amp;gt;\Tau&amp;lt;/math&amp;gt; &amp;amp;ndash; число итераций алгоритма.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;[[глоссарий#Детерминированность |&#039;&#039;Детерминированность&#039;&#039;]] и [[глоссарий#Устойчивость |&#039;&#039;Устойчивость&#039;&#039;]] &amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
Алгоритм &amp;lt;i&amp;gt;k means&amp;lt;/i&amp;gt; является итерационным. Количество итераций алгоритма в общем случае не фиксируется и зависит от начального расположения объектов в пространстве, параметра &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt;, а также от начального приближения центров кластеров, &amp;lt;math&amp;gt;\mu_1, ..., \mu_k&amp;lt;/math&amp;gt;. В результате этого может варьироваться результат работы алгоритма. При неудачном выборе начальных параметров итерационный процесс может сойтись к локальному оптимуму&amp;lt;ref&amp;gt;Von Luxburg, Ulrike. Clustering Stability. Now Publishers Inc, 2010.&amp;lt;/ref&amp;gt;. По этим причинам алгоритм не является ни &amp;lt;b&amp;gt;детермирированным&amp;lt;/b&amp;gt;, ни &amp;lt;b&amp;gt;устойчивым&amp;lt;/b&amp;gt;.&lt;br /&gt;
 &lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Соотношение последовательной и параллельной сложности алгоритма&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\frac{\Theta_{k-means}}{\Psi_{k-means}} = \frac{O(\Tau*k*d*n)}{O(\Tau*log(k*d*n))}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Сильные стороны алгоритма&amp;lt;/b&amp;gt;:&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;i&amp;gt;Сравнительно высокая эффективность при простоте реализации&amp;lt;/i&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;i&amp;gt;Высокое качество кластеризации&amp;lt;/i&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;i&amp;gt;Возможность распараллеливания&amp;lt;/i&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;i&amp;gt;Существование множества модификаций&amp;lt;/i&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;Недостатки алгоритма&amp;lt;/b&amp;gt;&amp;lt;ref&amp;gt;Ortega, Joaquín Pérez, Ma Del Rocío Boone Rojas, and María J. Somodevilla. &amp;quot;Research issues on K-means Algorithm: An Experimental Trial Using Matlab.&amp;quot;&amp;lt;/ref&amp;gt;:&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;i&amp;gt;Количество кластеров является параметром алгоритма&amp;lt;/i&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;&amp;lt;i&amp;gt;Чувствительность к начальным условиям&amp;lt;/i&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;Инициализация центров кластеров в значительной степени влияет на результат кластеризации.&amp;lt;/p&amp;gt;&lt;br /&gt;
  &amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;&amp;lt;i&amp;gt;Чувствительность к выбросам и шумам&amp;lt;/i&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;Выбросы, далекие от центров настоящих кластеров, все равно учитываются при вычислении их центров.&amp;lt;/p&amp;gt;&lt;br /&gt;
  &amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;&amp;lt;i&amp;gt;Возможность сходимости к локальному оптимуму&amp;lt;/i&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;Итеративный подход не дает гарантии сходимости к оптимальному решению.&amp;lt;/p&amp;gt;&lt;br /&gt;
  &amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;&amp;lt;i&amp;gt;Использование понятия &amp;quot;среднего&amp;quot;&amp;lt;/i&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;Алгоритм неприменим к данным, для которых не определено понятие &amp;quot;среднего&amp;quot;, например, категориальным данным.&amp;lt;/p&amp;gt;&lt;br /&gt;
  &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&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;
Исследование масштабируемости параллельной реализации алгоритма k means проводилось на суперкомпьютере &amp;quot;Ломоносов&amp;quot;. Алгоритм реализован на языке C с использованием средств MPI.&lt;br /&gt;
Для исследования масштабируемости проводилось множество запусков программы с разным значением параметра (количество векторов для кластеризации), а также с различным числом процессоров. Фиксировались результаты запусков &amp;amp;ndash; время работы &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt; и количество произведенных итераций алгоритма &amp;lt;math&amp;gt;\Tau&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Параметры запусков для экспериментальной оценки:&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;Значения &amp;lt;b&amp;gt;количества векторов&amp;lt;/b&amp;gt; &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;: 20&#039;000, 30&#039;000, 50&#039;000, 100&#039;000, 200&#039;000, 300&#039;000, 500&#039;000, 700&#039;000, 1&#039;000&#039;000, 1&#039;500&#039;000, 2&#039;000&#039;000.&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;Значения &amp;lt;b&amp;gt;количества процессоров&amp;lt;/b&amp;gt; &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt;: 1, 8, 16, 32, 64, 128, 160, 192, 224, 256, 288, 320, 352, 384, 416, 448, 480, 512.&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;Значение &amp;lt;b&amp;gt;количества кластеров&amp;lt;/b&amp;gt; &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt;: 100.&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;Значение &amp;lt;b&amp;gt;размерности векторов&amp;lt;/b&amp;gt; &amp;lt;math&amp;gt;d&amp;lt;/math&amp;gt;: 10.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Графики производительности и эффективности реализации представлены на рисунках 4 и 5 соответственно.&lt;br /&gt;
&lt;br /&gt;
[[file:Flops.png|thumb|center|800px|Рис. 4. График производительности реализации алгоритма.]]&lt;br /&gt;
&lt;br /&gt;
[[file:Efficiency.png|thumb|center|800px|Рис. 5. График эффективности реализации алгоритма.]]&lt;br /&gt;
&lt;br /&gt;
Для заданной конфигурации эксперимента (&amp;lt;math&amp;gt;n, d, p, k&amp;lt;/math&amp;gt;) и полученных результатах (&amp;lt;math&amp;gt;t, \Tau&amp;lt;/math&amp;gt;) производительность и эффективность реализации расчитывались по формулам (см. [[#Последовательная сложность алгоритма| последовательная сложность алгоритма]]):&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
&amp;lt;ul&amp;gt;&amp;lt;li&amp;gt;&amp;lt;math&amp;gt;Performance = \frac{\Theta_{k-means}^{d, n}}{t}\ \ FLOPS&amp;lt;/math&amp;gt;&amp;lt;/li&amp;gt;&amp;lt;/ul&amp;gt;&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
&amp;lt;ul&amp;gt;&amp;lt;li&amp;gt;&amp;lt;math&amp;gt;Efficiency = \frac{100 * Performance}{Performance_{Peak}^{p}}\ \ %,&amp;lt;/math&amp;gt;&amp;lt;/li&amp;gt;&amp;lt;/ul&amp;gt;&lt;br /&gt;
где &amp;lt;math&amp;gt;Performance_{Peak}^{p}&amp;lt;/math&amp;gt; &amp;amp;ndash; пиковая производительность суперкомпьютера при &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt; процессорах, вычисленная согласно спецификациям Intel&amp;lt;sup&amp;gt;&amp;amp;reg;&amp;lt;/sup&amp;gt; XEON&amp;lt;sup&amp;gt;&amp;amp;reg;&amp;lt;/sup&amp;gt; X5670&amp;lt;ref&amp;gt;&amp;quot;http://ark.intel.com/ru/products/47920/Intel-Xeon-Processor-X5670-12M-Cache-2_93-GHz-6_40-GTs-Intel-QPI&amp;quot;&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;В результате&amp;lt;/b&amp;gt; экспериментальной оценки были получены следующие оценки эффективности реализации:&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;b&amp;gt;Минимальное&amp;lt;/b&amp;gt; значение: 0.000409 % достигается при &amp;lt;math&amp;gt;n=20&#039;000, p=480&amp;lt;/math&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;b&amp;gt;Максимальное&amp;lt;/b&amp;gt; значение: 0.741119 % достигается при &amp;lt;math&amp;gt;n=300&#039;000, p=1&amp;lt;/math&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
Приведем оценки масштабируемости реализации алгоритма k means:&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;По числу процессоров: -0.002683 &amp;amp;ndash; эффективность убывает с ростом числа процессоров.&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;По размеру задачи: 0.002779 &amp;amp;ndash; эффективность растет с ростом числа векторов.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Динамические характеристики и эффективность реализации алгоритма ===&lt;br /&gt;
=== Выводы для классов архитектур ===&lt;br /&gt;
=== Существующие реализации алгоритма ===&lt;br /&gt;
==== Открытое программное обеспечение ====&lt;br /&gt;
&amp;lt;ol&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;[https://www.icpsr.umich.edu/CrimeStat/ CrimeStat]&amp;lt;/li&amp;gt; Программное обеспечение, созданное для операционных систем Windows, предоставляющее инструменты статистического  и пространственного анализа для решения задачи картирования преступности.&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://juliastats.github.io Julia]&amp;lt;/li&amp;gt; Высокоуровневый высокопроизводительный свободный язык программирования с динамической типизацией, созданный для математических вычислений, содержит реализацию k-means.&lt;br /&gt;
  &amp;lt;li&amp;gt;[https://mahout.apache.org Mahout]&amp;lt;/li&amp;gt; Apache Mahout - Java библиотека для работы с алгоритмами машинного обучения с использованием MapReduce. Содержит реализацию k-means.&lt;br /&gt;
  &amp;lt;li&amp;gt;[https://www.gnu.org/software/octave/ Octave]&amp;lt;/li&amp;gt; Написанная на C++  свободная система для математических вычислений, использующая совместимый с MATLAB язык высокого уровня, содержит реализацию k-means.&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://spark.apache.org/docs/latest/mllib-clustering.html Spark]&amp;lt;/li&amp;gt; Распределенная реализация k-means содержится в библиотеке Mlib для работы с алгоритмами машинного обучения, взаимодействующая с Python библиотекой NumPy и библиотека R.&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://torch.ch Torch]&amp;lt;/li&amp;gt;  MATLAB-подобная библиотека для языка программирования Lua с открытым исходным кодом, предоставляет большое количество алгоритмов для глубинного обучения и научных расчётов. Ядро написано на Си, прикладная часть выполняется на LuaJIT, поддерживается распараллеливание вычислений средствами CUDA и OpenMP. Существуют реализации k-means.&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://www.cs.waikato.ac.nz/ml/weka/ Weka]&amp;lt;/li&amp;gt;  Cвободное программное обеспечение для анализа данных, написанное на Java. Содержит k-means и x-means.&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://accord-framework.net/docs/html/T_Accord_MachineLearning_KMeans.htm Accord.NET]&amp;lt;/li&amp;gt; C# реализация алгоритмов k-means, k-means++, k-modes.&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://docs.opencv.org/3.0-beta/doc/py_tutorials/py_ml/py_kmeans/py_kmeans_opencv/py_kmeans_opencv.html OpenCV]&amp;lt;/li&amp;gt; Написанная на С++ библиотека, направленная в основном на решение задач компьютерного зрения. Содержит реализацию k-means.&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://mlpack.org/ MLPACK]&amp;lt;/li&amp;gt; Масштабируемая С++ библиотека для работы с алгоритмами машинного обучения, содержит реализацию k-means.&lt;br /&gt;
  &amp;lt;li&amp;gt;[https://www.scipy.org/ SciPy]&amp;lt;/li&amp;gt; Библиотека Python, содержит множество реализаций k-means.&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://scikit-learn.org/ scikit-learn]&amp;lt;/li&amp;gt; Библиотека Python, содержит множество реализаций k-means.&lt;br /&gt;
  &amp;lt;li&amp;gt;[https://www.r-bloggers.com/k-means-clustering-in-r/ R]&amp;lt;/li&amp;gt; Язык программирования для статистической обработки данных и работы с графикой, а также свободная программная среда вычислений с открытым исходным кодом в рамках проекта GNU, содержит три реализации k-means.&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://elki.dbs.ifi.lmu.de ELKI]&amp;lt;/li&amp;gt; Java фреймворк, содержащий реализацию k-means, а также множество других алгоритмов кластеризации.&lt;br /&gt;
&amp;lt;/ol&amp;gt;&lt;br /&gt;
==== Проприетарное программное обеспечение  ====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ol&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;[https://www.ayasdi.com/blog/bigdata/topological-data-analysis-of-oil-and-gas-petrophysical-data/ Ayasdi]&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://www.stata.com/features/cluster-analysis/ Stata]&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://mathworld.wolfram.com/K-MeansClusteringAlgorithm.html Mathematica]&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://www.mathworks.com/help/stats/kmeans.html?requestedDomain=www.mathworks.com MATLAB]&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;[https://support.sas.com/rnd/app/stat/procedures/fastclus.html SAS]&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://docs.rapidminer.com/studio/operators/modeling/segmentation/k_means.html RapidMiner]&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;[https://blogs.sap.com/2013/03/28/sap-hana-pal-k-means-algorithm-or-how-to-do-customer-segmentation-for-the-telecommunications-industry/ SAP HANA]&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ol&amp;gt;&lt;br /&gt;
== Литература ==&lt;br /&gt;
&amp;lt;references /&amp;gt;&lt;/div&gt;</summary>
		<author><name>DennZo1993</name></author>
	</entry>
	<entry>
		<id>https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:%D0%91%D1%80%D0%BE%D1%82%D0%B8%D0%BA%D0%BE%D0%B2%D1%81%D0%BA%D0%B0%D1%8F_%D0%94%D0%B0%D0%BD%D1%83%D1%82%D0%B0/%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_k-means&amp;diff=17178</id>
		<title>Участник:Бротиковская Данута/Алгоритм k-means</title>
		<link rel="alternate" type="text/html" href="https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:%D0%91%D1%80%D0%BE%D1%82%D0%B8%D0%BA%D0%BE%D0%B2%D1%81%D0%BA%D0%B0%D1%8F_%D0%94%D0%B0%D0%BD%D1%83%D1%82%D0%B0/%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_k-means&amp;diff=17178"/>
		<updated>2016-11-15T00:07:15Z</updated>

		<summary type="html">&lt;p&gt;DennZo1993: /* Масштабируемость реализации алгоритма */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt; {{Assignment|Zhum}}&lt;br /&gt;
&lt;br /&gt;
{{algorithm&lt;br /&gt;
| name              = Алгоритм k средних (k means)&lt;br /&gt;
| serial_complexity = &amp;lt;math&amp;gt;O(\Tau*k*d*n)&amp;lt;/math&amp;gt;&lt;br /&gt;
| input_data        = &amp;lt;math&amp;gt; d*n &amp;lt;/math&amp;gt;&lt;br /&gt;
| output_data       = &amp;lt;math&amp;gt; n &amp;lt;/math&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
Авторы страницы &amp;lt;b&amp;gt;[[Участник:Бротиковская Данута|Данута Бротиковская]]&amp;lt;/b&amp;gt; и &amp;lt;b&amp;gt;[[Участник:DennZo1993|Денис Зобнин]]&amp;lt;/b&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
Оба автора внесли одинаковый вклад в написание статьи (поиск материалов, изучение статей, заполнение контента статьи), четких разграничений по пунктам статьи сделать невозможно. &lt;br /&gt;
&lt;br /&gt;
== Свойства и структура алгоритма ==&lt;br /&gt;
&lt;br /&gt;
=== Общее описание алгоритма ===&lt;br /&gt;
Алгоритм &amp;lt;b&amp;gt;&amp;lt;i&amp;gt;k средних&amp;lt;/i&amp;gt;&amp;lt;/b&amp;gt; (&amp;lt;b&amp;gt;&amp;lt;i&amp;gt;k means&amp;lt;/i&amp;gt;&amp;lt;/b&amp;gt;) &amp;amp;ndash; неиерархический&amp;lt;ref&amp;gt;&amp;quot;https://ru.wikipedia.org/wiki/Иерархическая_кластеризация&amp;quot;&amp;lt;/ref&amp;gt;, итерационный метод кластеризации&amp;lt;ref&amp;gt;&amp;quot;https://ru.wikipedia.org/wiki/Кластерный_анализ&amp;quot;&amp;lt;/ref&amp;gt;, получивший большую популярность благодаря своей простоте, наглядности реализации и достаточно высокому качеству работы. Был изобретен в 1950-х годах математиком &amp;lt;i&amp;gt;Гуго Штейнгаузом&amp;lt;/i&amp;gt;&amp;lt;ref&amp;gt;Steinhaus, Hugo. &amp;quot;Sur la division des corp materiels en parties.&amp;quot; Bull. Acad. Polon. Sci 1.804 (1956): 801.&amp;lt;/ref&amp;gt; и почти одновременно &amp;lt;i&amp;gt;Стюартом Ллойдом&amp;lt;/i&amp;gt;&amp;lt;ref&amp;gt;Lloyd, S. P. &amp;quot;Least square quantization in PCM. Bell Telephone Laboratories Paper. Published in journal much later: Lloyd, SP: Least squares quantization in PCM.&amp;quot; IEEE Trans. Inform. Theor.(1957/1982).&amp;lt;/ref&amp;gt;. Особую популярность приобрел после публикации работы &amp;lt;i&amp;gt;МакКуина&amp;lt;/i&amp;gt;&amp;lt;ref&amp;gt;MacQueen, James. &amp;quot;Some methods for classification and analysis of multivariate observations.&amp;quot; Proceedings of the fifth Berkeley symposium on mathematical statistics and probability. Vol. 1. No. 14. 1967.&amp;lt;/ref&amp;gt; в 1967.&lt;br /&gt;
&lt;br /&gt;
Алгоритм представляет собой версию EM-алгоритма&amp;lt;ref&amp;gt;&amp;quot;https://ru.wikipedia.org/wiki/EM-алгоритм&amp;quot;&amp;lt;/ref&amp;gt;, применяемого также для разделения смеси гауссиан. Основная идея &amp;lt;i&amp;gt;k means&amp;lt;/i&amp;gt; заключается в том, что данные произвольно разбиваются на кластеры, после чего итеративно перевычисляется центр масс для каждого кластера, полученного на предыдущем шаге, затем векторы разбиваются на кластеры вновь в соответствии с тем, какой из новых центров оказался ближе по выбранной метрике.&lt;br /&gt;
&lt;br /&gt;
Цель алгоритма заключается в разделении &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; наблюдений на &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластеров таким образом, чтобы каждое наблюдение принадлежало ровно одному кластеру, расположенному на наименьшем расстоянии от наблюдения.&lt;br /&gt;
&lt;br /&gt;
=== Математическое описание алгоритма ===&lt;br /&gt;
&amp;lt;b&amp;gt;&amp;lt;u&amp;gt;Дано:&amp;lt;/u&amp;gt;&amp;lt;/b&amp;gt;&lt;br /&gt;
* набор из &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; наблюдений &amp;lt;math&amp;gt;X=\{\mathbf{x}_1, \mathbf{x}_2, ..., \mathbf{x}_n\}, \mathbf{x}_i \in \mathbb{R}^d, i=\overline{1, n}&amp;lt;/math&amp;gt;;&lt;br /&gt;
* &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; - требуемое число кластеров, &amp;lt;math&amp;gt;k \in \mathbb{N}, k \leq n&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;&amp;lt;u&amp;gt;Требуется:&amp;lt;/u&amp;gt;&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Разделить множество наблюдений &amp;lt;math&amp;gt;X&amp;lt;/math&amp;gt; на &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластеров &amp;lt;math&amp;gt;S_1, S_2, ..., S_k&amp;lt;/math&amp;gt;:&lt;br /&gt;
*   &amp;lt;math&amp;gt;S_i \cap S_j= \varnothing, \quad i \ne j&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
*   &amp;lt;math&amp;gt;\bigcup_{i=1}^{k} S_i = X&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;&amp;lt;u&amp;gt;Действие алгоритма:&amp;lt;/u&amp;gt;&amp;lt;/b&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;Алгоритм &amp;lt;i&amp;gt;k means&amp;lt;/i&amp;gt; разбивает набор &amp;lt;math&amp;gt;X&amp;lt;/math&amp;gt; на &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; наборов &amp;lt;math&amp;gt;S_1, S_2, ..., S_k,&amp;lt;/math&amp;gt; таким образом, чтобы минимизировать сумму квадратов расстояний от каждой точки кластера до его центра (центр масс кластера). Введем обозначение, &amp;lt;math&amp;gt;S=\{S_1, S_2, ..., S_k\}&amp;lt;/math&amp;gt;. Тогда действие алгоритма &amp;lt;i&amp;gt;k means&amp;lt;/i&amp;gt; равносильно поиску:&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;table style=&amp;quot;width:100%&amp;quot;&amp;gt;&lt;br /&gt;
  &amp;lt;tr&amp;gt;&lt;br /&gt;
    &amp;lt;td align=&amp;quot;center&amp;quot; width=&amp;quot;90%&amp;quot;&amp;gt;&amp;lt;math&amp;gt;\arg\min_{S} \sum\limits_{i=1}^k \sum\limits_{\mathbf{x} \in S_i} \rho(\mathbf{x}, \mathbf{\mu}_i )^2,&amp;lt;/math&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;td align=&amp;quot;right&amp;quot;&amp;gt;&amp;lt;math&amp;gt;(1)&amp;lt;/math&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;/table&amp;gt;&lt;br /&gt;
где &amp;lt;math&amp;gt;\mathbf{\mu}_i&amp;lt;/math&amp;gt; &amp;amp;ndash; центры кластеров, &amp;lt;math&amp;gt;i=\overline{1,k}, \quad \rho(\mathbf{x}, \mathbf{\mu}_i)&amp;lt;/math&amp;gt; &amp;amp;ndash; функция расстояния между &amp;lt;math&amp;gt;\mathbf{x}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\mu_i&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;&amp;lt;u&amp;gt;Шаги алгоритма: &amp;lt;/u&amp;gt;&amp;lt;/b&amp;gt;&lt;br /&gt;
&amp;lt;ol&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&lt;br /&gt;
    &amp;lt;b&amp;gt;Начальный шаг: инициализация кластеров&amp;lt;/b&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;Выбирается произвольное множество точек &amp;lt;math&amp;gt;\mu_i, i=\overline{1,k}&amp;lt;/math&amp;gt;, рассматриваемых как начальные центры кластеров: &amp;lt;math&amp;gt;\mu_i^{(0)} = \mu_i, \quad i=\overline{1, k}&amp;lt;/math&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
  &amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&lt;br /&gt;
    &amp;lt;b&amp;gt;Распределение векторов по кластерам&amp;lt;/b&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Шаг&amp;lt;/b&amp;gt; &amp;lt;math&amp;gt;t: \forall \mathbf{x}_i \in X, i=\overline{1,n}: \mathbf{x}_i \in S_j \iff  j=\arg\min_{k}\rho(\mathbf{x}_i,\mathbf{\mu}_k^{(t-1)})^2&amp;lt;/math&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
  &amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&lt;br /&gt;
    &amp;lt;b&amp;gt;Пересчет центров кластеров&amp;lt;/b&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Шаг &amp;lt;/b&amp;gt; &amp;lt;math&amp;gt;t: \forall i=\overline{1,k}:  \mu_i^{(t)} = \cfrac{1}{|S_i|}\sum_{\mathbf{x}\in S_i}\mathbf{x}&amp;lt;/math&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
  &amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&lt;br /&gt;
    &amp;lt;b&amp;gt;Проверка условия останова:&amp;lt;/b&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
    &#039;&#039;&#039;if&#039;&#039;&#039; &amp;lt;math&amp;gt;\exist i\in \overline{1,k}: \mu_i^{(t)} \ne \mu_i^{(t-1)}&amp;lt;/math&amp;gt; &#039;&#039;&#039;then&#039;&#039;&#039;&lt;br /&gt;
        t = t + 1;&lt;br /&gt;
        goto 2;&lt;br /&gt;
    &#039;&#039;&#039;else&#039;&#039;&#039;&lt;br /&gt;
        &#039;&#039;&#039;stop&#039;&#039;&#039;&lt;br /&gt;
  &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ol&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Вычислительное ядро алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Вычислительным ядром являются шаги 2 и 3 приведенного выше алгоритма: &amp;lt;b&amp;gt;&amp;lt;i&amp;gt;распределение векторов по кластерам&amp;lt;/i&amp;gt;&amp;lt;/b&amp;gt; и &amp;lt;b&amp;gt;&amp;lt;i&amp;gt;пересчет центров кластеров&amp;lt;/i&amp;gt;&amp;lt;/b&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;&amp;lt;i&amp;gt;Распределение векторов&amp;lt;/i&amp;gt;&amp;lt;/b&amp;gt; по кластерам предполагает вычисление расстояний между каждым вектором &amp;lt;math&amp;gt;\mathbf{x}_i \in X, i= \overline{1,n}&amp;lt;/math&amp;gt; и центрами кластера &amp;lt;math&amp;gt;\mathbf{\mu}_j, j= \overline{1,k}&amp;lt;/math&amp;gt;. Таким образом, данный шаг предполагает &amp;lt;math&amp;gt;k*n&amp;lt;/math&amp;gt; вычислений расстояний между d-мерными векторами. &lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;&amp;lt;i&amp;gt;Пересчет центров кластеров&amp;lt;/i&amp;gt;&amp;lt;/b&amp;gt; предполагает &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; вычислений центров масс &amp;lt;math&amp;gt;\mathbf{\mu}_i&amp;lt;/math&amp;gt; множеств &amp;lt;math&amp;gt;S_i, i=\overline{1,k}&amp;lt;/math&amp;gt; представленных выражением в шаге 3 представленного выше алгоритма.&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Макроструктура алгоритма ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Инициализация центров масс &amp;lt;math&amp;gt;\mu_1, ..., \mu_k&amp;lt;/math&amp;gt;&amp;lt;/b&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
Наиболее распространенными являются следующие стратегии:&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&lt;br /&gt;
    &amp;lt;b&amp;gt;Метод Forgy&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;В качестве начальных значений &amp;lt;math&amp;gt;\mu_1, ..., \mu_k&amp;lt;/math&amp;gt; берутся случайно выбранные векторы.&lt;br /&gt;
  &amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&lt;br /&gt;
    &amp;lt;b&amp;gt;Метод случайно разделения (Random Partitioning)&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;Для каждого вектора &amp;lt;math&amp;gt;\mathbf{x}_i \in X, i=\overline{1, n}&amp;lt;/math&amp;gt; выбирается случайным образом кластер &amp;lt;math&amp;gt;S_1, ..., S_k&amp;lt;/math&amp;gt;, после чего для каждого полученного кластера вычисляются значения &amp;lt;math&amp;gt;\mu_1, ..., \mu_k&amp;lt;/math&amp;gt;.&lt;br /&gt;
  &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Распределение векторов по кластерам&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Для этого шага алгоритма между векторами &amp;lt;math&amp;gt;\mathbf{x}_i \in X, i=\overline{1, n}&amp;lt;/math&amp;gt; и центрами кластеров &amp;lt;math&amp;gt;\mu_1, ..., \mu_k&amp;lt;/math&amp;gt; вычисляются &amp;lt;b&amp;gt;расстояния&amp;lt;/b&amp;gt; по формуле (как правило, используется Евлидово расстояние):&lt;br /&gt;
&amp;lt;table style=&amp;quot;width:100%&amp;quot;&amp;gt;&lt;br /&gt;
  &amp;lt;tr&amp;gt;&lt;br /&gt;
    &amp;lt;td align=&amp;quot;center&amp;quot; width=&amp;quot;90%&amp;quot;&amp;gt;&amp;lt;math&amp;gt; \mathbf{v}_1, \mathbf{v}_2 \in \mathbb{R}^d,  \quad \rho(\mathbf{v}_1, \mathbf{v}_2) = \lVert \mathbf{v}_1- \mathbf{v}_2 \rVert= \sqrt{\sum_{i=1}^{d}(\mathbf{v}_{1,i} - \mathbf{v}_{2,i})^2}&amp;lt;/math&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;td align=&amp;quot;right&amp;quot;&amp;gt;&amp;lt;math&amp;gt;(2)&amp;lt;/math&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;/table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Пересчет центров кластеров&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Для этого шага алгоритма производится пересчет центров кластера по &amp;lt;b&amp;gt;формуле вычисления центра масс&amp;lt;/b&amp;gt;:&lt;br /&gt;
&amp;lt;table style=&amp;quot;width:100%&amp;quot;&amp;gt;&lt;br /&gt;
  &amp;lt;tr&amp;gt;&lt;br /&gt;
    &amp;lt;td align=&amp;quot;center&amp;quot; width=&amp;quot;90%&amp;quot;&amp;gt;&amp;lt;math&amp;gt; \mu = \cfrac{1}{|S|}\sum_{\mathbf{x}\in S}\mathbf{x}&amp;lt;/math&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;td align=&amp;quot;right&amp;quot;&amp;gt;&amp;lt;math&amp;gt;(3)&amp;lt;/math&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;/table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Схема реализации последовательного алгоритма ===&lt;br /&gt;
&lt;br /&gt;
 &#039;&#039;&#039;algorithm&#039;&#039;&#039; k-means &#039;&#039;&#039;is&#039;&#039;&#039;&lt;br /&gt;
     &#039;&#039;&#039;1.&#039;&#039;&#039; Инициализировать центры кластеров &amp;lt;math&amp;gt;\mathbf{\mu}_i^{(1)}, i=\overline{1,k}&amp;lt;/math&amp;gt;&lt;br /&gt;
     &#039;&#039;&#039;2.&#039;&#039;&#039; &amp;lt;math&amp;gt;t \leftarrow 1&amp;lt;/math&amp;gt;&lt;br /&gt;
     &#039;&#039;&#039;3.&#039;&#039;&#039; &#039;&#039;&#039;Распределение по кластерам&#039;&#039;&#039;&amp;lt;br&amp;gt;&lt;br /&gt;
        &amp;lt;math&amp;gt;S_i^{(t)}=\{\mathbf{x}_p: \lVert\mathbf{x}_p-\mathbf{\mu}_i^{(t)}\rVert^2 \leq \lVert\mathbf{x}_p-\mathbf{\mu}_j^{(t)}\rVert^2 \quad \forall j=\overline{1,k}\},&amp;lt;/math&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
        где каждый вектор &amp;lt;math&amp;gt;\mathbf{x}_p&amp;lt;/math&amp;gt; соотносится единственному кластеру &amp;lt;math&amp;gt;S^{(t)}&amp;lt;/math&amp;gt;&lt;br /&gt;
     &#039;&#039;&#039;4.&#039;&#039;&#039; &#039;&#039;&#039;Обновление центров кластеров&#039;&#039;&#039;&amp;lt;br&amp;gt;&lt;br /&gt;
        &amp;lt;math&amp;gt;\mathbf{\mu}_i^{(t+1)} = \frac{1}{|S^{(t)}_i|} \sum_{\mathbf{x}_j \in S^{(t)}_i} \mathbf{x}_j &amp;lt;/math&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
     &#039;&#039;&#039;5.&#039;&#039;&#039; &#039;&#039;&#039;if&#039;&#039;&#039; &amp;lt;math&amp;gt;\exist i \in \overline{1,k}: \mathbf{\mu}_i^{(t+1)} \ne \mathbf{\mu}_i^{(t)}&amp;lt;/math&amp;gt; &#039;&#039;&#039;then&#039;&#039;&#039;&lt;br /&gt;
            t = t + 1;&lt;br /&gt;
            goto &#039;&#039;&#039;3&#039;&#039;&#039;;&lt;br /&gt;
        &#039;&#039;&#039;else&#039;&#039;&#039;&lt;br /&gt;
            &#039;&#039;&#039;stop&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
=== Последовательная сложность алгоритма===&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding-bottom: 20px&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;Обозначим &amp;lt;math&amp;gt;\Theta_{centroid}^{d, m}&amp;lt;/math&amp;gt; временную сложность вычисления центорида кластера, число элементов которого равна &amp;lt;math&amp;gt;m&amp;lt;/math&amp;gt;,  в d-мерном пространстве.&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;Аналогично  &amp;lt;math&amp;gt;\Theta_{distance}^d&amp;lt;/math&amp;gt; &amp;amp;ndash; временная сложность вычисления расстояния между двумя d-мерными векторами.&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding-bottom: 20px&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;Сложность шага инициализации &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластеров мощности &amp;lt;math&amp;gt;m&amp;lt;/math&amp;gt; в d-мерном пространстве &amp;amp;ndash; &amp;lt;math&amp;gt;\Theta_{init}^{k, d, m}&amp;lt;/math&amp;gt;&amp;lt;/b&amp;gt;&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;i&amp;gt;Стратерия Forgy&amp;lt;/i&amp;gt;: вычисления не требуются, &amp;lt;math&amp;gt;\Theta_{init}^{k, d, m} = 0&amp;lt;/math&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;i&amp;gt;Стратегия случайного разбиения&amp;lt;/i&amp;gt;: вычисление центров &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластеров,  &amp;lt;math&amp;gt;\Theta_{init}^{k, d, m} = k*\Theta_{centroid}^{d, m}, m \le n&amp;lt;/math&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding-bottom: 20px&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Cложность шага распределения d мерных векторов по &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластерам &amp;amp;ndash; &amp;lt;math&amp;gt;\Theta_{distribute}^{k, d}&amp;lt;/math&amp;gt;&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
На этом шаге для каждого вектора &amp;lt;math&amp;gt;\mathbf{x}_i \in X, i=\overline{1, n}&amp;lt;/math&amp;gt; вычисляется k расстояний до центров кластеров &amp;lt;math&amp;gt;\mathbf{\mu}_1, ...\mathbf{\mu}_k&amp;lt;/math&amp;gt;&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p align=&amp;quot;center&amp;quot;&amp;gt;&lt;br /&gt;
  &amp;lt;math&amp;gt;\Theta_{distribute}^{k, d} = n*k*\Theta_{distance}^d&amp;lt;/math&amp;gt;&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding-bottom: 20px&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;Сложность шага пересчета центров &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластеров размера &amp;lt;math&amp;gt;m&amp;lt;/math&amp;gt; в d-мерном пространстве &amp;amp;ndash; &amp;lt;math&amp;gt;\Theta_{recenter}^{k, d, m}&amp;lt;/math&amp;gt;&amp;lt;/b&amp;gt;&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;На этом шаге вычисляется &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; центров кластеров &amp;lt;math&amp;gt;\mathbf{\mu}_1, ...\mathbf{\mu}_k&amp;lt;/math&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p align=&amp;quot;center&amp;quot;&amp;gt;&amp;lt;math&amp;gt;\Theta_{recenter}^{k, d, m} = k*\Theta_{centroid}^{d, m}&amp;lt;/math&amp;gt; &amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding-bottom: 20px&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Рассчитаем &amp;lt;math&amp;gt;\Theta_{centroid}^{d, m}&amp;lt;/math&amp;gt; для кластера, число элементов которого равно &amp;lt;math&amp;gt;m&amp;lt;/math&amp;gt;&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p align=&amp;quot;center&amp;quot;&amp;gt;&amp;lt;math&amp;gt;\Theta_{centroid}^{d, m}&amp;lt;/math&amp;gt; = &amp;lt;math&amp;gt;m * d&amp;lt;/math&amp;gt; сложений + &amp;lt;math&amp;gt;d&amp;lt;/math&amp;gt; делений &amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding-bottom: 20px&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Рассчитаем &amp;lt;math&amp;gt;\Theta_{distance}^d&amp;lt;/math&amp;gt; в соответствие с формулой &amp;lt;math&amp;gt;(2)&amp;lt;/math&amp;gt;&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p align=&amp;quot;center&amp;quot;&amp;gt;&amp;lt;math&amp;gt;\Theta_{distance}^d&amp;lt;/math&amp;gt; = &amp;lt;math&amp;gt;d&amp;lt;/math&amp;gt; вычитаний + &amp;lt;math&amp;gt;d&amp;lt;/math&amp;gt; умножений + &amp;lt;math&amp;gt;(d-1)&amp;lt;/math&amp;gt; сложение&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding-bottom: 20px&amp;quot;&amp;gt;&lt;br /&gt;
  &amp;lt;p&amp;gt;Предположим, что алгоритм сошелся за &amp;lt;math&amp;gt;\Tau&amp;lt;/math&amp;gt; итераций, тогда временная сложность алгоритма &amp;lt;math&amp;gt;\Theta_{k-means}^{d, n}&amp;lt;/math&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
  &amp;lt;p align=&amp;quot;center&amp;quot;&amp;gt;&amp;lt;b&amp;gt;&amp;lt;math&amp;gt;\Theta_{k-means}^{d, n} \le \Theta_{init}^{k, d, n} + \Tau*(\Theta_{distribute}^{k, d} + \Theta_{recenter}^{k, d, n})&amp;lt;/math&amp;gt;&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding-bottom: 5px&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;Операции сложения/вычитания:&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p align=&amp;quot;center&amp;quot;&amp;gt;&amp;lt;b&amp;gt;&amp;lt;math&amp;gt;\Theta_{k-means}^{d, n} \le k*n*d+ \Tau*(k*n*(2d-1) + k*n*d) = k*n*d+ \Tau*(k*n*(3d-1)) \thicksim O(\Tau*k*d*n)&amp;lt;/math&amp;gt;&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding-bottom: 20px&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;Операции умножения/деления:&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p align=&amp;quot;center&amp;quot;&amp;gt;&amp;lt;b&amp;gt;&amp;lt;math&amp;gt;\Theta_{k-means}^{d, n} \le k*d + \Tau*(k*n*d + k*d) = k*d + \Tau * k*d*(n+1) \thicksim O(\Tau*k*d*n) &amp;lt;/math&amp;gt;&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding-bottom: 20px&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;Получаем, что &amp;lt;b&amp;gt;временная сложность&amp;lt;/b&amp;gt; алгоритма &amp;lt;b&amp;gt;k means&amp;lt;/b&amp;gt; кластеризации &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; &amp;lt;b&amp;gt;d-мерных&amp;lt;/b&amp;gt; векторов на &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластеров за &amp;lt;math&amp;gt;\Tau&amp;lt;/math&amp;gt; итераций:&amp;lt;/p&amp;gt;&lt;br /&gt;
 &amp;lt;p align=&amp;quot;center&amp;quot;&amp;gt;&amp;lt;b&amp;gt;&amp;lt;math&amp;gt; \Theta_{k-means}^{d, n} \thicksim O(\Tau*k*d*n) &amp;lt;/math&amp;gt;&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Информационный граф ===&lt;br /&gt;
&lt;br /&gt;
Рассмотрим информационный граф алгоритма. Алгоритм &amp;lt;i&amp;gt;k means&amp;lt;/i&amp;gt; начинается с этапа инициализации, после которого следуют итерации, на каждой из которых выполняется два последовательных шага (см. [[#Схема реализации последовательного алгоритма|&amp;quot;Схема реализации последовательного алгоритма&amp;quot;]]): &lt;br /&gt;
* распределение векторов по кластерам&lt;br /&gt;
* перерасчет центров кластеров&lt;br /&gt;
&lt;br /&gt;
Поскольку основная часть вычислений приходится на шаги итераций, распишем информационные графы данных шагов.&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Распределение векторов по кластерам&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
Информационный граф шага распределения векторов по кластерам представлен на &#039;&#039;рисунке 1&#039;&#039;. Исходами данного графа является исходные векторы &amp;lt;math&amp;gt;\mathbf{x}_1, ..., \mathbf{x}_n&amp;lt;/math&amp;gt;, а также центры кластеров &amp;lt;math&amp;gt;\mathbf{\mu}_1, ... \mathbf{\mu}_k&amp;lt;/math&amp;gt;, вычисленные ранее (на шаге инициализации, если рассматривается первая итерация алгоритма, или на шаге пересчета центров кластеров предыдущей итерации в противном случае). Каждая пара векторов данных &amp;lt;math&amp;gt;\mathbf{x}_i, i=\overline{1,n}&amp;lt;/math&amp;gt; и центров кластера &amp;lt;math&amp;gt;\mathbf{\mu}_j, j=\overline{1, k}&amp;lt;/math&amp;gt; : (&amp;lt;math&amp;gt;\mathbf{x}_i&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;\mathbf{\mu}_j&amp;lt;/math&amp;gt;) подаются на независимые узлы &amp;lt;i&amp;gt;&amp;quot;d&amp;quot;&amp;lt;/i&amp;gt; вычисления расстояния между векторами (более подробная схема вычисления расстояния представлена далее, &#039;&#039;рисунок 2&#039;&#039;). Далее узлы вычисления расстояния &amp;lt;i&amp;gt;&amp;quot;d&amp;quot;&amp;lt;/i&amp;gt;, соответствующие одному и тому же исходному вектору &amp;lt;math&amp;gt;\mathbf{x}_i&amp;lt;/math&amp;gt; передаются на один узел &amp;lt;i&amp;gt;&amp;quot;m&amp;quot;&amp;lt;/i&amp;gt;, где далее происходит вычисление новой метки кластера для каждого вектора &amp;lt;math&amp;gt;\mathbf{x}_i&amp;lt;/math&amp;gt; (берется кластер с минимальным результатом вычисления расстояния). На выходе графа выдаются метки кластеров , &amp;lt;math&amp;gt;L_1, ..., L_n&amp;lt;/math&amp;gt;, такие что &amp;lt;math&amp;gt;\forall \mathbf{x}_i, i=\overline{1, n}, \mathbf{x}_i \in S_j \Leftrightarrow L_i = j&amp;lt;/math&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
[[file:Clusterization.png|thumb|center|800px|Рис. 1. Схема распределения векторов по кластерам. &#039;&#039;d&#039;&#039; &amp;amp;ndash; вычисление расстояния между векторами; &#039;&#039;m&#039;&#039; &amp;amp;ndash; вычисление минимума.]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Вычисление расстояния между векторами&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
Подробная схема вычисления расстояния между векторами &amp;lt;math&amp;gt;\mathbf{x}_i, \mathbf{\mu}_j&amp;lt;/math&amp;gt; представлена на &#039;&#039;рисунке 2&#039;&#039;. Как показано на графе, узел вычисления расстояния между векторами &amp;lt;i&amp;gt;&amp;quot;d&amp;quot;&amp;lt;/i&amp;gt; состоит из шага взятия разности между векторами (узел &amp;quot;&amp;lt;math&amp;gt;-&amp;lt;/math&amp;gt;&amp;quot;) и взятия нормы получившегося вектора разности (узел &amp;quot;&amp;lt;math&amp;gt;||\cdot||^2&amp;lt;/math&amp;gt;&amp;quot;). Более подробно, вычисление расстояния между векторами &amp;lt;math&amp;gt;\mathbf{x}_i = {x_{i1,}, ...,{x_{in}}}, \mathbf{\mu}_j = {\mu_{j1}, ...,\mu_{jn}}&amp;lt;/math&amp;gt; может быть представлено как вычисление разности между каждой парой компонент &amp;lt;math&amp;gt;(x_{iz}, \mu_{jz}), z=\overline{1, d}&amp;lt;/math&amp;gt; (узел &amp;quot;&amp;lt;math&amp;gt;-&amp;lt;/math&amp;gt;&amp;quot;), далее возведение в квадрат для каждого узла &amp;quot;&amp;lt;math&amp;gt;-&amp;lt;/math&amp;gt;&amp;quot; (узел &amp;quot;&amp;lt;math&amp;gt;()^2&amp;lt;/math&amp;gt;&amp;quot;) и суммирования выходов всех узлов &amp;quot;&amp;lt;math&amp;gt;()^2&amp;lt;/math&amp;gt;&amp;quot; (узел &amp;quot;&amp;lt;math&amp;gt;+&amp;lt;/math&amp;gt;&amp;quot;).  &lt;br /&gt;
&lt;br /&gt;
[[file:dist_calc.png|thumb|center|800px|Рис. 2. Схема вычисления расстояния между вектором и центром кластера.]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Пересчет центров кластеров&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
Информационный граф шага пересчета центров кластеров представлен на &#039;&#039;рисунке 3&#039;&#039;. Исходами данного графа является исходные векторы &amp;lt;math&amp;gt;\mathbf{x}_1, ..., \mathbf{x}_n&amp;lt;/math&amp;gt;, а также им соответствующие метки кластера, &amp;lt;math&amp;gt;L_1, ..., L_n&amp;lt;/math&amp;gt;, такие что &amp;lt;math&amp;gt;\forall x_i, i=\overline{1, n}, \mathbf{x}_i \in S_j \Leftrightarrow L_i = j&amp;lt;/math&amp;gt;, вычисленные на этапе распределения векторов по кластерам. Все векторы &amp;lt;math&amp;gt;\mathbf{x}_1, ..., \mathbf{x}_n&amp;lt;/math&amp;gt; подаются в узлы &amp;lt;math&amp;gt;+_1, ...+_k&amp;lt;/math&amp;gt;, каждый узел &amp;lt;math&amp;gt;+_m, m = \overline{1,k}&amp;lt;/math&amp;gt; соответствует операции сложения векторов кластера с номером &amp;lt;math&amp;gt;m&amp;lt;/math&amp;gt;. Метки кластера &amp;lt;math&amp;gt;L_1, ..., L_n&amp;lt;/math&amp;gt; также совместно передаются на узлы &amp;lt;math&amp;gt;S_m, m = \overline{1,k}&amp;lt;/math&amp;gt;, на каждом из которых вычисляется количество векторов в соответствующем кластере (количество меток с соответствующим значением). Далее каждая пара выходов узлов &amp;lt;math&amp;gt;+_m&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;S_m&amp;lt;/math&amp;gt; подается на узел &amp;quot;&amp;lt;math&amp;gt;/&amp;lt;/math&amp;gt;&amp;quot;, где производится деление суммы векторов кластера на количество элементов в нем. Значения, вычисленные на узлах &amp;quot;&amp;lt;math&amp;gt;/&amp;lt;/math&amp;gt;&amp;quot;, присваиваются новым центрам кластеров (выходные значения графа).&lt;br /&gt;
&lt;br /&gt;
[[file:Recluster.png|thumb|center|800px|Рис. 3. Схема пересчета центров кластеров]]&lt;br /&gt;
&lt;br /&gt;
=== Ресурс параллелизма алгоритма ===&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
Работа алгоритма состоит из &amp;lt;math&amp;gt;\Tau&amp;lt;/math&amp;gt; итераций, в каждой из которых происходит &amp;lt;b&amp;gt;распределение d-мерных векторов по &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластерам&amp;lt;/b&amp;gt;, а также &amp;lt;b&amp;gt;пересчет центров кластеров в d-мерном пространстве&amp;lt;/b&amp;gt;. В шаге &amp;lt;b&amp;gt;распределения d-мерных векторов по &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластерам&amp;lt;/b&amp;gt; расстояния между вектором и центрами кластеров вычисляются независимо (отсутствуют информационные зависимости). &amp;lt;b&amp;gt;Центры масс кластеров&amp;lt;/b&amp;gt; также пересчитываются независимо друг от друга. Таким образом, имеет место [[глоссарий#Массовый параллелизм|&#039;&#039;массовый параллелизм&#039;&#039;]]. Вычислим параллельную сложность &amp;lt;math&amp;gt;\Psi_*&amp;lt;/math&amp;gt; каждого из шагов, а также параллельную сложность всего алгоритма, &amp;lt;math&amp;gt;\Psi_{k-means}&amp;lt;/math&amp;gt;. Будем исходить из предположения, что может быть использовано любое необходимое число потоков.&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Распределение d-мерных векторов по &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластерам&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;  &lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
Поскольку на данном шаге для каждой пары векторов &amp;lt;math&amp;gt;\mathbf{x}_i, i=\overline{1,n}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\mathbf{\mu}_j, j=\overline{1,k}&amp;lt;/math&amp;gt; операции вычисления расстояния не зависят друг от друга, они могут выполняться параллельно. Тогда, разделив все вычисление расстояний на &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; потоков, получим, что в каждом потоке будет выполняться только одна операция вычисления расстояния между векторами размерности d. При этом каждому вычислительному потоку передаются координаты центров всех кластеров &amp;lt;math&amp;gt;\mathbf{\mu}_1, ..., \mathbf{\mu}_k&amp;lt;/math&amp;gt;. Таким образом, параллельная сложность данного шага определяется &amp;lt;i&amp;gt; сложностью параллельной операции вычисления расстояния между d-мерными векторами&amp;lt;/i&amp;gt;, &amp;lt;math&amp;gt;\Psi_{distance}^d&amp;lt;/math&amp;gt;  и &amp;lt;i&amp;gt;сложностью определения наиболее близкого кластера&amp;lt;/i&amp;gt; (паралельное взятие минимума по расстояниям), &amp;lt;math&amp;gt;\Psi_{min}^k&amp;lt;/math&amp;gt;. Для оценки &amp;lt;math&amp;gt;\Psi_{distance}^d&amp;lt;/math&amp;gt; воспользуемся  [[Нахождение_частных_сумм_элементов_массива_сдваиванием | параллельной реализацией нахождения частичной суммы элементов массива путем сдваивания]]. Аналогично, &amp;lt;math&amp;gt;\Psi_{min}^k = log(k)&amp;lt;/math&amp;gt;. В результате, &amp;lt;math&amp;gt;\Psi_{distance}^d = O(log(d))&amp;lt;/math&amp;gt;.   Таким образом: &lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p align=&amp;quot;center&amp;quot;&amp;gt;&amp;lt;math&amp;gt;\Psi_{distribute}^{k, d}  = \Psi_{distance}^d + \Psi_{min}^k = O(log(d))+O(log(k)) = O(log(k*d))&amp;lt;/math&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Пересчет центров кластеров в d-мерном пространстве&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
Поскольку на данном шаге для каждого из &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластеров центр масс может быть вычислен независимо, данные операции могут быть выполнены в отдельных потоках. Таким образом, параллельная сложность данного шага, &amp;lt;math&amp;gt;\Psi_{recenter}^{k, d}&amp;lt;/math&amp;gt;,  будет определяться &amp;lt;i&amp;gt;параллельной сложностью вычисления одного центра масс кластера размера &amp;lt;math&amp;gt;m&amp;lt;/math&amp;gt;&amp;lt;/i&amp;gt;, &amp;lt;math&amp;gt;\Psi_{recenter}^{k, d}&amp;lt;/math&amp;gt;,  а так как &amp;lt;math&amp;gt;m \le n \Rightarrow \Psi_{recenter}^{d, m} \le \Psi_{recenter}^{d, n}&amp;lt;/math&amp;gt;. Сложность вычисления центра масс кластера d-мерных векторов размера n аналогично предыдущим вычислениям равна &amp;lt;math&amp;gt;O(log(n))&amp;lt;/math&amp;gt;. Тогда:  &lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p align=&amp;quot;center&amp;quot;&amp;gt;&amp;lt;math&amp;gt;\Psi_{recenter}^{k, d}  \le \Psi_{recenter}^{d, n} = O(log(n))&amp;lt;/math&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Общая параллельная сложность алгоритма&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
На каждой итерации необходимо обновление центров кластеров, которые будут использованы на следующей итерации. Таким образом, итерационный процесс выполняется последовательно&amp;lt;ref&amp;gt;Zhao, Weizhong, Huifang Ma, and Qing He. &amp;quot;Parallel k-means clustering based on mapreduce.&amp;quot; IEEE International Conference on Cloud Computing. Springer Berlin Heidelberg, 2009.&amp;lt;/ref&amp;gt;. Тогда, поскольку сложность каждой итерации  определяется &amp;lt;math&amp;gt;\Psi_{distribute}^{k, d}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\Psi_{recenter}&amp;lt;/math&amp;gt;, сложность всего алгоритма, &amp;lt;math&amp;gt;\Psi_{k-means}&amp;lt;/math&amp;gt; в предположении, что было сделано &amp;lt;math&amp;gt;\Tau&amp;lt;/math&amp;gt; операций определяется выражением&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p align=&amp;quot;center&amp;quot;&amp;gt;&amp;lt;math&amp;gt;\Psi_{k-means} \approx \Tau * (\Psi_{distribute}^{k, d} + \Psi_{recenter}^{k, d}) \le \Tau * O(log(k*d*n))&amp;lt;/math&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Входные и выходные данные алгоритма ===&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;Входные данные&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;Матрица из &amp;lt;math&amp;gt;n*d&amp;lt;/math&amp;gt; элементов &amp;lt;math&amp;gt;x_{i, j} \in \mathbb{R}, i=\overline{1, n}, j=\overline{1, d}&amp;lt;/math&amp;gt;&amp;amp;ndash; координат векторов (наблюдений).&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;Целое положительное число &amp;lt;math&amp;gt;k, k \le n&amp;lt;/math&amp;gt; &amp;amp;ndash; количество кластеров.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;Объем входных данных&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;math&amp;gt;1&amp;lt;/math&amp;gt; целое число + &amp;lt;math&amp;gt;n*d&amp;lt;/math&amp;gt; вещественных чисел (при условии, что координаты &amp;amp;ndash; вещественные числа).&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;Выходные данные&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; целых положительных чисел &amp;lt;math&amp;gt;L_1, ..., L_n&amp;lt;/math&amp;gt;&amp;amp;ndash; номера кластеров, соотвествующие каждому вектору (при условии, что нумерация кластеров начинается с &amp;lt;math&amp;gt;1&amp;lt;/math&amp;gt;).&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;Объем выходных данных&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; целых положительных чисел.&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Свойства алгоритма ===&lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;[[глоссарий#Вычислительная мощность|&#039;&#039;Вычислительная мощность&#039;&#039;]]&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
Вычислительная мощность алгоритма &amp;lt;i&amp;gt;k means&amp;lt;/i&amp;gt; равна &amp;lt;math&amp;gt;\frac{k*d*n*\Tau}{n*d} = k*\Tau &amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; &amp;amp;ndash; число кластеров, &amp;lt;math&amp;gt;\Tau&amp;lt;/math&amp;gt; &amp;amp;ndash; число итераций алгоритма.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;[[глоссарий#Детерминированность |&#039;&#039;Детерминированность&#039;&#039;]] и [[глоссарий#Устойчивость |&#039;&#039;Устойчивость&#039;&#039;]] &amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
Алгоритм &amp;lt;i&amp;gt;k means&amp;lt;/i&amp;gt; является итерационным. Количество итераций алгоритма в общем случае не фиксируется и зависит от начального расположения объектов в пространстве, параметра &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt;, а также от начального приближения центров кластеров, &amp;lt;math&amp;gt;\mu_1, ..., \mu_k&amp;lt;/math&amp;gt;. В результате этого может варьироваться результат работы алгоритма. При неудачном выборе начальных параметров итерационный процесс может сойтись к локальному оптимуму&amp;lt;ref&amp;gt;Von Luxburg, Ulrike. Clustering Stability. Now Publishers Inc, 2010.&amp;lt;/ref&amp;gt;. По этим причинам алгоритм не является ни &amp;lt;b&amp;gt;детермирированным&amp;lt;/b&amp;gt;, ни &amp;lt;b&amp;gt;устойчивым&amp;lt;/b&amp;gt;.&lt;br /&gt;
 &lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Соотношение последовательной и параллельной сложности алгоритма&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\frac{\Theta_{k-means}}{\Psi_{k-means}} = \frac{O(\Tau*k*d*n)}{O(\Tau*log(k*d*n))}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Сильные стороны алгоритма&amp;lt;/b&amp;gt;:&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;i&amp;gt;Сравнительно высокая эффективность при простоте реализации&amp;lt;/i&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;i&amp;gt;Высокое качество кластеризации&amp;lt;/i&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;i&amp;gt;Возможность распараллеливания&amp;lt;/i&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;i&amp;gt;Существование множества модификаций&amp;lt;/i&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;Недостатки алгоритма&amp;lt;/b&amp;gt;&amp;lt;ref&amp;gt;Ortega, Joaquín Pérez, Ma Del Rocío Boone Rojas, and María J. Somodevilla. &amp;quot;Research issues on K-means Algorithm: An Experimental Trial Using Matlab.&amp;quot;&amp;lt;/ref&amp;gt;:&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;i&amp;gt;Количество кластеров является параметром алгоритма&amp;lt;/i&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;&amp;lt;i&amp;gt;Чувствительность к начальным условиям&amp;lt;/i&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;Инициализация центров кластеров в значительной степени влияет на результат кластеризации.&amp;lt;/p&amp;gt;&lt;br /&gt;
  &amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;&amp;lt;i&amp;gt;Чувствительность к выбросам и шумам&amp;lt;/i&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;Выбросы, далекие от центров настоящих кластеров, все равно учитываются при вычислении их центров.&amp;lt;/p&amp;gt;&lt;br /&gt;
  &amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;&amp;lt;i&amp;gt;Возможность сходимости к локальному оптимуму&amp;lt;/i&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;Итеративный подход не дает гарантии сходимости к оптимальному решению.&amp;lt;/p&amp;gt;&lt;br /&gt;
  &amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;&amp;lt;i&amp;gt;Использование понятия &amp;quot;среднего&amp;quot;&amp;lt;/i&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;Алгоритм неприменим к данным, для которых не определено понятие &amp;quot;среднего&amp;quot;, например, категориальным данным.&amp;lt;/p&amp;gt;&lt;br /&gt;
  &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&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;
Исследование масштабируемости параллельной реализации алгоритма k means проводилось на суперкомпьютере &amp;quot;Ломоносов&amp;quot;. Алгоритм реализован на языке C с использованием средств MPI.&lt;br /&gt;
Для исследования масштабируемости проводилось множество запусков программы с разным значением параметра (количество векторов для кластеризации), а также с различным числом процессоров. Фиксировались результаты запусков &amp;amp;ndash; время работы &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt; и количество произведенных итераций алгоритма &amp;lt;math&amp;gt;\Tau&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Параметры запусков для экспериментальной оценки:&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;Значения &amp;lt;b&amp;gt;количества векторов&amp;lt;/b&amp;gt; &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;: 20&#039;000, 30&#039;000, 50&#039;000, 100&#039;000, 200&#039;000, 300&#039;000, 500&#039;000, 700&#039;000, 1&#039;000&#039;000, 1&#039;500&#039;000, 2&#039;000&#039;000.&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;Значения &amp;lt;b&amp;gt;количества процессоров&amp;lt;/b&amp;gt; &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt;: 1, 8, 16, 32, 64, 128, 160, 192, 224, 256, 288, 320, 352, 384, 416, 448, 480, 512.&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;Значение &amp;lt;b&amp;gt;количества кластеров&amp;lt;/b&amp;gt; &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt;: 100.&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;Значение &amp;lt;b&amp;gt;размерности векторов&amp;lt;/b&amp;gt; &amp;lt;math&amp;gt;d&amp;lt;/math&amp;gt;: 10.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Графики производительности и эффективности реализации представлены на рисунках 4 и 5 соответственно.&lt;br /&gt;
&lt;br /&gt;
[[file:Flops.png|thumb|center|800px|Рис. 4. График производительности реализации алгоритма.]]&lt;br /&gt;
&lt;br /&gt;
[[file:Efficiency.png|thumb|center|800px|Рис. 5. График эффективности реализации алгоритма.]]&lt;br /&gt;
&lt;br /&gt;
Для заданной конфигурации эксперимента (&amp;lt;math&amp;gt;n, d, p, k&amp;lt;/math&amp;gt;) и полученных результатах (&amp;lt;math&amp;gt;t, \Tau&amp;lt;/math&amp;gt;) производительность и эффективность реализации расчитывались по формулам (см. [[#Последовательная сложность алгоритма| последовательная сложность алгоритма]]):&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
&amp;lt;ul&amp;gt;&amp;lt;li&amp;gt;&amp;lt;math&amp;gt;Performance = \frac{\Theta_{k-means}^{d, n}}{t}\ \ FLOPS&amp;lt;/math&amp;gt;&amp;lt;/li&amp;gt;&amp;lt;/ul&amp;gt;&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
&amp;lt;ul&amp;gt;&amp;lt;li&amp;gt;&amp;lt;math&amp;gt;Efficiency = \frac{100 * Performance}{Performance_{Peak}^{p}}\ \ %,&amp;lt;/math&amp;gt;&amp;lt;/li&amp;gt;&amp;lt;/ul&amp;gt;&lt;br /&gt;
где &amp;lt;math&amp;gt;Performance_{Peak}^{p}&amp;lt;/math&amp;gt; &amp;amp;ndash; пиковая производительность суперкомпьютера при &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt; процессорах, вычисленная согласно спецификациям Intel&amp;lt;sup&amp;gt;&amp;amp;reg;&amp;lt;/sup&amp;gt; XEON&amp;lt;sup&amp;gt;&amp;amp;reg;&amp;lt;/sup&amp;gt; X5670&amp;lt;ref&amp;gt;&amp;quot;http://ark.intel.com/ru/products/47920/Intel-Xeon-Processor-X5670-12M-Cache-2_93-GHz-6_40-GTs-Intel-QPI&amp;quot;&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;В результате&amp;lt;/b&amp;gt; экспериментальной оценки были получены следующие оценки эффективности реализации:&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;b&amp;gt;Минимальное&amp;lt;/b&amp;gt; значение: 0.000409 % достигается при &amp;lt;math&amp;gt;n=20&#039;000, p=480&amp;lt;/math&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;b&amp;gt;Максимальное&amp;lt;/b&amp;gt; значение: 0.741119 % достигается при &amp;lt;math&amp;gt;n=300&#039;000, p=1&amp;lt;/math&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Динамические характеристики и эффективность реализации алгоритма ===&lt;br /&gt;
=== Выводы для классов архитектур ===&lt;br /&gt;
=== Существующие реализации алгоритма ===&lt;br /&gt;
==== Открытое программное обеспечение ====&lt;br /&gt;
&amp;lt;ol&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;[https://www.icpsr.umich.edu/CrimeStat/ CrimeStat]&amp;lt;/li&amp;gt; Программное обеспечение, созданное для операционных систем Windows, предоставляющее инструменты статистического  и пространственного анализа для решения задачи картирования преступности.&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://juliastats.github.io Julia]&amp;lt;/li&amp;gt; Высокоуровневый высокопроизводительный свободный язык программирования с динамической типизацией, созданный для математических вычислений, содержит реализацию k-means.&lt;br /&gt;
  &amp;lt;li&amp;gt;[https://mahout.apache.org Mahout]&amp;lt;/li&amp;gt; Apache Mahout - Java библиотека для работы с алгоритмами машинного обучения с использованием MapReduce. Содержит реализацию k-means.&lt;br /&gt;
  &amp;lt;li&amp;gt;[https://www.gnu.org/software/octave/ Octave]&amp;lt;/li&amp;gt; Написанная на C++  свободная система для математических вычислений, использующая совместимый с MATLAB язык высокого уровня, содержит реализацию k-means.&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://spark.apache.org/docs/latest/mllib-clustering.html Spark]&amp;lt;/li&amp;gt; Распределенная реализация k-means содержится в библиотеке Mlib для работы с алгоритмами машинного обучения, взаимодействующая с Python библиотекой NumPy и библиотека R.&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://torch.ch Torch]&amp;lt;/li&amp;gt;  MATLAB-подобная библиотека для языка программирования Lua с открытым исходным кодом, предоставляет большое количество алгоритмов для глубинного обучения и научных расчётов. Ядро написано на Си, прикладная часть выполняется на LuaJIT, поддерживается распараллеливание вычислений средствами CUDA и OpenMP. Существуют реализации k-means.&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://www.cs.waikato.ac.nz/ml/weka/ Weka]&amp;lt;/li&amp;gt;  Cвободное программное обеспечение для анализа данных, написанное на Java. Содержит k-means и x-means.&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://accord-framework.net/docs/html/T_Accord_MachineLearning_KMeans.htm Accord.NET]&amp;lt;/li&amp;gt; C# реализация алгоритмов k-means, k-means++, k-modes.&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://docs.opencv.org/3.0-beta/doc/py_tutorials/py_ml/py_kmeans/py_kmeans_opencv/py_kmeans_opencv.html OpenCV]&amp;lt;/li&amp;gt; Написанная на С++ библиотека, направленная в основном на решение задач компьютерного зрения. Содержит реализацию k-means.&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://mlpack.org/ MLPACK]&amp;lt;/li&amp;gt; Масштабируемая С++ библиотека для работы с алгоритмами машинного обучения, содержит реализацию k-means.&lt;br /&gt;
  &amp;lt;li&amp;gt;[https://www.scipy.org/ SciPy]&amp;lt;/li&amp;gt; Библиотека Python, содержит множество реализаций k-means.&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://scikit-learn.org/ scikit-learn]&amp;lt;/li&amp;gt; Библиотека Python, содержит множество реализаций k-means.&lt;br /&gt;
  &amp;lt;li&amp;gt;[https://www.r-bloggers.com/k-means-clustering-in-r/ R]&amp;lt;/li&amp;gt; Язык программирования для статистической обработки данных и работы с графикой, а также свободная программная среда вычислений с открытым исходным кодом в рамках проекта GNU, содержит три реализации k-means.&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://elki.dbs.ifi.lmu.de ELKI]&amp;lt;/li&amp;gt; Java фреймворк, содержащий реализацию k-means, а также множество других алгоритмов кластеризации.&lt;br /&gt;
&amp;lt;/ol&amp;gt;&lt;br /&gt;
==== Проприетарное программное обеспечение  ====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ol&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;[https://www.ayasdi.com/blog/bigdata/topological-data-analysis-of-oil-and-gas-petrophysical-data/ Ayasdi]&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://www.stata.com/features/cluster-analysis/ Stata]&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://mathworld.wolfram.com/K-MeansClusteringAlgorithm.html Mathematica]&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://www.mathworks.com/help/stats/kmeans.html?requestedDomain=www.mathworks.com MATLAB]&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;[https://support.sas.com/rnd/app/stat/procedures/fastclus.html SAS]&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://docs.rapidminer.com/studio/operators/modeling/segmentation/k_means.html RapidMiner]&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;[https://blogs.sap.com/2013/03/28/sap-hana-pal-k-means-algorithm-or-how-to-do-customer-segmentation-for-the-telecommunications-industry/ SAP HANA]&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ol&amp;gt;&lt;br /&gt;
== Литература ==&lt;br /&gt;
&amp;lt;references /&amp;gt;&lt;/div&gt;</summary>
		<author><name>DennZo1993</name></author>
	</entry>
	<entry>
		<id>https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:%D0%91%D1%80%D0%BE%D1%82%D0%B8%D0%BA%D0%BE%D0%B2%D1%81%D0%BA%D0%B0%D1%8F_%D0%94%D0%B0%D0%BD%D1%83%D1%82%D0%B0/%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_k-means&amp;diff=17177</id>
		<title>Участник:Бротиковская Данута/Алгоритм k-means</title>
		<link rel="alternate" type="text/html" href="https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:%D0%91%D1%80%D0%BE%D1%82%D0%B8%D0%BA%D0%BE%D0%B2%D1%81%D0%BA%D0%B0%D1%8F_%D0%94%D0%B0%D0%BD%D1%83%D1%82%D0%B0/%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_k-means&amp;diff=17177"/>
		<updated>2016-11-15T00:04:57Z</updated>

		<summary type="html">&lt;p&gt;DennZo1993: /* Масштабируемость реализации алгоритма */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt; {{Assignment|Zhum}}&lt;br /&gt;
&lt;br /&gt;
{{algorithm&lt;br /&gt;
| name              = Алгоритм k средних (k means)&lt;br /&gt;
| serial_complexity = &amp;lt;math&amp;gt;O(\Tau*k*d*n)&amp;lt;/math&amp;gt;&lt;br /&gt;
| input_data        = &amp;lt;math&amp;gt; d*n &amp;lt;/math&amp;gt;&lt;br /&gt;
| output_data       = &amp;lt;math&amp;gt; n &amp;lt;/math&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
Авторы страницы &amp;lt;b&amp;gt;[[Участник:Бротиковская Данута|Данута Бротиковская]]&amp;lt;/b&amp;gt; и &amp;lt;b&amp;gt;[[Участник:DennZo1993|Денис Зобнин]]&amp;lt;/b&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
Оба автора внесли одинаковый вклад в написание статьи (поиск материалов, изучение статей, заполнение контента статьи), четких разграничений по пунктам статьи сделать невозможно. &lt;br /&gt;
&lt;br /&gt;
== Свойства и структура алгоритма ==&lt;br /&gt;
&lt;br /&gt;
=== Общее описание алгоритма ===&lt;br /&gt;
Алгоритм &amp;lt;b&amp;gt;&amp;lt;i&amp;gt;k средних&amp;lt;/i&amp;gt;&amp;lt;/b&amp;gt; (&amp;lt;b&amp;gt;&amp;lt;i&amp;gt;k means&amp;lt;/i&amp;gt;&amp;lt;/b&amp;gt;) &amp;amp;ndash; неиерархический&amp;lt;ref&amp;gt;&amp;quot;https://ru.wikipedia.org/wiki/Иерархическая_кластеризация&amp;quot;&amp;lt;/ref&amp;gt;, итерационный метод кластеризации&amp;lt;ref&amp;gt;&amp;quot;https://ru.wikipedia.org/wiki/Кластерный_анализ&amp;quot;&amp;lt;/ref&amp;gt;, получивший большую популярность благодаря своей простоте, наглядности реализации и достаточно высокому качеству работы. Был изобретен в 1950-х годах математиком &amp;lt;i&amp;gt;Гуго Штейнгаузом&amp;lt;/i&amp;gt;&amp;lt;ref&amp;gt;Steinhaus, Hugo. &amp;quot;Sur la division des corp materiels en parties.&amp;quot; Bull. Acad. Polon. Sci 1.804 (1956): 801.&amp;lt;/ref&amp;gt; и почти одновременно &amp;lt;i&amp;gt;Стюартом Ллойдом&amp;lt;/i&amp;gt;&amp;lt;ref&amp;gt;Lloyd, S. P. &amp;quot;Least square quantization in PCM. Bell Telephone Laboratories Paper. Published in journal much later: Lloyd, SP: Least squares quantization in PCM.&amp;quot; IEEE Trans. Inform. Theor.(1957/1982).&amp;lt;/ref&amp;gt;. Особую популярность приобрел после публикации работы &amp;lt;i&amp;gt;МакКуина&amp;lt;/i&amp;gt;&amp;lt;ref&amp;gt;MacQueen, James. &amp;quot;Some methods for classification and analysis of multivariate observations.&amp;quot; Proceedings of the fifth Berkeley symposium on mathematical statistics and probability. Vol. 1. No. 14. 1967.&amp;lt;/ref&amp;gt; в 1967.&lt;br /&gt;
&lt;br /&gt;
Алгоритм представляет собой версию EM-алгоритма&amp;lt;ref&amp;gt;&amp;quot;https://ru.wikipedia.org/wiki/EM-алгоритм&amp;quot;&amp;lt;/ref&amp;gt;, применяемого также для разделения смеси гауссиан. Основная идея &amp;lt;i&amp;gt;k means&amp;lt;/i&amp;gt; заключается в том, что данные произвольно разбиваются на кластеры, после чего итеративно перевычисляется центр масс для каждого кластера, полученного на предыдущем шаге, затем векторы разбиваются на кластеры вновь в соответствии с тем, какой из новых центров оказался ближе по выбранной метрике.&lt;br /&gt;
&lt;br /&gt;
Цель алгоритма заключается в разделении &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; наблюдений на &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластеров таким образом, чтобы каждое наблюдение принадлежало ровно одному кластеру, расположенному на наименьшем расстоянии от наблюдения.&lt;br /&gt;
&lt;br /&gt;
=== Математическое описание алгоритма ===&lt;br /&gt;
&amp;lt;b&amp;gt;&amp;lt;u&amp;gt;Дано:&amp;lt;/u&amp;gt;&amp;lt;/b&amp;gt;&lt;br /&gt;
* набор из &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; наблюдений &amp;lt;math&amp;gt;X=\{\mathbf{x}_1, \mathbf{x}_2, ..., \mathbf{x}_n\}, \mathbf{x}_i \in \mathbb{R}^d, i=\overline{1, n}&amp;lt;/math&amp;gt;;&lt;br /&gt;
* &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; - требуемое число кластеров, &amp;lt;math&amp;gt;k \in \mathbb{N}, k \leq n&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;&amp;lt;u&amp;gt;Требуется:&amp;lt;/u&amp;gt;&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Разделить множество наблюдений &amp;lt;math&amp;gt;X&amp;lt;/math&amp;gt; на &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластеров &amp;lt;math&amp;gt;S_1, S_2, ..., S_k&amp;lt;/math&amp;gt;:&lt;br /&gt;
*   &amp;lt;math&amp;gt;S_i \cap S_j= \varnothing, \quad i \ne j&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
*   &amp;lt;math&amp;gt;\bigcup_{i=1}^{k} S_i = X&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;&amp;lt;u&amp;gt;Действие алгоритма:&amp;lt;/u&amp;gt;&amp;lt;/b&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;Алгоритм &amp;lt;i&amp;gt;k means&amp;lt;/i&amp;gt; разбивает набор &amp;lt;math&amp;gt;X&amp;lt;/math&amp;gt; на &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; наборов &amp;lt;math&amp;gt;S_1, S_2, ..., S_k,&amp;lt;/math&amp;gt; таким образом, чтобы минимизировать сумму квадратов расстояний от каждой точки кластера до его центра (центр масс кластера). Введем обозначение, &amp;lt;math&amp;gt;S=\{S_1, S_2, ..., S_k\}&amp;lt;/math&amp;gt;. Тогда действие алгоритма &amp;lt;i&amp;gt;k means&amp;lt;/i&amp;gt; равносильно поиску:&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;table style=&amp;quot;width:100%&amp;quot;&amp;gt;&lt;br /&gt;
  &amp;lt;tr&amp;gt;&lt;br /&gt;
    &amp;lt;td align=&amp;quot;center&amp;quot; width=&amp;quot;90%&amp;quot;&amp;gt;&amp;lt;math&amp;gt;\arg\min_{S} \sum\limits_{i=1}^k \sum\limits_{\mathbf{x} \in S_i} \rho(\mathbf{x}, \mathbf{\mu}_i )^2,&amp;lt;/math&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;td align=&amp;quot;right&amp;quot;&amp;gt;&amp;lt;math&amp;gt;(1)&amp;lt;/math&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;/table&amp;gt;&lt;br /&gt;
где &amp;lt;math&amp;gt;\mathbf{\mu}_i&amp;lt;/math&amp;gt; &amp;amp;ndash; центры кластеров, &amp;lt;math&amp;gt;i=\overline{1,k}, \quad \rho(\mathbf{x}, \mathbf{\mu}_i)&amp;lt;/math&amp;gt; &amp;amp;ndash; функция расстояния между &amp;lt;math&amp;gt;\mathbf{x}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\mu_i&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;&amp;lt;u&amp;gt;Шаги алгоритма: &amp;lt;/u&amp;gt;&amp;lt;/b&amp;gt;&lt;br /&gt;
&amp;lt;ol&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&lt;br /&gt;
    &amp;lt;b&amp;gt;Начальный шаг: инициализация кластеров&amp;lt;/b&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;Выбирается произвольное множество точек &amp;lt;math&amp;gt;\mu_i, i=\overline{1,k}&amp;lt;/math&amp;gt;, рассматриваемых как начальные центры кластеров: &amp;lt;math&amp;gt;\mu_i^{(0)} = \mu_i, \quad i=\overline{1, k}&amp;lt;/math&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
  &amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&lt;br /&gt;
    &amp;lt;b&amp;gt;Распределение векторов по кластерам&amp;lt;/b&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Шаг&amp;lt;/b&amp;gt; &amp;lt;math&amp;gt;t: \forall \mathbf{x}_i \in X, i=\overline{1,n}: \mathbf{x}_i \in S_j \iff  j=\arg\min_{k}\rho(\mathbf{x}_i,\mathbf{\mu}_k^{(t-1)})^2&amp;lt;/math&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
  &amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&lt;br /&gt;
    &amp;lt;b&amp;gt;Пересчет центров кластеров&amp;lt;/b&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Шаг &amp;lt;/b&amp;gt; &amp;lt;math&amp;gt;t: \forall i=\overline{1,k}:  \mu_i^{(t)} = \cfrac{1}{|S_i|}\sum_{\mathbf{x}\in S_i}\mathbf{x}&amp;lt;/math&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
  &amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&lt;br /&gt;
    &amp;lt;b&amp;gt;Проверка условия останова:&amp;lt;/b&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
    &#039;&#039;&#039;if&#039;&#039;&#039; &amp;lt;math&amp;gt;\exist i\in \overline{1,k}: \mu_i^{(t)} \ne \mu_i^{(t-1)}&amp;lt;/math&amp;gt; &#039;&#039;&#039;then&#039;&#039;&#039;&lt;br /&gt;
        t = t + 1;&lt;br /&gt;
        goto 2;&lt;br /&gt;
    &#039;&#039;&#039;else&#039;&#039;&#039;&lt;br /&gt;
        &#039;&#039;&#039;stop&#039;&#039;&#039;&lt;br /&gt;
  &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ol&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Вычислительное ядро алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Вычислительным ядром являются шаги 2 и 3 приведенного выше алгоритма: &amp;lt;b&amp;gt;&amp;lt;i&amp;gt;распределение векторов по кластерам&amp;lt;/i&amp;gt;&amp;lt;/b&amp;gt; и &amp;lt;b&amp;gt;&amp;lt;i&amp;gt;пересчет центров кластеров&amp;lt;/i&amp;gt;&amp;lt;/b&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;&amp;lt;i&amp;gt;Распределение векторов&amp;lt;/i&amp;gt;&amp;lt;/b&amp;gt; по кластерам предполагает вычисление расстояний между каждым вектором &amp;lt;math&amp;gt;\mathbf{x}_i \in X, i= \overline{1,n}&amp;lt;/math&amp;gt; и центрами кластера &amp;lt;math&amp;gt;\mathbf{\mu}_j, j= \overline{1,k}&amp;lt;/math&amp;gt;. Таким образом, данный шаг предполагает &amp;lt;math&amp;gt;k*n&amp;lt;/math&amp;gt; вычислений расстояний между d-мерными векторами. &lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;&amp;lt;i&amp;gt;Пересчет центров кластеров&amp;lt;/i&amp;gt;&amp;lt;/b&amp;gt; предполагает &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; вычислений центров масс &amp;lt;math&amp;gt;\mathbf{\mu}_i&amp;lt;/math&amp;gt; множеств &amp;lt;math&amp;gt;S_i, i=\overline{1,k}&amp;lt;/math&amp;gt; представленных выражением в шаге 3 представленного выше алгоритма.&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Макроструктура алгоритма ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Инициализация центров масс &amp;lt;math&amp;gt;\mu_1, ..., \mu_k&amp;lt;/math&amp;gt;&amp;lt;/b&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
Наиболее распространенными являются следующие стратегии:&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&lt;br /&gt;
    &amp;lt;b&amp;gt;Метод Forgy&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;В качестве начальных значений &amp;lt;math&amp;gt;\mu_1, ..., \mu_k&amp;lt;/math&amp;gt; берутся случайно выбранные векторы.&lt;br /&gt;
  &amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&lt;br /&gt;
    &amp;lt;b&amp;gt;Метод случайно разделения (Random Partitioning)&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;Для каждого вектора &amp;lt;math&amp;gt;\mathbf{x}_i \in X, i=\overline{1, n}&amp;lt;/math&amp;gt; выбирается случайным образом кластер &amp;lt;math&amp;gt;S_1, ..., S_k&amp;lt;/math&amp;gt;, после чего для каждого полученного кластера вычисляются значения &amp;lt;math&amp;gt;\mu_1, ..., \mu_k&amp;lt;/math&amp;gt;.&lt;br /&gt;
  &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Распределение векторов по кластерам&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Для этого шага алгоритма между векторами &amp;lt;math&amp;gt;\mathbf{x}_i \in X, i=\overline{1, n}&amp;lt;/math&amp;gt; и центрами кластеров &amp;lt;math&amp;gt;\mu_1, ..., \mu_k&amp;lt;/math&amp;gt; вычисляются &amp;lt;b&amp;gt;расстояния&amp;lt;/b&amp;gt; по формуле (как правило, используется Евлидово расстояние):&lt;br /&gt;
&amp;lt;table style=&amp;quot;width:100%&amp;quot;&amp;gt;&lt;br /&gt;
  &amp;lt;tr&amp;gt;&lt;br /&gt;
    &amp;lt;td align=&amp;quot;center&amp;quot; width=&amp;quot;90%&amp;quot;&amp;gt;&amp;lt;math&amp;gt; \mathbf{v}_1, \mathbf{v}_2 \in \mathbb{R}^d,  \quad \rho(\mathbf{v}_1, \mathbf{v}_2) = \lVert \mathbf{v}_1- \mathbf{v}_2 \rVert= \sqrt{\sum_{i=1}^{d}(\mathbf{v}_{1,i} - \mathbf{v}_{2,i})^2}&amp;lt;/math&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;td align=&amp;quot;right&amp;quot;&amp;gt;&amp;lt;math&amp;gt;(2)&amp;lt;/math&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;/table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Пересчет центров кластеров&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Для этого шага алгоритма производится пересчет центров кластера по &amp;lt;b&amp;gt;формуле вычисления центра масс&amp;lt;/b&amp;gt;:&lt;br /&gt;
&amp;lt;table style=&amp;quot;width:100%&amp;quot;&amp;gt;&lt;br /&gt;
  &amp;lt;tr&amp;gt;&lt;br /&gt;
    &amp;lt;td align=&amp;quot;center&amp;quot; width=&amp;quot;90%&amp;quot;&amp;gt;&amp;lt;math&amp;gt; \mu = \cfrac{1}{|S|}\sum_{\mathbf{x}\in S}\mathbf{x}&amp;lt;/math&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;td align=&amp;quot;right&amp;quot;&amp;gt;&amp;lt;math&amp;gt;(3)&amp;lt;/math&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;/table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Схема реализации последовательного алгоритма ===&lt;br /&gt;
&lt;br /&gt;
 &#039;&#039;&#039;algorithm&#039;&#039;&#039; k-means &#039;&#039;&#039;is&#039;&#039;&#039;&lt;br /&gt;
     &#039;&#039;&#039;1.&#039;&#039;&#039; Инициализировать центры кластеров &amp;lt;math&amp;gt;\mathbf{\mu}_i^{(1)}, i=\overline{1,k}&amp;lt;/math&amp;gt;&lt;br /&gt;
     &#039;&#039;&#039;2.&#039;&#039;&#039; &amp;lt;math&amp;gt;t \leftarrow 1&amp;lt;/math&amp;gt;&lt;br /&gt;
     &#039;&#039;&#039;3.&#039;&#039;&#039; &#039;&#039;&#039;Распределение по кластерам&#039;&#039;&#039;&amp;lt;br&amp;gt;&lt;br /&gt;
        &amp;lt;math&amp;gt;S_i^{(t)}=\{\mathbf{x}_p: \lVert\mathbf{x}_p-\mathbf{\mu}_i^{(t)}\rVert^2 \leq \lVert\mathbf{x}_p-\mathbf{\mu}_j^{(t)}\rVert^2 \quad \forall j=\overline{1,k}\},&amp;lt;/math&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
        где каждый вектор &amp;lt;math&amp;gt;\mathbf{x}_p&amp;lt;/math&amp;gt; соотносится единственному кластеру &amp;lt;math&amp;gt;S^{(t)}&amp;lt;/math&amp;gt;&lt;br /&gt;
     &#039;&#039;&#039;4.&#039;&#039;&#039; &#039;&#039;&#039;Обновление центров кластеров&#039;&#039;&#039;&amp;lt;br&amp;gt;&lt;br /&gt;
        &amp;lt;math&amp;gt;\mathbf{\mu}_i^{(t+1)} = \frac{1}{|S^{(t)}_i|} \sum_{\mathbf{x}_j \in S^{(t)}_i} \mathbf{x}_j &amp;lt;/math&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
     &#039;&#039;&#039;5.&#039;&#039;&#039; &#039;&#039;&#039;if&#039;&#039;&#039; &amp;lt;math&amp;gt;\exist i \in \overline{1,k}: \mathbf{\mu}_i^{(t+1)} \ne \mathbf{\mu}_i^{(t)}&amp;lt;/math&amp;gt; &#039;&#039;&#039;then&#039;&#039;&#039;&lt;br /&gt;
            t = t + 1;&lt;br /&gt;
            goto &#039;&#039;&#039;3&#039;&#039;&#039;;&lt;br /&gt;
        &#039;&#039;&#039;else&#039;&#039;&#039;&lt;br /&gt;
            &#039;&#039;&#039;stop&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
=== Последовательная сложность алгоритма===&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding-bottom: 20px&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;Обозначим &amp;lt;math&amp;gt;\Theta_{centroid}^{d, m}&amp;lt;/math&amp;gt; временную сложность вычисления центорида кластера, число элементов которого равна &amp;lt;math&amp;gt;m&amp;lt;/math&amp;gt;,  в d-мерном пространстве.&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;Аналогично  &amp;lt;math&amp;gt;\Theta_{distance}^d&amp;lt;/math&amp;gt; &amp;amp;ndash; временная сложность вычисления расстояния между двумя d-мерными векторами.&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding-bottom: 20px&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;Сложность шага инициализации &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластеров мощности &amp;lt;math&amp;gt;m&amp;lt;/math&amp;gt; в d-мерном пространстве &amp;amp;ndash; &amp;lt;math&amp;gt;\Theta_{init}^{k, d, m}&amp;lt;/math&amp;gt;&amp;lt;/b&amp;gt;&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;i&amp;gt;Стратерия Forgy&amp;lt;/i&amp;gt;: вычисления не требуются, &amp;lt;math&amp;gt;\Theta_{init}^{k, d, m} = 0&amp;lt;/math&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;i&amp;gt;Стратегия случайного разбиения&amp;lt;/i&amp;gt;: вычисление центров &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластеров,  &amp;lt;math&amp;gt;\Theta_{init}^{k, d, m} = k*\Theta_{centroid}^{d, m}, m \le n&amp;lt;/math&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding-bottom: 20px&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Cложность шага распределения d мерных векторов по &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластерам &amp;amp;ndash; &amp;lt;math&amp;gt;\Theta_{distribute}^{k, d}&amp;lt;/math&amp;gt;&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
На этом шаге для каждого вектора &amp;lt;math&amp;gt;\mathbf{x}_i \in X, i=\overline{1, n}&amp;lt;/math&amp;gt; вычисляется k расстояний до центров кластеров &amp;lt;math&amp;gt;\mathbf{\mu}_1, ...\mathbf{\mu}_k&amp;lt;/math&amp;gt;&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p align=&amp;quot;center&amp;quot;&amp;gt;&lt;br /&gt;
  &amp;lt;math&amp;gt;\Theta_{distribute}^{k, d} = n*k*\Theta_{distance}^d&amp;lt;/math&amp;gt;&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding-bottom: 20px&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;Сложность шага пересчета центров &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластеров размера &amp;lt;math&amp;gt;m&amp;lt;/math&amp;gt; в d-мерном пространстве &amp;amp;ndash; &amp;lt;math&amp;gt;\Theta_{recenter}^{k, d, m}&amp;lt;/math&amp;gt;&amp;lt;/b&amp;gt;&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;На этом шаге вычисляется &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; центров кластеров &amp;lt;math&amp;gt;\mathbf{\mu}_1, ...\mathbf{\mu}_k&amp;lt;/math&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p align=&amp;quot;center&amp;quot;&amp;gt;&amp;lt;math&amp;gt;\Theta_{recenter}^{k, d, m} = k*\Theta_{centroid}^{d, m}&amp;lt;/math&amp;gt; &amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding-bottom: 20px&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Рассчитаем &amp;lt;math&amp;gt;\Theta_{centroid}^{d, m}&amp;lt;/math&amp;gt; для кластера, число элементов которого равно &amp;lt;math&amp;gt;m&amp;lt;/math&amp;gt;&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p align=&amp;quot;center&amp;quot;&amp;gt;&amp;lt;math&amp;gt;\Theta_{centroid}^{d, m}&amp;lt;/math&amp;gt; = &amp;lt;math&amp;gt;m * d&amp;lt;/math&amp;gt; сложений + &amp;lt;math&amp;gt;d&amp;lt;/math&amp;gt; делений &amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding-bottom: 20px&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Рассчитаем &amp;lt;math&amp;gt;\Theta_{distance}^d&amp;lt;/math&amp;gt; в соответствие с формулой &amp;lt;math&amp;gt;(2)&amp;lt;/math&amp;gt;&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p align=&amp;quot;center&amp;quot;&amp;gt;&amp;lt;math&amp;gt;\Theta_{distance}^d&amp;lt;/math&amp;gt; = &amp;lt;math&amp;gt;d&amp;lt;/math&amp;gt; вычитаний + &amp;lt;math&amp;gt;d&amp;lt;/math&amp;gt; умножений + &amp;lt;math&amp;gt;(d-1)&amp;lt;/math&amp;gt; сложение&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding-bottom: 20px&amp;quot;&amp;gt;&lt;br /&gt;
  &amp;lt;p&amp;gt;Предположим, что алгоритм сошелся за &amp;lt;math&amp;gt;\Tau&amp;lt;/math&amp;gt; итераций, тогда временная сложность алгоритма &amp;lt;math&amp;gt;\Theta_{k-means}^{d, n}&amp;lt;/math&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
  &amp;lt;p align=&amp;quot;center&amp;quot;&amp;gt;&amp;lt;b&amp;gt;&amp;lt;math&amp;gt;\Theta_{k-means}^{d, n} \le \Theta_{init}^{k, d, n} + \Tau*(\Theta_{distribute}^{k, d} + \Theta_{recenter}^{k, d, n})&amp;lt;/math&amp;gt;&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding-bottom: 5px&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;Операции сложения/вычитания:&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p align=&amp;quot;center&amp;quot;&amp;gt;&amp;lt;b&amp;gt;&amp;lt;math&amp;gt;\Theta_{k-means}^{d, n} \le k*n*d+ \Tau*(k*n*(2d-1) + k*n*d) = k*n*d+ \Tau*(k*n*(3d-1)) \thicksim O(\Tau*k*d*n)&amp;lt;/math&amp;gt;&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding-bottom: 20px&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;Операции умножения/деления:&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p align=&amp;quot;center&amp;quot;&amp;gt;&amp;lt;b&amp;gt;&amp;lt;math&amp;gt;\Theta_{k-means}^{d, n} \le k*d + \Tau*(k*n*d + k*d) = k*d + \Tau * k*d*(n+1) \thicksim O(\Tau*k*d*n) &amp;lt;/math&amp;gt;&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding-bottom: 20px&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;Получаем, что &amp;lt;b&amp;gt;временная сложность&amp;lt;/b&amp;gt; алгоритма &amp;lt;b&amp;gt;k means&amp;lt;/b&amp;gt; кластеризации &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; &amp;lt;b&amp;gt;d-мерных&amp;lt;/b&amp;gt; векторов на &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластеров за &amp;lt;math&amp;gt;\Tau&amp;lt;/math&amp;gt; итераций:&amp;lt;/p&amp;gt;&lt;br /&gt;
 &amp;lt;p align=&amp;quot;center&amp;quot;&amp;gt;&amp;lt;b&amp;gt;&amp;lt;math&amp;gt; \Theta_{k-means}^{d, n} \thicksim O(\Tau*k*d*n) &amp;lt;/math&amp;gt;&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Информационный граф ===&lt;br /&gt;
&lt;br /&gt;
Рассмотрим информационный граф алгоритма. Алгоритм &amp;lt;i&amp;gt;k means&amp;lt;/i&amp;gt; начинается с этапа инициализации, после которого следуют итерации, на каждой из которых выполняется два последовательных шага (см. [[#Схема реализации последовательного алгоритма|&amp;quot;Схема реализации последовательного алгоритма&amp;quot;]]): &lt;br /&gt;
* распределение векторов по кластерам&lt;br /&gt;
* перерасчет центров кластеров&lt;br /&gt;
&lt;br /&gt;
Поскольку основная часть вычислений приходится на шаги итераций, распишем информационные графы данных шагов.&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Распределение векторов по кластерам&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
Информационный граф шага распределения векторов по кластерам представлен на &#039;&#039;рисунке 1&#039;&#039;. Исходами данного графа является исходные векторы &amp;lt;math&amp;gt;\mathbf{x}_1, ..., \mathbf{x}_n&amp;lt;/math&amp;gt;, а также центры кластеров &amp;lt;math&amp;gt;\mathbf{\mu}_1, ... \mathbf{\mu}_k&amp;lt;/math&amp;gt;, вычисленные ранее (на шаге инициализации, если рассматривается первая итерация алгоритма, или на шаге пересчета центров кластеров предыдущей итерации в противном случае). Каждая пара векторов данных &amp;lt;math&amp;gt;\mathbf{x}_i, i=\overline{1,n}&amp;lt;/math&amp;gt; и центров кластера &amp;lt;math&amp;gt;\mathbf{\mu}_j, j=\overline{1, k}&amp;lt;/math&amp;gt; : (&amp;lt;math&amp;gt;\mathbf{x}_i&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;\mathbf{\mu}_j&amp;lt;/math&amp;gt;) подаются на независимые узлы &amp;lt;i&amp;gt;&amp;quot;d&amp;quot;&amp;lt;/i&amp;gt; вычисления расстояния между векторами (более подробная схема вычисления расстояния представлена далее, &#039;&#039;рисунок 2&#039;&#039;). Далее узлы вычисления расстояния &amp;lt;i&amp;gt;&amp;quot;d&amp;quot;&amp;lt;/i&amp;gt;, соответствующие одному и тому же исходному вектору &amp;lt;math&amp;gt;\mathbf{x}_i&amp;lt;/math&amp;gt; передаются на один узел &amp;lt;i&amp;gt;&amp;quot;m&amp;quot;&amp;lt;/i&amp;gt;, где далее происходит вычисление новой метки кластера для каждого вектора &amp;lt;math&amp;gt;\mathbf{x}_i&amp;lt;/math&amp;gt; (берется кластер с минимальным результатом вычисления расстояния). На выходе графа выдаются метки кластеров , &amp;lt;math&amp;gt;L_1, ..., L_n&amp;lt;/math&amp;gt;, такие что &amp;lt;math&amp;gt;\forall \mathbf{x}_i, i=\overline{1, n}, \mathbf{x}_i \in S_j \Leftrightarrow L_i = j&amp;lt;/math&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
[[file:Clusterization.png|thumb|center|800px|Рис. 1. Схема распределения векторов по кластерам. &#039;&#039;d&#039;&#039; &amp;amp;ndash; вычисление расстояния между векторами; &#039;&#039;m&#039;&#039; &amp;amp;ndash; вычисление минимума.]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Вычисление расстояния между векторами&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
Подробная схема вычисления расстояния между векторами &amp;lt;math&amp;gt;\mathbf{x}_i, \mathbf{\mu}_j&amp;lt;/math&amp;gt; представлена на &#039;&#039;рисунке 2&#039;&#039;. Как показано на графе, узел вычисления расстояния между векторами &amp;lt;i&amp;gt;&amp;quot;d&amp;quot;&amp;lt;/i&amp;gt; состоит из шага взятия разности между векторами (узел &amp;quot;&amp;lt;math&amp;gt;-&amp;lt;/math&amp;gt;&amp;quot;) и взятия нормы получившегося вектора разности (узел &amp;quot;&amp;lt;math&amp;gt;||\cdot||^2&amp;lt;/math&amp;gt;&amp;quot;). Более подробно, вычисление расстояния между векторами &amp;lt;math&amp;gt;\mathbf{x}_i = {x_{i1,}, ...,{x_{in}}}, \mathbf{\mu}_j = {\mu_{j1}, ...,\mu_{jn}}&amp;lt;/math&amp;gt; может быть представлено как вычисление разности между каждой парой компонент &amp;lt;math&amp;gt;(x_{iz}, \mu_{jz}), z=\overline{1, d}&amp;lt;/math&amp;gt; (узел &amp;quot;&amp;lt;math&amp;gt;-&amp;lt;/math&amp;gt;&amp;quot;), далее возведение в квадрат для каждого узла &amp;quot;&amp;lt;math&amp;gt;-&amp;lt;/math&amp;gt;&amp;quot; (узел &amp;quot;&amp;lt;math&amp;gt;()^2&amp;lt;/math&amp;gt;&amp;quot;) и суммирования выходов всех узлов &amp;quot;&amp;lt;math&amp;gt;()^2&amp;lt;/math&amp;gt;&amp;quot; (узел &amp;quot;&amp;lt;math&amp;gt;+&amp;lt;/math&amp;gt;&amp;quot;).  &lt;br /&gt;
&lt;br /&gt;
[[file:dist_calc.png|thumb|center|800px|Рис. 2. Схема вычисления расстояния между вектором и центром кластера.]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Пересчет центров кластеров&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
Информационный граф шага пересчета центров кластеров представлен на &#039;&#039;рисунке 3&#039;&#039;. Исходами данного графа является исходные векторы &amp;lt;math&amp;gt;\mathbf{x}_1, ..., \mathbf{x}_n&amp;lt;/math&amp;gt;, а также им соответствующие метки кластера, &amp;lt;math&amp;gt;L_1, ..., L_n&amp;lt;/math&amp;gt;, такие что &amp;lt;math&amp;gt;\forall x_i, i=\overline{1, n}, \mathbf{x}_i \in S_j \Leftrightarrow L_i = j&amp;lt;/math&amp;gt;, вычисленные на этапе распределения векторов по кластерам. Все векторы &amp;lt;math&amp;gt;\mathbf{x}_1, ..., \mathbf{x}_n&amp;lt;/math&amp;gt; подаются в узлы &amp;lt;math&amp;gt;+_1, ...+_k&amp;lt;/math&amp;gt;, каждый узел &amp;lt;math&amp;gt;+_m, m = \overline{1,k}&amp;lt;/math&amp;gt; соответствует операции сложения векторов кластера с номером &amp;lt;math&amp;gt;m&amp;lt;/math&amp;gt;. Метки кластера &amp;lt;math&amp;gt;L_1, ..., L_n&amp;lt;/math&amp;gt; также совместно передаются на узлы &amp;lt;math&amp;gt;S_m, m = \overline{1,k}&amp;lt;/math&amp;gt;, на каждом из которых вычисляется количество векторов в соответствующем кластере (количество меток с соответствующим значением). Далее каждая пара выходов узлов &amp;lt;math&amp;gt;+_m&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;S_m&amp;lt;/math&amp;gt; подается на узел &amp;quot;&amp;lt;math&amp;gt;/&amp;lt;/math&amp;gt;&amp;quot;, где производится деление суммы векторов кластера на количество элементов в нем. Значения, вычисленные на узлах &amp;quot;&amp;lt;math&amp;gt;/&amp;lt;/math&amp;gt;&amp;quot;, присваиваются новым центрам кластеров (выходные значения графа).&lt;br /&gt;
&lt;br /&gt;
[[file:Recluster.png|thumb|center|800px|Рис. 3. Схема пересчета центров кластеров]]&lt;br /&gt;
&lt;br /&gt;
=== Ресурс параллелизма алгоритма ===&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
Работа алгоритма состоит из &amp;lt;math&amp;gt;\Tau&amp;lt;/math&amp;gt; итераций, в каждой из которых происходит &amp;lt;b&amp;gt;распределение d-мерных векторов по &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластерам&amp;lt;/b&amp;gt;, а также &amp;lt;b&amp;gt;пересчет центров кластеров в d-мерном пространстве&amp;lt;/b&amp;gt;. В шаге &amp;lt;b&amp;gt;распределения d-мерных векторов по &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластерам&amp;lt;/b&amp;gt; расстояния между вектором и центрами кластеров вычисляются независимо (отсутствуют информационные зависимости). &amp;lt;b&amp;gt;Центры масс кластеров&amp;lt;/b&amp;gt; также пересчитываются независимо друг от друга. Таким образом, имеет место [[глоссарий#Массовый параллелизм|&#039;&#039;массовый параллелизм&#039;&#039;]]. Вычислим параллельную сложность &amp;lt;math&amp;gt;\Psi_*&amp;lt;/math&amp;gt; каждого из шагов, а также параллельную сложность всего алгоритма, &amp;lt;math&amp;gt;\Psi_{k-means}&amp;lt;/math&amp;gt;. Будем исходить из предположения, что может быть использовано любое необходимое число потоков.&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Распределение d-мерных векторов по &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластерам&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;  &lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
Поскольку на данном шаге для каждой пары векторов &amp;lt;math&amp;gt;\mathbf{x}_i, i=\overline{1,n}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\mathbf{\mu}_j, j=\overline{1,k}&amp;lt;/math&amp;gt; операции вычисления расстояния не зависят друг от друга, они могут выполняться параллельно. Тогда, разделив все вычисление расстояний на &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; потоков, получим, что в каждом потоке будет выполняться только одна операция вычисления расстояния между векторами размерности d. При этом каждому вычислительному потоку передаются координаты центров всех кластеров &amp;lt;math&amp;gt;\mathbf{\mu}_1, ..., \mathbf{\mu}_k&amp;lt;/math&amp;gt;. Таким образом, параллельная сложность данного шага определяется &amp;lt;i&amp;gt; сложностью параллельной операции вычисления расстояния между d-мерными векторами&amp;lt;/i&amp;gt;, &amp;lt;math&amp;gt;\Psi_{distance}^d&amp;lt;/math&amp;gt;  и &amp;lt;i&amp;gt;сложностью определения наиболее близкого кластера&amp;lt;/i&amp;gt; (паралельное взятие минимума по расстояниям), &amp;lt;math&amp;gt;\Psi_{min}^k&amp;lt;/math&amp;gt;. Для оценки &amp;lt;math&amp;gt;\Psi_{distance}^d&amp;lt;/math&amp;gt; воспользуемся  [[Нахождение_частных_сумм_элементов_массива_сдваиванием | параллельной реализацией нахождения частичной суммы элементов массива путем сдваивания]]. Аналогично, &amp;lt;math&amp;gt;\Psi_{min}^k = log(k)&amp;lt;/math&amp;gt;. В результате, &amp;lt;math&amp;gt;\Psi_{distance}^d = O(log(d))&amp;lt;/math&amp;gt;.   Таким образом: &lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p align=&amp;quot;center&amp;quot;&amp;gt;&amp;lt;math&amp;gt;\Psi_{distribute}^{k, d}  = \Psi_{distance}^d + \Psi_{min}^k = O(log(d))+O(log(k)) = O(log(k*d))&amp;lt;/math&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Пересчет центров кластеров в d-мерном пространстве&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
Поскольку на данном шаге для каждого из &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластеров центр масс может быть вычислен независимо, данные операции могут быть выполнены в отдельных потоках. Таким образом, параллельная сложность данного шага, &amp;lt;math&amp;gt;\Psi_{recenter}^{k, d}&amp;lt;/math&amp;gt;,  будет определяться &amp;lt;i&amp;gt;параллельной сложностью вычисления одного центра масс кластера размера &amp;lt;math&amp;gt;m&amp;lt;/math&amp;gt;&amp;lt;/i&amp;gt;, &amp;lt;math&amp;gt;\Psi_{recenter}^{k, d}&amp;lt;/math&amp;gt;,  а так как &amp;lt;math&amp;gt;m \le n \Rightarrow \Psi_{recenter}^{d, m} \le \Psi_{recenter}^{d, n}&amp;lt;/math&amp;gt;. Сложность вычисления центра масс кластера d-мерных векторов размера n аналогично предыдущим вычислениям равна &amp;lt;math&amp;gt;O(log(n))&amp;lt;/math&amp;gt;. Тогда:  &lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p align=&amp;quot;center&amp;quot;&amp;gt;&amp;lt;math&amp;gt;\Psi_{recenter}^{k, d}  \le \Psi_{recenter}^{d, n} = O(log(n))&amp;lt;/math&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Общая параллельная сложность алгоритма&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
На каждой итерации необходимо обновление центров кластеров, которые будут использованы на следующей итерации. Таким образом, итерационный процесс выполняется последовательно&amp;lt;ref&amp;gt;Zhao, Weizhong, Huifang Ma, and Qing He. &amp;quot;Parallel k-means clustering based on mapreduce.&amp;quot; IEEE International Conference on Cloud Computing. Springer Berlin Heidelberg, 2009.&amp;lt;/ref&amp;gt;. Тогда, поскольку сложность каждой итерации  определяется &amp;lt;math&amp;gt;\Psi_{distribute}^{k, d}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\Psi_{recenter}&amp;lt;/math&amp;gt;, сложность всего алгоритма, &amp;lt;math&amp;gt;\Psi_{k-means}&amp;lt;/math&amp;gt; в предположении, что было сделано &amp;lt;math&amp;gt;\Tau&amp;lt;/math&amp;gt; операций определяется выражением&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p align=&amp;quot;center&amp;quot;&amp;gt;&amp;lt;math&amp;gt;\Psi_{k-means} \approx \Tau * (\Psi_{distribute}^{k, d} + \Psi_{recenter}^{k, d}) \le \Tau * O(log(k*d*n))&amp;lt;/math&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Входные и выходные данные алгоритма ===&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;Входные данные&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;Матрица из &amp;lt;math&amp;gt;n*d&amp;lt;/math&amp;gt; элементов &amp;lt;math&amp;gt;x_{i, j} \in \mathbb{R}, i=\overline{1, n}, j=\overline{1, d}&amp;lt;/math&amp;gt;&amp;amp;ndash; координат векторов (наблюдений).&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;Целое положительное число &amp;lt;math&amp;gt;k, k \le n&amp;lt;/math&amp;gt; &amp;amp;ndash; количество кластеров.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;Объем входных данных&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;math&amp;gt;1&amp;lt;/math&amp;gt; целое число + &amp;lt;math&amp;gt;n*d&amp;lt;/math&amp;gt; вещественных чисел (при условии, что координаты &amp;amp;ndash; вещественные числа).&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;Выходные данные&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; целых положительных чисел &amp;lt;math&amp;gt;L_1, ..., L_n&amp;lt;/math&amp;gt;&amp;amp;ndash; номера кластеров, соотвествующие каждому вектору (при условии, что нумерация кластеров начинается с &amp;lt;math&amp;gt;1&amp;lt;/math&amp;gt;).&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;Объем выходных данных&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; целых положительных чисел.&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Свойства алгоритма ===&lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;[[глоссарий#Вычислительная мощность|&#039;&#039;Вычислительная мощность&#039;&#039;]]&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
Вычислительная мощность алгоритма &amp;lt;i&amp;gt;k means&amp;lt;/i&amp;gt; равна &amp;lt;math&amp;gt;\frac{k*d*n*\Tau}{n*d} = k*\Tau &amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; &amp;amp;ndash; число кластеров, &amp;lt;math&amp;gt;\Tau&amp;lt;/math&amp;gt; &amp;amp;ndash; число итераций алгоритма.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;[[глоссарий#Детерминированность |&#039;&#039;Детерминированность&#039;&#039;]] и [[глоссарий#Устойчивость |&#039;&#039;Устойчивость&#039;&#039;]] &amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
Алгоритм &amp;lt;i&amp;gt;k means&amp;lt;/i&amp;gt; является итерационным. Количество итераций алгоритма в общем случае не фиксируется и зависит от начального расположения объектов в пространстве, параметра &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt;, а также от начального приближения центров кластеров, &amp;lt;math&amp;gt;\mu_1, ..., \mu_k&amp;lt;/math&amp;gt;. В результате этого может варьироваться результат работы алгоритма. При неудачном выборе начальных параметров итерационный процесс может сойтись к локальному оптимуму&amp;lt;ref&amp;gt;Von Luxburg, Ulrike. Clustering Stability. Now Publishers Inc, 2010.&amp;lt;/ref&amp;gt;. По этим причинам алгоритм не является ни &amp;lt;b&amp;gt;детермирированным&amp;lt;/b&amp;gt;, ни &amp;lt;b&amp;gt;устойчивым&amp;lt;/b&amp;gt;.&lt;br /&gt;
 &lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Соотношение последовательной и параллельной сложности алгоритма&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\frac{\Theta_{k-means}}{\Psi_{k-means}} = \frac{O(\Tau*k*d*n)}{O(\Tau*log(k*d*n))}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Сильные стороны алгоритма&amp;lt;/b&amp;gt;:&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;i&amp;gt;Сравнительно высокая эффективность при простоте реализации&amp;lt;/i&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;i&amp;gt;Высокое качество кластеризации&amp;lt;/i&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;i&amp;gt;Возможность распараллеливания&amp;lt;/i&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;i&amp;gt;Существование множества модификаций&amp;lt;/i&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;Недостатки алгоритма&amp;lt;/b&amp;gt;&amp;lt;ref&amp;gt;Ortega, Joaquín Pérez, Ma Del Rocío Boone Rojas, and María J. Somodevilla. &amp;quot;Research issues on K-means Algorithm: An Experimental Trial Using Matlab.&amp;quot;&amp;lt;/ref&amp;gt;:&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;i&amp;gt;Количество кластеров является параметром алгоритма&amp;lt;/i&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;&amp;lt;i&amp;gt;Чувствительность к начальным условиям&amp;lt;/i&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;Инициализация центров кластеров в значительной степени влияет на результат кластеризации.&amp;lt;/p&amp;gt;&lt;br /&gt;
  &amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;&amp;lt;i&amp;gt;Чувствительность к выбросам и шумам&amp;lt;/i&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;Выбросы, далекие от центров настоящих кластеров, все равно учитываются при вычислении их центров.&amp;lt;/p&amp;gt;&lt;br /&gt;
  &amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;&amp;lt;i&amp;gt;Возможность сходимости к локальному оптимуму&amp;lt;/i&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;Итеративный подход не дает гарантии сходимости к оптимальному решению.&amp;lt;/p&amp;gt;&lt;br /&gt;
  &amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;&amp;lt;i&amp;gt;Использование понятия &amp;quot;среднего&amp;quot;&amp;lt;/i&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;Алгоритм неприменим к данным, для которых не определено понятие &amp;quot;среднего&amp;quot;, например, категориальным данным.&amp;lt;/p&amp;gt;&lt;br /&gt;
  &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&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;
Исследование масштабируемости параллельной реализации алгоритма k means проводилось на суперкомпьютере &amp;quot;Ломоносов&amp;quot;. Алгоритм реализован на языке C с использованием средств MPI.&lt;br /&gt;
Для исследования масштабируемости проводилось множество запусков программы с разным значением параметра (количество векторов для кластеризации), а также с различным числом процессоров. Фиксировались результаты запусков &amp;amp;ndash; время работы &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt; и количество произведенных итераций алгоритма &amp;lt;math&amp;gt;\Tau&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Параметры запусков для экспериментальной оценки:&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;Значения &amp;lt;b&amp;gt;количества векторов&amp;lt;/b&amp;gt; &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;: 20&#039;000, 30&#039;000, 50&#039;000, 100&#039;000, 200&#039;000, 300&#039;000, 500&#039;000, 700&#039;000, 1&#039;000&#039;000, 1&#039;500&#039;000, 2&#039;000&#039;000.&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;Значения &amp;lt;b&amp;gt;количества процессоров&amp;lt;/b&amp;gt; &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt;: 1, 8, 16, 32, 64, 128, 160, 192, 224, 256, 288, 320, 352, 384, 416, 448, 480, 512.&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;Значение &amp;lt;b&amp;gt;количества кластеров&amp;lt;/b&amp;gt; &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt;: 100.&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;Значение &amp;lt;b&amp;gt;размерности векторов&amp;lt;/b&amp;gt; &amp;lt;math&amp;gt;d&amp;lt;/math&amp;gt;: 10.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Графики производительности и эффективности реализации представлены на рисунках 4 и 5 соответственно.&lt;br /&gt;
&lt;br /&gt;
[[file:Flops.png|thumb|center|800px|Рис. 4. График производительности реализации алгоритма.]]&lt;br /&gt;
&lt;br /&gt;
[[file:Efficiency.png|thumb|center|800px|Рис. 5. График эффективности реализации алгоритма.]]&lt;br /&gt;
&lt;br /&gt;
Для заданной конфигурации эксперимента (&amp;lt;math&amp;gt;n, d, p, k&amp;lt;/math&amp;gt;) и полученных результатах (&amp;lt;math&amp;gt;t, \Tau&amp;lt;/math&amp;gt;) производительность и эффективность реализации расчитывались по формулам (см. [[#Последовательная сложность алгоритма| последовательная сложность алгоритма]]):&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
&amp;lt;ul&amp;gt;&amp;lt;li&amp;gt;&amp;lt;math&amp;gt;Performance = \frac{\Theta_{k-means}^{d, n}}{t}\ \ FLOPS&amp;lt;/math&amp;gt;&amp;lt;/li&amp;gt;&amp;lt;/ul&amp;gt;&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
&amp;lt;ul&amp;gt;&amp;lt;li&amp;gt;&amp;lt;math&amp;gt;Efficiency = \frac{100 * Performance}{Performance_{Peak}^{p}}\ \ %,&amp;lt;/math&amp;gt;&amp;lt;/li&amp;gt;&amp;lt;/ul&amp;gt;&lt;br /&gt;
где &amp;lt;math&amp;gt;Performance_{Peak}^{p}&amp;lt;/math&amp;gt; &amp;amp;ndash; пиковая производительность суперкомпьютера при &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt; процессорах, вычисленная согласно спецификациям Intel &amp;amp;reg; XEON &amp;amp;reg; X5670&amp;lt;ref&amp;gt;&amp;quot;http://ark.intel.com/ru/products/47920/Intel-Xeon-Processor-X5670-12M-Cache-2_93-GHz-6_40-GTs-Intel-QPI&amp;quot;&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;В результате&amp;lt;/b&amp;gt; экспериментальной оценки были получены следующие оценки эффективности реализации:&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;b&amp;gt;Минимальное&amp;lt;/b&amp;gt; значение: 0.000409 % достигается при &amp;lt;math&amp;gt;n=20&#039;000, p=480&amp;lt;/math&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;b&amp;gt;Максимальное&amp;lt;/b&amp;gt; значение: 0.741119 % достигается при &amp;lt;math&amp;gt;n=300&#039;000, p=1&amp;lt;/math&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Динамические характеристики и эффективность реализации алгоритма ===&lt;br /&gt;
=== Выводы для классов архитектур ===&lt;br /&gt;
=== Существующие реализации алгоритма ===&lt;br /&gt;
==== Открытое программное обеспечение ====&lt;br /&gt;
&amp;lt;ol&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;[https://www.icpsr.umich.edu/CrimeStat/ CrimeStat]&amp;lt;/li&amp;gt; Программное обеспечение, созданное для операционных систем Windows, предоставляющее инструменты статистического  и пространственного анализа для решения задачи картирования преступности.&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://juliastats.github.io Julia]&amp;lt;/li&amp;gt; Высокоуровневый высокопроизводительный свободный язык программирования с динамической типизацией, созданный для математических вычислений, содержит реализацию k-means.&lt;br /&gt;
  &amp;lt;li&amp;gt;[https://mahout.apache.org Mahout]&amp;lt;/li&amp;gt; Apache Mahout - Java библиотека для работы с алгоритмами машинного обучения с использованием MapReduce. Содержит реализацию k-means.&lt;br /&gt;
  &amp;lt;li&amp;gt;[https://www.gnu.org/software/octave/ Octave]&amp;lt;/li&amp;gt; Написанная на C++  свободная система для математических вычислений, использующая совместимый с MATLAB язык высокого уровня, содержит реализацию k-means.&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://spark.apache.org/docs/latest/mllib-clustering.html Spark]&amp;lt;/li&amp;gt; Распределенная реализация k-means содержится в библиотеке Mlib для работы с алгоритмами машинного обучения, взаимодействующая с Python библиотекой NumPy и библиотека R.&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://torch.ch Torch]&amp;lt;/li&amp;gt;  MATLAB-подобная библиотека для языка программирования Lua с открытым исходным кодом, предоставляет большое количество алгоритмов для глубинного обучения и научных расчётов. Ядро написано на Си, прикладная часть выполняется на LuaJIT, поддерживается распараллеливание вычислений средствами CUDA и OpenMP. Существуют реализации k-means.&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://www.cs.waikato.ac.nz/ml/weka/ Weka]&amp;lt;/li&amp;gt;  Cвободное программное обеспечение для анализа данных, написанное на Java. Содержит k-means и x-means.&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://accord-framework.net/docs/html/T_Accord_MachineLearning_KMeans.htm Accord.NET]&amp;lt;/li&amp;gt; C# реализация алгоритмов k-means, k-means++, k-modes.&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://docs.opencv.org/3.0-beta/doc/py_tutorials/py_ml/py_kmeans/py_kmeans_opencv/py_kmeans_opencv.html OpenCV]&amp;lt;/li&amp;gt; Написанная на С++ библиотека, направленная в основном на решение задач компьютерного зрения. Содержит реализацию k-means.&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://mlpack.org/ MLPACK]&amp;lt;/li&amp;gt; Масштабируемая С++ библиотека для работы с алгоритмами машинного обучения, содержит реализацию k-means.&lt;br /&gt;
  &amp;lt;li&amp;gt;[https://www.scipy.org/ SciPy]&amp;lt;/li&amp;gt; Библиотека Python, содержит множество реализаций k-means.&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://scikit-learn.org/ scikit-learn]&amp;lt;/li&amp;gt; Библиотека Python, содержит множество реализаций k-means.&lt;br /&gt;
  &amp;lt;li&amp;gt;[https://www.r-bloggers.com/k-means-clustering-in-r/ R]&amp;lt;/li&amp;gt; Язык программирования для статистической обработки данных и работы с графикой, а также свободная программная среда вычислений с открытым исходным кодом в рамках проекта GNU, содержит три реализации k-means.&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://elki.dbs.ifi.lmu.de ELKI]&amp;lt;/li&amp;gt; Java фреймворк, содержащий реализацию k-means, а также множество других алгоритмов кластеризации.&lt;br /&gt;
&amp;lt;/ol&amp;gt;&lt;br /&gt;
==== Проприетарное программное обеспечение  ====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ol&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;[https://www.ayasdi.com/blog/bigdata/topological-data-analysis-of-oil-and-gas-petrophysical-data/ Ayasdi]&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://www.stata.com/features/cluster-analysis/ Stata]&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://mathworld.wolfram.com/K-MeansClusteringAlgorithm.html Mathematica]&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://www.mathworks.com/help/stats/kmeans.html?requestedDomain=www.mathworks.com MATLAB]&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;[https://support.sas.com/rnd/app/stat/procedures/fastclus.html SAS]&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://docs.rapidminer.com/studio/operators/modeling/segmentation/k_means.html RapidMiner]&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;[https://blogs.sap.com/2013/03/28/sap-hana-pal-k-means-algorithm-or-how-to-do-customer-segmentation-for-the-telecommunications-industry/ SAP HANA]&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ol&amp;gt;&lt;br /&gt;
== Литература ==&lt;br /&gt;
&amp;lt;references /&amp;gt;&lt;/div&gt;</summary>
		<author><name>DennZo1993</name></author>
	</entry>
	<entry>
		<id>https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:%D0%91%D1%80%D0%BE%D1%82%D0%B8%D0%BA%D0%BE%D0%B2%D1%81%D0%BA%D0%B0%D1%8F_%D0%94%D0%B0%D0%BD%D1%83%D1%82%D0%B0/%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_k-means&amp;diff=17176</id>
		<title>Участник:Бротиковская Данута/Алгоритм k-means</title>
		<link rel="alternate" type="text/html" href="https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:%D0%91%D1%80%D0%BE%D1%82%D0%B8%D0%BA%D0%BE%D0%B2%D1%81%D0%BA%D0%B0%D1%8F_%D0%94%D0%B0%D0%BD%D1%83%D1%82%D0%B0/%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_k-means&amp;diff=17176"/>
		<updated>2016-11-15T00:02:55Z</updated>

		<summary type="html">&lt;p&gt;DennZo1993: /* Масштабируемость реализации алгоритма */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt; {{Assignment|Zhum}}&lt;br /&gt;
&lt;br /&gt;
{{algorithm&lt;br /&gt;
| name              = Алгоритм k средних (k means)&lt;br /&gt;
| serial_complexity = &amp;lt;math&amp;gt;O(\Tau*k*d*n)&amp;lt;/math&amp;gt;&lt;br /&gt;
| input_data        = &amp;lt;math&amp;gt; d*n &amp;lt;/math&amp;gt;&lt;br /&gt;
| output_data       = &amp;lt;math&amp;gt; n &amp;lt;/math&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
Авторы страницы &amp;lt;b&amp;gt;[[Участник:Бротиковская Данута|Данута Бротиковская]]&amp;lt;/b&amp;gt; и &amp;lt;b&amp;gt;[[Участник:DennZo1993|Денис Зобнин]]&amp;lt;/b&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
Оба автора внесли одинаковый вклад в написание статьи (поиск материалов, изучение статей, заполнение контента статьи), четких разграничений по пунктам статьи сделать невозможно. &lt;br /&gt;
&lt;br /&gt;
== Свойства и структура алгоритма ==&lt;br /&gt;
&lt;br /&gt;
=== Общее описание алгоритма ===&lt;br /&gt;
Алгоритм &amp;lt;b&amp;gt;&amp;lt;i&amp;gt;k средних&amp;lt;/i&amp;gt;&amp;lt;/b&amp;gt; (&amp;lt;b&amp;gt;&amp;lt;i&amp;gt;k means&amp;lt;/i&amp;gt;&amp;lt;/b&amp;gt;) &amp;amp;ndash; неиерархический&amp;lt;ref&amp;gt;&amp;quot;https://ru.wikipedia.org/wiki/Иерархическая_кластеризация&amp;quot;&amp;lt;/ref&amp;gt;, итерационный метод кластеризации&amp;lt;ref&amp;gt;&amp;quot;https://ru.wikipedia.org/wiki/Кластерный_анализ&amp;quot;&amp;lt;/ref&amp;gt;, получивший большую популярность благодаря своей простоте, наглядности реализации и достаточно высокому качеству работы. Был изобретен в 1950-х годах математиком &amp;lt;i&amp;gt;Гуго Штейнгаузом&amp;lt;/i&amp;gt;&amp;lt;ref&amp;gt;Steinhaus, Hugo. &amp;quot;Sur la division des corp materiels en parties.&amp;quot; Bull. Acad. Polon. Sci 1.804 (1956): 801.&amp;lt;/ref&amp;gt; и почти одновременно &amp;lt;i&amp;gt;Стюартом Ллойдом&amp;lt;/i&amp;gt;&amp;lt;ref&amp;gt;Lloyd, S. P. &amp;quot;Least square quantization in PCM. Bell Telephone Laboratories Paper. Published in journal much later: Lloyd, SP: Least squares quantization in PCM.&amp;quot; IEEE Trans. Inform. Theor.(1957/1982).&amp;lt;/ref&amp;gt;. Особую популярность приобрел после публикации работы &amp;lt;i&amp;gt;МакКуина&amp;lt;/i&amp;gt;&amp;lt;ref&amp;gt;MacQueen, James. &amp;quot;Some methods for classification and analysis of multivariate observations.&amp;quot; Proceedings of the fifth Berkeley symposium on mathematical statistics and probability. Vol. 1. No. 14. 1967.&amp;lt;/ref&amp;gt; в 1967.&lt;br /&gt;
&lt;br /&gt;
Алгоритм представляет собой версию EM-алгоритма&amp;lt;ref&amp;gt;&amp;quot;https://ru.wikipedia.org/wiki/EM-алгоритм&amp;quot;&amp;lt;/ref&amp;gt;, применяемого также для разделения смеси гауссиан. Основная идея &amp;lt;i&amp;gt;k means&amp;lt;/i&amp;gt; заключается в том, что данные произвольно разбиваются на кластеры, после чего итеративно перевычисляется центр масс для каждого кластера, полученного на предыдущем шаге, затем векторы разбиваются на кластеры вновь в соответствии с тем, какой из новых центров оказался ближе по выбранной метрике.&lt;br /&gt;
&lt;br /&gt;
Цель алгоритма заключается в разделении &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; наблюдений на &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластеров таким образом, чтобы каждое наблюдение принадлежало ровно одному кластеру, расположенному на наименьшем расстоянии от наблюдения.&lt;br /&gt;
&lt;br /&gt;
=== Математическое описание алгоритма ===&lt;br /&gt;
&amp;lt;b&amp;gt;&amp;lt;u&amp;gt;Дано:&amp;lt;/u&amp;gt;&amp;lt;/b&amp;gt;&lt;br /&gt;
* набор из &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; наблюдений &amp;lt;math&amp;gt;X=\{\mathbf{x}_1, \mathbf{x}_2, ..., \mathbf{x}_n\}, \mathbf{x}_i \in \mathbb{R}^d, i=\overline{1, n}&amp;lt;/math&amp;gt;;&lt;br /&gt;
* &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; - требуемое число кластеров, &amp;lt;math&amp;gt;k \in \mathbb{N}, k \leq n&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;&amp;lt;u&amp;gt;Требуется:&amp;lt;/u&amp;gt;&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Разделить множество наблюдений &amp;lt;math&amp;gt;X&amp;lt;/math&amp;gt; на &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластеров &amp;lt;math&amp;gt;S_1, S_2, ..., S_k&amp;lt;/math&amp;gt;:&lt;br /&gt;
*   &amp;lt;math&amp;gt;S_i \cap S_j= \varnothing, \quad i \ne j&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
*   &amp;lt;math&amp;gt;\bigcup_{i=1}^{k} S_i = X&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;&amp;lt;u&amp;gt;Действие алгоритма:&amp;lt;/u&amp;gt;&amp;lt;/b&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;Алгоритм &amp;lt;i&amp;gt;k means&amp;lt;/i&amp;gt; разбивает набор &amp;lt;math&amp;gt;X&amp;lt;/math&amp;gt; на &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; наборов &amp;lt;math&amp;gt;S_1, S_2, ..., S_k,&amp;lt;/math&amp;gt; таким образом, чтобы минимизировать сумму квадратов расстояний от каждой точки кластера до его центра (центр масс кластера). Введем обозначение, &amp;lt;math&amp;gt;S=\{S_1, S_2, ..., S_k\}&amp;lt;/math&amp;gt;. Тогда действие алгоритма &amp;lt;i&amp;gt;k means&amp;lt;/i&amp;gt; равносильно поиску:&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;table style=&amp;quot;width:100%&amp;quot;&amp;gt;&lt;br /&gt;
  &amp;lt;tr&amp;gt;&lt;br /&gt;
    &amp;lt;td align=&amp;quot;center&amp;quot; width=&amp;quot;90%&amp;quot;&amp;gt;&amp;lt;math&amp;gt;\arg\min_{S} \sum\limits_{i=1}^k \sum\limits_{\mathbf{x} \in S_i} \rho(\mathbf{x}, \mathbf{\mu}_i )^2,&amp;lt;/math&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;td align=&amp;quot;right&amp;quot;&amp;gt;&amp;lt;math&amp;gt;(1)&amp;lt;/math&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;/table&amp;gt;&lt;br /&gt;
где &amp;lt;math&amp;gt;\mathbf{\mu}_i&amp;lt;/math&amp;gt; &amp;amp;ndash; центры кластеров, &amp;lt;math&amp;gt;i=\overline{1,k}, \quad \rho(\mathbf{x}, \mathbf{\mu}_i)&amp;lt;/math&amp;gt; &amp;amp;ndash; функция расстояния между &amp;lt;math&amp;gt;\mathbf{x}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\mu_i&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;&amp;lt;u&amp;gt;Шаги алгоритма: &amp;lt;/u&amp;gt;&amp;lt;/b&amp;gt;&lt;br /&gt;
&amp;lt;ol&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&lt;br /&gt;
    &amp;lt;b&amp;gt;Начальный шаг: инициализация кластеров&amp;lt;/b&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;Выбирается произвольное множество точек &amp;lt;math&amp;gt;\mu_i, i=\overline{1,k}&amp;lt;/math&amp;gt;, рассматриваемых как начальные центры кластеров: &amp;lt;math&amp;gt;\mu_i^{(0)} = \mu_i, \quad i=\overline{1, k}&amp;lt;/math&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
  &amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&lt;br /&gt;
    &amp;lt;b&amp;gt;Распределение векторов по кластерам&amp;lt;/b&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Шаг&amp;lt;/b&amp;gt; &amp;lt;math&amp;gt;t: \forall \mathbf{x}_i \in X, i=\overline{1,n}: \mathbf{x}_i \in S_j \iff  j=\arg\min_{k}\rho(\mathbf{x}_i,\mathbf{\mu}_k^{(t-1)})^2&amp;lt;/math&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
  &amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&lt;br /&gt;
    &amp;lt;b&amp;gt;Пересчет центров кластеров&amp;lt;/b&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Шаг &amp;lt;/b&amp;gt; &amp;lt;math&amp;gt;t: \forall i=\overline{1,k}:  \mu_i^{(t)} = \cfrac{1}{|S_i|}\sum_{\mathbf{x}\in S_i}\mathbf{x}&amp;lt;/math&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
  &amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&lt;br /&gt;
    &amp;lt;b&amp;gt;Проверка условия останова:&amp;lt;/b&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
    &#039;&#039;&#039;if&#039;&#039;&#039; &amp;lt;math&amp;gt;\exist i\in \overline{1,k}: \mu_i^{(t)} \ne \mu_i^{(t-1)}&amp;lt;/math&amp;gt; &#039;&#039;&#039;then&#039;&#039;&#039;&lt;br /&gt;
        t = t + 1;&lt;br /&gt;
        goto 2;&lt;br /&gt;
    &#039;&#039;&#039;else&#039;&#039;&#039;&lt;br /&gt;
        &#039;&#039;&#039;stop&#039;&#039;&#039;&lt;br /&gt;
  &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ol&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Вычислительное ядро алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Вычислительным ядром являются шаги 2 и 3 приведенного выше алгоритма: &amp;lt;b&amp;gt;&amp;lt;i&amp;gt;распределение векторов по кластерам&amp;lt;/i&amp;gt;&amp;lt;/b&amp;gt; и &amp;lt;b&amp;gt;&amp;lt;i&amp;gt;пересчет центров кластеров&amp;lt;/i&amp;gt;&amp;lt;/b&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;&amp;lt;i&amp;gt;Распределение векторов&amp;lt;/i&amp;gt;&amp;lt;/b&amp;gt; по кластерам предполагает вычисление расстояний между каждым вектором &amp;lt;math&amp;gt;\mathbf{x}_i \in X, i= \overline{1,n}&amp;lt;/math&amp;gt; и центрами кластера &amp;lt;math&amp;gt;\mathbf{\mu}_j, j= \overline{1,k}&amp;lt;/math&amp;gt;. Таким образом, данный шаг предполагает &amp;lt;math&amp;gt;k*n&amp;lt;/math&amp;gt; вычислений расстояний между d-мерными векторами. &lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;&amp;lt;i&amp;gt;Пересчет центров кластеров&amp;lt;/i&amp;gt;&amp;lt;/b&amp;gt; предполагает &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; вычислений центров масс &amp;lt;math&amp;gt;\mathbf{\mu}_i&amp;lt;/math&amp;gt; множеств &amp;lt;math&amp;gt;S_i, i=\overline{1,k}&amp;lt;/math&amp;gt; представленных выражением в шаге 3 представленного выше алгоритма.&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Макроструктура алгоритма ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Инициализация центров масс &amp;lt;math&amp;gt;\mu_1, ..., \mu_k&amp;lt;/math&amp;gt;&amp;lt;/b&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
Наиболее распространенными являются следующие стратегии:&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&lt;br /&gt;
    &amp;lt;b&amp;gt;Метод Forgy&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;В качестве начальных значений &amp;lt;math&amp;gt;\mu_1, ..., \mu_k&amp;lt;/math&amp;gt; берутся случайно выбранные векторы.&lt;br /&gt;
  &amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&lt;br /&gt;
    &amp;lt;b&amp;gt;Метод случайно разделения (Random Partitioning)&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;Для каждого вектора &amp;lt;math&amp;gt;\mathbf{x}_i \in X, i=\overline{1, n}&amp;lt;/math&amp;gt; выбирается случайным образом кластер &amp;lt;math&amp;gt;S_1, ..., S_k&amp;lt;/math&amp;gt;, после чего для каждого полученного кластера вычисляются значения &amp;lt;math&amp;gt;\mu_1, ..., \mu_k&amp;lt;/math&amp;gt;.&lt;br /&gt;
  &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Распределение векторов по кластерам&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Для этого шага алгоритма между векторами &amp;lt;math&amp;gt;\mathbf{x}_i \in X, i=\overline{1, n}&amp;lt;/math&amp;gt; и центрами кластеров &amp;lt;math&amp;gt;\mu_1, ..., \mu_k&amp;lt;/math&amp;gt; вычисляются &amp;lt;b&amp;gt;расстояния&amp;lt;/b&amp;gt; по формуле (как правило, используется Евлидово расстояние):&lt;br /&gt;
&amp;lt;table style=&amp;quot;width:100%&amp;quot;&amp;gt;&lt;br /&gt;
  &amp;lt;tr&amp;gt;&lt;br /&gt;
    &amp;lt;td align=&amp;quot;center&amp;quot; width=&amp;quot;90%&amp;quot;&amp;gt;&amp;lt;math&amp;gt; \mathbf{v}_1, \mathbf{v}_2 \in \mathbb{R}^d,  \quad \rho(\mathbf{v}_1, \mathbf{v}_2) = \lVert \mathbf{v}_1- \mathbf{v}_2 \rVert= \sqrt{\sum_{i=1}^{d}(\mathbf{v}_{1,i} - \mathbf{v}_{2,i})^2}&amp;lt;/math&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;td align=&amp;quot;right&amp;quot;&amp;gt;&amp;lt;math&amp;gt;(2)&amp;lt;/math&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;/table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Пересчет центров кластеров&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Для этого шага алгоритма производится пересчет центров кластера по &amp;lt;b&amp;gt;формуле вычисления центра масс&amp;lt;/b&amp;gt;:&lt;br /&gt;
&amp;lt;table style=&amp;quot;width:100%&amp;quot;&amp;gt;&lt;br /&gt;
  &amp;lt;tr&amp;gt;&lt;br /&gt;
    &amp;lt;td align=&amp;quot;center&amp;quot; width=&amp;quot;90%&amp;quot;&amp;gt;&amp;lt;math&amp;gt; \mu = \cfrac{1}{|S|}\sum_{\mathbf{x}\in S}\mathbf{x}&amp;lt;/math&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;td align=&amp;quot;right&amp;quot;&amp;gt;&amp;lt;math&amp;gt;(3)&amp;lt;/math&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;/table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Схема реализации последовательного алгоритма ===&lt;br /&gt;
&lt;br /&gt;
 &#039;&#039;&#039;algorithm&#039;&#039;&#039; k-means &#039;&#039;&#039;is&#039;&#039;&#039;&lt;br /&gt;
     &#039;&#039;&#039;1.&#039;&#039;&#039; Инициализировать центры кластеров &amp;lt;math&amp;gt;\mathbf{\mu}_i^{(1)}, i=\overline{1,k}&amp;lt;/math&amp;gt;&lt;br /&gt;
     &#039;&#039;&#039;2.&#039;&#039;&#039; &amp;lt;math&amp;gt;t \leftarrow 1&amp;lt;/math&amp;gt;&lt;br /&gt;
     &#039;&#039;&#039;3.&#039;&#039;&#039; &#039;&#039;&#039;Распределение по кластерам&#039;&#039;&#039;&amp;lt;br&amp;gt;&lt;br /&gt;
        &amp;lt;math&amp;gt;S_i^{(t)}=\{\mathbf{x}_p: \lVert\mathbf{x}_p-\mathbf{\mu}_i^{(t)}\rVert^2 \leq \lVert\mathbf{x}_p-\mathbf{\mu}_j^{(t)}\rVert^2 \quad \forall j=\overline{1,k}\},&amp;lt;/math&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
        где каждый вектор &amp;lt;math&amp;gt;\mathbf{x}_p&amp;lt;/math&amp;gt; соотносится единственному кластеру &amp;lt;math&amp;gt;S^{(t)}&amp;lt;/math&amp;gt;&lt;br /&gt;
     &#039;&#039;&#039;4.&#039;&#039;&#039; &#039;&#039;&#039;Обновление центров кластеров&#039;&#039;&#039;&amp;lt;br&amp;gt;&lt;br /&gt;
        &amp;lt;math&amp;gt;\mathbf{\mu}_i^{(t+1)} = \frac{1}{|S^{(t)}_i|} \sum_{\mathbf{x}_j \in S^{(t)}_i} \mathbf{x}_j &amp;lt;/math&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
     &#039;&#039;&#039;5.&#039;&#039;&#039; &#039;&#039;&#039;if&#039;&#039;&#039; &amp;lt;math&amp;gt;\exist i \in \overline{1,k}: \mathbf{\mu}_i^{(t+1)} \ne \mathbf{\mu}_i^{(t)}&amp;lt;/math&amp;gt; &#039;&#039;&#039;then&#039;&#039;&#039;&lt;br /&gt;
            t = t + 1;&lt;br /&gt;
            goto &#039;&#039;&#039;3&#039;&#039;&#039;;&lt;br /&gt;
        &#039;&#039;&#039;else&#039;&#039;&#039;&lt;br /&gt;
            &#039;&#039;&#039;stop&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
=== Последовательная сложность алгоритма===&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding-bottom: 20px&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;Обозначим &amp;lt;math&amp;gt;\Theta_{centroid}^{d, m}&amp;lt;/math&amp;gt; временную сложность вычисления центорида кластера, число элементов которого равна &amp;lt;math&amp;gt;m&amp;lt;/math&amp;gt;,  в d-мерном пространстве.&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;Аналогично  &amp;lt;math&amp;gt;\Theta_{distance}^d&amp;lt;/math&amp;gt; &amp;amp;ndash; временная сложность вычисления расстояния между двумя d-мерными векторами.&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding-bottom: 20px&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;Сложность шага инициализации &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластеров мощности &amp;lt;math&amp;gt;m&amp;lt;/math&amp;gt; в d-мерном пространстве &amp;amp;ndash; &amp;lt;math&amp;gt;\Theta_{init}^{k, d, m}&amp;lt;/math&amp;gt;&amp;lt;/b&amp;gt;&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;i&amp;gt;Стратерия Forgy&amp;lt;/i&amp;gt;: вычисления не требуются, &amp;lt;math&amp;gt;\Theta_{init}^{k, d, m} = 0&amp;lt;/math&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;i&amp;gt;Стратегия случайного разбиения&amp;lt;/i&amp;gt;: вычисление центров &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластеров,  &amp;lt;math&amp;gt;\Theta_{init}^{k, d, m} = k*\Theta_{centroid}^{d, m}, m \le n&amp;lt;/math&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding-bottom: 20px&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Cложность шага распределения d мерных векторов по &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластерам &amp;amp;ndash; &amp;lt;math&amp;gt;\Theta_{distribute}^{k, d}&amp;lt;/math&amp;gt;&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
На этом шаге для каждого вектора &amp;lt;math&amp;gt;\mathbf{x}_i \in X, i=\overline{1, n}&amp;lt;/math&amp;gt; вычисляется k расстояний до центров кластеров &amp;lt;math&amp;gt;\mathbf{\mu}_1, ...\mathbf{\mu}_k&amp;lt;/math&amp;gt;&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p align=&amp;quot;center&amp;quot;&amp;gt;&lt;br /&gt;
  &amp;lt;math&amp;gt;\Theta_{distribute}^{k, d} = n*k*\Theta_{distance}^d&amp;lt;/math&amp;gt;&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding-bottom: 20px&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;Сложность шага пересчета центров &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластеров размера &amp;lt;math&amp;gt;m&amp;lt;/math&amp;gt; в d-мерном пространстве &amp;amp;ndash; &amp;lt;math&amp;gt;\Theta_{recenter}^{k, d, m}&amp;lt;/math&amp;gt;&amp;lt;/b&amp;gt;&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;На этом шаге вычисляется &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; центров кластеров &amp;lt;math&amp;gt;\mathbf{\mu}_1, ...\mathbf{\mu}_k&amp;lt;/math&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p align=&amp;quot;center&amp;quot;&amp;gt;&amp;lt;math&amp;gt;\Theta_{recenter}^{k, d, m} = k*\Theta_{centroid}^{d, m}&amp;lt;/math&amp;gt; &amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding-bottom: 20px&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Рассчитаем &amp;lt;math&amp;gt;\Theta_{centroid}^{d, m}&amp;lt;/math&amp;gt; для кластера, число элементов которого равно &amp;lt;math&amp;gt;m&amp;lt;/math&amp;gt;&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p align=&amp;quot;center&amp;quot;&amp;gt;&amp;lt;math&amp;gt;\Theta_{centroid}^{d, m}&amp;lt;/math&amp;gt; = &amp;lt;math&amp;gt;m * d&amp;lt;/math&amp;gt; сложений + &amp;lt;math&amp;gt;d&amp;lt;/math&amp;gt; делений &amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding-bottom: 20px&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Рассчитаем &amp;lt;math&amp;gt;\Theta_{distance}^d&amp;lt;/math&amp;gt; в соответствие с формулой &amp;lt;math&amp;gt;(2)&amp;lt;/math&amp;gt;&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p align=&amp;quot;center&amp;quot;&amp;gt;&amp;lt;math&amp;gt;\Theta_{distance}^d&amp;lt;/math&amp;gt; = &amp;lt;math&amp;gt;d&amp;lt;/math&amp;gt; вычитаний + &amp;lt;math&amp;gt;d&amp;lt;/math&amp;gt; умножений + &amp;lt;math&amp;gt;(d-1)&amp;lt;/math&amp;gt; сложение&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding-bottom: 20px&amp;quot;&amp;gt;&lt;br /&gt;
  &amp;lt;p&amp;gt;Предположим, что алгоритм сошелся за &amp;lt;math&amp;gt;\Tau&amp;lt;/math&amp;gt; итераций, тогда временная сложность алгоритма &amp;lt;math&amp;gt;\Theta_{k-means}^{d, n}&amp;lt;/math&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
  &amp;lt;p align=&amp;quot;center&amp;quot;&amp;gt;&amp;lt;b&amp;gt;&amp;lt;math&amp;gt;\Theta_{k-means}^{d, n} \le \Theta_{init}^{k, d, n} + \Tau*(\Theta_{distribute}^{k, d} + \Theta_{recenter}^{k, d, n})&amp;lt;/math&amp;gt;&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding-bottom: 5px&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;Операции сложения/вычитания:&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p align=&amp;quot;center&amp;quot;&amp;gt;&amp;lt;b&amp;gt;&amp;lt;math&amp;gt;\Theta_{k-means}^{d, n} \le k*n*d+ \Tau*(k*n*(2d-1) + k*n*d) = k*n*d+ \Tau*(k*n*(3d-1)) \thicksim O(\Tau*k*d*n)&amp;lt;/math&amp;gt;&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding-bottom: 20px&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;Операции умножения/деления:&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p align=&amp;quot;center&amp;quot;&amp;gt;&amp;lt;b&amp;gt;&amp;lt;math&amp;gt;\Theta_{k-means}^{d, n} \le k*d + \Tau*(k*n*d + k*d) = k*d + \Tau * k*d*(n+1) \thicksim O(\Tau*k*d*n) &amp;lt;/math&amp;gt;&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding-bottom: 20px&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;Получаем, что &amp;lt;b&amp;gt;временная сложность&amp;lt;/b&amp;gt; алгоритма &amp;lt;b&amp;gt;k means&amp;lt;/b&amp;gt; кластеризации &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; &amp;lt;b&amp;gt;d-мерных&amp;lt;/b&amp;gt; векторов на &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластеров за &amp;lt;math&amp;gt;\Tau&amp;lt;/math&amp;gt; итераций:&amp;lt;/p&amp;gt;&lt;br /&gt;
 &amp;lt;p align=&amp;quot;center&amp;quot;&amp;gt;&amp;lt;b&amp;gt;&amp;lt;math&amp;gt; \Theta_{k-means}^{d, n} \thicksim O(\Tau*k*d*n) &amp;lt;/math&amp;gt;&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Информационный граф ===&lt;br /&gt;
&lt;br /&gt;
Рассмотрим информационный граф алгоритма. Алгоритм &amp;lt;i&amp;gt;k means&amp;lt;/i&amp;gt; начинается с этапа инициализации, после которого следуют итерации, на каждой из которых выполняется два последовательных шага (см. [[#Схема реализации последовательного алгоритма|&amp;quot;Схема реализации последовательного алгоритма&amp;quot;]]): &lt;br /&gt;
* распределение векторов по кластерам&lt;br /&gt;
* перерасчет центров кластеров&lt;br /&gt;
&lt;br /&gt;
Поскольку основная часть вычислений приходится на шаги итераций, распишем информационные графы данных шагов.&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Распределение векторов по кластерам&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
Информационный граф шага распределения векторов по кластерам представлен на &#039;&#039;рисунке 1&#039;&#039;. Исходами данного графа является исходные векторы &amp;lt;math&amp;gt;\mathbf{x}_1, ..., \mathbf{x}_n&amp;lt;/math&amp;gt;, а также центры кластеров &amp;lt;math&amp;gt;\mathbf{\mu}_1, ... \mathbf{\mu}_k&amp;lt;/math&amp;gt;, вычисленные ранее (на шаге инициализации, если рассматривается первая итерация алгоритма, или на шаге пересчета центров кластеров предыдущей итерации в противном случае). Каждая пара векторов данных &amp;lt;math&amp;gt;\mathbf{x}_i, i=\overline{1,n}&amp;lt;/math&amp;gt; и центров кластера &amp;lt;math&amp;gt;\mathbf{\mu}_j, j=\overline{1, k}&amp;lt;/math&amp;gt; : (&amp;lt;math&amp;gt;\mathbf{x}_i&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;\mathbf{\mu}_j&amp;lt;/math&amp;gt;) подаются на независимые узлы &amp;lt;i&amp;gt;&amp;quot;d&amp;quot;&amp;lt;/i&amp;gt; вычисления расстояния между векторами (более подробная схема вычисления расстояния представлена далее, &#039;&#039;рисунок 2&#039;&#039;). Далее узлы вычисления расстояния &amp;lt;i&amp;gt;&amp;quot;d&amp;quot;&amp;lt;/i&amp;gt;, соответствующие одному и тому же исходному вектору &amp;lt;math&amp;gt;\mathbf{x}_i&amp;lt;/math&amp;gt; передаются на один узел &amp;lt;i&amp;gt;&amp;quot;m&amp;quot;&amp;lt;/i&amp;gt;, где далее происходит вычисление новой метки кластера для каждого вектора &amp;lt;math&amp;gt;\mathbf{x}_i&amp;lt;/math&amp;gt; (берется кластер с минимальным результатом вычисления расстояния). На выходе графа выдаются метки кластеров , &amp;lt;math&amp;gt;L_1, ..., L_n&amp;lt;/math&amp;gt;, такие что &amp;lt;math&amp;gt;\forall \mathbf{x}_i, i=\overline{1, n}, \mathbf{x}_i \in S_j \Leftrightarrow L_i = j&amp;lt;/math&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
[[file:Clusterization.png|thumb|center|800px|Рис. 1. Схема распределения векторов по кластерам. &#039;&#039;d&#039;&#039; &amp;amp;ndash; вычисление расстояния между векторами; &#039;&#039;m&#039;&#039; &amp;amp;ndash; вычисление минимума.]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Вычисление расстояния между векторами&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
Подробная схема вычисления расстояния между векторами &amp;lt;math&amp;gt;\mathbf{x}_i, \mathbf{\mu}_j&amp;lt;/math&amp;gt; представлена на &#039;&#039;рисунке 2&#039;&#039;. Как показано на графе, узел вычисления расстояния между векторами &amp;lt;i&amp;gt;&amp;quot;d&amp;quot;&amp;lt;/i&amp;gt; состоит из шага взятия разности между векторами (узел &amp;quot;&amp;lt;math&amp;gt;-&amp;lt;/math&amp;gt;&amp;quot;) и взятия нормы получившегося вектора разности (узел &amp;quot;&amp;lt;math&amp;gt;||\cdot||^2&amp;lt;/math&amp;gt;&amp;quot;). Более подробно, вычисление расстояния между векторами &amp;lt;math&amp;gt;\mathbf{x}_i = {x_{i1,}, ...,{x_{in}}}, \mathbf{\mu}_j = {\mu_{j1}, ...,\mu_{jn}}&amp;lt;/math&amp;gt; может быть представлено как вычисление разности между каждой парой компонент &amp;lt;math&amp;gt;(x_{iz}, \mu_{jz}), z=\overline{1, d}&amp;lt;/math&amp;gt; (узел &amp;quot;&amp;lt;math&amp;gt;-&amp;lt;/math&amp;gt;&amp;quot;), далее возведение в квадрат для каждого узла &amp;quot;&amp;lt;math&amp;gt;-&amp;lt;/math&amp;gt;&amp;quot; (узел &amp;quot;&amp;lt;math&amp;gt;()^2&amp;lt;/math&amp;gt;&amp;quot;) и суммирования выходов всех узлов &amp;quot;&amp;lt;math&amp;gt;()^2&amp;lt;/math&amp;gt;&amp;quot; (узел &amp;quot;&amp;lt;math&amp;gt;+&amp;lt;/math&amp;gt;&amp;quot;).  &lt;br /&gt;
&lt;br /&gt;
[[file:dist_calc.png|thumb|center|800px|Рис. 2. Схема вычисления расстояния между вектором и центром кластера.]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Пересчет центров кластеров&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
Информационный граф шага пересчета центров кластеров представлен на &#039;&#039;рисунке 3&#039;&#039;. Исходами данного графа является исходные векторы &amp;lt;math&amp;gt;\mathbf{x}_1, ..., \mathbf{x}_n&amp;lt;/math&amp;gt;, а также им соответствующие метки кластера, &amp;lt;math&amp;gt;L_1, ..., L_n&amp;lt;/math&amp;gt;, такие что &amp;lt;math&amp;gt;\forall x_i, i=\overline{1, n}, \mathbf{x}_i \in S_j \Leftrightarrow L_i = j&amp;lt;/math&amp;gt;, вычисленные на этапе распределения векторов по кластерам. Все векторы &amp;lt;math&amp;gt;\mathbf{x}_1, ..., \mathbf{x}_n&amp;lt;/math&amp;gt; подаются в узлы &amp;lt;math&amp;gt;+_1, ...+_k&amp;lt;/math&amp;gt;, каждый узел &amp;lt;math&amp;gt;+_m, m = \overline{1,k}&amp;lt;/math&amp;gt; соответствует операции сложения векторов кластера с номером &amp;lt;math&amp;gt;m&amp;lt;/math&amp;gt;. Метки кластера &amp;lt;math&amp;gt;L_1, ..., L_n&amp;lt;/math&amp;gt; также совместно передаются на узлы &amp;lt;math&amp;gt;S_m, m = \overline{1,k}&amp;lt;/math&amp;gt;, на каждом из которых вычисляется количество векторов в соответствующем кластере (количество меток с соответствующим значением). Далее каждая пара выходов узлов &amp;lt;math&amp;gt;+_m&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;S_m&amp;lt;/math&amp;gt; подается на узел &amp;quot;&amp;lt;math&amp;gt;/&amp;lt;/math&amp;gt;&amp;quot;, где производится деление суммы векторов кластера на количество элементов в нем. Значения, вычисленные на узлах &amp;quot;&amp;lt;math&amp;gt;/&amp;lt;/math&amp;gt;&amp;quot;, присваиваются новым центрам кластеров (выходные значения графа).&lt;br /&gt;
&lt;br /&gt;
[[file:Recluster.png|thumb|center|800px|Рис. 3. Схема пересчета центров кластеров]]&lt;br /&gt;
&lt;br /&gt;
=== Ресурс параллелизма алгоритма ===&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
Работа алгоритма состоит из &amp;lt;math&amp;gt;\Tau&amp;lt;/math&amp;gt; итераций, в каждой из которых происходит &amp;lt;b&amp;gt;распределение d-мерных векторов по &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластерам&amp;lt;/b&amp;gt;, а также &amp;lt;b&amp;gt;пересчет центров кластеров в d-мерном пространстве&amp;lt;/b&amp;gt;. В шаге &amp;lt;b&amp;gt;распределения d-мерных векторов по &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластерам&amp;lt;/b&amp;gt; расстояния между вектором и центрами кластеров вычисляются независимо (отсутствуют информационные зависимости). &amp;lt;b&amp;gt;Центры масс кластеров&amp;lt;/b&amp;gt; также пересчитываются независимо друг от друга. Таким образом, имеет место [[глоссарий#Массовый параллелизм|&#039;&#039;массовый параллелизм&#039;&#039;]]. Вычислим параллельную сложность &amp;lt;math&amp;gt;\Psi_*&amp;lt;/math&amp;gt; каждого из шагов, а также параллельную сложность всего алгоритма, &amp;lt;math&amp;gt;\Psi_{k-means}&amp;lt;/math&amp;gt;. Будем исходить из предположения, что может быть использовано любое необходимое число потоков.&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Распределение d-мерных векторов по &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластерам&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;  &lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
Поскольку на данном шаге для каждой пары векторов &amp;lt;math&amp;gt;\mathbf{x}_i, i=\overline{1,n}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\mathbf{\mu}_j, j=\overline{1,k}&amp;lt;/math&amp;gt; операции вычисления расстояния не зависят друг от друга, они могут выполняться параллельно. Тогда, разделив все вычисление расстояний на &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; потоков, получим, что в каждом потоке будет выполняться только одна операция вычисления расстояния между векторами размерности d. При этом каждому вычислительному потоку передаются координаты центров всех кластеров &amp;lt;math&amp;gt;\mathbf{\mu}_1, ..., \mathbf{\mu}_k&amp;lt;/math&amp;gt;. Таким образом, параллельная сложность данного шага определяется &amp;lt;i&amp;gt; сложностью параллельной операции вычисления расстояния между d-мерными векторами&amp;lt;/i&amp;gt;, &amp;lt;math&amp;gt;\Psi_{distance}^d&amp;lt;/math&amp;gt;  и &amp;lt;i&amp;gt;сложностью определения наиболее близкого кластера&amp;lt;/i&amp;gt; (паралельное взятие минимума по расстояниям), &amp;lt;math&amp;gt;\Psi_{min}^k&amp;lt;/math&amp;gt;. Для оценки &amp;lt;math&amp;gt;\Psi_{distance}^d&amp;lt;/math&amp;gt; воспользуемся  [[Нахождение_частных_сумм_элементов_массива_сдваиванием | параллельной реализацией нахождения частичной суммы элементов массива путем сдваивания]]. Аналогично, &amp;lt;math&amp;gt;\Psi_{min}^k = log(k)&amp;lt;/math&amp;gt;. В результате, &amp;lt;math&amp;gt;\Psi_{distance}^d = O(log(d))&amp;lt;/math&amp;gt;.   Таким образом: &lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p align=&amp;quot;center&amp;quot;&amp;gt;&amp;lt;math&amp;gt;\Psi_{distribute}^{k, d}  = \Psi_{distance}^d + \Psi_{min}^k = O(log(d))+O(log(k)) = O(log(k*d))&amp;lt;/math&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Пересчет центров кластеров в d-мерном пространстве&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
Поскольку на данном шаге для каждого из &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластеров центр масс может быть вычислен независимо, данные операции могут быть выполнены в отдельных потоках. Таким образом, параллельная сложность данного шага, &amp;lt;math&amp;gt;\Psi_{recenter}^{k, d}&amp;lt;/math&amp;gt;,  будет определяться &amp;lt;i&amp;gt;параллельной сложностью вычисления одного центра масс кластера размера &amp;lt;math&amp;gt;m&amp;lt;/math&amp;gt;&amp;lt;/i&amp;gt;, &amp;lt;math&amp;gt;\Psi_{recenter}^{k, d}&amp;lt;/math&amp;gt;,  а так как &amp;lt;math&amp;gt;m \le n \Rightarrow \Psi_{recenter}^{d, m} \le \Psi_{recenter}^{d, n}&amp;lt;/math&amp;gt;. Сложность вычисления центра масс кластера d-мерных векторов размера n аналогично предыдущим вычислениям равна &amp;lt;math&amp;gt;O(log(n))&amp;lt;/math&amp;gt;. Тогда:  &lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p align=&amp;quot;center&amp;quot;&amp;gt;&amp;lt;math&amp;gt;\Psi_{recenter}^{k, d}  \le \Psi_{recenter}^{d, n} = O(log(n))&amp;lt;/math&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Общая параллельная сложность алгоритма&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
На каждой итерации необходимо обновление центров кластеров, которые будут использованы на следующей итерации. Таким образом, итерационный процесс выполняется последовательно&amp;lt;ref&amp;gt;Zhao, Weizhong, Huifang Ma, and Qing He. &amp;quot;Parallel k-means clustering based on mapreduce.&amp;quot; IEEE International Conference on Cloud Computing. Springer Berlin Heidelberg, 2009.&amp;lt;/ref&amp;gt;. Тогда, поскольку сложность каждой итерации  определяется &amp;lt;math&amp;gt;\Psi_{distribute}^{k, d}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\Psi_{recenter}&amp;lt;/math&amp;gt;, сложность всего алгоритма, &amp;lt;math&amp;gt;\Psi_{k-means}&amp;lt;/math&amp;gt; в предположении, что было сделано &amp;lt;math&amp;gt;\Tau&amp;lt;/math&amp;gt; операций определяется выражением&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p align=&amp;quot;center&amp;quot;&amp;gt;&amp;lt;math&amp;gt;\Psi_{k-means} \approx \Tau * (\Psi_{distribute}^{k, d} + \Psi_{recenter}^{k, d}) \le \Tau * O(log(k*d*n))&amp;lt;/math&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Входные и выходные данные алгоритма ===&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;Входные данные&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;Матрица из &amp;lt;math&amp;gt;n*d&amp;lt;/math&amp;gt; элементов &amp;lt;math&amp;gt;x_{i, j} \in \mathbb{R}, i=\overline{1, n}, j=\overline{1, d}&amp;lt;/math&amp;gt;&amp;amp;ndash; координат векторов (наблюдений).&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;Целое положительное число &amp;lt;math&amp;gt;k, k \le n&amp;lt;/math&amp;gt; &amp;amp;ndash; количество кластеров.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;Объем входных данных&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;math&amp;gt;1&amp;lt;/math&amp;gt; целое число + &amp;lt;math&amp;gt;n*d&amp;lt;/math&amp;gt; вещественных чисел (при условии, что координаты &amp;amp;ndash; вещественные числа).&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;Выходные данные&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; целых положительных чисел &amp;lt;math&amp;gt;L_1, ..., L_n&amp;lt;/math&amp;gt;&amp;amp;ndash; номера кластеров, соотвествующие каждому вектору (при условии, что нумерация кластеров начинается с &amp;lt;math&amp;gt;1&amp;lt;/math&amp;gt;).&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;Объем выходных данных&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; целых положительных чисел.&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Свойства алгоритма ===&lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;[[глоссарий#Вычислительная мощность|&#039;&#039;Вычислительная мощность&#039;&#039;]]&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
Вычислительная мощность алгоритма &amp;lt;i&amp;gt;k means&amp;lt;/i&amp;gt; равна &amp;lt;math&amp;gt;\frac{k*d*n*\Tau}{n*d} = k*\Tau &amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; &amp;amp;ndash; число кластеров, &amp;lt;math&amp;gt;\Tau&amp;lt;/math&amp;gt; &amp;amp;ndash; число итераций алгоритма.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;[[глоссарий#Детерминированность |&#039;&#039;Детерминированность&#039;&#039;]] и [[глоссарий#Устойчивость |&#039;&#039;Устойчивость&#039;&#039;]] &amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
Алгоритм &amp;lt;i&amp;gt;k means&amp;lt;/i&amp;gt; является итерационным. Количество итераций алгоритма в общем случае не фиксируется и зависит от начального расположения объектов в пространстве, параметра &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt;, а также от начального приближения центров кластеров, &amp;lt;math&amp;gt;\mu_1, ..., \mu_k&amp;lt;/math&amp;gt;. В результате этого может варьироваться результат работы алгоритма. При неудачном выборе начальных параметров итерационный процесс может сойтись к локальному оптимуму&amp;lt;ref&amp;gt;Von Luxburg, Ulrike. Clustering Stability. Now Publishers Inc, 2010.&amp;lt;/ref&amp;gt;. По этим причинам алгоритм не является ни &amp;lt;b&amp;gt;детермирированным&amp;lt;/b&amp;gt;, ни &amp;lt;b&amp;gt;устойчивым&amp;lt;/b&amp;gt;.&lt;br /&gt;
 &lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Соотношение последовательной и параллельной сложности алгоритма&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\frac{\Theta_{k-means}}{\Psi_{k-means}} = \frac{O(\Tau*k*d*n)}{O(\Tau*log(k*d*n))}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Сильные стороны алгоритма&amp;lt;/b&amp;gt;:&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;i&amp;gt;Сравнительно высокая эффективность при простоте реализации&amp;lt;/i&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;i&amp;gt;Высокое качество кластеризации&amp;lt;/i&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;i&amp;gt;Возможность распараллеливания&amp;lt;/i&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;i&amp;gt;Существование множества модификаций&amp;lt;/i&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;Недостатки алгоритма&amp;lt;/b&amp;gt;&amp;lt;ref&amp;gt;Ortega, Joaquín Pérez, Ma Del Rocío Boone Rojas, and María J. Somodevilla. &amp;quot;Research issues on K-means Algorithm: An Experimental Trial Using Matlab.&amp;quot;&amp;lt;/ref&amp;gt;:&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;i&amp;gt;Количество кластеров является параметром алгоритма&amp;lt;/i&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;&amp;lt;i&amp;gt;Чувствительность к начальным условиям&amp;lt;/i&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;Инициализация центров кластеров в значительной степени влияет на результат кластеризации.&amp;lt;/p&amp;gt;&lt;br /&gt;
  &amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;&amp;lt;i&amp;gt;Чувствительность к выбросам и шумам&amp;lt;/i&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;Выбросы, далекие от центров настоящих кластеров, все равно учитываются при вычислении их центров.&amp;lt;/p&amp;gt;&lt;br /&gt;
  &amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;&amp;lt;i&amp;gt;Возможность сходимости к локальному оптимуму&amp;lt;/i&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;Итеративный подход не дает гарантии сходимости к оптимальному решению.&amp;lt;/p&amp;gt;&lt;br /&gt;
  &amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;&amp;lt;i&amp;gt;Использование понятия &amp;quot;среднего&amp;quot;&amp;lt;/i&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;Алгоритм неприменим к данным, для которых не определено понятие &amp;quot;среднего&amp;quot;, например, категориальным данным.&amp;lt;/p&amp;gt;&lt;br /&gt;
  &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&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;
Исследование масштабируемости параллельной реализации алгоритма k means проводилось на суперкомпьютере &amp;quot;Ломоносов&amp;quot;. Алгоритм реализован на языке C с использованием средств MPI.&lt;br /&gt;
Для исследования масштабируемости проводилось множество запусков программы с разным значением параметра (количество векторов для кластеризации), а также с различным числом процессоров. Фиксировались результаты запусков &amp;amp;ndash; время работы &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt; и количество произведенных итераций алгоритма &amp;lt;math&amp;gt;\Tau&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Параметры запусков для экспериментальной оценки:&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;Значения &amp;lt;b&amp;gt;количества векторов&amp;lt;/b&amp;gt; &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;: 20&#039;000, 30&#039;000, 50&#039;000, 100&#039;000, 200&#039;000, 300&#039;000, 500&#039;000, 700&#039;000, 1&#039;000&#039;000, 1&#039;500&#039;000, 2&#039;000&#039;000.&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;Значения &amp;lt;b&amp;gt;количества процессоров&amp;lt;/b&amp;gt; &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt;: 1, 8, 16, 32, 64, 128, 160, 192, 224, 256, 288, 320, 352, 384, 416, 448, 480, 512.&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;Значение &amp;lt;b&amp;gt;количества кластеров&amp;lt;/b&amp;gt; &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt;: 100.&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;Значение &amp;lt;b&amp;gt;размерности векторов&amp;lt;/b&amp;gt; &amp;lt;math&amp;gt;d&amp;lt;/math&amp;gt;: 10.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Графики производительности и эффективности реализации представлены на рисунках 4 и 5 соответственно.&lt;br /&gt;
&lt;br /&gt;
[[file:Flops.png|thumb|center|800px|Рис. 4. График производительности реализации алгоритма.]]&lt;br /&gt;
&lt;br /&gt;
[[file:Efficiency.png|thumb|center|800px|Рис. 5. График эффективности реализации алгоритма.]]&lt;br /&gt;
&lt;br /&gt;
Для заданной конфигурации эксперимента (&amp;lt;math&amp;gt;n, d, p, k&amp;lt;/math&amp;gt;) и полученных результатах (&amp;lt;math&amp;gt;t, \Tau&amp;lt;/math&amp;gt;) производительность и эффективность реализации расчитывались по формулам (см. [[#Последовательная сложность алгоритма| последовательная сложность алгоритма]]):&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
&amp;lt;ul&amp;gt;&amp;lt;li&amp;gt;&amp;lt;math&amp;gt;Performance = \frac{\Theta_{k-means}^{d, n}}{t}\ \ FLOPS&amp;lt;/math&amp;gt;&amp;lt;/li&amp;gt;&amp;lt;/ul&amp;gt;&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
&amp;lt;ul&amp;gt;&amp;lt;li&amp;gt;&amp;lt;math&amp;gt;Efficiency = \frac{100 * Performance}{Performance_{Peak}^{p}}\ \ %,&amp;lt;/math&amp;gt;&amp;lt;/li&amp;gt;&amp;lt;/ul&amp;gt;&lt;br /&gt;
где &amp;lt;math&amp;gt;Performance_{Peak}^{p}&amp;lt;/math&amp;gt; &amp;amp;ndash; пиковая производительность суперкомпьютера при &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt; процессорах, вычисленная согласно спецификациям Intel&amp;amp;reg; XEON&amp;amp;reg; X5670&amp;lt;ref&amp;gt;&amp;quot;http://ark.intel.com/ru/products/47920/Intel-Xeon-Processor-X5670-12M-Cache-2_93-GHz-6_40-GTs-Intel-QPI&amp;quot;&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;В результате&amp;lt;/b&amp;gt; экспериментальной оценки были получены следующие оценки эффективности реализации:&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;b&amp;gt;Минимальное&amp;lt;/b&amp;gt; значение: 0.000409 % достигается при &amp;lt;math&amp;gt;n=20&#039;000, p=480&amp;lt;/math&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;b&amp;gt;Максимальное&amp;lt;/b&amp;gt; значение: 0.741119 % достигается при &amp;lt;math&amp;gt;n=300&#039;000, p=1&amp;lt;/math&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Динамические характеристики и эффективность реализации алгоритма ===&lt;br /&gt;
=== Выводы для классов архитектур ===&lt;br /&gt;
=== Существующие реализации алгоритма ===&lt;br /&gt;
==== Открытое программное обеспечение ====&lt;br /&gt;
&amp;lt;ol&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;[https://www.icpsr.umich.edu/CrimeStat/ CrimeStat]&amp;lt;/li&amp;gt; Программное обеспечение, созданное для операционных систем Windows, предоставляющее инструменты статистического  и пространственного анализа для решения задачи картирования преступности.&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://juliastats.github.io Julia]&amp;lt;/li&amp;gt; Высокоуровневый высокопроизводительный свободный язык программирования с динамической типизацией, созданный для математических вычислений, содержит реализацию k-means.&lt;br /&gt;
  &amp;lt;li&amp;gt;[https://mahout.apache.org Mahout]&amp;lt;/li&amp;gt; Apache Mahout - Java библиотека для работы с алгоритмами машинного обучения с использованием MapReduce. Содержит реализацию k-means.&lt;br /&gt;
  &amp;lt;li&amp;gt;[https://www.gnu.org/software/octave/ Octave]&amp;lt;/li&amp;gt; Написанная на C++  свободная система для математических вычислений, использующая совместимый с MATLAB язык высокого уровня, содержит реализацию k-means.&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://spark.apache.org/docs/latest/mllib-clustering.html Spark]&amp;lt;/li&amp;gt; Распределенная реализация k-means содержится в библиотеке Mlib для работы с алгоритмами машинного обучения, взаимодействующая с Python библиотекой NumPy и библиотека R.&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://torch.ch Torch]&amp;lt;/li&amp;gt;  MATLAB-подобная библиотека для языка программирования Lua с открытым исходным кодом, предоставляет большое количество алгоритмов для глубинного обучения и научных расчётов. Ядро написано на Си, прикладная часть выполняется на LuaJIT, поддерживается распараллеливание вычислений средствами CUDA и OpenMP. Существуют реализации k-means.&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://www.cs.waikato.ac.nz/ml/weka/ Weka]&amp;lt;/li&amp;gt;  Cвободное программное обеспечение для анализа данных, написанное на Java. Содержит k-means и x-means.&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://accord-framework.net/docs/html/T_Accord_MachineLearning_KMeans.htm Accord.NET]&amp;lt;/li&amp;gt; C# реализация алгоритмов k-means, k-means++, k-modes.&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://docs.opencv.org/3.0-beta/doc/py_tutorials/py_ml/py_kmeans/py_kmeans_opencv/py_kmeans_opencv.html OpenCV]&amp;lt;/li&amp;gt; Написанная на С++ библиотека, направленная в основном на решение задач компьютерного зрения. Содержит реализацию k-means.&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://mlpack.org/ MLPACK]&amp;lt;/li&amp;gt; Масштабируемая С++ библиотека для работы с алгоритмами машинного обучения, содержит реализацию k-means.&lt;br /&gt;
  &amp;lt;li&amp;gt;[https://www.scipy.org/ SciPy]&amp;lt;/li&amp;gt; Библиотека Python, содержит множество реализаций k-means.&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://scikit-learn.org/ scikit-learn]&amp;lt;/li&amp;gt; Библиотека Python, содержит множество реализаций k-means.&lt;br /&gt;
  &amp;lt;li&amp;gt;[https://www.r-bloggers.com/k-means-clustering-in-r/ R]&amp;lt;/li&amp;gt; Язык программирования для статистической обработки данных и работы с графикой, а также свободная программная среда вычислений с открытым исходным кодом в рамках проекта GNU, содержит три реализации k-means.&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://elki.dbs.ifi.lmu.de ELKI]&amp;lt;/li&amp;gt; Java фреймворк, содержащий реализацию k-means, а также множество других алгоритмов кластеризации.&lt;br /&gt;
&amp;lt;/ol&amp;gt;&lt;br /&gt;
==== Проприетарное программное обеспечение  ====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ol&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;[https://www.ayasdi.com/blog/bigdata/topological-data-analysis-of-oil-and-gas-petrophysical-data/ Ayasdi]&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://www.stata.com/features/cluster-analysis/ Stata]&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://mathworld.wolfram.com/K-MeansClusteringAlgorithm.html Mathematica]&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://www.mathworks.com/help/stats/kmeans.html?requestedDomain=www.mathworks.com MATLAB]&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;[https://support.sas.com/rnd/app/stat/procedures/fastclus.html SAS]&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://docs.rapidminer.com/studio/operators/modeling/segmentation/k_means.html RapidMiner]&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;[https://blogs.sap.com/2013/03/28/sap-hana-pal-k-means-algorithm-or-how-to-do-customer-segmentation-for-the-telecommunications-industry/ SAP HANA]&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ol&amp;gt;&lt;br /&gt;
== Литература ==&lt;br /&gt;
&amp;lt;references /&amp;gt;&lt;/div&gt;</summary>
		<author><name>DennZo1993</name></author>
	</entry>
	<entry>
		<id>https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:%D0%91%D1%80%D0%BE%D1%82%D0%B8%D0%BA%D0%BE%D0%B2%D1%81%D0%BA%D0%B0%D1%8F_%D0%94%D0%B0%D0%BD%D1%83%D1%82%D0%B0/%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_k-means&amp;diff=17175</id>
		<title>Участник:Бротиковская Данута/Алгоритм k-means</title>
		<link rel="alternate" type="text/html" href="https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:%D0%91%D1%80%D0%BE%D1%82%D0%B8%D0%BA%D0%BE%D0%B2%D1%81%D0%BA%D0%B0%D1%8F_%D0%94%D0%B0%D0%BD%D1%83%D1%82%D0%B0/%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_k-means&amp;diff=17175"/>
		<updated>2016-11-14T23:59:04Z</updated>

		<summary type="html">&lt;p&gt;DennZo1993: /* Масштабируемость реализации алгоритма */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt; {{Assignment|Zhum}}&lt;br /&gt;
&lt;br /&gt;
{{algorithm&lt;br /&gt;
| name              = Алгоритм k средних (k means)&lt;br /&gt;
| serial_complexity = &amp;lt;math&amp;gt;O(\Tau*k*d*n)&amp;lt;/math&amp;gt;&lt;br /&gt;
| input_data        = &amp;lt;math&amp;gt; d*n &amp;lt;/math&amp;gt;&lt;br /&gt;
| output_data       = &amp;lt;math&amp;gt; n &amp;lt;/math&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
Авторы страницы &amp;lt;b&amp;gt;[[Участник:Бротиковская Данута|Данута Бротиковская]]&amp;lt;/b&amp;gt; и &amp;lt;b&amp;gt;[[Участник:DennZo1993|Денис Зобнин]]&amp;lt;/b&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
Оба автора внесли одинаковый вклад в написание статьи (поиск материалов, изучение статей, заполнение контента статьи), четких разграничений по пунктам статьи сделать невозможно. &lt;br /&gt;
&lt;br /&gt;
== Свойства и структура алгоритма ==&lt;br /&gt;
&lt;br /&gt;
=== Общее описание алгоритма ===&lt;br /&gt;
Алгоритм &amp;lt;b&amp;gt;&amp;lt;i&amp;gt;k средних&amp;lt;/i&amp;gt;&amp;lt;/b&amp;gt; (&amp;lt;b&amp;gt;&amp;lt;i&amp;gt;k means&amp;lt;/i&amp;gt;&amp;lt;/b&amp;gt;) &amp;amp;ndash; неиерархический&amp;lt;ref&amp;gt;&amp;quot;https://ru.wikipedia.org/wiki/Иерархическая_кластеризация&amp;quot;&amp;lt;/ref&amp;gt;, итерационный метод кластеризации&amp;lt;ref&amp;gt;&amp;quot;https://ru.wikipedia.org/wiki/Кластерный_анализ&amp;quot;&amp;lt;/ref&amp;gt;, получивший большую популярность благодаря своей простоте, наглядности реализации и достаточно высокому качеству работы. Был изобретен в 1950-х годах математиком &amp;lt;i&amp;gt;Гуго Штейнгаузом&amp;lt;/i&amp;gt;&amp;lt;ref&amp;gt;Steinhaus, Hugo. &amp;quot;Sur la division des corp materiels en parties.&amp;quot; Bull. Acad. Polon. Sci 1.804 (1956): 801.&amp;lt;/ref&amp;gt; и почти одновременно &amp;lt;i&amp;gt;Стюартом Ллойдом&amp;lt;/i&amp;gt;&amp;lt;ref&amp;gt;Lloyd, S. P. &amp;quot;Least square quantization in PCM. Bell Telephone Laboratories Paper. Published in journal much later: Lloyd, SP: Least squares quantization in PCM.&amp;quot; IEEE Trans. Inform. Theor.(1957/1982).&amp;lt;/ref&amp;gt;. Особую популярность приобрел после публикации работы &amp;lt;i&amp;gt;МакКуина&amp;lt;/i&amp;gt;&amp;lt;ref&amp;gt;MacQueen, James. &amp;quot;Some methods for classification and analysis of multivariate observations.&amp;quot; Proceedings of the fifth Berkeley symposium on mathematical statistics and probability. Vol. 1. No. 14. 1967.&amp;lt;/ref&amp;gt; в 1967.&lt;br /&gt;
&lt;br /&gt;
Алгоритм представляет собой версию EM-алгоритма&amp;lt;ref&amp;gt;&amp;quot;https://ru.wikipedia.org/wiki/EM-алгоритм&amp;quot;&amp;lt;/ref&amp;gt;, применяемого также для разделения смеси гауссиан. Основная идея &amp;lt;i&amp;gt;k means&amp;lt;/i&amp;gt; заключается в том, что данные произвольно разбиваются на кластеры, после чего итеративно перевычисляется центр масс для каждого кластера, полученного на предыдущем шаге, затем векторы разбиваются на кластеры вновь в соответствии с тем, какой из новых центров оказался ближе по выбранной метрике.&lt;br /&gt;
&lt;br /&gt;
Цель алгоритма заключается в разделении &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; наблюдений на &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластеров таким образом, чтобы каждое наблюдение принадлежало ровно одному кластеру, расположенному на наименьшем расстоянии от наблюдения.&lt;br /&gt;
&lt;br /&gt;
=== Математическое описание алгоритма ===&lt;br /&gt;
&amp;lt;b&amp;gt;&amp;lt;u&amp;gt;Дано:&amp;lt;/u&amp;gt;&amp;lt;/b&amp;gt;&lt;br /&gt;
* набор из &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; наблюдений &amp;lt;math&amp;gt;X=\{\mathbf{x}_1, \mathbf{x}_2, ..., \mathbf{x}_n\}, \mathbf{x}_i \in \mathbb{R}^d, i=\overline{1, n}&amp;lt;/math&amp;gt;;&lt;br /&gt;
* &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; - требуемое число кластеров, &amp;lt;math&amp;gt;k \in \mathbb{N}, k \leq n&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;&amp;lt;u&amp;gt;Требуется:&amp;lt;/u&amp;gt;&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Разделить множество наблюдений &amp;lt;math&amp;gt;X&amp;lt;/math&amp;gt; на &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластеров &amp;lt;math&amp;gt;S_1, S_2, ..., S_k&amp;lt;/math&amp;gt;:&lt;br /&gt;
*   &amp;lt;math&amp;gt;S_i \cap S_j= \varnothing, \quad i \ne j&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
*   &amp;lt;math&amp;gt;\bigcup_{i=1}^{k} S_i = X&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;&amp;lt;u&amp;gt;Действие алгоритма:&amp;lt;/u&amp;gt;&amp;lt;/b&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;Алгоритм &amp;lt;i&amp;gt;k means&amp;lt;/i&amp;gt; разбивает набор &amp;lt;math&amp;gt;X&amp;lt;/math&amp;gt; на &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; наборов &amp;lt;math&amp;gt;S_1, S_2, ..., S_k,&amp;lt;/math&amp;gt; таким образом, чтобы минимизировать сумму квадратов расстояний от каждой точки кластера до его центра (центр масс кластера). Введем обозначение, &amp;lt;math&amp;gt;S=\{S_1, S_2, ..., S_k\}&amp;lt;/math&amp;gt;. Тогда действие алгоритма &amp;lt;i&amp;gt;k means&amp;lt;/i&amp;gt; равносильно поиску:&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;table style=&amp;quot;width:100%&amp;quot;&amp;gt;&lt;br /&gt;
  &amp;lt;tr&amp;gt;&lt;br /&gt;
    &amp;lt;td align=&amp;quot;center&amp;quot; width=&amp;quot;90%&amp;quot;&amp;gt;&amp;lt;math&amp;gt;\arg\min_{S} \sum\limits_{i=1}^k \sum\limits_{\mathbf{x} \in S_i} \rho(\mathbf{x}, \mathbf{\mu}_i )^2,&amp;lt;/math&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;td align=&amp;quot;right&amp;quot;&amp;gt;&amp;lt;math&amp;gt;(1)&amp;lt;/math&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;/table&amp;gt;&lt;br /&gt;
где &amp;lt;math&amp;gt;\mathbf{\mu}_i&amp;lt;/math&amp;gt; &amp;amp;ndash; центры кластеров, &amp;lt;math&amp;gt;i=\overline{1,k}, \quad \rho(\mathbf{x}, \mathbf{\mu}_i)&amp;lt;/math&amp;gt; &amp;amp;ndash; функция расстояния между &amp;lt;math&amp;gt;\mathbf{x}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\mu_i&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;&amp;lt;u&amp;gt;Шаги алгоритма: &amp;lt;/u&amp;gt;&amp;lt;/b&amp;gt;&lt;br /&gt;
&amp;lt;ol&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&lt;br /&gt;
    &amp;lt;b&amp;gt;Начальный шаг: инициализация кластеров&amp;lt;/b&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;Выбирается произвольное множество точек &amp;lt;math&amp;gt;\mu_i, i=\overline{1,k}&amp;lt;/math&amp;gt;, рассматриваемых как начальные центры кластеров: &amp;lt;math&amp;gt;\mu_i^{(0)} = \mu_i, \quad i=\overline{1, k}&amp;lt;/math&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
  &amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&lt;br /&gt;
    &amp;lt;b&amp;gt;Распределение векторов по кластерам&amp;lt;/b&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Шаг&amp;lt;/b&amp;gt; &amp;lt;math&amp;gt;t: \forall \mathbf{x}_i \in X, i=\overline{1,n}: \mathbf{x}_i \in S_j \iff  j=\arg\min_{k}\rho(\mathbf{x}_i,\mathbf{\mu}_k^{(t-1)})^2&amp;lt;/math&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
  &amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&lt;br /&gt;
    &amp;lt;b&amp;gt;Пересчет центров кластеров&amp;lt;/b&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Шаг &amp;lt;/b&amp;gt; &amp;lt;math&amp;gt;t: \forall i=\overline{1,k}:  \mu_i^{(t)} = \cfrac{1}{|S_i|}\sum_{\mathbf{x}\in S_i}\mathbf{x}&amp;lt;/math&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
  &amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&lt;br /&gt;
    &amp;lt;b&amp;gt;Проверка условия останова:&amp;lt;/b&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
    &#039;&#039;&#039;if&#039;&#039;&#039; &amp;lt;math&amp;gt;\exist i\in \overline{1,k}: \mu_i^{(t)} \ne \mu_i^{(t-1)}&amp;lt;/math&amp;gt; &#039;&#039;&#039;then&#039;&#039;&#039;&lt;br /&gt;
        t = t + 1;&lt;br /&gt;
        goto 2;&lt;br /&gt;
    &#039;&#039;&#039;else&#039;&#039;&#039;&lt;br /&gt;
        &#039;&#039;&#039;stop&#039;&#039;&#039;&lt;br /&gt;
  &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ol&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Вычислительное ядро алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Вычислительным ядром являются шаги 2 и 3 приведенного выше алгоритма: &amp;lt;b&amp;gt;&amp;lt;i&amp;gt;распределение векторов по кластерам&amp;lt;/i&amp;gt;&amp;lt;/b&amp;gt; и &amp;lt;b&amp;gt;&amp;lt;i&amp;gt;пересчет центров кластеров&amp;lt;/i&amp;gt;&amp;lt;/b&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;&amp;lt;i&amp;gt;Распределение векторов&amp;lt;/i&amp;gt;&amp;lt;/b&amp;gt; по кластерам предполагает вычисление расстояний между каждым вектором &amp;lt;math&amp;gt;\mathbf{x}_i \in X, i= \overline{1,n}&amp;lt;/math&amp;gt; и центрами кластера &amp;lt;math&amp;gt;\mathbf{\mu}_j, j= \overline{1,k}&amp;lt;/math&amp;gt;. Таким образом, данный шаг предполагает &amp;lt;math&amp;gt;k*n&amp;lt;/math&amp;gt; вычислений расстояний между d-мерными векторами. &lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;&amp;lt;i&amp;gt;Пересчет центров кластеров&amp;lt;/i&amp;gt;&amp;lt;/b&amp;gt; предполагает &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; вычислений центров масс &amp;lt;math&amp;gt;\mathbf{\mu}_i&amp;lt;/math&amp;gt; множеств &amp;lt;math&amp;gt;S_i, i=\overline{1,k}&amp;lt;/math&amp;gt; представленных выражением в шаге 3 представленного выше алгоритма.&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Макроструктура алгоритма ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Инициализация центров масс &amp;lt;math&amp;gt;\mu_1, ..., \mu_k&amp;lt;/math&amp;gt;&amp;lt;/b&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
Наиболее распространенными являются следующие стратегии:&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&lt;br /&gt;
    &amp;lt;b&amp;gt;Метод Forgy&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;В качестве начальных значений &amp;lt;math&amp;gt;\mu_1, ..., \mu_k&amp;lt;/math&amp;gt; берутся случайно выбранные векторы.&lt;br /&gt;
  &amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&lt;br /&gt;
    &amp;lt;b&amp;gt;Метод случайно разделения (Random Partitioning)&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;Для каждого вектора &amp;lt;math&amp;gt;\mathbf{x}_i \in X, i=\overline{1, n}&amp;lt;/math&amp;gt; выбирается случайным образом кластер &amp;lt;math&amp;gt;S_1, ..., S_k&amp;lt;/math&amp;gt;, после чего для каждого полученного кластера вычисляются значения &amp;lt;math&amp;gt;\mu_1, ..., \mu_k&amp;lt;/math&amp;gt;.&lt;br /&gt;
  &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Распределение векторов по кластерам&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Для этого шага алгоритма между векторами &amp;lt;math&amp;gt;\mathbf{x}_i \in X, i=\overline{1, n}&amp;lt;/math&amp;gt; и центрами кластеров &amp;lt;math&amp;gt;\mu_1, ..., \mu_k&amp;lt;/math&amp;gt; вычисляются &amp;lt;b&amp;gt;расстояния&amp;lt;/b&amp;gt; по формуле (как правило, используется Евлидово расстояние):&lt;br /&gt;
&amp;lt;table style=&amp;quot;width:100%&amp;quot;&amp;gt;&lt;br /&gt;
  &amp;lt;tr&amp;gt;&lt;br /&gt;
    &amp;lt;td align=&amp;quot;center&amp;quot; width=&amp;quot;90%&amp;quot;&amp;gt;&amp;lt;math&amp;gt; \mathbf{v}_1, \mathbf{v}_2 \in \mathbb{R}^d,  \quad \rho(\mathbf{v}_1, \mathbf{v}_2) = \lVert \mathbf{v}_1- \mathbf{v}_2 \rVert= \sqrt{\sum_{i=1}^{d}(\mathbf{v}_{1,i} - \mathbf{v}_{2,i})^2}&amp;lt;/math&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;td align=&amp;quot;right&amp;quot;&amp;gt;&amp;lt;math&amp;gt;(2)&amp;lt;/math&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;/table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Пересчет центров кластеров&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Для этого шага алгоритма производится пересчет центров кластера по &amp;lt;b&amp;gt;формуле вычисления центра масс&amp;lt;/b&amp;gt;:&lt;br /&gt;
&amp;lt;table style=&amp;quot;width:100%&amp;quot;&amp;gt;&lt;br /&gt;
  &amp;lt;tr&amp;gt;&lt;br /&gt;
    &amp;lt;td align=&amp;quot;center&amp;quot; width=&amp;quot;90%&amp;quot;&amp;gt;&amp;lt;math&amp;gt; \mu = \cfrac{1}{|S|}\sum_{\mathbf{x}\in S}\mathbf{x}&amp;lt;/math&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;td align=&amp;quot;right&amp;quot;&amp;gt;&amp;lt;math&amp;gt;(3)&amp;lt;/math&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;/table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Схема реализации последовательного алгоритма ===&lt;br /&gt;
&lt;br /&gt;
 &#039;&#039;&#039;algorithm&#039;&#039;&#039; k-means &#039;&#039;&#039;is&#039;&#039;&#039;&lt;br /&gt;
     &#039;&#039;&#039;1.&#039;&#039;&#039; Инициализировать центры кластеров &amp;lt;math&amp;gt;\mathbf{\mu}_i^{(1)}, i=\overline{1,k}&amp;lt;/math&amp;gt;&lt;br /&gt;
     &#039;&#039;&#039;2.&#039;&#039;&#039; &amp;lt;math&amp;gt;t \leftarrow 1&amp;lt;/math&amp;gt;&lt;br /&gt;
     &#039;&#039;&#039;3.&#039;&#039;&#039; &#039;&#039;&#039;Распределение по кластерам&#039;&#039;&#039;&amp;lt;br&amp;gt;&lt;br /&gt;
        &amp;lt;math&amp;gt;S_i^{(t)}=\{\mathbf{x}_p: \lVert\mathbf{x}_p-\mathbf{\mu}_i^{(t)}\rVert^2 \leq \lVert\mathbf{x}_p-\mathbf{\mu}_j^{(t)}\rVert^2 \quad \forall j=\overline{1,k}\},&amp;lt;/math&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
        где каждый вектор &amp;lt;math&amp;gt;\mathbf{x}_p&amp;lt;/math&amp;gt; соотносится единственному кластеру &amp;lt;math&amp;gt;S^{(t)}&amp;lt;/math&amp;gt;&lt;br /&gt;
     &#039;&#039;&#039;4.&#039;&#039;&#039; &#039;&#039;&#039;Обновление центров кластеров&#039;&#039;&#039;&amp;lt;br&amp;gt;&lt;br /&gt;
        &amp;lt;math&amp;gt;\mathbf{\mu}_i^{(t+1)} = \frac{1}{|S^{(t)}_i|} \sum_{\mathbf{x}_j \in S^{(t)}_i} \mathbf{x}_j &amp;lt;/math&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
     &#039;&#039;&#039;5.&#039;&#039;&#039; &#039;&#039;&#039;if&#039;&#039;&#039; &amp;lt;math&amp;gt;\exist i \in \overline{1,k}: \mathbf{\mu}_i^{(t+1)} \ne \mathbf{\mu}_i^{(t)}&amp;lt;/math&amp;gt; &#039;&#039;&#039;then&#039;&#039;&#039;&lt;br /&gt;
            t = t + 1;&lt;br /&gt;
            goto &#039;&#039;&#039;3&#039;&#039;&#039;;&lt;br /&gt;
        &#039;&#039;&#039;else&#039;&#039;&#039;&lt;br /&gt;
            &#039;&#039;&#039;stop&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
=== Последовательная сложность алгоритма===&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding-bottom: 20px&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;Обозначим &amp;lt;math&amp;gt;\Theta_{centroid}^{d, m}&amp;lt;/math&amp;gt; временную сложность вычисления центорида кластера, число элементов которого равна &amp;lt;math&amp;gt;m&amp;lt;/math&amp;gt;,  в d-мерном пространстве.&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;Аналогично  &amp;lt;math&amp;gt;\Theta_{distance}^d&amp;lt;/math&amp;gt; &amp;amp;ndash; временная сложность вычисления расстояния между двумя d-мерными векторами.&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding-bottom: 20px&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;Сложность шага инициализации &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластеров мощности &amp;lt;math&amp;gt;m&amp;lt;/math&amp;gt; в d-мерном пространстве &amp;amp;ndash; &amp;lt;math&amp;gt;\Theta_{init}^{k, d, m}&amp;lt;/math&amp;gt;&amp;lt;/b&amp;gt;&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;i&amp;gt;Стратерия Forgy&amp;lt;/i&amp;gt;: вычисления не требуются, &amp;lt;math&amp;gt;\Theta_{init}^{k, d, m} = 0&amp;lt;/math&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;i&amp;gt;Стратегия случайного разбиения&amp;lt;/i&amp;gt;: вычисление центров &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластеров,  &amp;lt;math&amp;gt;\Theta_{init}^{k, d, m} = k*\Theta_{centroid}^{d, m}, m \le n&amp;lt;/math&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding-bottom: 20px&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Cложность шага распределения d мерных векторов по &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластерам &amp;amp;ndash; &amp;lt;math&amp;gt;\Theta_{distribute}^{k, d}&amp;lt;/math&amp;gt;&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
На этом шаге для каждого вектора &amp;lt;math&amp;gt;\mathbf{x}_i \in X, i=\overline{1, n}&amp;lt;/math&amp;gt; вычисляется k расстояний до центров кластеров &amp;lt;math&amp;gt;\mathbf{\mu}_1, ...\mathbf{\mu}_k&amp;lt;/math&amp;gt;&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p align=&amp;quot;center&amp;quot;&amp;gt;&lt;br /&gt;
  &amp;lt;math&amp;gt;\Theta_{distribute}^{k, d} = n*k*\Theta_{distance}^d&amp;lt;/math&amp;gt;&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding-bottom: 20px&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;Сложность шага пересчета центров &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластеров размера &amp;lt;math&amp;gt;m&amp;lt;/math&amp;gt; в d-мерном пространстве &amp;amp;ndash; &amp;lt;math&amp;gt;\Theta_{recenter}^{k, d, m}&amp;lt;/math&amp;gt;&amp;lt;/b&amp;gt;&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;На этом шаге вычисляется &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; центров кластеров &amp;lt;math&amp;gt;\mathbf{\mu}_1, ...\mathbf{\mu}_k&amp;lt;/math&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p align=&amp;quot;center&amp;quot;&amp;gt;&amp;lt;math&amp;gt;\Theta_{recenter}^{k, d, m} = k*\Theta_{centroid}^{d, m}&amp;lt;/math&amp;gt; &amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding-bottom: 20px&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Рассчитаем &amp;lt;math&amp;gt;\Theta_{centroid}^{d, m}&amp;lt;/math&amp;gt; для кластера, число элементов которого равно &amp;lt;math&amp;gt;m&amp;lt;/math&amp;gt;&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p align=&amp;quot;center&amp;quot;&amp;gt;&amp;lt;math&amp;gt;\Theta_{centroid}^{d, m}&amp;lt;/math&amp;gt; = &amp;lt;math&amp;gt;m * d&amp;lt;/math&amp;gt; сложений + &amp;lt;math&amp;gt;d&amp;lt;/math&amp;gt; делений &amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding-bottom: 20px&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Рассчитаем &amp;lt;math&amp;gt;\Theta_{distance}^d&amp;lt;/math&amp;gt; в соответствие с формулой &amp;lt;math&amp;gt;(2)&amp;lt;/math&amp;gt;&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p align=&amp;quot;center&amp;quot;&amp;gt;&amp;lt;math&amp;gt;\Theta_{distance}^d&amp;lt;/math&amp;gt; = &amp;lt;math&amp;gt;d&amp;lt;/math&amp;gt; вычитаний + &amp;lt;math&amp;gt;d&amp;lt;/math&amp;gt; умножений + &amp;lt;math&amp;gt;(d-1)&amp;lt;/math&amp;gt; сложение&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding-bottom: 20px&amp;quot;&amp;gt;&lt;br /&gt;
  &amp;lt;p&amp;gt;Предположим, что алгоритм сошелся за &amp;lt;math&amp;gt;\Tau&amp;lt;/math&amp;gt; итераций, тогда временная сложность алгоритма &amp;lt;math&amp;gt;\Theta_{k-means}^{d, n}&amp;lt;/math&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
  &amp;lt;p align=&amp;quot;center&amp;quot;&amp;gt;&amp;lt;b&amp;gt;&amp;lt;math&amp;gt;\Theta_{k-means}^{d, n} \le \Theta_{init}^{k, d, n} + \Tau*(\Theta_{distribute}^{k, d} + \Theta_{recenter}^{k, d, n})&amp;lt;/math&amp;gt;&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding-bottom: 5px&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;Операции сложения/вычитания:&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p align=&amp;quot;center&amp;quot;&amp;gt;&amp;lt;b&amp;gt;&amp;lt;math&amp;gt;\Theta_{k-means}^{d, n} \le k*n*d+ \Tau*(k*n*(2d-1) + k*n*d) = k*n*d+ \Tau*(k*n*(3d-1)) \thicksim O(\Tau*k*d*n)&amp;lt;/math&amp;gt;&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding-bottom: 20px&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;Операции умножения/деления:&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p align=&amp;quot;center&amp;quot;&amp;gt;&amp;lt;b&amp;gt;&amp;lt;math&amp;gt;\Theta_{k-means}^{d, n} \le k*d + \Tau*(k*n*d + k*d) = k*d + \Tau * k*d*(n+1) \thicksim O(\Tau*k*d*n) &amp;lt;/math&amp;gt;&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding-bottom: 20px&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;Получаем, что &amp;lt;b&amp;gt;временная сложность&amp;lt;/b&amp;gt; алгоритма &amp;lt;b&amp;gt;k means&amp;lt;/b&amp;gt; кластеризации &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; &amp;lt;b&amp;gt;d-мерных&amp;lt;/b&amp;gt; векторов на &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластеров за &amp;lt;math&amp;gt;\Tau&amp;lt;/math&amp;gt; итераций:&amp;lt;/p&amp;gt;&lt;br /&gt;
 &amp;lt;p align=&amp;quot;center&amp;quot;&amp;gt;&amp;lt;b&amp;gt;&amp;lt;math&amp;gt; \Theta_{k-means}^{d, n} \thicksim O(\Tau*k*d*n) &amp;lt;/math&amp;gt;&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Информационный граф ===&lt;br /&gt;
&lt;br /&gt;
Рассмотрим информационный граф алгоритма. Алгоритм &amp;lt;i&amp;gt;k means&amp;lt;/i&amp;gt; начинается с этапа инициализации, после которого следуют итерации, на каждой из которых выполняется два последовательных шага (см. [[#Схема реализации последовательного алгоритма|&amp;quot;Схема реализации последовательного алгоритма&amp;quot;]]): &lt;br /&gt;
* распределение векторов по кластерам&lt;br /&gt;
* перерасчет центров кластеров&lt;br /&gt;
&lt;br /&gt;
Поскольку основная часть вычислений приходится на шаги итераций, распишем информационные графы данных шагов.&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Распределение векторов по кластерам&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
Информационный граф шага распределения векторов по кластерам представлен на &#039;&#039;рисунке 1&#039;&#039;. Исходами данного графа является исходные векторы &amp;lt;math&amp;gt;\mathbf{x}_1, ..., \mathbf{x}_n&amp;lt;/math&amp;gt;, а также центры кластеров &amp;lt;math&amp;gt;\mathbf{\mu}_1, ... \mathbf{\mu}_k&amp;lt;/math&amp;gt;, вычисленные ранее (на шаге инициализации, если рассматривается первая итерация алгоритма, или на шаге пересчета центров кластеров предыдущей итерации в противном случае). Каждая пара векторов данных &amp;lt;math&amp;gt;\mathbf{x}_i, i=\overline{1,n}&amp;lt;/math&amp;gt; и центров кластера &amp;lt;math&amp;gt;\mathbf{\mu}_j, j=\overline{1, k}&amp;lt;/math&amp;gt; : (&amp;lt;math&amp;gt;\mathbf{x}_i&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;\mathbf{\mu}_j&amp;lt;/math&amp;gt;) подаются на независимые узлы &amp;lt;i&amp;gt;&amp;quot;d&amp;quot;&amp;lt;/i&amp;gt; вычисления расстояния между векторами (более подробная схема вычисления расстояния представлена далее, &#039;&#039;рисунок 2&#039;&#039;). Далее узлы вычисления расстояния &amp;lt;i&amp;gt;&amp;quot;d&amp;quot;&amp;lt;/i&amp;gt;, соответствующие одному и тому же исходному вектору &amp;lt;math&amp;gt;\mathbf{x}_i&amp;lt;/math&amp;gt; передаются на один узел &amp;lt;i&amp;gt;&amp;quot;m&amp;quot;&amp;lt;/i&amp;gt;, где далее происходит вычисление новой метки кластера для каждого вектора &amp;lt;math&amp;gt;\mathbf{x}_i&amp;lt;/math&amp;gt; (берется кластер с минимальным результатом вычисления расстояния). На выходе графа выдаются метки кластеров , &amp;lt;math&amp;gt;L_1, ..., L_n&amp;lt;/math&amp;gt;, такие что &amp;lt;math&amp;gt;\forall \mathbf{x}_i, i=\overline{1, n}, \mathbf{x}_i \in S_j \Leftrightarrow L_i = j&amp;lt;/math&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
[[file:Clusterization.png|thumb|center|800px|Рис. 1. Схема распределения векторов по кластерам. &#039;&#039;d&#039;&#039; &amp;amp;ndash; вычисление расстояния между векторами; &#039;&#039;m&#039;&#039; &amp;amp;ndash; вычисление минимума.]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Вычисление расстояния между векторами&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
Подробная схема вычисления расстояния между векторами &amp;lt;math&amp;gt;\mathbf{x}_i, \mathbf{\mu}_j&amp;lt;/math&amp;gt; представлена на &#039;&#039;рисунке 2&#039;&#039;. Как показано на графе, узел вычисления расстояния между векторами &amp;lt;i&amp;gt;&amp;quot;d&amp;quot;&amp;lt;/i&amp;gt; состоит из шага взятия разности между векторами (узел &amp;quot;&amp;lt;math&amp;gt;-&amp;lt;/math&amp;gt;&amp;quot;) и взятия нормы получившегося вектора разности (узел &amp;quot;&amp;lt;math&amp;gt;||\cdot||^2&amp;lt;/math&amp;gt;&amp;quot;). Более подробно, вычисление расстояния между векторами &amp;lt;math&amp;gt;\mathbf{x}_i = {x_{i1,}, ...,{x_{in}}}, \mathbf{\mu}_j = {\mu_{j1}, ...,\mu_{jn}}&amp;lt;/math&amp;gt; может быть представлено как вычисление разности между каждой парой компонент &amp;lt;math&amp;gt;(x_{iz}, \mu_{jz}), z=\overline{1, d}&amp;lt;/math&amp;gt; (узел &amp;quot;&amp;lt;math&amp;gt;-&amp;lt;/math&amp;gt;&amp;quot;), далее возведение в квадрат для каждого узла &amp;quot;&amp;lt;math&amp;gt;-&amp;lt;/math&amp;gt;&amp;quot; (узел &amp;quot;&amp;lt;math&amp;gt;()^2&amp;lt;/math&amp;gt;&amp;quot;) и суммирования выходов всех узлов &amp;quot;&amp;lt;math&amp;gt;()^2&amp;lt;/math&amp;gt;&amp;quot; (узел &amp;quot;&amp;lt;math&amp;gt;+&amp;lt;/math&amp;gt;&amp;quot;).  &lt;br /&gt;
&lt;br /&gt;
[[file:dist_calc.png|thumb|center|800px|Рис. 2. Схема вычисления расстояния между вектором и центром кластера.]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Пересчет центров кластеров&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
Информационный граф шага пересчета центров кластеров представлен на &#039;&#039;рисунке 3&#039;&#039;. Исходами данного графа является исходные векторы &amp;lt;math&amp;gt;\mathbf{x}_1, ..., \mathbf{x}_n&amp;lt;/math&amp;gt;, а также им соответствующие метки кластера, &amp;lt;math&amp;gt;L_1, ..., L_n&amp;lt;/math&amp;gt;, такие что &amp;lt;math&amp;gt;\forall x_i, i=\overline{1, n}, \mathbf{x}_i \in S_j \Leftrightarrow L_i = j&amp;lt;/math&amp;gt;, вычисленные на этапе распределения векторов по кластерам. Все векторы &amp;lt;math&amp;gt;\mathbf{x}_1, ..., \mathbf{x}_n&amp;lt;/math&amp;gt; подаются в узлы &amp;lt;math&amp;gt;+_1, ...+_k&amp;lt;/math&amp;gt;, каждый узел &amp;lt;math&amp;gt;+_m, m = \overline{1,k}&amp;lt;/math&amp;gt; соответствует операции сложения векторов кластера с номером &amp;lt;math&amp;gt;m&amp;lt;/math&amp;gt;. Метки кластера &amp;lt;math&amp;gt;L_1, ..., L_n&amp;lt;/math&amp;gt; также совместно передаются на узлы &amp;lt;math&amp;gt;S_m, m = \overline{1,k}&amp;lt;/math&amp;gt;, на каждом из которых вычисляется количество векторов в соответствующем кластере (количество меток с соответствующим значением). Далее каждая пара выходов узлов &amp;lt;math&amp;gt;+_m&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;S_m&amp;lt;/math&amp;gt; подается на узел &amp;quot;&amp;lt;math&amp;gt;/&amp;lt;/math&amp;gt;&amp;quot;, где производится деление суммы векторов кластера на количество элементов в нем. Значения, вычисленные на узлах &amp;quot;&amp;lt;math&amp;gt;/&amp;lt;/math&amp;gt;&amp;quot;, присваиваются новым центрам кластеров (выходные значения графа).&lt;br /&gt;
&lt;br /&gt;
[[file:Recluster.png|thumb|center|800px|Рис. 3. Схема пересчета центров кластеров]]&lt;br /&gt;
&lt;br /&gt;
=== Ресурс параллелизма алгоритма ===&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
Работа алгоритма состоит из &amp;lt;math&amp;gt;\Tau&amp;lt;/math&amp;gt; итераций, в каждой из которых происходит &amp;lt;b&amp;gt;распределение d-мерных векторов по &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластерам&amp;lt;/b&amp;gt;, а также &amp;lt;b&amp;gt;пересчет центров кластеров в d-мерном пространстве&amp;lt;/b&amp;gt;. В шаге &amp;lt;b&amp;gt;распределения d-мерных векторов по &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластерам&amp;lt;/b&amp;gt; расстояния между вектором и центрами кластеров вычисляются независимо (отсутствуют информационные зависимости). &amp;lt;b&amp;gt;Центры масс кластеров&amp;lt;/b&amp;gt; также пересчитываются независимо друг от друга. Таким образом, имеет место [[глоссарий#Массовый параллелизм|&#039;&#039;массовый параллелизм&#039;&#039;]]. Вычислим параллельную сложность &amp;lt;math&amp;gt;\Psi_*&amp;lt;/math&amp;gt; каждого из шагов, а также параллельную сложность всего алгоритма, &amp;lt;math&amp;gt;\Psi_{k-means}&amp;lt;/math&amp;gt;. Будем исходить из предположения, что может быть использовано любое необходимое число потоков.&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Распределение d-мерных векторов по &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластерам&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;  &lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
Поскольку на данном шаге для каждой пары векторов &amp;lt;math&amp;gt;\mathbf{x}_i, i=\overline{1,n}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\mathbf{\mu}_j, j=\overline{1,k}&amp;lt;/math&amp;gt; операции вычисления расстояния не зависят друг от друга, они могут выполняться параллельно. Тогда, разделив все вычисление расстояний на &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; потоков, получим, что в каждом потоке будет выполняться только одна операция вычисления расстояния между векторами размерности d. При этом каждому вычислительному потоку передаются координаты центров всех кластеров &amp;lt;math&amp;gt;\mathbf{\mu}_1, ..., \mathbf{\mu}_k&amp;lt;/math&amp;gt;. Таким образом, параллельная сложность данного шага определяется &amp;lt;i&amp;gt; сложностью параллельной операции вычисления расстояния между d-мерными векторами&amp;lt;/i&amp;gt;, &amp;lt;math&amp;gt;\Psi_{distance}^d&amp;lt;/math&amp;gt;  и &amp;lt;i&amp;gt;сложностью определения наиболее близкого кластера&amp;lt;/i&amp;gt; (паралельное взятие минимума по расстояниям), &amp;lt;math&amp;gt;\Psi_{min}^k&amp;lt;/math&amp;gt;. Для оценки &amp;lt;math&amp;gt;\Psi_{distance}^d&amp;lt;/math&amp;gt; воспользуемся  [[Нахождение_частных_сумм_элементов_массива_сдваиванием | параллельной реализацией нахождения частичной суммы элементов массива путем сдваивания]]. Аналогично, &amp;lt;math&amp;gt;\Psi_{min}^k = log(k)&amp;lt;/math&amp;gt;. В результате, &amp;lt;math&amp;gt;\Psi_{distance}^d = O(log(d))&amp;lt;/math&amp;gt;.   Таким образом: &lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p align=&amp;quot;center&amp;quot;&amp;gt;&amp;lt;math&amp;gt;\Psi_{distribute}^{k, d}  = \Psi_{distance}^d + \Psi_{min}^k = O(log(d))+O(log(k)) = O(log(k*d))&amp;lt;/math&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Пересчет центров кластеров в d-мерном пространстве&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
Поскольку на данном шаге для каждого из &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластеров центр масс может быть вычислен независимо, данные операции могут быть выполнены в отдельных потоках. Таким образом, параллельная сложность данного шага, &amp;lt;math&amp;gt;\Psi_{recenter}^{k, d}&amp;lt;/math&amp;gt;,  будет определяться &amp;lt;i&amp;gt;параллельной сложностью вычисления одного центра масс кластера размера &amp;lt;math&amp;gt;m&amp;lt;/math&amp;gt;&amp;lt;/i&amp;gt;, &amp;lt;math&amp;gt;\Psi_{recenter}^{k, d}&amp;lt;/math&amp;gt;,  а так как &amp;lt;math&amp;gt;m \le n \Rightarrow \Psi_{recenter}^{d, m} \le \Psi_{recenter}^{d, n}&amp;lt;/math&amp;gt;. Сложность вычисления центра масс кластера d-мерных векторов размера n аналогично предыдущим вычислениям равна &amp;lt;math&amp;gt;O(log(n))&amp;lt;/math&amp;gt;. Тогда:  &lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p align=&amp;quot;center&amp;quot;&amp;gt;&amp;lt;math&amp;gt;\Psi_{recenter}^{k, d}  \le \Psi_{recenter}^{d, n} = O(log(n))&amp;lt;/math&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Общая параллельная сложность алгоритма&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
На каждой итерации необходимо обновление центров кластеров, которые будут использованы на следующей итерации. Таким образом, итерационный процесс выполняется последовательно&amp;lt;ref&amp;gt;Zhao, Weizhong, Huifang Ma, and Qing He. &amp;quot;Parallel k-means clustering based on mapreduce.&amp;quot; IEEE International Conference on Cloud Computing. Springer Berlin Heidelberg, 2009.&amp;lt;/ref&amp;gt;. Тогда, поскольку сложность каждой итерации  определяется &amp;lt;math&amp;gt;\Psi_{distribute}^{k, d}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\Psi_{recenter}&amp;lt;/math&amp;gt;, сложность всего алгоритма, &amp;lt;math&amp;gt;\Psi_{k-means}&amp;lt;/math&amp;gt; в предположении, что было сделано &amp;lt;math&amp;gt;\Tau&amp;lt;/math&amp;gt; операций определяется выражением&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p align=&amp;quot;center&amp;quot;&amp;gt;&amp;lt;math&amp;gt;\Psi_{k-means} \approx \Tau * (\Psi_{distribute}^{k, d} + \Psi_{recenter}^{k, d}) \le \Tau * O(log(k*d*n))&amp;lt;/math&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Входные и выходные данные алгоритма ===&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;Входные данные&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;Матрица из &amp;lt;math&amp;gt;n*d&amp;lt;/math&amp;gt; элементов &amp;lt;math&amp;gt;x_{i, j} \in \mathbb{R}, i=\overline{1, n}, j=\overline{1, d}&amp;lt;/math&amp;gt;&amp;amp;ndash; координат векторов (наблюдений).&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;Целое положительное число &amp;lt;math&amp;gt;k, k \le n&amp;lt;/math&amp;gt; &amp;amp;ndash; количество кластеров.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;Объем входных данных&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;math&amp;gt;1&amp;lt;/math&amp;gt; целое число + &amp;lt;math&amp;gt;n*d&amp;lt;/math&amp;gt; вещественных чисел (при условии, что координаты &amp;amp;ndash; вещественные числа).&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;Выходные данные&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; целых положительных чисел &amp;lt;math&amp;gt;L_1, ..., L_n&amp;lt;/math&amp;gt;&amp;amp;ndash; номера кластеров, соотвествующие каждому вектору (при условии, что нумерация кластеров начинается с &amp;lt;math&amp;gt;1&amp;lt;/math&amp;gt;).&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;Объем выходных данных&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; целых положительных чисел.&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Свойства алгоритма ===&lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;[[глоссарий#Вычислительная мощность|&#039;&#039;Вычислительная мощность&#039;&#039;]]&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
Вычислительная мощность алгоритма &amp;lt;i&amp;gt;k means&amp;lt;/i&amp;gt; равна &amp;lt;math&amp;gt;\frac{k*d*n*\Tau}{n*d} = k*\Tau &amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; &amp;amp;ndash; число кластеров, &amp;lt;math&amp;gt;\Tau&amp;lt;/math&amp;gt; &amp;amp;ndash; число итераций алгоритма.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;[[глоссарий#Детерминированность |&#039;&#039;Детерминированность&#039;&#039;]] и [[глоссарий#Устойчивость |&#039;&#039;Устойчивость&#039;&#039;]] &amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
Алгоритм &amp;lt;i&amp;gt;k means&amp;lt;/i&amp;gt; является итерационным. Количество итераций алгоритма в общем случае не фиксируется и зависит от начального расположения объектов в пространстве, параметра &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt;, а также от начального приближения центров кластеров, &amp;lt;math&amp;gt;\mu_1, ..., \mu_k&amp;lt;/math&amp;gt;. В результате этого может варьироваться результат работы алгоритма. При неудачном выборе начальных параметров итерационный процесс может сойтись к локальному оптимуму&amp;lt;ref&amp;gt;Von Luxburg, Ulrike. Clustering Stability. Now Publishers Inc, 2010.&amp;lt;/ref&amp;gt;. По этим причинам алгоритм не является ни &amp;lt;b&amp;gt;детермирированным&amp;lt;/b&amp;gt;, ни &amp;lt;b&amp;gt;устойчивым&amp;lt;/b&amp;gt;.&lt;br /&gt;
 &lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Соотношение последовательной и параллельной сложности алгоритма&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\frac{\Theta_{k-means}}{\Psi_{k-means}} = \frac{O(\Tau*k*d*n)}{O(\Tau*log(k*d*n))}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Сильные стороны алгоритма&amp;lt;/b&amp;gt;:&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;i&amp;gt;Сравнительно высокая эффективность при простоте реализации&amp;lt;/i&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;i&amp;gt;Высокое качество кластеризации&amp;lt;/i&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;i&amp;gt;Возможность распараллеливания&amp;lt;/i&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;i&amp;gt;Существование множества модификаций&amp;lt;/i&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;Недостатки алгоритма&amp;lt;/b&amp;gt;&amp;lt;ref&amp;gt;Ortega, Joaquín Pérez, Ma Del Rocío Boone Rojas, and María J. Somodevilla. &amp;quot;Research issues on K-means Algorithm: An Experimental Trial Using Matlab.&amp;quot;&amp;lt;/ref&amp;gt;:&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;i&amp;gt;Количество кластеров является параметром алгоритма&amp;lt;/i&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;&amp;lt;i&amp;gt;Чувствительность к начальным условиям&amp;lt;/i&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;Инициализация центров кластеров в значительной степени влияет на результат кластеризации.&amp;lt;/p&amp;gt;&lt;br /&gt;
  &amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;&amp;lt;i&amp;gt;Чувствительность к выбросам и шумам&amp;lt;/i&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;Выбросы, далекие от центров настоящих кластеров, все равно учитываются при вычислении их центров.&amp;lt;/p&amp;gt;&lt;br /&gt;
  &amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;&amp;lt;i&amp;gt;Возможность сходимости к локальному оптимуму&amp;lt;/i&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;Итеративный подход не дает гарантии сходимости к оптимальному решению.&amp;lt;/p&amp;gt;&lt;br /&gt;
  &amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;&amp;lt;i&amp;gt;Использование понятия &amp;quot;среднего&amp;quot;&amp;lt;/i&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;Алгоритм неприменим к данным, для которых не определено понятие &amp;quot;среднего&amp;quot;, например, категориальным данным.&amp;lt;/p&amp;gt;&lt;br /&gt;
  &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&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;
Исследование масштабируемости параллельной реализации алгоритма k means проводилось на суперкомпьютере &amp;quot;Ломоносов&amp;quot;. Алгоритм реализован на языке C с использованием средств MPI.&lt;br /&gt;
Для исследования масштабируемости проводилось множество запусков программы с разным значением параметра (количество векторов для кластеризации), а также с различным числом процессоров. Фиксировались результаты запусков &amp;amp;ndash; время работы &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt; и количество произведенных итераций алгоритма &amp;lt;math&amp;gt;\Tau&amp;lt;/math&amp;gt;.&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;Значения &amp;lt;b&amp;gt;количества векторов&amp;lt;/b&amp;gt; &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;: 20&#039;000, 30&#039;000, 50&#039;000, 100&#039;000, 200&#039;000, 300&#039;000, 500&#039;000, 700&#039;000, 1&#039;000&#039;000, 1&#039;500&#039;000, 2&#039;000&#039;000.&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;Значения &amp;lt;b&amp;gt;количества процессоров&amp;lt;/b&amp;gt; &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt;: 1, 8, 16, 32, 64, 128, 160, 192, 224, 256, 288, 320, 352, 384, 416, 448, 480, 512.&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;Значение &amp;lt;b&amp;gt;количества кластеров&amp;lt;/b&amp;gt; &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt;: 100.&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;Значение &amp;lt;b&amp;gt;размерности векторов&amp;lt;/b&amp;gt; &amp;lt;math&amp;gt;d&amp;lt;/math&amp;gt;: 10.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Графики производительности и эффективности реализации представлены на рисунках 4 и 5 соответственно.&lt;br /&gt;
&lt;br /&gt;
[[file:Flops.png|thumb|center|800px|Рис. 4. График производительности реализации алгоритма.]]&lt;br /&gt;
&lt;br /&gt;
[[file:Efficiency.png|thumb|center|800px|Рис. 5. График эффективности реализации алгоритма.]]&lt;br /&gt;
&lt;br /&gt;
Для заданной конфигурации эксперимента (&amp;lt;math&amp;gt;n, d, p, k&amp;lt;/math&amp;gt;) и полученных результатах (&amp;lt;math&amp;gt;t, \Tau&amp;lt;/math&amp;gt;) производительность и эффективность реализации расчитывались по формулам (см. [[#Последовательная сложность алгоритма| последовательная сложность алгоритма]]):&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
&amp;lt;ul&amp;gt;&amp;lt;li&amp;gt;&amp;lt;math&amp;gt;Performance = \frac{\Theta_{k-means}^{d, n}}{t}\ \ FLOPS&amp;lt;/math&amp;gt;&amp;lt;/li&amp;gt;&amp;lt;/ul&amp;gt;&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
&amp;lt;ul&amp;gt;&amp;lt;li&amp;gt;&amp;lt;math&amp;gt;Efficiency = \frac{100 * Performance}{Performance_{Peak}^{p}}\ \ %,&amp;lt;/math&amp;gt;&amp;lt;/li&amp;gt;&amp;lt;/ul&amp;gt;&lt;br /&gt;
где &amp;lt;math&amp;gt;Performance_{Peak}^{p}&amp;lt;/math&amp;gt; &amp;amp;ndash; пиковая производительность суперкомпьютера при &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt; процессорах, вычисленная согласно спецификациям Intel&amp;amp;reg; XEON&amp;amp;reg; X5670&amp;lt;ref&amp;gt;&amp;quot;http://ark.intel.com/ru/products/47920/Intel-Xeon-Processor-X5670-12M-Cache-2_93-GHz-6_40-GTs-Intel-QPI&amp;quot;&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;В результате&amp;lt;/b&amp;gt; экспериментальной оценки были получены следующие оценки эффективности реализации:&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;b&amp;gt;Минимальное&amp;lt;/b&amp;gt; значение: 0.000409 % достигается при &amp;lt;math&amp;gt;n=20&#039;000, p=480&amp;lt;/math&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;b&amp;gt;Максимальное&amp;lt;/b&amp;gt; значение: 0.741119 % достигается при &amp;lt;math&amp;gt;n=300&#039;000, p=1&amp;lt;/math&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Динамические характеристики и эффективность реализации алгоритма ===&lt;br /&gt;
=== Выводы для классов архитектур ===&lt;br /&gt;
=== Существующие реализации алгоритма ===&lt;br /&gt;
==== Открытое программное обеспечение ====&lt;br /&gt;
&amp;lt;ol&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;[https://www.icpsr.umich.edu/CrimeStat/ CrimeStat]&amp;lt;/li&amp;gt; Программное обеспечение, созданное для операционных систем Windows, предоставляющее инструменты статистического  и пространственного анализа для решения задачи картирования преступности.&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://juliastats.github.io Julia]&amp;lt;/li&amp;gt; Высокоуровневый высокопроизводительный свободный язык программирования с динамической типизацией, созданный для математических вычислений, содержит реализацию k-means.&lt;br /&gt;
  &amp;lt;li&amp;gt;[https://mahout.apache.org Mahout]&amp;lt;/li&amp;gt; Apache Mahout - Java библиотека для работы с алгоритмами машинного обучения с использованием MapReduce. Содержит реализацию k-means.&lt;br /&gt;
  &amp;lt;li&amp;gt;[https://www.gnu.org/software/octave/ Octave]&amp;lt;/li&amp;gt; Написанная на C++  свободная система для математических вычислений, использующая совместимый с MATLAB язык высокого уровня, содержит реализацию k-means.&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://spark.apache.org/docs/latest/mllib-clustering.html Spark]&amp;lt;/li&amp;gt; Распределенная реализация k-means содержится в библиотеке Mlib для работы с алгоритмами машинного обучения, взаимодействующая с Python библиотекой NumPy и библиотека R.&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://torch.ch Torch]&amp;lt;/li&amp;gt;  MATLAB-подобная библиотека для языка программирования Lua с открытым исходным кодом, предоставляет большое количество алгоритмов для глубинного обучения и научных расчётов. Ядро написано на Си, прикладная часть выполняется на LuaJIT, поддерживается распараллеливание вычислений средствами CUDA и OpenMP. Существуют реализации k-means.&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://www.cs.waikato.ac.nz/ml/weka/ Weka]&amp;lt;/li&amp;gt;  Cвободное программное обеспечение для анализа данных, написанное на Java. Содержит k-means и x-means.&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://accord-framework.net/docs/html/T_Accord_MachineLearning_KMeans.htm Accord.NET]&amp;lt;/li&amp;gt; C# реализация алгоритмов k-means, k-means++, k-modes.&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://docs.opencv.org/3.0-beta/doc/py_tutorials/py_ml/py_kmeans/py_kmeans_opencv/py_kmeans_opencv.html OpenCV]&amp;lt;/li&amp;gt; Написанная на С++ библиотека, направленная в основном на решение задач компьютерного зрения. Содержит реализацию k-means.&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://mlpack.org/ MLPACK]&amp;lt;/li&amp;gt; Масштабируемая С++ библиотека для работы с алгоритмами машинного обучения, содержит реализацию k-means.&lt;br /&gt;
  &amp;lt;li&amp;gt;[https://www.scipy.org/ SciPy]&amp;lt;/li&amp;gt; Библиотека Python, содержит множество реализаций k-means.&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://scikit-learn.org/ scikit-learn]&amp;lt;/li&amp;gt; Библиотека Python, содержит множество реализаций k-means.&lt;br /&gt;
  &amp;lt;li&amp;gt;[https://www.r-bloggers.com/k-means-clustering-in-r/ R]&amp;lt;/li&amp;gt; Язык программирования для статистической обработки данных и работы с графикой, а также свободная программная среда вычислений с открытым исходным кодом в рамках проекта GNU, содержит три реализации k-means.&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://elki.dbs.ifi.lmu.de ELKI]&amp;lt;/li&amp;gt; Java фреймворк, содержащий реализацию k-means, а также множество других алгоритмов кластеризации.&lt;br /&gt;
&amp;lt;/ol&amp;gt;&lt;br /&gt;
==== Проприетарное программное обеспечение  ====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ol&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;[https://www.ayasdi.com/blog/bigdata/topological-data-analysis-of-oil-and-gas-petrophysical-data/ Ayasdi]&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://www.stata.com/features/cluster-analysis/ Stata]&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://mathworld.wolfram.com/K-MeansClusteringAlgorithm.html Mathematica]&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://www.mathworks.com/help/stats/kmeans.html?requestedDomain=www.mathworks.com MATLAB]&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;[https://support.sas.com/rnd/app/stat/procedures/fastclus.html SAS]&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://docs.rapidminer.com/studio/operators/modeling/segmentation/k_means.html RapidMiner]&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;[https://blogs.sap.com/2013/03/28/sap-hana-pal-k-means-algorithm-or-how-to-do-customer-segmentation-for-the-telecommunications-industry/ SAP HANA]&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ol&amp;gt;&lt;br /&gt;
== Литература ==&lt;br /&gt;
&amp;lt;references /&amp;gt;&lt;/div&gt;</summary>
		<author><name>DennZo1993</name></author>
	</entry>
	<entry>
		<id>https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:%D0%91%D1%80%D0%BE%D1%82%D0%B8%D0%BA%D0%BE%D0%B2%D1%81%D0%BA%D0%B0%D1%8F_%D0%94%D0%B0%D0%BD%D1%83%D1%82%D0%B0/%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_k-means&amp;diff=17173</id>
		<title>Участник:Бротиковская Данута/Алгоритм k-means</title>
		<link rel="alternate" type="text/html" href="https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:%D0%91%D1%80%D0%BE%D1%82%D0%B8%D0%BA%D0%BE%D0%B2%D1%81%D0%BA%D0%B0%D1%8F_%D0%94%D0%B0%D0%BD%D1%83%D1%82%D0%B0/%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_k-means&amp;diff=17173"/>
		<updated>2016-11-14T23:55:46Z</updated>

		<summary type="html">&lt;p&gt;DennZo1993: /* Масштабируемость реализации алгоритма */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt; {{Assignment|Zhum}}&lt;br /&gt;
&lt;br /&gt;
{{algorithm&lt;br /&gt;
| name              = Алгоритм k средних (k means)&lt;br /&gt;
| serial_complexity = &amp;lt;math&amp;gt;O(\Tau*k*d*n)&amp;lt;/math&amp;gt;&lt;br /&gt;
| input_data        = &amp;lt;math&amp;gt; d*n &amp;lt;/math&amp;gt;&lt;br /&gt;
| output_data       = &amp;lt;math&amp;gt; n &amp;lt;/math&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
Авторы страницы &amp;lt;b&amp;gt;[[Участник:Бротиковская Данута|Данута Бротиковская]]&amp;lt;/b&amp;gt; и &amp;lt;b&amp;gt;[[Участник:DennZo1993|Денис Зобнин]]&amp;lt;/b&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
Оба автора внесли одинаковый вклад в написание статьи (поиск материалов, изучение статей, заполнение контента статьи), четких разграничений по пунктам статьи сделать невозможно. &lt;br /&gt;
&lt;br /&gt;
== Свойства и структура алгоритма ==&lt;br /&gt;
&lt;br /&gt;
=== Общее описание алгоритма ===&lt;br /&gt;
Алгоритм &amp;lt;b&amp;gt;&amp;lt;i&amp;gt;k средних&amp;lt;/i&amp;gt;&amp;lt;/b&amp;gt; (&amp;lt;b&amp;gt;&amp;lt;i&amp;gt;k means&amp;lt;/i&amp;gt;&amp;lt;/b&amp;gt;) &amp;amp;ndash; неиерархический&amp;lt;ref&amp;gt;&amp;quot;https://ru.wikipedia.org/wiki/Иерархическая_кластеризация&amp;quot;&amp;lt;/ref&amp;gt;, итерационный метод кластеризации&amp;lt;ref&amp;gt;&amp;quot;https://ru.wikipedia.org/wiki/Кластерный_анализ&amp;quot;&amp;lt;/ref&amp;gt;, получивший большую популярность благодаря своей простоте, наглядности реализации и достаточно высокому качеству работы. Был изобретен в 1950-х годах математиком &amp;lt;i&amp;gt;Гуго Штейнгаузом&amp;lt;/i&amp;gt;&amp;lt;ref&amp;gt;Steinhaus, Hugo. &amp;quot;Sur la division des corp materiels en parties.&amp;quot; Bull. Acad. Polon. Sci 1.804 (1956): 801.&amp;lt;/ref&amp;gt; и почти одновременно &amp;lt;i&amp;gt;Стюартом Ллойдом&amp;lt;/i&amp;gt;&amp;lt;ref&amp;gt;Lloyd, S. P. &amp;quot;Least square quantization in PCM. Bell Telephone Laboratories Paper. Published in journal much later: Lloyd, SP: Least squares quantization in PCM.&amp;quot; IEEE Trans. Inform. Theor.(1957/1982).&amp;lt;/ref&amp;gt;. Особую популярность приобрел после публикации работы &amp;lt;i&amp;gt;МакКуина&amp;lt;/i&amp;gt;&amp;lt;ref&amp;gt;MacQueen, James. &amp;quot;Some methods for classification and analysis of multivariate observations.&amp;quot; Proceedings of the fifth Berkeley symposium on mathematical statistics and probability. Vol. 1. No. 14. 1967.&amp;lt;/ref&amp;gt; в 1967.&lt;br /&gt;
&lt;br /&gt;
Алгоритм представляет собой версию EM-алгоритма&amp;lt;ref&amp;gt;&amp;quot;https://ru.wikipedia.org/wiki/EM-алгоритм&amp;quot;&amp;lt;/ref&amp;gt;, применяемого также для разделения смеси гауссиан. Основная идея &amp;lt;i&amp;gt;k means&amp;lt;/i&amp;gt; заключается в том, что данные произвольно разбиваются на кластеры, после чего итеративно перевычисляется центр масс для каждого кластера, полученного на предыдущем шаге, затем векторы разбиваются на кластеры вновь в соответствии с тем, какой из новых центров оказался ближе по выбранной метрике.&lt;br /&gt;
&lt;br /&gt;
Цель алгоритма заключается в разделении &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; наблюдений на &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластеров таким образом, чтобы каждое наблюдение принадлежало ровно одному кластеру, расположенному на наименьшем расстоянии от наблюдения.&lt;br /&gt;
&lt;br /&gt;
=== Математическое описание алгоритма ===&lt;br /&gt;
&amp;lt;b&amp;gt;&amp;lt;u&amp;gt;Дано:&amp;lt;/u&amp;gt;&amp;lt;/b&amp;gt;&lt;br /&gt;
* набор из &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; наблюдений &amp;lt;math&amp;gt;X=\{\mathbf{x}_1, \mathbf{x}_2, ..., \mathbf{x}_n\}, \mathbf{x}_i \in \mathbb{R}^d, i=\overline{1, n}&amp;lt;/math&amp;gt;;&lt;br /&gt;
* &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; - требуемое число кластеров, &amp;lt;math&amp;gt;k \in \mathbb{N}, k \leq n&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;&amp;lt;u&amp;gt;Требуется:&amp;lt;/u&amp;gt;&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Разделить множество наблюдений &amp;lt;math&amp;gt;X&amp;lt;/math&amp;gt; на &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластеров &amp;lt;math&amp;gt;S_1, S_2, ..., S_k&amp;lt;/math&amp;gt;:&lt;br /&gt;
*   &amp;lt;math&amp;gt;S_i \cap S_j= \varnothing, \quad i \ne j&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
*   &amp;lt;math&amp;gt;\bigcup_{i=1}^{k} S_i = X&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;&amp;lt;u&amp;gt;Действие алгоритма:&amp;lt;/u&amp;gt;&amp;lt;/b&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;Алгоритм &amp;lt;i&amp;gt;k means&amp;lt;/i&amp;gt; разбивает набор &amp;lt;math&amp;gt;X&amp;lt;/math&amp;gt; на &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; наборов &amp;lt;math&amp;gt;S_1, S_2, ..., S_k,&amp;lt;/math&amp;gt; таким образом, чтобы минимизировать сумму квадратов расстояний от каждой точки кластера до его центра (центр масс кластера). Введем обозначение, &amp;lt;math&amp;gt;S=\{S_1, S_2, ..., S_k\}&amp;lt;/math&amp;gt;. Тогда действие алгоритма &amp;lt;i&amp;gt;k means&amp;lt;/i&amp;gt; равносильно поиску:&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;table style=&amp;quot;width:100%&amp;quot;&amp;gt;&lt;br /&gt;
  &amp;lt;tr&amp;gt;&lt;br /&gt;
    &amp;lt;td align=&amp;quot;center&amp;quot; width=&amp;quot;90%&amp;quot;&amp;gt;&amp;lt;math&amp;gt;\arg\min_{S} \sum\limits_{i=1}^k \sum\limits_{\mathbf{x} \in S_i} \rho(\mathbf{x}, \mathbf{\mu}_i )^2,&amp;lt;/math&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;td align=&amp;quot;right&amp;quot;&amp;gt;&amp;lt;math&amp;gt;(1)&amp;lt;/math&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;/table&amp;gt;&lt;br /&gt;
где &amp;lt;math&amp;gt;\mathbf{\mu}_i&amp;lt;/math&amp;gt; &amp;amp;ndash; центры кластеров, &amp;lt;math&amp;gt;i=\overline{1,k}, \quad \rho(\mathbf{x}, \mathbf{\mu}_i)&amp;lt;/math&amp;gt; &amp;amp;ndash; функция расстояния между &amp;lt;math&amp;gt;\mathbf{x}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\mu_i&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;&amp;lt;u&amp;gt;Шаги алгоритма: &amp;lt;/u&amp;gt;&amp;lt;/b&amp;gt;&lt;br /&gt;
&amp;lt;ol&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&lt;br /&gt;
    &amp;lt;b&amp;gt;Начальный шаг: инициализация кластеров&amp;lt;/b&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;Выбирается произвольное множество точек &amp;lt;math&amp;gt;\mu_i, i=\overline{1,k}&amp;lt;/math&amp;gt;, рассматриваемых как начальные центры кластеров: &amp;lt;math&amp;gt;\mu_i^{(0)} = \mu_i, \quad i=\overline{1, k}&amp;lt;/math&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
  &amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&lt;br /&gt;
    &amp;lt;b&amp;gt;Распределение векторов по кластерам&amp;lt;/b&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Шаг&amp;lt;/b&amp;gt; &amp;lt;math&amp;gt;t: \forall \mathbf{x}_i \in X, i=\overline{1,n}: \mathbf{x}_i \in S_j \iff  j=\arg\min_{k}\rho(\mathbf{x}_i,\mathbf{\mu}_k^{(t-1)})^2&amp;lt;/math&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
  &amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&lt;br /&gt;
    &amp;lt;b&amp;gt;Пересчет центров кластеров&amp;lt;/b&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Шаг &amp;lt;/b&amp;gt; &amp;lt;math&amp;gt;t: \forall i=\overline{1,k}:  \mu_i^{(t)} = \cfrac{1}{|S_i|}\sum_{\mathbf{x}\in S_i}\mathbf{x}&amp;lt;/math&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
  &amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&lt;br /&gt;
    &amp;lt;b&amp;gt;Проверка условия останова:&amp;lt;/b&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
    &#039;&#039;&#039;if&#039;&#039;&#039; &amp;lt;math&amp;gt;\exist i\in \overline{1,k}: \mu_i^{(t)} \ne \mu_i^{(t-1)}&amp;lt;/math&amp;gt; &#039;&#039;&#039;then&#039;&#039;&#039;&lt;br /&gt;
        t = t + 1;&lt;br /&gt;
        goto 2;&lt;br /&gt;
    &#039;&#039;&#039;else&#039;&#039;&#039;&lt;br /&gt;
        &#039;&#039;&#039;stop&#039;&#039;&#039;&lt;br /&gt;
  &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ol&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Вычислительное ядро алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Вычислительным ядром являются шаги 2 и 3 приведенного выше алгоритма: &amp;lt;b&amp;gt;&amp;lt;i&amp;gt;распределение векторов по кластерам&amp;lt;/i&amp;gt;&amp;lt;/b&amp;gt; и &amp;lt;b&amp;gt;&amp;lt;i&amp;gt;пересчет центров кластеров&amp;lt;/i&amp;gt;&amp;lt;/b&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;&amp;lt;i&amp;gt;Распределение векторов&amp;lt;/i&amp;gt;&amp;lt;/b&amp;gt; по кластерам предполагает вычисление расстояний между каждым вектором &amp;lt;math&amp;gt;\mathbf{x}_i \in X, i= \overline{1,n}&amp;lt;/math&amp;gt; и центрами кластера &amp;lt;math&amp;gt;\mathbf{\mu}_j, j= \overline{1,k}&amp;lt;/math&amp;gt;. Таким образом, данный шаг предполагает &amp;lt;math&amp;gt;k*n&amp;lt;/math&amp;gt; вычислений расстояний между d-мерными векторами. &lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;&amp;lt;i&amp;gt;Пересчет центров кластеров&amp;lt;/i&amp;gt;&amp;lt;/b&amp;gt; предполагает &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; вычислений центров масс &amp;lt;math&amp;gt;\mathbf{\mu}_i&amp;lt;/math&amp;gt; множеств &amp;lt;math&amp;gt;S_i, i=\overline{1,k}&amp;lt;/math&amp;gt; представленных выражением в шаге 3 представленного выше алгоритма.&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Макроструктура алгоритма ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Инициализация центров масс &amp;lt;math&amp;gt;\mu_1, ..., \mu_k&amp;lt;/math&amp;gt;&amp;lt;/b&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
Наиболее распространенными являются следующие стратегии:&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&lt;br /&gt;
    &amp;lt;b&amp;gt;Метод Forgy&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;В качестве начальных значений &amp;lt;math&amp;gt;\mu_1, ..., \mu_k&amp;lt;/math&amp;gt; берутся случайно выбранные векторы.&lt;br /&gt;
  &amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&lt;br /&gt;
    &amp;lt;b&amp;gt;Метод случайно разделения (Random Partitioning)&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;Для каждого вектора &amp;lt;math&amp;gt;\mathbf{x}_i \in X, i=\overline{1, n}&amp;lt;/math&amp;gt; выбирается случайным образом кластер &amp;lt;math&amp;gt;S_1, ..., S_k&amp;lt;/math&amp;gt;, после чего для каждого полученного кластера вычисляются значения &amp;lt;math&amp;gt;\mu_1, ..., \mu_k&amp;lt;/math&amp;gt;.&lt;br /&gt;
  &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Распределение векторов по кластерам&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Для этого шага алгоритма между векторами &amp;lt;math&amp;gt;\mathbf{x}_i \in X, i=\overline{1, n}&amp;lt;/math&amp;gt; и центрами кластеров &amp;lt;math&amp;gt;\mu_1, ..., \mu_k&amp;lt;/math&amp;gt; вычисляются &amp;lt;b&amp;gt;расстояния&amp;lt;/b&amp;gt; по формуле (как правило, используется Евлидово расстояние):&lt;br /&gt;
&amp;lt;table style=&amp;quot;width:100%&amp;quot;&amp;gt;&lt;br /&gt;
  &amp;lt;tr&amp;gt;&lt;br /&gt;
    &amp;lt;td align=&amp;quot;center&amp;quot; width=&amp;quot;90%&amp;quot;&amp;gt;&amp;lt;math&amp;gt; \mathbf{v}_1, \mathbf{v}_2 \in \mathbb{R}^d,  \quad \rho(\mathbf{v}_1, \mathbf{v}_2) = \lVert \mathbf{v}_1- \mathbf{v}_2 \rVert= \sqrt{\sum_{i=1}^{d}(\mathbf{v}_{1,i} - \mathbf{v}_{2,i})^2}&amp;lt;/math&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;td align=&amp;quot;right&amp;quot;&amp;gt;&amp;lt;math&amp;gt;(2)&amp;lt;/math&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;/table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Пересчет центров кластеров&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Для этого шага алгоритма производится пересчет центров кластера по &amp;lt;b&amp;gt;формуле вычисления центра масс&amp;lt;/b&amp;gt;:&lt;br /&gt;
&amp;lt;table style=&amp;quot;width:100%&amp;quot;&amp;gt;&lt;br /&gt;
  &amp;lt;tr&amp;gt;&lt;br /&gt;
    &amp;lt;td align=&amp;quot;center&amp;quot; width=&amp;quot;90%&amp;quot;&amp;gt;&amp;lt;math&amp;gt; \mu = \cfrac{1}{|S|}\sum_{\mathbf{x}\in S}\mathbf{x}&amp;lt;/math&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;td align=&amp;quot;right&amp;quot;&amp;gt;&amp;lt;math&amp;gt;(3)&amp;lt;/math&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;/table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Схема реализации последовательного алгоритма ===&lt;br /&gt;
&lt;br /&gt;
 &#039;&#039;&#039;algorithm&#039;&#039;&#039; k-means &#039;&#039;&#039;is&#039;&#039;&#039;&lt;br /&gt;
     &#039;&#039;&#039;1.&#039;&#039;&#039; Инициализировать центры кластеров &amp;lt;math&amp;gt;\mathbf{\mu}_i^{(1)}, i=\overline{1,k}&amp;lt;/math&amp;gt;&lt;br /&gt;
     &#039;&#039;&#039;2.&#039;&#039;&#039; &amp;lt;math&amp;gt;t \leftarrow 1&amp;lt;/math&amp;gt;&lt;br /&gt;
     &#039;&#039;&#039;3.&#039;&#039;&#039; &#039;&#039;&#039;Распределение по кластерам&#039;&#039;&#039;&amp;lt;br&amp;gt;&lt;br /&gt;
        &amp;lt;math&amp;gt;S_i^{(t)}=\{\mathbf{x}_p: \lVert\mathbf{x}_p-\mathbf{\mu}_i^{(t)}\rVert^2 \leq \lVert\mathbf{x}_p-\mathbf{\mu}_j^{(t)}\rVert^2 \quad \forall j=\overline{1,k}\},&amp;lt;/math&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
        где каждый вектор &amp;lt;math&amp;gt;\mathbf{x}_p&amp;lt;/math&amp;gt; соотносится единственному кластеру &amp;lt;math&amp;gt;S^{(t)}&amp;lt;/math&amp;gt;&lt;br /&gt;
     &#039;&#039;&#039;4.&#039;&#039;&#039; &#039;&#039;&#039;Обновление центров кластеров&#039;&#039;&#039;&amp;lt;br&amp;gt;&lt;br /&gt;
        &amp;lt;math&amp;gt;\mathbf{\mu}_i^{(t+1)} = \frac{1}{|S^{(t)}_i|} \sum_{\mathbf{x}_j \in S^{(t)}_i} \mathbf{x}_j &amp;lt;/math&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
     &#039;&#039;&#039;5.&#039;&#039;&#039; &#039;&#039;&#039;if&#039;&#039;&#039; &amp;lt;math&amp;gt;\exist i \in \overline{1,k}: \mathbf{\mu}_i^{(t+1)} \ne \mathbf{\mu}_i^{(t)}&amp;lt;/math&amp;gt; &#039;&#039;&#039;then&#039;&#039;&#039;&lt;br /&gt;
            t = t + 1;&lt;br /&gt;
            goto &#039;&#039;&#039;3&#039;&#039;&#039;;&lt;br /&gt;
        &#039;&#039;&#039;else&#039;&#039;&#039;&lt;br /&gt;
            &#039;&#039;&#039;stop&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
=== Последовательная сложность алгоритма===&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding-bottom: 20px&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;Обозначим &amp;lt;math&amp;gt;\Theta_{centroid}^{d, m}&amp;lt;/math&amp;gt; временную сложность вычисления центорида кластера, число элементов которого равна &amp;lt;math&amp;gt;m&amp;lt;/math&amp;gt;,  в d-мерном пространстве.&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;Аналогично  &amp;lt;math&amp;gt;\Theta_{distance}^d&amp;lt;/math&amp;gt; &amp;amp;ndash; временная сложность вычисления расстояния между двумя d-мерными векторами.&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding-bottom: 20px&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;Сложность шага инициализации &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластеров мощности &amp;lt;math&amp;gt;m&amp;lt;/math&amp;gt; в d-мерном пространстве &amp;amp;ndash; &amp;lt;math&amp;gt;\Theta_{init}^{k, d, m}&amp;lt;/math&amp;gt;&amp;lt;/b&amp;gt;&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;i&amp;gt;Стратерия Forgy&amp;lt;/i&amp;gt;: вычисления не требуются, &amp;lt;math&amp;gt;\Theta_{init}^{k, d, m} = 0&amp;lt;/math&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;i&amp;gt;Стратегия случайного разбиения&amp;lt;/i&amp;gt;: вычисление центров &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластеров,  &amp;lt;math&amp;gt;\Theta_{init}^{k, d, m} = k*\Theta_{centroid}^{d, m}, m \le n&amp;lt;/math&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding-bottom: 20px&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Cложность шага распределения d мерных векторов по &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластерам &amp;amp;ndash; &amp;lt;math&amp;gt;\Theta_{distribute}^{k, d}&amp;lt;/math&amp;gt;&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
На этом шаге для каждого вектора &amp;lt;math&amp;gt;\mathbf{x}_i \in X, i=\overline{1, n}&amp;lt;/math&amp;gt; вычисляется k расстояний до центров кластеров &amp;lt;math&amp;gt;\mathbf{\mu}_1, ...\mathbf{\mu}_k&amp;lt;/math&amp;gt;&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p align=&amp;quot;center&amp;quot;&amp;gt;&lt;br /&gt;
  &amp;lt;math&amp;gt;\Theta_{distribute}^{k, d} = n*k*\Theta_{distance}^d&amp;lt;/math&amp;gt;&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding-bottom: 20px&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;Сложность шага пересчета центров &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластеров размера &amp;lt;math&amp;gt;m&amp;lt;/math&amp;gt; в d-мерном пространстве &amp;amp;ndash; &amp;lt;math&amp;gt;\Theta_{recenter}^{k, d, m}&amp;lt;/math&amp;gt;&amp;lt;/b&amp;gt;&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;На этом шаге вычисляется &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; центров кластеров &amp;lt;math&amp;gt;\mathbf{\mu}_1, ...\mathbf{\mu}_k&amp;lt;/math&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p align=&amp;quot;center&amp;quot;&amp;gt;&amp;lt;math&amp;gt;\Theta_{recenter}^{k, d, m} = k*\Theta_{centroid}^{d, m}&amp;lt;/math&amp;gt; &amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding-bottom: 20px&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Рассчитаем &amp;lt;math&amp;gt;\Theta_{centroid}^{d, m}&amp;lt;/math&amp;gt; для кластера, число элементов которого равно &amp;lt;math&amp;gt;m&amp;lt;/math&amp;gt;&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p align=&amp;quot;center&amp;quot;&amp;gt;&amp;lt;math&amp;gt;\Theta_{centroid}^{d, m}&amp;lt;/math&amp;gt; = &amp;lt;math&amp;gt;m * d&amp;lt;/math&amp;gt; сложений + &amp;lt;math&amp;gt;d&amp;lt;/math&amp;gt; делений &amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding-bottom: 20px&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Рассчитаем &amp;lt;math&amp;gt;\Theta_{distance}^d&amp;lt;/math&amp;gt; в соответствие с формулой &amp;lt;math&amp;gt;(2)&amp;lt;/math&amp;gt;&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p align=&amp;quot;center&amp;quot;&amp;gt;&amp;lt;math&amp;gt;\Theta_{distance}^d&amp;lt;/math&amp;gt; = &amp;lt;math&amp;gt;d&amp;lt;/math&amp;gt; вычитаний + &amp;lt;math&amp;gt;d&amp;lt;/math&amp;gt; умножений + &amp;lt;math&amp;gt;(d-1)&amp;lt;/math&amp;gt; сложение&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding-bottom: 20px&amp;quot;&amp;gt;&lt;br /&gt;
  &amp;lt;p&amp;gt;Предположим, что алгоритм сошелся за &amp;lt;math&amp;gt;\Tau&amp;lt;/math&amp;gt; итераций, тогда временная сложность алгоритма &amp;lt;math&amp;gt;\Theta_{k-means}^{d, n}&amp;lt;/math&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
  &amp;lt;p align=&amp;quot;center&amp;quot;&amp;gt;&amp;lt;b&amp;gt;&amp;lt;math&amp;gt;\Theta_{k-means}^{d, n} \le \Theta_{init}^{k, d, n} + \Tau*(\Theta_{distribute}^{k, d} + \Theta_{recenter}^{k, d, n})&amp;lt;/math&amp;gt;&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding-bottom: 5px&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;Операции сложения/вычитания:&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p align=&amp;quot;center&amp;quot;&amp;gt;&amp;lt;b&amp;gt;&amp;lt;math&amp;gt;\Theta_{k-means}^{d, n} \le k*n*d+ \Tau*(k*n*(2d-1) + k*n*d) = k*n*d+ \Tau*(k*n*(3d-1)) \thicksim O(\Tau*k*d*n)&amp;lt;/math&amp;gt;&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding-bottom: 20px&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;Операции умножения/деления:&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p align=&amp;quot;center&amp;quot;&amp;gt;&amp;lt;b&amp;gt;&amp;lt;math&amp;gt;\Theta_{k-means}^{d, n} \le k*d + \Tau*(k*n*d + k*d) = k*d + \Tau * k*d*(n+1) \thicksim O(\Tau*k*d*n) &amp;lt;/math&amp;gt;&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding-bottom: 20px&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;Получаем, что &amp;lt;b&amp;gt;временная сложность&amp;lt;/b&amp;gt; алгоритма &amp;lt;b&amp;gt;k means&amp;lt;/b&amp;gt; кластеризации &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; &amp;lt;b&amp;gt;d-мерных&amp;lt;/b&amp;gt; векторов на &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластеров за &amp;lt;math&amp;gt;\Tau&amp;lt;/math&amp;gt; итераций:&amp;lt;/p&amp;gt;&lt;br /&gt;
 &amp;lt;p align=&amp;quot;center&amp;quot;&amp;gt;&amp;lt;b&amp;gt;&amp;lt;math&amp;gt; \Theta_{k-means}^{d, n} \thicksim O(\Tau*k*d*n) &amp;lt;/math&amp;gt;&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Информационный граф ===&lt;br /&gt;
&lt;br /&gt;
Рассмотрим информационный граф алгоритма. Алгоритм &amp;lt;i&amp;gt;k means&amp;lt;/i&amp;gt; начинается с этапа инициализации, после которого следуют итерации, на каждой из которых выполняется два последовательных шага (см. [[#Схема реализации последовательного алгоритма|&amp;quot;Схема реализации последовательного алгоритма&amp;quot;]]): &lt;br /&gt;
* распределение векторов по кластерам&lt;br /&gt;
* перерасчет центров кластеров&lt;br /&gt;
&lt;br /&gt;
Поскольку основная часть вычислений приходится на шаги итераций, распишем информационные графы данных шагов.&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Распределение векторов по кластерам&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
Информационный граф шага распределения векторов по кластерам представлен на &#039;&#039;рисунке 1&#039;&#039;. Исходами данного графа является исходные векторы &amp;lt;math&amp;gt;\mathbf{x}_1, ..., \mathbf{x}_n&amp;lt;/math&amp;gt;, а также центры кластеров &amp;lt;math&amp;gt;\mathbf{\mu}_1, ... \mathbf{\mu}_k&amp;lt;/math&amp;gt;, вычисленные ранее (на шаге инициализации, если рассматривается первая итерация алгоритма, или на шаге пересчета центров кластеров предыдущей итерации в противном случае). Каждая пара векторов данных &amp;lt;math&amp;gt;\mathbf{x}_i, i=\overline{1,n}&amp;lt;/math&amp;gt; и центров кластера &amp;lt;math&amp;gt;\mathbf{\mu}_j, j=\overline{1, k}&amp;lt;/math&amp;gt; : (&amp;lt;math&amp;gt;\mathbf{x}_i&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;\mathbf{\mu}_j&amp;lt;/math&amp;gt;) подаются на независимые узлы &amp;lt;i&amp;gt;&amp;quot;d&amp;quot;&amp;lt;/i&amp;gt; вычисления расстояния между векторами (более подробная схема вычисления расстояния представлена далее, &#039;&#039;рисунок 2&#039;&#039;). Далее узлы вычисления расстояния &amp;lt;i&amp;gt;&amp;quot;d&amp;quot;&amp;lt;/i&amp;gt;, соответствующие одному и тому же исходному вектору &amp;lt;math&amp;gt;\mathbf{x}_i&amp;lt;/math&amp;gt; передаются на один узел &amp;lt;i&amp;gt;&amp;quot;m&amp;quot;&amp;lt;/i&amp;gt;, где далее происходит вычисление новой метки кластера для каждого вектора &amp;lt;math&amp;gt;\mathbf{x}_i&amp;lt;/math&amp;gt; (берется кластер с минимальным результатом вычисления расстояния). На выходе графа выдаются метки кластеров , &amp;lt;math&amp;gt;L_1, ..., L_n&amp;lt;/math&amp;gt;, такие что &amp;lt;math&amp;gt;\forall \mathbf{x}_i, i=\overline{1, n}, \mathbf{x}_i \in S_j \Leftrightarrow L_i = j&amp;lt;/math&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
[[file:Clusterization.png|thumb|center|800px|Рис. 1. Схема распределения векторов по кластерам. &#039;&#039;d&#039;&#039; &amp;amp;ndash; вычисление расстояния между векторами; &#039;&#039;m&#039;&#039; &amp;amp;ndash; вычисление минимума.]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Вычисление расстояния между векторами&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
Подробная схема вычисления расстояния между векторами &amp;lt;math&amp;gt;\mathbf{x}_i, \mathbf{\mu}_j&amp;lt;/math&amp;gt; представлена на &#039;&#039;рисунке 2&#039;&#039;. Как показано на графе, узел вычисления расстояния между векторами &amp;lt;i&amp;gt;&amp;quot;d&amp;quot;&amp;lt;/i&amp;gt; состоит из шага взятия разности между векторами (узел &amp;quot;&amp;lt;math&amp;gt;-&amp;lt;/math&amp;gt;&amp;quot;) и взятия нормы получившегося вектора разности (узел &amp;quot;&amp;lt;math&amp;gt;||\cdot||^2&amp;lt;/math&amp;gt;&amp;quot;). Более подробно, вычисление расстояния между векторами &amp;lt;math&amp;gt;\mathbf{x}_i = {x_{i1,}, ...,{x_{in}}}, \mathbf{\mu}_j = {\mu_{j1}, ...,\mu_{jn}}&amp;lt;/math&amp;gt; может быть представлено как вычисление разности между каждой парой компонент &amp;lt;math&amp;gt;(x_{iz}, \mu_{jz}), z=\overline{1, d}&amp;lt;/math&amp;gt; (узел &amp;quot;&amp;lt;math&amp;gt;-&amp;lt;/math&amp;gt;&amp;quot;), далее возведение в квадрат для каждого узла &amp;quot;&amp;lt;math&amp;gt;-&amp;lt;/math&amp;gt;&amp;quot; (узел &amp;quot;&amp;lt;math&amp;gt;()^2&amp;lt;/math&amp;gt;&amp;quot;) и суммирования выходов всех узлов &amp;quot;&amp;lt;math&amp;gt;()^2&amp;lt;/math&amp;gt;&amp;quot; (узел &amp;quot;&amp;lt;math&amp;gt;+&amp;lt;/math&amp;gt;&amp;quot;).  &lt;br /&gt;
&lt;br /&gt;
[[file:dist_calc.png|thumb|center|800px|Рис. 2. Схема вычисления расстояния между вектором и центром кластера.]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Пересчет центров кластеров&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
Информационный граф шага пересчета центров кластеров представлен на &#039;&#039;рисунке 3&#039;&#039;. Исходами данного графа является исходные векторы &amp;lt;math&amp;gt;\mathbf{x}_1, ..., \mathbf{x}_n&amp;lt;/math&amp;gt;, а также им соответствующие метки кластера, &amp;lt;math&amp;gt;L_1, ..., L_n&amp;lt;/math&amp;gt;, такие что &amp;lt;math&amp;gt;\forall x_i, i=\overline{1, n}, \mathbf{x}_i \in S_j \Leftrightarrow L_i = j&amp;lt;/math&amp;gt;, вычисленные на этапе распределения векторов по кластерам. Все векторы &amp;lt;math&amp;gt;\mathbf{x}_1, ..., \mathbf{x}_n&amp;lt;/math&amp;gt; подаются в узлы &amp;lt;math&amp;gt;+_1, ...+_k&amp;lt;/math&amp;gt;, каждый узел &amp;lt;math&amp;gt;+_m, m = \overline{1,k}&amp;lt;/math&amp;gt; соответствует операции сложения векторов кластера с номером &amp;lt;math&amp;gt;m&amp;lt;/math&amp;gt;. Метки кластера &amp;lt;math&amp;gt;L_1, ..., L_n&amp;lt;/math&amp;gt; также совместно передаются на узлы &amp;lt;math&amp;gt;S_m, m = \overline{1,k}&amp;lt;/math&amp;gt;, на каждом из которых вычисляется количество векторов в соответствующем кластере (количество меток с соответствующим значением). Далее каждая пара выходов узлов &amp;lt;math&amp;gt;+_m&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;S_m&amp;lt;/math&amp;gt; подается на узел &amp;quot;&amp;lt;math&amp;gt;/&amp;lt;/math&amp;gt;&amp;quot;, где производится деление суммы векторов кластера на количество элементов в нем. Значения, вычисленные на узлах &amp;quot;&amp;lt;math&amp;gt;/&amp;lt;/math&amp;gt;&amp;quot;, присваиваются новым центрам кластеров (выходные значения графа).&lt;br /&gt;
&lt;br /&gt;
[[file:Recluster.png|thumb|center|800px|Рис. 3. Схема пересчета центров кластеров]]&lt;br /&gt;
&lt;br /&gt;
=== Ресурс параллелизма алгоритма ===&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
Работа алгоритма состоит из &amp;lt;math&amp;gt;\Tau&amp;lt;/math&amp;gt; итераций, в каждой из которых происходит &amp;lt;b&amp;gt;распределение d-мерных векторов по &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластерам&amp;lt;/b&amp;gt;, а также &amp;lt;b&amp;gt;пересчет центров кластеров в d-мерном пространстве&amp;lt;/b&amp;gt;. В шаге &amp;lt;b&amp;gt;распределения d-мерных векторов по &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластерам&amp;lt;/b&amp;gt; расстояния между вектором и центрами кластеров вычисляются независимо (отсутствуют информационные зависимости). &amp;lt;b&amp;gt;Центры масс кластеров&amp;lt;/b&amp;gt; также пересчитываются независимо друг от друга. Таким образом, имеет место [[глоссарий#Массовый параллелизм|&#039;&#039;массовый параллелизм&#039;&#039;]]. Вычислим параллельную сложность &amp;lt;math&amp;gt;\Psi_*&amp;lt;/math&amp;gt; каждого из шагов, а также параллельную сложность всего алгоритма, &amp;lt;math&amp;gt;\Psi_{k-means}&amp;lt;/math&amp;gt;. Будем исходить из предположения, что может быть использовано любое необходимое число потоков.&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Распределение d-мерных векторов по &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластерам&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;  &lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
Поскольку на данном шаге для каждой пары векторов &amp;lt;math&amp;gt;\mathbf{x}_i, i=\overline{1,n}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\mathbf{\mu}_j, j=\overline{1,k}&amp;lt;/math&amp;gt; операции вычисления расстояния не зависят друг от друга, они могут выполняться параллельно. Тогда, разделив все вычисление расстояний на &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; потоков, получим, что в каждом потоке будет выполняться только одна операция вычисления расстояния между векторами размерности d. При этом каждому вычислительному потоку передаются координаты центров всех кластеров &amp;lt;math&amp;gt;\mathbf{\mu}_1, ..., \mathbf{\mu}_k&amp;lt;/math&amp;gt;. Таким образом, параллельная сложность данного шага определяется &amp;lt;i&amp;gt; сложностью параллельной операции вычисления расстояния между d-мерными векторами&amp;lt;/i&amp;gt;, &amp;lt;math&amp;gt;\Psi_{distance}^d&amp;lt;/math&amp;gt;  и &amp;lt;i&amp;gt;сложностью определения наиболее близкого кластера&amp;lt;/i&amp;gt; (паралельное взятие минимума по расстояниям), &amp;lt;math&amp;gt;\Psi_{min}^k&amp;lt;/math&amp;gt;. Для оценки &amp;lt;math&amp;gt;\Psi_{distance}^d&amp;lt;/math&amp;gt; воспользуемся  [[Нахождение_частных_сумм_элементов_массива_сдваиванием | параллельной реализацией нахождения частичной суммы элементов массива путем сдваивания]]. Аналогично, &amp;lt;math&amp;gt;\Psi_{min}^k = log(k)&amp;lt;/math&amp;gt;. В результате, &amp;lt;math&amp;gt;\Psi_{distance}^d = O(log(d))&amp;lt;/math&amp;gt;.   Таким образом: &lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p align=&amp;quot;center&amp;quot;&amp;gt;&amp;lt;math&amp;gt;\Psi_{distribute}^{k, d}  = \Psi_{distance}^d + \Psi_{min}^k = O(log(d))+O(log(k)) = O(log(k*d))&amp;lt;/math&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Пересчет центров кластеров в d-мерном пространстве&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
Поскольку на данном шаге для каждого из &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластеров центр масс может быть вычислен независимо, данные операции могут быть выполнены в отдельных потоках. Таким образом, параллельная сложность данного шага, &amp;lt;math&amp;gt;\Psi_{recenter}^{k, d}&amp;lt;/math&amp;gt;,  будет определяться &amp;lt;i&amp;gt;параллельной сложностью вычисления одного центра масс кластера размера &amp;lt;math&amp;gt;m&amp;lt;/math&amp;gt;&amp;lt;/i&amp;gt;, &amp;lt;math&amp;gt;\Psi_{recenter}^{k, d}&amp;lt;/math&amp;gt;,  а так как &amp;lt;math&amp;gt;m \le n \Rightarrow \Psi_{recenter}^{d, m} \le \Psi_{recenter}^{d, n}&amp;lt;/math&amp;gt;. Сложность вычисления центра масс кластера d-мерных векторов размера n аналогично предыдущим вычислениям равна &amp;lt;math&amp;gt;O(log(n))&amp;lt;/math&amp;gt;. Тогда:  &lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p align=&amp;quot;center&amp;quot;&amp;gt;&amp;lt;math&amp;gt;\Psi_{recenter}^{k, d}  \le \Psi_{recenter}^{d, n} = O(log(n))&amp;lt;/math&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Общая параллельная сложность алгоритма&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
На каждой итерации необходимо обновление центров кластеров, которые будут использованы на следующей итерации. Таким образом, итерационный процесс выполняется последовательно&amp;lt;ref&amp;gt;Zhao, Weizhong, Huifang Ma, and Qing He. &amp;quot;Parallel k-means clustering based on mapreduce.&amp;quot; IEEE International Conference on Cloud Computing. Springer Berlin Heidelberg, 2009.&amp;lt;/ref&amp;gt;. Тогда, поскольку сложность каждой итерации  определяется &amp;lt;math&amp;gt;\Psi_{distribute}^{k, d}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\Psi_{recenter}&amp;lt;/math&amp;gt;, сложность всего алгоритма, &amp;lt;math&amp;gt;\Psi_{k-means}&amp;lt;/math&amp;gt; в предположении, что было сделано &amp;lt;math&amp;gt;\Tau&amp;lt;/math&amp;gt; операций определяется выражением&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p align=&amp;quot;center&amp;quot;&amp;gt;&amp;lt;math&amp;gt;\Psi_{k-means} \approx \Tau * (\Psi_{distribute}^{k, d} + \Psi_{recenter}^{k, d}) \le \Tau * O(log(k*d*n))&amp;lt;/math&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Входные и выходные данные алгоритма ===&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;Входные данные&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;Матрица из &amp;lt;math&amp;gt;n*d&amp;lt;/math&amp;gt; элементов &amp;lt;math&amp;gt;x_{i, j} \in \mathbb{R}, i=\overline{1, n}, j=\overline{1, d}&amp;lt;/math&amp;gt;&amp;amp;ndash; координат векторов (наблюдений).&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;Целое положительное число &amp;lt;math&amp;gt;k, k \le n&amp;lt;/math&amp;gt; &amp;amp;ndash; количество кластеров.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;Объем входных данных&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;math&amp;gt;1&amp;lt;/math&amp;gt; целое число + &amp;lt;math&amp;gt;n*d&amp;lt;/math&amp;gt; вещественных чисел (при условии, что координаты &amp;amp;ndash; вещественные числа).&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;Выходные данные&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; целых положительных чисел &amp;lt;math&amp;gt;L_1, ..., L_n&amp;lt;/math&amp;gt;&amp;amp;ndash; номера кластеров, соотвествующие каждому вектору (при условии, что нумерация кластеров начинается с &amp;lt;math&amp;gt;1&amp;lt;/math&amp;gt;).&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;Объем выходных данных&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; целых положительных чисел.&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Свойства алгоритма ===&lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;[[глоссарий#Вычислительная мощность|&#039;&#039;Вычислительная мощность&#039;&#039;]]&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
Вычислительная мощность алгоритма &amp;lt;i&amp;gt;k means&amp;lt;/i&amp;gt; равна &amp;lt;math&amp;gt;\frac{k*d*n*\Tau}{n*d} = k*\Tau &amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; &amp;amp;ndash; число кластеров, &amp;lt;math&amp;gt;\Tau&amp;lt;/math&amp;gt; &amp;amp;ndash; число итераций алгоритма.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;[[глоссарий#Детерминированность |&#039;&#039;Детерминированность&#039;&#039;]] и [[глоссарий#Устойчивость |&#039;&#039;Устойчивость&#039;&#039;]] &amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
Алгоритм &amp;lt;i&amp;gt;k means&amp;lt;/i&amp;gt; является итерационным. Количество итераций алгоритма в общем случае не фиксируется и зависит от начального расположения объектов в пространстве, параметра &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt;, а также от начального приближения центров кластеров, &amp;lt;math&amp;gt;\mu_1, ..., \mu_k&amp;lt;/math&amp;gt;. В результате этого может варьироваться результат работы алгоритма. При неудачном выборе начальных параметров итерационный процесс может сойтись к локальному оптимуму&amp;lt;ref&amp;gt;Von Luxburg, Ulrike. Clustering Stability. Now Publishers Inc, 2010.&amp;lt;/ref&amp;gt;. По этим причинам алгоритм не является ни &amp;lt;b&amp;gt;детермирированным&amp;lt;/b&amp;gt;, ни &amp;lt;b&amp;gt;устойчивым&amp;lt;/b&amp;gt;.&lt;br /&gt;
 &lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Соотношение последовательной и параллельной сложности алгоритма&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\frac{\Theta_{k-means}}{\Psi_{k-means}} = \frac{O(\Tau*k*d*n)}{O(\Tau*log(k*d*n))}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Сильные стороны алгоритма&amp;lt;/b&amp;gt;:&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;i&amp;gt;Сравнительно высокая эффективность при простоте реализации&amp;lt;/i&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;i&amp;gt;Высокое качество кластеризации&amp;lt;/i&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;i&amp;gt;Возможность распараллеливания&amp;lt;/i&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;i&amp;gt;Существование множества модификаций&amp;lt;/i&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;Недостатки алгоритма&amp;lt;/b&amp;gt;&amp;lt;ref&amp;gt;Ortega, Joaquín Pérez, Ma Del Rocío Boone Rojas, and María J. Somodevilla. &amp;quot;Research issues on K-means Algorithm: An Experimental Trial Using Matlab.&amp;quot;&amp;lt;/ref&amp;gt;:&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;i&amp;gt;Количество кластеров является параметром алгоритма&amp;lt;/i&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;&amp;lt;i&amp;gt;Чувствительность к начальным условиям&amp;lt;/i&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;Инициализация центров кластеров в значительной степени влияет на результат кластеризации.&amp;lt;/p&amp;gt;&lt;br /&gt;
  &amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;&amp;lt;i&amp;gt;Чувствительность к выбросам и шумам&amp;lt;/i&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;Выбросы, далекие от центров настоящих кластеров, все равно учитываются при вычислении их центров.&amp;lt;/p&amp;gt;&lt;br /&gt;
  &amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;&amp;lt;i&amp;gt;Возможность сходимости к локальному оптимуму&amp;lt;/i&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;Итеративный подход не дает гарантии сходимости к оптимальному решению.&amp;lt;/p&amp;gt;&lt;br /&gt;
  &amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;&amp;lt;i&amp;gt;Использование понятия &amp;quot;среднего&amp;quot;&amp;lt;/i&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;Алгоритм неприменим к данным, для которых не определено понятие &amp;quot;среднего&amp;quot;, например, категориальным данным.&amp;lt;/p&amp;gt;&lt;br /&gt;
  &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&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;
Исследование масштабируемости параллельной реализации алгоритма k means проводилось на суперкомпьютере &amp;quot;Ломоносов&amp;quot;. Алгоритм реализован на языке C с использованием средств MPI.&lt;br /&gt;
Для исследования масштабируемости проводилось множество запусков программы с разным значением параметра (количество векторов для кластеризации), а также с различным числом процессоров. Фиксировались результаты запусков &amp;amp;ndash; время работы &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt; и количество произведенных итераций алгоритма &amp;lt;math&amp;gt;\Tau&amp;lt;/math&amp;gt;.&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;Значения &amp;lt;b&amp;gt;количества векторов&amp;lt;/b&amp;gt; &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;: 20&#039;000, 30&#039;000, 50&#039;000, 100&#039;000, 200&#039;000, 300&#039;000, 500&#039;000, 700&#039;000, 1&#039;000&#039;000, 1&#039;500&#039;000, 2&#039;000&#039;000.&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;Значения &amp;lt;b&amp;gt;количества процессоров&amp;lt;/b&amp;gt; &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt;: 1, 8, 16, 32, 64, 128, 160, 192, 224, 256, 288, 320, 352, 384, 416, 448, 480, 512.&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;Значение &amp;lt;b&amp;gt;количества кластеров&amp;lt;/b&amp;gt; &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt;: 100.&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;Значение &amp;lt;b&amp;gt;размерности векторов&amp;lt;/b&amp;gt; &amp;lt;math&amp;gt;d&amp;lt;/math&amp;gt;: 10.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Графики производительности и эффективности реализации представлены на рисунках 4 и 5 соответственно.&lt;br /&gt;
&lt;br /&gt;
[[file:Flops.png|thumb|center|800px|Рис. 4. График производительности реализации алгоритма.]]&lt;br /&gt;
&lt;br /&gt;
[[file:Efficiency.png|thumb|center|800px|Рис. 5. График эффективности реализации алгоритма.]]&lt;br /&gt;
&lt;br /&gt;
Для заданной конфигурации эксперимента (&amp;lt;math&amp;gt;n, d, p, k&amp;lt;/math&amp;gt;) и полученных результатах (&amp;lt;math&amp;gt;t, \Tau&amp;lt;/math&amp;gt;) производительность и эффективность реализации расчитывались по формулам (см. [[#Последовательная сложность алгоритма| последовательная сложность алгоритма]]):&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
&amp;lt;ul&amp;gt;&amp;lt;li&amp;gt;&amp;lt;math&amp;gt;Performance = \frac{\Theta_{k-means}^{d, n}}{t}\ \ FLOPS&amp;lt;/math&amp;gt;&amp;lt;/li&amp;gt;&amp;lt;/ul&amp;gt;&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
&amp;lt;ul&amp;gt;&amp;lt;li&amp;gt;&amp;lt;math&amp;gt;Efficiency = \frac{100 * Performance}{Performance_{Peak}^{p}}\ \ %,&amp;lt;/math&amp;gt;&amp;lt;/li&amp;gt;&amp;lt;/ul&amp;gt;&lt;br /&gt;
где &amp;lt;math&amp;gt;Performance_{Peak}^{p}&amp;lt;/math&amp;gt; &amp;amp;ndash; пиковая производительность суперкомпьютера при &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt; процессорах, вычисленная согласно спецификациям Intel&amp;amp;reg; XEON&amp;amp;reg; X5670&amp;lt;ref&amp;gt;&amp;quot;http://ark.intel.com/ru/products/47920/Intel-Xeon-Processor-X5670-12M-Cache-2_93-GHz-6_40-GTs-Intel-QPI&amp;quot;&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;В результате&amp;lt;/b&amp;gt; экспериментальной оценки были получены следующие оценки эффективности реализации:&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;b&amp;gt;Минимальное&amp;lt;/b&amp;gt; значение: 0.000409 %&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;b&amp;gt;Максимальное&amp;lt;/b&amp;gt; значение: 0.741119 %&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Динамические характеристики и эффективность реализации алгоритма ===&lt;br /&gt;
=== Выводы для классов архитектур ===&lt;br /&gt;
=== Существующие реализации алгоритма ===&lt;br /&gt;
==== Открытое программное обеспечение ====&lt;br /&gt;
&amp;lt;ol&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;[https://www.icpsr.umich.edu/CrimeStat/ CrimeStat]&amp;lt;/li&amp;gt; Программное обеспечение, созданное для операционных систем Windows, предоставляющее инструменты статистического  и пространственного анализа для решения задачи картирования преступности.&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://juliastats.github.io Julia]&amp;lt;/li&amp;gt; Высокоуровневый высокопроизводительный свободный язык программирования с динамической типизацией, созданный для математических вычислений, содержит реализацию k-means.&lt;br /&gt;
  &amp;lt;li&amp;gt;[https://mahout.apache.org Mahout]&amp;lt;/li&amp;gt; Apache Mahout - Java библиотека для работы с алгоритмами машинного обучения с использованием MapReduce. Содержит реализацию k-means.&lt;br /&gt;
  &amp;lt;li&amp;gt;[https://www.gnu.org/software/octave/ Octave]&amp;lt;/li&amp;gt; Написанная на C++  свободная система для математических вычислений, использующая совместимый с MATLAB язык высокого уровня, содержит реализацию k-means.&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://spark.apache.org/docs/latest/mllib-clustering.html Spark]&amp;lt;/li&amp;gt; Распределенная реализация k-means содержится в библиотеке Mlib для работы с алгоритмами машинного обучения, взаимодействующая с Python библиотекой NumPy и библиотека R.&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://torch.ch Torch]&amp;lt;/li&amp;gt;  MATLAB-подобная библиотека для языка программирования Lua с открытым исходным кодом, предоставляет большое количество алгоритмов для глубинного обучения и научных расчётов. Ядро написано на Си, прикладная часть выполняется на LuaJIT, поддерживается распараллеливание вычислений средствами CUDA и OpenMP. Существуют реализации k-means.&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://www.cs.waikato.ac.nz/ml/weka/ Weka]&amp;lt;/li&amp;gt;  Cвободное программное обеспечение для анализа данных, написанное на Java. Содержит k-means и x-means.&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://accord-framework.net/docs/html/T_Accord_MachineLearning_KMeans.htm Accord.NET]&amp;lt;/li&amp;gt; C# реализация алгоритмов k-means, k-means++, k-modes.&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://docs.opencv.org/3.0-beta/doc/py_tutorials/py_ml/py_kmeans/py_kmeans_opencv/py_kmeans_opencv.html OpenCV]&amp;lt;/li&amp;gt; Написанная на С++ библиотека, направленная в основном на решение задач компьютерного зрения. Содержит реализацию k-means.&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://mlpack.org/ MLPACK]&amp;lt;/li&amp;gt; Масштабируемая С++ библиотека для работы с алгоритмами машинного обучения, содержит реализацию k-means.&lt;br /&gt;
  &amp;lt;li&amp;gt;[https://www.scipy.org/ SciPy]&amp;lt;/li&amp;gt; Библиотека Python, содержит множество реализаций k-means.&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://scikit-learn.org/ scikit-learn]&amp;lt;/li&amp;gt; Библиотека Python, содержит множество реализаций k-means.&lt;br /&gt;
  &amp;lt;li&amp;gt;[https://www.r-bloggers.com/k-means-clustering-in-r/ R]&amp;lt;/li&amp;gt; Язык программирования для статистической обработки данных и работы с графикой, а также свободная программная среда вычислений с открытым исходным кодом в рамках проекта GNU, содержит три реализации k-means.&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://elki.dbs.ifi.lmu.de ELKI]&amp;lt;/li&amp;gt; Java фреймворк, содержащий реализацию k-means, а также множество других алгоритмов кластеризации.&lt;br /&gt;
&amp;lt;/ol&amp;gt;&lt;br /&gt;
==== Проприетарное программное обеспечение  ====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ol&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;[https://www.ayasdi.com/blog/bigdata/topological-data-analysis-of-oil-and-gas-petrophysical-data/ Ayasdi]&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://www.stata.com/features/cluster-analysis/ Stata]&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://mathworld.wolfram.com/K-MeansClusteringAlgorithm.html Mathematica]&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://www.mathworks.com/help/stats/kmeans.html?requestedDomain=www.mathworks.com MATLAB]&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;[https://support.sas.com/rnd/app/stat/procedures/fastclus.html SAS]&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://docs.rapidminer.com/studio/operators/modeling/segmentation/k_means.html RapidMiner]&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;[https://blogs.sap.com/2013/03/28/sap-hana-pal-k-means-algorithm-or-how-to-do-customer-segmentation-for-the-telecommunications-industry/ SAP HANA]&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ol&amp;gt;&lt;br /&gt;
== Литература ==&lt;br /&gt;
&amp;lt;references /&amp;gt;&lt;/div&gt;</summary>
		<author><name>DennZo1993</name></author>
	</entry>
	<entry>
		<id>https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:%D0%91%D1%80%D0%BE%D1%82%D0%B8%D0%BA%D0%BE%D0%B2%D1%81%D0%BA%D0%B0%D1%8F_%D0%94%D0%B0%D0%BD%D1%83%D1%82%D0%B0/%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_k-means&amp;diff=17172</id>
		<title>Участник:Бротиковская Данута/Алгоритм k-means</title>
		<link rel="alternate" type="text/html" href="https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:%D0%91%D1%80%D0%BE%D1%82%D0%B8%D0%BA%D0%BE%D0%B2%D1%81%D0%BA%D0%B0%D1%8F_%D0%94%D0%B0%D0%BD%D1%83%D1%82%D0%B0/%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_k-means&amp;diff=17172"/>
		<updated>2016-11-14T23:54:44Z</updated>

		<summary type="html">&lt;p&gt;DennZo1993: /* Масштабируемость реализации алгоритма */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt; {{Assignment|Zhum}}&lt;br /&gt;
&lt;br /&gt;
{{algorithm&lt;br /&gt;
| name              = Алгоритм k средних (k means)&lt;br /&gt;
| serial_complexity = &amp;lt;math&amp;gt;O(\Tau*k*d*n)&amp;lt;/math&amp;gt;&lt;br /&gt;
| input_data        = &amp;lt;math&amp;gt; d*n &amp;lt;/math&amp;gt;&lt;br /&gt;
| output_data       = &amp;lt;math&amp;gt; n &amp;lt;/math&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
Авторы страницы &amp;lt;b&amp;gt;[[Участник:Бротиковская Данута|Данута Бротиковская]]&amp;lt;/b&amp;gt; и &amp;lt;b&amp;gt;[[Участник:DennZo1993|Денис Зобнин]]&amp;lt;/b&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
Оба автора внесли одинаковый вклад в написание статьи (поиск материалов, изучение статей, заполнение контента статьи), четких разграничений по пунктам статьи сделать невозможно. &lt;br /&gt;
&lt;br /&gt;
== Свойства и структура алгоритма ==&lt;br /&gt;
&lt;br /&gt;
=== Общее описание алгоритма ===&lt;br /&gt;
Алгоритм &amp;lt;b&amp;gt;&amp;lt;i&amp;gt;k средних&amp;lt;/i&amp;gt;&amp;lt;/b&amp;gt; (&amp;lt;b&amp;gt;&amp;lt;i&amp;gt;k means&amp;lt;/i&amp;gt;&amp;lt;/b&amp;gt;) &amp;amp;ndash; неиерархический&amp;lt;ref&amp;gt;&amp;quot;https://ru.wikipedia.org/wiki/Иерархическая_кластеризация&amp;quot;&amp;lt;/ref&amp;gt;, итерационный метод кластеризации&amp;lt;ref&amp;gt;&amp;quot;https://ru.wikipedia.org/wiki/Кластерный_анализ&amp;quot;&amp;lt;/ref&amp;gt;, получивший большую популярность благодаря своей простоте, наглядности реализации и достаточно высокому качеству работы. Был изобретен в 1950-х годах математиком &amp;lt;i&amp;gt;Гуго Штейнгаузом&amp;lt;/i&amp;gt;&amp;lt;ref&amp;gt;Steinhaus, Hugo. &amp;quot;Sur la division des corp materiels en parties.&amp;quot; Bull. Acad. Polon. Sci 1.804 (1956): 801.&amp;lt;/ref&amp;gt; и почти одновременно &amp;lt;i&amp;gt;Стюартом Ллойдом&amp;lt;/i&amp;gt;&amp;lt;ref&amp;gt;Lloyd, S. P. &amp;quot;Least square quantization in PCM. Bell Telephone Laboratories Paper. Published in journal much later: Lloyd, SP: Least squares quantization in PCM.&amp;quot; IEEE Trans. Inform. Theor.(1957/1982).&amp;lt;/ref&amp;gt;. Особую популярность приобрел после публикации работы &amp;lt;i&amp;gt;МакКуина&amp;lt;/i&amp;gt;&amp;lt;ref&amp;gt;MacQueen, James. &amp;quot;Some methods for classification and analysis of multivariate observations.&amp;quot; Proceedings of the fifth Berkeley symposium on mathematical statistics and probability. Vol. 1. No. 14. 1967.&amp;lt;/ref&amp;gt; в 1967.&lt;br /&gt;
&lt;br /&gt;
Алгоритм представляет собой версию EM-алгоритма&amp;lt;ref&amp;gt;&amp;quot;https://ru.wikipedia.org/wiki/EM-алгоритм&amp;quot;&amp;lt;/ref&amp;gt;, применяемого также для разделения смеси гауссиан. Основная идея &amp;lt;i&amp;gt;k means&amp;lt;/i&amp;gt; заключается в том, что данные произвольно разбиваются на кластеры, после чего итеративно перевычисляется центр масс для каждого кластера, полученного на предыдущем шаге, затем векторы разбиваются на кластеры вновь в соответствии с тем, какой из новых центров оказался ближе по выбранной метрике.&lt;br /&gt;
&lt;br /&gt;
Цель алгоритма заключается в разделении &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; наблюдений на &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластеров таким образом, чтобы каждое наблюдение принадлежало ровно одному кластеру, расположенному на наименьшем расстоянии от наблюдения.&lt;br /&gt;
&lt;br /&gt;
=== Математическое описание алгоритма ===&lt;br /&gt;
&amp;lt;b&amp;gt;&amp;lt;u&amp;gt;Дано:&amp;lt;/u&amp;gt;&amp;lt;/b&amp;gt;&lt;br /&gt;
* набор из &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; наблюдений &amp;lt;math&amp;gt;X=\{\mathbf{x}_1, \mathbf{x}_2, ..., \mathbf{x}_n\}, \mathbf{x}_i \in \mathbb{R}^d, i=\overline{1, n}&amp;lt;/math&amp;gt;;&lt;br /&gt;
* &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; - требуемое число кластеров, &amp;lt;math&amp;gt;k \in \mathbb{N}, k \leq n&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;&amp;lt;u&amp;gt;Требуется:&amp;lt;/u&amp;gt;&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Разделить множество наблюдений &amp;lt;math&amp;gt;X&amp;lt;/math&amp;gt; на &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластеров &amp;lt;math&amp;gt;S_1, S_2, ..., S_k&amp;lt;/math&amp;gt;:&lt;br /&gt;
*   &amp;lt;math&amp;gt;S_i \cap S_j= \varnothing, \quad i \ne j&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
*   &amp;lt;math&amp;gt;\bigcup_{i=1}^{k} S_i = X&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;&amp;lt;u&amp;gt;Действие алгоритма:&amp;lt;/u&amp;gt;&amp;lt;/b&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;Алгоритм &amp;lt;i&amp;gt;k means&amp;lt;/i&amp;gt; разбивает набор &amp;lt;math&amp;gt;X&amp;lt;/math&amp;gt; на &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; наборов &amp;lt;math&amp;gt;S_1, S_2, ..., S_k,&amp;lt;/math&amp;gt; таким образом, чтобы минимизировать сумму квадратов расстояний от каждой точки кластера до его центра (центр масс кластера). Введем обозначение, &amp;lt;math&amp;gt;S=\{S_1, S_2, ..., S_k\}&amp;lt;/math&amp;gt;. Тогда действие алгоритма &amp;lt;i&amp;gt;k means&amp;lt;/i&amp;gt; равносильно поиску:&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;table style=&amp;quot;width:100%&amp;quot;&amp;gt;&lt;br /&gt;
  &amp;lt;tr&amp;gt;&lt;br /&gt;
    &amp;lt;td align=&amp;quot;center&amp;quot; width=&amp;quot;90%&amp;quot;&amp;gt;&amp;lt;math&amp;gt;\arg\min_{S} \sum\limits_{i=1}^k \sum\limits_{\mathbf{x} \in S_i} \rho(\mathbf{x}, \mathbf{\mu}_i )^2,&amp;lt;/math&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;td align=&amp;quot;right&amp;quot;&amp;gt;&amp;lt;math&amp;gt;(1)&amp;lt;/math&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;/table&amp;gt;&lt;br /&gt;
где &amp;lt;math&amp;gt;\mathbf{\mu}_i&amp;lt;/math&amp;gt; &amp;amp;ndash; центры кластеров, &amp;lt;math&amp;gt;i=\overline{1,k}, \quad \rho(\mathbf{x}, \mathbf{\mu}_i)&amp;lt;/math&amp;gt; &amp;amp;ndash; функция расстояния между &amp;lt;math&amp;gt;\mathbf{x}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\mu_i&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;&amp;lt;u&amp;gt;Шаги алгоритма: &amp;lt;/u&amp;gt;&amp;lt;/b&amp;gt;&lt;br /&gt;
&amp;lt;ol&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&lt;br /&gt;
    &amp;lt;b&amp;gt;Начальный шаг: инициализация кластеров&amp;lt;/b&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;Выбирается произвольное множество точек &amp;lt;math&amp;gt;\mu_i, i=\overline{1,k}&amp;lt;/math&amp;gt;, рассматриваемых как начальные центры кластеров: &amp;lt;math&amp;gt;\mu_i^{(0)} = \mu_i, \quad i=\overline{1, k}&amp;lt;/math&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
  &amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&lt;br /&gt;
    &amp;lt;b&amp;gt;Распределение векторов по кластерам&amp;lt;/b&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Шаг&amp;lt;/b&amp;gt; &amp;lt;math&amp;gt;t: \forall \mathbf{x}_i \in X, i=\overline{1,n}: \mathbf{x}_i \in S_j \iff  j=\arg\min_{k}\rho(\mathbf{x}_i,\mathbf{\mu}_k^{(t-1)})^2&amp;lt;/math&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
  &amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&lt;br /&gt;
    &amp;lt;b&amp;gt;Пересчет центров кластеров&amp;lt;/b&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Шаг &amp;lt;/b&amp;gt; &amp;lt;math&amp;gt;t: \forall i=\overline{1,k}:  \mu_i^{(t)} = \cfrac{1}{|S_i|}\sum_{\mathbf{x}\in S_i}\mathbf{x}&amp;lt;/math&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
  &amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&lt;br /&gt;
    &amp;lt;b&amp;gt;Проверка условия останова:&amp;lt;/b&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
    &#039;&#039;&#039;if&#039;&#039;&#039; &amp;lt;math&amp;gt;\exist i\in \overline{1,k}: \mu_i^{(t)} \ne \mu_i^{(t-1)}&amp;lt;/math&amp;gt; &#039;&#039;&#039;then&#039;&#039;&#039;&lt;br /&gt;
        t = t + 1;&lt;br /&gt;
        goto 2;&lt;br /&gt;
    &#039;&#039;&#039;else&#039;&#039;&#039;&lt;br /&gt;
        &#039;&#039;&#039;stop&#039;&#039;&#039;&lt;br /&gt;
  &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ol&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Вычислительное ядро алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Вычислительным ядром являются шаги 2 и 3 приведенного выше алгоритма: &amp;lt;b&amp;gt;&amp;lt;i&amp;gt;распределение векторов по кластерам&amp;lt;/i&amp;gt;&amp;lt;/b&amp;gt; и &amp;lt;b&amp;gt;&amp;lt;i&amp;gt;пересчет центров кластеров&amp;lt;/i&amp;gt;&amp;lt;/b&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;&amp;lt;i&amp;gt;Распределение векторов&amp;lt;/i&amp;gt;&amp;lt;/b&amp;gt; по кластерам предполагает вычисление расстояний между каждым вектором &amp;lt;math&amp;gt;\mathbf{x}_i \in X, i= \overline{1,n}&amp;lt;/math&amp;gt; и центрами кластера &amp;lt;math&amp;gt;\mathbf{\mu}_j, j= \overline{1,k}&amp;lt;/math&amp;gt;. Таким образом, данный шаг предполагает &amp;lt;math&amp;gt;k*n&amp;lt;/math&amp;gt; вычислений расстояний между d-мерными векторами. &lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;&amp;lt;i&amp;gt;Пересчет центров кластеров&amp;lt;/i&amp;gt;&amp;lt;/b&amp;gt; предполагает &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; вычислений центров масс &amp;lt;math&amp;gt;\mathbf{\mu}_i&amp;lt;/math&amp;gt; множеств &amp;lt;math&amp;gt;S_i, i=\overline{1,k}&amp;lt;/math&amp;gt; представленных выражением в шаге 3 представленного выше алгоритма.&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Макроструктура алгоритма ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Инициализация центров масс &amp;lt;math&amp;gt;\mu_1, ..., \mu_k&amp;lt;/math&amp;gt;&amp;lt;/b&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
Наиболее распространенными являются следующие стратегии:&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&lt;br /&gt;
    &amp;lt;b&amp;gt;Метод Forgy&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;В качестве начальных значений &amp;lt;math&amp;gt;\mu_1, ..., \mu_k&amp;lt;/math&amp;gt; берутся случайно выбранные векторы.&lt;br /&gt;
  &amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&lt;br /&gt;
    &amp;lt;b&amp;gt;Метод случайно разделения (Random Partitioning)&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;Для каждого вектора &amp;lt;math&amp;gt;\mathbf{x}_i \in X, i=\overline{1, n}&amp;lt;/math&amp;gt; выбирается случайным образом кластер &amp;lt;math&amp;gt;S_1, ..., S_k&amp;lt;/math&amp;gt;, после чего для каждого полученного кластера вычисляются значения &amp;lt;math&amp;gt;\mu_1, ..., \mu_k&amp;lt;/math&amp;gt;.&lt;br /&gt;
  &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Распределение векторов по кластерам&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Для этого шага алгоритма между векторами &amp;lt;math&amp;gt;\mathbf{x}_i \in X, i=\overline{1, n}&amp;lt;/math&amp;gt; и центрами кластеров &amp;lt;math&amp;gt;\mu_1, ..., \mu_k&amp;lt;/math&amp;gt; вычисляются &amp;lt;b&amp;gt;расстояния&amp;lt;/b&amp;gt; по формуле (как правило, используется Евлидово расстояние):&lt;br /&gt;
&amp;lt;table style=&amp;quot;width:100%&amp;quot;&amp;gt;&lt;br /&gt;
  &amp;lt;tr&amp;gt;&lt;br /&gt;
    &amp;lt;td align=&amp;quot;center&amp;quot; width=&amp;quot;90%&amp;quot;&amp;gt;&amp;lt;math&amp;gt; \mathbf{v}_1, \mathbf{v}_2 \in \mathbb{R}^d,  \quad \rho(\mathbf{v}_1, \mathbf{v}_2) = \lVert \mathbf{v}_1- \mathbf{v}_2 \rVert= \sqrt{\sum_{i=1}^{d}(\mathbf{v}_{1,i} - \mathbf{v}_{2,i})^2}&amp;lt;/math&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;td align=&amp;quot;right&amp;quot;&amp;gt;&amp;lt;math&amp;gt;(2)&amp;lt;/math&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;/table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Пересчет центров кластеров&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Для этого шага алгоритма производится пересчет центров кластера по &amp;lt;b&amp;gt;формуле вычисления центра масс&amp;lt;/b&amp;gt;:&lt;br /&gt;
&amp;lt;table style=&amp;quot;width:100%&amp;quot;&amp;gt;&lt;br /&gt;
  &amp;lt;tr&amp;gt;&lt;br /&gt;
    &amp;lt;td align=&amp;quot;center&amp;quot; width=&amp;quot;90%&amp;quot;&amp;gt;&amp;lt;math&amp;gt; \mu = \cfrac{1}{|S|}\sum_{\mathbf{x}\in S}\mathbf{x}&amp;lt;/math&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;td align=&amp;quot;right&amp;quot;&amp;gt;&amp;lt;math&amp;gt;(3)&amp;lt;/math&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;/table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Схема реализации последовательного алгоритма ===&lt;br /&gt;
&lt;br /&gt;
 &#039;&#039;&#039;algorithm&#039;&#039;&#039; k-means &#039;&#039;&#039;is&#039;&#039;&#039;&lt;br /&gt;
     &#039;&#039;&#039;1.&#039;&#039;&#039; Инициализировать центры кластеров &amp;lt;math&amp;gt;\mathbf{\mu}_i^{(1)}, i=\overline{1,k}&amp;lt;/math&amp;gt;&lt;br /&gt;
     &#039;&#039;&#039;2.&#039;&#039;&#039; &amp;lt;math&amp;gt;t \leftarrow 1&amp;lt;/math&amp;gt;&lt;br /&gt;
     &#039;&#039;&#039;3.&#039;&#039;&#039; &#039;&#039;&#039;Распределение по кластерам&#039;&#039;&#039;&amp;lt;br&amp;gt;&lt;br /&gt;
        &amp;lt;math&amp;gt;S_i^{(t)}=\{\mathbf{x}_p: \lVert\mathbf{x}_p-\mathbf{\mu}_i^{(t)}\rVert^2 \leq \lVert\mathbf{x}_p-\mathbf{\mu}_j^{(t)}\rVert^2 \quad \forall j=\overline{1,k}\},&amp;lt;/math&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
        где каждый вектор &amp;lt;math&amp;gt;\mathbf{x}_p&amp;lt;/math&amp;gt; соотносится единственному кластеру &amp;lt;math&amp;gt;S^{(t)}&amp;lt;/math&amp;gt;&lt;br /&gt;
     &#039;&#039;&#039;4.&#039;&#039;&#039; &#039;&#039;&#039;Обновление центров кластеров&#039;&#039;&#039;&amp;lt;br&amp;gt;&lt;br /&gt;
        &amp;lt;math&amp;gt;\mathbf{\mu}_i^{(t+1)} = \frac{1}{|S^{(t)}_i|} \sum_{\mathbf{x}_j \in S^{(t)}_i} \mathbf{x}_j &amp;lt;/math&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
     &#039;&#039;&#039;5.&#039;&#039;&#039; &#039;&#039;&#039;if&#039;&#039;&#039; &amp;lt;math&amp;gt;\exist i \in \overline{1,k}: \mathbf{\mu}_i^{(t+1)} \ne \mathbf{\mu}_i^{(t)}&amp;lt;/math&amp;gt; &#039;&#039;&#039;then&#039;&#039;&#039;&lt;br /&gt;
            t = t + 1;&lt;br /&gt;
            goto &#039;&#039;&#039;3&#039;&#039;&#039;;&lt;br /&gt;
        &#039;&#039;&#039;else&#039;&#039;&#039;&lt;br /&gt;
            &#039;&#039;&#039;stop&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
=== Последовательная сложность алгоритма===&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding-bottom: 20px&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;Обозначим &amp;lt;math&amp;gt;\Theta_{centroid}^{d, m}&amp;lt;/math&amp;gt; временную сложность вычисления центорида кластера, число элементов которого равна &amp;lt;math&amp;gt;m&amp;lt;/math&amp;gt;,  в d-мерном пространстве.&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;Аналогично  &amp;lt;math&amp;gt;\Theta_{distance}^d&amp;lt;/math&amp;gt; &amp;amp;ndash; временная сложность вычисления расстояния между двумя d-мерными векторами.&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding-bottom: 20px&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;Сложность шага инициализации &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластеров мощности &amp;lt;math&amp;gt;m&amp;lt;/math&amp;gt; в d-мерном пространстве &amp;amp;ndash; &amp;lt;math&amp;gt;\Theta_{init}^{k, d, m}&amp;lt;/math&amp;gt;&amp;lt;/b&amp;gt;&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;i&amp;gt;Стратерия Forgy&amp;lt;/i&amp;gt;: вычисления не требуются, &amp;lt;math&amp;gt;\Theta_{init}^{k, d, m} = 0&amp;lt;/math&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;i&amp;gt;Стратегия случайного разбиения&amp;lt;/i&amp;gt;: вычисление центров &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластеров,  &amp;lt;math&amp;gt;\Theta_{init}^{k, d, m} = k*\Theta_{centroid}^{d, m}, m \le n&amp;lt;/math&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding-bottom: 20px&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Cложность шага распределения d мерных векторов по &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластерам &amp;amp;ndash; &amp;lt;math&amp;gt;\Theta_{distribute}^{k, d}&amp;lt;/math&amp;gt;&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
На этом шаге для каждого вектора &amp;lt;math&amp;gt;\mathbf{x}_i \in X, i=\overline{1, n}&amp;lt;/math&amp;gt; вычисляется k расстояний до центров кластеров &amp;lt;math&amp;gt;\mathbf{\mu}_1, ...\mathbf{\mu}_k&amp;lt;/math&amp;gt;&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p align=&amp;quot;center&amp;quot;&amp;gt;&lt;br /&gt;
  &amp;lt;math&amp;gt;\Theta_{distribute}^{k, d} = n*k*\Theta_{distance}^d&amp;lt;/math&amp;gt;&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding-bottom: 20px&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;Сложность шага пересчета центров &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластеров размера &amp;lt;math&amp;gt;m&amp;lt;/math&amp;gt; в d-мерном пространстве &amp;amp;ndash; &amp;lt;math&amp;gt;\Theta_{recenter}^{k, d, m}&amp;lt;/math&amp;gt;&amp;lt;/b&amp;gt;&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;На этом шаге вычисляется &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; центров кластеров &amp;lt;math&amp;gt;\mathbf{\mu}_1, ...\mathbf{\mu}_k&amp;lt;/math&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p align=&amp;quot;center&amp;quot;&amp;gt;&amp;lt;math&amp;gt;\Theta_{recenter}^{k, d, m} = k*\Theta_{centroid}^{d, m}&amp;lt;/math&amp;gt; &amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding-bottom: 20px&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Рассчитаем &amp;lt;math&amp;gt;\Theta_{centroid}^{d, m}&amp;lt;/math&amp;gt; для кластера, число элементов которого равно &amp;lt;math&amp;gt;m&amp;lt;/math&amp;gt;&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p align=&amp;quot;center&amp;quot;&amp;gt;&amp;lt;math&amp;gt;\Theta_{centroid}^{d, m}&amp;lt;/math&amp;gt; = &amp;lt;math&amp;gt;m * d&amp;lt;/math&amp;gt; сложений + &amp;lt;math&amp;gt;d&amp;lt;/math&amp;gt; делений &amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding-bottom: 20px&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Рассчитаем &amp;lt;math&amp;gt;\Theta_{distance}^d&amp;lt;/math&amp;gt; в соответствие с формулой &amp;lt;math&amp;gt;(2)&amp;lt;/math&amp;gt;&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p align=&amp;quot;center&amp;quot;&amp;gt;&amp;lt;math&amp;gt;\Theta_{distance}^d&amp;lt;/math&amp;gt; = &amp;lt;math&amp;gt;d&amp;lt;/math&amp;gt; вычитаний + &amp;lt;math&amp;gt;d&amp;lt;/math&amp;gt; умножений + &amp;lt;math&amp;gt;(d-1)&amp;lt;/math&amp;gt; сложение&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding-bottom: 20px&amp;quot;&amp;gt;&lt;br /&gt;
  &amp;lt;p&amp;gt;Предположим, что алгоритм сошелся за &amp;lt;math&amp;gt;\Tau&amp;lt;/math&amp;gt; итераций, тогда временная сложность алгоритма &amp;lt;math&amp;gt;\Theta_{k-means}^{d, n}&amp;lt;/math&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
  &amp;lt;p align=&amp;quot;center&amp;quot;&amp;gt;&amp;lt;b&amp;gt;&amp;lt;math&amp;gt;\Theta_{k-means}^{d, n} \le \Theta_{init}^{k, d, n} + \Tau*(\Theta_{distribute}^{k, d} + \Theta_{recenter}^{k, d, n})&amp;lt;/math&amp;gt;&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding-bottom: 5px&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;Операции сложения/вычитания:&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p align=&amp;quot;center&amp;quot;&amp;gt;&amp;lt;b&amp;gt;&amp;lt;math&amp;gt;\Theta_{k-means}^{d, n} \le k*n*d+ \Tau*(k*n*(2d-1) + k*n*d) = k*n*d+ \Tau*(k*n*(3d-1)) \thicksim O(\Tau*k*d*n)&amp;lt;/math&amp;gt;&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding-bottom: 20px&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;Операции умножения/деления:&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p align=&amp;quot;center&amp;quot;&amp;gt;&amp;lt;b&amp;gt;&amp;lt;math&amp;gt;\Theta_{k-means}^{d, n} \le k*d + \Tau*(k*n*d + k*d) = k*d + \Tau * k*d*(n+1) \thicksim O(\Tau*k*d*n) &amp;lt;/math&amp;gt;&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding-bottom: 20px&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;Получаем, что &amp;lt;b&amp;gt;временная сложность&amp;lt;/b&amp;gt; алгоритма &amp;lt;b&amp;gt;k means&amp;lt;/b&amp;gt; кластеризации &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; &amp;lt;b&amp;gt;d-мерных&amp;lt;/b&amp;gt; векторов на &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластеров за &amp;lt;math&amp;gt;\Tau&amp;lt;/math&amp;gt; итераций:&amp;lt;/p&amp;gt;&lt;br /&gt;
 &amp;lt;p align=&amp;quot;center&amp;quot;&amp;gt;&amp;lt;b&amp;gt;&amp;lt;math&amp;gt; \Theta_{k-means}^{d, n} \thicksim O(\Tau*k*d*n) &amp;lt;/math&amp;gt;&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Информационный граф ===&lt;br /&gt;
&lt;br /&gt;
Рассмотрим информационный граф алгоритма. Алгоритм &amp;lt;i&amp;gt;k means&amp;lt;/i&amp;gt; начинается с этапа инициализации, после которого следуют итерации, на каждой из которых выполняется два последовательных шага (см. [[#Схема реализации последовательного алгоритма|&amp;quot;Схема реализации последовательного алгоритма&amp;quot;]]): &lt;br /&gt;
* распределение векторов по кластерам&lt;br /&gt;
* перерасчет центров кластеров&lt;br /&gt;
&lt;br /&gt;
Поскольку основная часть вычислений приходится на шаги итераций, распишем информационные графы данных шагов.&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Распределение векторов по кластерам&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
Информационный граф шага распределения векторов по кластерам представлен на &#039;&#039;рисунке 1&#039;&#039;. Исходами данного графа является исходные векторы &amp;lt;math&amp;gt;\mathbf{x}_1, ..., \mathbf{x}_n&amp;lt;/math&amp;gt;, а также центры кластеров &amp;lt;math&amp;gt;\mathbf{\mu}_1, ... \mathbf{\mu}_k&amp;lt;/math&amp;gt;, вычисленные ранее (на шаге инициализации, если рассматривается первая итерация алгоритма, или на шаге пересчета центров кластеров предыдущей итерации в противном случае). Каждая пара векторов данных &amp;lt;math&amp;gt;\mathbf{x}_i, i=\overline{1,n}&amp;lt;/math&amp;gt; и центров кластера &amp;lt;math&amp;gt;\mathbf{\mu}_j, j=\overline{1, k}&amp;lt;/math&amp;gt; : (&amp;lt;math&amp;gt;\mathbf{x}_i&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;\mathbf{\mu}_j&amp;lt;/math&amp;gt;) подаются на независимые узлы &amp;lt;i&amp;gt;&amp;quot;d&amp;quot;&amp;lt;/i&amp;gt; вычисления расстояния между векторами (более подробная схема вычисления расстояния представлена далее, &#039;&#039;рисунок 2&#039;&#039;). Далее узлы вычисления расстояния &amp;lt;i&amp;gt;&amp;quot;d&amp;quot;&amp;lt;/i&amp;gt;, соответствующие одному и тому же исходному вектору &amp;lt;math&amp;gt;\mathbf{x}_i&amp;lt;/math&amp;gt; передаются на один узел &amp;lt;i&amp;gt;&amp;quot;m&amp;quot;&amp;lt;/i&amp;gt;, где далее происходит вычисление новой метки кластера для каждого вектора &amp;lt;math&amp;gt;\mathbf{x}_i&amp;lt;/math&amp;gt; (берется кластер с минимальным результатом вычисления расстояния). На выходе графа выдаются метки кластеров , &amp;lt;math&amp;gt;L_1, ..., L_n&amp;lt;/math&amp;gt;, такие что &amp;lt;math&amp;gt;\forall \mathbf{x}_i, i=\overline{1, n}, \mathbf{x}_i \in S_j \Leftrightarrow L_i = j&amp;lt;/math&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
[[file:Clusterization.png|thumb|center|800px|Рис. 1. Схема распределения векторов по кластерам. &#039;&#039;d&#039;&#039; &amp;amp;ndash; вычисление расстояния между векторами; &#039;&#039;m&#039;&#039; &amp;amp;ndash; вычисление минимума.]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Вычисление расстояния между векторами&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
Подробная схема вычисления расстояния между векторами &amp;lt;math&amp;gt;\mathbf{x}_i, \mathbf{\mu}_j&amp;lt;/math&amp;gt; представлена на &#039;&#039;рисунке 2&#039;&#039;. Как показано на графе, узел вычисления расстояния между векторами &amp;lt;i&amp;gt;&amp;quot;d&amp;quot;&amp;lt;/i&amp;gt; состоит из шага взятия разности между векторами (узел &amp;quot;&amp;lt;math&amp;gt;-&amp;lt;/math&amp;gt;&amp;quot;) и взятия нормы получившегося вектора разности (узел &amp;quot;&amp;lt;math&amp;gt;||\cdot||^2&amp;lt;/math&amp;gt;&amp;quot;). Более подробно, вычисление расстояния между векторами &amp;lt;math&amp;gt;\mathbf{x}_i = {x_{i1,}, ...,{x_{in}}}, \mathbf{\mu}_j = {\mu_{j1}, ...,\mu_{jn}}&amp;lt;/math&amp;gt; может быть представлено как вычисление разности между каждой парой компонент &amp;lt;math&amp;gt;(x_{iz}, \mu_{jz}), z=\overline{1, d}&amp;lt;/math&amp;gt; (узел &amp;quot;&amp;lt;math&amp;gt;-&amp;lt;/math&amp;gt;&amp;quot;), далее возведение в квадрат для каждого узла &amp;quot;&amp;lt;math&amp;gt;-&amp;lt;/math&amp;gt;&amp;quot; (узел &amp;quot;&amp;lt;math&amp;gt;()^2&amp;lt;/math&amp;gt;&amp;quot;) и суммирования выходов всех узлов &amp;quot;&amp;lt;math&amp;gt;()^2&amp;lt;/math&amp;gt;&amp;quot; (узел &amp;quot;&amp;lt;math&amp;gt;+&amp;lt;/math&amp;gt;&amp;quot;).  &lt;br /&gt;
&lt;br /&gt;
[[file:dist_calc.png|thumb|center|800px|Рис. 2. Схема вычисления расстояния между вектором и центром кластера.]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Пересчет центров кластеров&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
Информационный граф шага пересчета центров кластеров представлен на &#039;&#039;рисунке 3&#039;&#039;. Исходами данного графа является исходные векторы &amp;lt;math&amp;gt;\mathbf{x}_1, ..., \mathbf{x}_n&amp;lt;/math&amp;gt;, а также им соответствующие метки кластера, &amp;lt;math&amp;gt;L_1, ..., L_n&amp;lt;/math&amp;gt;, такие что &amp;lt;math&amp;gt;\forall x_i, i=\overline{1, n}, \mathbf{x}_i \in S_j \Leftrightarrow L_i = j&amp;lt;/math&amp;gt;, вычисленные на этапе распределения векторов по кластерам. Все векторы &amp;lt;math&amp;gt;\mathbf{x}_1, ..., \mathbf{x}_n&amp;lt;/math&amp;gt; подаются в узлы &amp;lt;math&amp;gt;+_1, ...+_k&amp;lt;/math&amp;gt;, каждый узел &amp;lt;math&amp;gt;+_m, m = \overline{1,k}&amp;lt;/math&amp;gt; соответствует операции сложения векторов кластера с номером &amp;lt;math&amp;gt;m&amp;lt;/math&amp;gt;. Метки кластера &amp;lt;math&amp;gt;L_1, ..., L_n&amp;lt;/math&amp;gt; также совместно передаются на узлы &amp;lt;math&amp;gt;S_m, m = \overline{1,k}&amp;lt;/math&amp;gt;, на каждом из которых вычисляется количество векторов в соответствующем кластере (количество меток с соответствующим значением). Далее каждая пара выходов узлов &amp;lt;math&amp;gt;+_m&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;S_m&amp;lt;/math&amp;gt; подается на узел &amp;quot;&amp;lt;math&amp;gt;/&amp;lt;/math&amp;gt;&amp;quot;, где производится деление суммы векторов кластера на количество элементов в нем. Значения, вычисленные на узлах &amp;quot;&amp;lt;math&amp;gt;/&amp;lt;/math&amp;gt;&amp;quot;, присваиваются новым центрам кластеров (выходные значения графа).&lt;br /&gt;
&lt;br /&gt;
[[file:Recluster.png|thumb|center|800px|Рис. 3. Схема пересчета центров кластеров]]&lt;br /&gt;
&lt;br /&gt;
=== Ресурс параллелизма алгоритма ===&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
Работа алгоритма состоит из &amp;lt;math&amp;gt;\Tau&amp;lt;/math&amp;gt; итераций, в каждой из которых происходит &amp;lt;b&amp;gt;распределение d-мерных векторов по &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластерам&amp;lt;/b&amp;gt;, а также &amp;lt;b&amp;gt;пересчет центров кластеров в d-мерном пространстве&amp;lt;/b&amp;gt;. В шаге &amp;lt;b&amp;gt;распределения d-мерных векторов по &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластерам&amp;lt;/b&amp;gt; расстояния между вектором и центрами кластеров вычисляются независимо (отсутствуют информационные зависимости). &amp;lt;b&amp;gt;Центры масс кластеров&amp;lt;/b&amp;gt; также пересчитываются независимо друг от друга. Таким образом, имеет место [[глоссарий#Массовый параллелизм|&#039;&#039;массовый параллелизм&#039;&#039;]]. Вычислим параллельную сложность &amp;lt;math&amp;gt;\Psi_*&amp;lt;/math&amp;gt; каждого из шагов, а также параллельную сложность всего алгоритма, &amp;lt;math&amp;gt;\Psi_{k-means}&amp;lt;/math&amp;gt;. Будем исходить из предположения, что может быть использовано любое необходимое число потоков.&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Распределение d-мерных векторов по &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластерам&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;  &lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
Поскольку на данном шаге для каждой пары векторов &amp;lt;math&amp;gt;\mathbf{x}_i, i=\overline{1,n}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\mathbf{\mu}_j, j=\overline{1,k}&amp;lt;/math&amp;gt; операции вычисления расстояния не зависят друг от друга, они могут выполняться параллельно. Тогда, разделив все вычисление расстояний на &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; потоков, получим, что в каждом потоке будет выполняться только одна операция вычисления расстояния между векторами размерности d. При этом каждому вычислительному потоку передаются координаты центров всех кластеров &amp;lt;math&amp;gt;\mathbf{\mu}_1, ..., \mathbf{\mu}_k&amp;lt;/math&amp;gt;. Таким образом, параллельная сложность данного шага определяется &amp;lt;i&amp;gt; сложностью параллельной операции вычисления расстояния между d-мерными векторами&amp;lt;/i&amp;gt;, &amp;lt;math&amp;gt;\Psi_{distance}^d&amp;lt;/math&amp;gt;  и &amp;lt;i&amp;gt;сложностью определения наиболее близкого кластера&amp;lt;/i&amp;gt; (паралельное взятие минимума по расстояниям), &amp;lt;math&amp;gt;\Psi_{min}^k&amp;lt;/math&amp;gt;. Для оценки &amp;lt;math&amp;gt;\Psi_{distance}^d&amp;lt;/math&amp;gt; воспользуемся  [[Нахождение_частных_сумм_элементов_массива_сдваиванием | параллельной реализацией нахождения частичной суммы элементов массива путем сдваивания]]. Аналогично, &amp;lt;math&amp;gt;\Psi_{min}^k = log(k)&amp;lt;/math&amp;gt;. В результате, &amp;lt;math&amp;gt;\Psi_{distance}^d = O(log(d))&amp;lt;/math&amp;gt;.   Таким образом: &lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p align=&amp;quot;center&amp;quot;&amp;gt;&amp;lt;math&amp;gt;\Psi_{distribute}^{k, d}  = \Psi_{distance}^d + \Psi_{min}^k = O(log(d))+O(log(k)) = O(log(k*d))&amp;lt;/math&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Пересчет центров кластеров в d-мерном пространстве&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
Поскольку на данном шаге для каждого из &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластеров центр масс может быть вычислен независимо, данные операции могут быть выполнены в отдельных потоках. Таким образом, параллельная сложность данного шага, &amp;lt;math&amp;gt;\Psi_{recenter}^{k, d}&amp;lt;/math&amp;gt;,  будет определяться &amp;lt;i&amp;gt;параллельной сложностью вычисления одного центра масс кластера размера &amp;lt;math&amp;gt;m&amp;lt;/math&amp;gt;&amp;lt;/i&amp;gt;, &amp;lt;math&amp;gt;\Psi_{recenter}^{k, d}&amp;lt;/math&amp;gt;,  а так как &amp;lt;math&amp;gt;m \le n \Rightarrow \Psi_{recenter}^{d, m} \le \Psi_{recenter}^{d, n}&amp;lt;/math&amp;gt;. Сложность вычисления центра масс кластера d-мерных векторов размера n аналогично предыдущим вычислениям равна &amp;lt;math&amp;gt;O(log(n))&amp;lt;/math&amp;gt;. Тогда:  &lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p align=&amp;quot;center&amp;quot;&amp;gt;&amp;lt;math&amp;gt;\Psi_{recenter}^{k, d}  \le \Psi_{recenter}^{d, n} = O(log(n))&amp;lt;/math&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Общая параллельная сложность алгоритма&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
На каждой итерации необходимо обновление центров кластеров, которые будут использованы на следующей итерации. Таким образом, итерационный процесс выполняется последовательно&amp;lt;ref&amp;gt;Zhao, Weizhong, Huifang Ma, and Qing He. &amp;quot;Parallel k-means clustering based on mapreduce.&amp;quot; IEEE International Conference on Cloud Computing. Springer Berlin Heidelberg, 2009.&amp;lt;/ref&amp;gt;. Тогда, поскольку сложность каждой итерации  определяется &amp;lt;math&amp;gt;\Psi_{distribute}^{k, d}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\Psi_{recenter}&amp;lt;/math&amp;gt;, сложность всего алгоритма, &amp;lt;math&amp;gt;\Psi_{k-means}&amp;lt;/math&amp;gt; в предположении, что было сделано &amp;lt;math&amp;gt;\Tau&amp;lt;/math&amp;gt; операций определяется выражением&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p align=&amp;quot;center&amp;quot;&amp;gt;&amp;lt;math&amp;gt;\Psi_{k-means} \approx \Tau * (\Psi_{distribute}^{k, d} + \Psi_{recenter}^{k, d}) \le \Tau * O(log(k*d*n))&amp;lt;/math&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Входные и выходные данные алгоритма ===&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;Входные данные&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;Матрица из &amp;lt;math&amp;gt;n*d&amp;lt;/math&amp;gt; элементов &amp;lt;math&amp;gt;x_{i, j} \in \mathbb{R}, i=\overline{1, n}, j=\overline{1, d}&amp;lt;/math&amp;gt;&amp;amp;ndash; координат векторов (наблюдений).&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;Целое положительное число &amp;lt;math&amp;gt;k, k \le n&amp;lt;/math&amp;gt; &amp;amp;ndash; количество кластеров.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;Объем входных данных&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;math&amp;gt;1&amp;lt;/math&amp;gt; целое число + &amp;lt;math&amp;gt;n*d&amp;lt;/math&amp;gt; вещественных чисел (при условии, что координаты &amp;amp;ndash; вещественные числа).&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;Выходные данные&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; целых положительных чисел &amp;lt;math&amp;gt;L_1, ..., L_n&amp;lt;/math&amp;gt;&amp;amp;ndash; номера кластеров, соотвествующие каждому вектору (при условии, что нумерация кластеров начинается с &amp;lt;math&amp;gt;1&amp;lt;/math&amp;gt;).&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;Объем выходных данных&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; целых положительных чисел.&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Свойства алгоритма ===&lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;[[глоссарий#Вычислительная мощность|&#039;&#039;Вычислительная мощность&#039;&#039;]]&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
Вычислительная мощность алгоритма &amp;lt;i&amp;gt;k means&amp;lt;/i&amp;gt; равна &amp;lt;math&amp;gt;\frac{k*d*n*\Tau}{n*d} = k*\Tau &amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; &amp;amp;ndash; число кластеров, &amp;lt;math&amp;gt;\Tau&amp;lt;/math&amp;gt; &amp;amp;ndash; число итераций алгоритма.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;[[глоссарий#Детерминированность |&#039;&#039;Детерминированность&#039;&#039;]] и [[глоссарий#Устойчивость |&#039;&#039;Устойчивость&#039;&#039;]] &amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
Алгоритм &amp;lt;i&amp;gt;k means&amp;lt;/i&amp;gt; является итерационным. Количество итераций алгоритма в общем случае не фиксируется и зависит от начального расположения объектов в пространстве, параметра &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt;, а также от начального приближения центров кластеров, &amp;lt;math&amp;gt;\mu_1, ..., \mu_k&amp;lt;/math&amp;gt;. В результате этого может варьироваться результат работы алгоритма. При неудачном выборе начальных параметров итерационный процесс может сойтись к локальному оптимуму&amp;lt;ref&amp;gt;Von Luxburg, Ulrike. Clustering Stability. Now Publishers Inc, 2010.&amp;lt;/ref&amp;gt;. По этим причинам алгоритм не является ни &amp;lt;b&amp;gt;детермирированным&amp;lt;/b&amp;gt;, ни &amp;lt;b&amp;gt;устойчивым&amp;lt;/b&amp;gt;.&lt;br /&gt;
 &lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Соотношение последовательной и параллельной сложности алгоритма&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\frac{\Theta_{k-means}}{\Psi_{k-means}} = \frac{O(\Tau*k*d*n)}{O(\Tau*log(k*d*n))}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Сильные стороны алгоритма&amp;lt;/b&amp;gt;:&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;i&amp;gt;Сравнительно высокая эффективность при простоте реализации&amp;lt;/i&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;i&amp;gt;Высокое качество кластеризации&amp;lt;/i&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;i&amp;gt;Возможность распараллеливания&amp;lt;/i&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;i&amp;gt;Существование множества модификаций&amp;lt;/i&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;Недостатки алгоритма&amp;lt;/b&amp;gt;&amp;lt;ref&amp;gt;Ortega, Joaquín Pérez, Ma Del Rocío Boone Rojas, and María J. Somodevilla. &amp;quot;Research issues on K-means Algorithm: An Experimental Trial Using Matlab.&amp;quot;&amp;lt;/ref&amp;gt;:&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;i&amp;gt;Количество кластеров является параметром алгоритма&amp;lt;/i&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;&amp;lt;i&amp;gt;Чувствительность к начальным условиям&amp;lt;/i&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;Инициализация центров кластеров в значительной степени влияет на результат кластеризации.&amp;lt;/p&amp;gt;&lt;br /&gt;
  &amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;&amp;lt;i&amp;gt;Чувствительность к выбросам и шумам&amp;lt;/i&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;Выбросы, далекие от центров настоящих кластеров, все равно учитываются при вычислении их центров.&amp;lt;/p&amp;gt;&lt;br /&gt;
  &amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;&amp;lt;i&amp;gt;Возможность сходимости к локальному оптимуму&amp;lt;/i&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;Итеративный подход не дает гарантии сходимости к оптимальному решению.&amp;lt;/p&amp;gt;&lt;br /&gt;
  &amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;&amp;lt;i&amp;gt;Использование понятия &amp;quot;среднего&amp;quot;&amp;lt;/i&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;Алгоритм неприменим к данным, для которых не определено понятие &amp;quot;среднего&amp;quot;, например, категориальным данным.&amp;lt;/p&amp;gt;&lt;br /&gt;
  &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&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;
Исследование масштабируемости параллельной реализации алгоритма k means проводилось на суперкомпьютере &amp;quot;Ломоносов&amp;quot;. Алгоритм реализован на языке C с использованием средств MPI.&lt;br /&gt;
Для исследования масштабируемости проводилось множество запусков программы с разным значением параметра (количество векторов для кластеризации), а также с различным числом процессоров. Фиксировались результаты запусков &amp;amp;ndash; время работы &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt; и количество произведенных итераций алгоритма &amp;lt;math&amp;gt;\Tau&amp;lt;/math&amp;gt;.&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;Значения &amp;lt;b&amp;gt;количества векторов&amp;lt;/b&amp;gt; &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;: 20&#039;000, 30&#039;000, 50&#039;000, 100&#039;000, 200&#039;000, 300&#039;000, 500&#039;000, 700&#039;000, 1&#039;000&#039;000, 1&#039;500&#039;000, 2&#039;000&#039;000.&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;Значения &amp;lt;b&amp;gt;количества процессоров&amp;lt;/b&amp;gt; &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt;: 1, 8, 16, 32, 64, 128, 160, 192, 224, 256, 288, 320, 352, 384, 416, 448, 480, 512.&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;Значение &amp;lt;b&amp;gt;количества кластеров&amp;lt;/b&amp;gt; &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt;: 100.&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;Значение &amp;lt;b&amp;gt;размерности векторов&amp;lt;/b&amp;gt; &amp;lt;math&amp;gt;d&amp;lt;/math&amp;gt;: 10.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Графики производительности и эффективности реализации представлены на рисунках 4 и 5 соответственно.&lt;br /&gt;
&lt;br /&gt;
[[file:Flops.png|thumb|center|800px|Рис. 4. График производительности реализации алгоритма.]]&lt;br /&gt;
&lt;br /&gt;
[[file:Efficiency.png|thumb|center|800px|Рис. 5. График эффективности реализации алгоритма.]]&lt;br /&gt;
&lt;br /&gt;
Для заданной конфигурации эксперимента (&amp;lt;math&amp;gt;n, d, p, k&amp;lt;/math&amp;gt;) и полученных результатах (&amp;lt;math&amp;gt;t, \Tau&amp;lt;/math&amp;gt;) производительность и эффективность реализации расчитывались по формулам (см. [[#Последовательная сложность алгоритма| последовательная сложность алгоритма]]):&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
&amp;lt;ul&amp;gt;&amp;lt;li&amp;gt;&amp;lt;math&amp;gt;Performance = \frac{\Theta_{k-means}^{d, n}}{t}\ \ FLOPS&amp;lt;/math&amp;gt;&amp;lt;/li&amp;gt;&amp;lt;/ul&amp;gt;&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
&amp;lt;ul&amp;gt;&amp;lt;li&amp;gt;&amp;lt;math&amp;gt;Efficiency = \frac{100 * Performance}{Performance_{Peak}^{p}}\ \ %,&amp;lt;/math&amp;gt;&amp;lt;/li&amp;gt;&amp;lt;/ul&amp;gt;&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
где &amp;lt;math&amp;gt;Performance_{Peak}^{p}&amp;lt;/math&amp;gt; &amp;amp;ndash; пиковая производительность суперкомпьютера при &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt; процессорах, вычисленная согласно спецификациям Intel&amp;amp;reg; XEON&amp;amp;reg; X5670&amp;lt;ref&amp;gt;&amp;quot;http://ark.intel.com/ru/products/47920/Intel-Xeon-Processor-X5670-12M-Cache-2_93-GHz-6_40-GTs-Intel-QPI&amp;quot;&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;В результате&amp;lt;/b&amp;gt; экспериментальной оценки были получены следующие оценки эффективности реализации:&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;b&amp;gt;Минимальное&amp;lt;/b&amp;gt; значение: 0.000409 %&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;b&amp;gt;Максимальное&amp;lt;/b&amp;gt; значение: 0.741119 %&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Динамические характеристики и эффективность реализации алгоритма ===&lt;br /&gt;
=== Выводы для классов архитектур ===&lt;br /&gt;
=== Существующие реализации алгоритма ===&lt;br /&gt;
==== Открытое программное обеспечение ====&lt;br /&gt;
&amp;lt;ol&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;[https://www.icpsr.umich.edu/CrimeStat/ CrimeStat]&amp;lt;/li&amp;gt; Программное обеспечение, созданное для операционных систем Windows, предоставляющее инструменты статистического  и пространственного анализа для решения задачи картирования преступности.&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://juliastats.github.io Julia]&amp;lt;/li&amp;gt; Высокоуровневый высокопроизводительный свободный язык программирования с динамической типизацией, созданный для математических вычислений, содержит реализацию k-means.&lt;br /&gt;
  &amp;lt;li&amp;gt;[https://mahout.apache.org Mahout]&amp;lt;/li&amp;gt; Apache Mahout - Java библиотека для работы с алгоритмами машинного обучения с использованием MapReduce. Содержит реализацию k-means.&lt;br /&gt;
  &amp;lt;li&amp;gt;[https://www.gnu.org/software/octave/ Octave]&amp;lt;/li&amp;gt; Написанная на C++  свободная система для математических вычислений, использующая совместимый с MATLAB язык высокого уровня, содержит реализацию k-means.&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://spark.apache.org/docs/latest/mllib-clustering.html Spark]&amp;lt;/li&amp;gt; Распределенная реализация k-means содержится в библиотеке Mlib для работы с алгоритмами машинного обучения, взаимодействующая с Python библиотекой NumPy и библиотека R.&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://torch.ch Torch]&amp;lt;/li&amp;gt;  MATLAB-подобная библиотека для языка программирования Lua с открытым исходным кодом, предоставляет большое количество алгоритмов для глубинного обучения и научных расчётов. Ядро написано на Си, прикладная часть выполняется на LuaJIT, поддерживается распараллеливание вычислений средствами CUDA и OpenMP. Существуют реализации k-means.&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://www.cs.waikato.ac.nz/ml/weka/ Weka]&amp;lt;/li&amp;gt;  Cвободное программное обеспечение для анализа данных, написанное на Java. Содержит k-means и x-means.&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://accord-framework.net/docs/html/T_Accord_MachineLearning_KMeans.htm Accord.NET]&amp;lt;/li&amp;gt; C# реализация алгоритмов k-means, k-means++, k-modes.&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://docs.opencv.org/3.0-beta/doc/py_tutorials/py_ml/py_kmeans/py_kmeans_opencv/py_kmeans_opencv.html OpenCV]&amp;lt;/li&amp;gt; Написанная на С++ библиотека, направленная в основном на решение задач компьютерного зрения. Содержит реализацию k-means.&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://mlpack.org/ MLPACK]&amp;lt;/li&amp;gt; Масштабируемая С++ библиотека для работы с алгоритмами машинного обучения, содержит реализацию k-means.&lt;br /&gt;
  &amp;lt;li&amp;gt;[https://www.scipy.org/ SciPy]&amp;lt;/li&amp;gt; Библиотека Python, содержит множество реализаций k-means.&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://scikit-learn.org/ scikit-learn]&amp;lt;/li&amp;gt; Библиотека Python, содержит множество реализаций k-means.&lt;br /&gt;
  &amp;lt;li&amp;gt;[https://www.r-bloggers.com/k-means-clustering-in-r/ R]&amp;lt;/li&amp;gt; Язык программирования для статистической обработки данных и работы с графикой, а также свободная программная среда вычислений с открытым исходным кодом в рамках проекта GNU, содержит три реализации k-means.&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://elki.dbs.ifi.lmu.de ELKI]&amp;lt;/li&amp;gt; Java фреймворк, содержащий реализацию k-means, а также множество других алгоритмов кластеризации.&lt;br /&gt;
&amp;lt;/ol&amp;gt;&lt;br /&gt;
==== Проприетарное программное обеспечение  ====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ol&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;[https://www.ayasdi.com/blog/bigdata/topological-data-analysis-of-oil-and-gas-petrophysical-data/ Ayasdi]&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://www.stata.com/features/cluster-analysis/ Stata]&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://mathworld.wolfram.com/K-MeansClusteringAlgorithm.html Mathematica]&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://www.mathworks.com/help/stats/kmeans.html?requestedDomain=www.mathworks.com MATLAB]&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;[https://support.sas.com/rnd/app/stat/procedures/fastclus.html SAS]&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://docs.rapidminer.com/studio/operators/modeling/segmentation/k_means.html RapidMiner]&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;[https://blogs.sap.com/2013/03/28/sap-hana-pal-k-means-algorithm-or-how-to-do-customer-segmentation-for-the-telecommunications-industry/ SAP HANA]&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ol&amp;gt;&lt;br /&gt;
== Литература ==&lt;br /&gt;
&amp;lt;references /&amp;gt;&lt;/div&gt;</summary>
		<author><name>DennZo1993</name></author>
	</entry>
	<entry>
		<id>https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:%D0%91%D1%80%D0%BE%D1%82%D0%B8%D0%BA%D0%BE%D0%B2%D1%81%D0%BA%D0%B0%D1%8F_%D0%94%D0%B0%D0%BD%D1%83%D1%82%D0%B0/%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_k-means&amp;diff=17171</id>
		<title>Участник:Бротиковская Данута/Алгоритм k-means</title>
		<link rel="alternate" type="text/html" href="https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:%D0%91%D1%80%D0%BE%D1%82%D0%B8%D0%BA%D0%BE%D0%B2%D1%81%D0%BA%D0%B0%D1%8F_%D0%94%D0%B0%D0%BD%D1%83%D1%82%D0%B0/%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_k-means&amp;diff=17171"/>
		<updated>2016-11-14T23:53:00Z</updated>

		<summary type="html">&lt;p&gt;DennZo1993: /* Масштабируемость реализации алгоритма */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt; {{Assignment|Zhum}}&lt;br /&gt;
&lt;br /&gt;
{{algorithm&lt;br /&gt;
| name              = Алгоритм k средних (k means)&lt;br /&gt;
| serial_complexity = &amp;lt;math&amp;gt;O(\Tau*k*d*n)&amp;lt;/math&amp;gt;&lt;br /&gt;
| input_data        = &amp;lt;math&amp;gt; d*n &amp;lt;/math&amp;gt;&lt;br /&gt;
| output_data       = &amp;lt;math&amp;gt; n &amp;lt;/math&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
Авторы страницы &amp;lt;b&amp;gt;[[Участник:Бротиковская Данута|Данута Бротиковская]]&amp;lt;/b&amp;gt; и &amp;lt;b&amp;gt;[[Участник:DennZo1993|Денис Зобнин]]&amp;lt;/b&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
Оба автора внесли одинаковый вклад в написание статьи (поиск материалов, изучение статей, заполнение контента статьи), четких разграничений по пунктам статьи сделать невозможно. &lt;br /&gt;
&lt;br /&gt;
== Свойства и структура алгоритма ==&lt;br /&gt;
&lt;br /&gt;
=== Общее описание алгоритма ===&lt;br /&gt;
Алгоритм &amp;lt;b&amp;gt;&amp;lt;i&amp;gt;k средних&amp;lt;/i&amp;gt;&amp;lt;/b&amp;gt; (&amp;lt;b&amp;gt;&amp;lt;i&amp;gt;k means&amp;lt;/i&amp;gt;&amp;lt;/b&amp;gt;) &amp;amp;ndash; неиерархический&amp;lt;ref&amp;gt;&amp;quot;https://ru.wikipedia.org/wiki/Иерархическая_кластеризация&amp;quot;&amp;lt;/ref&amp;gt;, итерационный метод кластеризации&amp;lt;ref&amp;gt;&amp;quot;https://ru.wikipedia.org/wiki/Кластерный_анализ&amp;quot;&amp;lt;/ref&amp;gt;, получивший большую популярность благодаря своей простоте, наглядности реализации и достаточно высокому качеству работы. Был изобретен в 1950-х годах математиком &amp;lt;i&amp;gt;Гуго Штейнгаузом&amp;lt;/i&amp;gt;&amp;lt;ref&amp;gt;Steinhaus, Hugo. &amp;quot;Sur la division des corp materiels en parties.&amp;quot; Bull. Acad. Polon. Sci 1.804 (1956): 801.&amp;lt;/ref&amp;gt; и почти одновременно &amp;lt;i&amp;gt;Стюартом Ллойдом&amp;lt;/i&amp;gt;&amp;lt;ref&amp;gt;Lloyd, S. P. &amp;quot;Least square quantization in PCM. Bell Telephone Laboratories Paper. Published in journal much later: Lloyd, SP: Least squares quantization in PCM.&amp;quot; IEEE Trans. Inform. Theor.(1957/1982).&amp;lt;/ref&amp;gt;. Особую популярность приобрел после публикации работы &amp;lt;i&amp;gt;МакКуина&amp;lt;/i&amp;gt;&amp;lt;ref&amp;gt;MacQueen, James. &amp;quot;Some methods for classification and analysis of multivariate observations.&amp;quot; Proceedings of the fifth Berkeley symposium on mathematical statistics and probability. Vol. 1. No. 14. 1967.&amp;lt;/ref&amp;gt; в 1967.&lt;br /&gt;
&lt;br /&gt;
Алгоритм представляет собой версию EM-алгоритма&amp;lt;ref&amp;gt;&amp;quot;https://ru.wikipedia.org/wiki/EM-алгоритм&amp;quot;&amp;lt;/ref&amp;gt;, применяемого также для разделения смеси гауссиан. Основная идея &amp;lt;i&amp;gt;k means&amp;lt;/i&amp;gt; заключается в том, что данные произвольно разбиваются на кластеры, после чего итеративно перевычисляется центр масс для каждого кластера, полученного на предыдущем шаге, затем векторы разбиваются на кластеры вновь в соответствии с тем, какой из новых центров оказался ближе по выбранной метрике.&lt;br /&gt;
&lt;br /&gt;
Цель алгоритма заключается в разделении &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; наблюдений на &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластеров таким образом, чтобы каждое наблюдение принадлежало ровно одному кластеру, расположенному на наименьшем расстоянии от наблюдения.&lt;br /&gt;
&lt;br /&gt;
=== Математическое описание алгоритма ===&lt;br /&gt;
&amp;lt;b&amp;gt;&amp;lt;u&amp;gt;Дано:&amp;lt;/u&amp;gt;&amp;lt;/b&amp;gt;&lt;br /&gt;
* набор из &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; наблюдений &amp;lt;math&amp;gt;X=\{\mathbf{x}_1, \mathbf{x}_2, ..., \mathbf{x}_n\}, \mathbf{x}_i \in \mathbb{R}^d, i=\overline{1, n}&amp;lt;/math&amp;gt;;&lt;br /&gt;
* &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; - требуемое число кластеров, &amp;lt;math&amp;gt;k \in \mathbb{N}, k \leq n&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;&amp;lt;u&amp;gt;Требуется:&amp;lt;/u&amp;gt;&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Разделить множество наблюдений &amp;lt;math&amp;gt;X&amp;lt;/math&amp;gt; на &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластеров &amp;lt;math&amp;gt;S_1, S_2, ..., S_k&amp;lt;/math&amp;gt;:&lt;br /&gt;
*   &amp;lt;math&amp;gt;S_i \cap S_j= \varnothing, \quad i \ne j&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
*   &amp;lt;math&amp;gt;\bigcup_{i=1}^{k} S_i = X&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;&amp;lt;u&amp;gt;Действие алгоритма:&amp;lt;/u&amp;gt;&amp;lt;/b&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;Алгоритм &amp;lt;i&amp;gt;k means&amp;lt;/i&amp;gt; разбивает набор &amp;lt;math&amp;gt;X&amp;lt;/math&amp;gt; на &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; наборов &amp;lt;math&amp;gt;S_1, S_2, ..., S_k,&amp;lt;/math&amp;gt; таким образом, чтобы минимизировать сумму квадратов расстояний от каждой точки кластера до его центра (центр масс кластера). Введем обозначение, &amp;lt;math&amp;gt;S=\{S_1, S_2, ..., S_k\}&amp;lt;/math&amp;gt;. Тогда действие алгоритма &amp;lt;i&amp;gt;k means&amp;lt;/i&amp;gt; равносильно поиску:&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;table style=&amp;quot;width:100%&amp;quot;&amp;gt;&lt;br /&gt;
  &amp;lt;tr&amp;gt;&lt;br /&gt;
    &amp;lt;td align=&amp;quot;center&amp;quot; width=&amp;quot;90%&amp;quot;&amp;gt;&amp;lt;math&amp;gt;\arg\min_{S} \sum\limits_{i=1}^k \sum\limits_{\mathbf{x} \in S_i} \rho(\mathbf{x}, \mathbf{\mu}_i )^2,&amp;lt;/math&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;td align=&amp;quot;right&amp;quot;&amp;gt;&amp;lt;math&amp;gt;(1)&amp;lt;/math&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;/table&amp;gt;&lt;br /&gt;
где &amp;lt;math&amp;gt;\mathbf{\mu}_i&amp;lt;/math&amp;gt; &amp;amp;ndash; центры кластеров, &amp;lt;math&amp;gt;i=\overline{1,k}, \quad \rho(\mathbf{x}, \mathbf{\mu}_i)&amp;lt;/math&amp;gt; &amp;amp;ndash; функция расстояния между &amp;lt;math&amp;gt;\mathbf{x}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\mu_i&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;&amp;lt;u&amp;gt;Шаги алгоритма: &amp;lt;/u&amp;gt;&amp;lt;/b&amp;gt;&lt;br /&gt;
&amp;lt;ol&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&lt;br /&gt;
    &amp;lt;b&amp;gt;Начальный шаг: инициализация кластеров&amp;lt;/b&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;Выбирается произвольное множество точек &amp;lt;math&amp;gt;\mu_i, i=\overline{1,k}&amp;lt;/math&amp;gt;, рассматриваемых как начальные центры кластеров: &amp;lt;math&amp;gt;\mu_i^{(0)} = \mu_i, \quad i=\overline{1, k}&amp;lt;/math&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
  &amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&lt;br /&gt;
    &amp;lt;b&amp;gt;Распределение векторов по кластерам&amp;lt;/b&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Шаг&amp;lt;/b&amp;gt; &amp;lt;math&amp;gt;t: \forall \mathbf{x}_i \in X, i=\overline{1,n}: \mathbf{x}_i \in S_j \iff  j=\arg\min_{k}\rho(\mathbf{x}_i,\mathbf{\mu}_k^{(t-1)})^2&amp;lt;/math&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
  &amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&lt;br /&gt;
    &amp;lt;b&amp;gt;Пересчет центров кластеров&amp;lt;/b&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Шаг &amp;lt;/b&amp;gt; &amp;lt;math&amp;gt;t: \forall i=\overline{1,k}:  \mu_i^{(t)} = \cfrac{1}{|S_i|}\sum_{\mathbf{x}\in S_i}\mathbf{x}&amp;lt;/math&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
  &amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&lt;br /&gt;
    &amp;lt;b&amp;gt;Проверка условия останова:&amp;lt;/b&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
    &#039;&#039;&#039;if&#039;&#039;&#039; &amp;lt;math&amp;gt;\exist i\in \overline{1,k}: \mu_i^{(t)} \ne \mu_i^{(t-1)}&amp;lt;/math&amp;gt; &#039;&#039;&#039;then&#039;&#039;&#039;&lt;br /&gt;
        t = t + 1;&lt;br /&gt;
        goto 2;&lt;br /&gt;
    &#039;&#039;&#039;else&#039;&#039;&#039;&lt;br /&gt;
        &#039;&#039;&#039;stop&#039;&#039;&#039;&lt;br /&gt;
  &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ol&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Вычислительное ядро алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Вычислительным ядром являются шаги 2 и 3 приведенного выше алгоритма: &amp;lt;b&amp;gt;&amp;lt;i&amp;gt;распределение векторов по кластерам&amp;lt;/i&amp;gt;&amp;lt;/b&amp;gt; и &amp;lt;b&amp;gt;&amp;lt;i&amp;gt;пересчет центров кластеров&amp;lt;/i&amp;gt;&amp;lt;/b&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;&amp;lt;i&amp;gt;Распределение векторов&amp;lt;/i&amp;gt;&amp;lt;/b&amp;gt; по кластерам предполагает вычисление расстояний между каждым вектором &amp;lt;math&amp;gt;\mathbf{x}_i \in X, i= \overline{1,n}&amp;lt;/math&amp;gt; и центрами кластера &amp;lt;math&amp;gt;\mathbf{\mu}_j, j= \overline{1,k}&amp;lt;/math&amp;gt;. Таким образом, данный шаг предполагает &amp;lt;math&amp;gt;k*n&amp;lt;/math&amp;gt; вычислений расстояний между d-мерными векторами. &lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;&amp;lt;i&amp;gt;Пересчет центров кластеров&amp;lt;/i&amp;gt;&amp;lt;/b&amp;gt; предполагает &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; вычислений центров масс &amp;lt;math&amp;gt;\mathbf{\mu}_i&amp;lt;/math&amp;gt; множеств &amp;lt;math&amp;gt;S_i, i=\overline{1,k}&amp;lt;/math&amp;gt; представленных выражением в шаге 3 представленного выше алгоритма.&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Макроструктура алгоритма ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Инициализация центров масс &amp;lt;math&amp;gt;\mu_1, ..., \mu_k&amp;lt;/math&amp;gt;&amp;lt;/b&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
Наиболее распространенными являются следующие стратегии:&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&lt;br /&gt;
    &amp;lt;b&amp;gt;Метод Forgy&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;В качестве начальных значений &amp;lt;math&amp;gt;\mu_1, ..., \mu_k&amp;lt;/math&amp;gt; берутся случайно выбранные векторы.&lt;br /&gt;
  &amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&lt;br /&gt;
    &amp;lt;b&amp;gt;Метод случайно разделения (Random Partitioning)&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;Для каждого вектора &amp;lt;math&amp;gt;\mathbf{x}_i \in X, i=\overline{1, n}&amp;lt;/math&amp;gt; выбирается случайным образом кластер &amp;lt;math&amp;gt;S_1, ..., S_k&amp;lt;/math&amp;gt;, после чего для каждого полученного кластера вычисляются значения &amp;lt;math&amp;gt;\mu_1, ..., \mu_k&amp;lt;/math&amp;gt;.&lt;br /&gt;
  &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Распределение векторов по кластерам&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Для этого шага алгоритма между векторами &amp;lt;math&amp;gt;\mathbf{x}_i \in X, i=\overline{1, n}&amp;lt;/math&amp;gt; и центрами кластеров &amp;lt;math&amp;gt;\mu_1, ..., \mu_k&amp;lt;/math&amp;gt; вычисляются &amp;lt;b&amp;gt;расстояния&amp;lt;/b&amp;gt; по формуле (как правило, используется Евлидово расстояние):&lt;br /&gt;
&amp;lt;table style=&amp;quot;width:100%&amp;quot;&amp;gt;&lt;br /&gt;
  &amp;lt;tr&amp;gt;&lt;br /&gt;
    &amp;lt;td align=&amp;quot;center&amp;quot; width=&amp;quot;90%&amp;quot;&amp;gt;&amp;lt;math&amp;gt; \mathbf{v}_1, \mathbf{v}_2 \in \mathbb{R}^d,  \quad \rho(\mathbf{v}_1, \mathbf{v}_2) = \lVert \mathbf{v}_1- \mathbf{v}_2 \rVert= \sqrt{\sum_{i=1}^{d}(\mathbf{v}_{1,i} - \mathbf{v}_{2,i})^2}&amp;lt;/math&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;td align=&amp;quot;right&amp;quot;&amp;gt;&amp;lt;math&amp;gt;(2)&amp;lt;/math&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;/table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Пересчет центров кластеров&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Для этого шага алгоритма производится пересчет центров кластера по &amp;lt;b&amp;gt;формуле вычисления центра масс&amp;lt;/b&amp;gt;:&lt;br /&gt;
&amp;lt;table style=&amp;quot;width:100%&amp;quot;&amp;gt;&lt;br /&gt;
  &amp;lt;tr&amp;gt;&lt;br /&gt;
    &amp;lt;td align=&amp;quot;center&amp;quot; width=&amp;quot;90%&amp;quot;&amp;gt;&amp;lt;math&amp;gt; \mu = \cfrac{1}{|S|}\sum_{\mathbf{x}\in S}\mathbf{x}&amp;lt;/math&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;td align=&amp;quot;right&amp;quot;&amp;gt;&amp;lt;math&amp;gt;(3)&amp;lt;/math&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;/table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Схема реализации последовательного алгоритма ===&lt;br /&gt;
&lt;br /&gt;
 &#039;&#039;&#039;algorithm&#039;&#039;&#039; k-means &#039;&#039;&#039;is&#039;&#039;&#039;&lt;br /&gt;
     &#039;&#039;&#039;1.&#039;&#039;&#039; Инициализировать центры кластеров &amp;lt;math&amp;gt;\mathbf{\mu}_i^{(1)}, i=\overline{1,k}&amp;lt;/math&amp;gt;&lt;br /&gt;
     &#039;&#039;&#039;2.&#039;&#039;&#039; &amp;lt;math&amp;gt;t \leftarrow 1&amp;lt;/math&amp;gt;&lt;br /&gt;
     &#039;&#039;&#039;3.&#039;&#039;&#039; &#039;&#039;&#039;Распределение по кластерам&#039;&#039;&#039;&amp;lt;br&amp;gt;&lt;br /&gt;
        &amp;lt;math&amp;gt;S_i^{(t)}=\{\mathbf{x}_p: \lVert\mathbf{x}_p-\mathbf{\mu}_i^{(t)}\rVert^2 \leq \lVert\mathbf{x}_p-\mathbf{\mu}_j^{(t)}\rVert^2 \quad \forall j=\overline{1,k}\},&amp;lt;/math&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
        где каждый вектор &amp;lt;math&amp;gt;\mathbf{x}_p&amp;lt;/math&amp;gt; соотносится единственному кластеру &amp;lt;math&amp;gt;S^{(t)}&amp;lt;/math&amp;gt;&lt;br /&gt;
     &#039;&#039;&#039;4.&#039;&#039;&#039; &#039;&#039;&#039;Обновление центров кластеров&#039;&#039;&#039;&amp;lt;br&amp;gt;&lt;br /&gt;
        &amp;lt;math&amp;gt;\mathbf{\mu}_i^{(t+1)} = \frac{1}{|S^{(t)}_i|} \sum_{\mathbf{x}_j \in S^{(t)}_i} \mathbf{x}_j &amp;lt;/math&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
     &#039;&#039;&#039;5.&#039;&#039;&#039; &#039;&#039;&#039;if&#039;&#039;&#039; &amp;lt;math&amp;gt;\exist i \in \overline{1,k}: \mathbf{\mu}_i^{(t+1)} \ne \mathbf{\mu}_i^{(t)}&amp;lt;/math&amp;gt; &#039;&#039;&#039;then&#039;&#039;&#039;&lt;br /&gt;
            t = t + 1;&lt;br /&gt;
            goto &#039;&#039;&#039;3&#039;&#039;&#039;;&lt;br /&gt;
        &#039;&#039;&#039;else&#039;&#039;&#039;&lt;br /&gt;
            &#039;&#039;&#039;stop&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
=== Последовательная сложность алгоритма===&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding-bottom: 20px&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;Обозначим &amp;lt;math&amp;gt;\Theta_{centroid}^{d, m}&amp;lt;/math&amp;gt; временную сложность вычисления центорида кластера, число элементов которого равна &amp;lt;math&amp;gt;m&amp;lt;/math&amp;gt;,  в d-мерном пространстве.&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;Аналогично  &amp;lt;math&amp;gt;\Theta_{distance}^d&amp;lt;/math&amp;gt; &amp;amp;ndash; временная сложность вычисления расстояния между двумя d-мерными векторами.&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding-bottom: 20px&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;Сложность шага инициализации &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластеров мощности &amp;lt;math&amp;gt;m&amp;lt;/math&amp;gt; в d-мерном пространстве &amp;amp;ndash; &amp;lt;math&amp;gt;\Theta_{init}^{k, d, m}&amp;lt;/math&amp;gt;&amp;lt;/b&amp;gt;&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;i&amp;gt;Стратерия Forgy&amp;lt;/i&amp;gt;: вычисления не требуются, &amp;lt;math&amp;gt;\Theta_{init}^{k, d, m} = 0&amp;lt;/math&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;i&amp;gt;Стратегия случайного разбиения&amp;lt;/i&amp;gt;: вычисление центров &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластеров,  &amp;lt;math&amp;gt;\Theta_{init}^{k, d, m} = k*\Theta_{centroid}^{d, m}, m \le n&amp;lt;/math&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding-bottom: 20px&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Cложность шага распределения d мерных векторов по &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластерам &amp;amp;ndash; &amp;lt;math&amp;gt;\Theta_{distribute}^{k, d}&amp;lt;/math&amp;gt;&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
На этом шаге для каждого вектора &amp;lt;math&amp;gt;\mathbf{x}_i \in X, i=\overline{1, n}&amp;lt;/math&amp;gt; вычисляется k расстояний до центров кластеров &amp;lt;math&amp;gt;\mathbf{\mu}_1, ...\mathbf{\mu}_k&amp;lt;/math&amp;gt;&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p align=&amp;quot;center&amp;quot;&amp;gt;&lt;br /&gt;
  &amp;lt;math&amp;gt;\Theta_{distribute}^{k, d} = n*k*\Theta_{distance}^d&amp;lt;/math&amp;gt;&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding-bottom: 20px&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;Сложность шага пересчета центров &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластеров размера &amp;lt;math&amp;gt;m&amp;lt;/math&amp;gt; в d-мерном пространстве &amp;amp;ndash; &amp;lt;math&amp;gt;\Theta_{recenter}^{k, d, m}&amp;lt;/math&amp;gt;&amp;lt;/b&amp;gt;&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;На этом шаге вычисляется &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; центров кластеров &amp;lt;math&amp;gt;\mathbf{\mu}_1, ...\mathbf{\mu}_k&amp;lt;/math&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p align=&amp;quot;center&amp;quot;&amp;gt;&amp;lt;math&amp;gt;\Theta_{recenter}^{k, d, m} = k*\Theta_{centroid}^{d, m}&amp;lt;/math&amp;gt; &amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding-bottom: 20px&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Рассчитаем &amp;lt;math&amp;gt;\Theta_{centroid}^{d, m}&amp;lt;/math&amp;gt; для кластера, число элементов которого равно &amp;lt;math&amp;gt;m&amp;lt;/math&amp;gt;&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p align=&amp;quot;center&amp;quot;&amp;gt;&amp;lt;math&amp;gt;\Theta_{centroid}^{d, m}&amp;lt;/math&amp;gt; = &amp;lt;math&amp;gt;m * d&amp;lt;/math&amp;gt; сложений + &amp;lt;math&amp;gt;d&amp;lt;/math&amp;gt; делений &amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding-bottom: 20px&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Рассчитаем &amp;lt;math&amp;gt;\Theta_{distance}^d&amp;lt;/math&amp;gt; в соответствие с формулой &amp;lt;math&amp;gt;(2)&amp;lt;/math&amp;gt;&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p align=&amp;quot;center&amp;quot;&amp;gt;&amp;lt;math&amp;gt;\Theta_{distance}^d&amp;lt;/math&amp;gt; = &amp;lt;math&amp;gt;d&amp;lt;/math&amp;gt; вычитаний + &amp;lt;math&amp;gt;d&amp;lt;/math&amp;gt; умножений + &amp;lt;math&amp;gt;(d-1)&amp;lt;/math&amp;gt; сложение&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding-bottom: 20px&amp;quot;&amp;gt;&lt;br /&gt;
  &amp;lt;p&amp;gt;Предположим, что алгоритм сошелся за &amp;lt;math&amp;gt;\Tau&amp;lt;/math&amp;gt; итераций, тогда временная сложность алгоритма &amp;lt;math&amp;gt;\Theta_{k-means}^{d, n}&amp;lt;/math&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
  &amp;lt;p align=&amp;quot;center&amp;quot;&amp;gt;&amp;lt;b&amp;gt;&amp;lt;math&amp;gt;\Theta_{k-means}^{d, n} \le \Theta_{init}^{k, d, n} + \Tau*(\Theta_{distribute}^{k, d} + \Theta_{recenter}^{k, d, n})&amp;lt;/math&amp;gt;&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding-bottom: 5px&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;Операции сложения/вычитания:&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p align=&amp;quot;center&amp;quot;&amp;gt;&amp;lt;b&amp;gt;&amp;lt;math&amp;gt;\Theta_{k-means}^{d, n} \le k*n*d+ \Tau*(k*n*(2d-1) + k*n*d) = k*n*d+ \Tau*(k*n*(3d-1)) \thicksim O(\Tau*k*d*n)&amp;lt;/math&amp;gt;&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding-bottom: 20px&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;Операции умножения/деления:&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p align=&amp;quot;center&amp;quot;&amp;gt;&amp;lt;b&amp;gt;&amp;lt;math&amp;gt;\Theta_{k-means}^{d, n} \le k*d + \Tau*(k*n*d + k*d) = k*d + \Tau * k*d*(n+1) \thicksim O(\Tau*k*d*n) &amp;lt;/math&amp;gt;&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding-bottom: 20px&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;Получаем, что &amp;lt;b&amp;gt;временная сложность&amp;lt;/b&amp;gt; алгоритма &amp;lt;b&amp;gt;k means&amp;lt;/b&amp;gt; кластеризации &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; &amp;lt;b&amp;gt;d-мерных&amp;lt;/b&amp;gt; векторов на &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластеров за &amp;lt;math&amp;gt;\Tau&amp;lt;/math&amp;gt; итераций:&amp;lt;/p&amp;gt;&lt;br /&gt;
 &amp;lt;p align=&amp;quot;center&amp;quot;&amp;gt;&amp;lt;b&amp;gt;&amp;lt;math&amp;gt; \Theta_{k-means}^{d, n} \thicksim O(\Tau*k*d*n) &amp;lt;/math&amp;gt;&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Информационный граф ===&lt;br /&gt;
&lt;br /&gt;
Рассмотрим информационный граф алгоритма. Алгоритм &amp;lt;i&amp;gt;k means&amp;lt;/i&amp;gt; начинается с этапа инициализации, после которого следуют итерации, на каждой из которых выполняется два последовательных шага (см. [[#Схема реализации последовательного алгоритма|&amp;quot;Схема реализации последовательного алгоритма&amp;quot;]]): &lt;br /&gt;
* распределение векторов по кластерам&lt;br /&gt;
* перерасчет центров кластеров&lt;br /&gt;
&lt;br /&gt;
Поскольку основная часть вычислений приходится на шаги итераций, распишем информационные графы данных шагов.&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Распределение векторов по кластерам&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
Информационный граф шага распределения векторов по кластерам представлен на &#039;&#039;рисунке 1&#039;&#039;. Исходами данного графа является исходные векторы &amp;lt;math&amp;gt;\mathbf{x}_1, ..., \mathbf{x}_n&amp;lt;/math&amp;gt;, а также центры кластеров &amp;lt;math&amp;gt;\mathbf{\mu}_1, ... \mathbf{\mu}_k&amp;lt;/math&amp;gt;, вычисленные ранее (на шаге инициализации, если рассматривается первая итерация алгоритма, или на шаге пересчета центров кластеров предыдущей итерации в противном случае). Каждая пара векторов данных &amp;lt;math&amp;gt;\mathbf{x}_i, i=\overline{1,n}&amp;lt;/math&amp;gt; и центров кластера &amp;lt;math&amp;gt;\mathbf{\mu}_j, j=\overline{1, k}&amp;lt;/math&amp;gt; : (&amp;lt;math&amp;gt;\mathbf{x}_i&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;\mathbf{\mu}_j&amp;lt;/math&amp;gt;) подаются на независимые узлы &amp;lt;i&amp;gt;&amp;quot;d&amp;quot;&amp;lt;/i&amp;gt; вычисления расстояния между векторами (более подробная схема вычисления расстояния представлена далее, &#039;&#039;рисунок 2&#039;&#039;). Далее узлы вычисления расстояния &amp;lt;i&amp;gt;&amp;quot;d&amp;quot;&amp;lt;/i&amp;gt;, соответствующие одному и тому же исходному вектору &amp;lt;math&amp;gt;\mathbf{x}_i&amp;lt;/math&amp;gt; передаются на один узел &amp;lt;i&amp;gt;&amp;quot;m&amp;quot;&amp;lt;/i&amp;gt;, где далее происходит вычисление новой метки кластера для каждого вектора &amp;lt;math&amp;gt;\mathbf{x}_i&amp;lt;/math&amp;gt; (берется кластер с минимальным результатом вычисления расстояния). На выходе графа выдаются метки кластеров , &amp;lt;math&amp;gt;L_1, ..., L_n&amp;lt;/math&amp;gt;, такие что &amp;lt;math&amp;gt;\forall \mathbf{x}_i, i=\overline{1, n}, \mathbf{x}_i \in S_j \Leftrightarrow L_i = j&amp;lt;/math&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
[[file:Clusterization.png|thumb|center|800px|Рис. 1. Схема распределения векторов по кластерам. &#039;&#039;d&#039;&#039; &amp;amp;ndash; вычисление расстояния между векторами; &#039;&#039;m&#039;&#039; &amp;amp;ndash; вычисление минимума.]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Вычисление расстояния между векторами&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
Подробная схема вычисления расстояния между векторами &amp;lt;math&amp;gt;\mathbf{x}_i, \mathbf{\mu}_j&amp;lt;/math&amp;gt; представлена на &#039;&#039;рисунке 2&#039;&#039;. Как показано на графе, узел вычисления расстояния между векторами &amp;lt;i&amp;gt;&amp;quot;d&amp;quot;&amp;lt;/i&amp;gt; состоит из шага взятия разности между векторами (узел &amp;quot;&amp;lt;math&amp;gt;-&amp;lt;/math&amp;gt;&amp;quot;) и взятия нормы получившегося вектора разности (узел &amp;quot;&amp;lt;math&amp;gt;||\cdot||^2&amp;lt;/math&amp;gt;&amp;quot;). Более подробно, вычисление расстояния между векторами &amp;lt;math&amp;gt;\mathbf{x}_i = {x_{i1,}, ...,{x_{in}}}, \mathbf{\mu}_j = {\mu_{j1}, ...,\mu_{jn}}&amp;lt;/math&amp;gt; может быть представлено как вычисление разности между каждой парой компонент &amp;lt;math&amp;gt;(x_{iz}, \mu_{jz}), z=\overline{1, d}&amp;lt;/math&amp;gt; (узел &amp;quot;&amp;lt;math&amp;gt;-&amp;lt;/math&amp;gt;&amp;quot;), далее возведение в квадрат для каждого узла &amp;quot;&amp;lt;math&amp;gt;-&amp;lt;/math&amp;gt;&amp;quot; (узел &amp;quot;&amp;lt;math&amp;gt;()^2&amp;lt;/math&amp;gt;&amp;quot;) и суммирования выходов всех узлов &amp;quot;&amp;lt;math&amp;gt;()^2&amp;lt;/math&amp;gt;&amp;quot; (узел &amp;quot;&amp;lt;math&amp;gt;+&amp;lt;/math&amp;gt;&amp;quot;).  &lt;br /&gt;
&lt;br /&gt;
[[file:dist_calc.png|thumb|center|800px|Рис. 2. Схема вычисления расстояния между вектором и центром кластера.]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Пересчет центров кластеров&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
Информационный граф шага пересчета центров кластеров представлен на &#039;&#039;рисунке 3&#039;&#039;. Исходами данного графа является исходные векторы &amp;lt;math&amp;gt;\mathbf{x}_1, ..., \mathbf{x}_n&amp;lt;/math&amp;gt;, а также им соответствующие метки кластера, &amp;lt;math&amp;gt;L_1, ..., L_n&amp;lt;/math&amp;gt;, такие что &amp;lt;math&amp;gt;\forall x_i, i=\overline{1, n}, \mathbf{x}_i \in S_j \Leftrightarrow L_i = j&amp;lt;/math&amp;gt;, вычисленные на этапе распределения векторов по кластерам. Все векторы &amp;lt;math&amp;gt;\mathbf{x}_1, ..., \mathbf{x}_n&amp;lt;/math&amp;gt; подаются в узлы &amp;lt;math&amp;gt;+_1, ...+_k&amp;lt;/math&amp;gt;, каждый узел &amp;lt;math&amp;gt;+_m, m = \overline{1,k}&amp;lt;/math&amp;gt; соответствует операции сложения векторов кластера с номером &amp;lt;math&amp;gt;m&amp;lt;/math&amp;gt;. Метки кластера &amp;lt;math&amp;gt;L_1, ..., L_n&amp;lt;/math&amp;gt; также совместно передаются на узлы &amp;lt;math&amp;gt;S_m, m = \overline{1,k}&amp;lt;/math&amp;gt;, на каждом из которых вычисляется количество векторов в соответствующем кластере (количество меток с соответствующим значением). Далее каждая пара выходов узлов &amp;lt;math&amp;gt;+_m&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;S_m&amp;lt;/math&amp;gt; подается на узел &amp;quot;&amp;lt;math&amp;gt;/&amp;lt;/math&amp;gt;&amp;quot;, где производится деление суммы векторов кластера на количество элементов в нем. Значения, вычисленные на узлах &amp;quot;&amp;lt;math&amp;gt;/&amp;lt;/math&amp;gt;&amp;quot;, присваиваются новым центрам кластеров (выходные значения графа).&lt;br /&gt;
&lt;br /&gt;
[[file:Recluster.png|thumb|center|800px|Рис. 3. Схема пересчета центров кластеров]]&lt;br /&gt;
&lt;br /&gt;
=== Ресурс параллелизма алгоритма ===&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
Работа алгоритма состоит из &amp;lt;math&amp;gt;\Tau&amp;lt;/math&amp;gt; итераций, в каждой из которых происходит &amp;lt;b&amp;gt;распределение d-мерных векторов по &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластерам&amp;lt;/b&amp;gt;, а также &amp;lt;b&amp;gt;пересчет центров кластеров в d-мерном пространстве&amp;lt;/b&amp;gt;. В шаге &amp;lt;b&amp;gt;распределения d-мерных векторов по &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластерам&amp;lt;/b&amp;gt; расстояния между вектором и центрами кластеров вычисляются независимо (отсутствуют информационные зависимости). &amp;lt;b&amp;gt;Центры масс кластеров&amp;lt;/b&amp;gt; также пересчитываются независимо друг от друга. Таким образом, имеет место [[глоссарий#Массовый параллелизм|&#039;&#039;массовый параллелизм&#039;&#039;]]. Вычислим параллельную сложность &amp;lt;math&amp;gt;\Psi_*&amp;lt;/math&amp;gt; каждого из шагов, а также параллельную сложность всего алгоритма, &amp;lt;math&amp;gt;\Psi_{k-means}&amp;lt;/math&amp;gt;. Будем исходить из предположения, что может быть использовано любое необходимое число потоков.&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Распределение d-мерных векторов по &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластерам&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;  &lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
Поскольку на данном шаге для каждой пары векторов &amp;lt;math&amp;gt;\mathbf{x}_i, i=\overline{1,n}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\mathbf{\mu}_j, j=\overline{1,k}&amp;lt;/math&amp;gt; операции вычисления расстояния не зависят друг от друга, они могут выполняться параллельно. Тогда, разделив все вычисление расстояний на &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; потоков, получим, что в каждом потоке будет выполняться только одна операция вычисления расстояния между векторами размерности d. При этом каждому вычислительному потоку передаются координаты центров всех кластеров &amp;lt;math&amp;gt;\mathbf{\mu}_1, ..., \mathbf{\mu}_k&amp;lt;/math&amp;gt;. Таким образом, параллельная сложность данного шага определяется &amp;lt;i&amp;gt; сложностью параллельной операции вычисления расстояния между d-мерными векторами&amp;lt;/i&amp;gt;, &amp;lt;math&amp;gt;\Psi_{distance}^d&amp;lt;/math&amp;gt;  и &amp;lt;i&amp;gt;сложностью определения наиболее близкого кластера&amp;lt;/i&amp;gt; (паралельное взятие минимума по расстояниям), &amp;lt;math&amp;gt;\Psi_{min}^k&amp;lt;/math&amp;gt;. Для оценки &amp;lt;math&amp;gt;\Psi_{distance}^d&amp;lt;/math&amp;gt; воспользуемся  [[Нахождение_частных_сумм_элементов_массива_сдваиванием | параллельной реализацией нахождения частичной суммы элементов массива путем сдваивания]]. Аналогично, &amp;lt;math&amp;gt;\Psi_{min}^k = log(k)&amp;lt;/math&amp;gt;. В результате, &amp;lt;math&amp;gt;\Psi_{distance}^d = O(log(d))&amp;lt;/math&amp;gt;.   Таким образом: &lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p align=&amp;quot;center&amp;quot;&amp;gt;&amp;lt;math&amp;gt;\Psi_{distribute}^{k, d}  = \Psi_{distance}^d + \Psi_{min}^k = O(log(d))+O(log(k)) = O(log(k*d))&amp;lt;/math&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Пересчет центров кластеров в d-мерном пространстве&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
Поскольку на данном шаге для каждого из &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластеров центр масс может быть вычислен независимо, данные операции могут быть выполнены в отдельных потоках. Таким образом, параллельная сложность данного шага, &amp;lt;math&amp;gt;\Psi_{recenter}^{k, d}&amp;lt;/math&amp;gt;,  будет определяться &amp;lt;i&amp;gt;параллельной сложностью вычисления одного центра масс кластера размера &amp;lt;math&amp;gt;m&amp;lt;/math&amp;gt;&amp;lt;/i&amp;gt;, &amp;lt;math&amp;gt;\Psi_{recenter}^{k, d}&amp;lt;/math&amp;gt;,  а так как &amp;lt;math&amp;gt;m \le n \Rightarrow \Psi_{recenter}^{d, m} \le \Psi_{recenter}^{d, n}&amp;lt;/math&amp;gt;. Сложность вычисления центра масс кластера d-мерных векторов размера n аналогично предыдущим вычислениям равна &amp;lt;math&amp;gt;O(log(n))&amp;lt;/math&amp;gt;. Тогда:  &lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p align=&amp;quot;center&amp;quot;&amp;gt;&amp;lt;math&amp;gt;\Psi_{recenter}^{k, d}  \le \Psi_{recenter}^{d, n} = O(log(n))&amp;lt;/math&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Общая параллельная сложность алгоритма&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
На каждой итерации необходимо обновление центров кластеров, которые будут использованы на следующей итерации. Таким образом, итерационный процесс выполняется последовательно&amp;lt;ref&amp;gt;Zhao, Weizhong, Huifang Ma, and Qing He. &amp;quot;Parallel k-means clustering based on mapreduce.&amp;quot; IEEE International Conference on Cloud Computing. Springer Berlin Heidelberg, 2009.&amp;lt;/ref&amp;gt;. Тогда, поскольку сложность каждой итерации  определяется &amp;lt;math&amp;gt;\Psi_{distribute}^{k, d}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\Psi_{recenter}&amp;lt;/math&amp;gt;, сложность всего алгоритма, &amp;lt;math&amp;gt;\Psi_{k-means}&amp;lt;/math&amp;gt; в предположении, что было сделано &amp;lt;math&amp;gt;\Tau&amp;lt;/math&amp;gt; операций определяется выражением&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p align=&amp;quot;center&amp;quot;&amp;gt;&amp;lt;math&amp;gt;\Psi_{k-means} \approx \Tau * (\Psi_{distribute}^{k, d} + \Psi_{recenter}^{k, d}) \le \Tau * O(log(k*d*n))&amp;lt;/math&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Входные и выходные данные алгоритма ===&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;Входные данные&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;Матрица из &amp;lt;math&amp;gt;n*d&amp;lt;/math&amp;gt; элементов &amp;lt;math&amp;gt;x_{i, j} \in \mathbb{R}, i=\overline{1, n}, j=\overline{1, d}&amp;lt;/math&amp;gt;&amp;amp;ndash; координат векторов (наблюдений).&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;Целое положительное число &amp;lt;math&amp;gt;k, k \le n&amp;lt;/math&amp;gt; &amp;amp;ndash; количество кластеров.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;Объем входных данных&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;math&amp;gt;1&amp;lt;/math&amp;gt; целое число + &amp;lt;math&amp;gt;n*d&amp;lt;/math&amp;gt; вещественных чисел (при условии, что координаты &amp;amp;ndash; вещественные числа).&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;Выходные данные&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; целых положительных чисел &amp;lt;math&amp;gt;L_1, ..., L_n&amp;lt;/math&amp;gt;&amp;amp;ndash; номера кластеров, соотвествующие каждому вектору (при условии, что нумерация кластеров начинается с &amp;lt;math&amp;gt;1&amp;lt;/math&amp;gt;).&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;Объем выходных данных&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; целых положительных чисел.&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Свойства алгоритма ===&lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;[[глоссарий#Вычислительная мощность|&#039;&#039;Вычислительная мощность&#039;&#039;]]&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
Вычислительная мощность алгоритма &amp;lt;i&amp;gt;k means&amp;lt;/i&amp;gt; равна &amp;lt;math&amp;gt;\frac{k*d*n*\Tau}{n*d} = k*\Tau &amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; &amp;amp;ndash; число кластеров, &amp;lt;math&amp;gt;\Tau&amp;lt;/math&amp;gt; &amp;amp;ndash; число итераций алгоритма.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;[[глоссарий#Детерминированность |&#039;&#039;Детерминированность&#039;&#039;]] и [[глоссарий#Устойчивость |&#039;&#039;Устойчивость&#039;&#039;]] &amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
Алгоритм &amp;lt;i&amp;gt;k means&amp;lt;/i&amp;gt; является итерационным. Количество итераций алгоритма в общем случае не фиксируется и зависит от начального расположения объектов в пространстве, параметра &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt;, а также от начального приближения центров кластеров, &amp;lt;math&amp;gt;\mu_1, ..., \mu_k&amp;lt;/math&amp;gt;. В результате этого может варьироваться результат работы алгоритма. При неудачном выборе начальных параметров итерационный процесс может сойтись к локальному оптимуму&amp;lt;ref&amp;gt;Von Luxburg, Ulrike. Clustering Stability. Now Publishers Inc, 2010.&amp;lt;/ref&amp;gt;. По этим причинам алгоритм не является ни &amp;lt;b&amp;gt;детермирированным&amp;lt;/b&amp;gt;, ни &amp;lt;b&amp;gt;устойчивым&amp;lt;/b&amp;gt;.&lt;br /&gt;
 &lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Соотношение последовательной и параллельной сложности алгоритма&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\frac{\Theta_{k-means}}{\Psi_{k-means}} = \frac{O(\Tau*k*d*n)}{O(\Tau*log(k*d*n))}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Сильные стороны алгоритма&amp;lt;/b&amp;gt;:&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;i&amp;gt;Сравнительно высокая эффективность при простоте реализации&amp;lt;/i&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;i&amp;gt;Высокое качество кластеризации&amp;lt;/i&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;i&amp;gt;Возможность распараллеливания&amp;lt;/i&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;i&amp;gt;Существование множества модификаций&amp;lt;/i&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;Недостатки алгоритма&amp;lt;/b&amp;gt;&amp;lt;ref&amp;gt;Ortega, Joaquín Pérez, Ma Del Rocío Boone Rojas, and María J. Somodevilla. &amp;quot;Research issues on K-means Algorithm: An Experimental Trial Using Matlab.&amp;quot;&amp;lt;/ref&amp;gt;:&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;i&amp;gt;Количество кластеров является параметром алгоритма&amp;lt;/i&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;&amp;lt;i&amp;gt;Чувствительность к начальным условиям&amp;lt;/i&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;Инициализация центров кластеров в значительной степени влияет на результат кластеризации.&amp;lt;/p&amp;gt;&lt;br /&gt;
  &amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;&amp;lt;i&amp;gt;Чувствительность к выбросам и шумам&amp;lt;/i&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;Выбросы, далекие от центров настоящих кластеров, все равно учитываются при вычислении их центров.&amp;lt;/p&amp;gt;&lt;br /&gt;
  &amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;&amp;lt;i&amp;gt;Возможность сходимости к локальному оптимуму&amp;lt;/i&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;Итеративный подход не дает гарантии сходимости к оптимальному решению.&amp;lt;/p&amp;gt;&lt;br /&gt;
  &amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;&amp;lt;i&amp;gt;Использование понятия &amp;quot;среднего&amp;quot;&amp;lt;/i&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;Алгоритм неприменим к данным, для которых не определено понятие &amp;quot;среднего&amp;quot;, например, категориальным данным.&amp;lt;/p&amp;gt;&lt;br /&gt;
  &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&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;
Исследование масштабируемости параллельной реализации алгоритма k means проводилось на суперкомпьютере &amp;quot;Ломоносов&amp;quot;. Алгоритм реализован на языке C с использованием средств MPI.&lt;br /&gt;
Для исследования масштабируемости проводилось множество запусков программы с разным значением параметра (количество векторов для кластеризации), а также с различным числом процессоров. Фиксировались результаты запусков &amp;amp;ndash; время работы &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt; и количество произведенных итераций алгоритма &amp;lt;math&amp;gt;\Tau&amp;lt;/math&amp;gt;.&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;Значения &amp;lt;b&amp;gt;количества векторов&amp;lt;/b&amp;gt; &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;: 20&#039;000, 30&#039;000, 50&#039;000, 100&#039;000, 200&#039;000, 300&#039;000, 500&#039;000, 700&#039;000, 1&#039;000&#039;000, 1&#039;500&#039;000, 2&#039;000&#039;000.&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;Значения &amp;lt;b&amp;gt;количества процессоров&amp;lt;/b&amp;gt; &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt;: 1, 8, 16, 32, 64, 128, 160, 192, 224, 256, 288, 320, 352, 384, 416, 448, 480, 512.&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;Значение &amp;lt;b&amp;gt;количества кластеров&amp;lt;/b&amp;gt; &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt;: 100.&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;Значение &amp;lt;b&amp;gt;размерности векторов&amp;lt;/b&amp;gt; &amp;lt;math&amp;gt;d&amp;lt;/math&amp;gt;: 10.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Графики производительности и эффективности реализации представлены на рисунках 4 и 5 соответственно.&lt;br /&gt;
&lt;br /&gt;
[[file:Flops.png|thumb|center|800px|Рис. 4. График производительности реализации алгоритма.]]&lt;br /&gt;
&lt;br /&gt;
[[file:Efficiency.png|thumb|center|800px|Рис. 5. График эффективности реализации алгоритма.]]&lt;br /&gt;
&lt;br /&gt;
Для заданной конфигурации эксперимента (&amp;lt;math&amp;gt;n, d, p, k&amp;lt;/math&amp;gt;) и полученных результатах (&amp;lt;math&amp;gt;t, \Tau&amp;lt;/math&amp;gt;) производительность и эффективность реализации расчитывались по формулам (см. [[#Последовательная сложность алгоритма| последовательная сложность алгоритма]]):&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
&amp;lt;ul&amp;gt;&amp;lt;li&amp;gt;&amp;lt;math&amp;gt;Performance = \frac{\Theta_{k-means}^{d, n}}{t}\ \ FLOPS&amp;lt;/math&amp;gt;&amp;lt;/li&amp;gt;&amp;lt;/ul&amp;gt;&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
&amp;lt;ul&amp;gt;&amp;lt;li&amp;gt;&amp;lt;math&amp;gt;Efficiency = \frac{100 * Performance}{Performance_{Peak}^{p}}\ \ %,&amp;lt;/math&amp;gt;&amp;lt;/li&amp;gt;&amp;lt;/ul&amp;gt;&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
где &amp;lt;math&amp;gt;Performance_{Peak}^{p}&amp;lt;/math&amp;gt; &amp;amp;ndash; пиковая производительность суперкомпьютера при &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt; процессорах, вычисленная согласно спецификациям Intel&amp;amp;reg; XEON&amp;amp;reg; X5670&amp;lt;ref&amp;gt;&amp;quot;http://ark.intel.com/ru/products/47920/Intel-Xeon-Processor-X5670-12M-Cache-2_93-GHz-6_40-GTs-Intel-QPI&amp;quot;&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
В результате экспериментальной оценки были получены следующие оценки эффективности реализации:&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;b&amp;gt;Минимальное&amp;lt;/b&amp;gt; значение: 0.000409 %&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;b&amp;gt;Максимальное&amp;lt;/b&amp;gt; значение: 0.741119 %&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Динамические характеристики и эффективность реализации алгоритма ===&lt;br /&gt;
=== Выводы для классов архитектур ===&lt;br /&gt;
=== Существующие реализации алгоритма ===&lt;br /&gt;
==== Открытое программное обеспечение ====&lt;br /&gt;
&amp;lt;ol&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;[https://www.icpsr.umich.edu/CrimeStat/ CrimeStat]&amp;lt;/li&amp;gt; Программное обеспечение, созданное для операционных систем Windows, предоставляющее инструменты статистического  и пространственного анализа для решения задачи картирования преступности.&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://juliastats.github.io Julia]&amp;lt;/li&amp;gt; Высокоуровневый высокопроизводительный свободный язык программирования с динамической типизацией, созданный для математических вычислений, содержит реализацию k-means.&lt;br /&gt;
  &amp;lt;li&amp;gt;[https://mahout.apache.org Mahout]&amp;lt;/li&amp;gt; Apache Mahout - Java библиотека для работы с алгоритмами машинного обучения с использованием MapReduce. Содержит реализацию k-means.&lt;br /&gt;
  &amp;lt;li&amp;gt;[https://www.gnu.org/software/octave/ Octave]&amp;lt;/li&amp;gt; Написанная на C++  свободная система для математических вычислений, использующая совместимый с MATLAB язык высокого уровня, содержит реализацию k-means.&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://spark.apache.org/docs/latest/mllib-clustering.html Spark]&amp;lt;/li&amp;gt; Распределенная реализация k-means содержится в библиотеке Mlib для работы с алгоритмами машинного обучения, взаимодействующая с Python библиотекой NumPy и библиотека R.&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://torch.ch Torch]&amp;lt;/li&amp;gt;  MATLAB-подобная библиотека для языка программирования Lua с открытым исходным кодом, предоставляет большое количество алгоритмов для глубинного обучения и научных расчётов. Ядро написано на Си, прикладная часть выполняется на LuaJIT, поддерживается распараллеливание вычислений средствами CUDA и OpenMP. Существуют реализации k-means.&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://www.cs.waikato.ac.nz/ml/weka/ Weka]&amp;lt;/li&amp;gt;  Cвободное программное обеспечение для анализа данных, написанное на Java. Содержит k-means и x-means.&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://accord-framework.net/docs/html/T_Accord_MachineLearning_KMeans.htm Accord.NET]&amp;lt;/li&amp;gt; C# реализация алгоритмов k-means, k-means++, k-modes.&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://docs.opencv.org/3.0-beta/doc/py_tutorials/py_ml/py_kmeans/py_kmeans_opencv/py_kmeans_opencv.html OpenCV]&amp;lt;/li&amp;gt; Написанная на С++ библиотека, направленная в основном на решение задач компьютерного зрения. Содержит реализацию k-means.&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://mlpack.org/ MLPACK]&amp;lt;/li&amp;gt; Масштабируемая С++ библиотека для работы с алгоритмами машинного обучения, содержит реализацию k-means.&lt;br /&gt;
  &amp;lt;li&amp;gt;[https://www.scipy.org/ SciPy]&amp;lt;/li&amp;gt; Библиотека Python, содержит множество реализаций k-means.&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://scikit-learn.org/ scikit-learn]&amp;lt;/li&amp;gt; Библиотека Python, содержит множество реализаций k-means.&lt;br /&gt;
  &amp;lt;li&amp;gt;[https://www.r-bloggers.com/k-means-clustering-in-r/ R]&amp;lt;/li&amp;gt; Язык программирования для статистической обработки данных и работы с графикой, а также свободная программная среда вычислений с открытым исходным кодом в рамках проекта GNU, содержит три реализации k-means.&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://elki.dbs.ifi.lmu.de ELKI]&amp;lt;/li&amp;gt; Java фреймворк, содержащий реализацию k-means, а также множество других алгоритмов кластеризации.&lt;br /&gt;
&amp;lt;/ol&amp;gt;&lt;br /&gt;
==== Проприетарное программное обеспечение  ====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ol&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;[https://www.ayasdi.com/blog/bigdata/topological-data-analysis-of-oil-and-gas-petrophysical-data/ Ayasdi]&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://www.stata.com/features/cluster-analysis/ Stata]&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://mathworld.wolfram.com/K-MeansClusteringAlgorithm.html Mathematica]&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://www.mathworks.com/help/stats/kmeans.html?requestedDomain=www.mathworks.com MATLAB]&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;[https://support.sas.com/rnd/app/stat/procedures/fastclus.html SAS]&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://docs.rapidminer.com/studio/operators/modeling/segmentation/k_means.html RapidMiner]&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;[https://blogs.sap.com/2013/03/28/sap-hana-pal-k-means-algorithm-or-how-to-do-customer-segmentation-for-the-telecommunications-industry/ SAP HANA]&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ol&amp;gt;&lt;br /&gt;
== Литература ==&lt;br /&gt;
&amp;lt;references /&amp;gt;&lt;/div&gt;</summary>
		<author><name>DennZo1993</name></author>
	</entry>
	<entry>
		<id>https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:%D0%91%D1%80%D0%BE%D1%82%D0%B8%D0%BA%D0%BE%D0%B2%D1%81%D0%BA%D0%B0%D1%8F_%D0%94%D0%B0%D0%BD%D1%83%D1%82%D0%B0/%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_k-means&amp;diff=17170</id>
		<title>Участник:Бротиковская Данута/Алгоритм k-means</title>
		<link rel="alternate" type="text/html" href="https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:%D0%91%D1%80%D0%BE%D1%82%D0%B8%D0%BA%D0%BE%D0%B2%D1%81%D0%BA%D0%B0%D1%8F_%D0%94%D0%B0%D0%BD%D1%83%D1%82%D0%B0/%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_k-means&amp;diff=17170"/>
		<updated>2016-11-14T23:52:25Z</updated>

		<summary type="html">&lt;p&gt;DennZo1993: /* Масштабируемость реализации алгоритма */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt; {{Assignment|Zhum}}&lt;br /&gt;
&lt;br /&gt;
{{algorithm&lt;br /&gt;
| name              = Алгоритм k средних (k means)&lt;br /&gt;
| serial_complexity = &amp;lt;math&amp;gt;O(\Tau*k*d*n)&amp;lt;/math&amp;gt;&lt;br /&gt;
| input_data        = &amp;lt;math&amp;gt; d*n &amp;lt;/math&amp;gt;&lt;br /&gt;
| output_data       = &amp;lt;math&amp;gt; n &amp;lt;/math&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
Авторы страницы &amp;lt;b&amp;gt;[[Участник:Бротиковская Данута|Данута Бротиковская]]&amp;lt;/b&amp;gt; и &amp;lt;b&amp;gt;[[Участник:DennZo1993|Денис Зобнин]]&amp;lt;/b&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
Оба автора внесли одинаковый вклад в написание статьи (поиск материалов, изучение статей, заполнение контента статьи), четких разграничений по пунктам статьи сделать невозможно. &lt;br /&gt;
&lt;br /&gt;
== Свойства и структура алгоритма ==&lt;br /&gt;
&lt;br /&gt;
=== Общее описание алгоритма ===&lt;br /&gt;
Алгоритм &amp;lt;b&amp;gt;&amp;lt;i&amp;gt;k средних&amp;lt;/i&amp;gt;&amp;lt;/b&amp;gt; (&amp;lt;b&amp;gt;&amp;lt;i&amp;gt;k means&amp;lt;/i&amp;gt;&amp;lt;/b&amp;gt;) &amp;amp;ndash; неиерархический&amp;lt;ref&amp;gt;&amp;quot;https://ru.wikipedia.org/wiki/Иерархическая_кластеризация&amp;quot;&amp;lt;/ref&amp;gt;, итерационный метод кластеризации&amp;lt;ref&amp;gt;&amp;quot;https://ru.wikipedia.org/wiki/Кластерный_анализ&amp;quot;&amp;lt;/ref&amp;gt;, получивший большую популярность благодаря своей простоте, наглядности реализации и достаточно высокому качеству работы. Был изобретен в 1950-х годах математиком &amp;lt;i&amp;gt;Гуго Штейнгаузом&amp;lt;/i&amp;gt;&amp;lt;ref&amp;gt;Steinhaus, Hugo. &amp;quot;Sur la division des corp materiels en parties.&amp;quot; Bull. Acad. Polon. Sci 1.804 (1956): 801.&amp;lt;/ref&amp;gt; и почти одновременно &amp;lt;i&amp;gt;Стюартом Ллойдом&amp;lt;/i&amp;gt;&amp;lt;ref&amp;gt;Lloyd, S. P. &amp;quot;Least square quantization in PCM. Bell Telephone Laboratories Paper. Published in journal much later: Lloyd, SP: Least squares quantization in PCM.&amp;quot; IEEE Trans. Inform. Theor.(1957/1982).&amp;lt;/ref&amp;gt;. Особую популярность приобрел после публикации работы &amp;lt;i&amp;gt;МакКуина&amp;lt;/i&amp;gt;&amp;lt;ref&amp;gt;MacQueen, James. &amp;quot;Some methods for classification and analysis of multivariate observations.&amp;quot; Proceedings of the fifth Berkeley symposium on mathematical statistics and probability. Vol. 1. No. 14. 1967.&amp;lt;/ref&amp;gt; в 1967.&lt;br /&gt;
&lt;br /&gt;
Алгоритм представляет собой версию EM-алгоритма&amp;lt;ref&amp;gt;&amp;quot;https://ru.wikipedia.org/wiki/EM-алгоритм&amp;quot;&amp;lt;/ref&amp;gt;, применяемого также для разделения смеси гауссиан. Основная идея &amp;lt;i&amp;gt;k means&amp;lt;/i&amp;gt; заключается в том, что данные произвольно разбиваются на кластеры, после чего итеративно перевычисляется центр масс для каждого кластера, полученного на предыдущем шаге, затем векторы разбиваются на кластеры вновь в соответствии с тем, какой из новых центров оказался ближе по выбранной метрике.&lt;br /&gt;
&lt;br /&gt;
Цель алгоритма заключается в разделении &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; наблюдений на &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластеров таким образом, чтобы каждое наблюдение принадлежало ровно одному кластеру, расположенному на наименьшем расстоянии от наблюдения.&lt;br /&gt;
&lt;br /&gt;
=== Математическое описание алгоритма ===&lt;br /&gt;
&amp;lt;b&amp;gt;&amp;lt;u&amp;gt;Дано:&amp;lt;/u&amp;gt;&amp;lt;/b&amp;gt;&lt;br /&gt;
* набор из &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; наблюдений &amp;lt;math&amp;gt;X=\{\mathbf{x}_1, \mathbf{x}_2, ..., \mathbf{x}_n\}, \mathbf{x}_i \in \mathbb{R}^d, i=\overline{1, n}&amp;lt;/math&amp;gt;;&lt;br /&gt;
* &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; - требуемое число кластеров, &amp;lt;math&amp;gt;k \in \mathbb{N}, k \leq n&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;&amp;lt;u&amp;gt;Требуется:&amp;lt;/u&amp;gt;&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Разделить множество наблюдений &amp;lt;math&amp;gt;X&amp;lt;/math&amp;gt; на &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластеров &amp;lt;math&amp;gt;S_1, S_2, ..., S_k&amp;lt;/math&amp;gt;:&lt;br /&gt;
*   &amp;lt;math&amp;gt;S_i \cap S_j= \varnothing, \quad i \ne j&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
*   &amp;lt;math&amp;gt;\bigcup_{i=1}^{k} S_i = X&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;&amp;lt;u&amp;gt;Действие алгоритма:&amp;lt;/u&amp;gt;&amp;lt;/b&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;Алгоритм &amp;lt;i&amp;gt;k means&amp;lt;/i&amp;gt; разбивает набор &amp;lt;math&amp;gt;X&amp;lt;/math&amp;gt; на &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; наборов &amp;lt;math&amp;gt;S_1, S_2, ..., S_k,&amp;lt;/math&amp;gt; таким образом, чтобы минимизировать сумму квадратов расстояний от каждой точки кластера до его центра (центр масс кластера). Введем обозначение, &amp;lt;math&amp;gt;S=\{S_1, S_2, ..., S_k\}&amp;lt;/math&amp;gt;. Тогда действие алгоритма &amp;lt;i&amp;gt;k means&amp;lt;/i&amp;gt; равносильно поиску:&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;table style=&amp;quot;width:100%&amp;quot;&amp;gt;&lt;br /&gt;
  &amp;lt;tr&amp;gt;&lt;br /&gt;
    &amp;lt;td align=&amp;quot;center&amp;quot; width=&amp;quot;90%&amp;quot;&amp;gt;&amp;lt;math&amp;gt;\arg\min_{S} \sum\limits_{i=1}^k \sum\limits_{\mathbf{x} \in S_i} \rho(\mathbf{x}, \mathbf{\mu}_i )^2,&amp;lt;/math&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;td align=&amp;quot;right&amp;quot;&amp;gt;&amp;lt;math&amp;gt;(1)&amp;lt;/math&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;/table&amp;gt;&lt;br /&gt;
где &amp;lt;math&amp;gt;\mathbf{\mu}_i&amp;lt;/math&amp;gt; &amp;amp;ndash; центры кластеров, &amp;lt;math&amp;gt;i=\overline{1,k}, \quad \rho(\mathbf{x}, \mathbf{\mu}_i)&amp;lt;/math&amp;gt; &amp;amp;ndash; функция расстояния между &amp;lt;math&amp;gt;\mathbf{x}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\mu_i&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;&amp;lt;u&amp;gt;Шаги алгоритма: &amp;lt;/u&amp;gt;&amp;lt;/b&amp;gt;&lt;br /&gt;
&amp;lt;ol&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&lt;br /&gt;
    &amp;lt;b&amp;gt;Начальный шаг: инициализация кластеров&amp;lt;/b&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;Выбирается произвольное множество точек &amp;lt;math&amp;gt;\mu_i, i=\overline{1,k}&amp;lt;/math&amp;gt;, рассматриваемых как начальные центры кластеров: &amp;lt;math&amp;gt;\mu_i^{(0)} = \mu_i, \quad i=\overline{1, k}&amp;lt;/math&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
  &amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&lt;br /&gt;
    &amp;lt;b&amp;gt;Распределение векторов по кластерам&amp;lt;/b&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Шаг&amp;lt;/b&amp;gt; &amp;lt;math&amp;gt;t: \forall \mathbf{x}_i \in X, i=\overline{1,n}: \mathbf{x}_i \in S_j \iff  j=\arg\min_{k}\rho(\mathbf{x}_i,\mathbf{\mu}_k^{(t-1)})^2&amp;lt;/math&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
  &amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&lt;br /&gt;
    &amp;lt;b&amp;gt;Пересчет центров кластеров&amp;lt;/b&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Шаг &amp;lt;/b&amp;gt; &amp;lt;math&amp;gt;t: \forall i=\overline{1,k}:  \mu_i^{(t)} = \cfrac{1}{|S_i|}\sum_{\mathbf{x}\in S_i}\mathbf{x}&amp;lt;/math&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
  &amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&lt;br /&gt;
    &amp;lt;b&amp;gt;Проверка условия останова:&amp;lt;/b&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
    &#039;&#039;&#039;if&#039;&#039;&#039; &amp;lt;math&amp;gt;\exist i\in \overline{1,k}: \mu_i^{(t)} \ne \mu_i^{(t-1)}&amp;lt;/math&amp;gt; &#039;&#039;&#039;then&#039;&#039;&#039;&lt;br /&gt;
        t = t + 1;&lt;br /&gt;
        goto 2;&lt;br /&gt;
    &#039;&#039;&#039;else&#039;&#039;&#039;&lt;br /&gt;
        &#039;&#039;&#039;stop&#039;&#039;&#039;&lt;br /&gt;
  &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ol&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Вычислительное ядро алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Вычислительным ядром являются шаги 2 и 3 приведенного выше алгоритма: &amp;lt;b&amp;gt;&amp;lt;i&amp;gt;распределение векторов по кластерам&amp;lt;/i&amp;gt;&amp;lt;/b&amp;gt; и &amp;lt;b&amp;gt;&amp;lt;i&amp;gt;пересчет центров кластеров&amp;lt;/i&amp;gt;&amp;lt;/b&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;&amp;lt;i&amp;gt;Распределение векторов&amp;lt;/i&amp;gt;&amp;lt;/b&amp;gt; по кластерам предполагает вычисление расстояний между каждым вектором &amp;lt;math&amp;gt;\mathbf{x}_i \in X, i= \overline{1,n}&amp;lt;/math&amp;gt; и центрами кластера &amp;lt;math&amp;gt;\mathbf{\mu}_j, j= \overline{1,k}&amp;lt;/math&amp;gt;. Таким образом, данный шаг предполагает &amp;lt;math&amp;gt;k*n&amp;lt;/math&amp;gt; вычислений расстояний между d-мерными векторами. &lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;&amp;lt;i&amp;gt;Пересчет центров кластеров&amp;lt;/i&amp;gt;&amp;lt;/b&amp;gt; предполагает &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; вычислений центров масс &amp;lt;math&amp;gt;\mathbf{\mu}_i&amp;lt;/math&amp;gt; множеств &amp;lt;math&amp;gt;S_i, i=\overline{1,k}&amp;lt;/math&amp;gt; представленных выражением в шаге 3 представленного выше алгоритма.&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Макроструктура алгоритма ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Инициализация центров масс &amp;lt;math&amp;gt;\mu_1, ..., \mu_k&amp;lt;/math&amp;gt;&amp;lt;/b&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
Наиболее распространенными являются следующие стратегии:&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&lt;br /&gt;
    &amp;lt;b&amp;gt;Метод Forgy&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;В качестве начальных значений &amp;lt;math&amp;gt;\mu_1, ..., \mu_k&amp;lt;/math&amp;gt; берутся случайно выбранные векторы.&lt;br /&gt;
  &amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&lt;br /&gt;
    &amp;lt;b&amp;gt;Метод случайно разделения (Random Partitioning)&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;Для каждого вектора &amp;lt;math&amp;gt;\mathbf{x}_i \in X, i=\overline{1, n}&amp;lt;/math&amp;gt; выбирается случайным образом кластер &amp;lt;math&amp;gt;S_1, ..., S_k&amp;lt;/math&amp;gt;, после чего для каждого полученного кластера вычисляются значения &amp;lt;math&amp;gt;\mu_1, ..., \mu_k&amp;lt;/math&amp;gt;.&lt;br /&gt;
  &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Распределение векторов по кластерам&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Для этого шага алгоритма между векторами &amp;lt;math&amp;gt;\mathbf{x}_i \in X, i=\overline{1, n}&amp;lt;/math&amp;gt; и центрами кластеров &amp;lt;math&amp;gt;\mu_1, ..., \mu_k&amp;lt;/math&amp;gt; вычисляются &amp;lt;b&amp;gt;расстояния&amp;lt;/b&amp;gt; по формуле (как правило, используется Евлидово расстояние):&lt;br /&gt;
&amp;lt;table style=&amp;quot;width:100%&amp;quot;&amp;gt;&lt;br /&gt;
  &amp;lt;tr&amp;gt;&lt;br /&gt;
    &amp;lt;td align=&amp;quot;center&amp;quot; width=&amp;quot;90%&amp;quot;&amp;gt;&amp;lt;math&amp;gt; \mathbf{v}_1, \mathbf{v}_2 \in \mathbb{R}^d,  \quad \rho(\mathbf{v}_1, \mathbf{v}_2) = \lVert \mathbf{v}_1- \mathbf{v}_2 \rVert= \sqrt{\sum_{i=1}^{d}(\mathbf{v}_{1,i} - \mathbf{v}_{2,i})^2}&amp;lt;/math&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;td align=&amp;quot;right&amp;quot;&amp;gt;&amp;lt;math&amp;gt;(2)&amp;lt;/math&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;/table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Пересчет центров кластеров&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Для этого шага алгоритма производится пересчет центров кластера по &amp;lt;b&amp;gt;формуле вычисления центра масс&amp;lt;/b&amp;gt;:&lt;br /&gt;
&amp;lt;table style=&amp;quot;width:100%&amp;quot;&amp;gt;&lt;br /&gt;
  &amp;lt;tr&amp;gt;&lt;br /&gt;
    &amp;lt;td align=&amp;quot;center&amp;quot; width=&amp;quot;90%&amp;quot;&amp;gt;&amp;lt;math&amp;gt; \mu = \cfrac{1}{|S|}\sum_{\mathbf{x}\in S}\mathbf{x}&amp;lt;/math&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;td align=&amp;quot;right&amp;quot;&amp;gt;&amp;lt;math&amp;gt;(3)&amp;lt;/math&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;/table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Схема реализации последовательного алгоритма ===&lt;br /&gt;
&lt;br /&gt;
 &#039;&#039;&#039;algorithm&#039;&#039;&#039; k-means &#039;&#039;&#039;is&#039;&#039;&#039;&lt;br /&gt;
     &#039;&#039;&#039;1.&#039;&#039;&#039; Инициализировать центры кластеров &amp;lt;math&amp;gt;\mathbf{\mu}_i^{(1)}, i=\overline{1,k}&amp;lt;/math&amp;gt;&lt;br /&gt;
     &#039;&#039;&#039;2.&#039;&#039;&#039; &amp;lt;math&amp;gt;t \leftarrow 1&amp;lt;/math&amp;gt;&lt;br /&gt;
     &#039;&#039;&#039;3.&#039;&#039;&#039; &#039;&#039;&#039;Распределение по кластерам&#039;&#039;&#039;&amp;lt;br&amp;gt;&lt;br /&gt;
        &amp;lt;math&amp;gt;S_i^{(t)}=\{\mathbf{x}_p: \lVert\mathbf{x}_p-\mathbf{\mu}_i^{(t)}\rVert^2 \leq \lVert\mathbf{x}_p-\mathbf{\mu}_j^{(t)}\rVert^2 \quad \forall j=\overline{1,k}\},&amp;lt;/math&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
        где каждый вектор &amp;lt;math&amp;gt;\mathbf{x}_p&amp;lt;/math&amp;gt; соотносится единственному кластеру &amp;lt;math&amp;gt;S^{(t)}&amp;lt;/math&amp;gt;&lt;br /&gt;
     &#039;&#039;&#039;4.&#039;&#039;&#039; &#039;&#039;&#039;Обновление центров кластеров&#039;&#039;&#039;&amp;lt;br&amp;gt;&lt;br /&gt;
        &amp;lt;math&amp;gt;\mathbf{\mu}_i^{(t+1)} = \frac{1}{|S^{(t)}_i|} \sum_{\mathbf{x}_j \in S^{(t)}_i} \mathbf{x}_j &amp;lt;/math&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
     &#039;&#039;&#039;5.&#039;&#039;&#039; &#039;&#039;&#039;if&#039;&#039;&#039; &amp;lt;math&amp;gt;\exist i \in \overline{1,k}: \mathbf{\mu}_i^{(t+1)} \ne \mathbf{\mu}_i^{(t)}&amp;lt;/math&amp;gt; &#039;&#039;&#039;then&#039;&#039;&#039;&lt;br /&gt;
            t = t + 1;&lt;br /&gt;
            goto &#039;&#039;&#039;3&#039;&#039;&#039;;&lt;br /&gt;
        &#039;&#039;&#039;else&#039;&#039;&#039;&lt;br /&gt;
            &#039;&#039;&#039;stop&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
=== Последовательная сложность алгоритма===&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding-bottom: 20px&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;Обозначим &amp;lt;math&amp;gt;\Theta_{centroid}^{d, m}&amp;lt;/math&amp;gt; временную сложность вычисления центорида кластера, число элементов которого равна &amp;lt;math&amp;gt;m&amp;lt;/math&amp;gt;,  в d-мерном пространстве.&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;Аналогично  &amp;lt;math&amp;gt;\Theta_{distance}^d&amp;lt;/math&amp;gt; &amp;amp;ndash; временная сложность вычисления расстояния между двумя d-мерными векторами.&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding-bottom: 20px&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;Сложность шага инициализации &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластеров мощности &amp;lt;math&amp;gt;m&amp;lt;/math&amp;gt; в d-мерном пространстве &amp;amp;ndash; &amp;lt;math&amp;gt;\Theta_{init}^{k, d, m}&amp;lt;/math&amp;gt;&amp;lt;/b&amp;gt;&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;i&amp;gt;Стратерия Forgy&amp;lt;/i&amp;gt;: вычисления не требуются, &amp;lt;math&amp;gt;\Theta_{init}^{k, d, m} = 0&amp;lt;/math&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;i&amp;gt;Стратегия случайного разбиения&amp;lt;/i&amp;gt;: вычисление центров &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластеров,  &amp;lt;math&amp;gt;\Theta_{init}^{k, d, m} = k*\Theta_{centroid}^{d, m}, m \le n&amp;lt;/math&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding-bottom: 20px&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Cложность шага распределения d мерных векторов по &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластерам &amp;amp;ndash; &amp;lt;math&amp;gt;\Theta_{distribute}^{k, d}&amp;lt;/math&amp;gt;&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
На этом шаге для каждого вектора &amp;lt;math&amp;gt;\mathbf{x}_i \in X, i=\overline{1, n}&amp;lt;/math&amp;gt; вычисляется k расстояний до центров кластеров &amp;lt;math&amp;gt;\mathbf{\mu}_1, ...\mathbf{\mu}_k&amp;lt;/math&amp;gt;&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p align=&amp;quot;center&amp;quot;&amp;gt;&lt;br /&gt;
  &amp;lt;math&amp;gt;\Theta_{distribute}^{k, d} = n*k*\Theta_{distance}^d&amp;lt;/math&amp;gt;&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding-bottom: 20px&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;Сложность шага пересчета центров &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластеров размера &amp;lt;math&amp;gt;m&amp;lt;/math&amp;gt; в d-мерном пространстве &amp;amp;ndash; &amp;lt;math&amp;gt;\Theta_{recenter}^{k, d, m}&amp;lt;/math&amp;gt;&amp;lt;/b&amp;gt;&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;На этом шаге вычисляется &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; центров кластеров &amp;lt;math&amp;gt;\mathbf{\mu}_1, ...\mathbf{\mu}_k&amp;lt;/math&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p align=&amp;quot;center&amp;quot;&amp;gt;&amp;lt;math&amp;gt;\Theta_{recenter}^{k, d, m} = k*\Theta_{centroid}^{d, m}&amp;lt;/math&amp;gt; &amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding-bottom: 20px&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Рассчитаем &amp;lt;math&amp;gt;\Theta_{centroid}^{d, m}&amp;lt;/math&amp;gt; для кластера, число элементов которого равно &amp;lt;math&amp;gt;m&amp;lt;/math&amp;gt;&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p align=&amp;quot;center&amp;quot;&amp;gt;&amp;lt;math&amp;gt;\Theta_{centroid}^{d, m}&amp;lt;/math&amp;gt; = &amp;lt;math&amp;gt;m * d&amp;lt;/math&amp;gt; сложений + &amp;lt;math&amp;gt;d&amp;lt;/math&amp;gt; делений &amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding-bottom: 20px&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Рассчитаем &amp;lt;math&amp;gt;\Theta_{distance}^d&amp;lt;/math&amp;gt; в соответствие с формулой &amp;lt;math&amp;gt;(2)&amp;lt;/math&amp;gt;&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p align=&amp;quot;center&amp;quot;&amp;gt;&amp;lt;math&amp;gt;\Theta_{distance}^d&amp;lt;/math&amp;gt; = &amp;lt;math&amp;gt;d&amp;lt;/math&amp;gt; вычитаний + &amp;lt;math&amp;gt;d&amp;lt;/math&amp;gt; умножений + &amp;lt;math&amp;gt;(d-1)&amp;lt;/math&amp;gt; сложение&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding-bottom: 20px&amp;quot;&amp;gt;&lt;br /&gt;
  &amp;lt;p&amp;gt;Предположим, что алгоритм сошелся за &amp;lt;math&amp;gt;\Tau&amp;lt;/math&amp;gt; итераций, тогда временная сложность алгоритма &amp;lt;math&amp;gt;\Theta_{k-means}^{d, n}&amp;lt;/math&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
  &amp;lt;p align=&amp;quot;center&amp;quot;&amp;gt;&amp;lt;b&amp;gt;&amp;lt;math&amp;gt;\Theta_{k-means}^{d, n} \le \Theta_{init}^{k, d, n} + \Tau*(\Theta_{distribute}^{k, d} + \Theta_{recenter}^{k, d, n})&amp;lt;/math&amp;gt;&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding-bottom: 5px&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;Операции сложения/вычитания:&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p align=&amp;quot;center&amp;quot;&amp;gt;&amp;lt;b&amp;gt;&amp;lt;math&amp;gt;\Theta_{k-means}^{d, n} \le k*n*d+ \Tau*(k*n*(2d-1) + k*n*d) = k*n*d+ \Tau*(k*n*(3d-1)) \thicksim O(\Tau*k*d*n)&amp;lt;/math&amp;gt;&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding-bottom: 20px&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;Операции умножения/деления:&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p align=&amp;quot;center&amp;quot;&amp;gt;&amp;lt;b&amp;gt;&amp;lt;math&amp;gt;\Theta_{k-means}^{d, n} \le k*d + \Tau*(k*n*d + k*d) = k*d + \Tau * k*d*(n+1) \thicksim O(\Tau*k*d*n) &amp;lt;/math&amp;gt;&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding-bottom: 20px&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;Получаем, что &amp;lt;b&amp;gt;временная сложность&amp;lt;/b&amp;gt; алгоритма &amp;lt;b&amp;gt;k means&amp;lt;/b&amp;gt; кластеризации &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; &amp;lt;b&amp;gt;d-мерных&amp;lt;/b&amp;gt; векторов на &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластеров за &amp;lt;math&amp;gt;\Tau&amp;lt;/math&amp;gt; итераций:&amp;lt;/p&amp;gt;&lt;br /&gt;
 &amp;lt;p align=&amp;quot;center&amp;quot;&amp;gt;&amp;lt;b&amp;gt;&amp;lt;math&amp;gt; \Theta_{k-means}^{d, n} \thicksim O(\Tau*k*d*n) &amp;lt;/math&amp;gt;&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Информационный граф ===&lt;br /&gt;
&lt;br /&gt;
Рассмотрим информационный граф алгоритма. Алгоритм &amp;lt;i&amp;gt;k means&amp;lt;/i&amp;gt; начинается с этапа инициализации, после которого следуют итерации, на каждой из которых выполняется два последовательных шага (см. [[#Схема реализации последовательного алгоритма|&amp;quot;Схема реализации последовательного алгоритма&amp;quot;]]): &lt;br /&gt;
* распределение векторов по кластерам&lt;br /&gt;
* перерасчет центров кластеров&lt;br /&gt;
&lt;br /&gt;
Поскольку основная часть вычислений приходится на шаги итераций, распишем информационные графы данных шагов.&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Распределение векторов по кластерам&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
Информационный граф шага распределения векторов по кластерам представлен на &#039;&#039;рисунке 1&#039;&#039;. Исходами данного графа является исходные векторы &amp;lt;math&amp;gt;\mathbf{x}_1, ..., \mathbf{x}_n&amp;lt;/math&amp;gt;, а также центры кластеров &amp;lt;math&amp;gt;\mathbf{\mu}_1, ... \mathbf{\mu}_k&amp;lt;/math&amp;gt;, вычисленные ранее (на шаге инициализации, если рассматривается первая итерация алгоритма, или на шаге пересчета центров кластеров предыдущей итерации в противном случае). Каждая пара векторов данных &amp;lt;math&amp;gt;\mathbf{x}_i, i=\overline{1,n}&amp;lt;/math&amp;gt; и центров кластера &amp;lt;math&amp;gt;\mathbf{\mu}_j, j=\overline{1, k}&amp;lt;/math&amp;gt; : (&amp;lt;math&amp;gt;\mathbf{x}_i&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;\mathbf{\mu}_j&amp;lt;/math&amp;gt;) подаются на независимые узлы &amp;lt;i&amp;gt;&amp;quot;d&amp;quot;&amp;lt;/i&amp;gt; вычисления расстояния между векторами (более подробная схема вычисления расстояния представлена далее, &#039;&#039;рисунок 2&#039;&#039;). Далее узлы вычисления расстояния &amp;lt;i&amp;gt;&amp;quot;d&amp;quot;&amp;lt;/i&amp;gt;, соответствующие одному и тому же исходному вектору &amp;lt;math&amp;gt;\mathbf{x}_i&amp;lt;/math&amp;gt; передаются на один узел &amp;lt;i&amp;gt;&amp;quot;m&amp;quot;&amp;lt;/i&amp;gt;, где далее происходит вычисление новой метки кластера для каждого вектора &amp;lt;math&amp;gt;\mathbf{x}_i&amp;lt;/math&amp;gt; (берется кластер с минимальным результатом вычисления расстояния). На выходе графа выдаются метки кластеров , &amp;lt;math&amp;gt;L_1, ..., L_n&amp;lt;/math&amp;gt;, такие что &amp;lt;math&amp;gt;\forall \mathbf{x}_i, i=\overline{1, n}, \mathbf{x}_i \in S_j \Leftrightarrow L_i = j&amp;lt;/math&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
[[file:Clusterization.png|thumb|center|800px|Рис. 1. Схема распределения векторов по кластерам. &#039;&#039;d&#039;&#039; &amp;amp;ndash; вычисление расстояния между векторами; &#039;&#039;m&#039;&#039; &amp;amp;ndash; вычисление минимума.]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Вычисление расстояния между векторами&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
Подробная схема вычисления расстояния между векторами &amp;lt;math&amp;gt;\mathbf{x}_i, \mathbf{\mu}_j&amp;lt;/math&amp;gt; представлена на &#039;&#039;рисунке 2&#039;&#039;. Как показано на графе, узел вычисления расстояния между векторами &amp;lt;i&amp;gt;&amp;quot;d&amp;quot;&amp;lt;/i&amp;gt; состоит из шага взятия разности между векторами (узел &amp;quot;&amp;lt;math&amp;gt;-&amp;lt;/math&amp;gt;&amp;quot;) и взятия нормы получившегося вектора разности (узел &amp;quot;&amp;lt;math&amp;gt;||\cdot||^2&amp;lt;/math&amp;gt;&amp;quot;). Более подробно, вычисление расстояния между векторами &amp;lt;math&amp;gt;\mathbf{x}_i = {x_{i1,}, ...,{x_{in}}}, \mathbf{\mu}_j = {\mu_{j1}, ...,\mu_{jn}}&amp;lt;/math&amp;gt; может быть представлено как вычисление разности между каждой парой компонент &amp;lt;math&amp;gt;(x_{iz}, \mu_{jz}), z=\overline{1, d}&amp;lt;/math&amp;gt; (узел &amp;quot;&amp;lt;math&amp;gt;-&amp;lt;/math&amp;gt;&amp;quot;), далее возведение в квадрат для каждого узла &amp;quot;&amp;lt;math&amp;gt;-&amp;lt;/math&amp;gt;&amp;quot; (узел &amp;quot;&amp;lt;math&amp;gt;()^2&amp;lt;/math&amp;gt;&amp;quot;) и суммирования выходов всех узлов &amp;quot;&amp;lt;math&amp;gt;()^2&amp;lt;/math&amp;gt;&amp;quot; (узел &amp;quot;&amp;lt;math&amp;gt;+&amp;lt;/math&amp;gt;&amp;quot;).  &lt;br /&gt;
&lt;br /&gt;
[[file:dist_calc.png|thumb|center|800px|Рис. 2. Схема вычисления расстояния между вектором и центром кластера.]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Пересчет центров кластеров&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
Информационный граф шага пересчета центров кластеров представлен на &#039;&#039;рисунке 3&#039;&#039;. Исходами данного графа является исходные векторы &amp;lt;math&amp;gt;\mathbf{x}_1, ..., \mathbf{x}_n&amp;lt;/math&amp;gt;, а также им соответствующие метки кластера, &amp;lt;math&amp;gt;L_1, ..., L_n&amp;lt;/math&amp;gt;, такие что &amp;lt;math&amp;gt;\forall x_i, i=\overline{1, n}, \mathbf{x}_i \in S_j \Leftrightarrow L_i = j&amp;lt;/math&amp;gt;, вычисленные на этапе распределения векторов по кластерам. Все векторы &amp;lt;math&amp;gt;\mathbf{x}_1, ..., \mathbf{x}_n&amp;lt;/math&amp;gt; подаются в узлы &amp;lt;math&amp;gt;+_1, ...+_k&amp;lt;/math&amp;gt;, каждый узел &amp;lt;math&amp;gt;+_m, m = \overline{1,k}&amp;lt;/math&amp;gt; соответствует операции сложения векторов кластера с номером &amp;lt;math&amp;gt;m&amp;lt;/math&amp;gt;. Метки кластера &amp;lt;math&amp;gt;L_1, ..., L_n&amp;lt;/math&amp;gt; также совместно передаются на узлы &amp;lt;math&amp;gt;S_m, m = \overline{1,k}&amp;lt;/math&amp;gt;, на каждом из которых вычисляется количество векторов в соответствующем кластере (количество меток с соответствующим значением). Далее каждая пара выходов узлов &amp;lt;math&amp;gt;+_m&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;S_m&amp;lt;/math&amp;gt; подается на узел &amp;quot;&amp;lt;math&amp;gt;/&amp;lt;/math&amp;gt;&amp;quot;, где производится деление суммы векторов кластера на количество элементов в нем. Значения, вычисленные на узлах &amp;quot;&amp;lt;math&amp;gt;/&amp;lt;/math&amp;gt;&amp;quot;, присваиваются новым центрам кластеров (выходные значения графа).&lt;br /&gt;
&lt;br /&gt;
[[file:Recluster.png|thumb|center|800px|Рис. 3. Схема пересчета центров кластеров]]&lt;br /&gt;
&lt;br /&gt;
=== Ресурс параллелизма алгоритма ===&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
Работа алгоритма состоит из &amp;lt;math&amp;gt;\Tau&amp;lt;/math&amp;gt; итераций, в каждой из которых происходит &amp;lt;b&amp;gt;распределение d-мерных векторов по &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластерам&amp;lt;/b&amp;gt;, а также &amp;lt;b&amp;gt;пересчет центров кластеров в d-мерном пространстве&amp;lt;/b&amp;gt;. В шаге &amp;lt;b&amp;gt;распределения d-мерных векторов по &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластерам&amp;lt;/b&amp;gt; расстояния между вектором и центрами кластеров вычисляются независимо (отсутствуют информационные зависимости). &amp;lt;b&amp;gt;Центры масс кластеров&amp;lt;/b&amp;gt; также пересчитываются независимо друг от друга. Таким образом, имеет место [[глоссарий#Массовый параллелизм|&#039;&#039;массовый параллелизм&#039;&#039;]]. Вычислим параллельную сложность &amp;lt;math&amp;gt;\Psi_*&amp;lt;/math&amp;gt; каждого из шагов, а также параллельную сложность всего алгоритма, &amp;lt;math&amp;gt;\Psi_{k-means}&amp;lt;/math&amp;gt;. Будем исходить из предположения, что может быть использовано любое необходимое число потоков.&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Распределение d-мерных векторов по &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластерам&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;  &lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
Поскольку на данном шаге для каждой пары векторов &amp;lt;math&amp;gt;\mathbf{x}_i, i=\overline{1,n}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\mathbf{\mu}_j, j=\overline{1,k}&amp;lt;/math&amp;gt; операции вычисления расстояния не зависят друг от друга, они могут выполняться параллельно. Тогда, разделив все вычисление расстояний на &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; потоков, получим, что в каждом потоке будет выполняться только одна операция вычисления расстояния между векторами размерности d. При этом каждому вычислительному потоку передаются координаты центров всех кластеров &amp;lt;math&amp;gt;\mathbf{\mu}_1, ..., \mathbf{\mu}_k&amp;lt;/math&amp;gt;. Таким образом, параллельная сложность данного шага определяется &amp;lt;i&amp;gt; сложностью параллельной операции вычисления расстояния между d-мерными векторами&amp;lt;/i&amp;gt;, &amp;lt;math&amp;gt;\Psi_{distance}^d&amp;lt;/math&amp;gt;  и &amp;lt;i&amp;gt;сложностью определения наиболее близкого кластера&amp;lt;/i&amp;gt; (паралельное взятие минимума по расстояниям), &amp;lt;math&amp;gt;\Psi_{min}^k&amp;lt;/math&amp;gt;. Для оценки &amp;lt;math&amp;gt;\Psi_{distance}^d&amp;lt;/math&amp;gt; воспользуемся  [[Нахождение_частных_сумм_элементов_массива_сдваиванием | параллельной реализацией нахождения частичной суммы элементов массива путем сдваивания]]. Аналогично, &amp;lt;math&amp;gt;\Psi_{min}^k = log(k)&amp;lt;/math&amp;gt;. В результате, &amp;lt;math&amp;gt;\Psi_{distance}^d = O(log(d))&amp;lt;/math&amp;gt;.   Таким образом: &lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p align=&amp;quot;center&amp;quot;&amp;gt;&amp;lt;math&amp;gt;\Psi_{distribute}^{k, d}  = \Psi_{distance}^d + \Psi_{min}^k = O(log(d))+O(log(k)) = O(log(k*d))&amp;lt;/math&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Пересчет центров кластеров в d-мерном пространстве&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
Поскольку на данном шаге для каждого из &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластеров центр масс может быть вычислен независимо, данные операции могут быть выполнены в отдельных потоках. Таким образом, параллельная сложность данного шага, &amp;lt;math&amp;gt;\Psi_{recenter}^{k, d}&amp;lt;/math&amp;gt;,  будет определяться &amp;lt;i&amp;gt;параллельной сложностью вычисления одного центра масс кластера размера &amp;lt;math&amp;gt;m&amp;lt;/math&amp;gt;&amp;lt;/i&amp;gt;, &amp;lt;math&amp;gt;\Psi_{recenter}^{k, d}&amp;lt;/math&amp;gt;,  а так как &amp;lt;math&amp;gt;m \le n \Rightarrow \Psi_{recenter}^{d, m} \le \Psi_{recenter}^{d, n}&amp;lt;/math&amp;gt;. Сложность вычисления центра масс кластера d-мерных векторов размера n аналогично предыдущим вычислениям равна &amp;lt;math&amp;gt;O(log(n))&amp;lt;/math&amp;gt;. Тогда:  &lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p align=&amp;quot;center&amp;quot;&amp;gt;&amp;lt;math&amp;gt;\Psi_{recenter}^{k, d}  \le \Psi_{recenter}^{d, n} = O(log(n))&amp;lt;/math&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Общая параллельная сложность алгоритма&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
На каждой итерации необходимо обновление центров кластеров, которые будут использованы на следующей итерации. Таким образом, итерационный процесс выполняется последовательно&amp;lt;ref&amp;gt;Zhao, Weizhong, Huifang Ma, and Qing He. &amp;quot;Parallel k-means clustering based on mapreduce.&amp;quot; IEEE International Conference on Cloud Computing. Springer Berlin Heidelberg, 2009.&amp;lt;/ref&amp;gt;. Тогда, поскольку сложность каждой итерации  определяется &amp;lt;math&amp;gt;\Psi_{distribute}^{k, d}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\Psi_{recenter}&amp;lt;/math&amp;gt;, сложность всего алгоритма, &amp;lt;math&amp;gt;\Psi_{k-means}&amp;lt;/math&amp;gt; в предположении, что было сделано &amp;lt;math&amp;gt;\Tau&amp;lt;/math&amp;gt; операций определяется выражением&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p align=&amp;quot;center&amp;quot;&amp;gt;&amp;lt;math&amp;gt;\Psi_{k-means} \approx \Tau * (\Psi_{distribute}^{k, d} + \Psi_{recenter}^{k, d}) \le \Tau * O(log(k*d*n))&amp;lt;/math&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Входные и выходные данные алгоритма ===&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;Входные данные&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;Матрица из &amp;lt;math&amp;gt;n*d&amp;lt;/math&amp;gt; элементов &amp;lt;math&amp;gt;x_{i, j} \in \mathbb{R}, i=\overline{1, n}, j=\overline{1, d}&amp;lt;/math&amp;gt;&amp;amp;ndash; координат векторов (наблюдений).&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;Целое положительное число &amp;lt;math&amp;gt;k, k \le n&amp;lt;/math&amp;gt; &amp;amp;ndash; количество кластеров.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;Объем входных данных&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;math&amp;gt;1&amp;lt;/math&amp;gt; целое число + &amp;lt;math&amp;gt;n*d&amp;lt;/math&amp;gt; вещественных чисел (при условии, что координаты &amp;amp;ndash; вещественные числа).&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;Выходные данные&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; целых положительных чисел &amp;lt;math&amp;gt;L_1, ..., L_n&amp;lt;/math&amp;gt;&amp;amp;ndash; номера кластеров, соотвествующие каждому вектору (при условии, что нумерация кластеров начинается с &amp;lt;math&amp;gt;1&amp;lt;/math&amp;gt;).&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;Объем выходных данных&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; целых положительных чисел.&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Свойства алгоритма ===&lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;[[глоссарий#Вычислительная мощность|&#039;&#039;Вычислительная мощность&#039;&#039;]]&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
Вычислительная мощность алгоритма &amp;lt;i&amp;gt;k means&amp;lt;/i&amp;gt; равна &amp;lt;math&amp;gt;\frac{k*d*n*\Tau}{n*d} = k*\Tau &amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; &amp;amp;ndash; число кластеров, &amp;lt;math&amp;gt;\Tau&amp;lt;/math&amp;gt; &amp;amp;ndash; число итераций алгоритма.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;[[глоссарий#Детерминированность |&#039;&#039;Детерминированность&#039;&#039;]] и [[глоссарий#Устойчивость |&#039;&#039;Устойчивость&#039;&#039;]] &amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
Алгоритм &amp;lt;i&amp;gt;k means&amp;lt;/i&amp;gt; является итерационным. Количество итераций алгоритма в общем случае не фиксируется и зависит от начального расположения объектов в пространстве, параметра &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt;, а также от начального приближения центров кластеров, &amp;lt;math&amp;gt;\mu_1, ..., \mu_k&amp;lt;/math&amp;gt;. В результате этого может варьироваться результат работы алгоритма. При неудачном выборе начальных параметров итерационный процесс может сойтись к локальному оптимуму&amp;lt;ref&amp;gt;Von Luxburg, Ulrike. Clustering Stability. Now Publishers Inc, 2010.&amp;lt;/ref&amp;gt;. По этим причинам алгоритм не является ни &amp;lt;b&amp;gt;детермирированным&amp;lt;/b&amp;gt;, ни &amp;lt;b&amp;gt;устойчивым&amp;lt;/b&amp;gt;.&lt;br /&gt;
 &lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Соотношение последовательной и параллельной сложности алгоритма&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\frac{\Theta_{k-means}}{\Psi_{k-means}} = \frac{O(\Tau*k*d*n)}{O(\Tau*log(k*d*n))}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Сильные стороны алгоритма&amp;lt;/b&amp;gt;:&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;i&amp;gt;Сравнительно высокая эффективность при простоте реализации&amp;lt;/i&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;i&amp;gt;Высокое качество кластеризации&amp;lt;/i&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;i&amp;gt;Возможность распараллеливания&amp;lt;/i&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;i&amp;gt;Существование множества модификаций&amp;lt;/i&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;Недостатки алгоритма&amp;lt;/b&amp;gt;&amp;lt;ref&amp;gt;Ortega, Joaquín Pérez, Ma Del Rocío Boone Rojas, and María J. Somodevilla. &amp;quot;Research issues on K-means Algorithm: An Experimental Trial Using Matlab.&amp;quot;&amp;lt;/ref&amp;gt;:&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;i&amp;gt;Количество кластеров является параметром алгоритма&amp;lt;/i&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;&amp;lt;i&amp;gt;Чувствительность к начальным условиям&amp;lt;/i&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;Инициализация центров кластеров в значительной степени влияет на результат кластеризации.&amp;lt;/p&amp;gt;&lt;br /&gt;
  &amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;&amp;lt;i&amp;gt;Чувствительность к выбросам и шумам&amp;lt;/i&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;Выбросы, далекие от центров настоящих кластеров, все равно учитываются при вычислении их центров.&amp;lt;/p&amp;gt;&lt;br /&gt;
  &amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;&amp;lt;i&amp;gt;Возможность сходимости к локальному оптимуму&amp;lt;/i&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;Итеративный подход не дает гарантии сходимости к оптимальному решению.&amp;lt;/p&amp;gt;&lt;br /&gt;
  &amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;&amp;lt;i&amp;gt;Использование понятия &amp;quot;среднего&amp;quot;&amp;lt;/i&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;Алгоритм неприменим к данным, для которых не определено понятие &amp;quot;среднего&amp;quot;, например, категориальным данным.&amp;lt;/p&amp;gt;&lt;br /&gt;
  &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&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;
Исследование масштабируемости параллельной реализации алгоритма k means проводилось на суперкомпьютере &amp;quot;Ломоносов&amp;quot;. Алгоритм реализован на языке C с использованием средств MPI.&lt;br /&gt;
Для исследования масштабируемости проводилось множество запусков программы с разным значением параметра (количество векторов для кластеризации), а также с различным числом процессоров. Фиксировались результаты запусков &amp;amp;ndash; время работы &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt; и количество произведенных итераций алгоритма &amp;lt;math&amp;gt;\Tau&amp;lt;/math&amp;gt;.&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;Значения &amp;lt;b&amp;gt;количества векторов&amp;lt;/b&amp;gt; &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;: 20&#039;000, 30&#039;000, 50&#039;000, 100&#039;000, 200&#039;000, 300&#039;000, 500&#039;000, 700&#039;000, 1&#039;000&#039;000, 1&#039;500&#039;000, 2&#039;000&#039;000.&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;Значения &amp;lt;b&amp;gt;количества процессоров&amp;lt;/b&amp;gt; &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt;: 1, 8, 16, 32, 64, 128, 160, 192, 224, 256, 288, 320, 352, 384, 416, 448, 480, 512.&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;Значение &amp;lt;b&amp;gt;количества кластеров&amp;lt;/b&amp;gt; &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt;: 100.&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;Значение &amp;lt;b&amp;gt;размерности векторов&amp;lt;/b&amp;gt; &amp;lt;math&amp;gt;d&amp;lt;/math&amp;gt;: 10.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Графики производительности и эффективности реализации представлены на рисунках 4 и 5 соответственно.&lt;br /&gt;
&lt;br /&gt;
[[file:Flops.png|thumb|center|800px|Рис. 4. График производительности реализации алгоритма.]]&lt;br /&gt;
&lt;br /&gt;
[[file:Efficiency.png|thumb|center|800px|Рис. 5. График эффективности реализации алгоритма.]]&lt;br /&gt;
&lt;br /&gt;
Для заданной конфигурации эксперимента (&amp;lt;math&amp;gt;n, p, k&amp;lt;/math&amp;gt;) и полученных результатах (&amp;lt;math&amp;gt;t, \Tau&amp;lt;/math&amp;gt;) производительность и эффективность реализации расчитывались по формулам (см. [[#Последовательная сложность алгоритма| последовательная сложность алгоритма]]):&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
&amp;lt;ul&amp;gt;&amp;lt;li&amp;gt;&amp;lt;math&amp;gt;Performance = \frac{\Theta_{k-means}^{d, n}}{t}\ \ FLOPS&amp;lt;/math&amp;gt;&amp;lt;/li&amp;gt;&amp;lt;/ul&amp;gt;&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
&amp;lt;ul&amp;gt;&amp;lt;li&amp;gt;&amp;lt;math&amp;gt;Efficiency = \frac{100 * Performance}{Performance_{Peak}^{p}}\ \ %,&amp;lt;/math&amp;gt;&amp;lt;/li&amp;gt;&amp;lt;/ul&amp;gt;&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
где &amp;lt;math&amp;gt;Performance_{Peak}^{p}&amp;lt;/math&amp;gt; &amp;amp;ndash; пиковая производительность суперкомпьютера при &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt; процессорах, вычисленная согласно спецификациям Intel&amp;amp;reg; XEON&amp;amp;reg; X5670&amp;lt;ref&amp;gt;&amp;quot;http://ark.intel.com/ru/products/47920/Intel-Xeon-Processor-X5670-12M-Cache-2_93-GHz-6_40-GTs-Intel-QPI&amp;quot;&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
В результате экспериментальной оценки были получены следующие оценки эффективности реализации:&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;b&amp;gt;Минимальное&amp;lt;/b&amp;gt; значение: 0.000409 %&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;b&amp;gt;Максимальное&amp;lt;/b&amp;gt; значение: 0.741119 %&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Динамические характеристики и эффективность реализации алгоритма ===&lt;br /&gt;
=== Выводы для классов архитектур ===&lt;br /&gt;
=== Существующие реализации алгоритма ===&lt;br /&gt;
==== Открытое программное обеспечение ====&lt;br /&gt;
&amp;lt;ol&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;[https://www.icpsr.umich.edu/CrimeStat/ CrimeStat]&amp;lt;/li&amp;gt; Программное обеспечение, созданное для операционных систем Windows, предоставляющее инструменты статистического  и пространственного анализа для решения задачи картирования преступности.&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://juliastats.github.io Julia]&amp;lt;/li&amp;gt; Высокоуровневый высокопроизводительный свободный язык программирования с динамической типизацией, созданный для математических вычислений, содержит реализацию k-means.&lt;br /&gt;
  &amp;lt;li&amp;gt;[https://mahout.apache.org Mahout]&amp;lt;/li&amp;gt; Apache Mahout - Java библиотека для работы с алгоритмами машинного обучения с использованием MapReduce. Содержит реализацию k-means.&lt;br /&gt;
  &amp;lt;li&amp;gt;[https://www.gnu.org/software/octave/ Octave]&amp;lt;/li&amp;gt; Написанная на C++  свободная система для математических вычислений, использующая совместимый с MATLAB язык высокого уровня, содержит реализацию k-means.&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://spark.apache.org/docs/latest/mllib-clustering.html Spark]&amp;lt;/li&amp;gt; Распределенная реализация k-means содержится в библиотеке Mlib для работы с алгоритмами машинного обучения, взаимодействующая с Python библиотекой NumPy и библиотека R.&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://torch.ch Torch]&amp;lt;/li&amp;gt;  MATLAB-подобная библиотека для языка программирования Lua с открытым исходным кодом, предоставляет большое количество алгоритмов для глубинного обучения и научных расчётов. Ядро написано на Си, прикладная часть выполняется на LuaJIT, поддерживается распараллеливание вычислений средствами CUDA и OpenMP. Существуют реализации k-means.&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://www.cs.waikato.ac.nz/ml/weka/ Weka]&amp;lt;/li&amp;gt;  Cвободное программное обеспечение для анализа данных, написанное на Java. Содержит k-means и x-means.&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://accord-framework.net/docs/html/T_Accord_MachineLearning_KMeans.htm Accord.NET]&amp;lt;/li&amp;gt; C# реализация алгоритмов k-means, k-means++, k-modes.&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://docs.opencv.org/3.0-beta/doc/py_tutorials/py_ml/py_kmeans/py_kmeans_opencv/py_kmeans_opencv.html OpenCV]&amp;lt;/li&amp;gt; Написанная на С++ библиотека, направленная в основном на решение задач компьютерного зрения. Содержит реализацию k-means.&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://mlpack.org/ MLPACK]&amp;lt;/li&amp;gt; Масштабируемая С++ библиотека для работы с алгоритмами машинного обучения, содержит реализацию k-means.&lt;br /&gt;
  &amp;lt;li&amp;gt;[https://www.scipy.org/ SciPy]&amp;lt;/li&amp;gt; Библиотека Python, содержит множество реализаций k-means.&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://scikit-learn.org/ scikit-learn]&amp;lt;/li&amp;gt; Библиотека Python, содержит множество реализаций k-means.&lt;br /&gt;
  &amp;lt;li&amp;gt;[https://www.r-bloggers.com/k-means-clustering-in-r/ R]&amp;lt;/li&amp;gt; Язык программирования для статистической обработки данных и работы с графикой, а также свободная программная среда вычислений с открытым исходным кодом в рамках проекта GNU, содержит три реализации k-means.&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://elki.dbs.ifi.lmu.de ELKI]&amp;lt;/li&amp;gt; Java фреймворк, содержащий реализацию k-means, а также множество других алгоритмов кластеризации.&lt;br /&gt;
&amp;lt;/ol&amp;gt;&lt;br /&gt;
==== Проприетарное программное обеспечение  ====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ol&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;[https://www.ayasdi.com/blog/bigdata/topological-data-analysis-of-oil-and-gas-petrophysical-data/ Ayasdi]&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://www.stata.com/features/cluster-analysis/ Stata]&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://mathworld.wolfram.com/K-MeansClusteringAlgorithm.html Mathematica]&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://www.mathworks.com/help/stats/kmeans.html?requestedDomain=www.mathworks.com MATLAB]&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;[https://support.sas.com/rnd/app/stat/procedures/fastclus.html SAS]&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://docs.rapidminer.com/studio/operators/modeling/segmentation/k_means.html RapidMiner]&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;[https://blogs.sap.com/2013/03/28/sap-hana-pal-k-means-algorithm-or-how-to-do-customer-segmentation-for-the-telecommunications-industry/ SAP HANA]&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ol&amp;gt;&lt;br /&gt;
== Литература ==&lt;br /&gt;
&amp;lt;references /&amp;gt;&lt;/div&gt;</summary>
		<author><name>DennZo1993</name></author>
	</entry>
	<entry>
		<id>https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:%D0%91%D1%80%D0%BE%D1%82%D0%B8%D0%BA%D0%BE%D0%B2%D1%81%D0%BA%D0%B0%D1%8F_%D0%94%D0%B0%D0%BD%D1%83%D1%82%D0%B0/%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_k-means&amp;diff=17169</id>
		<title>Участник:Бротиковская Данута/Алгоритм k-means</title>
		<link rel="alternate" type="text/html" href="https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:%D0%91%D1%80%D0%BE%D1%82%D0%B8%D0%BA%D0%BE%D0%B2%D1%81%D0%BA%D0%B0%D1%8F_%D0%94%D0%B0%D0%BD%D1%83%D1%82%D0%B0/%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_k-means&amp;diff=17169"/>
		<updated>2016-11-14T23:51:46Z</updated>

		<summary type="html">&lt;p&gt;DennZo1993: /* Масштабируемость реализации алгоритма */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt; {{Assignment|Zhum}}&lt;br /&gt;
&lt;br /&gt;
{{algorithm&lt;br /&gt;
| name              = Алгоритм k средних (k means)&lt;br /&gt;
| serial_complexity = &amp;lt;math&amp;gt;O(\Tau*k*d*n)&amp;lt;/math&amp;gt;&lt;br /&gt;
| input_data        = &amp;lt;math&amp;gt; d*n &amp;lt;/math&amp;gt;&lt;br /&gt;
| output_data       = &amp;lt;math&amp;gt; n &amp;lt;/math&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
Авторы страницы &amp;lt;b&amp;gt;[[Участник:Бротиковская Данута|Данута Бротиковская]]&amp;lt;/b&amp;gt; и &amp;lt;b&amp;gt;[[Участник:DennZo1993|Денис Зобнин]]&amp;lt;/b&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
Оба автора внесли одинаковый вклад в написание статьи (поиск материалов, изучение статей, заполнение контента статьи), четких разграничений по пунктам статьи сделать невозможно. &lt;br /&gt;
&lt;br /&gt;
== Свойства и структура алгоритма ==&lt;br /&gt;
&lt;br /&gt;
=== Общее описание алгоритма ===&lt;br /&gt;
Алгоритм &amp;lt;b&amp;gt;&amp;lt;i&amp;gt;k средних&amp;lt;/i&amp;gt;&amp;lt;/b&amp;gt; (&amp;lt;b&amp;gt;&amp;lt;i&amp;gt;k means&amp;lt;/i&amp;gt;&amp;lt;/b&amp;gt;) &amp;amp;ndash; неиерархический&amp;lt;ref&amp;gt;&amp;quot;https://ru.wikipedia.org/wiki/Иерархическая_кластеризация&amp;quot;&amp;lt;/ref&amp;gt;, итерационный метод кластеризации&amp;lt;ref&amp;gt;&amp;quot;https://ru.wikipedia.org/wiki/Кластерный_анализ&amp;quot;&amp;lt;/ref&amp;gt;, получивший большую популярность благодаря своей простоте, наглядности реализации и достаточно высокому качеству работы. Был изобретен в 1950-х годах математиком &amp;lt;i&amp;gt;Гуго Штейнгаузом&amp;lt;/i&amp;gt;&amp;lt;ref&amp;gt;Steinhaus, Hugo. &amp;quot;Sur la division des corp materiels en parties.&amp;quot; Bull. Acad. Polon. Sci 1.804 (1956): 801.&amp;lt;/ref&amp;gt; и почти одновременно &amp;lt;i&amp;gt;Стюартом Ллойдом&amp;lt;/i&amp;gt;&amp;lt;ref&amp;gt;Lloyd, S. P. &amp;quot;Least square quantization in PCM. Bell Telephone Laboratories Paper. Published in journal much later: Lloyd, SP: Least squares quantization in PCM.&amp;quot; IEEE Trans. Inform. Theor.(1957/1982).&amp;lt;/ref&amp;gt;. Особую популярность приобрел после публикации работы &amp;lt;i&amp;gt;МакКуина&amp;lt;/i&amp;gt;&amp;lt;ref&amp;gt;MacQueen, James. &amp;quot;Some methods for classification and analysis of multivariate observations.&amp;quot; Proceedings of the fifth Berkeley symposium on mathematical statistics and probability. Vol. 1. No. 14. 1967.&amp;lt;/ref&amp;gt; в 1967.&lt;br /&gt;
&lt;br /&gt;
Алгоритм представляет собой версию EM-алгоритма&amp;lt;ref&amp;gt;&amp;quot;https://ru.wikipedia.org/wiki/EM-алгоритм&amp;quot;&amp;lt;/ref&amp;gt;, применяемого также для разделения смеси гауссиан. Основная идея &amp;lt;i&amp;gt;k means&amp;lt;/i&amp;gt; заключается в том, что данные произвольно разбиваются на кластеры, после чего итеративно перевычисляется центр масс для каждого кластера, полученного на предыдущем шаге, затем векторы разбиваются на кластеры вновь в соответствии с тем, какой из новых центров оказался ближе по выбранной метрике.&lt;br /&gt;
&lt;br /&gt;
Цель алгоритма заключается в разделении &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; наблюдений на &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластеров таким образом, чтобы каждое наблюдение принадлежало ровно одному кластеру, расположенному на наименьшем расстоянии от наблюдения.&lt;br /&gt;
&lt;br /&gt;
=== Математическое описание алгоритма ===&lt;br /&gt;
&amp;lt;b&amp;gt;&amp;lt;u&amp;gt;Дано:&amp;lt;/u&amp;gt;&amp;lt;/b&amp;gt;&lt;br /&gt;
* набор из &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; наблюдений &amp;lt;math&amp;gt;X=\{\mathbf{x}_1, \mathbf{x}_2, ..., \mathbf{x}_n\}, \mathbf{x}_i \in \mathbb{R}^d, i=\overline{1, n}&amp;lt;/math&amp;gt;;&lt;br /&gt;
* &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; - требуемое число кластеров, &amp;lt;math&amp;gt;k \in \mathbb{N}, k \leq n&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;&amp;lt;u&amp;gt;Требуется:&amp;lt;/u&amp;gt;&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Разделить множество наблюдений &amp;lt;math&amp;gt;X&amp;lt;/math&amp;gt; на &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластеров &amp;lt;math&amp;gt;S_1, S_2, ..., S_k&amp;lt;/math&amp;gt;:&lt;br /&gt;
*   &amp;lt;math&amp;gt;S_i \cap S_j= \varnothing, \quad i \ne j&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
*   &amp;lt;math&amp;gt;\bigcup_{i=1}^{k} S_i = X&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;&amp;lt;u&amp;gt;Действие алгоритма:&amp;lt;/u&amp;gt;&amp;lt;/b&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;Алгоритм &amp;lt;i&amp;gt;k means&amp;lt;/i&amp;gt; разбивает набор &amp;lt;math&amp;gt;X&amp;lt;/math&amp;gt; на &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; наборов &amp;lt;math&amp;gt;S_1, S_2, ..., S_k,&amp;lt;/math&amp;gt; таким образом, чтобы минимизировать сумму квадратов расстояний от каждой точки кластера до его центра (центр масс кластера). Введем обозначение, &amp;lt;math&amp;gt;S=\{S_1, S_2, ..., S_k\}&amp;lt;/math&amp;gt;. Тогда действие алгоритма &amp;lt;i&amp;gt;k means&amp;lt;/i&amp;gt; равносильно поиску:&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;table style=&amp;quot;width:100%&amp;quot;&amp;gt;&lt;br /&gt;
  &amp;lt;tr&amp;gt;&lt;br /&gt;
    &amp;lt;td align=&amp;quot;center&amp;quot; width=&amp;quot;90%&amp;quot;&amp;gt;&amp;lt;math&amp;gt;\arg\min_{S} \sum\limits_{i=1}^k \sum\limits_{\mathbf{x} \in S_i} \rho(\mathbf{x}, \mathbf{\mu}_i )^2,&amp;lt;/math&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;td align=&amp;quot;right&amp;quot;&amp;gt;&amp;lt;math&amp;gt;(1)&amp;lt;/math&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;/table&amp;gt;&lt;br /&gt;
где &amp;lt;math&amp;gt;\mathbf{\mu}_i&amp;lt;/math&amp;gt; &amp;amp;ndash; центры кластеров, &amp;lt;math&amp;gt;i=\overline{1,k}, \quad \rho(\mathbf{x}, \mathbf{\mu}_i)&amp;lt;/math&amp;gt; &amp;amp;ndash; функция расстояния между &amp;lt;math&amp;gt;\mathbf{x}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\mu_i&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;&amp;lt;u&amp;gt;Шаги алгоритма: &amp;lt;/u&amp;gt;&amp;lt;/b&amp;gt;&lt;br /&gt;
&amp;lt;ol&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&lt;br /&gt;
    &amp;lt;b&amp;gt;Начальный шаг: инициализация кластеров&amp;lt;/b&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;Выбирается произвольное множество точек &amp;lt;math&amp;gt;\mu_i, i=\overline{1,k}&amp;lt;/math&amp;gt;, рассматриваемых как начальные центры кластеров: &amp;lt;math&amp;gt;\mu_i^{(0)} = \mu_i, \quad i=\overline{1, k}&amp;lt;/math&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
  &amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&lt;br /&gt;
    &amp;lt;b&amp;gt;Распределение векторов по кластерам&amp;lt;/b&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Шаг&amp;lt;/b&amp;gt; &amp;lt;math&amp;gt;t: \forall \mathbf{x}_i \in X, i=\overline{1,n}: \mathbf{x}_i \in S_j \iff  j=\arg\min_{k}\rho(\mathbf{x}_i,\mathbf{\mu}_k^{(t-1)})^2&amp;lt;/math&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
  &amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&lt;br /&gt;
    &amp;lt;b&amp;gt;Пересчет центров кластеров&amp;lt;/b&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Шаг &amp;lt;/b&amp;gt; &amp;lt;math&amp;gt;t: \forall i=\overline{1,k}:  \mu_i^{(t)} = \cfrac{1}{|S_i|}\sum_{\mathbf{x}\in S_i}\mathbf{x}&amp;lt;/math&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
  &amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&lt;br /&gt;
    &amp;lt;b&amp;gt;Проверка условия останова:&amp;lt;/b&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
    &#039;&#039;&#039;if&#039;&#039;&#039; &amp;lt;math&amp;gt;\exist i\in \overline{1,k}: \mu_i^{(t)} \ne \mu_i^{(t-1)}&amp;lt;/math&amp;gt; &#039;&#039;&#039;then&#039;&#039;&#039;&lt;br /&gt;
        t = t + 1;&lt;br /&gt;
        goto 2;&lt;br /&gt;
    &#039;&#039;&#039;else&#039;&#039;&#039;&lt;br /&gt;
        &#039;&#039;&#039;stop&#039;&#039;&#039;&lt;br /&gt;
  &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ol&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Вычислительное ядро алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Вычислительным ядром являются шаги 2 и 3 приведенного выше алгоритма: &amp;lt;b&amp;gt;&amp;lt;i&amp;gt;распределение векторов по кластерам&amp;lt;/i&amp;gt;&amp;lt;/b&amp;gt; и &amp;lt;b&amp;gt;&amp;lt;i&amp;gt;пересчет центров кластеров&amp;lt;/i&amp;gt;&amp;lt;/b&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;&amp;lt;i&amp;gt;Распределение векторов&amp;lt;/i&amp;gt;&amp;lt;/b&amp;gt; по кластерам предполагает вычисление расстояний между каждым вектором &amp;lt;math&amp;gt;\mathbf{x}_i \in X, i= \overline{1,n}&amp;lt;/math&amp;gt; и центрами кластера &amp;lt;math&amp;gt;\mathbf{\mu}_j, j= \overline{1,k}&amp;lt;/math&amp;gt;. Таким образом, данный шаг предполагает &amp;lt;math&amp;gt;k*n&amp;lt;/math&amp;gt; вычислений расстояний между d-мерными векторами. &lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;&amp;lt;i&amp;gt;Пересчет центров кластеров&amp;lt;/i&amp;gt;&amp;lt;/b&amp;gt; предполагает &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; вычислений центров масс &amp;lt;math&amp;gt;\mathbf{\mu}_i&amp;lt;/math&amp;gt; множеств &amp;lt;math&amp;gt;S_i, i=\overline{1,k}&amp;lt;/math&amp;gt; представленных выражением в шаге 3 представленного выше алгоритма.&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Макроструктура алгоритма ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Инициализация центров масс &amp;lt;math&amp;gt;\mu_1, ..., \mu_k&amp;lt;/math&amp;gt;&amp;lt;/b&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
Наиболее распространенными являются следующие стратегии:&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&lt;br /&gt;
    &amp;lt;b&amp;gt;Метод Forgy&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;В качестве начальных значений &amp;lt;math&amp;gt;\mu_1, ..., \mu_k&amp;lt;/math&amp;gt; берутся случайно выбранные векторы.&lt;br /&gt;
  &amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&lt;br /&gt;
    &amp;lt;b&amp;gt;Метод случайно разделения (Random Partitioning)&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;Для каждого вектора &amp;lt;math&amp;gt;\mathbf{x}_i \in X, i=\overline{1, n}&amp;lt;/math&amp;gt; выбирается случайным образом кластер &amp;lt;math&amp;gt;S_1, ..., S_k&amp;lt;/math&amp;gt;, после чего для каждого полученного кластера вычисляются значения &amp;lt;math&amp;gt;\mu_1, ..., \mu_k&amp;lt;/math&amp;gt;.&lt;br /&gt;
  &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Распределение векторов по кластерам&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Для этого шага алгоритма между векторами &amp;lt;math&amp;gt;\mathbf{x}_i \in X, i=\overline{1, n}&amp;lt;/math&amp;gt; и центрами кластеров &amp;lt;math&amp;gt;\mu_1, ..., \mu_k&amp;lt;/math&amp;gt; вычисляются &amp;lt;b&amp;gt;расстояния&amp;lt;/b&amp;gt; по формуле (как правило, используется Евлидово расстояние):&lt;br /&gt;
&amp;lt;table style=&amp;quot;width:100%&amp;quot;&amp;gt;&lt;br /&gt;
  &amp;lt;tr&amp;gt;&lt;br /&gt;
    &amp;lt;td align=&amp;quot;center&amp;quot; width=&amp;quot;90%&amp;quot;&amp;gt;&amp;lt;math&amp;gt; \mathbf{v}_1, \mathbf{v}_2 \in \mathbb{R}^d,  \quad \rho(\mathbf{v}_1, \mathbf{v}_2) = \lVert \mathbf{v}_1- \mathbf{v}_2 \rVert= \sqrt{\sum_{i=1}^{d}(\mathbf{v}_{1,i} - \mathbf{v}_{2,i})^2}&amp;lt;/math&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;td align=&amp;quot;right&amp;quot;&amp;gt;&amp;lt;math&amp;gt;(2)&amp;lt;/math&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;/table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Пересчет центров кластеров&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Для этого шага алгоритма производится пересчет центров кластера по &amp;lt;b&amp;gt;формуле вычисления центра масс&amp;lt;/b&amp;gt;:&lt;br /&gt;
&amp;lt;table style=&amp;quot;width:100%&amp;quot;&amp;gt;&lt;br /&gt;
  &amp;lt;tr&amp;gt;&lt;br /&gt;
    &amp;lt;td align=&amp;quot;center&amp;quot; width=&amp;quot;90%&amp;quot;&amp;gt;&amp;lt;math&amp;gt; \mu = \cfrac{1}{|S|}\sum_{\mathbf{x}\in S}\mathbf{x}&amp;lt;/math&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;td align=&amp;quot;right&amp;quot;&amp;gt;&amp;lt;math&amp;gt;(3)&amp;lt;/math&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;/table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Схема реализации последовательного алгоритма ===&lt;br /&gt;
&lt;br /&gt;
 &#039;&#039;&#039;algorithm&#039;&#039;&#039; k-means &#039;&#039;&#039;is&#039;&#039;&#039;&lt;br /&gt;
     &#039;&#039;&#039;1.&#039;&#039;&#039; Инициализировать центры кластеров &amp;lt;math&amp;gt;\mathbf{\mu}_i^{(1)}, i=\overline{1,k}&amp;lt;/math&amp;gt;&lt;br /&gt;
     &#039;&#039;&#039;2.&#039;&#039;&#039; &amp;lt;math&amp;gt;t \leftarrow 1&amp;lt;/math&amp;gt;&lt;br /&gt;
     &#039;&#039;&#039;3.&#039;&#039;&#039; &#039;&#039;&#039;Распределение по кластерам&#039;&#039;&#039;&amp;lt;br&amp;gt;&lt;br /&gt;
        &amp;lt;math&amp;gt;S_i^{(t)}=\{\mathbf{x}_p: \lVert\mathbf{x}_p-\mathbf{\mu}_i^{(t)}\rVert^2 \leq \lVert\mathbf{x}_p-\mathbf{\mu}_j^{(t)}\rVert^2 \quad \forall j=\overline{1,k}\},&amp;lt;/math&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
        где каждый вектор &amp;lt;math&amp;gt;\mathbf{x}_p&amp;lt;/math&amp;gt; соотносится единственному кластеру &amp;lt;math&amp;gt;S^{(t)}&amp;lt;/math&amp;gt;&lt;br /&gt;
     &#039;&#039;&#039;4.&#039;&#039;&#039; &#039;&#039;&#039;Обновление центров кластеров&#039;&#039;&#039;&amp;lt;br&amp;gt;&lt;br /&gt;
        &amp;lt;math&amp;gt;\mathbf{\mu}_i^{(t+1)} = \frac{1}{|S^{(t)}_i|} \sum_{\mathbf{x}_j \in S^{(t)}_i} \mathbf{x}_j &amp;lt;/math&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
     &#039;&#039;&#039;5.&#039;&#039;&#039; &#039;&#039;&#039;if&#039;&#039;&#039; &amp;lt;math&amp;gt;\exist i \in \overline{1,k}: \mathbf{\mu}_i^{(t+1)} \ne \mathbf{\mu}_i^{(t)}&amp;lt;/math&amp;gt; &#039;&#039;&#039;then&#039;&#039;&#039;&lt;br /&gt;
            t = t + 1;&lt;br /&gt;
            goto &#039;&#039;&#039;3&#039;&#039;&#039;;&lt;br /&gt;
        &#039;&#039;&#039;else&#039;&#039;&#039;&lt;br /&gt;
            &#039;&#039;&#039;stop&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
=== Последовательная сложность алгоритма===&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding-bottom: 20px&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;Обозначим &amp;lt;math&amp;gt;\Theta_{centroid}^{d, m}&amp;lt;/math&amp;gt; временную сложность вычисления центорида кластера, число элементов которого равна &amp;lt;math&amp;gt;m&amp;lt;/math&amp;gt;,  в d-мерном пространстве.&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;Аналогично  &amp;lt;math&amp;gt;\Theta_{distance}^d&amp;lt;/math&amp;gt; &amp;amp;ndash; временная сложность вычисления расстояния между двумя d-мерными векторами.&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding-bottom: 20px&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;Сложность шага инициализации &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластеров мощности &amp;lt;math&amp;gt;m&amp;lt;/math&amp;gt; в d-мерном пространстве &amp;amp;ndash; &amp;lt;math&amp;gt;\Theta_{init}^{k, d, m}&amp;lt;/math&amp;gt;&amp;lt;/b&amp;gt;&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;i&amp;gt;Стратерия Forgy&amp;lt;/i&amp;gt;: вычисления не требуются, &amp;lt;math&amp;gt;\Theta_{init}^{k, d, m} = 0&amp;lt;/math&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;i&amp;gt;Стратегия случайного разбиения&amp;lt;/i&amp;gt;: вычисление центров &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластеров,  &amp;lt;math&amp;gt;\Theta_{init}^{k, d, m} = k*\Theta_{centroid}^{d, m}, m \le n&amp;lt;/math&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding-bottom: 20px&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Cложность шага распределения d мерных векторов по &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластерам &amp;amp;ndash; &amp;lt;math&amp;gt;\Theta_{distribute}^{k, d}&amp;lt;/math&amp;gt;&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
На этом шаге для каждого вектора &amp;lt;math&amp;gt;\mathbf{x}_i \in X, i=\overline{1, n}&amp;lt;/math&amp;gt; вычисляется k расстояний до центров кластеров &amp;lt;math&amp;gt;\mathbf{\mu}_1, ...\mathbf{\mu}_k&amp;lt;/math&amp;gt;&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p align=&amp;quot;center&amp;quot;&amp;gt;&lt;br /&gt;
  &amp;lt;math&amp;gt;\Theta_{distribute}^{k, d} = n*k*\Theta_{distance}^d&amp;lt;/math&amp;gt;&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding-bottom: 20px&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;Сложность шага пересчета центров &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластеров размера &amp;lt;math&amp;gt;m&amp;lt;/math&amp;gt; в d-мерном пространстве &amp;amp;ndash; &amp;lt;math&amp;gt;\Theta_{recenter}^{k, d, m}&amp;lt;/math&amp;gt;&amp;lt;/b&amp;gt;&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;На этом шаге вычисляется &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; центров кластеров &amp;lt;math&amp;gt;\mathbf{\mu}_1, ...\mathbf{\mu}_k&amp;lt;/math&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p align=&amp;quot;center&amp;quot;&amp;gt;&amp;lt;math&amp;gt;\Theta_{recenter}^{k, d, m} = k*\Theta_{centroid}^{d, m}&amp;lt;/math&amp;gt; &amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding-bottom: 20px&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Рассчитаем &amp;lt;math&amp;gt;\Theta_{centroid}^{d, m}&amp;lt;/math&amp;gt; для кластера, число элементов которого равно &amp;lt;math&amp;gt;m&amp;lt;/math&amp;gt;&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p align=&amp;quot;center&amp;quot;&amp;gt;&amp;lt;math&amp;gt;\Theta_{centroid}^{d, m}&amp;lt;/math&amp;gt; = &amp;lt;math&amp;gt;m * d&amp;lt;/math&amp;gt; сложений + &amp;lt;math&amp;gt;d&amp;lt;/math&amp;gt; делений &amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding-bottom: 20px&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Рассчитаем &amp;lt;math&amp;gt;\Theta_{distance}^d&amp;lt;/math&amp;gt; в соответствие с формулой &amp;lt;math&amp;gt;(2)&amp;lt;/math&amp;gt;&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p align=&amp;quot;center&amp;quot;&amp;gt;&amp;lt;math&amp;gt;\Theta_{distance}^d&amp;lt;/math&amp;gt; = &amp;lt;math&amp;gt;d&amp;lt;/math&amp;gt; вычитаний + &amp;lt;math&amp;gt;d&amp;lt;/math&amp;gt; умножений + &amp;lt;math&amp;gt;(d-1)&amp;lt;/math&amp;gt; сложение&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding-bottom: 20px&amp;quot;&amp;gt;&lt;br /&gt;
  &amp;lt;p&amp;gt;Предположим, что алгоритм сошелся за &amp;lt;math&amp;gt;\Tau&amp;lt;/math&amp;gt; итераций, тогда временная сложность алгоритма &amp;lt;math&amp;gt;\Theta_{k-means}^{d, n}&amp;lt;/math&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
  &amp;lt;p align=&amp;quot;center&amp;quot;&amp;gt;&amp;lt;b&amp;gt;&amp;lt;math&amp;gt;\Theta_{k-means}^{d, n} \le \Theta_{init}^{k, d, n} + \Tau*(\Theta_{distribute}^{k, d} + \Theta_{recenter}^{k, d, n})&amp;lt;/math&amp;gt;&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding-bottom: 5px&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;Операции сложения/вычитания:&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p align=&amp;quot;center&amp;quot;&amp;gt;&amp;lt;b&amp;gt;&amp;lt;math&amp;gt;\Theta_{k-means}^{d, n} \le k*n*d+ \Tau*(k*n*(2d-1) + k*n*d) = k*n*d+ \Tau*(k*n*(3d-1)) \thicksim O(\Tau*k*d*n)&amp;lt;/math&amp;gt;&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding-bottom: 20px&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;Операции умножения/деления:&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p align=&amp;quot;center&amp;quot;&amp;gt;&amp;lt;b&amp;gt;&amp;lt;math&amp;gt;\Theta_{k-means}^{d, n} \le k*d + \Tau*(k*n*d + k*d) = k*d + \Tau * k*d*(n+1) \thicksim O(\Tau*k*d*n) &amp;lt;/math&amp;gt;&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding-bottom: 20px&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;Получаем, что &amp;lt;b&amp;gt;временная сложность&amp;lt;/b&amp;gt; алгоритма &amp;lt;b&amp;gt;k means&amp;lt;/b&amp;gt; кластеризации &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; &amp;lt;b&amp;gt;d-мерных&amp;lt;/b&amp;gt; векторов на &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластеров за &amp;lt;math&amp;gt;\Tau&amp;lt;/math&amp;gt; итераций:&amp;lt;/p&amp;gt;&lt;br /&gt;
 &amp;lt;p align=&amp;quot;center&amp;quot;&amp;gt;&amp;lt;b&amp;gt;&amp;lt;math&amp;gt; \Theta_{k-means}^{d, n} \thicksim O(\Tau*k*d*n) &amp;lt;/math&amp;gt;&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Информационный граф ===&lt;br /&gt;
&lt;br /&gt;
Рассмотрим информационный граф алгоритма. Алгоритм &amp;lt;i&amp;gt;k means&amp;lt;/i&amp;gt; начинается с этапа инициализации, после которого следуют итерации, на каждой из которых выполняется два последовательных шага (см. [[#Схема реализации последовательного алгоритма|&amp;quot;Схема реализации последовательного алгоритма&amp;quot;]]): &lt;br /&gt;
* распределение векторов по кластерам&lt;br /&gt;
* перерасчет центров кластеров&lt;br /&gt;
&lt;br /&gt;
Поскольку основная часть вычислений приходится на шаги итераций, распишем информационные графы данных шагов.&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Распределение векторов по кластерам&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
Информационный граф шага распределения векторов по кластерам представлен на &#039;&#039;рисунке 1&#039;&#039;. Исходами данного графа является исходные векторы &amp;lt;math&amp;gt;\mathbf{x}_1, ..., \mathbf{x}_n&amp;lt;/math&amp;gt;, а также центры кластеров &amp;lt;math&amp;gt;\mathbf{\mu}_1, ... \mathbf{\mu}_k&amp;lt;/math&amp;gt;, вычисленные ранее (на шаге инициализации, если рассматривается первая итерация алгоритма, или на шаге пересчета центров кластеров предыдущей итерации в противном случае). Каждая пара векторов данных &amp;lt;math&amp;gt;\mathbf{x}_i, i=\overline{1,n}&amp;lt;/math&amp;gt; и центров кластера &amp;lt;math&amp;gt;\mathbf{\mu}_j, j=\overline{1, k}&amp;lt;/math&amp;gt; : (&amp;lt;math&amp;gt;\mathbf{x}_i&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;\mathbf{\mu}_j&amp;lt;/math&amp;gt;) подаются на независимые узлы &amp;lt;i&amp;gt;&amp;quot;d&amp;quot;&amp;lt;/i&amp;gt; вычисления расстояния между векторами (более подробная схема вычисления расстояния представлена далее, &#039;&#039;рисунок 2&#039;&#039;). Далее узлы вычисления расстояния &amp;lt;i&amp;gt;&amp;quot;d&amp;quot;&amp;lt;/i&amp;gt;, соответствующие одному и тому же исходному вектору &amp;lt;math&amp;gt;\mathbf{x}_i&amp;lt;/math&amp;gt; передаются на один узел &amp;lt;i&amp;gt;&amp;quot;m&amp;quot;&amp;lt;/i&amp;gt;, где далее происходит вычисление новой метки кластера для каждого вектора &amp;lt;math&amp;gt;\mathbf{x}_i&amp;lt;/math&amp;gt; (берется кластер с минимальным результатом вычисления расстояния). На выходе графа выдаются метки кластеров , &amp;lt;math&amp;gt;L_1, ..., L_n&amp;lt;/math&amp;gt;, такие что &amp;lt;math&amp;gt;\forall \mathbf{x}_i, i=\overline{1, n}, \mathbf{x}_i \in S_j \Leftrightarrow L_i = j&amp;lt;/math&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
[[file:Clusterization.png|thumb|center|800px|Рис. 1. Схема распределения векторов по кластерам. &#039;&#039;d&#039;&#039; &amp;amp;ndash; вычисление расстояния между векторами; &#039;&#039;m&#039;&#039; &amp;amp;ndash; вычисление минимума.]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Вычисление расстояния между векторами&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
Подробная схема вычисления расстояния между векторами &amp;lt;math&amp;gt;\mathbf{x}_i, \mathbf{\mu}_j&amp;lt;/math&amp;gt; представлена на &#039;&#039;рисунке 2&#039;&#039;. Как показано на графе, узел вычисления расстояния между векторами &amp;lt;i&amp;gt;&amp;quot;d&amp;quot;&amp;lt;/i&amp;gt; состоит из шага взятия разности между векторами (узел &amp;quot;&amp;lt;math&amp;gt;-&amp;lt;/math&amp;gt;&amp;quot;) и взятия нормы получившегося вектора разности (узел &amp;quot;&amp;lt;math&amp;gt;||\cdot||^2&amp;lt;/math&amp;gt;&amp;quot;). Более подробно, вычисление расстояния между векторами &amp;lt;math&amp;gt;\mathbf{x}_i = {x_{i1,}, ...,{x_{in}}}, \mathbf{\mu}_j = {\mu_{j1}, ...,\mu_{jn}}&amp;lt;/math&amp;gt; может быть представлено как вычисление разности между каждой парой компонент &amp;lt;math&amp;gt;(x_{iz}, \mu_{jz}), z=\overline{1, d}&amp;lt;/math&amp;gt; (узел &amp;quot;&amp;lt;math&amp;gt;-&amp;lt;/math&amp;gt;&amp;quot;), далее возведение в квадрат для каждого узла &amp;quot;&amp;lt;math&amp;gt;-&amp;lt;/math&amp;gt;&amp;quot; (узел &amp;quot;&amp;lt;math&amp;gt;()^2&amp;lt;/math&amp;gt;&amp;quot;) и суммирования выходов всех узлов &amp;quot;&amp;lt;math&amp;gt;()^2&amp;lt;/math&amp;gt;&amp;quot; (узел &amp;quot;&amp;lt;math&amp;gt;+&amp;lt;/math&amp;gt;&amp;quot;).  &lt;br /&gt;
&lt;br /&gt;
[[file:dist_calc.png|thumb|center|800px|Рис. 2. Схема вычисления расстояния между вектором и центром кластера.]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Пересчет центров кластеров&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
Информационный граф шага пересчета центров кластеров представлен на &#039;&#039;рисунке 3&#039;&#039;. Исходами данного графа является исходные векторы &amp;lt;math&amp;gt;\mathbf{x}_1, ..., \mathbf{x}_n&amp;lt;/math&amp;gt;, а также им соответствующие метки кластера, &amp;lt;math&amp;gt;L_1, ..., L_n&amp;lt;/math&amp;gt;, такие что &amp;lt;math&amp;gt;\forall x_i, i=\overline{1, n}, \mathbf{x}_i \in S_j \Leftrightarrow L_i = j&amp;lt;/math&amp;gt;, вычисленные на этапе распределения векторов по кластерам. Все векторы &amp;lt;math&amp;gt;\mathbf{x}_1, ..., \mathbf{x}_n&amp;lt;/math&amp;gt; подаются в узлы &amp;lt;math&amp;gt;+_1, ...+_k&amp;lt;/math&amp;gt;, каждый узел &amp;lt;math&amp;gt;+_m, m = \overline{1,k}&amp;lt;/math&amp;gt; соответствует операции сложения векторов кластера с номером &amp;lt;math&amp;gt;m&amp;lt;/math&amp;gt;. Метки кластера &amp;lt;math&amp;gt;L_1, ..., L_n&amp;lt;/math&amp;gt; также совместно передаются на узлы &amp;lt;math&amp;gt;S_m, m = \overline{1,k}&amp;lt;/math&amp;gt;, на каждом из которых вычисляется количество векторов в соответствующем кластере (количество меток с соответствующим значением). Далее каждая пара выходов узлов &amp;lt;math&amp;gt;+_m&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;S_m&amp;lt;/math&amp;gt; подается на узел &amp;quot;&amp;lt;math&amp;gt;/&amp;lt;/math&amp;gt;&amp;quot;, где производится деление суммы векторов кластера на количество элементов в нем. Значения, вычисленные на узлах &amp;quot;&amp;lt;math&amp;gt;/&amp;lt;/math&amp;gt;&amp;quot;, присваиваются новым центрам кластеров (выходные значения графа).&lt;br /&gt;
&lt;br /&gt;
[[file:Recluster.png|thumb|center|800px|Рис. 3. Схема пересчета центров кластеров]]&lt;br /&gt;
&lt;br /&gt;
=== Ресурс параллелизма алгоритма ===&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
Работа алгоритма состоит из &amp;lt;math&amp;gt;\Tau&amp;lt;/math&amp;gt; итераций, в каждой из которых происходит &amp;lt;b&amp;gt;распределение d-мерных векторов по &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластерам&amp;lt;/b&amp;gt;, а также &amp;lt;b&amp;gt;пересчет центров кластеров в d-мерном пространстве&amp;lt;/b&amp;gt;. В шаге &amp;lt;b&amp;gt;распределения d-мерных векторов по &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластерам&amp;lt;/b&amp;gt; расстояния между вектором и центрами кластеров вычисляются независимо (отсутствуют информационные зависимости). &amp;lt;b&amp;gt;Центры масс кластеров&amp;lt;/b&amp;gt; также пересчитываются независимо друг от друга. Таким образом, имеет место [[глоссарий#Массовый параллелизм|&#039;&#039;массовый параллелизм&#039;&#039;]]. Вычислим параллельную сложность &amp;lt;math&amp;gt;\Psi_*&amp;lt;/math&amp;gt; каждого из шагов, а также параллельную сложность всего алгоритма, &amp;lt;math&amp;gt;\Psi_{k-means}&amp;lt;/math&amp;gt;. Будем исходить из предположения, что может быть использовано любое необходимое число потоков.&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Распределение d-мерных векторов по &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластерам&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;  &lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
Поскольку на данном шаге для каждой пары векторов &amp;lt;math&amp;gt;\mathbf{x}_i, i=\overline{1,n}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\mathbf{\mu}_j, j=\overline{1,k}&amp;lt;/math&amp;gt; операции вычисления расстояния не зависят друг от друга, они могут выполняться параллельно. Тогда, разделив все вычисление расстояний на &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; потоков, получим, что в каждом потоке будет выполняться только одна операция вычисления расстояния между векторами размерности d. При этом каждому вычислительному потоку передаются координаты центров всех кластеров &amp;lt;math&amp;gt;\mathbf{\mu}_1, ..., \mathbf{\mu}_k&amp;lt;/math&amp;gt;. Таким образом, параллельная сложность данного шага определяется &amp;lt;i&amp;gt; сложностью параллельной операции вычисления расстояния между d-мерными векторами&amp;lt;/i&amp;gt;, &amp;lt;math&amp;gt;\Psi_{distance}^d&amp;lt;/math&amp;gt;  и &amp;lt;i&amp;gt;сложностью определения наиболее близкого кластера&amp;lt;/i&amp;gt; (паралельное взятие минимума по расстояниям), &amp;lt;math&amp;gt;\Psi_{min}^k&amp;lt;/math&amp;gt;. Для оценки &amp;lt;math&amp;gt;\Psi_{distance}^d&amp;lt;/math&amp;gt; воспользуемся  [[Нахождение_частных_сумм_элементов_массива_сдваиванием | параллельной реализацией нахождения частичной суммы элементов массива путем сдваивания]]. Аналогично, &amp;lt;math&amp;gt;\Psi_{min}^k = log(k)&amp;lt;/math&amp;gt;. В результате, &amp;lt;math&amp;gt;\Psi_{distance}^d = O(log(d))&amp;lt;/math&amp;gt;.   Таким образом: &lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p align=&amp;quot;center&amp;quot;&amp;gt;&amp;lt;math&amp;gt;\Psi_{distribute}^{k, d}  = \Psi_{distance}^d + \Psi_{min}^k = O(log(d))+O(log(k)) = O(log(k*d))&amp;lt;/math&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Пересчет центров кластеров в d-мерном пространстве&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
Поскольку на данном шаге для каждого из &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластеров центр масс может быть вычислен независимо, данные операции могут быть выполнены в отдельных потоках. Таким образом, параллельная сложность данного шага, &amp;lt;math&amp;gt;\Psi_{recenter}^{k, d}&amp;lt;/math&amp;gt;,  будет определяться &amp;lt;i&amp;gt;параллельной сложностью вычисления одного центра масс кластера размера &amp;lt;math&amp;gt;m&amp;lt;/math&amp;gt;&amp;lt;/i&amp;gt;, &amp;lt;math&amp;gt;\Psi_{recenter}^{k, d}&amp;lt;/math&amp;gt;,  а так как &amp;lt;math&amp;gt;m \le n \Rightarrow \Psi_{recenter}^{d, m} \le \Psi_{recenter}^{d, n}&amp;lt;/math&amp;gt;. Сложность вычисления центра масс кластера d-мерных векторов размера n аналогично предыдущим вычислениям равна &amp;lt;math&amp;gt;O(log(n))&amp;lt;/math&amp;gt;. Тогда:  &lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p align=&amp;quot;center&amp;quot;&amp;gt;&amp;lt;math&amp;gt;\Psi_{recenter}^{k, d}  \le \Psi_{recenter}^{d, n} = O(log(n))&amp;lt;/math&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Общая параллельная сложность алгоритма&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
На каждой итерации необходимо обновление центров кластеров, которые будут использованы на следующей итерации. Таким образом, итерационный процесс выполняется последовательно&amp;lt;ref&amp;gt;Zhao, Weizhong, Huifang Ma, and Qing He. &amp;quot;Parallel k-means clustering based on mapreduce.&amp;quot; IEEE International Conference on Cloud Computing. Springer Berlin Heidelberg, 2009.&amp;lt;/ref&amp;gt;. Тогда, поскольку сложность каждой итерации  определяется &amp;lt;math&amp;gt;\Psi_{distribute}^{k, d}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\Psi_{recenter}&amp;lt;/math&amp;gt;, сложность всего алгоритма, &amp;lt;math&amp;gt;\Psi_{k-means}&amp;lt;/math&amp;gt; в предположении, что было сделано &amp;lt;math&amp;gt;\Tau&amp;lt;/math&amp;gt; операций определяется выражением&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p align=&amp;quot;center&amp;quot;&amp;gt;&amp;lt;math&amp;gt;\Psi_{k-means} \approx \Tau * (\Psi_{distribute}^{k, d} + \Psi_{recenter}^{k, d}) \le \Tau * O(log(k*d*n))&amp;lt;/math&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Входные и выходные данные алгоритма ===&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;Входные данные&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;Матрица из &amp;lt;math&amp;gt;n*d&amp;lt;/math&amp;gt; элементов &amp;lt;math&amp;gt;x_{i, j} \in \mathbb{R}, i=\overline{1, n}, j=\overline{1, d}&amp;lt;/math&amp;gt;&amp;amp;ndash; координат векторов (наблюдений).&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;Целое положительное число &amp;lt;math&amp;gt;k, k \le n&amp;lt;/math&amp;gt; &amp;amp;ndash; количество кластеров.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;Объем входных данных&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;math&amp;gt;1&amp;lt;/math&amp;gt; целое число + &amp;lt;math&amp;gt;n*d&amp;lt;/math&amp;gt; вещественных чисел (при условии, что координаты &amp;amp;ndash; вещественные числа).&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;Выходные данные&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; целых положительных чисел &amp;lt;math&amp;gt;L_1, ..., L_n&amp;lt;/math&amp;gt;&amp;amp;ndash; номера кластеров, соотвествующие каждому вектору (при условии, что нумерация кластеров начинается с &amp;lt;math&amp;gt;1&amp;lt;/math&amp;gt;).&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;Объем выходных данных&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; целых положительных чисел.&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Свойства алгоритма ===&lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;[[глоссарий#Вычислительная мощность|&#039;&#039;Вычислительная мощность&#039;&#039;]]&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
Вычислительная мощность алгоритма &amp;lt;i&amp;gt;k means&amp;lt;/i&amp;gt; равна &amp;lt;math&amp;gt;\frac{k*d*n*\Tau}{n*d} = k*\Tau &amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; &amp;amp;ndash; число кластеров, &amp;lt;math&amp;gt;\Tau&amp;lt;/math&amp;gt; &amp;amp;ndash; число итераций алгоритма.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;[[глоссарий#Детерминированность |&#039;&#039;Детерминированность&#039;&#039;]] и [[глоссарий#Устойчивость |&#039;&#039;Устойчивость&#039;&#039;]] &amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
Алгоритм &amp;lt;i&amp;gt;k means&amp;lt;/i&amp;gt; является итерационным. Количество итераций алгоритма в общем случае не фиксируется и зависит от начального расположения объектов в пространстве, параметра &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt;, а также от начального приближения центров кластеров, &amp;lt;math&amp;gt;\mu_1, ..., \mu_k&amp;lt;/math&amp;gt;. В результате этого может варьироваться результат работы алгоритма. При неудачном выборе начальных параметров итерационный процесс может сойтись к локальному оптимуму&amp;lt;ref&amp;gt;Von Luxburg, Ulrike. Clustering Stability. Now Publishers Inc, 2010.&amp;lt;/ref&amp;gt;. По этим причинам алгоритм не является ни &amp;lt;b&amp;gt;детермирированным&amp;lt;/b&amp;gt;, ни &amp;lt;b&amp;gt;устойчивым&amp;lt;/b&amp;gt;.&lt;br /&gt;
 &lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Соотношение последовательной и параллельной сложности алгоритма&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\frac{\Theta_{k-means}}{\Psi_{k-means}} = \frac{O(\Tau*k*d*n)}{O(\Tau*log(k*d*n))}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Сильные стороны алгоритма&amp;lt;/b&amp;gt;:&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;i&amp;gt;Сравнительно высокая эффективность при простоте реализации&amp;lt;/i&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;i&amp;gt;Высокое качество кластеризации&amp;lt;/i&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;i&amp;gt;Возможность распараллеливания&amp;lt;/i&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;i&amp;gt;Существование множества модификаций&amp;lt;/i&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;Недостатки алгоритма&amp;lt;/b&amp;gt;&amp;lt;ref&amp;gt;Ortega, Joaquín Pérez, Ma Del Rocío Boone Rojas, and María J. Somodevilla. &amp;quot;Research issues on K-means Algorithm: An Experimental Trial Using Matlab.&amp;quot;&amp;lt;/ref&amp;gt;:&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;i&amp;gt;Количество кластеров является параметром алгоритма&amp;lt;/i&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;&amp;lt;i&amp;gt;Чувствительность к начальным условиям&amp;lt;/i&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;Инициализация центров кластеров в значительной степени влияет на результат кластеризации.&amp;lt;/p&amp;gt;&lt;br /&gt;
  &amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;&amp;lt;i&amp;gt;Чувствительность к выбросам и шумам&amp;lt;/i&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;Выбросы, далекие от центров настоящих кластеров, все равно учитываются при вычислении их центров.&amp;lt;/p&amp;gt;&lt;br /&gt;
  &amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;&amp;lt;i&amp;gt;Возможность сходимости к локальному оптимуму&amp;lt;/i&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;Итеративный подход не дает гарантии сходимости к оптимальному решению.&amp;lt;/p&amp;gt;&lt;br /&gt;
  &amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;&amp;lt;i&amp;gt;Использование понятия &amp;quot;среднего&amp;quot;&amp;lt;/i&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;Алгоритм неприменим к данным, для которых не определено понятие &amp;quot;среднего&amp;quot;, например, категориальным данным.&amp;lt;/p&amp;gt;&lt;br /&gt;
  &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&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;
Исследование масштабируемости параллельной реализации алгоритма k means проводилось на суперкомпьютере &amp;quot;Ломоносов&amp;quot;. Алгоритм реализован на языке C с использованием средств MPI.&lt;br /&gt;
Для исследования масштабируемости проводилось множество запусков программы с разным значением параметра (количество векторов для кластеризации), а также с различным числом процессоров. Фиксировались результаты запусков &amp;amp;ndash; время работы &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt; и количество произведенных итераций алгоритма &amp;lt;math&amp;gt;\Tau&amp;lt;/math&amp;gt;.&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;Значения &amp;lt;b&amp;gt;количества векторов&amp;lt;/b&amp;gt; &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;: 20&#039;000, 30&#039;000, 50&#039;000, 100&#039;000, 200&#039;000, 300&#039;000, 500&#039;000, 700&#039;000, 1&#039;000&#039;000, 1&#039;500&#039;000, 2&#039;000&#039;000.&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;Значения &amp;lt;b&amp;gt;количества процессоров&amp;lt;/b&amp;gt; &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt;: 1, 8, 16, 32, 64, 128, 160, 192, 224, 256, 288, 320, 352, 384, 416, 448, 480, 512.&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;Значение &amp;lt;b&amp;gt;количества кластеров&amp;lt;/b&amp;gt; &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt;: 100.&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;Значение &amp;lt;b&amp;gt;размерности векторов&amp;lt;/b&amp;gt; &amp;lt;math&amp;gt;d&amp;lt;/math&amp;gt;: 10.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Графики производительности и эффективности реализации представлены на рисунках 4 и 5 соответственно.&lt;br /&gt;
&lt;br /&gt;
[[file:Flops.png|thumb|center|800px|Рис. 4. График производительности реализации алгоритма.]]&lt;br /&gt;
&lt;br /&gt;
[[file:Efficiency.png|thumb|center|800px|Рис. 5. График эффективности реализации алгоритма.]]&lt;br /&gt;
&lt;br /&gt;
Для заданной конфигурации эксперимента (&amp;lt;math&amp;gt;n, p, k&amp;lt;/math&amp;gt;) и полученных результатах (&amp;lt;math&amp;gt;t, \Tau&amp;lt;/math&amp;gt;) производительность и эффективность реализации расчитывались по формулам (см. [[#Последовательная сложность алгоритма| последовательная сложность алгоритма]]):&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
&amp;lt;ul&amp;gt;&amp;lt;li&amp;gt;&amp;lt;math&amp;gt;Performance = \frac{\Theta_{k-means}^{d, n}}{t}\ \ FLOPS&amp;lt;/math&amp;gt;&amp;lt;/li&amp;gt;&amp;lt;/ul&amp;gt;&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
&amp;lt;ul&amp;gt;&amp;lt;li&amp;gt;&amp;lt;math&amp;gt;Efficiency = \frac{100 * Performance}{Performance_{Peak}^{p}}\ \ %,&amp;lt;/math&amp;gt;&amp;lt;/li&amp;gt;&amp;lt;/ul&amp;gt;&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
где &amp;lt;math&amp;gt;Performance_{Peak}^{p}&amp;lt;/math&amp;gt; &amp;amp;ndash; пиковая производительность суперкомпьютера при &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt; процессорах, вычисленная согласно спецификациям&amp;lt;ref&amp;gt;&amp;quot;http://ark.intel.com/ru/products/47920/Intel-Xeon-Processor-X5670-12M-Cache-2_93-GHz-6_40-GTs-Intel-QPI&amp;quot;&amp;lt;/ref&amp;gt; Intel&amp;amp;reg; XEON&amp;amp;reg; X5670)&lt;br /&gt;
&lt;br /&gt;
В результате экспериментальной оценки были получены следующие оценки эффективности реализации:&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;b&amp;gt;Минимальное&amp;lt;/b&amp;gt; значение: 0.000409 %&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;b&amp;gt;Максимальное&amp;lt;/b&amp;gt; значение: 0.741119 %&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Динамические характеристики и эффективность реализации алгоритма ===&lt;br /&gt;
=== Выводы для классов архитектур ===&lt;br /&gt;
=== Существующие реализации алгоритма ===&lt;br /&gt;
==== Открытое программное обеспечение ====&lt;br /&gt;
&amp;lt;ol&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;[https://www.icpsr.umich.edu/CrimeStat/ CrimeStat]&amp;lt;/li&amp;gt; Программное обеспечение, созданное для операционных систем Windows, предоставляющее инструменты статистического  и пространственного анализа для решения задачи картирования преступности.&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://juliastats.github.io Julia]&amp;lt;/li&amp;gt; Высокоуровневый высокопроизводительный свободный язык программирования с динамической типизацией, созданный для математических вычислений, содержит реализацию k-means.&lt;br /&gt;
  &amp;lt;li&amp;gt;[https://mahout.apache.org Mahout]&amp;lt;/li&amp;gt; Apache Mahout - Java библиотека для работы с алгоритмами машинного обучения с использованием MapReduce. Содержит реализацию k-means.&lt;br /&gt;
  &amp;lt;li&amp;gt;[https://www.gnu.org/software/octave/ Octave]&amp;lt;/li&amp;gt; Написанная на C++  свободная система для математических вычислений, использующая совместимый с MATLAB язык высокого уровня, содержит реализацию k-means.&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://spark.apache.org/docs/latest/mllib-clustering.html Spark]&amp;lt;/li&amp;gt; Распределенная реализация k-means содержится в библиотеке Mlib для работы с алгоритмами машинного обучения, взаимодействующая с Python библиотекой NumPy и библиотека R.&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://torch.ch Torch]&amp;lt;/li&amp;gt;  MATLAB-подобная библиотека для языка программирования Lua с открытым исходным кодом, предоставляет большое количество алгоритмов для глубинного обучения и научных расчётов. Ядро написано на Си, прикладная часть выполняется на LuaJIT, поддерживается распараллеливание вычислений средствами CUDA и OpenMP. Существуют реализации k-means.&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://www.cs.waikato.ac.nz/ml/weka/ Weka]&amp;lt;/li&amp;gt;  Cвободное программное обеспечение для анализа данных, написанное на Java. Содержит k-means и x-means.&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://accord-framework.net/docs/html/T_Accord_MachineLearning_KMeans.htm Accord.NET]&amp;lt;/li&amp;gt; C# реализация алгоритмов k-means, k-means++, k-modes.&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://docs.opencv.org/3.0-beta/doc/py_tutorials/py_ml/py_kmeans/py_kmeans_opencv/py_kmeans_opencv.html OpenCV]&amp;lt;/li&amp;gt; Написанная на С++ библиотека, направленная в основном на решение задач компьютерного зрения. Содержит реализацию k-means.&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://mlpack.org/ MLPACK]&amp;lt;/li&amp;gt; Масштабируемая С++ библиотека для работы с алгоритмами машинного обучения, содержит реализацию k-means.&lt;br /&gt;
  &amp;lt;li&amp;gt;[https://www.scipy.org/ SciPy]&amp;lt;/li&amp;gt; Библиотека Python, содержит множество реализаций k-means.&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://scikit-learn.org/ scikit-learn]&amp;lt;/li&amp;gt; Библиотека Python, содержит множество реализаций k-means.&lt;br /&gt;
  &amp;lt;li&amp;gt;[https://www.r-bloggers.com/k-means-clustering-in-r/ R]&amp;lt;/li&amp;gt; Язык программирования для статистической обработки данных и работы с графикой, а также свободная программная среда вычислений с открытым исходным кодом в рамках проекта GNU, содержит три реализации k-means.&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://elki.dbs.ifi.lmu.de ELKI]&amp;lt;/li&amp;gt; Java фреймворк, содержащий реализацию k-means, а также множество других алгоритмов кластеризации.&lt;br /&gt;
&amp;lt;/ol&amp;gt;&lt;br /&gt;
==== Проприетарное программное обеспечение  ====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ol&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;[https://www.ayasdi.com/blog/bigdata/topological-data-analysis-of-oil-and-gas-petrophysical-data/ Ayasdi]&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://www.stata.com/features/cluster-analysis/ Stata]&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://mathworld.wolfram.com/K-MeansClusteringAlgorithm.html Mathematica]&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://www.mathworks.com/help/stats/kmeans.html?requestedDomain=www.mathworks.com MATLAB]&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;[https://support.sas.com/rnd/app/stat/procedures/fastclus.html SAS]&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://docs.rapidminer.com/studio/operators/modeling/segmentation/k_means.html RapidMiner]&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;[https://blogs.sap.com/2013/03/28/sap-hana-pal-k-means-algorithm-or-how-to-do-customer-segmentation-for-the-telecommunications-industry/ SAP HANA]&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ol&amp;gt;&lt;br /&gt;
== Литература ==&lt;br /&gt;
&amp;lt;references /&amp;gt;&lt;/div&gt;</summary>
		<author><name>DennZo1993</name></author>
	</entry>
	<entry>
		<id>https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:%D0%91%D1%80%D0%BE%D1%82%D0%B8%D0%BA%D0%BE%D0%B2%D1%81%D0%BA%D0%B0%D1%8F_%D0%94%D0%B0%D0%BD%D1%83%D1%82%D0%B0/%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_k-means&amp;diff=17168</id>
		<title>Участник:Бротиковская Данута/Алгоритм k-means</title>
		<link rel="alternate" type="text/html" href="https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:%D0%91%D1%80%D0%BE%D1%82%D0%B8%D0%BA%D0%BE%D0%B2%D1%81%D0%BA%D0%B0%D1%8F_%D0%94%D0%B0%D0%BD%D1%83%D1%82%D0%B0/%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_k-means&amp;diff=17168"/>
		<updated>2016-11-14T23:49:57Z</updated>

		<summary type="html">&lt;p&gt;DennZo1993: /* Масштабируемость реализации алгоритма */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt; {{Assignment|Zhum}}&lt;br /&gt;
&lt;br /&gt;
{{algorithm&lt;br /&gt;
| name              = Алгоритм k средних (k means)&lt;br /&gt;
| serial_complexity = &amp;lt;math&amp;gt;O(\Tau*k*d*n)&amp;lt;/math&amp;gt;&lt;br /&gt;
| input_data        = &amp;lt;math&amp;gt; d*n &amp;lt;/math&amp;gt;&lt;br /&gt;
| output_data       = &amp;lt;math&amp;gt; n &amp;lt;/math&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
Авторы страницы &amp;lt;b&amp;gt;[[Участник:Бротиковская Данута|Данута Бротиковская]]&amp;lt;/b&amp;gt; и &amp;lt;b&amp;gt;[[Участник:DennZo1993|Денис Зобнин]]&amp;lt;/b&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
Оба автора внесли одинаковый вклад в написание статьи (поиск материалов, изучение статей, заполнение контента статьи), четких разграничений по пунктам статьи сделать невозможно. &lt;br /&gt;
&lt;br /&gt;
== Свойства и структура алгоритма ==&lt;br /&gt;
&lt;br /&gt;
=== Общее описание алгоритма ===&lt;br /&gt;
Алгоритм &amp;lt;b&amp;gt;&amp;lt;i&amp;gt;k средних&amp;lt;/i&amp;gt;&amp;lt;/b&amp;gt; (&amp;lt;b&amp;gt;&amp;lt;i&amp;gt;k means&amp;lt;/i&amp;gt;&amp;lt;/b&amp;gt;) &amp;amp;ndash; неиерархический&amp;lt;ref&amp;gt;&amp;quot;https://ru.wikipedia.org/wiki/Иерархическая_кластеризация&amp;quot;&amp;lt;/ref&amp;gt;, итерационный метод кластеризации&amp;lt;ref&amp;gt;&amp;quot;https://ru.wikipedia.org/wiki/Кластерный_анализ&amp;quot;&amp;lt;/ref&amp;gt;, получивший большую популярность благодаря своей простоте, наглядности реализации и достаточно высокому качеству работы. Был изобретен в 1950-х годах математиком &amp;lt;i&amp;gt;Гуго Штейнгаузом&amp;lt;/i&amp;gt;&amp;lt;ref&amp;gt;Steinhaus, Hugo. &amp;quot;Sur la division des corp materiels en parties.&amp;quot; Bull. Acad. Polon. Sci 1.804 (1956): 801.&amp;lt;/ref&amp;gt; и почти одновременно &amp;lt;i&amp;gt;Стюартом Ллойдом&amp;lt;/i&amp;gt;&amp;lt;ref&amp;gt;Lloyd, S. P. &amp;quot;Least square quantization in PCM. Bell Telephone Laboratories Paper. Published in journal much later: Lloyd, SP: Least squares quantization in PCM.&amp;quot; IEEE Trans. Inform. Theor.(1957/1982).&amp;lt;/ref&amp;gt;. Особую популярность приобрел после публикации работы &amp;lt;i&amp;gt;МакКуина&amp;lt;/i&amp;gt;&amp;lt;ref&amp;gt;MacQueen, James. &amp;quot;Some methods for classification and analysis of multivariate observations.&amp;quot; Proceedings of the fifth Berkeley symposium on mathematical statistics and probability. Vol. 1. No. 14. 1967.&amp;lt;/ref&amp;gt; в 1967.&lt;br /&gt;
&lt;br /&gt;
Алгоритм представляет собой версию EM-алгоритма&amp;lt;ref&amp;gt;&amp;quot;https://ru.wikipedia.org/wiki/EM-алгоритм&amp;quot;&amp;lt;/ref&amp;gt;, применяемого также для разделения смеси гауссиан. Основная идея &amp;lt;i&amp;gt;k means&amp;lt;/i&amp;gt; заключается в том, что данные произвольно разбиваются на кластеры, после чего итеративно перевычисляется центр масс для каждого кластера, полученного на предыдущем шаге, затем векторы разбиваются на кластеры вновь в соответствии с тем, какой из новых центров оказался ближе по выбранной метрике.&lt;br /&gt;
&lt;br /&gt;
Цель алгоритма заключается в разделении &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; наблюдений на &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластеров таким образом, чтобы каждое наблюдение принадлежало ровно одному кластеру, расположенному на наименьшем расстоянии от наблюдения.&lt;br /&gt;
&lt;br /&gt;
=== Математическое описание алгоритма ===&lt;br /&gt;
&amp;lt;b&amp;gt;&amp;lt;u&amp;gt;Дано:&amp;lt;/u&amp;gt;&amp;lt;/b&amp;gt;&lt;br /&gt;
* набор из &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; наблюдений &amp;lt;math&amp;gt;X=\{\mathbf{x}_1, \mathbf{x}_2, ..., \mathbf{x}_n\}, \mathbf{x}_i \in \mathbb{R}^d, i=\overline{1, n}&amp;lt;/math&amp;gt;;&lt;br /&gt;
* &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; - требуемое число кластеров, &amp;lt;math&amp;gt;k \in \mathbb{N}, k \leq n&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;&amp;lt;u&amp;gt;Требуется:&amp;lt;/u&amp;gt;&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Разделить множество наблюдений &amp;lt;math&amp;gt;X&amp;lt;/math&amp;gt; на &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластеров &amp;lt;math&amp;gt;S_1, S_2, ..., S_k&amp;lt;/math&amp;gt;:&lt;br /&gt;
*   &amp;lt;math&amp;gt;S_i \cap S_j= \varnothing, \quad i \ne j&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
*   &amp;lt;math&amp;gt;\bigcup_{i=1}^{k} S_i = X&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;&amp;lt;u&amp;gt;Действие алгоритма:&amp;lt;/u&amp;gt;&amp;lt;/b&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;Алгоритм &amp;lt;i&amp;gt;k means&amp;lt;/i&amp;gt; разбивает набор &amp;lt;math&amp;gt;X&amp;lt;/math&amp;gt; на &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; наборов &amp;lt;math&amp;gt;S_1, S_2, ..., S_k,&amp;lt;/math&amp;gt; таким образом, чтобы минимизировать сумму квадратов расстояний от каждой точки кластера до его центра (центр масс кластера). Введем обозначение, &amp;lt;math&amp;gt;S=\{S_1, S_2, ..., S_k\}&amp;lt;/math&amp;gt;. Тогда действие алгоритма &amp;lt;i&amp;gt;k means&amp;lt;/i&amp;gt; равносильно поиску:&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;table style=&amp;quot;width:100%&amp;quot;&amp;gt;&lt;br /&gt;
  &amp;lt;tr&amp;gt;&lt;br /&gt;
    &amp;lt;td align=&amp;quot;center&amp;quot; width=&amp;quot;90%&amp;quot;&amp;gt;&amp;lt;math&amp;gt;\arg\min_{S} \sum\limits_{i=1}^k \sum\limits_{\mathbf{x} \in S_i} \rho(\mathbf{x}, \mathbf{\mu}_i )^2,&amp;lt;/math&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;td align=&amp;quot;right&amp;quot;&amp;gt;&amp;lt;math&amp;gt;(1)&amp;lt;/math&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;/table&amp;gt;&lt;br /&gt;
где &amp;lt;math&amp;gt;\mathbf{\mu}_i&amp;lt;/math&amp;gt; &amp;amp;ndash; центры кластеров, &amp;lt;math&amp;gt;i=\overline{1,k}, \quad \rho(\mathbf{x}, \mathbf{\mu}_i)&amp;lt;/math&amp;gt; &amp;amp;ndash; функция расстояния между &amp;lt;math&amp;gt;\mathbf{x}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\mu_i&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;&amp;lt;u&amp;gt;Шаги алгоритма: &amp;lt;/u&amp;gt;&amp;lt;/b&amp;gt;&lt;br /&gt;
&amp;lt;ol&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&lt;br /&gt;
    &amp;lt;b&amp;gt;Начальный шаг: инициализация кластеров&amp;lt;/b&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;Выбирается произвольное множество точек &amp;lt;math&amp;gt;\mu_i, i=\overline{1,k}&amp;lt;/math&amp;gt;, рассматриваемых как начальные центры кластеров: &amp;lt;math&amp;gt;\mu_i^{(0)} = \mu_i, \quad i=\overline{1, k}&amp;lt;/math&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
  &amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&lt;br /&gt;
    &amp;lt;b&amp;gt;Распределение векторов по кластерам&amp;lt;/b&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Шаг&amp;lt;/b&amp;gt; &amp;lt;math&amp;gt;t: \forall \mathbf{x}_i \in X, i=\overline{1,n}: \mathbf{x}_i \in S_j \iff  j=\arg\min_{k}\rho(\mathbf{x}_i,\mathbf{\mu}_k^{(t-1)})^2&amp;lt;/math&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
  &amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&lt;br /&gt;
    &amp;lt;b&amp;gt;Пересчет центров кластеров&amp;lt;/b&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Шаг &amp;lt;/b&amp;gt; &amp;lt;math&amp;gt;t: \forall i=\overline{1,k}:  \mu_i^{(t)} = \cfrac{1}{|S_i|}\sum_{\mathbf{x}\in S_i}\mathbf{x}&amp;lt;/math&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
  &amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&lt;br /&gt;
    &amp;lt;b&amp;gt;Проверка условия останова:&amp;lt;/b&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
    &#039;&#039;&#039;if&#039;&#039;&#039; &amp;lt;math&amp;gt;\exist i\in \overline{1,k}: \mu_i^{(t)} \ne \mu_i^{(t-1)}&amp;lt;/math&amp;gt; &#039;&#039;&#039;then&#039;&#039;&#039;&lt;br /&gt;
        t = t + 1;&lt;br /&gt;
        goto 2;&lt;br /&gt;
    &#039;&#039;&#039;else&#039;&#039;&#039;&lt;br /&gt;
        &#039;&#039;&#039;stop&#039;&#039;&#039;&lt;br /&gt;
  &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ol&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Вычислительное ядро алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Вычислительным ядром являются шаги 2 и 3 приведенного выше алгоритма: &amp;lt;b&amp;gt;&amp;lt;i&amp;gt;распределение векторов по кластерам&amp;lt;/i&amp;gt;&amp;lt;/b&amp;gt; и &amp;lt;b&amp;gt;&amp;lt;i&amp;gt;пересчет центров кластеров&amp;lt;/i&amp;gt;&amp;lt;/b&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;&amp;lt;i&amp;gt;Распределение векторов&amp;lt;/i&amp;gt;&amp;lt;/b&amp;gt; по кластерам предполагает вычисление расстояний между каждым вектором &amp;lt;math&amp;gt;\mathbf{x}_i \in X, i= \overline{1,n}&amp;lt;/math&amp;gt; и центрами кластера &amp;lt;math&amp;gt;\mathbf{\mu}_j, j= \overline{1,k}&amp;lt;/math&amp;gt;. Таким образом, данный шаг предполагает &amp;lt;math&amp;gt;k*n&amp;lt;/math&amp;gt; вычислений расстояний между d-мерными векторами. &lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;&amp;lt;i&amp;gt;Пересчет центров кластеров&amp;lt;/i&amp;gt;&amp;lt;/b&amp;gt; предполагает &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; вычислений центров масс &amp;lt;math&amp;gt;\mathbf{\mu}_i&amp;lt;/math&amp;gt; множеств &amp;lt;math&amp;gt;S_i, i=\overline{1,k}&amp;lt;/math&amp;gt; представленных выражением в шаге 3 представленного выше алгоритма.&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Макроструктура алгоритма ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Инициализация центров масс &amp;lt;math&amp;gt;\mu_1, ..., \mu_k&amp;lt;/math&amp;gt;&amp;lt;/b&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
Наиболее распространенными являются следующие стратегии:&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&lt;br /&gt;
    &amp;lt;b&amp;gt;Метод Forgy&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;В качестве начальных значений &amp;lt;math&amp;gt;\mu_1, ..., \mu_k&amp;lt;/math&amp;gt; берутся случайно выбранные векторы.&lt;br /&gt;
  &amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&lt;br /&gt;
    &amp;lt;b&amp;gt;Метод случайно разделения (Random Partitioning)&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;Для каждого вектора &amp;lt;math&amp;gt;\mathbf{x}_i \in X, i=\overline{1, n}&amp;lt;/math&amp;gt; выбирается случайным образом кластер &amp;lt;math&amp;gt;S_1, ..., S_k&amp;lt;/math&amp;gt;, после чего для каждого полученного кластера вычисляются значения &amp;lt;math&amp;gt;\mu_1, ..., \mu_k&amp;lt;/math&amp;gt;.&lt;br /&gt;
  &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Распределение векторов по кластерам&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Для этого шага алгоритма между векторами &amp;lt;math&amp;gt;\mathbf{x}_i \in X, i=\overline{1, n}&amp;lt;/math&amp;gt; и центрами кластеров &amp;lt;math&amp;gt;\mu_1, ..., \mu_k&amp;lt;/math&amp;gt; вычисляются &amp;lt;b&amp;gt;расстояния&amp;lt;/b&amp;gt; по формуле (как правило, используется Евлидово расстояние):&lt;br /&gt;
&amp;lt;table style=&amp;quot;width:100%&amp;quot;&amp;gt;&lt;br /&gt;
  &amp;lt;tr&amp;gt;&lt;br /&gt;
    &amp;lt;td align=&amp;quot;center&amp;quot; width=&amp;quot;90%&amp;quot;&amp;gt;&amp;lt;math&amp;gt; \mathbf{v}_1, \mathbf{v}_2 \in \mathbb{R}^d,  \quad \rho(\mathbf{v}_1, \mathbf{v}_2) = \lVert \mathbf{v}_1- \mathbf{v}_2 \rVert= \sqrt{\sum_{i=1}^{d}(\mathbf{v}_{1,i} - \mathbf{v}_{2,i})^2}&amp;lt;/math&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;td align=&amp;quot;right&amp;quot;&amp;gt;&amp;lt;math&amp;gt;(2)&amp;lt;/math&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;/table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Пересчет центров кластеров&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Для этого шага алгоритма производится пересчет центров кластера по &amp;lt;b&amp;gt;формуле вычисления центра масс&amp;lt;/b&amp;gt;:&lt;br /&gt;
&amp;lt;table style=&amp;quot;width:100%&amp;quot;&amp;gt;&lt;br /&gt;
  &amp;lt;tr&amp;gt;&lt;br /&gt;
    &amp;lt;td align=&amp;quot;center&amp;quot; width=&amp;quot;90%&amp;quot;&amp;gt;&amp;lt;math&amp;gt; \mu = \cfrac{1}{|S|}\sum_{\mathbf{x}\in S}\mathbf{x}&amp;lt;/math&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;td align=&amp;quot;right&amp;quot;&amp;gt;&amp;lt;math&amp;gt;(3)&amp;lt;/math&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;/table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Схема реализации последовательного алгоритма ===&lt;br /&gt;
&lt;br /&gt;
 &#039;&#039;&#039;algorithm&#039;&#039;&#039; k-means &#039;&#039;&#039;is&#039;&#039;&#039;&lt;br /&gt;
     &#039;&#039;&#039;1.&#039;&#039;&#039; Инициализировать центры кластеров &amp;lt;math&amp;gt;\mathbf{\mu}_i^{(1)}, i=\overline{1,k}&amp;lt;/math&amp;gt;&lt;br /&gt;
     &#039;&#039;&#039;2.&#039;&#039;&#039; &amp;lt;math&amp;gt;t \leftarrow 1&amp;lt;/math&amp;gt;&lt;br /&gt;
     &#039;&#039;&#039;3.&#039;&#039;&#039; &#039;&#039;&#039;Распределение по кластерам&#039;&#039;&#039;&amp;lt;br&amp;gt;&lt;br /&gt;
        &amp;lt;math&amp;gt;S_i^{(t)}=\{\mathbf{x}_p: \lVert\mathbf{x}_p-\mathbf{\mu}_i^{(t)}\rVert^2 \leq \lVert\mathbf{x}_p-\mathbf{\mu}_j^{(t)}\rVert^2 \quad \forall j=\overline{1,k}\},&amp;lt;/math&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
        где каждый вектор &amp;lt;math&amp;gt;\mathbf{x}_p&amp;lt;/math&amp;gt; соотносится единственному кластеру &amp;lt;math&amp;gt;S^{(t)}&amp;lt;/math&amp;gt;&lt;br /&gt;
     &#039;&#039;&#039;4.&#039;&#039;&#039; &#039;&#039;&#039;Обновление центров кластеров&#039;&#039;&#039;&amp;lt;br&amp;gt;&lt;br /&gt;
        &amp;lt;math&amp;gt;\mathbf{\mu}_i^{(t+1)} = \frac{1}{|S^{(t)}_i|} \sum_{\mathbf{x}_j \in S^{(t)}_i} \mathbf{x}_j &amp;lt;/math&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
     &#039;&#039;&#039;5.&#039;&#039;&#039; &#039;&#039;&#039;if&#039;&#039;&#039; &amp;lt;math&amp;gt;\exist i \in \overline{1,k}: \mathbf{\mu}_i^{(t+1)} \ne \mathbf{\mu}_i^{(t)}&amp;lt;/math&amp;gt; &#039;&#039;&#039;then&#039;&#039;&#039;&lt;br /&gt;
            t = t + 1;&lt;br /&gt;
            goto &#039;&#039;&#039;3&#039;&#039;&#039;;&lt;br /&gt;
        &#039;&#039;&#039;else&#039;&#039;&#039;&lt;br /&gt;
            &#039;&#039;&#039;stop&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
=== Последовательная сложность алгоритма===&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding-bottom: 20px&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;Обозначим &amp;lt;math&amp;gt;\Theta_{centroid}^{d, m}&amp;lt;/math&amp;gt; временную сложность вычисления центорида кластера, число элементов которого равна &amp;lt;math&amp;gt;m&amp;lt;/math&amp;gt;,  в d-мерном пространстве.&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;Аналогично  &amp;lt;math&amp;gt;\Theta_{distance}^d&amp;lt;/math&amp;gt; &amp;amp;ndash; временная сложность вычисления расстояния между двумя d-мерными векторами.&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding-bottom: 20px&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;Сложность шага инициализации &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластеров мощности &amp;lt;math&amp;gt;m&amp;lt;/math&amp;gt; в d-мерном пространстве &amp;amp;ndash; &amp;lt;math&amp;gt;\Theta_{init}^{k, d, m}&amp;lt;/math&amp;gt;&amp;lt;/b&amp;gt;&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;i&amp;gt;Стратерия Forgy&amp;lt;/i&amp;gt;: вычисления не требуются, &amp;lt;math&amp;gt;\Theta_{init}^{k, d, m} = 0&amp;lt;/math&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;i&amp;gt;Стратегия случайного разбиения&amp;lt;/i&amp;gt;: вычисление центров &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластеров,  &amp;lt;math&amp;gt;\Theta_{init}^{k, d, m} = k*\Theta_{centroid}^{d, m}, m \le n&amp;lt;/math&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding-bottom: 20px&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Cложность шага распределения d мерных векторов по &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластерам &amp;amp;ndash; &amp;lt;math&amp;gt;\Theta_{distribute}^{k, d}&amp;lt;/math&amp;gt;&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
На этом шаге для каждого вектора &amp;lt;math&amp;gt;\mathbf{x}_i \in X, i=\overline{1, n}&amp;lt;/math&amp;gt; вычисляется k расстояний до центров кластеров &amp;lt;math&amp;gt;\mathbf{\mu}_1, ...\mathbf{\mu}_k&amp;lt;/math&amp;gt;&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p align=&amp;quot;center&amp;quot;&amp;gt;&lt;br /&gt;
  &amp;lt;math&amp;gt;\Theta_{distribute}^{k, d} = n*k*\Theta_{distance}^d&amp;lt;/math&amp;gt;&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding-bottom: 20px&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;Сложность шага пересчета центров &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластеров размера &amp;lt;math&amp;gt;m&amp;lt;/math&amp;gt; в d-мерном пространстве &amp;amp;ndash; &amp;lt;math&amp;gt;\Theta_{recenter}^{k, d, m}&amp;lt;/math&amp;gt;&amp;lt;/b&amp;gt;&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;На этом шаге вычисляется &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; центров кластеров &amp;lt;math&amp;gt;\mathbf{\mu}_1, ...\mathbf{\mu}_k&amp;lt;/math&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p align=&amp;quot;center&amp;quot;&amp;gt;&amp;lt;math&amp;gt;\Theta_{recenter}^{k, d, m} = k*\Theta_{centroid}^{d, m}&amp;lt;/math&amp;gt; &amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding-bottom: 20px&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Рассчитаем &amp;lt;math&amp;gt;\Theta_{centroid}^{d, m}&amp;lt;/math&amp;gt; для кластера, число элементов которого равно &amp;lt;math&amp;gt;m&amp;lt;/math&amp;gt;&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p align=&amp;quot;center&amp;quot;&amp;gt;&amp;lt;math&amp;gt;\Theta_{centroid}^{d, m}&amp;lt;/math&amp;gt; = &amp;lt;math&amp;gt;m * d&amp;lt;/math&amp;gt; сложений + &amp;lt;math&amp;gt;d&amp;lt;/math&amp;gt; делений &amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding-bottom: 20px&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Рассчитаем &amp;lt;math&amp;gt;\Theta_{distance}^d&amp;lt;/math&amp;gt; в соответствие с формулой &amp;lt;math&amp;gt;(2)&amp;lt;/math&amp;gt;&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p align=&amp;quot;center&amp;quot;&amp;gt;&amp;lt;math&amp;gt;\Theta_{distance}^d&amp;lt;/math&amp;gt; = &amp;lt;math&amp;gt;d&amp;lt;/math&amp;gt; вычитаний + &amp;lt;math&amp;gt;d&amp;lt;/math&amp;gt; умножений + &amp;lt;math&amp;gt;(d-1)&amp;lt;/math&amp;gt; сложение&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding-bottom: 20px&amp;quot;&amp;gt;&lt;br /&gt;
  &amp;lt;p&amp;gt;Предположим, что алгоритм сошелся за &amp;lt;math&amp;gt;\Tau&amp;lt;/math&amp;gt; итераций, тогда временная сложность алгоритма &amp;lt;math&amp;gt;\Theta_{k-means}^{d, n}&amp;lt;/math&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
  &amp;lt;p align=&amp;quot;center&amp;quot;&amp;gt;&amp;lt;b&amp;gt;&amp;lt;math&amp;gt;\Theta_{k-means}^{d, n} \le \Theta_{init}^{k, d, n} + \Tau*(\Theta_{distribute}^{k, d} + \Theta_{recenter}^{k, d, n})&amp;lt;/math&amp;gt;&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding-bottom: 5px&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;Операции сложения/вычитания:&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p align=&amp;quot;center&amp;quot;&amp;gt;&amp;lt;b&amp;gt;&amp;lt;math&amp;gt;\Theta_{k-means}^{d, n} \le k*n*d+ \Tau*(k*n*(2d-1) + k*n*d) = k*n*d+ \Tau*(k*n*(3d-1)) \thicksim O(\Tau*k*d*n)&amp;lt;/math&amp;gt;&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding-bottom: 20px&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;Операции умножения/деления:&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p align=&amp;quot;center&amp;quot;&amp;gt;&amp;lt;b&amp;gt;&amp;lt;math&amp;gt;\Theta_{k-means}^{d, n} \le k*d + \Tau*(k*n*d + k*d) = k*d + \Tau * k*d*(n+1) \thicksim O(\Tau*k*d*n) &amp;lt;/math&amp;gt;&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding-bottom: 20px&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;Получаем, что &amp;lt;b&amp;gt;временная сложность&amp;lt;/b&amp;gt; алгоритма &amp;lt;b&amp;gt;k means&amp;lt;/b&amp;gt; кластеризации &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; &amp;lt;b&amp;gt;d-мерных&amp;lt;/b&amp;gt; векторов на &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластеров за &amp;lt;math&amp;gt;\Tau&amp;lt;/math&amp;gt; итераций:&amp;lt;/p&amp;gt;&lt;br /&gt;
 &amp;lt;p align=&amp;quot;center&amp;quot;&amp;gt;&amp;lt;b&amp;gt;&amp;lt;math&amp;gt; \Theta_{k-means}^{d, n} \thicksim O(\Tau*k*d*n) &amp;lt;/math&amp;gt;&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Информационный граф ===&lt;br /&gt;
&lt;br /&gt;
Рассмотрим информационный граф алгоритма. Алгоритм &amp;lt;i&amp;gt;k means&amp;lt;/i&amp;gt; начинается с этапа инициализации, после которого следуют итерации, на каждой из которых выполняется два последовательных шага (см. [[#Схема реализации последовательного алгоритма|&amp;quot;Схема реализации последовательного алгоритма&amp;quot;]]): &lt;br /&gt;
* распределение векторов по кластерам&lt;br /&gt;
* перерасчет центров кластеров&lt;br /&gt;
&lt;br /&gt;
Поскольку основная часть вычислений приходится на шаги итераций, распишем информационные графы данных шагов.&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Распределение векторов по кластерам&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
Информационный граф шага распределения векторов по кластерам представлен на &#039;&#039;рисунке 1&#039;&#039;. Исходами данного графа является исходные векторы &amp;lt;math&amp;gt;\mathbf{x}_1, ..., \mathbf{x}_n&amp;lt;/math&amp;gt;, а также центры кластеров &amp;lt;math&amp;gt;\mathbf{\mu}_1, ... \mathbf{\mu}_k&amp;lt;/math&amp;gt;, вычисленные ранее (на шаге инициализации, если рассматривается первая итерация алгоритма, или на шаге пересчета центров кластеров предыдущей итерации в противном случае). Каждая пара векторов данных &amp;lt;math&amp;gt;\mathbf{x}_i, i=\overline{1,n}&amp;lt;/math&amp;gt; и центров кластера &amp;lt;math&amp;gt;\mathbf{\mu}_j, j=\overline{1, k}&amp;lt;/math&amp;gt; : (&amp;lt;math&amp;gt;\mathbf{x}_i&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;\mathbf{\mu}_j&amp;lt;/math&amp;gt;) подаются на независимые узлы &amp;lt;i&amp;gt;&amp;quot;d&amp;quot;&amp;lt;/i&amp;gt; вычисления расстояния между векторами (более подробная схема вычисления расстояния представлена далее, &#039;&#039;рисунок 2&#039;&#039;). Далее узлы вычисления расстояния &amp;lt;i&amp;gt;&amp;quot;d&amp;quot;&amp;lt;/i&amp;gt;, соответствующие одному и тому же исходному вектору &amp;lt;math&amp;gt;\mathbf{x}_i&amp;lt;/math&amp;gt; передаются на один узел &amp;lt;i&amp;gt;&amp;quot;m&amp;quot;&amp;lt;/i&amp;gt;, где далее происходит вычисление новой метки кластера для каждого вектора &amp;lt;math&amp;gt;\mathbf{x}_i&amp;lt;/math&amp;gt; (берется кластер с минимальным результатом вычисления расстояния). На выходе графа выдаются метки кластеров , &amp;lt;math&amp;gt;L_1, ..., L_n&amp;lt;/math&amp;gt;, такие что &amp;lt;math&amp;gt;\forall \mathbf{x}_i, i=\overline{1, n}, \mathbf{x}_i \in S_j \Leftrightarrow L_i = j&amp;lt;/math&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
[[file:Clusterization.png|thumb|center|800px|Рис. 1. Схема распределения векторов по кластерам. &#039;&#039;d&#039;&#039; &amp;amp;ndash; вычисление расстояния между векторами; &#039;&#039;m&#039;&#039; &amp;amp;ndash; вычисление минимума.]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Вычисление расстояния между векторами&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
Подробная схема вычисления расстояния между векторами &amp;lt;math&amp;gt;\mathbf{x}_i, \mathbf{\mu}_j&amp;lt;/math&amp;gt; представлена на &#039;&#039;рисунке 2&#039;&#039;. Как показано на графе, узел вычисления расстояния между векторами &amp;lt;i&amp;gt;&amp;quot;d&amp;quot;&amp;lt;/i&amp;gt; состоит из шага взятия разности между векторами (узел &amp;quot;&amp;lt;math&amp;gt;-&amp;lt;/math&amp;gt;&amp;quot;) и взятия нормы получившегося вектора разности (узел &amp;quot;&amp;lt;math&amp;gt;||\cdot||^2&amp;lt;/math&amp;gt;&amp;quot;). Более подробно, вычисление расстояния между векторами &amp;lt;math&amp;gt;\mathbf{x}_i = {x_{i1,}, ...,{x_{in}}}, \mathbf{\mu}_j = {\mu_{j1}, ...,\mu_{jn}}&amp;lt;/math&amp;gt; может быть представлено как вычисление разности между каждой парой компонент &amp;lt;math&amp;gt;(x_{iz}, \mu_{jz}), z=\overline{1, d}&amp;lt;/math&amp;gt; (узел &amp;quot;&amp;lt;math&amp;gt;-&amp;lt;/math&amp;gt;&amp;quot;), далее возведение в квадрат для каждого узла &amp;quot;&amp;lt;math&amp;gt;-&amp;lt;/math&amp;gt;&amp;quot; (узел &amp;quot;&amp;lt;math&amp;gt;()^2&amp;lt;/math&amp;gt;&amp;quot;) и суммирования выходов всех узлов &amp;quot;&amp;lt;math&amp;gt;()^2&amp;lt;/math&amp;gt;&amp;quot; (узел &amp;quot;&amp;lt;math&amp;gt;+&amp;lt;/math&amp;gt;&amp;quot;).  &lt;br /&gt;
&lt;br /&gt;
[[file:dist_calc.png|thumb|center|800px|Рис. 2. Схема вычисления расстояния между вектором и центром кластера.]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Пересчет центров кластеров&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
Информационный граф шага пересчета центров кластеров представлен на &#039;&#039;рисунке 3&#039;&#039;. Исходами данного графа является исходные векторы &amp;lt;math&amp;gt;\mathbf{x}_1, ..., \mathbf{x}_n&amp;lt;/math&amp;gt;, а также им соответствующие метки кластера, &amp;lt;math&amp;gt;L_1, ..., L_n&amp;lt;/math&amp;gt;, такие что &amp;lt;math&amp;gt;\forall x_i, i=\overline{1, n}, \mathbf{x}_i \in S_j \Leftrightarrow L_i = j&amp;lt;/math&amp;gt;, вычисленные на этапе распределения векторов по кластерам. Все векторы &amp;lt;math&amp;gt;\mathbf{x}_1, ..., \mathbf{x}_n&amp;lt;/math&amp;gt; подаются в узлы &amp;lt;math&amp;gt;+_1, ...+_k&amp;lt;/math&amp;gt;, каждый узел &amp;lt;math&amp;gt;+_m, m = \overline{1,k}&amp;lt;/math&amp;gt; соответствует операции сложения векторов кластера с номером &amp;lt;math&amp;gt;m&amp;lt;/math&amp;gt;. Метки кластера &amp;lt;math&amp;gt;L_1, ..., L_n&amp;lt;/math&amp;gt; также совместно передаются на узлы &amp;lt;math&amp;gt;S_m, m = \overline{1,k}&amp;lt;/math&amp;gt;, на каждом из которых вычисляется количество векторов в соответствующем кластере (количество меток с соответствующим значением). Далее каждая пара выходов узлов &amp;lt;math&amp;gt;+_m&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;S_m&amp;lt;/math&amp;gt; подается на узел &amp;quot;&amp;lt;math&amp;gt;/&amp;lt;/math&amp;gt;&amp;quot;, где производится деление суммы векторов кластера на количество элементов в нем. Значения, вычисленные на узлах &amp;quot;&amp;lt;math&amp;gt;/&amp;lt;/math&amp;gt;&amp;quot;, присваиваются новым центрам кластеров (выходные значения графа).&lt;br /&gt;
&lt;br /&gt;
[[file:Recluster.png|thumb|center|800px|Рис. 3. Схема пересчета центров кластеров]]&lt;br /&gt;
&lt;br /&gt;
=== Ресурс параллелизма алгоритма ===&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
Работа алгоритма состоит из &amp;lt;math&amp;gt;\Tau&amp;lt;/math&amp;gt; итераций, в каждой из которых происходит &amp;lt;b&amp;gt;распределение d-мерных векторов по &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластерам&amp;lt;/b&amp;gt;, а также &amp;lt;b&amp;gt;пересчет центров кластеров в d-мерном пространстве&amp;lt;/b&amp;gt;. В шаге &amp;lt;b&amp;gt;распределения d-мерных векторов по &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластерам&amp;lt;/b&amp;gt; расстояния между вектором и центрами кластеров вычисляются независимо (отсутствуют информационные зависимости). &amp;lt;b&amp;gt;Центры масс кластеров&amp;lt;/b&amp;gt; также пересчитываются независимо друг от друга. Таким образом, имеет место [[глоссарий#Массовый параллелизм|&#039;&#039;массовый параллелизм&#039;&#039;]]. Вычислим параллельную сложность &amp;lt;math&amp;gt;\Psi_*&amp;lt;/math&amp;gt; каждого из шагов, а также параллельную сложность всего алгоритма, &amp;lt;math&amp;gt;\Psi_{k-means}&amp;lt;/math&amp;gt;. Будем исходить из предположения, что может быть использовано любое необходимое число потоков.&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Распределение d-мерных векторов по &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластерам&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;  &lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
Поскольку на данном шаге для каждой пары векторов &amp;lt;math&amp;gt;\mathbf{x}_i, i=\overline{1,n}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\mathbf{\mu}_j, j=\overline{1,k}&amp;lt;/math&amp;gt; операции вычисления расстояния не зависят друг от друга, они могут выполняться параллельно. Тогда, разделив все вычисление расстояний на &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; потоков, получим, что в каждом потоке будет выполняться только одна операция вычисления расстояния между векторами размерности d. При этом каждому вычислительному потоку передаются координаты центров всех кластеров &amp;lt;math&amp;gt;\mathbf{\mu}_1, ..., \mathbf{\mu}_k&amp;lt;/math&amp;gt;. Таким образом, параллельная сложность данного шага определяется &amp;lt;i&amp;gt; сложностью параллельной операции вычисления расстояния между d-мерными векторами&amp;lt;/i&amp;gt;, &amp;lt;math&amp;gt;\Psi_{distance}^d&amp;lt;/math&amp;gt;  и &amp;lt;i&amp;gt;сложностью определения наиболее близкого кластера&amp;lt;/i&amp;gt; (паралельное взятие минимума по расстояниям), &amp;lt;math&amp;gt;\Psi_{min}^k&amp;lt;/math&amp;gt;. Для оценки &amp;lt;math&amp;gt;\Psi_{distance}^d&amp;lt;/math&amp;gt; воспользуемся  [[Нахождение_частных_сумм_элементов_массива_сдваиванием | параллельной реализацией нахождения частичной суммы элементов массива путем сдваивания]]. Аналогично, &amp;lt;math&amp;gt;\Psi_{min}^k = log(k)&amp;lt;/math&amp;gt;. В результате, &amp;lt;math&amp;gt;\Psi_{distance}^d = O(log(d))&amp;lt;/math&amp;gt;.   Таким образом: &lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p align=&amp;quot;center&amp;quot;&amp;gt;&amp;lt;math&amp;gt;\Psi_{distribute}^{k, d}  = \Psi_{distance}^d + \Psi_{min}^k = O(log(d))+O(log(k)) = O(log(k*d))&amp;lt;/math&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Пересчет центров кластеров в d-мерном пространстве&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
Поскольку на данном шаге для каждого из &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластеров центр масс может быть вычислен независимо, данные операции могут быть выполнены в отдельных потоках. Таким образом, параллельная сложность данного шага, &amp;lt;math&amp;gt;\Psi_{recenter}^{k, d}&amp;lt;/math&amp;gt;,  будет определяться &amp;lt;i&amp;gt;параллельной сложностью вычисления одного центра масс кластера размера &amp;lt;math&amp;gt;m&amp;lt;/math&amp;gt;&amp;lt;/i&amp;gt;, &amp;lt;math&amp;gt;\Psi_{recenter}^{k, d}&amp;lt;/math&amp;gt;,  а так как &amp;lt;math&amp;gt;m \le n \Rightarrow \Psi_{recenter}^{d, m} \le \Psi_{recenter}^{d, n}&amp;lt;/math&amp;gt;. Сложность вычисления центра масс кластера d-мерных векторов размера n аналогично предыдущим вычислениям равна &amp;lt;math&amp;gt;O(log(n))&amp;lt;/math&amp;gt;. Тогда:  &lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p align=&amp;quot;center&amp;quot;&amp;gt;&amp;lt;math&amp;gt;\Psi_{recenter}^{k, d}  \le \Psi_{recenter}^{d, n} = O(log(n))&amp;lt;/math&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Общая параллельная сложность алгоритма&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
На каждой итерации необходимо обновление центров кластеров, которые будут использованы на следующей итерации. Таким образом, итерационный процесс выполняется последовательно&amp;lt;ref&amp;gt;Zhao, Weizhong, Huifang Ma, and Qing He. &amp;quot;Parallel k-means clustering based on mapreduce.&amp;quot; IEEE International Conference on Cloud Computing. Springer Berlin Heidelberg, 2009.&amp;lt;/ref&amp;gt;. Тогда, поскольку сложность каждой итерации  определяется &amp;lt;math&amp;gt;\Psi_{distribute}^{k, d}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\Psi_{recenter}&amp;lt;/math&amp;gt;, сложность всего алгоритма, &amp;lt;math&amp;gt;\Psi_{k-means}&amp;lt;/math&amp;gt; в предположении, что было сделано &amp;lt;math&amp;gt;\Tau&amp;lt;/math&amp;gt; операций определяется выражением&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p align=&amp;quot;center&amp;quot;&amp;gt;&amp;lt;math&amp;gt;\Psi_{k-means} \approx \Tau * (\Psi_{distribute}^{k, d} + \Psi_{recenter}^{k, d}) \le \Tau * O(log(k*d*n))&amp;lt;/math&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Входные и выходные данные алгоритма ===&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;Входные данные&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;Матрица из &amp;lt;math&amp;gt;n*d&amp;lt;/math&amp;gt; элементов &amp;lt;math&amp;gt;x_{i, j} \in \mathbb{R}, i=\overline{1, n}, j=\overline{1, d}&amp;lt;/math&amp;gt;&amp;amp;ndash; координат векторов (наблюдений).&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;Целое положительное число &amp;lt;math&amp;gt;k, k \le n&amp;lt;/math&amp;gt; &amp;amp;ndash; количество кластеров.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;Объем входных данных&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;math&amp;gt;1&amp;lt;/math&amp;gt; целое число + &amp;lt;math&amp;gt;n*d&amp;lt;/math&amp;gt; вещественных чисел (при условии, что координаты &amp;amp;ndash; вещественные числа).&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;Выходные данные&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; целых положительных чисел &amp;lt;math&amp;gt;L_1, ..., L_n&amp;lt;/math&amp;gt;&amp;amp;ndash; номера кластеров, соотвествующие каждому вектору (при условии, что нумерация кластеров начинается с &amp;lt;math&amp;gt;1&amp;lt;/math&amp;gt;).&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;Объем выходных данных&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; целых положительных чисел.&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Свойства алгоритма ===&lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;[[глоссарий#Вычислительная мощность|&#039;&#039;Вычислительная мощность&#039;&#039;]]&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
Вычислительная мощность алгоритма &amp;lt;i&amp;gt;k means&amp;lt;/i&amp;gt; равна &amp;lt;math&amp;gt;\frac{k*d*n*\Tau}{n*d} = k*\Tau &amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; &amp;amp;ndash; число кластеров, &amp;lt;math&amp;gt;\Tau&amp;lt;/math&amp;gt; &amp;amp;ndash; число итераций алгоритма.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;[[глоссарий#Детерминированность |&#039;&#039;Детерминированность&#039;&#039;]] и [[глоссарий#Устойчивость |&#039;&#039;Устойчивость&#039;&#039;]] &amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
Алгоритм &amp;lt;i&amp;gt;k means&amp;lt;/i&amp;gt; является итерационным. Количество итераций алгоритма в общем случае не фиксируется и зависит от начального расположения объектов в пространстве, параметра &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt;, а также от начального приближения центров кластеров, &amp;lt;math&amp;gt;\mu_1, ..., \mu_k&amp;lt;/math&amp;gt;. В результате этого может варьироваться результат работы алгоритма. При неудачном выборе начальных параметров итерационный процесс может сойтись к локальному оптимуму&amp;lt;ref&amp;gt;Von Luxburg, Ulrike. Clustering Stability. Now Publishers Inc, 2010.&amp;lt;/ref&amp;gt;. По этим причинам алгоритм не является ни &amp;lt;b&amp;gt;детермирированным&amp;lt;/b&amp;gt;, ни &amp;lt;b&amp;gt;устойчивым&amp;lt;/b&amp;gt;.&lt;br /&gt;
 &lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Соотношение последовательной и параллельной сложности алгоритма&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\frac{\Theta_{k-means}}{\Psi_{k-means}} = \frac{O(\Tau*k*d*n)}{O(\Tau*log(k*d*n))}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Сильные стороны алгоритма&amp;lt;/b&amp;gt;:&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;i&amp;gt;Сравнительно высокая эффективность при простоте реализации&amp;lt;/i&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;i&amp;gt;Высокое качество кластеризации&amp;lt;/i&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;i&amp;gt;Возможность распараллеливания&amp;lt;/i&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;i&amp;gt;Существование множества модификаций&amp;lt;/i&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;Недостатки алгоритма&amp;lt;/b&amp;gt;&amp;lt;ref&amp;gt;Ortega, Joaquín Pérez, Ma Del Rocío Boone Rojas, and María J. Somodevilla. &amp;quot;Research issues on K-means Algorithm: An Experimental Trial Using Matlab.&amp;quot;&amp;lt;/ref&amp;gt;:&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;i&amp;gt;Количество кластеров является параметром алгоритма&amp;lt;/i&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;&amp;lt;i&amp;gt;Чувствительность к начальным условиям&amp;lt;/i&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;Инициализация центров кластеров в значительной степени влияет на результат кластеризации.&amp;lt;/p&amp;gt;&lt;br /&gt;
  &amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;&amp;lt;i&amp;gt;Чувствительность к выбросам и шумам&amp;lt;/i&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;Выбросы, далекие от центров настоящих кластеров, все равно учитываются при вычислении их центров.&amp;lt;/p&amp;gt;&lt;br /&gt;
  &amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;&amp;lt;i&amp;gt;Возможность сходимости к локальному оптимуму&amp;lt;/i&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;Итеративный подход не дает гарантии сходимости к оптимальному решению.&amp;lt;/p&amp;gt;&lt;br /&gt;
  &amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;&amp;lt;i&amp;gt;Использование понятия &amp;quot;среднего&amp;quot;&amp;lt;/i&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;Алгоритм неприменим к данным, для которых не определено понятие &amp;quot;среднего&amp;quot;, например, категориальным данным.&amp;lt;/p&amp;gt;&lt;br /&gt;
  &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&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;
Исследование масштабируемости параллельной реализации алгоритма k means проводилось на суперкомпьютере &amp;quot;Ломоносов&amp;quot;. Алгоритм реализован на языке C с использованием средств MPI.&lt;br /&gt;
Для исследования масштабируемости проводилось множество запусков программы с разным значением параметра (количество векторов для кластеризации), а также с различным числом процессоров. Фиксировались результаты запусков &amp;amp;ndash; время работы &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt; и количество произведенных итераций алгоритма &amp;lt;math&amp;gt;\Tau&amp;lt;/math&amp;gt;.&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;Значения &amp;lt;b&amp;gt;количества векторов&amp;lt;/b&amp;gt; &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;: 20&#039;000, 30&#039;000, 50&#039;000, 100&#039;000, 200&#039;000, 300&#039;000, 500&#039;000, 700&#039;000, 1&#039;000&#039;000, 1&#039;500&#039;000, 2&#039;000&#039;000.&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;Значения &amp;lt;b&amp;gt;количества процессоров&amp;lt;/b&amp;gt; &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt;: 1, 8, 16, 32, 64, 128, 160, 192, 224, 256, 288, 320, 352, 384, 416, 448, 480, 512.&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;Значение &amp;lt;b&amp;gt;количества кластеров&amp;lt;/b&amp;gt; &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt;: 100.&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;Значение &amp;lt;b&amp;gt;размерности векторов&amp;lt;/b&amp;gt; &amp;lt;math&amp;gt;d&amp;lt;/math&amp;gt;: 10.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Графики производительности и эффективности реализации представлены на рисунках 4 и 5 соответственно.&lt;br /&gt;
&lt;br /&gt;
[[file:Flops.png|thumb|center|800px|Рис. 4. График производительности реализации алгоритма.]]&lt;br /&gt;
&lt;br /&gt;
[[file:Efficiency.png|thumb|center|800px|Рис. 5. График эффективности реализации алгоритма.]]&lt;br /&gt;
&lt;br /&gt;
Для заданной конфигурации эксперимента (&amp;lt;math&amp;gt;n, p, k&amp;lt;/math&amp;gt;) и полученных результатах (&amp;lt;math&amp;gt;t, \Tau&amp;lt;/math&amp;gt;) производительность и эффективность реализации расчитывались по формулам (см. [[#Последовательная сложность алгоритма| последовательная сложность алгоритма]]):&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
&amp;lt;ul&amp;gt;&amp;lt;li&amp;gt;&amp;lt;math&amp;gt;Performance = \frac{\Theta_{k-means}^{d, n}}{t}\ \ FLOPS&amp;lt;/math&amp;gt;&amp;lt;/li&amp;gt;&amp;lt;/ul&amp;gt;&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
&amp;lt;ul&amp;gt;&amp;lt;li&amp;gt;&amp;lt;math&amp;gt;Efficiency = \frac{100 * Performance}{Performance_{Peak}^{p}}\ \ %,&amp;lt;/math&amp;gt;&amp;lt;/li&amp;gt;&amp;lt;/ul&amp;gt;&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
где &amp;lt;math&amp;gt;Performance_{Peak}^{p}&amp;lt;/math&amp;gt; &amp;amp;ndash; пиковая производительность суперкомпьютера при &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt; процессорах, вычисленная согласно спецификациям Intel&amp;amp;reg; XEON&amp;amp;reg; X5670)&lt;br /&gt;
&lt;br /&gt;
В результате экспериментальной оценки были получены следующие оценки эффективности реализации:&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;b&amp;gt;Минимальное&amp;lt;/b&amp;gt; значение: 0.000409 %&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;b&amp;gt;Максимальное&amp;lt;/b&amp;gt; значение: 0.741119 %&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Динамические характеристики и эффективность реализации алгоритма ===&lt;br /&gt;
=== Выводы для классов архитектур ===&lt;br /&gt;
=== Существующие реализации алгоритма ===&lt;br /&gt;
==== Открытое программное обеспечение ====&lt;br /&gt;
&amp;lt;ol&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;[https://www.icpsr.umich.edu/CrimeStat/ CrimeStat]&amp;lt;/li&amp;gt; Программное обеспечение, созданное для операционных систем Windows, предоставляющее инструменты статистического  и пространственного анализа для решения задачи картирования преступности.&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://juliastats.github.io Julia]&amp;lt;/li&amp;gt; Высокоуровневый высокопроизводительный свободный язык программирования с динамической типизацией, созданный для математических вычислений, содержит реализацию k-means.&lt;br /&gt;
  &amp;lt;li&amp;gt;[https://mahout.apache.org Mahout]&amp;lt;/li&amp;gt; Apache Mahout - Java библиотека для работы с алгоритмами машинного обучения с использованием MapReduce. Содержит реализацию k-means.&lt;br /&gt;
  &amp;lt;li&amp;gt;[https://www.gnu.org/software/octave/ Octave]&amp;lt;/li&amp;gt; Написанная на C++  свободная система для математических вычислений, использующая совместимый с MATLAB язык высокого уровня, содержит реализацию k-means.&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://spark.apache.org/docs/latest/mllib-clustering.html Spark]&amp;lt;/li&amp;gt; Распределенная реализация k-means содержится в библиотеке Mlib для работы с алгоритмами машинного обучения, взаимодействующая с Python библиотекой NumPy и библиотека R.&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://torch.ch Torch]&amp;lt;/li&amp;gt;  MATLAB-подобная библиотека для языка программирования Lua с открытым исходным кодом, предоставляет большое количество алгоритмов для глубинного обучения и научных расчётов. Ядро написано на Си, прикладная часть выполняется на LuaJIT, поддерживается распараллеливание вычислений средствами CUDA и OpenMP. Существуют реализации k-means.&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://www.cs.waikato.ac.nz/ml/weka/ Weka]&amp;lt;/li&amp;gt;  Cвободное программное обеспечение для анализа данных, написанное на Java. Содержит k-means и x-means.&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://accord-framework.net/docs/html/T_Accord_MachineLearning_KMeans.htm Accord.NET]&amp;lt;/li&amp;gt; C# реализация алгоритмов k-means, k-means++, k-modes.&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://docs.opencv.org/3.0-beta/doc/py_tutorials/py_ml/py_kmeans/py_kmeans_opencv/py_kmeans_opencv.html OpenCV]&amp;lt;/li&amp;gt; Написанная на С++ библиотека, направленная в основном на решение задач компьютерного зрения. Содержит реализацию k-means.&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://mlpack.org/ MLPACK]&amp;lt;/li&amp;gt; Масштабируемая С++ библиотека для работы с алгоритмами машинного обучения, содержит реализацию k-means.&lt;br /&gt;
  &amp;lt;li&amp;gt;[https://www.scipy.org/ SciPy]&amp;lt;/li&amp;gt; Библиотека Python, содержит множество реализаций k-means.&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://scikit-learn.org/ scikit-learn]&amp;lt;/li&amp;gt; Библиотека Python, содержит множество реализаций k-means.&lt;br /&gt;
  &amp;lt;li&amp;gt;[https://www.r-bloggers.com/k-means-clustering-in-r/ R]&amp;lt;/li&amp;gt; Язык программирования для статистической обработки данных и работы с графикой, а также свободная программная среда вычислений с открытым исходным кодом в рамках проекта GNU, содержит три реализации k-means.&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://elki.dbs.ifi.lmu.de ELKI]&amp;lt;/li&amp;gt; Java фреймворк, содержащий реализацию k-means, а также множество других алгоритмов кластеризации.&lt;br /&gt;
&amp;lt;/ol&amp;gt;&lt;br /&gt;
==== Проприетарное программное обеспечение  ====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ol&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;[https://www.ayasdi.com/blog/bigdata/topological-data-analysis-of-oil-and-gas-petrophysical-data/ Ayasdi]&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://www.stata.com/features/cluster-analysis/ Stata]&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://mathworld.wolfram.com/K-MeansClusteringAlgorithm.html Mathematica]&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://www.mathworks.com/help/stats/kmeans.html?requestedDomain=www.mathworks.com MATLAB]&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;[https://support.sas.com/rnd/app/stat/procedures/fastclus.html SAS]&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://docs.rapidminer.com/studio/operators/modeling/segmentation/k_means.html RapidMiner]&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;[https://blogs.sap.com/2013/03/28/sap-hana-pal-k-means-algorithm-or-how-to-do-customer-segmentation-for-the-telecommunications-industry/ SAP HANA]&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ol&amp;gt;&lt;br /&gt;
== Литература ==&lt;br /&gt;
&amp;lt;references /&amp;gt;&lt;/div&gt;</summary>
		<author><name>DennZo1993</name></author>
	</entry>
	<entry>
		<id>https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:%D0%91%D1%80%D0%BE%D1%82%D0%B8%D0%BA%D0%BE%D0%B2%D1%81%D0%BA%D0%B0%D1%8F_%D0%94%D0%B0%D0%BD%D1%83%D1%82%D0%B0/%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_k-means&amp;diff=17167</id>
		<title>Участник:Бротиковская Данута/Алгоритм k-means</title>
		<link rel="alternate" type="text/html" href="https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:%D0%91%D1%80%D0%BE%D1%82%D0%B8%D0%BA%D0%BE%D0%B2%D1%81%D0%BA%D0%B0%D1%8F_%D0%94%D0%B0%D0%BD%D1%83%D1%82%D0%B0/%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_k-means&amp;diff=17167"/>
		<updated>2016-11-14T23:38:07Z</updated>

		<summary type="html">&lt;p&gt;DennZo1993: /* Масштабируемость реализации алгоритма */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt; {{Assignment|Zhum}}&lt;br /&gt;
&lt;br /&gt;
{{algorithm&lt;br /&gt;
| name              = Алгоритм k средних (k means)&lt;br /&gt;
| serial_complexity = &amp;lt;math&amp;gt;O(\Tau*k*d*n)&amp;lt;/math&amp;gt;&lt;br /&gt;
| input_data        = &amp;lt;math&amp;gt; d*n &amp;lt;/math&amp;gt;&lt;br /&gt;
| output_data       = &amp;lt;math&amp;gt; n &amp;lt;/math&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
Авторы страницы &amp;lt;b&amp;gt;[[Участник:Бротиковская Данута|Данута Бротиковская]]&amp;lt;/b&amp;gt; и &amp;lt;b&amp;gt;[[Участник:DennZo1993|Денис Зобнин]]&amp;lt;/b&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
Оба автора внесли одинаковый вклад в написание статьи (поиск материалов, изучение статей, заполнение контента статьи), четких разграничений по пунктам статьи сделать невозможно. &lt;br /&gt;
&lt;br /&gt;
== Свойства и структура алгоритма ==&lt;br /&gt;
&lt;br /&gt;
=== Общее описание алгоритма ===&lt;br /&gt;
Алгоритм &amp;lt;b&amp;gt;&amp;lt;i&amp;gt;k средних&amp;lt;/i&amp;gt;&amp;lt;/b&amp;gt; (&amp;lt;b&amp;gt;&amp;lt;i&amp;gt;k means&amp;lt;/i&amp;gt;&amp;lt;/b&amp;gt;) &amp;amp;ndash; неиерархический&amp;lt;ref&amp;gt;&amp;quot;https://ru.wikipedia.org/wiki/Иерархическая_кластеризация&amp;quot;&amp;lt;/ref&amp;gt;, итерационный метод кластеризации&amp;lt;ref&amp;gt;&amp;quot;https://ru.wikipedia.org/wiki/Кластерный_анализ&amp;quot;&amp;lt;/ref&amp;gt;, получивший большую популярность благодаря своей простоте, наглядности реализации и достаточно высокому качеству работы. Был изобретен в 1950-х годах математиком &amp;lt;i&amp;gt;Гуго Штейнгаузом&amp;lt;/i&amp;gt;&amp;lt;ref&amp;gt;Steinhaus, Hugo. &amp;quot;Sur la division des corp materiels en parties.&amp;quot; Bull. Acad. Polon. Sci 1.804 (1956): 801.&amp;lt;/ref&amp;gt; и почти одновременно &amp;lt;i&amp;gt;Стюартом Ллойдом&amp;lt;/i&amp;gt;&amp;lt;ref&amp;gt;Lloyd, S. P. &amp;quot;Least square quantization in PCM. Bell Telephone Laboratories Paper. Published in journal much later: Lloyd, SP: Least squares quantization in PCM.&amp;quot; IEEE Trans. Inform. Theor.(1957/1982).&amp;lt;/ref&amp;gt;. Особую популярность приобрел после публикации работы &amp;lt;i&amp;gt;МакКуина&amp;lt;/i&amp;gt;&amp;lt;ref&amp;gt;MacQueen, James. &amp;quot;Some methods for classification and analysis of multivariate observations.&amp;quot; Proceedings of the fifth Berkeley symposium on mathematical statistics and probability. Vol. 1. No. 14. 1967.&amp;lt;/ref&amp;gt; в 1967.&lt;br /&gt;
&lt;br /&gt;
Алгоритм представляет собой версию EM-алгоритма&amp;lt;ref&amp;gt;&amp;quot;https://ru.wikipedia.org/wiki/EM-алгоритм&amp;quot;&amp;lt;/ref&amp;gt;, применяемого также для разделения смеси гауссиан. Основная идея &amp;lt;i&amp;gt;k means&amp;lt;/i&amp;gt; заключается в том, что данные произвольно разбиваются на кластеры, после чего итеративно перевычисляется центр масс для каждого кластера, полученного на предыдущем шаге, затем векторы разбиваются на кластеры вновь в соответствии с тем, какой из новых центров оказался ближе по выбранной метрике.&lt;br /&gt;
&lt;br /&gt;
Цель алгоритма заключается в разделении &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; наблюдений на &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластеров таким образом, чтобы каждое наблюдение принадлежало ровно одному кластеру, расположенному на наименьшем расстоянии от наблюдения.&lt;br /&gt;
&lt;br /&gt;
=== Математическое описание алгоритма ===&lt;br /&gt;
&amp;lt;b&amp;gt;&amp;lt;u&amp;gt;Дано:&amp;lt;/u&amp;gt;&amp;lt;/b&amp;gt;&lt;br /&gt;
* набор из &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; наблюдений &amp;lt;math&amp;gt;X=\{\mathbf{x}_1, \mathbf{x}_2, ..., \mathbf{x}_n\}, \mathbf{x}_i \in \mathbb{R}^d, i=\overline{1, n}&amp;lt;/math&amp;gt;;&lt;br /&gt;
* &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; - требуемое число кластеров, &amp;lt;math&amp;gt;k \in \mathbb{N}, k \leq n&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;&amp;lt;u&amp;gt;Требуется:&amp;lt;/u&amp;gt;&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Разделить множество наблюдений &amp;lt;math&amp;gt;X&amp;lt;/math&amp;gt; на &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластеров &amp;lt;math&amp;gt;S_1, S_2, ..., S_k&amp;lt;/math&amp;gt;:&lt;br /&gt;
*   &amp;lt;math&amp;gt;S_i \cap S_j= \varnothing, \quad i \ne j&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
*   &amp;lt;math&amp;gt;\bigcup_{i=1}^{k} S_i = X&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;&amp;lt;u&amp;gt;Действие алгоритма:&amp;lt;/u&amp;gt;&amp;lt;/b&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;Алгоритм &amp;lt;i&amp;gt;k means&amp;lt;/i&amp;gt; разбивает набор &amp;lt;math&amp;gt;X&amp;lt;/math&amp;gt; на &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; наборов &amp;lt;math&amp;gt;S_1, S_2, ..., S_k,&amp;lt;/math&amp;gt; таким образом, чтобы минимизировать сумму квадратов расстояний от каждой точки кластера до его центра (центр масс кластера). Введем обозначение, &amp;lt;math&amp;gt;S=\{S_1, S_2, ..., S_k\}&amp;lt;/math&amp;gt;. Тогда действие алгоритма &amp;lt;i&amp;gt;k means&amp;lt;/i&amp;gt; равносильно поиску:&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;table style=&amp;quot;width:100%&amp;quot;&amp;gt;&lt;br /&gt;
  &amp;lt;tr&amp;gt;&lt;br /&gt;
    &amp;lt;td align=&amp;quot;center&amp;quot; width=&amp;quot;90%&amp;quot;&amp;gt;&amp;lt;math&amp;gt;\arg\min_{S} \sum\limits_{i=1}^k \sum\limits_{\mathbf{x} \in S_i} \rho(\mathbf{x}, \mathbf{\mu}_i )^2,&amp;lt;/math&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;td align=&amp;quot;right&amp;quot;&amp;gt;&amp;lt;math&amp;gt;(1)&amp;lt;/math&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;/table&amp;gt;&lt;br /&gt;
где &amp;lt;math&amp;gt;\mathbf{\mu}_i&amp;lt;/math&amp;gt; &amp;amp;ndash; центры кластеров, &amp;lt;math&amp;gt;i=\overline{1,k}, \quad \rho(\mathbf{x}, \mathbf{\mu}_i)&amp;lt;/math&amp;gt; &amp;amp;ndash; функция расстояния между &amp;lt;math&amp;gt;\mathbf{x}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\mu_i&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;&amp;lt;u&amp;gt;Шаги алгоритма: &amp;lt;/u&amp;gt;&amp;lt;/b&amp;gt;&lt;br /&gt;
&amp;lt;ol&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&lt;br /&gt;
    &amp;lt;b&amp;gt;Начальный шаг: инициализация кластеров&amp;lt;/b&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;Выбирается произвольное множество точек &amp;lt;math&amp;gt;\mu_i, i=\overline{1,k}&amp;lt;/math&amp;gt;, рассматриваемых как начальные центры кластеров: &amp;lt;math&amp;gt;\mu_i^{(0)} = \mu_i, \quad i=\overline{1, k}&amp;lt;/math&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
  &amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&lt;br /&gt;
    &amp;lt;b&amp;gt;Распределение векторов по кластерам&amp;lt;/b&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Шаг&amp;lt;/b&amp;gt; &amp;lt;math&amp;gt;t: \forall \mathbf{x}_i \in X, i=\overline{1,n}: \mathbf{x}_i \in S_j \iff  j=\arg\min_{k}\rho(\mathbf{x}_i,\mathbf{\mu}_k^{(t-1)})^2&amp;lt;/math&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
  &amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&lt;br /&gt;
    &amp;lt;b&amp;gt;Пересчет центров кластеров&amp;lt;/b&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Шаг &amp;lt;/b&amp;gt; &amp;lt;math&amp;gt;t: \forall i=\overline{1,k}:  \mu_i^{(t)} = \cfrac{1}{|S_i|}\sum_{\mathbf{x}\in S_i}\mathbf{x}&amp;lt;/math&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
  &amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&lt;br /&gt;
    &amp;lt;b&amp;gt;Проверка условия останова:&amp;lt;/b&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
    &#039;&#039;&#039;if&#039;&#039;&#039; &amp;lt;math&amp;gt;\exist i\in \overline{1,k}: \mu_i^{(t)} \ne \mu_i^{(t-1)}&amp;lt;/math&amp;gt; &#039;&#039;&#039;then&#039;&#039;&#039;&lt;br /&gt;
        t = t + 1;&lt;br /&gt;
        goto 2;&lt;br /&gt;
    &#039;&#039;&#039;else&#039;&#039;&#039;&lt;br /&gt;
        &#039;&#039;&#039;stop&#039;&#039;&#039;&lt;br /&gt;
  &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ol&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Вычислительное ядро алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Вычислительным ядром являются шаги 2 и 3 приведенного выше алгоритма: &amp;lt;b&amp;gt;&amp;lt;i&amp;gt;распределение векторов по кластерам&amp;lt;/i&amp;gt;&amp;lt;/b&amp;gt; и &amp;lt;b&amp;gt;&amp;lt;i&amp;gt;пересчет центров кластеров&amp;lt;/i&amp;gt;&amp;lt;/b&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;&amp;lt;i&amp;gt;Распределение векторов&amp;lt;/i&amp;gt;&amp;lt;/b&amp;gt; по кластерам предполагает вычисление расстояний между каждым вектором &amp;lt;math&amp;gt;\mathbf{x}_i \in X, i= \overline{1,n}&amp;lt;/math&amp;gt; и центрами кластера &amp;lt;math&amp;gt;\mathbf{\mu}_j, j= \overline{1,k}&amp;lt;/math&amp;gt;. Таким образом, данный шаг предполагает &amp;lt;math&amp;gt;k*n&amp;lt;/math&amp;gt; вычислений расстояний между d-мерными векторами. &lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;&amp;lt;i&amp;gt;Пересчет центров кластеров&amp;lt;/i&amp;gt;&amp;lt;/b&amp;gt; предполагает &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; вычислений центров масс &amp;lt;math&amp;gt;\mathbf{\mu}_i&amp;lt;/math&amp;gt; множеств &amp;lt;math&amp;gt;S_i, i=\overline{1,k}&amp;lt;/math&amp;gt; представленных выражением в шаге 3 представленного выше алгоритма.&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Макроструктура алгоритма ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Инициализация центров масс &amp;lt;math&amp;gt;\mu_1, ..., \mu_k&amp;lt;/math&amp;gt;&amp;lt;/b&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
Наиболее распространенными являются следующие стратегии:&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&lt;br /&gt;
    &amp;lt;b&amp;gt;Метод Forgy&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;В качестве начальных значений &amp;lt;math&amp;gt;\mu_1, ..., \mu_k&amp;lt;/math&amp;gt; берутся случайно выбранные векторы.&lt;br /&gt;
  &amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&lt;br /&gt;
    &amp;lt;b&amp;gt;Метод случайно разделения (Random Partitioning)&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;Для каждого вектора &amp;lt;math&amp;gt;\mathbf{x}_i \in X, i=\overline{1, n}&amp;lt;/math&amp;gt; выбирается случайным образом кластер &amp;lt;math&amp;gt;S_1, ..., S_k&amp;lt;/math&amp;gt;, после чего для каждого полученного кластера вычисляются значения &amp;lt;math&amp;gt;\mu_1, ..., \mu_k&amp;lt;/math&amp;gt;.&lt;br /&gt;
  &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Распределение векторов по кластерам&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Для этого шага алгоритма между векторами &amp;lt;math&amp;gt;\mathbf{x}_i \in X, i=\overline{1, n}&amp;lt;/math&amp;gt; и центрами кластеров &amp;lt;math&amp;gt;\mu_1, ..., \mu_k&amp;lt;/math&amp;gt; вычисляются &amp;lt;b&amp;gt;расстояния&amp;lt;/b&amp;gt; по формуле (как правило, используется Евлидово расстояние):&lt;br /&gt;
&amp;lt;table style=&amp;quot;width:100%&amp;quot;&amp;gt;&lt;br /&gt;
  &amp;lt;tr&amp;gt;&lt;br /&gt;
    &amp;lt;td align=&amp;quot;center&amp;quot; width=&amp;quot;90%&amp;quot;&amp;gt;&amp;lt;math&amp;gt; \mathbf{v}_1, \mathbf{v}_2 \in \mathbb{R}^d,  \quad \rho(\mathbf{v}_1, \mathbf{v}_2) = \lVert \mathbf{v}_1- \mathbf{v}_2 \rVert= \sqrt{\sum_{i=1}^{d}(\mathbf{v}_{1,i} - \mathbf{v}_{2,i})^2}&amp;lt;/math&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;td align=&amp;quot;right&amp;quot;&amp;gt;&amp;lt;math&amp;gt;(2)&amp;lt;/math&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;/table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Пересчет центров кластеров&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Для этого шага алгоритма производится пересчет центров кластера по &amp;lt;b&amp;gt;формуле вычисления центра масс&amp;lt;/b&amp;gt;:&lt;br /&gt;
&amp;lt;table style=&amp;quot;width:100%&amp;quot;&amp;gt;&lt;br /&gt;
  &amp;lt;tr&amp;gt;&lt;br /&gt;
    &amp;lt;td align=&amp;quot;center&amp;quot; width=&amp;quot;90%&amp;quot;&amp;gt;&amp;lt;math&amp;gt; \mu = \cfrac{1}{|S|}\sum_{\mathbf{x}\in S}\mathbf{x}&amp;lt;/math&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;td align=&amp;quot;right&amp;quot;&amp;gt;&amp;lt;math&amp;gt;(3)&amp;lt;/math&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;/table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Схема реализации последовательного алгоритма ===&lt;br /&gt;
&lt;br /&gt;
 &#039;&#039;&#039;algorithm&#039;&#039;&#039; k-means &#039;&#039;&#039;is&#039;&#039;&#039;&lt;br /&gt;
     &#039;&#039;&#039;1.&#039;&#039;&#039; Инициализировать центры кластеров &amp;lt;math&amp;gt;\mathbf{\mu}_i^{(1)}, i=\overline{1,k}&amp;lt;/math&amp;gt;&lt;br /&gt;
     &#039;&#039;&#039;2.&#039;&#039;&#039; &amp;lt;math&amp;gt;t \leftarrow 1&amp;lt;/math&amp;gt;&lt;br /&gt;
     &#039;&#039;&#039;3.&#039;&#039;&#039; &#039;&#039;&#039;Распределение по кластерам&#039;&#039;&#039;&amp;lt;br&amp;gt;&lt;br /&gt;
        &amp;lt;math&amp;gt;S_i^{(t)}=\{\mathbf{x}_p: \lVert\mathbf{x}_p-\mathbf{\mu}_i^{(t)}\rVert^2 \leq \lVert\mathbf{x}_p-\mathbf{\mu}_j^{(t)}\rVert^2 \quad \forall j=\overline{1,k}\},&amp;lt;/math&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
        где каждый вектор &amp;lt;math&amp;gt;\mathbf{x}_p&amp;lt;/math&amp;gt; соотносится единственному кластеру &amp;lt;math&amp;gt;S^{(t)}&amp;lt;/math&amp;gt;&lt;br /&gt;
     &#039;&#039;&#039;4.&#039;&#039;&#039; &#039;&#039;&#039;Обновление центров кластеров&#039;&#039;&#039;&amp;lt;br&amp;gt;&lt;br /&gt;
        &amp;lt;math&amp;gt;\mathbf{\mu}_i^{(t+1)} = \frac{1}{|S^{(t)}_i|} \sum_{\mathbf{x}_j \in S^{(t)}_i} \mathbf{x}_j &amp;lt;/math&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
     &#039;&#039;&#039;5.&#039;&#039;&#039; &#039;&#039;&#039;if&#039;&#039;&#039; &amp;lt;math&amp;gt;\exist i \in \overline{1,k}: \mathbf{\mu}_i^{(t+1)} \ne \mathbf{\mu}_i^{(t)}&amp;lt;/math&amp;gt; &#039;&#039;&#039;then&#039;&#039;&#039;&lt;br /&gt;
            t = t + 1;&lt;br /&gt;
            goto &#039;&#039;&#039;3&#039;&#039;&#039;;&lt;br /&gt;
        &#039;&#039;&#039;else&#039;&#039;&#039;&lt;br /&gt;
            &#039;&#039;&#039;stop&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
=== Последовательная сложность алгоритма===&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding-bottom: 20px&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;Обозначим &amp;lt;math&amp;gt;\Theta_{centroid}^{d, m}&amp;lt;/math&amp;gt; временную сложность вычисления центорида кластера, число элементов которого равна &amp;lt;math&amp;gt;m&amp;lt;/math&amp;gt;,  в d-мерном пространстве.&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;Аналогично  &amp;lt;math&amp;gt;\Theta_{distance}^d&amp;lt;/math&amp;gt; &amp;amp;ndash; временная сложность вычисления расстояния между двумя d-мерными векторами.&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding-bottom: 20px&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;Сложность шага инициализации &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластеров мощности &amp;lt;math&amp;gt;m&amp;lt;/math&amp;gt; в d-мерном пространстве &amp;amp;ndash; &amp;lt;math&amp;gt;\Theta_{init}^{k, d, m}&amp;lt;/math&amp;gt;&amp;lt;/b&amp;gt;&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;i&amp;gt;Стратерия Forgy&amp;lt;/i&amp;gt;: вычисления не требуются, &amp;lt;math&amp;gt;\Theta_{init}^{k, d, m} = 0&amp;lt;/math&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;i&amp;gt;Стратегия случайного разбиения&amp;lt;/i&amp;gt;: вычисление центров &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластеров,  &amp;lt;math&amp;gt;\Theta_{init}^{k, d, m} = k*\Theta_{centroid}^{d, m}, m \le n&amp;lt;/math&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding-bottom: 20px&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Cложность шага распределения d мерных векторов по &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластерам &amp;amp;ndash; &amp;lt;math&amp;gt;\Theta_{distribute}^{k, d}&amp;lt;/math&amp;gt;&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
На этом шаге для каждого вектора &amp;lt;math&amp;gt;\mathbf{x}_i \in X, i=\overline{1, n}&amp;lt;/math&amp;gt; вычисляется k расстояний до центров кластеров &amp;lt;math&amp;gt;\mathbf{\mu}_1, ...\mathbf{\mu}_k&amp;lt;/math&amp;gt;&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p align=&amp;quot;center&amp;quot;&amp;gt;&lt;br /&gt;
  &amp;lt;math&amp;gt;\Theta_{distribute}^{k, d} = n*k*\Theta_{distance}^d&amp;lt;/math&amp;gt;&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding-bottom: 20px&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;Сложность шага пересчета центров &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластеров размера &amp;lt;math&amp;gt;m&amp;lt;/math&amp;gt; в d-мерном пространстве &amp;amp;ndash; &amp;lt;math&amp;gt;\Theta_{recenter}^{k, d, m}&amp;lt;/math&amp;gt;&amp;lt;/b&amp;gt;&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;На этом шаге вычисляется &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; центров кластеров &amp;lt;math&amp;gt;\mathbf{\mu}_1, ...\mathbf{\mu}_k&amp;lt;/math&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p align=&amp;quot;center&amp;quot;&amp;gt;&amp;lt;math&amp;gt;\Theta_{recenter}^{k, d, m} = k*\Theta_{centroid}^{d, m}&amp;lt;/math&amp;gt; &amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding-bottom: 20px&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Рассчитаем &amp;lt;math&amp;gt;\Theta_{centroid}^{d, m}&amp;lt;/math&amp;gt; для кластера, число элементов которого равно &amp;lt;math&amp;gt;m&amp;lt;/math&amp;gt;&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p align=&amp;quot;center&amp;quot;&amp;gt;&amp;lt;math&amp;gt;\Theta_{centroid}^{d, m}&amp;lt;/math&amp;gt; = &amp;lt;math&amp;gt;m * d&amp;lt;/math&amp;gt; сложений + &amp;lt;math&amp;gt;d&amp;lt;/math&amp;gt; делений &amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding-bottom: 20px&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Рассчитаем &amp;lt;math&amp;gt;\Theta_{distance}^d&amp;lt;/math&amp;gt; в соответствие с формулой &amp;lt;math&amp;gt;(2)&amp;lt;/math&amp;gt;&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p align=&amp;quot;center&amp;quot;&amp;gt;&amp;lt;math&amp;gt;\Theta_{distance}^d&amp;lt;/math&amp;gt; = &amp;lt;math&amp;gt;d&amp;lt;/math&amp;gt; вычитаний + &amp;lt;math&amp;gt;d&amp;lt;/math&amp;gt; умножений + &amp;lt;math&amp;gt;(d-1)&amp;lt;/math&amp;gt; сложение&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding-bottom: 20px&amp;quot;&amp;gt;&lt;br /&gt;
  &amp;lt;p&amp;gt;Предположим, что алгоритм сошелся за &amp;lt;math&amp;gt;\Tau&amp;lt;/math&amp;gt; итераций, тогда временная сложность алгоритма &amp;lt;math&amp;gt;\Theta_{k-means}^{d, n}&amp;lt;/math&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
  &amp;lt;p align=&amp;quot;center&amp;quot;&amp;gt;&amp;lt;b&amp;gt;&amp;lt;math&amp;gt;\Theta_{k-means}^{d, n} \le \Theta_{init}^{k, d, n} + \Tau*(\Theta_{distribute}^{k, d} + \Theta_{recenter}^{k, d, n})&amp;lt;/math&amp;gt;&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding-bottom: 5px&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;Операции сложения/вычитания:&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p align=&amp;quot;center&amp;quot;&amp;gt;&amp;lt;b&amp;gt;&amp;lt;math&amp;gt;\Theta_{k-means}^{d, n} \le k*n*d+ \Tau*(k*n*(2d-1) + k*n*d) = k*n*d+ \Tau*(k*n*(3d-1)) \thicksim O(\Tau*k*d*n)&amp;lt;/math&amp;gt;&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding-bottom: 20px&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;Операции умножения/деления:&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p align=&amp;quot;center&amp;quot;&amp;gt;&amp;lt;b&amp;gt;&amp;lt;math&amp;gt;\Theta_{k-means}^{d, n} \le k*d + \Tau*(k*n*d + k*d) = k*d + \Tau * k*d*(n+1) \thicksim O(\Tau*k*d*n) &amp;lt;/math&amp;gt;&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding-bottom: 20px&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;Получаем, что &amp;lt;b&amp;gt;временная сложность&amp;lt;/b&amp;gt; алгоритма &amp;lt;b&amp;gt;k means&amp;lt;/b&amp;gt; кластеризации &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; &amp;lt;b&amp;gt;d-мерных&amp;lt;/b&amp;gt; векторов на &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластеров за &amp;lt;math&amp;gt;\Tau&amp;lt;/math&amp;gt; итераций:&amp;lt;/p&amp;gt;&lt;br /&gt;
 &amp;lt;p align=&amp;quot;center&amp;quot;&amp;gt;&amp;lt;b&amp;gt;&amp;lt;math&amp;gt; \Theta_{k-means}^{d, n} \thicksim O(\Tau*k*d*n) &amp;lt;/math&amp;gt;&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Информационный граф ===&lt;br /&gt;
&lt;br /&gt;
Рассмотрим информационный граф алгоритма. Алгоритм &amp;lt;i&amp;gt;k means&amp;lt;/i&amp;gt; начинается с этапа инициализации, после которого следуют итерации, на каждой из которых выполняется два последовательных шага (см. [[#Схема реализации последовательного алгоритма|&amp;quot;Схема реализации последовательного алгоритма&amp;quot;]]): &lt;br /&gt;
* распределение векторов по кластерам&lt;br /&gt;
* перерасчет центров кластеров&lt;br /&gt;
&lt;br /&gt;
Поскольку основная часть вычислений приходится на шаги итераций, распишем информационные графы данных шагов.&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Распределение векторов по кластерам&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
Информационный граф шага распределения векторов по кластерам представлен на &#039;&#039;рисунке 1&#039;&#039;. Исходами данного графа является исходные векторы &amp;lt;math&amp;gt;\mathbf{x}_1, ..., \mathbf{x}_n&amp;lt;/math&amp;gt;, а также центры кластеров &amp;lt;math&amp;gt;\mathbf{\mu}_1, ... \mathbf{\mu}_k&amp;lt;/math&amp;gt;, вычисленные ранее (на шаге инициализации, если рассматривается первая итерация алгоритма, или на шаге пересчета центров кластеров предыдущей итерации в противном случае). Каждая пара векторов данных &amp;lt;math&amp;gt;\mathbf{x}_i, i=\overline{1,n}&amp;lt;/math&amp;gt; и центров кластера &amp;lt;math&amp;gt;\mathbf{\mu}_j, j=\overline{1, k}&amp;lt;/math&amp;gt; : (&amp;lt;math&amp;gt;\mathbf{x}_i&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;\mathbf{\mu}_j&amp;lt;/math&amp;gt;) подаются на независимые узлы &amp;lt;i&amp;gt;&amp;quot;d&amp;quot;&amp;lt;/i&amp;gt; вычисления расстояния между векторами (более подробная схема вычисления расстояния представлена далее, &#039;&#039;рисунок 2&#039;&#039;). Далее узлы вычисления расстояния &amp;lt;i&amp;gt;&amp;quot;d&amp;quot;&amp;lt;/i&amp;gt;, соответствующие одному и тому же исходному вектору &amp;lt;math&amp;gt;\mathbf{x}_i&amp;lt;/math&amp;gt; передаются на один узел &amp;lt;i&amp;gt;&amp;quot;m&amp;quot;&amp;lt;/i&amp;gt;, где далее происходит вычисление новой метки кластера для каждого вектора &amp;lt;math&amp;gt;\mathbf{x}_i&amp;lt;/math&amp;gt; (берется кластер с минимальным результатом вычисления расстояния). На выходе графа выдаются метки кластеров , &amp;lt;math&amp;gt;L_1, ..., L_n&amp;lt;/math&amp;gt;, такие что &amp;lt;math&amp;gt;\forall \mathbf{x}_i, i=\overline{1, n}, \mathbf{x}_i \in S_j \Leftrightarrow L_i = j&amp;lt;/math&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
[[file:Clusterization.png|thumb|center|800px|Рис. 1. Схема распределения векторов по кластерам. &#039;&#039;d&#039;&#039; &amp;amp;ndash; вычисление расстояния между векторами; &#039;&#039;m&#039;&#039; &amp;amp;ndash; вычисление минимума.]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Вычисление расстояния между векторами&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
Подробная схема вычисления расстояния между векторами &amp;lt;math&amp;gt;\mathbf{x}_i, \mathbf{\mu}_j&amp;lt;/math&amp;gt; представлена на &#039;&#039;рисунке 2&#039;&#039;. Как показано на графе, узел вычисления расстояния между векторами &amp;lt;i&amp;gt;&amp;quot;d&amp;quot;&amp;lt;/i&amp;gt; состоит из шага взятия разности между векторами (узел &amp;quot;&amp;lt;math&amp;gt;-&amp;lt;/math&amp;gt;&amp;quot;) и взятия нормы получившегося вектора разности (узел &amp;quot;&amp;lt;math&amp;gt;||\cdot||^2&amp;lt;/math&amp;gt;&amp;quot;). Более подробно, вычисление расстояния между векторами &amp;lt;math&amp;gt;\mathbf{x}_i = {x_{i1,}, ...,{x_{in}}}, \mathbf{\mu}_j = {\mu_{j1}, ...,\mu_{jn}}&amp;lt;/math&amp;gt; может быть представлено как вычисление разности между каждой парой компонент &amp;lt;math&amp;gt;(x_{iz}, \mu_{jz}), z=\overline{1, d}&amp;lt;/math&amp;gt; (узел &amp;quot;&amp;lt;math&amp;gt;-&amp;lt;/math&amp;gt;&amp;quot;), далее возведение в квадрат для каждого узла &amp;quot;&amp;lt;math&amp;gt;-&amp;lt;/math&amp;gt;&amp;quot; (узел &amp;quot;&amp;lt;math&amp;gt;()^2&amp;lt;/math&amp;gt;&amp;quot;) и суммирования выходов всех узлов &amp;quot;&amp;lt;math&amp;gt;()^2&amp;lt;/math&amp;gt;&amp;quot; (узел &amp;quot;&amp;lt;math&amp;gt;+&amp;lt;/math&amp;gt;&amp;quot;).  &lt;br /&gt;
&lt;br /&gt;
[[file:dist_calc.png|thumb|center|800px|Рис. 2. Схема вычисления расстояния между вектором и центром кластера.]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Пересчет центров кластеров&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
Информационный граф шага пересчета центров кластеров представлен на &#039;&#039;рисунке 3&#039;&#039;. Исходами данного графа является исходные векторы &amp;lt;math&amp;gt;\mathbf{x}_1, ..., \mathbf{x}_n&amp;lt;/math&amp;gt;, а также им соответствующие метки кластера, &amp;lt;math&amp;gt;L_1, ..., L_n&amp;lt;/math&amp;gt;, такие что &amp;lt;math&amp;gt;\forall x_i, i=\overline{1, n}, \mathbf{x}_i \in S_j \Leftrightarrow L_i = j&amp;lt;/math&amp;gt;, вычисленные на этапе распределения векторов по кластерам. Все векторы &amp;lt;math&amp;gt;\mathbf{x}_1, ..., \mathbf{x}_n&amp;lt;/math&amp;gt; подаются в узлы &amp;lt;math&amp;gt;+_1, ...+_k&amp;lt;/math&amp;gt;, каждый узел &amp;lt;math&amp;gt;+_m, m = \overline{1,k}&amp;lt;/math&amp;gt; соответствует операции сложения векторов кластера с номером &amp;lt;math&amp;gt;m&amp;lt;/math&amp;gt;. Метки кластера &amp;lt;math&amp;gt;L_1, ..., L_n&amp;lt;/math&amp;gt; также совместно передаются на узлы &amp;lt;math&amp;gt;S_m, m = \overline{1,k}&amp;lt;/math&amp;gt;, на каждом из которых вычисляется количество векторов в соответствующем кластере (количество меток с соответствующим значением). Далее каждая пара выходов узлов &amp;lt;math&amp;gt;+_m&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;S_m&amp;lt;/math&amp;gt; подается на узел &amp;quot;&amp;lt;math&amp;gt;/&amp;lt;/math&amp;gt;&amp;quot;, где производится деление суммы векторов кластера на количество элементов в нем. Значения, вычисленные на узлах &amp;quot;&amp;lt;math&amp;gt;/&amp;lt;/math&amp;gt;&amp;quot;, присваиваются новым центрам кластеров (выходные значения графа).&lt;br /&gt;
&lt;br /&gt;
[[file:Recluster.png|thumb|center|800px|Рис. 3. Схема пересчета центров кластеров]]&lt;br /&gt;
&lt;br /&gt;
=== Ресурс параллелизма алгоритма ===&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
Работа алгоритма состоит из &amp;lt;math&amp;gt;\Tau&amp;lt;/math&amp;gt; итераций, в каждой из которых происходит &amp;lt;b&amp;gt;распределение d-мерных векторов по &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластерам&amp;lt;/b&amp;gt;, а также &amp;lt;b&amp;gt;пересчет центров кластеров в d-мерном пространстве&amp;lt;/b&amp;gt;. В шаге &amp;lt;b&amp;gt;распределения d-мерных векторов по &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластерам&amp;lt;/b&amp;gt; расстояния между вектором и центрами кластеров вычисляются независимо (отсутствуют информационные зависимости). &amp;lt;b&amp;gt;Центры масс кластеров&amp;lt;/b&amp;gt; также пересчитываются независимо друг от друга. Таким образом, имеет место [[глоссарий#Массовый параллелизм|&#039;&#039;массовый параллелизм&#039;&#039;]]. Вычислим параллельную сложность &amp;lt;math&amp;gt;\Psi_*&amp;lt;/math&amp;gt; каждого из шагов, а также параллельную сложность всего алгоритма, &amp;lt;math&amp;gt;\Psi_{k-means}&amp;lt;/math&amp;gt;. Будем исходить из предположения, что может быть использовано любое необходимое число потоков.&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Распределение d-мерных векторов по &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластерам&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;  &lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
Поскольку на данном шаге для каждой пары векторов &amp;lt;math&amp;gt;\mathbf{x}_i, i=\overline{1,n}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\mathbf{\mu}_j, j=\overline{1,k}&amp;lt;/math&amp;gt; операции вычисления расстояния не зависят друг от друга, они могут выполняться параллельно. Тогда, разделив все вычисление расстояний на &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; потоков, получим, что в каждом потоке будет выполняться только одна операция вычисления расстояния между векторами размерности d. При этом каждому вычислительному потоку передаются координаты центров всех кластеров &amp;lt;math&amp;gt;\mathbf{\mu}_1, ..., \mathbf{\mu}_k&amp;lt;/math&amp;gt;. Таким образом, параллельная сложность данного шага определяется &amp;lt;i&amp;gt; сложностью параллельной операции вычисления расстояния между d-мерными векторами&amp;lt;/i&amp;gt;, &amp;lt;math&amp;gt;\Psi_{distance}^d&amp;lt;/math&amp;gt;  и &amp;lt;i&amp;gt;сложностью определения наиболее близкого кластера&amp;lt;/i&amp;gt; (паралельное взятие минимума по расстояниям), &amp;lt;math&amp;gt;\Psi_{min}^k&amp;lt;/math&amp;gt;. Для оценки &amp;lt;math&amp;gt;\Psi_{distance}^d&amp;lt;/math&amp;gt; воспользуемся  [[Нахождение_частных_сумм_элементов_массива_сдваиванием | параллельной реализацией нахождения частичной суммы элементов массива путем сдваивания]]. Аналогично, &amp;lt;math&amp;gt;\Psi_{min}^k = log(k)&amp;lt;/math&amp;gt;. В результате, &amp;lt;math&amp;gt;\Psi_{distance}^d = O(log(d))&amp;lt;/math&amp;gt;.   Таким образом: &lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p align=&amp;quot;center&amp;quot;&amp;gt;&amp;lt;math&amp;gt;\Psi_{distribute}^{k, d}  = \Psi_{distance}^d + \Psi_{min}^k = O(log(d))+O(log(k)) = O(log(k*d))&amp;lt;/math&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Пересчет центров кластеров в d-мерном пространстве&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
Поскольку на данном шаге для каждого из &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластеров центр масс может быть вычислен независимо, данные операции могут быть выполнены в отдельных потоках. Таким образом, параллельная сложность данного шага, &amp;lt;math&amp;gt;\Psi_{recenter}^{k, d}&amp;lt;/math&amp;gt;,  будет определяться &amp;lt;i&amp;gt;параллельной сложностью вычисления одного центра масс кластера размера &amp;lt;math&amp;gt;m&amp;lt;/math&amp;gt;&amp;lt;/i&amp;gt;, &amp;lt;math&amp;gt;\Psi_{recenter}^{k, d}&amp;lt;/math&amp;gt;,  а так как &amp;lt;math&amp;gt;m \le n \Rightarrow \Psi_{recenter}^{d, m} \le \Psi_{recenter}^{d, n}&amp;lt;/math&amp;gt;. Сложность вычисления центра масс кластера d-мерных векторов размера n аналогично предыдущим вычислениям равна &amp;lt;math&amp;gt;O(log(n))&amp;lt;/math&amp;gt;. Тогда:  &lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p align=&amp;quot;center&amp;quot;&amp;gt;&amp;lt;math&amp;gt;\Psi_{recenter}^{k, d}  \le \Psi_{recenter}^{d, n} = O(log(n))&amp;lt;/math&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Общая параллельная сложность алгоритма&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
На каждой итерации необходимо обновление центров кластеров, которые будут использованы на следующей итерации. Таким образом, итерационный процесс выполняется последовательно&amp;lt;ref&amp;gt;Zhao, Weizhong, Huifang Ma, and Qing He. &amp;quot;Parallel k-means clustering based on mapreduce.&amp;quot; IEEE International Conference on Cloud Computing. Springer Berlin Heidelberg, 2009.&amp;lt;/ref&amp;gt;. Тогда, поскольку сложность каждой итерации  определяется &amp;lt;math&amp;gt;\Psi_{distribute}^{k, d}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\Psi_{recenter}&amp;lt;/math&amp;gt;, сложность всего алгоритма, &amp;lt;math&amp;gt;\Psi_{k-means}&amp;lt;/math&amp;gt; в предположении, что было сделано &amp;lt;math&amp;gt;\Tau&amp;lt;/math&amp;gt; операций определяется выражением&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p align=&amp;quot;center&amp;quot;&amp;gt;&amp;lt;math&amp;gt;\Psi_{k-means} \approx \Tau * (\Psi_{distribute}^{k, d} + \Psi_{recenter}^{k, d}) \le \Tau * O(log(k*d*n))&amp;lt;/math&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Входные и выходные данные алгоритма ===&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;Входные данные&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;Матрица из &amp;lt;math&amp;gt;n*d&amp;lt;/math&amp;gt; элементов &amp;lt;math&amp;gt;x_{i, j} \in \mathbb{R}, i=\overline{1, n}, j=\overline{1, d}&amp;lt;/math&amp;gt;&amp;amp;ndash; координат векторов (наблюдений).&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;Целое положительное число &amp;lt;math&amp;gt;k, k \le n&amp;lt;/math&amp;gt; &amp;amp;ndash; количество кластеров.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;Объем входных данных&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;math&amp;gt;1&amp;lt;/math&amp;gt; целое число + &amp;lt;math&amp;gt;n*d&amp;lt;/math&amp;gt; вещественных чисел (при условии, что координаты &amp;amp;ndash; вещественные числа).&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;Выходные данные&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; целых положительных чисел &amp;lt;math&amp;gt;L_1, ..., L_n&amp;lt;/math&amp;gt;&amp;amp;ndash; номера кластеров, соотвествующие каждому вектору (при условии, что нумерация кластеров начинается с &amp;lt;math&amp;gt;1&amp;lt;/math&amp;gt;).&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;Объем выходных данных&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; целых положительных чисел.&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Свойства алгоритма ===&lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;[[глоссарий#Вычислительная мощность|&#039;&#039;Вычислительная мощность&#039;&#039;]]&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
Вычислительная мощность алгоритма &amp;lt;i&amp;gt;k means&amp;lt;/i&amp;gt; равна &amp;lt;math&amp;gt;\frac{k*d*n*\Tau}{n*d} = k*\Tau &amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; &amp;amp;ndash; число кластеров, &amp;lt;math&amp;gt;\Tau&amp;lt;/math&amp;gt; &amp;amp;ndash; число итераций алгоритма.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;[[глоссарий#Детерминированность |&#039;&#039;Детерминированность&#039;&#039;]] и [[глоссарий#Устойчивость |&#039;&#039;Устойчивость&#039;&#039;]] &amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
Алгоритм &amp;lt;i&amp;gt;k means&amp;lt;/i&amp;gt; является итерационным. Количество итераций алгоритма в общем случае не фиксируется и зависит от начального расположения объектов в пространстве, параметра &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt;, а также от начального приближения центров кластеров, &amp;lt;math&amp;gt;\mu_1, ..., \mu_k&amp;lt;/math&amp;gt;. В результате этого может варьироваться результат работы алгоритма. При неудачном выборе начальных параметров итерационный процесс может сойтись к локальному оптимуму&amp;lt;ref&amp;gt;Von Luxburg, Ulrike. Clustering Stability. Now Publishers Inc, 2010.&amp;lt;/ref&amp;gt;. По этим причинам алгоритм не является ни &amp;lt;b&amp;gt;детермирированным&amp;lt;/b&amp;gt;, ни &amp;lt;b&amp;gt;устойчивым&amp;lt;/b&amp;gt;.&lt;br /&gt;
 &lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Соотношение последовательной и параллельной сложности алгоритма&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\frac{\Theta_{k-means}}{\Psi_{k-means}} = \frac{O(\Tau*k*d*n)}{O(\Tau*log(k*d*n))}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Сильные стороны алгоритма&amp;lt;/b&amp;gt;:&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;i&amp;gt;Сравнительно высокая эффективность при простоте реализации&amp;lt;/i&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;i&amp;gt;Высокое качество кластеризации&amp;lt;/i&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;i&amp;gt;Возможность распараллеливания&amp;lt;/i&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;i&amp;gt;Существование множества модификаций&amp;lt;/i&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;Недостатки алгоритма&amp;lt;/b&amp;gt;&amp;lt;ref&amp;gt;Ortega, Joaquín Pérez, Ma Del Rocío Boone Rojas, and María J. Somodevilla. &amp;quot;Research issues on K-means Algorithm: An Experimental Trial Using Matlab.&amp;quot;&amp;lt;/ref&amp;gt;:&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;i&amp;gt;Количество кластеров является параметром алгоритма&amp;lt;/i&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;&amp;lt;i&amp;gt;Чувствительность к начальным условиям&amp;lt;/i&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;Инициализация центров кластеров в значительной степени влияет на результат кластеризации.&amp;lt;/p&amp;gt;&lt;br /&gt;
  &amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;&amp;lt;i&amp;gt;Чувствительность к выбросам и шумам&amp;lt;/i&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;Выбросы, далекие от центров настоящих кластеров, все равно учитываются при вычислении их центров.&amp;lt;/p&amp;gt;&lt;br /&gt;
  &amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;&amp;lt;i&amp;gt;Возможность сходимости к локальному оптимуму&amp;lt;/i&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;Итеративный подход не дает гарантии сходимости к оптимальному решению.&amp;lt;/p&amp;gt;&lt;br /&gt;
  &amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;&amp;lt;i&amp;gt;Использование понятия &amp;quot;среднего&amp;quot;&amp;lt;/i&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;Алгоритм неприменим к данным, для которых не определено понятие &amp;quot;среднего&amp;quot;, например, категориальным данным.&amp;lt;/p&amp;gt;&lt;br /&gt;
  &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&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;
Исследование масштабируемости параллельной реализации алгоритма k means проводилось на суперкомпьютере &amp;quot;Ломоносов&amp;quot;. Алгоритм реализован на языке C с использованием средств MPI.&lt;br /&gt;
Для исследования масштабируемости проводилось множество запусков программы с разным значением параметра (количество векторов для кластеризации), а также с различным числом процессоров. Фиксировались результаты запусков &amp;amp;ndash; время работы &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt; и количество произведенных итераций алгоритма &amp;lt;math&amp;gt;\Tau&amp;lt;/math&amp;gt;.&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;Значения &amp;lt;b&amp;gt;количества векторов&amp;lt;/b&amp;gt; &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;: 20&#039;000, 30&#039;000, 50&#039;000, 100&#039;000, 200&#039;000, 300&#039;000, 500&#039;000, 700&#039;000, 1&#039;000&#039;000, 1&#039;500&#039;000, 2&#039;000&#039;000.&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;Значения &amp;lt;b&amp;gt;количества процессоров&amp;lt;/b&amp;gt; &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt;: 1, 8, 16, 32, 64, 128, 160, 192, 224, 256, 288, 320, 352, 384, 416, 448, 480, 512.&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;Значение &amp;lt;b&amp;gt;количества кластеров&amp;lt;/b&amp;gt; &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt;: 100.&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;Значение &amp;lt;b&amp;gt;размерности векторов&amp;lt;/b&amp;gt; &amp;lt;math&amp;gt;d&amp;lt;/math&amp;gt;: 10.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Графики производительности и эффективности реализации представлены на рисунках 4 и 5 соответственно.&lt;br /&gt;
&lt;br /&gt;
[[file:Flops.png|thumb|center|800px|Рис. 4. График производительности реализации алгоритма.]]&lt;br /&gt;
&lt;br /&gt;
[[file:Efficiency.png|thumb|center|800px|Рис. 5. График эффективности реализации алгоритма.]]&lt;br /&gt;
&lt;br /&gt;
Для заданной конфигурации эксперимента (&amp;lt;math&amp;gt;n, p, k&amp;lt;/math&amp;gt;) и полученных результатах (&amp;lt;math&amp;gt;t, \Tau&amp;lt;/math&amp;gt;) производительность и эффективность реализации расчитывались по формулам (см. [[#Последовательная сложность алгоритма| последовательная сложность алгоритма]]):&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;math&amp;gt;Performance = \frac{\Theta_{k-means}^{d, n}}{t}\ FLOPS&amp;lt;/math&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;math&amp;gt;Efficiency = \frac{100 * Performance}{Peak}&amp;lt;/math&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
В результате экспериментальной оценки были получены следующие оценки эффективности реализации:&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;b&amp;gt;Минимальное&amp;lt;/b&amp;gt; значение: 0.000409 %&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;b&amp;gt;Максимальное&amp;lt;/b&amp;gt; значение: 0.741119 %&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Динамические характеристики и эффективность реализации алгоритма ===&lt;br /&gt;
=== Выводы для классов архитектур ===&lt;br /&gt;
=== Существующие реализации алгоритма ===&lt;br /&gt;
==== Открытое программное обеспечение ====&lt;br /&gt;
&amp;lt;ol&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;[https://www.icpsr.umich.edu/CrimeStat/ CrimeStat]&amp;lt;/li&amp;gt; Программное обеспечение, созданное для операционных систем Windows, предоставляющее инструменты статистического  и пространственного анализа для решения задачи картирования преступности.&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://juliastats.github.io Julia]&amp;lt;/li&amp;gt; Высокоуровневый высокопроизводительный свободный язык программирования с динамической типизацией, созданный для математических вычислений, содержит реализацию k-means.&lt;br /&gt;
  &amp;lt;li&amp;gt;[https://mahout.apache.org Mahout]&amp;lt;/li&amp;gt; Apache Mahout - Java библиотека для работы с алгоритмами машинного обучения с использованием MapReduce. Содержит реализацию k-means.&lt;br /&gt;
  &amp;lt;li&amp;gt;[https://www.gnu.org/software/octave/ Octave]&amp;lt;/li&amp;gt; Написанная на C++  свободная система для математических вычислений, использующая совместимый с MATLAB язык высокого уровня, содержит реализацию k-means.&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://spark.apache.org/docs/latest/mllib-clustering.html Spark]&amp;lt;/li&amp;gt; Распределенная реализация k-means содержится в библиотеке Mlib для работы с алгоритмами машинного обучения, взаимодействующая с Python библиотекой NumPy и библиотека R.&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://torch.ch Torch]&amp;lt;/li&amp;gt;  MATLAB-подобная библиотека для языка программирования Lua с открытым исходным кодом, предоставляет большое количество алгоритмов для глубинного обучения и научных расчётов. Ядро написано на Си, прикладная часть выполняется на LuaJIT, поддерживается распараллеливание вычислений средствами CUDA и OpenMP. Существуют реализации k-means.&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://www.cs.waikato.ac.nz/ml/weka/ Weka]&amp;lt;/li&amp;gt;  Cвободное программное обеспечение для анализа данных, написанное на Java. Содержит k-means и x-means.&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://accord-framework.net/docs/html/T_Accord_MachineLearning_KMeans.htm Accord.NET]&amp;lt;/li&amp;gt; C# реализация алгоритмов k-means, k-means++, k-modes.&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://docs.opencv.org/3.0-beta/doc/py_tutorials/py_ml/py_kmeans/py_kmeans_opencv/py_kmeans_opencv.html OpenCV]&amp;lt;/li&amp;gt; Написанная на С++ библиотека, направленная в основном на решение задач компьютерного зрения. Содержит реализацию k-means.&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://mlpack.org/ MLPACK]&amp;lt;/li&amp;gt; Масштабируемая С++ библиотека для работы с алгоритмами машинного обучения, содержит реализацию k-means.&lt;br /&gt;
  &amp;lt;li&amp;gt;[https://www.scipy.org/ SciPy]&amp;lt;/li&amp;gt; Библиотека Python, содержит множество реализаций k-means.&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://scikit-learn.org/ scikit-learn]&amp;lt;/li&amp;gt; Библиотека Python, содержит множество реализаций k-means.&lt;br /&gt;
  &amp;lt;li&amp;gt;[https://www.r-bloggers.com/k-means-clustering-in-r/ R]&amp;lt;/li&amp;gt; Язык программирования для статистической обработки данных и работы с графикой, а также свободная программная среда вычислений с открытым исходным кодом в рамках проекта GNU, содержит три реализации k-means.&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://elki.dbs.ifi.lmu.de ELKI]&amp;lt;/li&amp;gt; Java фреймворк, содержащий реализацию k-means, а также множество других алгоритмов кластеризации.&lt;br /&gt;
&amp;lt;/ol&amp;gt;&lt;br /&gt;
==== Проприетарное программное обеспечение  ====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ol&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;[https://www.ayasdi.com/blog/bigdata/topological-data-analysis-of-oil-and-gas-petrophysical-data/ Ayasdi]&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://www.stata.com/features/cluster-analysis/ Stata]&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://mathworld.wolfram.com/K-MeansClusteringAlgorithm.html Mathematica]&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://www.mathworks.com/help/stats/kmeans.html?requestedDomain=www.mathworks.com MATLAB]&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;[https://support.sas.com/rnd/app/stat/procedures/fastclus.html SAS]&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://docs.rapidminer.com/studio/operators/modeling/segmentation/k_means.html RapidMiner]&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;[https://blogs.sap.com/2013/03/28/sap-hana-pal-k-means-algorithm-or-how-to-do-customer-segmentation-for-the-telecommunications-industry/ SAP HANA]&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ol&amp;gt;&lt;br /&gt;
== Литература ==&lt;br /&gt;
&amp;lt;references /&amp;gt;&lt;/div&gt;</summary>
		<author><name>DennZo1993</name></author>
	</entry>
	<entry>
		<id>https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:%D0%91%D1%80%D0%BE%D1%82%D0%B8%D0%BA%D0%BE%D0%B2%D1%81%D0%BA%D0%B0%D1%8F_%D0%94%D0%B0%D0%BD%D1%83%D1%82%D0%B0/%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_k-means&amp;diff=17166</id>
		<title>Участник:Бротиковская Данута/Алгоритм k-means</title>
		<link rel="alternate" type="text/html" href="https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:%D0%91%D1%80%D0%BE%D1%82%D0%B8%D0%BA%D0%BE%D0%B2%D1%81%D0%BA%D0%B0%D1%8F_%D0%94%D0%B0%D0%BD%D1%83%D1%82%D0%B0/%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_k-means&amp;diff=17166"/>
		<updated>2016-11-14T23:34:30Z</updated>

		<summary type="html">&lt;p&gt;DennZo1993: /* Масштабируемость реализации алгоритма */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt; {{Assignment|Zhum}}&lt;br /&gt;
&lt;br /&gt;
{{algorithm&lt;br /&gt;
| name              = Алгоритм k средних (k means)&lt;br /&gt;
| serial_complexity = &amp;lt;math&amp;gt;O(\Tau*k*d*n)&amp;lt;/math&amp;gt;&lt;br /&gt;
| input_data        = &amp;lt;math&amp;gt; d*n &amp;lt;/math&amp;gt;&lt;br /&gt;
| output_data       = &amp;lt;math&amp;gt; n &amp;lt;/math&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
Авторы страницы &amp;lt;b&amp;gt;[[Участник:Бротиковская Данута|Данута Бротиковская]]&amp;lt;/b&amp;gt; и &amp;lt;b&amp;gt;[[Участник:DennZo1993|Денис Зобнин]]&amp;lt;/b&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
Оба автора внесли одинаковый вклад в написание статьи (поиск материалов, изучение статей, заполнение контента статьи), четких разграничений по пунктам статьи сделать невозможно. &lt;br /&gt;
&lt;br /&gt;
== Свойства и структура алгоритма ==&lt;br /&gt;
&lt;br /&gt;
=== Общее описание алгоритма ===&lt;br /&gt;
Алгоритм &amp;lt;b&amp;gt;&amp;lt;i&amp;gt;k средних&amp;lt;/i&amp;gt;&amp;lt;/b&amp;gt; (&amp;lt;b&amp;gt;&amp;lt;i&amp;gt;k means&amp;lt;/i&amp;gt;&amp;lt;/b&amp;gt;) &amp;amp;ndash; неиерархический&amp;lt;ref&amp;gt;&amp;quot;https://ru.wikipedia.org/wiki/Иерархическая_кластеризация&amp;quot;&amp;lt;/ref&amp;gt;, итерационный метод кластеризации&amp;lt;ref&amp;gt;&amp;quot;https://ru.wikipedia.org/wiki/Кластерный_анализ&amp;quot;&amp;lt;/ref&amp;gt;, получивший большую популярность благодаря своей простоте, наглядности реализации и достаточно высокому качеству работы. Был изобретен в 1950-х годах математиком &amp;lt;i&amp;gt;Гуго Штейнгаузом&amp;lt;/i&amp;gt;&amp;lt;ref&amp;gt;Steinhaus, Hugo. &amp;quot;Sur la division des corp materiels en parties.&amp;quot; Bull. Acad. Polon. Sci 1.804 (1956): 801.&amp;lt;/ref&amp;gt; и почти одновременно &amp;lt;i&amp;gt;Стюартом Ллойдом&amp;lt;/i&amp;gt;&amp;lt;ref&amp;gt;Lloyd, S. P. &amp;quot;Least square quantization in PCM. Bell Telephone Laboratories Paper. Published in journal much later: Lloyd, SP: Least squares quantization in PCM.&amp;quot; IEEE Trans. Inform. Theor.(1957/1982).&amp;lt;/ref&amp;gt;. Особую популярность приобрел после публикации работы &amp;lt;i&amp;gt;МакКуина&amp;lt;/i&amp;gt;&amp;lt;ref&amp;gt;MacQueen, James. &amp;quot;Some methods for classification and analysis of multivariate observations.&amp;quot; Proceedings of the fifth Berkeley symposium on mathematical statistics and probability. Vol. 1. No. 14. 1967.&amp;lt;/ref&amp;gt; в 1967.&lt;br /&gt;
&lt;br /&gt;
Алгоритм представляет собой версию EM-алгоритма&amp;lt;ref&amp;gt;&amp;quot;https://ru.wikipedia.org/wiki/EM-алгоритм&amp;quot;&amp;lt;/ref&amp;gt;, применяемого также для разделения смеси гауссиан. Основная идея &amp;lt;i&amp;gt;k means&amp;lt;/i&amp;gt; заключается в том, что данные произвольно разбиваются на кластеры, после чего итеративно перевычисляется центр масс для каждого кластера, полученного на предыдущем шаге, затем векторы разбиваются на кластеры вновь в соответствии с тем, какой из новых центров оказался ближе по выбранной метрике.&lt;br /&gt;
&lt;br /&gt;
Цель алгоритма заключается в разделении &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; наблюдений на &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластеров таким образом, чтобы каждое наблюдение принадлежало ровно одному кластеру, расположенному на наименьшем расстоянии от наблюдения.&lt;br /&gt;
&lt;br /&gt;
=== Математическое описание алгоритма ===&lt;br /&gt;
&amp;lt;b&amp;gt;&amp;lt;u&amp;gt;Дано:&amp;lt;/u&amp;gt;&amp;lt;/b&amp;gt;&lt;br /&gt;
* набор из &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; наблюдений &amp;lt;math&amp;gt;X=\{\mathbf{x}_1, \mathbf{x}_2, ..., \mathbf{x}_n\}, \mathbf{x}_i \in \mathbb{R}^d, i=\overline{1, n}&amp;lt;/math&amp;gt;;&lt;br /&gt;
* &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; - требуемое число кластеров, &amp;lt;math&amp;gt;k \in \mathbb{N}, k \leq n&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;&amp;lt;u&amp;gt;Требуется:&amp;lt;/u&amp;gt;&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Разделить множество наблюдений &amp;lt;math&amp;gt;X&amp;lt;/math&amp;gt; на &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластеров &amp;lt;math&amp;gt;S_1, S_2, ..., S_k&amp;lt;/math&amp;gt;:&lt;br /&gt;
*   &amp;lt;math&amp;gt;S_i \cap S_j= \varnothing, \quad i \ne j&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
*   &amp;lt;math&amp;gt;\bigcup_{i=1}^{k} S_i = X&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;&amp;lt;u&amp;gt;Действие алгоритма:&amp;lt;/u&amp;gt;&amp;lt;/b&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;Алгоритм &amp;lt;i&amp;gt;k means&amp;lt;/i&amp;gt; разбивает набор &amp;lt;math&amp;gt;X&amp;lt;/math&amp;gt; на &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; наборов &amp;lt;math&amp;gt;S_1, S_2, ..., S_k,&amp;lt;/math&amp;gt; таким образом, чтобы минимизировать сумму квадратов расстояний от каждой точки кластера до его центра (центр масс кластера). Введем обозначение, &amp;lt;math&amp;gt;S=\{S_1, S_2, ..., S_k\}&amp;lt;/math&amp;gt;. Тогда действие алгоритма &amp;lt;i&amp;gt;k means&amp;lt;/i&amp;gt; равносильно поиску:&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;table style=&amp;quot;width:100%&amp;quot;&amp;gt;&lt;br /&gt;
  &amp;lt;tr&amp;gt;&lt;br /&gt;
    &amp;lt;td align=&amp;quot;center&amp;quot; width=&amp;quot;90%&amp;quot;&amp;gt;&amp;lt;math&amp;gt;\arg\min_{S} \sum\limits_{i=1}^k \sum\limits_{\mathbf{x} \in S_i} \rho(\mathbf{x}, \mathbf{\mu}_i )^2,&amp;lt;/math&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;td align=&amp;quot;right&amp;quot;&amp;gt;&amp;lt;math&amp;gt;(1)&amp;lt;/math&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;/table&amp;gt;&lt;br /&gt;
где &amp;lt;math&amp;gt;\mathbf{\mu}_i&amp;lt;/math&amp;gt; &amp;amp;ndash; центры кластеров, &amp;lt;math&amp;gt;i=\overline{1,k}, \quad \rho(\mathbf{x}, \mathbf{\mu}_i)&amp;lt;/math&amp;gt; &amp;amp;ndash; функция расстояния между &amp;lt;math&amp;gt;\mathbf{x}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\mu_i&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;&amp;lt;u&amp;gt;Шаги алгоритма: &amp;lt;/u&amp;gt;&amp;lt;/b&amp;gt;&lt;br /&gt;
&amp;lt;ol&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&lt;br /&gt;
    &amp;lt;b&amp;gt;Начальный шаг: инициализация кластеров&amp;lt;/b&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;Выбирается произвольное множество точек &amp;lt;math&amp;gt;\mu_i, i=\overline{1,k}&amp;lt;/math&amp;gt;, рассматриваемых как начальные центры кластеров: &amp;lt;math&amp;gt;\mu_i^{(0)} = \mu_i, \quad i=\overline{1, k}&amp;lt;/math&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
  &amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&lt;br /&gt;
    &amp;lt;b&amp;gt;Распределение векторов по кластерам&amp;lt;/b&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Шаг&amp;lt;/b&amp;gt; &amp;lt;math&amp;gt;t: \forall \mathbf{x}_i \in X, i=\overline{1,n}: \mathbf{x}_i \in S_j \iff  j=\arg\min_{k}\rho(\mathbf{x}_i,\mathbf{\mu}_k^{(t-1)})^2&amp;lt;/math&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
  &amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&lt;br /&gt;
    &amp;lt;b&amp;gt;Пересчет центров кластеров&amp;lt;/b&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Шаг &amp;lt;/b&amp;gt; &amp;lt;math&amp;gt;t: \forall i=\overline{1,k}:  \mu_i^{(t)} = \cfrac{1}{|S_i|}\sum_{\mathbf{x}\in S_i}\mathbf{x}&amp;lt;/math&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
  &amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&lt;br /&gt;
    &amp;lt;b&amp;gt;Проверка условия останова:&amp;lt;/b&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
    &#039;&#039;&#039;if&#039;&#039;&#039; &amp;lt;math&amp;gt;\exist i\in \overline{1,k}: \mu_i^{(t)} \ne \mu_i^{(t-1)}&amp;lt;/math&amp;gt; &#039;&#039;&#039;then&#039;&#039;&#039;&lt;br /&gt;
        t = t + 1;&lt;br /&gt;
        goto 2;&lt;br /&gt;
    &#039;&#039;&#039;else&#039;&#039;&#039;&lt;br /&gt;
        &#039;&#039;&#039;stop&#039;&#039;&#039;&lt;br /&gt;
  &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ol&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Вычислительное ядро алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Вычислительным ядром являются шаги 2 и 3 приведенного выше алгоритма: &amp;lt;b&amp;gt;&amp;lt;i&amp;gt;распределение векторов по кластерам&amp;lt;/i&amp;gt;&amp;lt;/b&amp;gt; и &amp;lt;b&amp;gt;&amp;lt;i&amp;gt;пересчет центров кластеров&amp;lt;/i&amp;gt;&amp;lt;/b&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;&amp;lt;i&amp;gt;Распределение векторов&amp;lt;/i&amp;gt;&amp;lt;/b&amp;gt; по кластерам предполагает вычисление расстояний между каждым вектором &amp;lt;math&amp;gt;\mathbf{x}_i \in X, i= \overline{1,n}&amp;lt;/math&amp;gt; и центрами кластера &amp;lt;math&amp;gt;\mathbf{\mu}_j, j= \overline{1,k}&amp;lt;/math&amp;gt;. Таким образом, данный шаг предполагает &amp;lt;math&amp;gt;k*n&amp;lt;/math&amp;gt; вычислений расстояний между d-мерными векторами. &lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;&amp;lt;i&amp;gt;Пересчет центров кластеров&amp;lt;/i&amp;gt;&amp;lt;/b&amp;gt; предполагает &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; вычислений центров масс &amp;lt;math&amp;gt;\mathbf{\mu}_i&amp;lt;/math&amp;gt; множеств &amp;lt;math&amp;gt;S_i, i=\overline{1,k}&amp;lt;/math&amp;gt; представленных выражением в шаге 3 представленного выше алгоритма.&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Макроструктура алгоритма ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Инициализация центров масс &amp;lt;math&amp;gt;\mu_1, ..., \mu_k&amp;lt;/math&amp;gt;&amp;lt;/b&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
Наиболее распространенными являются следующие стратегии:&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&lt;br /&gt;
    &amp;lt;b&amp;gt;Метод Forgy&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;В качестве начальных значений &amp;lt;math&amp;gt;\mu_1, ..., \mu_k&amp;lt;/math&amp;gt; берутся случайно выбранные векторы.&lt;br /&gt;
  &amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&lt;br /&gt;
    &amp;lt;b&amp;gt;Метод случайно разделения (Random Partitioning)&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;Для каждого вектора &amp;lt;math&amp;gt;\mathbf{x}_i \in X, i=\overline{1, n}&amp;lt;/math&amp;gt; выбирается случайным образом кластер &amp;lt;math&amp;gt;S_1, ..., S_k&amp;lt;/math&amp;gt;, после чего для каждого полученного кластера вычисляются значения &amp;lt;math&amp;gt;\mu_1, ..., \mu_k&amp;lt;/math&amp;gt;.&lt;br /&gt;
  &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Распределение векторов по кластерам&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Для этого шага алгоритма между векторами &amp;lt;math&amp;gt;\mathbf{x}_i \in X, i=\overline{1, n}&amp;lt;/math&amp;gt; и центрами кластеров &amp;lt;math&amp;gt;\mu_1, ..., \mu_k&amp;lt;/math&amp;gt; вычисляются &amp;lt;b&amp;gt;расстояния&amp;lt;/b&amp;gt; по формуле (как правило, используется Евлидово расстояние):&lt;br /&gt;
&amp;lt;table style=&amp;quot;width:100%&amp;quot;&amp;gt;&lt;br /&gt;
  &amp;lt;tr&amp;gt;&lt;br /&gt;
    &amp;lt;td align=&amp;quot;center&amp;quot; width=&amp;quot;90%&amp;quot;&amp;gt;&amp;lt;math&amp;gt; \mathbf{v}_1, \mathbf{v}_2 \in \mathbb{R}^d,  \quad \rho(\mathbf{v}_1, \mathbf{v}_2) = \lVert \mathbf{v}_1- \mathbf{v}_2 \rVert= \sqrt{\sum_{i=1}^{d}(\mathbf{v}_{1,i} - \mathbf{v}_{2,i})^2}&amp;lt;/math&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;td align=&amp;quot;right&amp;quot;&amp;gt;&amp;lt;math&amp;gt;(2)&amp;lt;/math&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;/table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Пересчет центров кластеров&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Для этого шага алгоритма производится пересчет центров кластера по &amp;lt;b&amp;gt;формуле вычисления центра масс&amp;lt;/b&amp;gt;:&lt;br /&gt;
&amp;lt;table style=&amp;quot;width:100%&amp;quot;&amp;gt;&lt;br /&gt;
  &amp;lt;tr&amp;gt;&lt;br /&gt;
    &amp;lt;td align=&amp;quot;center&amp;quot; width=&amp;quot;90%&amp;quot;&amp;gt;&amp;lt;math&amp;gt; \mu = \cfrac{1}{|S|}\sum_{\mathbf{x}\in S}\mathbf{x}&amp;lt;/math&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;td align=&amp;quot;right&amp;quot;&amp;gt;&amp;lt;math&amp;gt;(3)&amp;lt;/math&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;/table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Схема реализации последовательного алгоритма ===&lt;br /&gt;
&lt;br /&gt;
 &#039;&#039;&#039;algorithm&#039;&#039;&#039; k-means &#039;&#039;&#039;is&#039;&#039;&#039;&lt;br /&gt;
     &#039;&#039;&#039;1.&#039;&#039;&#039; Инициализировать центры кластеров &amp;lt;math&amp;gt;\mathbf{\mu}_i^{(1)}, i=\overline{1,k}&amp;lt;/math&amp;gt;&lt;br /&gt;
     &#039;&#039;&#039;2.&#039;&#039;&#039; &amp;lt;math&amp;gt;t \leftarrow 1&amp;lt;/math&amp;gt;&lt;br /&gt;
     &#039;&#039;&#039;3.&#039;&#039;&#039; &#039;&#039;&#039;Распределение по кластерам&#039;&#039;&#039;&amp;lt;br&amp;gt;&lt;br /&gt;
        &amp;lt;math&amp;gt;S_i^{(t)}=\{\mathbf{x}_p: \lVert\mathbf{x}_p-\mathbf{\mu}_i^{(t)}\rVert^2 \leq \lVert\mathbf{x}_p-\mathbf{\mu}_j^{(t)}\rVert^2 \quad \forall j=\overline{1,k}\},&amp;lt;/math&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
        где каждый вектор &amp;lt;math&amp;gt;\mathbf{x}_p&amp;lt;/math&amp;gt; соотносится единственному кластеру &amp;lt;math&amp;gt;S^{(t)}&amp;lt;/math&amp;gt;&lt;br /&gt;
     &#039;&#039;&#039;4.&#039;&#039;&#039; &#039;&#039;&#039;Обновление центров кластеров&#039;&#039;&#039;&amp;lt;br&amp;gt;&lt;br /&gt;
        &amp;lt;math&amp;gt;\mathbf{\mu}_i^{(t+1)} = \frac{1}{|S^{(t)}_i|} \sum_{\mathbf{x}_j \in S^{(t)}_i} \mathbf{x}_j &amp;lt;/math&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
     &#039;&#039;&#039;5.&#039;&#039;&#039; &#039;&#039;&#039;if&#039;&#039;&#039; &amp;lt;math&amp;gt;\exist i \in \overline{1,k}: \mathbf{\mu}_i^{(t+1)} \ne \mathbf{\mu}_i^{(t)}&amp;lt;/math&amp;gt; &#039;&#039;&#039;then&#039;&#039;&#039;&lt;br /&gt;
            t = t + 1;&lt;br /&gt;
            goto &#039;&#039;&#039;3&#039;&#039;&#039;;&lt;br /&gt;
        &#039;&#039;&#039;else&#039;&#039;&#039;&lt;br /&gt;
            &#039;&#039;&#039;stop&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
=== Последовательная сложность алгоритма===&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding-bottom: 20px&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;Обозначим &amp;lt;math&amp;gt;\Theta_{centroid}^{d, m}&amp;lt;/math&amp;gt; временную сложность вычисления центорида кластера, число элементов которого равна &amp;lt;math&amp;gt;m&amp;lt;/math&amp;gt;,  в d-мерном пространстве.&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;Аналогично  &amp;lt;math&amp;gt;\Theta_{distance}^d&amp;lt;/math&amp;gt; &amp;amp;ndash; временная сложность вычисления расстояния между двумя d-мерными векторами.&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding-bottom: 20px&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;Сложность шага инициализации &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластеров мощности &amp;lt;math&amp;gt;m&amp;lt;/math&amp;gt; в d-мерном пространстве &amp;amp;ndash; &amp;lt;math&amp;gt;\Theta_{init}^{k, d, m}&amp;lt;/math&amp;gt;&amp;lt;/b&amp;gt;&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;i&amp;gt;Стратерия Forgy&amp;lt;/i&amp;gt;: вычисления не требуются, &amp;lt;math&amp;gt;\Theta_{init}^{k, d, m} = 0&amp;lt;/math&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;i&amp;gt;Стратегия случайного разбиения&amp;lt;/i&amp;gt;: вычисление центров &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластеров,  &amp;lt;math&amp;gt;\Theta_{init}^{k, d, m} = k*\Theta_{centroid}^{d, m}, m \le n&amp;lt;/math&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding-bottom: 20px&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Cложность шага распределения d мерных векторов по &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластерам &amp;amp;ndash; &amp;lt;math&amp;gt;\Theta_{distribute}^{k, d}&amp;lt;/math&amp;gt;&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
На этом шаге для каждого вектора &amp;lt;math&amp;gt;\mathbf{x}_i \in X, i=\overline{1, n}&amp;lt;/math&amp;gt; вычисляется k расстояний до центров кластеров &amp;lt;math&amp;gt;\mathbf{\mu}_1, ...\mathbf{\mu}_k&amp;lt;/math&amp;gt;&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p align=&amp;quot;center&amp;quot;&amp;gt;&lt;br /&gt;
  &amp;lt;math&amp;gt;\Theta_{distribute}^{k, d} = n*k*\Theta_{distance}^d&amp;lt;/math&amp;gt;&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding-bottom: 20px&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;Сложность шага пересчета центров &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластеров размера &amp;lt;math&amp;gt;m&amp;lt;/math&amp;gt; в d-мерном пространстве &amp;amp;ndash; &amp;lt;math&amp;gt;\Theta_{recenter}^{k, d, m}&amp;lt;/math&amp;gt;&amp;lt;/b&amp;gt;&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;На этом шаге вычисляется &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; центров кластеров &amp;lt;math&amp;gt;\mathbf{\mu}_1, ...\mathbf{\mu}_k&amp;lt;/math&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p align=&amp;quot;center&amp;quot;&amp;gt;&amp;lt;math&amp;gt;\Theta_{recenter}^{k, d, m} = k*\Theta_{centroid}^{d, m}&amp;lt;/math&amp;gt; &amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding-bottom: 20px&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Рассчитаем &amp;lt;math&amp;gt;\Theta_{centroid}^{d, m}&amp;lt;/math&amp;gt; для кластера, число элементов которого равно &amp;lt;math&amp;gt;m&amp;lt;/math&amp;gt;&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p align=&amp;quot;center&amp;quot;&amp;gt;&amp;lt;math&amp;gt;\Theta_{centroid}^{d, m}&amp;lt;/math&amp;gt; = &amp;lt;math&amp;gt;m * d&amp;lt;/math&amp;gt; сложений + &amp;lt;math&amp;gt;d&amp;lt;/math&amp;gt; делений &amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding-bottom: 20px&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Рассчитаем &amp;lt;math&amp;gt;\Theta_{distance}^d&amp;lt;/math&amp;gt; в соответствие с формулой &amp;lt;math&amp;gt;(2)&amp;lt;/math&amp;gt;&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p align=&amp;quot;center&amp;quot;&amp;gt;&amp;lt;math&amp;gt;\Theta_{distance}^d&amp;lt;/math&amp;gt; = &amp;lt;math&amp;gt;d&amp;lt;/math&amp;gt; вычитаний + &amp;lt;math&amp;gt;d&amp;lt;/math&amp;gt; умножений + &amp;lt;math&amp;gt;(d-1)&amp;lt;/math&amp;gt; сложение&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding-bottom: 20px&amp;quot;&amp;gt;&lt;br /&gt;
  &amp;lt;p&amp;gt;Предположим, что алгоритм сошелся за &amp;lt;math&amp;gt;\Tau&amp;lt;/math&amp;gt; итераций, тогда временная сложность алгоритма &amp;lt;math&amp;gt;\Theta_{k-means}^{d, n}&amp;lt;/math&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
  &amp;lt;p align=&amp;quot;center&amp;quot;&amp;gt;&amp;lt;b&amp;gt;&amp;lt;math&amp;gt;\Theta_{k-means}^{d, n} \le \Theta_{init}^{k, d, n} + \Tau*(\Theta_{distribute}^{k, d} + \Theta_{recenter}^{k, d, n})&amp;lt;/math&amp;gt;&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding-bottom: 5px&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;Операции сложения/вычитания:&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p align=&amp;quot;center&amp;quot;&amp;gt;&amp;lt;b&amp;gt;&amp;lt;math&amp;gt;\Theta_{k-means}^{d, n} \le k*n*d+ \Tau*(k*n*(2d-1) + k*n*d) = k*n*d+ \Tau*(k*n*(3d-1)) \thicksim O(\Tau*k*d*n)&amp;lt;/math&amp;gt;&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding-bottom: 20px&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;Операции умножения/деления:&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p align=&amp;quot;center&amp;quot;&amp;gt;&amp;lt;b&amp;gt;&amp;lt;math&amp;gt;\Theta_{k-means}^{d, n} \le k*d + \Tau*(k*n*d + k*d) = k*d + \Tau * k*d*(n+1) \thicksim O(\Tau*k*d*n) &amp;lt;/math&amp;gt;&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding-bottom: 20px&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;Получаем, что &amp;lt;b&amp;gt;временная сложность&amp;lt;/b&amp;gt; алгоритма &amp;lt;b&amp;gt;k means&amp;lt;/b&amp;gt; кластеризации &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; &amp;lt;b&amp;gt;d-мерных&amp;lt;/b&amp;gt; векторов на &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластеров за &amp;lt;math&amp;gt;\Tau&amp;lt;/math&amp;gt; итераций:&amp;lt;/p&amp;gt;&lt;br /&gt;
 &amp;lt;p align=&amp;quot;center&amp;quot;&amp;gt;&amp;lt;b&amp;gt;&amp;lt;math&amp;gt; \Theta_{k-means}^{d, n} \thicksim O(\Tau*k*d*n) &amp;lt;/math&amp;gt;&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Информационный граф ===&lt;br /&gt;
&lt;br /&gt;
Рассмотрим информационный граф алгоритма. Алгоритм &amp;lt;i&amp;gt;k means&amp;lt;/i&amp;gt; начинается с этапа инициализации, после которого следуют итерации, на каждой из которых выполняется два последовательных шага (см. [[#Схема реализации последовательного алгоритма|&amp;quot;Схема реализации последовательного алгоритма&amp;quot;]]): &lt;br /&gt;
* распределение векторов по кластерам&lt;br /&gt;
* перерасчет центров кластеров&lt;br /&gt;
&lt;br /&gt;
Поскольку основная часть вычислений приходится на шаги итераций, распишем информационные графы данных шагов.&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Распределение векторов по кластерам&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
Информационный граф шага распределения векторов по кластерам представлен на &#039;&#039;рисунке 1&#039;&#039;. Исходами данного графа является исходные векторы &amp;lt;math&amp;gt;\mathbf{x}_1, ..., \mathbf{x}_n&amp;lt;/math&amp;gt;, а также центры кластеров &amp;lt;math&amp;gt;\mathbf{\mu}_1, ... \mathbf{\mu}_k&amp;lt;/math&amp;gt;, вычисленные ранее (на шаге инициализации, если рассматривается первая итерация алгоритма, или на шаге пересчета центров кластеров предыдущей итерации в противном случае). Каждая пара векторов данных &amp;lt;math&amp;gt;\mathbf{x}_i, i=\overline{1,n}&amp;lt;/math&amp;gt; и центров кластера &amp;lt;math&amp;gt;\mathbf{\mu}_j, j=\overline{1, k}&amp;lt;/math&amp;gt; : (&amp;lt;math&amp;gt;\mathbf{x}_i&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;\mathbf{\mu}_j&amp;lt;/math&amp;gt;) подаются на независимые узлы &amp;lt;i&amp;gt;&amp;quot;d&amp;quot;&amp;lt;/i&amp;gt; вычисления расстояния между векторами (более подробная схема вычисления расстояния представлена далее, &#039;&#039;рисунок 2&#039;&#039;). Далее узлы вычисления расстояния &amp;lt;i&amp;gt;&amp;quot;d&amp;quot;&amp;lt;/i&amp;gt;, соответствующие одному и тому же исходному вектору &amp;lt;math&amp;gt;\mathbf{x}_i&amp;lt;/math&amp;gt; передаются на один узел &amp;lt;i&amp;gt;&amp;quot;m&amp;quot;&amp;lt;/i&amp;gt;, где далее происходит вычисление новой метки кластера для каждого вектора &amp;lt;math&amp;gt;\mathbf{x}_i&amp;lt;/math&amp;gt; (берется кластер с минимальным результатом вычисления расстояния). На выходе графа выдаются метки кластеров , &amp;lt;math&amp;gt;L_1, ..., L_n&amp;lt;/math&amp;gt;, такие что &amp;lt;math&amp;gt;\forall \mathbf{x}_i, i=\overline{1, n}, \mathbf{x}_i \in S_j \Leftrightarrow L_i = j&amp;lt;/math&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
[[file:Clusterization.png|thumb|center|800px|Рис. 1. Схема распределения векторов по кластерам. &#039;&#039;d&#039;&#039; &amp;amp;ndash; вычисление расстояния между векторами; &#039;&#039;m&#039;&#039; &amp;amp;ndash; вычисление минимума.]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Вычисление расстояния между векторами&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
Подробная схема вычисления расстояния между векторами &amp;lt;math&amp;gt;\mathbf{x}_i, \mathbf{\mu}_j&amp;lt;/math&amp;gt; представлена на &#039;&#039;рисунке 2&#039;&#039;. Как показано на графе, узел вычисления расстояния между векторами &amp;lt;i&amp;gt;&amp;quot;d&amp;quot;&amp;lt;/i&amp;gt; состоит из шага взятия разности между векторами (узел &amp;quot;&amp;lt;math&amp;gt;-&amp;lt;/math&amp;gt;&amp;quot;) и взятия нормы получившегося вектора разности (узел &amp;quot;&amp;lt;math&amp;gt;||\cdot||^2&amp;lt;/math&amp;gt;&amp;quot;). Более подробно, вычисление расстояния между векторами &amp;lt;math&amp;gt;\mathbf{x}_i = {x_{i1,}, ...,{x_{in}}}, \mathbf{\mu}_j = {\mu_{j1}, ...,\mu_{jn}}&amp;lt;/math&amp;gt; может быть представлено как вычисление разности между каждой парой компонент &amp;lt;math&amp;gt;(x_{iz}, \mu_{jz}), z=\overline{1, d}&amp;lt;/math&amp;gt; (узел &amp;quot;&amp;lt;math&amp;gt;-&amp;lt;/math&amp;gt;&amp;quot;), далее возведение в квадрат для каждого узла &amp;quot;&amp;lt;math&amp;gt;-&amp;lt;/math&amp;gt;&amp;quot; (узел &amp;quot;&amp;lt;math&amp;gt;()^2&amp;lt;/math&amp;gt;&amp;quot;) и суммирования выходов всех узлов &amp;quot;&amp;lt;math&amp;gt;()^2&amp;lt;/math&amp;gt;&amp;quot; (узел &amp;quot;&amp;lt;math&amp;gt;+&amp;lt;/math&amp;gt;&amp;quot;).  &lt;br /&gt;
&lt;br /&gt;
[[file:dist_calc.png|thumb|center|800px|Рис. 2. Схема вычисления расстояния между вектором и центром кластера.]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Пересчет центров кластеров&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
Информационный граф шага пересчета центров кластеров представлен на &#039;&#039;рисунке 3&#039;&#039;. Исходами данного графа является исходные векторы &amp;lt;math&amp;gt;\mathbf{x}_1, ..., \mathbf{x}_n&amp;lt;/math&amp;gt;, а также им соответствующие метки кластера, &amp;lt;math&amp;gt;L_1, ..., L_n&amp;lt;/math&amp;gt;, такие что &amp;lt;math&amp;gt;\forall x_i, i=\overline{1, n}, \mathbf{x}_i \in S_j \Leftrightarrow L_i = j&amp;lt;/math&amp;gt;, вычисленные на этапе распределения векторов по кластерам. Все векторы &amp;lt;math&amp;gt;\mathbf{x}_1, ..., \mathbf{x}_n&amp;lt;/math&amp;gt; подаются в узлы &amp;lt;math&amp;gt;+_1, ...+_k&amp;lt;/math&amp;gt;, каждый узел &amp;lt;math&amp;gt;+_m, m = \overline{1,k}&amp;lt;/math&amp;gt; соответствует операции сложения векторов кластера с номером &amp;lt;math&amp;gt;m&amp;lt;/math&amp;gt;. Метки кластера &amp;lt;math&amp;gt;L_1, ..., L_n&amp;lt;/math&amp;gt; также совместно передаются на узлы &amp;lt;math&amp;gt;S_m, m = \overline{1,k}&amp;lt;/math&amp;gt;, на каждом из которых вычисляется количество векторов в соответствующем кластере (количество меток с соответствующим значением). Далее каждая пара выходов узлов &amp;lt;math&amp;gt;+_m&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;S_m&amp;lt;/math&amp;gt; подается на узел &amp;quot;&amp;lt;math&amp;gt;/&amp;lt;/math&amp;gt;&amp;quot;, где производится деление суммы векторов кластера на количество элементов в нем. Значения, вычисленные на узлах &amp;quot;&amp;lt;math&amp;gt;/&amp;lt;/math&amp;gt;&amp;quot;, присваиваются новым центрам кластеров (выходные значения графа).&lt;br /&gt;
&lt;br /&gt;
[[file:Recluster.png|thumb|center|800px|Рис. 3. Схема пересчета центров кластеров]]&lt;br /&gt;
&lt;br /&gt;
=== Ресурс параллелизма алгоритма ===&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
Работа алгоритма состоит из &amp;lt;math&amp;gt;\Tau&amp;lt;/math&amp;gt; итераций, в каждой из которых происходит &amp;lt;b&amp;gt;распределение d-мерных векторов по &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластерам&amp;lt;/b&amp;gt;, а также &amp;lt;b&amp;gt;пересчет центров кластеров в d-мерном пространстве&amp;lt;/b&amp;gt;. В шаге &amp;lt;b&amp;gt;распределения d-мерных векторов по &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластерам&amp;lt;/b&amp;gt; расстояния между вектором и центрами кластеров вычисляются независимо (отсутствуют информационные зависимости). &amp;lt;b&amp;gt;Центры масс кластеров&amp;lt;/b&amp;gt; также пересчитываются независимо друг от друга. Таким образом, имеет место [[глоссарий#Массовый параллелизм|&#039;&#039;массовый параллелизм&#039;&#039;]]. Вычислим параллельную сложность &amp;lt;math&amp;gt;\Psi_*&amp;lt;/math&amp;gt; каждого из шагов, а также параллельную сложность всего алгоритма, &amp;lt;math&amp;gt;\Psi_{k-means}&amp;lt;/math&amp;gt;. Будем исходить из предположения, что может быть использовано любое необходимое число потоков.&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Распределение d-мерных векторов по &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластерам&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;  &lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
Поскольку на данном шаге для каждой пары векторов &amp;lt;math&amp;gt;\mathbf{x}_i, i=\overline{1,n}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\mathbf{\mu}_j, j=\overline{1,k}&amp;lt;/math&amp;gt; операции вычисления расстояния не зависят друг от друга, они могут выполняться параллельно. Тогда, разделив все вычисление расстояний на &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; потоков, получим, что в каждом потоке будет выполняться только одна операция вычисления расстояния между векторами размерности d. При этом каждому вычислительному потоку передаются координаты центров всех кластеров &amp;lt;math&amp;gt;\mathbf{\mu}_1, ..., \mathbf{\mu}_k&amp;lt;/math&amp;gt;. Таким образом, параллельная сложность данного шага определяется &amp;lt;i&amp;gt; сложностью параллельной операции вычисления расстояния между d-мерными векторами&amp;lt;/i&amp;gt;, &amp;lt;math&amp;gt;\Psi_{distance}^d&amp;lt;/math&amp;gt;  и &amp;lt;i&amp;gt;сложностью определения наиболее близкого кластера&amp;lt;/i&amp;gt; (паралельное взятие минимума по расстояниям), &amp;lt;math&amp;gt;\Psi_{min}^k&amp;lt;/math&amp;gt;. Для оценки &amp;lt;math&amp;gt;\Psi_{distance}^d&amp;lt;/math&amp;gt; воспользуемся  [[Нахождение_частных_сумм_элементов_массива_сдваиванием | параллельной реализацией нахождения частичной суммы элементов массива путем сдваивания]]. Аналогично, &amp;lt;math&amp;gt;\Psi_{min}^k = log(k)&amp;lt;/math&amp;gt;. В результате, &amp;lt;math&amp;gt;\Psi_{distance}^d = O(log(d))&amp;lt;/math&amp;gt;.   Таким образом: &lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p align=&amp;quot;center&amp;quot;&amp;gt;&amp;lt;math&amp;gt;\Psi_{distribute}^{k, d}  = \Psi_{distance}^d + \Psi_{min}^k = O(log(d))+O(log(k)) = O(log(k*d))&amp;lt;/math&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Пересчет центров кластеров в d-мерном пространстве&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
Поскольку на данном шаге для каждого из &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластеров центр масс может быть вычислен независимо, данные операции могут быть выполнены в отдельных потоках. Таким образом, параллельная сложность данного шага, &amp;lt;math&amp;gt;\Psi_{recenter}^{k, d}&amp;lt;/math&amp;gt;,  будет определяться &amp;lt;i&amp;gt;параллельной сложностью вычисления одного центра масс кластера размера &amp;lt;math&amp;gt;m&amp;lt;/math&amp;gt;&amp;lt;/i&amp;gt;, &amp;lt;math&amp;gt;\Psi_{recenter}^{k, d}&amp;lt;/math&amp;gt;,  а так как &amp;lt;math&amp;gt;m \le n \Rightarrow \Psi_{recenter}^{d, m} \le \Psi_{recenter}^{d, n}&amp;lt;/math&amp;gt;. Сложность вычисления центра масс кластера d-мерных векторов размера n аналогично предыдущим вычислениям равна &amp;lt;math&amp;gt;O(log(n))&amp;lt;/math&amp;gt;. Тогда:  &lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p align=&amp;quot;center&amp;quot;&amp;gt;&amp;lt;math&amp;gt;\Psi_{recenter}^{k, d}  \le \Psi_{recenter}^{d, n} = O(log(n))&amp;lt;/math&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Общая параллельная сложность алгоритма&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
На каждой итерации необходимо обновление центров кластеров, которые будут использованы на следующей итерации. Таким образом, итерационный процесс выполняется последовательно&amp;lt;ref&amp;gt;Zhao, Weizhong, Huifang Ma, and Qing He. &amp;quot;Parallel k-means clustering based on mapreduce.&amp;quot; IEEE International Conference on Cloud Computing. Springer Berlin Heidelberg, 2009.&amp;lt;/ref&amp;gt;. Тогда, поскольку сложность каждой итерации  определяется &amp;lt;math&amp;gt;\Psi_{distribute}^{k, d}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\Psi_{recenter}&amp;lt;/math&amp;gt;, сложность всего алгоритма, &amp;lt;math&amp;gt;\Psi_{k-means}&amp;lt;/math&amp;gt; в предположении, что было сделано &amp;lt;math&amp;gt;\Tau&amp;lt;/math&amp;gt; операций определяется выражением&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p align=&amp;quot;center&amp;quot;&amp;gt;&amp;lt;math&amp;gt;\Psi_{k-means} \approx \Tau * (\Psi_{distribute}^{k, d} + \Psi_{recenter}^{k, d}) \le \Tau * O(log(k*d*n))&amp;lt;/math&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Входные и выходные данные алгоритма ===&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;Входные данные&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;Матрица из &amp;lt;math&amp;gt;n*d&amp;lt;/math&amp;gt; элементов &amp;lt;math&amp;gt;x_{i, j} \in \mathbb{R}, i=\overline{1, n}, j=\overline{1, d}&amp;lt;/math&amp;gt;&amp;amp;ndash; координат векторов (наблюдений).&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;Целое положительное число &amp;lt;math&amp;gt;k, k \le n&amp;lt;/math&amp;gt; &amp;amp;ndash; количество кластеров.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;Объем входных данных&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;math&amp;gt;1&amp;lt;/math&amp;gt; целое число + &amp;lt;math&amp;gt;n*d&amp;lt;/math&amp;gt; вещественных чисел (при условии, что координаты &amp;amp;ndash; вещественные числа).&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;Выходные данные&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; целых положительных чисел &amp;lt;math&amp;gt;L_1, ..., L_n&amp;lt;/math&amp;gt;&amp;amp;ndash; номера кластеров, соотвествующие каждому вектору (при условии, что нумерация кластеров начинается с &amp;lt;math&amp;gt;1&amp;lt;/math&amp;gt;).&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;Объем выходных данных&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; целых положительных чисел.&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Свойства алгоритма ===&lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;[[глоссарий#Вычислительная мощность|&#039;&#039;Вычислительная мощность&#039;&#039;]]&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
Вычислительная мощность алгоритма &amp;lt;i&amp;gt;k means&amp;lt;/i&amp;gt; равна &amp;lt;math&amp;gt;\frac{k*d*n*\Tau}{n*d} = k*\Tau &amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; &amp;amp;ndash; число кластеров, &amp;lt;math&amp;gt;\Tau&amp;lt;/math&amp;gt; &amp;amp;ndash; число итераций алгоритма.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;[[глоссарий#Детерминированность |&#039;&#039;Детерминированность&#039;&#039;]] и [[глоссарий#Устойчивость |&#039;&#039;Устойчивость&#039;&#039;]] &amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
Алгоритм &amp;lt;i&amp;gt;k means&amp;lt;/i&amp;gt; является итерационным. Количество итераций алгоритма в общем случае не фиксируется и зависит от начального расположения объектов в пространстве, параметра &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt;, а также от начального приближения центров кластеров, &amp;lt;math&amp;gt;\mu_1, ..., \mu_k&amp;lt;/math&amp;gt;. В результате этого может варьироваться результат работы алгоритма. При неудачном выборе начальных параметров итерационный процесс может сойтись к локальному оптимуму&amp;lt;ref&amp;gt;Von Luxburg, Ulrike. Clustering Stability. Now Publishers Inc, 2010.&amp;lt;/ref&amp;gt;. По этим причинам алгоритм не является ни &amp;lt;b&amp;gt;детермирированным&amp;lt;/b&amp;gt;, ни &amp;lt;b&amp;gt;устойчивым&amp;lt;/b&amp;gt;.&lt;br /&gt;
 &lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Соотношение последовательной и параллельной сложности алгоритма&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\frac{\Theta_{k-means}}{\Psi_{k-means}} = \frac{O(\Tau*k*d*n)}{O(\Tau*log(k*d*n))}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Сильные стороны алгоритма&amp;lt;/b&amp;gt;:&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;i&amp;gt;Сравнительно высокая эффективность при простоте реализации&amp;lt;/i&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;i&amp;gt;Высокое качество кластеризации&amp;lt;/i&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;i&amp;gt;Возможность распараллеливания&amp;lt;/i&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;i&amp;gt;Существование множества модификаций&amp;lt;/i&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;Недостатки алгоритма&amp;lt;/b&amp;gt;&amp;lt;ref&amp;gt;Ortega, Joaquín Pérez, Ma Del Rocío Boone Rojas, and María J. Somodevilla. &amp;quot;Research issues on K-means Algorithm: An Experimental Trial Using Matlab.&amp;quot;&amp;lt;/ref&amp;gt;:&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;i&amp;gt;Количество кластеров является параметром алгоритма&amp;lt;/i&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;&amp;lt;i&amp;gt;Чувствительность к начальным условиям&amp;lt;/i&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;Инициализация центров кластеров в значительной степени влияет на результат кластеризации.&amp;lt;/p&amp;gt;&lt;br /&gt;
  &amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;&amp;lt;i&amp;gt;Чувствительность к выбросам и шумам&amp;lt;/i&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;Выбросы, далекие от центров настоящих кластеров, все равно учитываются при вычислении их центров.&amp;lt;/p&amp;gt;&lt;br /&gt;
  &amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;&amp;lt;i&amp;gt;Возможность сходимости к локальному оптимуму&amp;lt;/i&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;Итеративный подход не дает гарантии сходимости к оптимальному решению.&amp;lt;/p&amp;gt;&lt;br /&gt;
  &amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;&amp;lt;i&amp;gt;Использование понятия &amp;quot;среднего&amp;quot;&amp;lt;/i&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;Алгоритм неприменим к данным, для которых не определено понятие &amp;quot;среднего&amp;quot;, например, категориальным данным.&amp;lt;/p&amp;gt;&lt;br /&gt;
  &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&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;
Исследование масштабируемости параллельной реализации алгоритма k means проводилось на суперкомпьютере &amp;quot;Ломоносов&amp;quot;. Алгоритм реализован на языке C с использованием средств MPI.&lt;br /&gt;
Для исследования масштабируемости проводилось множество запусков программы с разным значением параметра (количество векторов для кластеризации), а также с различным числом процессоров. Фиксировались результаты запусков &amp;amp;ndash; время работы &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt; и количество произведенных итераций алгоритма &amp;lt;math&amp;gt;\Tau&amp;lt;/math&amp;gt;.&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;Значения &amp;lt;b&amp;gt;количества векторов&amp;lt;/b&amp;gt; &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;: 20&#039;000, 30&#039;000, 50&#039;000, 100&#039;000, 200&#039;000, 300&#039;000, 500&#039;000, 700&#039;000, 1&#039;000&#039;000, 1&#039;500&#039;000, 2&#039;000&#039;000.&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;Значения &amp;lt;b&amp;gt;количества процессоров&amp;lt;/b&amp;gt; &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt;: 1, 8, 16, 32, 64, 128, 160, 192, 224, 256, 288, 320, 352, 384, 416, 448, 480, 512.&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;Значение &amp;lt;b&amp;gt;количества кластеров&amp;lt;/b&amp;gt; &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt;: 100.&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;Значение &amp;lt;b&amp;gt;размерности векторов&amp;lt;/b&amp;gt; &amp;lt;math&amp;gt;d&amp;lt;/math&amp;gt;: 10.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Графики производительности и эффективности реализации представлены на рисунках 4 и 5 соответственно.&lt;br /&gt;
&lt;br /&gt;
[[file:Flops.png|thumb|center|800px|Рис. 4. График производительности реализации алгоритма.]]&lt;br /&gt;
&lt;br /&gt;
[[file:Efficiency.png|thumb|center|800px|Рис. 5. График эффективности реализации алгоритма.]]&lt;br /&gt;
&lt;br /&gt;
Для заданной конфигурации эксперимента (&amp;lt;math&amp;gt;n, p, k&amp;lt;/math&amp;gt;) и полученных результатах (&amp;lt;math&amp;gt;t, \Tau&amp;lt;/math&amp;gt;) производительность и эффективность реализации расчитывались по формулам (см. [[#Последовательная сложность алгоритма| последовательная сложность алгоритма]]):&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;math&amp;gt;Performance = \frac{\Theta_{k-means}^{d, n}}{t}&amp;lt;/math&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;math&amp;gt;Efficiency = &amp;lt;/math&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
В результате экспериментальной оценки были получены следующие оценки эффективности реализации:&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;b&amp;gt;Минимальное&amp;lt;/b&amp;gt; значение: 0.000409 %&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;b&amp;gt;Максимальное&amp;lt;/b&amp;gt; значение: 0.741119 %&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Динамические характеристики и эффективность реализации алгоритма ===&lt;br /&gt;
=== Выводы для классов архитектур ===&lt;br /&gt;
=== Существующие реализации алгоритма ===&lt;br /&gt;
==== Открытое программное обеспечение ====&lt;br /&gt;
&amp;lt;ol&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;[https://www.icpsr.umich.edu/CrimeStat/ CrimeStat]&amp;lt;/li&amp;gt; Программное обеспечение, созданное для операционных систем Windows, предоставляющее инструменты статистического  и пространственного анализа для решения задачи картирования преступности.&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://juliastats.github.io Julia]&amp;lt;/li&amp;gt; Высокоуровневый высокопроизводительный свободный язык программирования с динамической типизацией, созданный для математических вычислений, содержит реализацию k-means.&lt;br /&gt;
  &amp;lt;li&amp;gt;[https://mahout.apache.org Mahout]&amp;lt;/li&amp;gt; Apache Mahout - Java библиотека для работы с алгоритмами машинного обучения с использованием MapReduce. Содержит реализацию k-means.&lt;br /&gt;
  &amp;lt;li&amp;gt;[https://www.gnu.org/software/octave/ Octave]&amp;lt;/li&amp;gt; Написанная на C++  свободная система для математических вычислений, использующая совместимый с MATLAB язык высокого уровня, содержит реализацию k-means.&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://spark.apache.org/docs/latest/mllib-clustering.html Spark]&amp;lt;/li&amp;gt; Распределенная реализация k-means содержится в библиотеке Mlib для работы с алгоритмами машинного обучения, взаимодействующая с Python библиотекой NumPy и библиотека R.&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://torch.ch Torch]&amp;lt;/li&amp;gt;  MATLAB-подобная библиотека для языка программирования Lua с открытым исходным кодом, предоставляет большое количество алгоритмов для глубинного обучения и научных расчётов. Ядро написано на Си, прикладная часть выполняется на LuaJIT, поддерживается распараллеливание вычислений средствами CUDA и OpenMP. Существуют реализации k-means.&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://www.cs.waikato.ac.nz/ml/weka/ Weka]&amp;lt;/li&amp;gt;  Cвободное программное обеспечение для анализа данных, написанное на Java. Содержит k-means и x-means.&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://accord-framework.net/docs/html/T_Accord_MachineLearning_KMeans.htm Accord.NET]&amp;lt;/li&amp;gt; C# реализация алгоритмов k-means, k-means++, k-modes.&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://docs.opencv.org/3.0-beta/doc/py_tutorials/py_ml/py_kmeans/py_kmeans_opencv/py_kmeans_opencv.html OpenCV]&amp;lt;/li&amp;gt; Написанная на С++ библиотека, направленная в основном на решение задач компьютерного зрения. Содержит реализацию k-means.&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://mlpack.org/ MLPACK]&amp;lt;/li&amp;gt; Масштабируемая С++ библиотека для работы с алгоритмами машинного обучения, содержит реализацию k-means.&lt;br /&gt;
  &amp;lt;li&amp;gt;[https://www.scipy.org/ SciPy]&amp;lt;/li&amp;gt; Библиотека Python, содержит множество реализаций k-means.&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://scikit-learn.org/ scikit-learn]&amp;lt;/li&amp;gt; Библиотека Python, содержит множество реализаций k-means.&lt;br /&gt;
  &amp;lt;li&amp;gt;[https://www.r-bloggers.com/k-means-clustering-in-r/ R]&amp;lt;/li&amp;gt; Язык программирования для статистической обработки данных и работы с графикой, а также свободная программная среда вычислений с открытым исходным кодом в рамках проекта GNU, содержит три реализации k-means.&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://elki.dbs.ifi.lmu.de ELKI]&amp;lt;/li&amp;gt; Java фреймворк, содержащий реализацию k-means, а также множество других алгоритмов кластеризации.&lt;br /&gt;
&amp;lt;/ol&amp;gt;&lt;br /&gt;
==== Проприетарное программное обеспечение  ====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ol&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;[https://www.ayasdi.com/blog/bigdata/topological-data-analysis-of-oil-and-gas-petrophysical-data/ Ayasdi]&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://www.stata.com/features/cluster-analysis/ Stata]&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://mathworld.wolfram.com/K-MeansClusteringAlgorithm.html Mathematica]&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://www.mathworks.com/help/stats/kmeans.html?requestedDomain=www.mathworks.com MATLAB]&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;[https://support.sas.com/rnd/app/stat/procedures/fastclus.html SAS]&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://docs.rapidminer.com/studio/operators/modeling/segmentation/k_means.html RapidMiner]&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;[https://blogs.sap.com/2013/03/28/sap-hana-pal-k-means-algorithm-or-how-to-do-customer-segmentation-for-the-telecommunications-industry/ SAP HANA]&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ol&amp;gt;&lt;br /&gt;
== Литература ==&lt;br /&gt;
&amp;lt;references /&amp;gt;&lt;/div&gt;</summary>
		<author><name>DennZo1993</name></author>
	</entry>
	<entry>
		<id>https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:%D0%91%D1%80%D0%BE%D1%82%D0%B8%D0%BA%D0%BE%D0%B2%D1%81%D0%BA%D0%B0%D1%8F_%D0%94%D0%B0%D0%BD%D1%83%D1%82%D0%B0/%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_k-means&amp;diff=17165</id>
		<title>Участник:Бротиковская Данута/Алгоритм k-means</title>
		<link rel="alternate" type="text/html" href="https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:%D0%91%D1%80%D0%BE%D1%82%D0%B8%D0%BA%D0%BE%D0%B2%D1%81%D0%BA%D0%B0%D1%8F_%D0%94%D0%B0%D0%BD%D1%83%D1%82%D0%B0/%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_k-means&amp;diff=17165"/>
		<updated>2016-11-14T23:33:00Z</updated>

		<summary type="html">&lt;p&gt;DennZo1993: /* Масштабируемость реализации алгоритма */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt; {{Assignment|Zhum}}&lt;br /&gt;
&lt;br /&gt;
{{algorithm&lt;br /&gt;
| name              = Алгоритм k средних (k means)&lt;br /&gt;
| serial_complexity = &amp;lt;math&amp;gt;O(\Tau*k*d*n)&amp;lt;/math&amp;gt;&lt;br /&gt;
| input_data        = &amp;lt;math&amp;gt; d*n &amp;lt;/math&amp;gt;&lt;br /&gt;
| output_data       = &amp;lt;math&amp;gt; n &amp;lt;/math&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
Авторы страницы &amp;lt;b&amp;gt;[[Участник:Бротиковская Данута|Данута Бротиковская]]&amp;lt;/b&amp;gt; и &amp;lt;b&amp;gt;[[Участник:DennZo1993|Денис Зобнин]]&amp;lt;/b&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
Оба автора внесли одинаковый вклад в написание статьи (поиск материалов, изучение статей, заполнение контента статьи), четких разграничений по пунктам статьи сделать невозможно. &lt;br /&gt;
&lt;br /&gt;
== Свойства и структура алгоритма ==&lt;br /&gt;
&lt;br /&gt;
=== Общее описание алгоритма ===&lt;br /&gt;
Алгоритм &amp;lt;b&amp;gt;&amp;lt;i&amp;gt;k средних&amp;lt;/i&amp;gt;&amp;lt;/b&amp;gt; (&amp;lt;b&amp;gt;&amp;lt;i&amp;gt;k means&amp;lt;/i&amp;gt;&amp;lt;/b&amp;gt;) &amp;amp;ndash; неиерархический&amp;lt;ref&amp;gt;&amp;quot;https://ru.wikipedia.org/wiki/Иерархическая_кластеризация&amp;quot;&amp;lt;/ref&amp;gt;, итерационный метод кластеризации&amp;lt;ref&amp;gt;&amp;quot;https://ru.wikipedia.org/wiki/Кластерный_анализ&amp;quot;&amp;lt;/ref&amp;gt;, получивший большую популярность благодаря своей простоте, наглядности реализации и достаточно высокому качеству работы. Был изобретен в 1950-х годах математиком &amp;lt;i&amp;gt;Гуго Штейнгаузом&amp;lt;/i&amp;gt;&amp;lt;ref&amp;gt;Steinhaus, Hugo. &amp;quot;Sur la division des corp materiels en parties.&amp;quot; Bull. Acad. Polon. Sci 1.804 (1956): 801.&amp;lt;/ref&amp;gt; и почти одновременно &amp;lt;i&amp;gt;Стюартом Ллойдом&amp;lt;/i&amp;gt;&amp;lt;ref&amp;gt;Lloyd, S. P. &amp;quot;Least square quantization in PCM. Bell Telephone Laboratories Paper. Published in journal much later: Lloyd, SP: Least squares quantization in PCM.&amp;quot; IEEE Trans. Inform. Theor.(1957/1982).&amp;lt;/ref&amp;gt;. Особую популярность приобрел после публикации работы &amp;lt;i&amp;gt;МакКуина&amp;lt;/i&amp;gt;&amp;lt;ref&amp;gt;MacQueen, James. &amp;quot;Some methods for classification and analysis of multivariate observations.&amp;quot; Proceedings of the fifth Berkeley symposium on mathematical statistics and probability. Vol. 1. No. 14. 1967.&amp;lt;/ref&amp;gt; в 1967.&lt;br /&gt;
&lt;br /&gt;
Алгоритм представляет собой версию EM-алгоритма&amp;lt;ref&amp;gt;&amp;quot;https://ru.wikipedia.org/wiki/EM-алгоритм&amp;quot;&amp;lt;/ref&amp;gt;, применяемого также для разделения смеси гауссиан. Основная идея &amp;lt;i&amp;gt;k means&amp;lt;/i&amp;gt; заключается в том, что данные произвольно разбиваются на кластеры, после чего итеративно перевычисляется центр масс для каждого кластера, полученного на предыдущем шаге, затем векторы разбиваются на кластеры вновь в соответствии с тем, какой из новых центров оказался ближе по выбранной метрике.&lt;br /&gt;
&lt;br /&gt;
Цель алгоритма заключается в разделении &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; наблюдений на &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластеров таким образом, чтобы каждое наблюдение принадлежало ровно одному кластеру, расположенному на наименьшем расстоянии от наблюдения.&lt;br /&gt;
&lt;br /&gt;
=== Математическое описание алгоритма ===&lt;br /&gt;
&amp;lt;b&amp;gt;&amp;lt;u&amp;gt;Дано:&amp;lt;/u&amp;gt;&amp;lt;/b&amp;gt;&lt;br /&gt;
* набор из &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; наблюдений &amp;lt;math&amp;gt;X=\{\mathbf{x}_1, \mathbf{x}_2, ..., \mathbf{x}_n\}, \mathbf{x}_i \in \mathbb{R}^d, i=\overline{1, n}&amp;lt;/math&amp;gt;;&lt;br /&gt;
* &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; - требуемое число кластеров, &amp;lt;math&amp;gt;k \in \mathbb{N}, k \leq n&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;&amp;lt;u&amp;gt;Требуется:&amp;lt;/u&amp;gt;&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Разделить множество наблюдений &amp;lt;math&amp;gt;X&amp;lt;/math&amp;gt; на &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластеров &amp;lt;math&amp;gt;S_1, S_2, ..., S_k&amp;lt;/math&amp;gt;:&lt;br /&gt;
*   &amp;lt;math&amp;gt;S_i \cap S_j= \varnothing, \quad i \ne j&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
*   &amp;lt;math&amp;gt;\bigcup_{i=1}^{k} S_i = X&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;&amp;lt;u&amp;gt;Действие алгоритма:&amp;lt;/u&amp;gt;&amp;lt;/b&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;Алгоритм &amp;lt;i&amp;gt;k means&amp;lt;/i&amp;gt; разбивает набор &amp;lt;math&amp;gt;X&amp;lt;/math&amp;gt; на &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; наборов &amp;lt;math&amp;gt;S_1, S_2, ..., S_k,&amp;lt;/math&amp;gt; таким образом, чтобы минимизировать сумму квадратов расстояний от каждой точки кластера до его центра (центр масс кластера). Введем обозначение, &amp;lt;math&amp;gt;S=\{S_1, S_2, ..., S_k\}&amp;lt;/math&amp;gt;. Тогда действие алгоритма &amp;lt;i&amp;gt;k means&amp;lt;/i&amp;gt; равносильно поиску:&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;table style=&amp;quot;width:100%&amp;quot;&amp;gt;&lt;br /&gt;
  &amp;lt;tr&amp;gt;&lt;br /&gt;
    &amp;lt;td align=&amp;quot;center&amp;quot; width=&amp;quot;90%&amp;quot;&amp;gt;&amp;lt;math&amp;gt;\arg\min_{S} \sum\limits_{i=1}^k \sum\limits_{\mathbf{x} \in S_i} \rho(\mathbf{x}, \mathbf{\mu}_i )^2,&amp;lt;/math&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;td align=&amp;quot;right&amp;quot;&amp;gt;&amp;lt;math&amp;gt;(1)&amp;lt;/math&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;/table&amp;gt;&lt;br /&gt;
где &amp;lt;math&amp;gt;\mathbf{\mu}_i&amp;lt;/math&amp;gt; &amp;amp;ndash; центры кластеров, &amp;lt;math&amp;gt;i=\overline{1,k}, \quad \rho(\mathbf{x}, \mathbf{\mu}_i)&amp;lt;/math&amp;gt; &amp;amp;ndash; функция расстояния между &amp;lt;math&amp;gt;\mathbf{x}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\mu_i&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;&amp;lt;u&amp;gt;Шаги алгоритма: &amp;lt;/u&amp;gt;&amp;lt;/b&amp;gt;&lt;br /&gt;
&amp;lt;ol&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&lt;br /&gt;
    &amp;lt;b&amp;gt;Начальный шаг: инициализация кластеров&amp;lt;/b&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;Выбирается произвольное множество точек &amp;lt;math&amp;gt;\mu_i, i=\overline{1,k}&amp;lt;/math&amp;gt;, рассматриваемых как начальные центры кластеров: &amp;lt;math&amp;gt;\mu_i^{(0)} = \mu_i, \quad i=\overline{1, k}&amp;lt;/math&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
  &amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&lt;br /&gt;
    &amp;lt;b&amp;gt;Распределение векторов по кластерам&amp;lt;/b&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Шаг&amp;lt;/b&amp;gt; &amp;lt;math&amp;gt;t: \forall \mathbf{x}_i \in X, i=\overline{1,n}: \mathbf{x}_i \in S_j \iff  j=\arg\min_{k}\rho(\mathbf{x}_i,\mathbf{\mu}_k^{(t-1)})^2&amp;lt;/math&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
  &amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&lt;br /&gt;
    &amp;lt;b&amp;gt;Пересчет центров кластеров&amp;lt;/b&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Шаг &amp;lt;/b&amp;gt; &amp;lt;math&amp;gt;t: \forall i=\overline{1,k}:  \mu_i^{(t)} = \cfrac{1}{|S_i|}\sum_{\mathbf{x}\in S_i}\mathbf{x}&amp;lt;/math&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
  &amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&lt;br /&gt;
    &amp;lt;b&amp;gt;Проверка условия останова:&amp;lt;/b&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
    &#039;&#039;&#039;if&#039;&#039;&#039; &amp;lt;math&amp;gt;\exist i\in \overline{1,k}: \mu_i^{(t)} \ne \mu_i^{(t-1)}&amp;lt;/math&amp;gt; &#039;&#039;&#039;then&#039;&#039;&#039;&lt;br /&gt;
        t = t + 1;&lt;br /&gt;
        goto 2;&lt;br /&gt;
    &#039;&#039;&#039;else&#039;&#039;&#039;&lt;br /&gt;
        &#039;&#039;&#039;stop&#039;&#039;&#039;&lt;br /&gt;
  &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ol&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Вычислительное ядро алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Вычислительным ядром являются шаги 2 и 3 приведенного выше алгоритма: &amp;lt;b&amp;gt;&amp;lt;i&amp;gt;распределение векторов по кластерам&amp;lt;/i&amp;gt;&amp;lt;/b&amp;gt; и &amp;lt;b&amp;gt;&amp;lt;i&amp;gt;пересчет центров кластеров&amp;lt;/i&amp;gt;&amp;lt;/b&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;&amp;lt;i&amp;gt;Распределение векторов&amp;lt;/i&amp;gt;&amp;lt;/b&amp;gt; по кластерам предполагает вычисление расстояний между каждым вектором &amp;lt;math&amp;gt;\mathbf{x}_i \in X, i= \overline{1,n}&amp;lt;/math&amp;gt; и центрами кластера &amp;lt;math&amp;gt;\mathbf{\mu}_j, j= \overline{1,k}&amp;lt;/math&amp;gt;. Таким образом, данный шаг предполагает &amp;lt;math&amp;gt;k*n&amp;lt;/math&amp;gt; вычислений расстояний между d-мерными векторами. &lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;&amp;lt;i&amp;gt;Пересчет центров кластеров&amp;lt;/i&amp;gt;&amp;lt;/b&amp;gt; предполагает &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; вычислений центров масс &amp;lt;math&amp;gt;\mathbf{\mu}_i&amp;lt;/math&amp;gt; множеств &amp;lt;math&amp;gt;S_i, i=\overline{1,k}&amp;lt;/math&amp;gt; представленных выражением в шаге 3 представленного выше алгоритма.&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Макроструктура алгоритма ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Инициализация центров масс &amp;lt;math&amp;gt;\mu_1, ..., \mu_k&amp;lt;/math&amp;gt;&amp;lt;/b&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
Наиболее распространенными являются следующие стратегии:&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&lt;br /&gt;
    &amp;lt;b&amp;gt;Метод Forgy&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;В качестве начальных значений &amp;lt;math&amp;gt;\mu_1, ..., \mu_k&amp;lt;/math&amp;gt; берутся случайно выбранные векторы.&lt;br /&gt;
  &amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&lt;br /&gt;
    &amp;lt;b&amp;gt;Метод случайно разделения (Random Partitioning)&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;Для каждого вектора &amp;lt;math&amp;gt;\mathbf{x}_i \in X, i=\overline{1, n}&amp;lt;/math&amp;gt; выбирается случайным образом кластер &amp;lt;math&amp;gt;S_1, ..., S_k&amp;lt;/math&amp;gt;, после чего для каждого полученного кластера вычисляются значения &amp;lt;math&amp;gt;\mu_1, ..., \mu_k&amp;lt;/math&amp;gt;.&lt;br /&gt;
  &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Распределение векторов по кластерам&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Для этого шага алгоритма между векторами &amp;lt;math&amp;gt;\mathbf{x}_i \in X, i=\overline{1, n}&amp;lt;/math&amp;gt; и центрами кластеров &amp;lt;math&amp;gt;\mu_1, ..., \mu_k&amp;lt;/math&amp;gt; вычисляются &amp;lt;b&amp;gt;расстояния&amp;lt;/b&amp;gt; по формуле (как правило, используется Евлидово расстояние):&lt;br /&gt;
&amp;lt;table style=&amp;quot;width:100%&amp;quot;&amp;gt;&lt;br /&gt;
  &amp;lt;tr&amp;gt;&lt;br /&gt;
    &amp;lt;td align=&amp;quot;center&amp;quot; width=&amp;quot;90%&amp;quot;&amp;gt;&amp;lt;math&amp;gt; \mathbf{v}_1, \mathbf{v}_2 \in \mathbb{R}^d,  \quad \rho(\mathbf{v}_1, \mathbf{v}_2) = \lVert \mathbf{v}_1- \mathbf{v}_2 \rVert= \sqrt{\sum_{i=1}^{d}(\mathbf{v}_{1,i} - \mathbf{v}_{2,i})^2}&amp;lt;/math&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;td align=&amp;quot;right&amp;quot;&amp;gt;&amp;lt;math&amp;gt;(2)&amp;lt;/math&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;/table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Пересчет центров кластеров&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Для этого шага алгоритма производится пересчет центров кластера по &amp;lt;b&amp;gt;формуле вычисления центра масс&amp;lt;/b&amp;gt;:&lt;br /&gt;
&amp;lt;table style=&amp;quot;width:100%&amp;quot;&amp;gt;&lt;br /&gt;
  &amp;lt;tr&amp;gt;&lt;br /&gt;
    &amp;lt;td align=&amp;quot;center&amp;quot; width=&amp;quot;90%&amp;quot;&amp;gt;&amp;lt;math&amp;gt; \mu = \cfrac{1}{|S|}\sum_{\mathbf{x}\in S}\mathbf{x}&amp;lt;/math&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;td align=&amp;quot;right&amp;quot;&amp;gt;&amp;lt;math&amp;gt;(3)&amp;lt;/math&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;/table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Схема реализации последовательного алгоритма ===&lt;br /&gt;
&lt;br /&gt;
 &#039;&#039;&#039;algorithm&#039;&#039;&#039; k-means &#039;&#039;&#039;is&#039;&#039;&#039;&lt;br /&gt;
     &#039;&#039;&#039;1.&#039;&#039;&#039; Инициализировать центры кластеров &amp;lt;math&amp;gt;\mathbf{\mu}_i^{(1)}, i=\overline{1,k}&amp;lt;/math&amp;gt;&lt;br /&gt;
     &#039;&#039;&#039;2.&#039;&#039;&#039; &amp;lt;math&amp;gt;t \leftarrow 1&amp;lt;/math&amp;gt;&lt;br /&gt;
     &#039;&#039;&#039;3.&#039;&#039;&#039; &#039;&#039;&#039;Распределение по кластерам&#039;&#039;&#039;&amp;lt;br&amp;gt;&lt;br /&gt;
        &amp;lt;math&amp;gt;S_i^{(t)}=\{\mathbf{x}_p: \lVert\mathbf{x}_p-\mathbf{\mu}_i^{(t)}\rVert^2 \leq \lVert\mathbf{x}_p-\mathbf{\mu}_j^{(t)}\rVert^2 \quad \forall j=\overline{1,k}\},&amp;lt;/math&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
        где каждый вектор &amp;lt;math&amp;gt;\mathbf{x}_p&amp;lt;/math&amp;gt; соотносится единственному кластеру &amp;lt;math&amp;gt;S^{(t)}&amp;lt;/math&amp;gt;&lt;br /&gt;
     &#039;&#039;&#039;4.&#039;&#039;&#039; &#039;&#039;&#039;Обновление центров кластеров&#039;&#039;&#039;&amp;lt;br&amp;gt;&lt;br /&gt;
        &amp;lt;math&amp;gt;\mathbf{\mu}_i^{(t+1)} = \frac{1}{|S^{(t)}_i|} \sum_{\mathbf{x}_j \in S^{(t)}_i} \mathbf{x}_j &amp;lt;/math&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
     &#039;&#039;&#039;5.&#039;&#039;&#039; &#039;&#039;&#039;if&#039;&#039;&#039; &amp;lt;math&amp;gt;\exist i \in \overline{1,k}: \mathbf{\mu}_i^{(t+1)} \ne \mathbf{\mu}_i^{(t)}&amp;lt;/math&amp;gt; &#039;&#039;&#039;then&#039;&#039;&#039;&lt;br /&gt;
            t = t + 1;&lt;br /&gt;
            goto &#039;&#039;&#039;3&#039;&#039;&#039;;&lt;br /&gt;
        &#039;&#039;&#039;else&#039;&#039;&#039;&lt;br /&gt;
            &#039;&#039;&#039;stop&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
=== Последовательная сложность алгоритма===&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding-bottom: 20px&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;Обозначим &amp;lt;math&amp;gt;\Theta_{centroid}^{d, m}&amp;lt;/math&amp;gt; временную сложность вычисления центорида кластера, число элементов которого равна &amp;lt;math&amp;gt;m&amp;lt;/math&amp;gt;,  в d-мерном пространстве.&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;Аналогично  &amp;lt;math&amp;gt;\Theta_{distance}^d&amp;lt;/math&amp;gt; &amp;amp;ndash; временная сложность вычисления расстояния между двумя d-мерными векторами.&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding-bottom: 20px&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;Сложность шага инициализации &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластеров мощности &amp;lt;math&amp;gt;m&amp;lt;/math&amp;gt; в d-мерном пространстве &amp;amp;ndash; &amp;lt;math&amp;gt;\Theta_{init}^{k, d, m}&amp;lt;/math&amp;gt;&amp;lt;/b&amp;gt;&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;i&amp;gt;Стратерия Forgy&amp;lt;/i&amp;gt;: вычисления не требуются, &amp;lt;math&amp;gt;\Theta_{init}^{k, d, m} = 0&amp;lt;/math&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;i&amp;gt;Стратегия случайного разбиения&amp;lt;/i&amp;gt;: вычисление центров &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластеров,  &amp;lt;math&amp;gt;\Theta_{init}^{k, d, m} = k*\Theta_{centroid}^{d, m}, m \le n&amp;lt;/math&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding-bottom: 20px&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Cложность шага распределения d мерных векторов по &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластерам &amp;amp;ndash; &amp;lt;math&amp;gt;\Theta_{distribute}^{k, d}&amp;lt;/math&amp;gt;&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
На этом шаге для каждого вектора &amp;lt;math&amp;gt;\mathbf{x}_i \in X, i=\overline{1, n}&amp;lt;/math&amp;gt; вычисляется k расстояний до центров кластеров &amp;lt;math&amp;gt;\mathbf{\mu}_1, ...\mathbf{\mu}_k&amp;lt;/math&amp;gt;&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p align=&amp;quot;center&amp;quot;&amp;gt;&lt;br /&gt;
  &amp;lt;math&amp;gt;\Theta_{distribute}^{k, d} = n*k*\Theta_{distance}^d&amp;lt;/math&amp;gt;&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding-bottom: 20px&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;Сложность шага пересчета центров &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластеров размера &amp;lt;math&amp;gt;m&amp;lt;/math&amp;gt; в d-мерном пространстве &amp;amp;ndash; &amp;lt;math&amp;gt;\Theta_{recenter}^{k, d, m}&amp;lt;/math&amp;gt;&amp;lt;/b&amp;gt;&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;На этом шаге вычисляется &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; центров кластеров &amp;lt;math&amp;gt;\mathbf{\mu}_1, ...\mathbf{\mu}_k&amp;lt;/math&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p align=&amp;quot;center&amp;quot;&amp;gt;&amp;lt;math&amp;gt;\Theta_{recenter}^{k, d, m} = k*\Theta_{centroid}^{d, m}&amp;lt;/math&amp;gt; &amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding-bottom: 20px&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Рассчитаем &amp;lt;math&amp;gt;\Theta_{centroid}^{d, m}&amp;lt;/math&amp;gt; для кластера, число элементов которого равно &amp;lt;math&amp;gt;m&amp;lt;/math&amp;gt;&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p align=&amp;quot;center&amp;quot;&amp;gt;&amp;lt;math&amp;gt;\Theta_{centroid}^{d, m}&amp;lt;/math&amp;gt; = &amp;lt;math&amp;gt;m * d&amp;lt;/math&amp;gt; сложений + &amp;lt;math&amp;gt;d&amp;lt;/math&amp;gt; делений &amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding-bottom: 20px&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Рассчитаем &amp;lt;math&amp;gt;\Theta_{distance}^d&amp;lt;/math&amp;gt; в соответствие с формулой &amp;lt;math&amp;gt;(2)&amp;lt;/math&amp;gt;&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p align=&amp;quot;center&amp;quot;&amp;gt;&amp;lt;math&amp;gt;\Theta_{distance}^d&amp;lt;/math&amp;gt; = &amp;lt;math&amp;gt;d&amp;lt;/math&amp;gt; вычитаний + &amp;lt;math&amp;gt;d&amp;lt;/math&amp;gt; умножений + &amp;lt;math&amp;gt;(d-1)&amp;lt;/math&amp;gt; сложение&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding-bottom: 20px&amp;quot;&amp;gt;&lt;br /&gt;
  &amp;lt;p&amp;gt;Предположим, что алгоритм сошелся за &amp;lt;math&amp;gt;\Tau&amp;lt;/math&amp;gt; итераций, тогда временная сложность алгоритма &amp;lt;math&amp;gt;\Theta_{k-means}^{d, n}&amp;lt;/math&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
  &amp;lt;p align=&amp;quot;center&amp;quot;&amp;gt;&amp;lt;b&amp;gt;&amp;lt;math&amp;gt;\Theta_{k-means}^{d, n} \le \Theta_{init}^{k, d, n} + \Tau*(\Theta_{distribute}^{k, d} + \Theta_{recenter}^{k, d, n})&amp;lt;/math&amp;gt;&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding-bottom: 5px&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;Операции сложения/вычитания:&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p align=&amp;quot;center&amp;quot;&amp;gt;&amp;lt;b&amp;gt;&amp;lt;math&amp;gt;\Theta_{k-means}^{d, n} \le k*n*d+ \Tau*(k*n*(2d-1) + k*n*d) = k*n*d+ \Tau*(k*n*(3d-1)) \thicksim O(\Tau*k*d*n)&amp;lt;/math&amp;gt;&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding-bottom: 20px&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;Операции умножения/деления:&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p align=&amp;quot;center&amp;quot;&amp;gt;&amp;lt;b&amp;gt;&amp;lt;math&amp;gt;\Theta_{k-means}^{d, n} \le k*d + \Tau*(k*n*d + k*d) = k*d + \Tau * k*d*(n+1) \thicksim O(\Tau*k*d*n) &amp;lt;/math&amp;gt;&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding-bottom: 20px&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;Получаем, что &amp;lt;b&amp;gt;временная сложность&amp;lt;/b&amp;gt; алгоритма &amp;lt;b&amp;gt;k means&amp;lt;/b&amp;gt; кластеризации &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; &amp;lt;b&amp;gt;d-мерных&amp;lt;/b&amp;gt; векторов на &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластеров за &amp;lt;math&amp;gt;\Tau&amp;lt;/math&amp;gt; итераций:&amp;lt;/p&amp;gt;&lt;br /&gt;
 &amp;lt;p align=&amp;quot;center&amp;quot;&amp;gt;&amp;lt;b&amp;gt;&amp;lt;math&amp;gt; \Theta_{k-means}^{d, n} \thicksim O(\Tau*k*d*n) &amp;lt;/math&amp;gt;&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Информационный граф ===&lt;br /&gt;
&lt;br /&gt;
Рассмотрим информационный граф алгоритма. Алгоритм &amp;lt;i&amp;gt;k means&amp;lt;/i&amp;gt; начинается с этапа инициализации, после которого следуют итерации, на каждой из которых выполняется два последовательных шага (см. [[#Схема реализации последовательного алгоритма|&amp;quot;Схема реализации последовательного алгоритма&amp;quot;]]): &lt;br /&gt;
* распределение векторов по кластерам&lt;br /&gt;
* перерасчет центров кластеров&lt;br /&gt;
&lt;br /&gt;
Поскольку основная часть вычислений приходится на шаги итераций, распишем информационные графы данных шагов.&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Распределение векторов по кластерам&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
Информационный граф шага распределения векторов по кластерам представлен на &#039;&#039;рисунке 1&#039;&#039;. Исходами данного графа является исходные векторы &amp;lt;math&amp;gt;\mathbf{x}_1, ..., \mathbf{x}_n&amp;lt;/math&amp;gt;, а также центры кластеров &amp;lt;math&amp;gt;\mathbf{\mu}_1, ... \mathbf{\mu}_k&amp;lt;/math&amp;gt;, вычисленные ранее (на шаге инициализации, если рассматривается первая итерация алгоритма, или на шаге пересчета центров кластеров предыдущей итерации в противном случае). Каждая пара векторов данных &amp;lt;math&amp;gt;\mathbf{x}_i, i=\overline{1,n}&amp;lt;/math&amp;gt; и центров кластера &amp;lt;math&amp;gt;\mathbf{\mu}_j, j=\overline{1, k}&amp;lt;/math&amp;gt; : (&amp;lt;math&amp;gt;\mathbf{x}_i&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;\mathbf{\mu}_j&amp;lt;/math&amp;gt;) подаются на независимые узлы &amp;lt;i&amp;gt;&amp;quot;d&amp;quot;&amp;lt;/i&amp;gt; вычисления расстояния между векторами (более подробная схема вычисления расстояния представлена далее, &#039;&#039;рисунок 2&#039;&#039;). Далее узлы вычисления расстояния &amp;lt;i&amp;gt;&amp;quot;d&amp;quot;&amp;lt;/i&amp;gt;, соответствующие одному и тому же исходному вектору &amp;lt;math&amp;gt;\mathbf{x}_i&amp;lt;/math&amp;gt; передаются на один узел &amp;lt;i&amp;gt;&amp;quot;m&amp;quot;&amp;lt;/i&amp;gt;, где далее происходит вычисление новой метки кластера для каждого вектора &amp;lt;math&amp;gt;\mathbf{x}_i&amp;lt;/math&amp;gt; (берется кластер с минимальным результатом вычисления расстояния). На выходе графа выдаются метки кластеров , &amp;lt;math&amp;gt;L_1, ..., L_n&amp;lt;/math&amp;gt;, такие что &amp;lt;math&amp;gt;\forall \mathbf{x}_i, i=\overline{1, n}, \mathbf{x}_i \in S_j \Leftrightarrow L_i = j&amp;lt;/math&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
[[file:Clusterization.png|thumb|center|800px|Рис. 1. Схема распределения векторов по кластерам. &#039;&#039;d&#039;&#039; &amp;amp;ndash; вычисление расстояния между векторами; &#039;&#039;m&#039;&#039; &amp;amp;ndash; вычисление минимума.]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Вычисление расстояния между векторами&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
Подробная схема вычисления расстояния между векторами &amp;lt;math&amp;gt;\mathbf{x}_i, \mathbf{\mu}_j&amp;lt;/math&amp;gt; представлена на &#039;&#039;рисунке 2&#039;&#039;. Как показано на графе, узел вычисления расстояния между векторами &amp;lt;i&amp;gt;&amp;quot;d&amp;quot;&amp;lt;/i&amp;gt; состоит из шага взятия разности между векторами (узел &amp;quot;&amp;lt;math&amp;gt;-&amp;lt;/math&amp;gt;&amp;quot;) и взятия нормы получившегося вектора разности (узел &amp;quot;&amp;lt;math&amp;gt;||\cdot||^2&amp;lt;/math&amp;gt;&amp;quot;). Более подробно, вычисление расстояния между векторами &amp;lt;math&amp;gt;\mathbf{x}_i = {x_{i1,}, ...,{x_{in}}}, \mathbf{\mu}_j = {\mu_{j1}, ...,\mu_{jn}}&amp;lt;/math&amp;gt; может быть представлено как вычисление разности между каждой парой компонент &amp;lt;math&amp;gt;(x_{iz}, \mu_{jz}), z=\overline{1, d}&amp;lt;/math&amp;gt; (узел &amp;quot;&amp;lt;math&amp;gt;-&amp;lt;/math&amp;gt;&amp;quot;), далее возведение в квадрат для каждого узла &amp;quot;&amp;lt;math&amp;gt;-&amp;lt;/math&amp;gt;&amp;quot; (узел &amp;quot;&amp;lt;math&amp;gt;()^2&amp;lt;/math&amp;gt;&amp;quot;) и суммирования выходов всех узлов &amp;quot;&amp;lt;math&amp;gt;()^2&amp;lt;/math&amp;gt;&amp;quot; (узел &amp;quot;&amp;lt;math&amp;gt;+&amp;lt;/math&amp;gt;&amp;quot;).  &lt;br /&gt;
&lt;br /&gt;
[[file:dist_calc.png|thumb|center|800px|Рис. 2. Схема вычисления расстояния между вектором и центром кластера.]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Пересчет центров кластеров&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
Информационный граф шага пересчета центров кластеров представлен на &#039;&#039;рисунке 3&#039;&#039;. Исходами данного графа является исходные векторы &amp;lt;math&amp;gt;\mathbf{x}_1, ..., \mathbf{x}_n&amp;lt;/math&amp;gt;, а также им соответствующие метки кластера, &amp;lt;math&amp;gt;L_1, ..., L_n&amp;lt;/math&amp;gt;, такие что &amp;lt;math&amp;gt;\forall x_i, i=\overline{1, n}, \mathbf{x}_i \in S_j \Leftrightarrow L_i = j&amp;lt;/math&amp;gt;, вычисленные на этапе распределения векторов по кластерам. Все векторы &amp;lt;math&amp;gt;\mathbf{x}_1, ..., \mathbf{x}_n&amp;lt;/math&amp;gt; подаются в узлы &amp;lt;math&amp;gt;+_1, ...+_k&amp;lt;/math&amp;gt;, каждый узел &amp;lt;math&amp;gt;+_m, m = \overline{1,k}&amp;lt;/math&amp;gt; соответствует операции сложения векторов кластера с номером &amp;lt;math&amp;gt;m&amp;lt;/math&amp;gt;. Метки кластера &amp;lt;math&amp;gt;L_1, ..., L_n&amp;lt;/math&amp;gt; также совместно передаются на узлы &amp;lt;math&amp;gt;S_m, m = \overline{1,k}&amp;lt;/math&amp;gt;, на каждом из которых вычисляется количество векторов в соответствующем кластере (количество меток с соответствующим значением). Далее каждая пара выходов узлов &amp;lt;math&amp;gt;+_m&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;S_m&amp;lt;/math&amp;gt; подается на узел &amp;quot;&amp;lt;math&amp;gt;/&amp;lt;/math&amp;gt;&amp;quot;, где производится деление суммы векторов кластера на количество элементов в нем. Значения, вычисленные на узлах &amp;quot;&amp;lt;math&amp;gt;/&amp;lt;/math&amp;gt;&amp;quot;, присваиваются новым центрам кластеров (выходные значения графа).&lt;br /&gt;
&lt;br /&gt;
[[file:Recluster.png|thumb|center|800px|Рис. 3. Схема пересчета центров кластеров]]&lt;br /&gt;
&lt;br /&gt;
=== Ресурс параллелизма алгоритма ===&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
Работа алгоритма состоит из &amp;lt;math&amp;gt;\Tau&amp;lt;/math&amp;gt; итераций, в каждой из которых происходит &amp;lt;b&amp;gt;распределение d-мерных векторов по &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластерам&amp;lt;/b&amp;gt;, а также &amp;lt;b&amp;gt;пересчет центров кластеров в d-мерном пространстве&amp;lt;/b&amp;gt;. В шаге &amp;lt;b&amp;gt;распределения d-мерных векторов по &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластерам&amp;lt;/b&amp;gt; расстояния между вектором и центрами кластеров вычисляются независимо (отсутствуют информационные зависимости). &amp;lt;b&amp;gt;Центры масс кластеров&amp;lt;/b&amp;gt; также пересчитываются независимо друг от друга. Таким образом, имеет место [[глоссарий#Массовый параллелизм|&#039;&#039;массовый параллелизм&#039;&#039;]]. Вычислим параллельную сложность &amp;lt;math&amp;gt;\Psi_*&amp;lt;/math&amp;gt; каждого из шагов, а также параллельную сложность всего алгоритма, &amp;lt;math&amp;gt;\Psi_{k-means}&amp;lt;/math&amp;gt;. Будем исходить из предположения, что может быть использовано любое необходимое число потоков.&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Распределение d-мерных векторов по &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластерам&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;  &lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
Поскольку на данном шаге для каждой пары векторов &amp;lt;math&amp;gt;\mathbf{x}_i, i=\overline{1,n}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\mathbf{\mu}_j, j=\overline{1,k}&amp;lt;/math&amp;gt; операции вычисления расстояния не зависят друг от друга, они могут выполняться параллельно. Тогда, разделив все вычисление расстояний на &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; потоков, получим, что в каждом потоке будет выполняться только одна операция вычисления расстояния между векторами размерности d. При этом каждому вычислительному потоку передаются координаты центров всех кластеров &amp;lt;math&amp;gt;\mathbf{\mu}_1, ..., \mathbf{\mu}_k&amp;lt;/math&amp;gt;. Таким образом, параллельная сложность данного шага определяется &amp;lt;i&amp;gt; сложностью параллельной операции вычисления расстояния между d-мерными векторами&amp;lt;/i&amp;gt;, &amp;lt;math&amp;gt;\Psi_{distance}^d&amp;lt;/math&amp;gt;  и &amp;lt;i&amp;gt;сложностью определения наиболее близкого кластера&amp;lt;/i&amp;gt; (паралельное взятие минимума по расстояниям), &amp;lt;math&amp;gt;\Psi_{min}^k&amp;lt;/math&amp;gt;. Для оценки &amp;lt;math&amp;gt;\Psi_{distance}^d&amp;lt;/math&amp;gt; воспользуемся  [[Нахождение_частных_сумм_элементов_массива_сдваиванием | параллельной реализацией нахождения частичной суммы элементов массива путем сдваивания]]. Аналогично, &amp;lt;math&amp;gt;\Psi_{min}^k = log(k)&amp;lt;/math&amp;gt;. В результате, &amp;lt;math&amp;gt;\Psi_{distance}^d = O(log(d))&amp;lt;/math&amp;gt;.   Таким образом: &lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p align=&amp;quot;center&amp;quot;&amp;gt;&amp;lt;math&amp;gt;\Psi_{distribute}^{k, d}  = \Psi_{distance}^d + \Psi_{min}^k = O(log(d))+O(log(k)) = O(log(k*d))&amp;lt;/math&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Пересчет центров кластеров в d-мерном пространстве&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
Поскольку на данном шаге для каждого из &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластеров центр масс может быть вычислен независимо, данные операции могут быть выполнены в отдельных потоках. Таким образом, параллельная сложность данного шага, &amp;lt;math&amp;gt;\Psi_{recenter}^{k, d}&amp;lt;/math&amp;gt;,  будет определяться &amp;lt;i&amp;gt;параллельной сложностью вычисления одного центра масс кластера размера &amp;lt;math&amp;gt;m&amp;lt;/math&amp;gt;&amp;lt;/i&amp;gt;, &amp;lt;math&amp;gt;\Psi_{recenter}^{k, d}&amp;lt;/math&amp;gt;,  а так как &amp;lt;math&amp;gt;m \le n \Rightarrow \Psi_{recenter}^{d, m} \le \Psi_{recenter}^{d, n}&amp;lt;/math&amp;gt;. Сложность вычисления центра масс кластера d-мерных векторов размера n аналогично предыдущим вычислениям равна &amp;lt;math&amp;gt;O(log(n))&amp;lt;/math&amp;gt;. Тогда:  &lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p align=&amp;quot;center&amp;quot;&amp;gt;&amp;lt;math&amp;gt;\Psi_{recenter}^{k, d}  \le \Psi_{recenter}^{d, n} = O(log(n))&amp;lt;/math&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Общая параллельная сложность алгоритма&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
На каждой итерации необходимо обновление центров кластеров, которые будут использованы на следующей итерации. Таким образом, итерационный процесс выполняется последовательно&amp;lt;ref&amp;gt;Zhao, Weizhong, Huifang Ma, and Qing He. &amp;quot;Parallel k-means clustering based on mapreduce.&amp;quot; IEEE International Conference on Cloud Computing. Springer Berlin Heidelberg, 2009.&amp;lt;/ref&amp;gt;. Тогда, поскольку сложность каждой итерации  определяется &amp;lt;math&amp;gt;\Psi_{distribute}^{k, d}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\Psi_{recenter}&amp;lt;/math&amp;gt;, сложность всего алгоритма, &amp;lt;math&amp;gt;\Psi_{k-means}&amp;lt;/math&amp;gt; в предположении, что было сделано &amp;lt;math&amp;gt;\Tau&amp;lt;/math&amp;gt; операций определяется выражением&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p align=&amp;quot;center&amp;quot;&amp;gt;&amp;lt;math&amp;gt;\Psi_{k-means} \approx \Tau * (\Psi_{distribute}^{k, d} + \Psi_{recenter}^{k, d}) \le \Tau * O(log(k*d*n))&amp;lt;/math&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Входные и выходные данные алгоритма ===&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;Входные данные&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;Матрица из &amp;lt;math&amp;gt;n*d&amp;lt;/math&amp;gt; элементов &amp;lt;math&amp;gt;x_{i, j} \in \mathbb{R}, i=\overline{1, n}, j=\overline{1, d}&amp;lt;/math&amp;gt;&amp;amp;ndash; координат векторов (наблюдений).&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;Целое положительное число &amp;lt;math&amp;gt;k, k \le n&amp;lt;/math&amp;gt; &amp;amp;ndash; количество кластеров.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;Объем входных данных&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;math&amp;gt;1&amp;lt;/math&amp;gt; целое число + &amp;lt;math&amp;gt;n*d&amp;lt;/math&amp;gt; вещественных чисел (при условии, что координаты &amp;amp;ndash; вещественные числа).&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;Выходные данные&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; целых положительных чисел &amp;lt;math&amp;gt;L_1, ..., L_n&amp;lt;/math&amp;gt;&amp;amp;ndash; номера кластеров, соотвествующие каждому вектору (при условии, что нумерация кластеров начинается с &amp;lt;math&amp;gt;1&amp;lt;/math&amp;gt;).&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;Объем выходных данных&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; целых положительных чисел.&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Свойства алгоритма ===&lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;[[глоссарий#Вычислительная мощность|&#039;&#039;Вычислительная мощность&#039;&#039;]]&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
Вычислительная мощность алгоритма &amp;lt;i&amp;gt;k means&amp;lt;/i&amp;gt; равна &amp;lt;math&amp;gt;\frac{k*d*n*\Tau}{n*d} = k*\Tau &amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; &amp;amp;ndash; число кластеров, &amp;lt;math&amp;gt;\Tau&amp;lt;/math&amp;gt; &amp;amp;ndash; число итераций алгоритма.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;[[глоссарий#Детерминированность |&#039;&#039;Детерминированность&#039;&#039;]] и [[глоссарий#Устойчивость |&#039;&#039;Устойчивость&#039;&#039;]] &amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
Алгоритм &amp;lt;i&amp;gt;k means&amp;lt;/i&amp;gt; является итерационным. Количество итераций алгоритма в общем случае не фиксируется и зависит от начального расположения объектов в пространстве, параметра &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt;, а также от начального приближения центров кластеров, &amp;lt;math&amp;gt;\mu_1, ..., \mu_k&amp;lt;/math&amp;gt;. В результате этого может варьироваться результат работы алгоритма. При неудачном выборе начальных параметров итерационный процесс может сойтись к локальному оптимуму&amp;lt;ref&amp;gt;Von Luxburg, Ulrike. Clustering Stability. Now Publishers Inc, 2010.&amp;lt;/ref&amp;gt;. По этим причинам алгоритм не является ни &amp;lt;b&amp;gt;детермирированным&amp;lt;/b&amp;gt;, ни &amp;lt;b&amp;gt;устойчивым&amp;lt;/b&amp;gt;.&lt;br /&gt;
 &lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Соотношение последовательной и параллельной сложности алгоритма&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\frac{\Theta_{k-means}}{\Psi_{k-means}} = \frac{O(\Tau*k*d*n)}{O(\Tau*log(k*d*n))}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Сильные стороны алгоритма&amp;lt;/b&amp;gt;:&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;i&amp;gt;Сравнительно высокая эффективность при простоте реализации&amp;lt;/i&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;i&amp;gt;Высокое качество кластеризации&amp;lt;/i&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;i&amp;gt;Возможность распараллеливания&amp;lt;/i&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;i&amp;gt;Существование множества модификаций&amp;lt;/i&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;Недостатки алгоритма&amp;lt;/b&amp;gt;&amp;lt;ref&amp;gt;Ortega, Joaquín Pérez, Ma Del Rocío Boone Rojas, and María J. Somodevilla. &amp;quot;Research issues on K-means Algorithm: An Experimental Trial Using Matlab.&amp;quot;&amp;lt;/ref&amp;gt;:&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;i&amp;gt;Количество кластеров является параметром алгоритма&amp;lt;/i&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;&amp;lt;i&amp;gt;Чувствительность к начальным условиям&amp;lt;/i&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;Инициализация центров кластеров в значительной степени влияет на результат кластеризации.&amp;lt;/p&amp;gt;&lt;br /&gt;
  &amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;&amp;lt;i&amp;gt;Чувствительность к выбросам и шумам&amp;lt;/i&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;Выбросы, далекие от центров настоящих кластеров, все равно учитываются при вычислении их центров.&amp;lt;/p&amp;gt;&lt;br /&gt;
  &amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;&amp;lt;i&amp;gt;Возможность сходимости к локальному оптимуму&amp;lt;/i&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;Итеративный подход не дает гарантии сходимости к оптимальному решению.&amp;lt;/p&amp;gt;&lt;br /&gt;
  &amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;&amp;lt;i&amp;gt;Использование понятия &amp;quot;среднего&amp;quot;&amp;lt;/i&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;Алгоритм неприменим к данным, для которых не определено понятие &amp;quot;среднего&amp;quot;, например, категориальным данным.&amp;lt;/p&amp;gt;&lt;br /&gt;
  &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&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;
Исследование масштабируемости параллельной реализации алгоритма k means проводилось на суперкомпьютере &amp;quot;Ломоносов&amp;quot;. Алгоритм реализован на языке C с использованием средств MPI.&lt;br /&gt;
Для исследования масштабируемости проводилось множество запусков программы с разным значением параметра (количество векторов для кластеризации), а также с различным числом процессоров. Фиксировались результаты запусков &amp;amp;ndash; время работы &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt; и количество произведенных итераций алгоритма &amp;lt;math&amp;gt;\Tau&amp;lt;/math&amp;gt;.&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;Значения &amp;lt;b&amp;gt;количества векторов&amp;lt;/b&amp;gt; &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;: 20&#039;000, 30&#039;000, 50&#039;000, 100&#039;000, 200&#039;000, 300&#039;000, 500&#039;000, 700&#039;000, 1&#039;000&#039;000, 1&#039;500&#039;000, 2&#039;000&#039;000.&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;Значения &amp;lt;b&amp;gt;количества процессоров&amp;lt;/b&amp;gt; &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt;: 1, 8, 16, 32, 64, 128, 160, 192, 224, 256, 288, 320, 352, 384, 416, 448, 480, 512.&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;Значение &amp;lt;b&amp;gt;количества кластеров&amp;lt;/b&amp;gt; &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt;: 100.&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;Значение &amp;lt;b&amp;gt;размерности векторов&amp;lt;/b&amp;gt; &amp;lt;math&amp;gt;d&amp;lt;/math&amp;gt;: 10.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Графики производительности и эффективности реализации представлены на рисунках 4 и 5 соответственно.&lt;br /&gt;
&lt;br /&gt;
[[file:Flops.png|thumb|center|800px|Рис. 4. График производительности реализации алгоритма.]]&lt;br /&gt;
&lt;br /&gt;
[[file:Efficiency.png|thumb|center|800px|Рис. 5. График эффективности реализации алгоритма.]]&lt;br /&gt;
&lt;br /&gt;
Для заданной конфигурации эксперимента (&amp;lt;math&amp;gt;n, p, k&amp;lt;/math&amp;gt;) и полученных результатах (&amp;lt;math&amp;gt;t, \Tau&amp;lt;/math&amp;gt;) производительность и эффективность реализации расчитывались по формулам (см. [[#Последовательная сложность алгоритма| последовательная сложность алгоритма]]):&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;math&amp;gt;Performance = \frac{\Theta_{k-means}^{d, n}}{t}&amp;lt;/math&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
В результате экспериментальной оценки были получены следующие оценки эффективности реализации:&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;b&amp;gt;Минимальное&amp;lt;/b&amp;gt; значение: 0.000409 %&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;b&amp;gt;Максимальное&amp;lt;/b&amp;gt; значение: 0.741119 %&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Динамические характеристики и эффективность реализации алгоритма ===&lt;br /&gt;
=== Выводы для классов архитектур ===&lt;br /&gt;
=== Существующие реализации алгоритма ===&lt;br /&gt;
==== Открытое программное обеспечение ====&lt;br /&gt;
&amp;lt;ol&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;[https://www.icpsr.umich.edu/CrimeStat/ CrimeStat]&amp;lt;/li&amp;gt; Программное обеспечение, созданное для операционных систем Windows, предоставляющее инструменты статистического  и пространственного анализа для решения задачи картирования преступности.&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://juliastats.github.io Julia]&amp;lt;/li&amp;gt; Высокоуровневый высокопроизводительный свободный язык программирования с динамической типизацией, созданный для математических вычислений, содержит реализацию k-means.&lt;br /&gt;
  &amp;lt;li&amp;gt;[https://mahout.apache.org Mahout]&amp;lt;/li&amp;gt; Apache Mahout - Java библиотека для работы с алгоритмами машинного обучения с использованием MapReduce. Содержит реализацию k-means.&lt;br /&gt;
  &amp;lt;li&amp;gt;[https://www.gnu.org/software/octave/ Octave]&amp;lt;/li&amp;gt; Написанная на C++  свободная система для математических вычислений, использующая совместимый с MATLAB язык высокого уровня, содержит реализацию k-means.&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://spark.apache.org/docs/latest/mllib-clustering.html Spark]&amp;lt;/li&amp;gt; Распределенная реализация k-means содержится в библиотеке Mlib для работы с алгоритмами машинного обучения, взаимодействующая с Python библиотекой NumPy и библиотека R.&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://torch.ch Torch]&amp;lt;/li&amp;gt;  MATLAB-подобная библиотека для языка программирования Lua с открытым исходным кодом, предоставляет большое количество алгоритмов для глубинного обучения и научных расчётов. Ядро написано на Си, прикладная часть выполняется на LuaJIT, поддерживается распараллеливание вычислений средствами CUDA и OpenMP. Существуют реализации k-means.&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://www.cs.waikato.ac.nz/ml/weka/ Weka]&amp;lt;/li&amp;gt;  Cвободное программное обеспечение для анализа данных, написанное на Java. Содержит k-means и x-means.&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://accord-framework.net/docs/html/T_Accord_MachineLearning_KMeans.htm Accord.NET]&amp;lt;/li&amp;gt; C# реализация алгоритмов k-means, k-means++, k-modes.&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://docs.opencv.org/3.0-beta/doc/py_tutorials/py_ml/py_kmeans/py_kmeans_opencv/py_kmeans_opencv.html OpenCV]&amp;lt;/li&amp;gt; Написанная на С++ библиотека, направленная в основном на решение задач компьютерного зрения. Содержит реализацию k-means.&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://mlpack.org/ MLPACK]&amp;lt;/li&amp;gt; Масштабируемая С++ библиотека для работы с алгоритмами машинного обучения, содержит реализацию k-means.&lt;br /&gt;
  &amp;lt;li&amp;gt;[https://www.scipy.org/ SciPy]&amp;lt;/li&amp;gt; Библиотека Python, содержит множество реализаций k-means.&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://scikit-learn.org/ scikit-learn]&amp;lt;/li&amp;gt; Библиотека Python, содержит множество реализаций k-means.&lt;br /&gt;
  &amp;lt;li&amp;gt;[https://www.r-bloggers.com/k-means-clustering-in-r/ R]&amp;lt;/li&amp;gt; Язык программирования для статистической обработки данных и работы с графикой, а также свободная программная среда вычислений с открытым исходным кодом в рамках проекта GNU, содержит три реализации k-means.&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://elki.dbs.ifi.lmu.de ELKI]&amp;lt;/li&amp;gt; Java фреймворк, содержащий реализацию k-means, а также множество других алгоритмов кластеризации.&lt;br /&gt;
&amp;lt;/ol&amp;gt;&lt;br /&gt;
==== Проприетарное программное обеспечение  ====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ol&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;[https://www.ayasdi.com/blog/bigdata/topological-data-analysis-of-oil-and-gas-petrophysical-data/ Ayasdi]&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://www.stata.com/features/cluster-analysis/ Stata]&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://mathworld.wolfram.com/K-MeansClusteringAlgorithm.html Mathematica]&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://www.mathworks.com/help/stats/kmeans.html?requestedDomain=www.mathworks.com MATLAB]&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;[https://support.sas.com/rnd/app/stat/procedures/fastclus.html SAS]&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://docs.rapidminer.com/studio/operators/modeling/segmentation/k_means.html RapidMiner]&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;[https://blogs.sap.com/2013/03/28/sap-hana-pal-k-means-algorithm-or-how-to-do-customer-segmentation-for-the-telecommunications-industry/ SAP HANA]&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ol&amp;gt;&lt;br /&gt;
== Литература ==&lt;br /&gt;
&amp;lt;references /&amp;gt;&lt;/div&gt;</summary>
		<author><name>DennZo1993</name></author>
	</entry>
	<entry>
		<id>https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:%D0%91%D1%80%D0%BE%D1%82%D0%B8%D0%BA%D0%BE%D0%B2%D1%81%D0%BA%D0%B0%D1%8F_%D0%94%D0%B0%D0%BD%D1%83%D1%82%D0%B0/%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_k-means&amp;diff=17164</id>
		<title>Участник:Бротиковская Данута/Алгоритм k-means</title>
		<link rel="alternate" type="text/html" href="https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:%D0%91%D1%80%D0%BE%D1%82%D0%B8%D0%BA%D0%BE%D0%B2%D1%81%D0%BA%D0%B0%D1%8F_%D0%94%D0%B0%D0%BD%D1%83%D1%82%D0%B0/%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_k-means&amp;diff=17164"/>
		<updated>2016-11-14T23:31:53Z</updated>

		<summary type="html">&lt;p&gt;DennZo1993: /* Масштабируемость реализации алгоритма */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt; {{Assignment|Zhum}}&lt;br /&gt;
&lt;br /&gt;
{{algorithm&lt;br /&gt;
| name              = Алгоритм k средних (k means)&lt;br /&gt;
| serial_complexity = &amp;lt;math&amp;gt;O(\Tau*k*d*n)&amp;lt;/math&amp;gt;&lt;br /&gt;
| input_data        = &amp;lt;math&amp;gt; d*n &amp;lt;/math&amp;gt;&lt;br /&gt;
| output_data       = &amp;lt;math&amp;gt; n &amp;lt;/math&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
Авторы страницы &amp;lt;b&amp;gt;[[Участник:Бротиковская Данута|Данута Бротиковская]]&amp;lt;/b&amp;gt; и &amp;lt;b&amp;gt;[[Участник:DennZo1993|Денис Зобнин]]&amp;lt;/b&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
Оба автора внесли одинаковый вклад в написание статьи (поиск материалов, изучение статей, заполнение контента статьи), четких разграничений по пунктам статьи сделать невозможно. &lt;br /&gt;
&lt;br /&gt;
== Свойства и структура алгоритма ==&lt;br /&gt;
&lt;br /&gt;
=== Общее описание алгоритма ===&lt;br /&gt;
Алгоритм &amp;lt;b&amp;gt;&amp;lt;i&amp;gt;k средних&amp;lt;/i&amp;gt;&amp;lt;/b&amp;gt; (&amp;lt;b&amp;gt;&amp;lt;i&amp;gt;k means&amp;lt;/i&amp;gt;&amp;lt;/b&amp;gt;) &amp;amp;ndash; неиерархический&amp;lt;ref&amp;gt;&amp;quot;https://ru.wikipedia.org/wiki/Иерархическая_кластеризация&amp;quot;&amp;lt;/ref&amp;gt;, итерационный метод кластеризации&amp;lt;ref&amp;gt;&amp;quot;https://ru.wikipedia.org/wiki/Кластерный_анализ&amp;quot;&amp;lt;/ref&amp;gt;, получивший большую популярность благодаря своей простоте, наглядности реализации и достаточно высокому качеству работы. Был изобретен в 1950-х годах математиком &amp;lt;i&amp;gt;Гуго Штейнгаузом&amp;lt;/i&amp;gt;&amp;lt;ref&amp;gt;Steinhaus, Hugo. &amp;quot;Sur la division des corp materiels en parties.&amp;quot; Bull. Acad. Polon. Sci 1.804 (1956): 801.&amp;lt;/ref&amp;gt; и почти одновременно &amp;lt;i&amp;gt;Стюартом Ллойдом&amp;lt;/i&amp;gt;&amp;lt;ref&amp;gt;Lloyd, S. P. &amp;quot;Least square quantization in PCM. Bell Telephone Laboratories Paper. Published in journal much later: Lloyd, SP: Least squares quantization in PCM.&amp;quot; IEEE Trans. Inform. Theor.(1957/1982).&amp;lt;/ref&amp;gt;. Особую популярность приобрел после публикации работы &amp;lt;i&amp;gt;МакКуина&amp;lt;/i&amp;gt;&amp;lt;ref&amp;gt;MacQueen, James. &amp;quot;Some methods for classification and analysis of multivariate observations.&amp;quot; Proceedings of the fifth Berkeley symposium on mathematical statistics and probability. Vol. 1. No. 14. 1967.&amp;lt;/ref&amp;gt; в 1967.&lt;br /&gt;
&lt;br /&gt;
Алгоритм представляет собой версию EM-алгоритма&amp;lt;ref&amp;gt;&amp;quot;https://ru.wikipedia.org/wiki/EM-алгоритм&amp;quot;&amp;lt;/ref&amp;gt;, применяемого также для разделения смеси гауссиан. Основная идея &amp;lt;i&amp;gt;k means&amp;lt;/i&amp;gt; заключается в том, что данные произвольно разбиваются на кластеры, после чего итеративно перевычисляется центр масс для каждого кластера, полученного на предыдущем шаге, затем векторы разбиваются на кластеры вновь в соответствии с тем, какой из новых центров оказался ближе по выбранной метрике.&lt;br /&gt;
&lt;br /&gt;
Цель алгоритма заключается в разделении &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; наблюдений на &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластеров таким образом, чтобы каждое наблюдение принадлежало ровно одному кластеру, расположенному на наименьшем расстоянии от наблюдения.&lt;br /&gt;
&lt;br /&gt;
=== Математическое описание алгоритма ===&lt;br /&gt;
&amp;lt;b&amp;gt;&amp;lt;u&amp;gt;Дано:&amp;lt;/u&amp;gt;&amp;lt;/b&amp;gt;&lt;br /&gt;
* набор из &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; наблюдений &amp;lt;math&amp;gt;X=\{\mathbf{x}_1, \mathbf{x}_2, ..., \mathbf{x}_n\}, \mathbf{x}_i \in \mathbb{R}^d, i=\overline{1, n}&amp;lt;/math&amp;gt;;&lt;br /&gt;
* &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; - требуемое число кластеров, &amp;lt;math&amp;gt;k \in \mathbb{N}, k \leq n&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;&amp;lt;u&amp;gt;Требуется:&amp;lt;/u&amp;gt;&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Разделить множество наблюдений &amp;lt;math&amp;gt;X&amp;lt;/math&amp;gt; на &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластеров &amp;lt;math&amp;gt;S_1, S_2, ..., S_k&amp;lt;/math&amp;gt;:&lt;br /&gt;
*   &amp;lt;math&amp;gt;S_i \cap S_j= \varnothing, \quad i \ne j&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
*   &amp;lt;math&amp;gt;\bigcup_{i=1}^{k} S_i = X&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;&amp;lt;u&amp;gt;Действие алгоритма:&amp;lt;/u&amp;gt;&amp;lt;/b&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;Алгоритм &amp;lt;i&amp;gt;k means&amp;lt;/i&amp;gt; разбивает набор &amp;lt;math&amp;gt;X&amp;lt;/math&amp;gt; на &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; наборов &amp;lt;math&amp;gt;S_1, S_2, ..., S_k,&amp;lt;/math&amp;gt; таким образом, чтобы минимизировать сумму квадратов расстояний от каждой точки кластера до его центра (центр масс кластера). Введем обозначение, &amp;lt;math&amp;gt;S=\{S_1, S_2, ..., S_k\}&amp;lt;/math&amp;gt;. Тогда действие алгоритма &amp;lt;i&amp;gt;k means&amp;lt;/i&amp;gt; равносильно поиску:&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;table style=&amp;quot;width:100%&amp;quot;&amp;gt;&lt;br /&gt;
  &amp;lt;tr&amp;gt;&lt;br /&gt;
    &amp;lt;td align=&amp;quot;center&amp;quot; width=&amp;quot;90%&amp;quot;&amp;gt;&amp;lt;math&amp;gt;\arg\min_{S} \sum\limits_{i=1}^k \sum\limits_{\mathbf{x} \in S_i} \rho(\mathbf{x}, \mathbf{\mu}_i )^2,&amp;lt;/math&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;td align=&amp;quot;right&amp;quot;&amp;gt;&amp;lt;math&amp;gt;(1)&amp;lt;/math&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;/table&amp;gt;&lt;br /&gt;
где &amp;lt;math&amp;gt;\mathbf{\mu}_i&amp;lt;/math&amp;gt; &amp;amp;ndash; центры кластеров, &amp;lt;math&amp;gt;i=\overline{1,k}, \quad \rho(\mathbf{x}, \mathbf{\mu}_i)&amp;lt;/math&amp;gt; &amp;amp;ndash; функция расстояния между &amp;lt;math&amp;gt;\mathbf{x}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\mu_i&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;&amp;lt;u&amp;gt;Шаги алгоритма: &amp;lt;/u&amp;gt;&amp;lt;/b&amp;gt;&lt;br /&gt;
&amp;lt;ol&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&lt;br /&gt;
    &amp;lt;b&amp;gt;Начальный шаг: инициализация кластеров&amp;lt;/b&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;Выбирается произвольное множество точек &amp;lt;math&amp;gt;\mu_i, i=\overline{1,k}&amp;lt;/math&amp;gt;, рассматриваемых как начальные центры кластеров: &amp;lt;math&amp;gt;\mu_i^{(0)} = \mu_i, \quad i=\overline{1, k}&amp;lt;/math&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
  &amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&lt;br /&gt;
    &amp;lt;b&amp;gt;Распределение векторов по кластерам&amp;lt;/b&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Шаг&amp;lt;/b&amp;gt; &amp;lt;math&amp;gt;t: \forall \mathbf{x}_i \in X, i=\overline{1,n}: \mathbf{x}_i \in S_j \iff  j=\arg\min_{k}\rho(\mathbf{x}_i,\mathbf{\mu}_k^{(t-1)})^2&amp;lt;/math&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
  &amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&lt;br /&gt;
    &amp;lt;b&amp;gt;Пересчет центров кластеров&amp;lt;/b&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Шаг &amp;lt;/b&amp;gt; &amp;lt;math&amp;gt;t: \forall i=\overline{1,k}:  \mu_i^{(t)} = \cfrac{1}{|S_i|}\sum_{\mathbf{x}\in S_i}\mathbf{x}&amp;lt;/math&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
  &amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&lt;br /&gt;
    &amp;lt;b&amp;gt;Проверка условия останова:&amp;lt;/b&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
    &#039;&#039;&#039;if&#039;&#039;&#039; &amp;lt;math&amp;gt;\exist i\in \overline{1,k}: \mu_i^{(t)} \ne \mu_i^{(t-1)}&amp;lt;/math&amp;gt; &#039;&#039;&#039;then&#039;&#039;&#039;&lt;br /&gt;
        t = t + 1;&lt;br /&gt;
        goto 2;&lt;br /&gt;
    &#039;&#039;&#039;else&#039;&#039;&#039;&lt;br /&gt;
        &#039;&#039;&#039;stop&#039;&#039;&#039;&lt;br /&gt;
  &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ol&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Вычислительное ядро алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Вычислительным ядром являются шаги 2 и 3 приведенного выше алгоритма: &amp;lt;b&amp;gt;&amp;lt;i&amp;gt;распределение векторов по кластерам&amp;lt;/i&amp;gt;&amp;lt;/b&amp;gt; и &amp;lt;b&amp;gt;&amp;lt;i&amp;gt;пересчет центров кластеров&amp;lt;/i&amp;gt;&amp;lt;/b&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;&amp;lt;i&amp;gt;Распределение векторов&amp;lt;/i&amp;gt;&amp;lt;/b&amp;gt; по кластерам предполагает вычисление расстояний между каждым вектором &amp;lt;math&amp;gt;\mathbf{x}_i \in X, i= \overline{1,n}&amp;lt;/math&amp;gt; и центрами кластера &amp;lt;math&amp;gt;\mathbf{\mu}_j, j= \overline{1,k}&amp;lt;/math&amp;gt;. Таким образом, данный шаг предполагает &amp;lt;math&amp;gt;k*n&amp;lt;/math&amp;gt; вычислений расстояний между d-мерными векторами. &lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;&amp;lt;i&amp;gt;Пересчет центров кластеров&amp;lt;/i&amp;gt;&amp;lt;/b&amp;gt; предполагает &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; вычислений центров масс &amp;lt;math&amp;gt;\mathbf{\mu}_i&amp;lt;/math&amp;gt; множеств &amp;lt;math&amp;gt;S_i, i=\overline{1,k}&amp;lt;/math&amp;gt; представленных выражением в шаге 3 представленного выше алгоритма.&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Макроструктура алгоритма ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Инициализация центров масс &amp;lt;math&amp;gt;\mu_1, ..., \mu_k&amp;lt;/math&amp;gt;&amp;lt;/b&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
Наиболее распространенными являются следующие стратегии:&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&lt;br /&gt;
    &amp;lt;b&amp;gt;Метод Forgy&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;В качестве начальных значений &amp;lt;math&amp;gt;\mu_1, ..., \mu_k&amp;lt;/math&amp;gt; берутся случайно выбранные векторы.&lt;br /&gt;
  &amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&lt;br /&gt;
    &amp;lt;b&amp;gt;Метод случайно разделения (Random Partitioning)&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;Для каждого вектора &amp;lt;math&amp;gt;\mathbf{x}_i \in X, i=\overline{1, n}&amp;lt;/math&amp;gt; выбирается случайным образом кластер &amp;lt;math&amp;gt;S_1, ..., S_k&amp;lt;/math&amp;gt;, после чего для каждого полученного кластера вычисляются значения &amp;lt;math&amp;gt;\mu_1, ..., \mu_k&amp;lt;/math&amp;gt;.&lt;br /&gt;
  &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Распределение векторов по кластерам&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Для этого шага алгоритма между векторами &amp;lt;math&amp;gt;\mathbf{x}_i \in X, i=\overline{1, n}&amp;lt;/math&amp;gt; и центрами кластеров &amp;lt;math&amp;gt;\mu_1, ..., \mu_k&amp;lt;/math&amp;gt; вычисляются &amp;lt;b&amp;gt;расстояния&amp;lt;/b&amp;gt; по формуле (как правило, используется Евлидово расстояние):&lt;br /&gt;
&amp;lt;table style=&amp;quot;width:100%&amp;quot;&amp;gt;&lt;br /&gt;
  &amp;lt;tr&amp;gt;&lt;br /&gt;
    &amp;lt;td align=&amp;quot;center&amp;quot; width=&amp;quot;90%&amp;quot;&amp;gt;&amp;lt;math&amp;gt; \mathbf{v}_1, \mathbf{v}_2 \in \mathbb{R}^d,  \quad \rho(\mathbf{v}_1, \mathbf{v}_2) = \lVert \mathbf{v}_1- \mathbf{v}_2 \rVert= \sqrt{\sum_{i=1}^{d}(\mathbf{v}_{1,i} - \mathbf{v}_{2,i})^2}&amp;lt;/math&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;td align=&amp;quot;right&amp;quot;&amp;gt;&amp;lt;math&amp;gt;(2)&amp;lt;/math&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;/table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Пересчет центров кластеров&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Для этого шага алгоритма производится пересчет центров кластера по &amp;lt;b&amp;gt;формуле вычисления центра масс&amp;lt;/b&amp;gt;:&lt;br /&gt;
&amp;lt;table style=&amp;quot;width:100%&amp;quot;&amp;gt;&lt;br /&gt;
  &amp;lt;tr&amp;gt;&lt;br /&gt;
    &amp;lt;td align=&amp;quot;center&amp;quot; width=&amp;quot;90%&amp;quot;&amp;gt;&amp;lt;math&amp;gt; \mu = \cfrac{1}{|S|}\sum_{\mathbf{x}\in S}\mathbf{x}&amp;lt;/math&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;td align=&amp;quot;right&amp;quot;&amp;gt;&amp;lt;math&amp;gt;(3)&amp;lt;/math&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;/table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Схема реализации последовательного алгоритма ===&lt;br /&gt;
&lt;br /&gt;
 &#039;&#039;&#039;algorithm&#039;&#039;&#039; k-means &#039;&#039;&#039;is&#039;&#039;&#039;&lt;br /&gt;
     &#039;&#039;&#039;1.&#039;&#039;&#039; Инициализировать центры кластеров &amp;lt;math&amp;gt;\mathbf{\mu}_i^{(1)}, i=\overline{1,k}&amp;lt;/math&amp;gt;&lt;br /&gt;
     &#039;&#039;&#039;2.&#039;&#039;&#039; &amp;lt;math&amp;gt;t \leftarrow 1&amp;lt;/math&amp;gt;&lt;br /&gt;
     &#039;&#039;&#039;3.&#039;&#039;&#039; &#039;&#039;&#039;Распределение по кластерам&#039;&#039;&#039;&amp;lt;br&amp;gt;&lt;br /&gt;
        &amp;lt;math&amp;gt;S_i^{(t)}=\{\mathbf{x}_p: \lVert\mathbf{x}_p-\mathbf{\mu}_i^{(t)}\rVert^2 \leq \lVert\mathbf{x}_p-\mathbf{\mu}_j^{(t)}\rVert^2 \quad \forall j=\overline{1,k}\},&amp;lt;/math&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
        где каждый вектор &amp;lt;math&amp;gt;\mathbf{x}_p&amp;lt;/math&amp;gt; соотносится единственному кластеру &amp;lt;math&amp;gt;S^{(t)}&amp;lt;/math&amp;gt;&lt;br /&gt;
     &#039;&#039;&#039;4.&#039;&#039;&#039; &#039;&#039;&#039;Обновление центров кластеров&#039;&#039;&#039;&amp;lt;br&amp;gt;&lt;br /&gt;
        &amp;lt;math&amp;gt;\mathbf{\mu}_i^{(t+1)} = \frac{1}{|S^{(t)}_i|} \sum_{\mathbf{x}_j \in S^{(t)}_i} \mathbf{x}_j &amp;lt;/math&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
     &#039;&#039;&#039;5.&#039;&#039;&#039; &#039;&#039;&#039;if&#039;&#039;&#039; &amp;lt;math&amp;gt;\exist i \in \overline{1,k}: \mathbf{\mu}_i^{(t+1)} \ne \mathbf{\mu}_i^{(t)}&amp;lt;/math&amp;gt; &#039;&#039;&#039;then&#039;&#039;&#039;&lt;br /&gt;
            t = t + 1;&lt;br /&gt;
            goto &#039;&#039;&#039;3&#039;&#039;&#039;;&lt;br /&gt;
        &#039;&#039;&#039;else&#039;&#039;&#039;&lt;br /&gt;
            &#039;&#039;&#039;stop&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
=== Последовательная сложность алгоритма===&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding-bottom: 20px&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;Обозначим &amp;lt;math&amp;gt;\Theta_{centroid}^{d, m}&amp;lt;/math&amp;gt; временную сложность вычисления центорида кластера, число элементов которого равна &amp;lt;math&amp;gt;m&amp;lt;/math&amp;gt;,  в d-мерном пространстве.&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;Аналогично  &amp;lt;math&amp;gt;\Theta_{distance}^d&amp;lt;/math&amp;gt; &amp;amp;ndash; временная сложность вычисления расстояния между двумя d-мерными векторами.&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding-bottom: 20px&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;Сложность шага инициализации &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластеров мощности &amp;lt;math&amp;gt;m&amp;lt;/math&amp;gt; в d-мерном пространстве &amp;amp;ndash; &amp;lt;math&amp;gt;\Theta_{init}^{k, d, m}&amp;lt;/math&amp;gt;&amp;lt;/b&amp;gt;&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;i&amp;gt;Стратерия Forgy&amp;lt;/i&amp;gt;: вычисления не требуются, &amp;lt;math&amp;gt;\Theta_{init}^{k, d, m} = 0&amp;lt;/math&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;i&amp;gt;Стратегия случайного разбиения&amp;lt;/i&amp;gt;: вычисление центров &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластеров,  &amp;lt;math&amp;gt;\Theta_{init}^{k, d, m} = k*\Theta_{centroid}^{d, m}, m \le n&amp;lt;/math&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding-bottom: 20px&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Cложность шага распределения d мерных векторов по &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластерам &amp;amp;ndash; &amp;lt;math&amp;gt;\Theta_{distribute}^{k, d}&amp;lt;/math&amp;gt;&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
На этом шаге для каждого вектора &amp;lt;math&amp;gt;\mathbf{x}_i \in X, i=\overline{1, n}&amp;lt;/math&amp;gt; вычисляется k расстояний до центров кластеров &amp;lt;math&amp;gt;\mathbf{\mu}_1, ...\mathbf{\mu}_k&amp;lt;/math&amp;gt;&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p align=&amp;quot;center&amp;quot;&amp;gt;&lt;br /&gt;
  &amp;lt;math&amp;gt;\Theta_{distribute}^{k, d} = n*k*\Theta_{distance}^d&amp;lt;/math&amp;gt;&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding-bottom: 20px&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;Сложность шага пересчета центров &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластеров размера &amp;lt;math&amp;gt;m&amp;lt;/math&amp;gt; в d-мерном пространстве &amp;amp;ndash; &amp;lt;math&amp;gt;\Theta_{recenter}^{k, d, m}&amp;lt;/math&amp;gt;&amp;lt;/b&amp;gt;&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;На этом шаге вычисляется &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; центров кластеров &amp;lt;math&amp;gt;\mathbf{\mu}_1, ...\mathbf{\mu}_k&amp;lt;/math&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p align=&amp;quot;center&amp;quot;&amp;gt;&amp;lt;math&amp;gt;\Theta_{recenter}^{k, d, m} = k*\Theta_{centroid}^{d, m}&amp;lt;/math&amp;gt; &amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding-bottom: 20px&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Рассчитаем &amp;lt;math&amp;gt;\Theta_{centroid}^{d, m}&amp;lt;/math&amp;gt; для кластера, число элементов которого равно &amp;lt;math&amp;gt;m&amp;lt;/math&amp;gt;&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p align=&amp;quot;center&amp;quot;&amp;gt;&amp;lt;math&amp;gt;\Theta_{centroid}^{d, m}&amp;lt;/math&amp;gt; = &amp;lt;math&amp;gt;m * d&amp;lt;/math&amp;gt; сложений + &amp;lt;math&amp;gt;d&amp;lt;/math&amp;gt; делений &amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding-bottom: 20px&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Рассчитаем &amp;lt;math&amp;gt;\Theta_{distance}^d&amp;lt;/math&amp;gt; в соответствие с формулой &amp;lt;math&amp;gt;(2)&amp;lt;/math&amp;gt;&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p align=&amp;quot;center&amp;quot;&amp;gt;&amp;lt;math&amp;gt;\Theta_{distance}^d&amp;lt;/math&amp;gt; = &amp;lt;math&amp;gt;d&amp;lt;/math&amp;gt; вычитаний + &amp;lt;math&amp;gt;d&amp;lt;/math&amp;gt; умножений + &amp;lt;math&amp;gt;(d-1)&amp;lt;/math&amp;gt; сложение&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding-bottom: 20px&amp;quot;&amp;gt;&lt;br /&gt;
  &amp;lt;p&amp;gt;Предположим, что алгоритм сошелся за &amp;lt;math&amp;gt;\Tau&amp;lt;/math&amp;gt; итераций, тогда временная сложность алгоритма &amp;lt;math&amp;gt;\Theta_{k-means}^{d, n}&amp;lt;/math&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
  &amp;lt;p align=&amp;quot;center&amp;quot;&amp;gt;&amp;lt;b&amp;gt;&amp;lt;math&amp;gt;\Theta_{k-means}^{d, n} \le \Theta_{init}^{k, d, n} + \Tau*(\Theta_{distribute}^{k, d} + \Theta_{recenter}^{k, d, n})&amp;lt;/math&amp;gt;&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding-bottom: 5px&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;Операции сложения/вычитания:&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p align=&amp;quot;center&amp;quot;&amp;gt;&amp;lt;b&amp;gt;&amp;lt;math&amp;gt;\Theta_{k-means}^{d, n} \le k*n*d+ \Tau*(k*n*(2d-1) + k*n*d) = k*n*d+ \Tau*(k*n*(3d-1)) \thicksim O(\Tau*k*d*n)&amp;lt;/math&amp;gt;&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding-bottom: 20px&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;Операции умножения/деления:&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p align=&amp;quot;center&amp;quot;&amp;gt;&amp;lt;b&amp;gt;&amp;lt;math&amp;gt;\Theta_{k-means}^{d, n} \le k*d + \Tau*(k*n*d + k*d) = k*d + \Tau * k*d*(n+1) \thicksim O(\Tau*k*d*n) &amp;lt;/math&amp;gt;&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding-bottom: 20px&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;Получаем, что &amp;lt;b&amp;gt;временная сложность&amp;lt;/b&amp;gt; алгоритма &amp;lt;b&amp;gt;k means&amp;lt;/b&amp;gt; кластеризации &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; &amp;lt;b&amp;gt;d-мерных&amp;lt;/b&amp;gt; векторов на &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластеров за &amp;lt;math&amp;gt;\Tau&amp;lt;/math&amp;gt; итераций:&amp;lt;/p&amp;gt;&lt;br /&gt;
 &amp;lt;p align=&amp;quot;center&amp;quot;&amp;gt;&amp;lt;b&amp;gt;&amp;lt;math&amp;gt; \Theta_{k-means}^{d, n} \thicksim O(\Tau*k*d*n) &amp;lt;/math&amp;gt;&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Информационный граф ===&lt;br /&gt;
&lt;br /&gt;
Рассмотрим информационный граф алгоритма. Алгоритм &amp;lt;i&amp;gt;k means&amp;lt;/i&amp;gt; начинается с этапа инициализации, после которого следуют итерации, на каждой из которых выполняется два последовательных шага (см. [[#Схема реализации последовательного алгоритма|&amp;quot;Схема реализации последовательного алгоритма&amp;quot;]]): &lt;br /&gt;
* распределение векторов по кластерам&lt;br /&gt;
* перерасчет центров кластеров&lt;br /&gt;
&lt;br /&gt;
Поскольку основная часть вычислений приходится на шаги итераций, распишем информационные графы данных шагов.&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Распределение векторов по кластерам&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
Информационный граф шага распределения векторов по кластерам представлен на &#039;&#039;рисунке 1&#039;&#039;. Исходами данного графа является исходные векторы &amp;lt;math&amp;gt;\mathbf{x}_1, ..., \mathbf{x}_n&amp;lt;/math&amp;gt;, а также центры кластеров &amp;lt;math&amp;gt;\mathbf{\mu}_1, ... \mathbf{\mu}_k&amp;lt;/math&amp;gt;, вычисленные ранее (на шаге инициализации, если рассматривается первая итерация алгоритма, или на шаге пересчета центров кластеров предыдущей итерации в противном случае). Каждая пара векторов данных &amp;lt;math&amp;gt;\mathbf{x}_i, i=\overline{1,n}&amp;lt;/math&amp;gt; и центров кластера &amp;lt;math&amp;gt;\mathbf{\mu}_j, j=\overline{1, k}&amp;lt;/math&amp;gt; : (&amp;lt;math&amp;gt;\mathbf{x}_i&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;\mathbf{\mu}_j&amp;lt;/math&amp;gt;) подаются на независимые узлы &amp;lt;i&amp;gt;&amp;quot;d&amp;quot;&amp;lt;/i&amp;gt; вычисления расстояния между векторами (более подробная схема вычисления расстояния представлена далее, &#039;&#039;рисунок 2&#039;&#039;). Далее узлы вычисления расстояния &amp;lt;i&amp;gt;&amp;quot;d&amp;quot;&amp;lt;/i&amp;gt;, соответствующие одному и тому же исходному вектору &amp;lt;math&amp;gt;\mathbf{x}_i&amp;lt;/math&amp;gt; передаются на один узел &amp;lt;i&amp;gt;&amp;quot;m&amp;quot;&amp;lt;/i&amp;gt;, где далее происходит вычисление новой метки кластера для каждого вектора &amp;lt;math&amp;gt;\mathbf{x}_i&amp;lt;/math&amp;gt; (берется кластер с минимальным результатом вычисления расстояния). На выходе графа выдаются метки кластеров , &amp;lt;math&amp;gt;L_1, ..., L_n&amp;lt;/math&amp;gt;, такие что &amp;lt;math&amp;gt;\forall \mathbf{x}_i, i=\overline{1, n}, \mathbf{x}_i \in S_j \Leftrightarrow L_i = j&amp;lt;/math&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
[[file:Clusterization.png|thumb|center|800px|Рис. 1. Схема распределения векторов по кластерам. &#039;&#039;d&#039;&#039; &amp;amp;ndash; вычисление расстояния между векторами; &#039;&#039;m&#039;&#039; &amp;amp;ndash; вычисление минимума.]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Вычисление расстояния между векторами&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
Подробная схема вычисления расстояния между векторами &amp;lt;math&amp;gt;\mathbf{x}_i, \mathbf{\mu}_j&amp;lt;/math&amp;gt; представлена на &#039;&#039;рисунке 2&#039;&#039;. Как показано на графе, узел вычисления расстояния между векторами &amp;lt;i&amp;gt;&amp;quot;d&amp;quot;&amp;lt;/i&amp;gt; состоит из шага взятия разности между векторами (узел &amp;quot;&amp;lt;math&amp;gt;-&amp;lt;/math&amp;gt;&amp;quot;) и взятия нормы получившегося вектора разности (узел &amp;quot;&amp;lt;math&amp;gt;||\cdot||^2&amp;lt;/math&amp;gt;&amp;quot;). Более подробно, вычисление расстояния между векторами &amp;lt;math&amp;gt;\mathbf{x}_i = {x_{i1,}, ...,{x_{in}}}, \mathbf{\mu}_j = {\mu_{j1}, ...,\mu_{jn}}&amp;lt;/math&amp;gt; может быть представлено как вычисление разности между каждой парой компонент &amp;lt;math&amp;gt;(x_{iz}, \mu_{jz}), z=\overline{1, d}&amp;lt;/math&amp;gt; (узел &amp;quot;&amp;lt;math&amp;gt;-&amp;lt;/math&amp;gt;&amp;quot;), далее возведение в квадрат для каждого узла &amp;quot;&amp;lt;math&amp;gt;-&amp;lt;/math&amp;gt;&amp;quot; (узел &amp;quot;&amp;lt;math&amp;gt;()^2&amp;lt;/math&amp;gt;&amp;quot;) и суммирования выходов всех узлов &amp;quot;&amp;lt;math&amp;gt;()^2&amp;lt;/math&amp;gt;&amp;quot; (узел &amp;quot;&amp;lt;math&amp;gt;+&amp;lt;/math&amp;gt;&amp;quot;).  &lt;br /&gt;
&lt;br /&gt;
[[file:dist_calc.png|thumb|center|800px|Рис. 2. Схема вычисления расстояния между вектором и центром кластера.]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Пересчет центров кластеров&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
Информационный граф шага пересчета центров кластеров представлен на &#039;&#039;рисунке 3&#039;&#039;. Исходами данного графа является исходные векторы &amp;lt;math&amp;gt;\mathbf{x}_1, ..., \mathbf{x}_n&amp;lt;/math&amp;gt;, а также им соответствующие метки кластера, &amp;lt;math&amp;gt;L_1, ..., L_n&amp;lt;/math&amp;gt;, такие что &amp;lt;math&amp;gt;\forall x_i, i=\overline{1, n}, \mathbf{x}_i \in S_j \Leftrightarrow L_i = j&amp;lt;/math&amp;gt;, вычисленные на этапе распределения векторов по кластерам. Все векторы &amp;lt;math&amp;gt;\mathbf{x}_1, ..., \mathbf{x}_n&amp;lt;/math&amp;gt; подаются в узлы &amp;lt;math&amp;gt;+_1, ...+_k&amp;lt;/math&amp;gt;, каждый узел &amp;lt;math&amp;gt;+_m, m = \overline{1,k}&amp;lt;/math&amp;gt; соответствует операции сложения векторов кластера с номером &amp;lt;math&amp;gt;m&amp;lt;/math&amp;gt;. Метки кластера &amp;lt;math&amp;gt;L_1, ..., L_n&amp;lt;/math&amp;gt; также совместно передаются на узлы &amp;lt;math&amp;gt;S_m, m = \overline{1,k}&amp;lt;/math&amp;gt;, на каждом из которых вычисляется количество векторов в соответствующем кластере (количество меток с соответствующим значением). Далее каждая пара выходов узлов &amp;lt;math&amp;gt;+_m&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;S_m&amp;lt;/math&amp;gt; подается на узел &amp;quot;&amp;lt;math&amp;gt;/&amp;lt;/math&amp;gt;&amp;quot;, где производится деление суммы векторов кластера на количество элементов в нем. Значения, вычисленные на узлах &amp;quot;&amp;lt;math&amp;gt;/&amp;lt;/math&amp;gt;&amp;quot;, присваиваются новым центрам кластеров (выходные значения графа).&lt;br /&gt;
&lt;br /&gt;
[[file:Recluster.png|thumb|center|800px|Рис. 3. Схема пересчета центров кластеров]]&lt;br /&gt;
&lt;br /&gt;
=== Ресурс параллелизма алгоритма ===&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
Работа алгоритма состоит из &amp;lt;math&amp;gt;\Tau&amp;lt;/math&amp;gt; итераций, в каждой из которых происходит &amp;lt;b&amp;gt;распределение d-мерных векторов по &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластерам&amp;lt;/b&amp;gt;, а также &amp;lt;b&amp;gt;пересчет центров кластеров в d-мерном пространстве&amp;lt;/b&amp;gt;. В шаге &amp;lt;b&amp;gt;распределения d-мерных векторов по &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластерам&amp;lt;/b&amp;gt; расстояния между вектором и центрами кластеров вычисляются независимо (отсутствуют информационные зависимости). &amp;lt;b&amp;gt;Центры масс кластеров&amp;lt;/b&amp;gt; также пересчитываются независимо друг от друга. Таким образом, имеет место [[глоссарий#Массовый параллелизм|&#039;&#039;массовый параллелизм&#039;&#039;]]. Вычислим параллельную сложность &amp;lt;math&amp;gt;\Psi_*&amp;lt;/math&amp;gt; каждого из шагов, а также параллельную сложность всего алгоритма, &amp;lt;math&amp;gt;\Psi_{k-means}&amp;lt;/math&amp;gt;. Будем исходить из предположения, что может быть использовано любое необходимое число потоков.&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Распределение d-мерных векторов по &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластерам&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;  &lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
Поскольку на данном шаге для каждой пары векторов &amp;lt;math&amp;gt;\mathbf{x}_i, i=\overline{1,n}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\mathbf{\mu}_j, j=\overline{1,k}&amp;lt;/math&amp;gt; операции вычисления расстояния не зависят друг от друга, они могут выполняться параллельно. Тогда, разделив все вычисление расстояний на &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; потоков, получим, что в каждом потоке будет выполняться только одна операция вычисления расстояния между векторами размерности d. При этом каждому вычислительному потоку передаются координаты центров всех кластеров &amp;lt;math&amp;gt;\mathbf{\mu}_1, ..., \mathbf{\mu}_k&amp;lt;/math&amp;gt;. Таким образом, параллельная сложность данного шага определяется &amp;lt;i&amp;gt; сложностью параллельной операции вычисления расстояния между d-мерными векторами&amp;lt;/i&amp;gt;, &amp;lt;math&amp;gt;\Psi_{distance}^d&amp;lt;/math&amp;gt;  и &amp;lt;i&amp;gt;сложностью определения наиболее близкого кластера&amp;lt;/i&amp;gt; (паралельное взятие минимума по расстояниям), &amp;lt;math&amp;gt;\Psi_{min}^k&amp;lt;/math&amp;gt;. Для оценки &amp;lt;math&amp;gt;\Psi_{distance}^d&amp;lt;/math&amp;gt; воспользуемся  [[Нахождение_частных_сумм_элементов_массива_сдваиванием | параллельной реализацией нахождения частичной суммы элементов массива путем сдваивания]]. Аналогично, &amp;lt;math&amp;gt;\Psi_{min}^k = log(k)&amp;lt;/math&amp;gt;. В результате, &amp;lt;math&amp;gt;\Psi_{distance}^d = O(log(d))&amp;lt;/math&amp;gt;.   Таким образом: &lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p align=&amp;quot;center&amp;quot;&amp;gt;&amp;lt;math&amp;gt;\Psi_{distribute}^{k, d}  = \Psi_{distance}^d + \Psi_{min}^k = O(log(d))+O(log(k)) = O(log(k*d))&amp;lt;/math&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Пересчет центров кластеров в d-мерном пространстве&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
Поскольку на данном шаге для каждого из &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластеров центр масс может быть вычислен независимо, данные операции могут быть выполнены в отдельных потоках. Таким образом, параллельная сложность данного шага, &amp;lt;math&amp;gt;\Psi_{recenter}^{k, d}&amp;lt;/math&amp;gt;,  будет определяться &amp;lt;i&amp;gt;параллельной сложностью вычисления одного центра масс кластера размера &amp;lt;math&amp;gt;m&amp;lt;/math&amp;gt;&amp;lt;/i&amp;gt;, &amp;lt;math&amp;gt;\Psi_{recenter}^{k, d}&amp;lt;/math&amp;gt;,  а так как &amp;lt;math&amp;gt;m \le n \Rightarrow \Psi_{recenter}^{d, m} \le \Psi_{recenter}^{d, n}&amp;lt;/math&amp;gt;. Сложность вычисления центра масс кластера d-мерных векторов размера n аналогично предыдущим вычислениям равна &amp;lt;math&amp;gt;O(log(n))&amp;lt;/math&amp;gt;. Тогда:  &lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p align=&amp;quot;center&amp;quot;&amp;gt;&amp;lt;math&amp;gt;\Psi_{recenter}^{k, d}  \le \Psi_{recenter}^{d, n} = O(log(n))&amp;lt;/math&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Общая параллельная сложность алгоритма&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
На каждой итерации необходимо обновление центров кластеров, которые будут использованы на следующей итерации. Таким образом, итерационный процесс выполняется последовательно&amp;lt;ref&amp;gt;Zhao, Weizhong, Huifang Ma, and Qing He. &amp;quot;Parallel k-means clustering based on mapreduce.&amp;quot; IEEE International Conference on Cloud Computing. Springer Berlin Heidelberg, 2009.&amp;lt;/ref&amp;gt;. Тогда, поскольку сложность каждой итерации  определяется &amp;lt;math&amp;gt;\Psi_{distribute}^{k, d}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\Psi_{recenter}&amp;lt;/math&amp;gt;, сложность всего алгоритма, &amp;lt;math&amp;gt;\Psi_{k-means}&amp;lt;/math&amp;gt; в предположении, что было сделано &amp;lt;math&amp;gt;\Tau&amp;lt;/math&amp;gt; операций определяется выражением&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p align=&amp;quot;center&amp;quot;&amp;gt;&amp;lt;math&amp;gt;\Psi_{k-means} \approx \Tau * (\Psi_{distribute}^{k, d} + \Psi_{recenter}^{k, d}) \le \Tau * O(log(k*d*n))&amp;lt;/math&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Входные и выходные данные алгоритма ===&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;Входные данные&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;Матрица из &amp;lt;math&amp;gt;n*d&amp;lt;/math&amp;gt; элементов &amp;lt;math&amp;gt;x_{i, j} \in \mathbb{R}, i=\overline{1, n}, j=\overline{1, d}&amp;lt;/math&amp;gt;&amp;amp;ndash; координат векторов (наблюдений).&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;Целое положительное число &amp;lt;math&amp;gt;k, k \le n&amp;lt;/math&amp;gt; &amp;amp;ndash; количество кластеров.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;Объем входных данных&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;math&amp;gt;1&amp;lt;/math&amp;gt; целое число + &amp;lt;math&amp;gt;n*d&amp;lt;/math&amp;gt; вещественных чисел (при условии, что координаты &amp;amp;ndash; вещественные числа).&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;Выходные данные&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; целых положительных чисел &amp;lt;math&amp;gt;L_1, ..., L_n&amp;lt;/math&amp;gt;&amp;amp;ndash; номера кластеров, соотвествующие каждому вектору (при условии, что нумерация кластеров начинается с &amp;lt;math&amp;gt;1&amp;lt;/math&amp;gt;).&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;Объем выходных данных&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; целых положительных чисел.&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Свойства алгоритма ===&lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;[[глоссарий#Вычислительная мощность|&#039;&#039;Вычислительная мощность&#039;&#039;]]&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
Вычислительная мощность алгоритма &amp;lt;i&amp;gt;k means&amp;lt;/i&amp;gt; равна &amp;lt;math&amp;gt;\frac{k*d*n*\Tau}{n*d} = k*\Tau &amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; &amp;amp;ndash; число кластеров, &amp;lt;math&amp;gt;\Tau&amp;lt;/math&amp;gt; &amp;amp;ndash; число итераций алгоритма.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;[[глоссарий#Детерминированность |&#039;&#039;Детерминированность&#039;&#039;]] и [[глоссарий#Устойчивость |&#039;&#039;Устойчивость&#039;&#039;]] &amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
Алгоритм &amp;lt;i&amp;gt;k means&amp;lt;/i&amp;gt; является итерационным. Количество итераций алгоритма в общем случае не фиксируется и зависит от начального расположения объектов в пространстве, параметра &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt;, а также от начального приближения центров кластеров, &amp;lt;math&amp;gt;\mu_1, ..., \mu_k&amp;lt;/math&amp;gt;. В результате этого может варьироваться результат работы алгоритма. При неудачном выборе начальных параметров итерационный процесс может сойтись к локальному оптимуму&amp;lt;ref&amp;gt;Von Luxburg, Ulrike. Clustering Stability. Now Publishers Inc, 2010.&amp;lt;/ref&amp;gt;. По этим причинам алгоритм не является ни &amp;lt;b&amp;gt;детермирированным&amp;lt;/b&amp;gt;, ни &amp;lt;b&amp;gt;устойчивым&amp;lt;/b&amp;gt;.&lt;br /&gt;
 &lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Соотношение последовательной и параллельной сложности алгоритма&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\frac{\Theta_{k-means}}{\Psi_{k-means}} = \frac{O(\Tau*k*d*n)}{O(\Tau*log(k*d*n))}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Сильные стороны алгоритма&amp;lt;/b&amp;gt;:&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;i&amp;gt;Сравнительно высокая эффективность при простоте реализации&amp;lt;/i&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;i&amp;gt;Высокое качество кластеризации&amp;lt;/i&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;i&amp;gt;Возможность распараллеливания&amp;lt;/i&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;i&amp;gt;Существование множества модификаций&amp;lt;/i&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;Недостатки алгоритма&amp;lt;/b&amp;gt;&amp;lt;ref&amp;gt;Ortega, Joaquín Pérez, Ma Del Rocío Boone Rojas, and María J. Somodevilla. &amp;quot;Research issues on K-means Algorithm: An Experimental Trial Using Matlab.&amp;quot;&amp;lt;/ref&amp;gt;:&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;i&amp;gt;Количество кластеров является параметром алгоритма&amp;lt;/i&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;&amp;lt;i&amp;gt;Чувствительность к начальным условиям&amp;lt;/i&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;Инициализация центров кластеров в значительной степени влияет на результат кластеризации.&amp;lt;/p&amp;gt;&lt;br /&gt;
  &amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;&amp;lt;i&amp;gt;Чувствительность к выбросам и шумам&amp;lt;/i&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;Выбросы, далекие от центров настоящих кластеров, все равно учитываются при вычислении их центров.&amp;lt;/p&amp;gt;&lt;br /&gt;
  &amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;&amp;lt;i&amp;gt;Возможность сходимости к локальному оптимуму&amp;lt;/i&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;Итеративный подход не дает гарантии сходимости к оптимальному решению.&amp;lt;/p&amp;gt;&lt;br /&gt;
  &amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;&amp;lt;i&amp;gt;Использование понятия &amp;quot;среднего&amp;quot;&amp;lt;/i&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
    &amp;lt;p&amp;gt;Алгоритм неприменим к данным, для которых не определено понятие &amp;quot;среднего&amp;quot;, например, категориальным данным.&amp;lt;/p&amp;gt;&lt;br /&gt;
  &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&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;
Исследование масштабируемости параллельной реализации алгоритма k means проводилось на суперкомпьютере &amp;quot;Ломоносов&amp;quot;. Алгоритм реализован на языке C с использованием средств MPI.&lt;br /&gt;
Для исследования масштабируемости проводилось множество запусков программы с разным значением параметра (количество векторов для кластеризации), а также с различным числом процессоров. Фиксировались результаты запусков &amp;amp;ndash; время работы &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt; и количество произведенных итераций алгоритма &amp;lt;math&amp;gt;\Tau&amp;lt;/math&amp;gt;.&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;Значения &amp;lt;b&amp;gt;количества векторов&amp;lt;/b&amp;gt; &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;: 20&#039;000, 30&#039;000, 50&#039;000, 100&#039;000, 200&#039;000, 300&#039;000, 500&#039;000, 700&#039;000, 1&#039;000&#039;000, 1&#039;500&#039;000, 2&#039;000&#039;000.&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;Значения &amp;lt;b&amp;gt;количества процессоров&amp;lt;/b&amp;gt; &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt;: 1, 8, 16, 32, 64, 128, 160, 192, 224, 256, 288, 320, 352, 384, 416, 448, 480, 512.&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;Значение &amp;lt;b&amp;gt;количества кластеров&amp;lt;/b&amp;gt; &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt;: 100.&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;Значение &amp;lt;b&amp;gt;размерности векторов&amp;lt;/b&amp;gt; &amp;lt;math&amp;gt;d&amp;lt;/math&amp;gt;: 10.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Графики производительности и эффективности реализации представлены на рисунках 4 и 5 соответственно.&lt;br /&gt;
&lt;br /&gt;
[[file:Flops.png|thumb|center|800px|Рис. 4. График производительности реализации алгоритма.]]&lt;br /&gt;
&lt;br /&gt;
[[file:Efficiency.png|thumb|center|800px|Рис. 5. График эффективности реализации алгоритма.]]&lt;br /&gt;
&lt;br /&gt;
Для заданной конфигурации эксперимента (&amp;lt;math&amp;gt;n, p, k&amp;lt;/math&amp;gt;) и полученных результатах (&amp;lt;math&amp;gt;t, \Tau&amp;lt;/math&amp;gt;) производительность и эффективность реализации расчитывались по формулам:&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;math&amp;gt;Performance = \frac{\Theta_{k-means}^{d, n}}{t}&amp;lt;/math&amp;gt; (см. [[#Последовательная сложность алгоритма| последовательная сложность алгоритма]])&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
В результате экспериментальной оценки были получены следующие оценки эффективности реализации:&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;b&amp;gt;Минимальное&amp;lt;/b&amp;gt; значение: 0.000409 %&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;b&amp;gt;Максимальное&amp;lt;/b&amp;gt; значение: 0.741119 %&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Динамические характеристики и эффективность реализации алгоритма ===&lt;br /&gt;
=== Выводы для классов архитектур ===&lt;br /&gt;
=== Существующие реализации алгоритма ===&lt;br /&gt;
==== Открытое программное обеспечение ====&lt;br /&gt;
&amp;lt;ol&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;[https://www.icpsr.umich.edu/CrimeStat/ CrimeStat]&amp;lt;/li&amp;gt; Программное обеспечение, созданное для операционных систем Windows, предоставляющее инструменты статистического  и пространственного анализа для решения задачи картирования преступности.&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://juliastats.github.io Julia]&amp;lt;/li&amp;gt; Высокоуровневый высокопроизводительный свободный язык программирования с динамической типизацией, созданный для математических вычислений, содержит реализацию k-means.&lt;br /&gt;
  &amp;lt;li&amp;gt;[https://mahout.apache.org Mahout]&amp;lt;/li&amp;gt; Apache Mahout - Java библиотека для работы с алгоритмами машинного обучения с использованием MapReduce. Содержит реализацию k-means.&lt;br /&gt;
  &amp;lt;li&amp;gt;[https://www.gnu.org/software/octave/ Octave]&amp;lt;/li&amp;gt; Написанная на C++  свободная система для математических вычислений, использующая совместимый с MATLAB язык высокого уровня, содержит реализацию k-means.&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://spark.apache.org/docs/latest/mllib-clustering.html Spark]&amp;lt;/li&amp;gt; Распределенная реализация k-means содержится в библиотеке Mlib для работы с алгоритмами машинного обучения, взаимодействующая с Python библиотекой NumPy и библиотека R.&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://torch.ch Torch]&amp;lt;/li&amp;gt;  MATLAB-подобная библиотека для языка программирования Lua с открытым исходным кодом, предоставляет большое количество алгоритмов для глубинного обучения и научных расчётов. Ядро написано на Си, прикладная часть выполняется на LuaJIT, поддерживается распараллеливание вычислений средствами CUDA и OpenMP. Существуют реализации k-means.&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://www.cs.waikato.ac.nz/ml/weka/ Weka]&amp;lt;/li&amp;gt;  Cвободное программное обеспечение для анализа данных, написанное на Java. Содержит k-means и x-means.&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://accord-framework.net/docs/html/T_Accord_MachineLearning_KMeans.htm Accord.NET]&amp;lt;/li&amp;gt; C# реализация алгоритмов k-means, k-means++, k-modes.&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://docs.opencv.org/3.0-beta/doc/py_tutorials/py_ml/py_kmeans/py_kmeans_opencv/py_kmeans_opencv.html OpenCV]&amp;lt;/li&amp;gt; Написанная на С++ библиотека, направленная в основном на решение задач компьютерного зрения. Содержит реализацию k-means.&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://mlpack.org/ MLPACK]&amp;lt;/li&amp;gt; Масштабируемая С++ библиотека для работы с алгоритмами машинного обучения, содержит реализацию k-means.&lt;br /&gt;
  &amp;lt;li&amp;gt;[https://www.scipy.org/ SciPy]&amp;lt;/li&amp;gt; Библиотека Python, содержит множество реализаций k-means.&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://scikit-learn.org/ scikit-learn]&amp;lt;/li&amp;gt; Библиотека Python, содержит множество реализаций k-means.&lt;br /&gt;
  &amp;lt;li&amp;gt;[https://www.r-bloggers.com/k-means-clustering-in-r/ R]&amp;lt;/li&amp;gt; Язык программирования для статистической обработки данных и работы с графикой, а также свободная программная среда вычислений с открытым исходным кодом в рамках проекта GNU, содержит три реализации k-means.&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://elki.dbs.ifi.lmu.de ELKI]&amp;lt;/li&amp;gt; Java фреймворк, содержащий реализацию k-means, а также множество других алгоритмов кластеризации.&lt;br /&gt;
&amp;lt;/ol&amp;gt;&lt;br /&gt;
==== Проприетарное программное обеспечение  ====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ol&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;[https://www.ayasdi.com/blog/bigdata/topological-data-analysis-of-oil-and-gas-petrophysical-data/ Ayasdi]&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://www.stata.com/features/cluster-analysis/ Stata]&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://mathworld.wolfram.com/K-MeansClusteringAlgorithm.html Mathematica]&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://www.mathworks.com/help/stats/kmeans.html?requestedDomain=www.mathworks.com MATLAB]&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;[https://support.sas.com/rnd/app/stat/procedures/fastclus.html SAS]&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;[http://docs.rapidminer.com/studio/operators/modeling/segmentation/k_means.html RapidMiner]&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;[https://blogs.sap.com/2013/03/28/sap-hana-pal-k-means-algorithm-or-how-to-do-customer-segmentation-for-the-telecommunications-industry/ SAP HANA]&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ol&amp;gt;&lt;br /&gt;
== Литература ==&lt;br /&gt;
&amp;lt;references /&amp;gt;&lt;/div&gt;</summary>
		<author><name>DennZo1993</name></author>
	</entry>
</feed>