<?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=%D0%91%D0%BE%D0%B3%D0%BE%D0%BC%D0%B0%D0%B7%D0%BE%D0%B2+%D0%95%D0%B2%D0%B3%D0%B5%D0%BD%D0%B8%D0%B9</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=%D0%91%D0%BE%D0%B3%D0%BE%D0%BC%D0%B0%D0%B7%D0%BE%D0%B2+%D0%95%D0%B2%D0%B3%D0%B5%D0%BD%D0%B8%D0%B9"/>
	<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/%D0%91%D0%BE%D0%B3%D0%BE%D0%BC%D0%B0%D0%B7%D0%BE%D0%B2_%D0%95%D0%B2%D0%B3%D0%B5%D0%BD%D0%B8%D0%B9"/>
	<updated>2026-10-22T23:59:54Z</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%98%D0%BB%D1%8C%D1%8F_%D0%95%D0%B3%D0%BE%D1%80%D0%BE%D0%B2/%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_k-%D1%81%D1%80%D0%B5%D0%B4%D0%BD%D0%B8%D1%85&amp;diff=12049</id>
		<title>Участник:Илья Егоров/Алгоритм k-средних</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%98%D0%BB%D1%8C%D1%8F_%D0%95%D0%B3%D0%BE%D1%80%D0%BE%D0%B2/%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_k-%D1%81%D1%80%D0%B5%D0%B4%D0%BD%D0%B8%D1%85&amp;diff=12049"/>
		<updated>2016-10-15T20:57:40Z</updated>

		<summary type="html">&lt;p&gt;Богомазов Евгений: /* Математическое описание алгоритма */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{algorithm&lt;br /&gt;
| name              = Алгоритм k-средних (k-means)&lt;br /&gt;
| serial_complexity = &amp;lt;math&amp;gt;O(n*k*d)&amp;lt;/math&amp;gt;&lt;br /&gt;
| input_data        = &amp;lt;math&amp;gt;n*d&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;quot;Илья Егоров — Евгений Богомазов&amp;quot;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
= ЧАСТЬ. Свойства и структура алгоритмов =&lt;br /&gt;
== Общее описание алгоритма ==&lt;br /&gt;
&lt;br /&gt;
Алгоритм кластеризации k-средних впервые был предложен в 1950-х годах математиками Гуго Штейнгаузом и Стюартом Ллойдом независимо друг от друга. Наибольшую популярность он получил после работы Маккуина.&lt;br /&gt;
&lt;br /&gt;
Алгоритм позволяет при заданном числе &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; построить &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластеров, расположенных на максимальном расстоянии друг от друга. Таким образом, наибольшей точности результат выполнения алгоритма достигает при полной осведомленности Пользователя о характере кластеризуемых объектов и, как следствие, при обладании максимально корректной информацией о числе кластеров.&lt;br /&gt;
&lt;br /&gt;
В общем случае выбор числа &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; может базироваться на любых значимых факторах, в том числе на результатах предшествующих исследований, теоретических соображениях или интуиции. &lt;br /&gt;
&lt;br /&gt;
== Математическое описание алгоритма ==&lt;br /&gt;
&#039;&#039;&#039;Исходные данные:&#039;&#039;&#039;&lt;br /&gt;
* Совокупность &amp;lt;b&amp;gt;n&amp;lt;/b&amp;gt; &amp;lt;b&amp;gt;d&amp;lt;/b&amp;gt;-мерных векторов &amp;lt;math&amp;gt; X = \{x_1 \dots x_n\} , &amp;lt;/math&amp;gt; где  &amp;lt;math&amp;gt; x_i = \{x_{i1} \dots x_{id}\} &amp;lt;/math&amp;gt;&lt;br /&gt;
* Предполагаемое количество кластеров &amp;lt;b&amp;gt;k&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Выходные данные:&#039;&#039;&#039;&lt;br /&gt;
* Разбиение X на множество &amp;lt;math&amp;gt; S = \{S_1 \dots S_k \}, \bigcup S_i = X, S_i \cap S_j = \emptyset, i \neq j &amp;lt;/math&amp;gt;&lt;br /&gt;
* k центров кластеров &amp;lt;math&amp;gt; \Mu = \{\mu_1 \dots \mu_k \} &amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt; \mu_i = \{\mu_{i1} \dots \mu_{id} \} &amp;lt;/math&amp;gt; такие, что&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; \begin{cases}\tilde{\mu_i} = \underset{y}{argmin } \sum_{x \in S_i} ||x-y||^2_E \\ \Mu = \underset{\tilde{\Mu}}{argmin } \sum_{i \in k} \sum_{x \in S_i} ||x-\tilde{\mu_i}||^2_E \end{cases} &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Алгоритм:&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
1) &amp;lt;math&amp;gt; \mu_{i} = random &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
2) &amp;lt;math&amp;gt; S_i = \{x \in S~|~\underset{j}{argmin } ||x-\mu_j||_E = i\} i = 1 \dots k &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
3) &amp;lt;math&amp;gt; \tilde{\mu_{i}} = E_{x \in S_i}(x) &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
4) Если для &amp;lt;math&amp;gt; \forall i:  \mu_i = \tilde{\mu_i} &amp;lt;/math&amp;gt; то алгоритм завершен, иначе &amp;lt;math&amp;gt; \mu_i = \tilde{\mu_i} &amp;lt;/math&amp;gt; и перейти на пункт 2)&lt;br /&gt;
&lt;br /&gt;
== Вычислительное ядро алгоритма ==&lt;br /&gt;
&lt;br /&gt;
Вычислительным ядром алгоритма является второй этап, а точнее нахождение матрицы расстояний между &amp;lt;math&amp;gt;X&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\Mu&amp;lt;/math&amp;gt;. Для &#039;&#039;&#039;d&#039;&#039;&#039;-мерного вектора &amp;lt;math&amp;gt;a:&amp;lt;/math&amp;gt; &lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;||a||=\sqrt{\sum_{i=1\dots d} a_i^2}&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; операций сложения и одну операция вычисления квадратного корня. Но так как эти расстояния используются только для сравнения, а &#039;&#039;sqrt&#039;&#039; является монотонно возрастающей функцией, то ее можно не вычислять. Поэтому нахождения матрицы расстояний потребует всего &amp;lt;math&amp;gt;n*k*d&amp;lt;/math&amp;gt; операций умножений и &amp;lt;math&amp;gt;n*k*(d-1)&amp;lt;/math&amp;gt; операций сложений.&lt;br /&gt;
&lt;br /&gt;
== Макроструктура алгоритма ==&lt;br /&gt;
&lt;br /&gt;
В алгоритме можно выделить следующие макрооперации: &lt;br /&gt;
*&#039;&#039;&#039;Вычисление расстояния между векторами&#039;&#039;&#039;,&lt;br /&gt;
*&#039;&#039;&#039;Суммирование векторов&#039;&#039;&#039;,&lt;br /&gt;
*&#039;&#039;&#039;Поиск минимума в векторе&#039;&#039;&#039;,&lt;br /&gt;
*&#039;&#039;&#039;Сравнение векторов&#039;&#039;&#039;,&lt;br /&gt;
*&#039;&#039;&#039;Деление вектора на скаляр&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;1)&#039;&#039;&#039; На шаге инициализации центроидов в общем случае (случайный выбор элементов) макроопераций не производится. Но так как правило определения количества кластеров &#039;&#039;&#039;k&#039;&#039;&#039; неоднозначно, то для некоторых вариантов макрооперации могут понадобиться. К примеру, существует класс стратегий поиска &#039;&#039;&#039;k&#039;&#039;&#039;, которые базируются на определении центра масс всех объектов, и для которых будут дополнительно выполняться макрооперации &#039;&#039;&#039;&amp;quot;Суммирование векторов&amp;quot;&#039;&#039;&#039; и &#039;&#039;&#039;&amp;quot;Деление вектора на скаляр&amp;quot;&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;2a)&#039;&#039;&#039; При составлении матрицы расстояний &#039;&#039;&#039; k &amp;lt;math&amp;gt; \cdot &amp;lt;/math&amp;gt;  n&#039;&#039;&#039; раз производится макрооперация &#039;&#039;&#039;&amp;quot;Вычисление расстояния между векторами&amp;quot;&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;2b)&#039;&#039;&#039; При нахождение вектора распределения объектов по кластерам &#039;&#039;&#039;n&#039;&#039;&#039; раз производится макрооперация &#039;&#039;&#039;&amp;quot;Поиск минимума в векторе&amp;quot;&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;3)&#039;&#039;&#039; При пересчете центроидов &#039;&#039;&#039;n - k&#039;&#039;&#039; раз производится макрооперация &#039;&#039;&#039;&amp;quot;Суммирование векторов&amp;quot;&#039;&#039;&#039; и &#039;&#039;&#039;k&#039;&#039;&#039; раз - &#039;&#039;&#039;&amp;quot;Деление вектора на скаляр&amp;quot;&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;4)&#039;&#039;&#039; Для проверки критерия останова требуется &#039;&#039;&#039;k&#039;&#039;&#039; раз произвести макрооперацию &#039;&#039;&#039;&amp;quot;Сравнение векторов&amp;quot;&#039;&#039;&#039; для сопоставления обновленных значений центроидов с уже имеющимися.&lt;br /&gt;
&lt;br /&gt;
== Схема реализации последовательного алгоритма ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Последовательность шагов алгоритма следующая:&lt;br /&gt;
&lt;br /&gt;
    &#039;&#039;&#039;1) Инициализация центроидов &amp;lt;math&amp;gt;\Mu&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt; iter = 1 &amp;lt;/math&amp;gt;, задание максимального количество итераций &amp;lt;math&amp;gt;maxiter&amp;lt;/math&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
        &lt;br /&gt;
    &#039;&#039;&#039;2a) Нахождение матрицы расстояний &#039;&#039;&#039;&amp;lt;math&amp;gt;dist:&amp;lt;/math&amp;gt;&lt;br /&gt;
    &lt;br /&gt;
        &amp;lt;math&amp;gt;dist_{ij} = \sum_{l = 1\dots d} (x_{il}-\mu_{jl})^2&amp;lt;/math&amp;gt;&lt;br /&gt;
        &lt;br /&gt;
    &#039;&#039;&#039;2b) Нахождение вектора распределения объектов по кластерам &#039;&#039;&#039;&amp;lt;math&amp;gt;index: &amp;lt;/math&amp;gt;&lt;br /&gt;
    &lt;br /&gt;
        &amp;lt;math&amp;gt;index_{i} =   \underset{j}{argmin }~dist_{ij} &amp;lt;/math&amp;gt;&lt;br /&gt;
    &lt;br /&gt;
    &#039;&#039;&#039;3) Пересчет центроидов &#039;&#039;&#039;&amp;lt;math&amp;gt;\tilde{\Mu}:&amp;lt;/math&amp;gt;&lt;br /&gt;
    &lt;br /&gt;
        &amp;lt;math&amp;gt;\tilde{\mu_{ij}} = \sum_{l \in S_i} \dfrac{x_{lj}}{|S_i|} &amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;S_i = \{l~|~l \in 1\dots n, index_l = i\}  &amp;lt;/math&amp;gt;&lt;br /&gt;
    &lt;br /&gt;
    &#039;&#039;&#039;4) Проверка критерия останова:&#039;&#039;&#039;&lt;br /&gt;
    &lt;br /&gt;
        &#039;&#039;&#039;Если&#039;&#039;&#039; &amp;lt;math&amp;gt; \exists i: \tilde{\mu_i} \neq \mu_i&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt; iter &amp;lt; maxiter &amp;lt;/math&amp;gt;,&lt;br /&gt;
    &lt;br /&gt;
        &#039;&#039;&#039;то&#039;&#039;&#039; &amp;lt;math&amp;gt; inc(iter), \Mu=\tilde{\Mu},&amp;lt;/math&amp;gt; &#039;&#039;&#039;GOTO 2.а.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
== Последовательная сложность алгоритма ==&lt;br /&gt;
&lt;br /&gt;
    &#039;&#039;&#039;1)&#039;&#039;&#039; Сложность инициализации в общем случае зависит от применяемого метода генерации/получения случайных чисел, но ей можно пренебречь&lt;br /&gt;
    &lt;br /&gt;
    &#039;&#039;&#039;2a)&#039;&#039;&#039; Вычисление матрицы расстояний требует &amp;lt;math&amp;gt; n*k*d &amp;lt;/math&amp;gt; операций умножения и &amp;lt;math&amp;gt; n*k*(d-1) &amp;lt;/math&amp;gt; операций сложения&lt;br /&gt;
    &lt;br /&gt;
    &#039;&#039;&#039;2b)&#039;&#039;&#039; Нахождение вектора распределения требует &amp;lt;math&amp;gt; n*(k-1) &amp;lt;/math&amp;gt; операций сравнения&lt;br /&gt;
    &lt;br /&gt;
    &#039;&#039;&#039;3)&#039;&#039;&#039; Для вычисления &amp;lt;math&amp;gt; \tilde{\Mu} &amp;lt;/math&amp;gt; требуется &amp;lt;math&amp;gt; (n - k + 1) * d &amp;lt;/math&amp;gt; операций сложения и &amp;lt;math&amp;gt; k * d &amp;lt;/math&amp;gt; операций деления&lt;br /&gt;
    &lt;br /&gt;
    &#039;&#039;&#039;4)&#039;&#039;&#039; Для критерия останова требуется &amp;lt;math&amp;gt; n*d &amp;lt;/math&amp;gt; сравнений&lt;br /&gt;
&lt;br /&gt;
Итого: так как максимальное количество итераций задается в алгоритме заранее и не зависит от входных данных, то количество итераций ограничено константой. Тогда сложность алгоритма:&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;math&amp;gt; O(n*k*d)&amp;lt;/math&amp;gt; операций сложения/вычитания&lt;br /&gt;
* &amp;lt;math&amp;gt; O(n*k*d)&amp;lt;/math&amp;gt; операций умножения, &amp;lt;math&amp;gt; O(k*d) &amp;lt;/math&amp;gt; операций деления&lt;br /&gt;
&lt;br /&gt;
== Информационный граф ==&lt;br /&gt;
&lt;br /&gt;
Рассмотрим вычислительные этапы алгоритма k-means. Это распределение объектов по кластерам и перерасчет центроидов.&lt;br /&gt;
&lt;br /&gt;
Распределение объектов по кластерам состоит из нахождения матрицы расстояний между &amp;lt;math&amp;gt;X&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\Mu&amp;lt;/math&amp;gt; (этапа &#039;&#039;&#039;2a)&#039;&#039;&#039;) и нахождения индекса минимального элемента в каждой строке (этап &#039;&#039;&#039;2b)&#039;&#039;&#039;). Ниже приведен информационный граф данного этапа.&lt;br /&gt;
&lt;br /&gt;
[[Файл:EgorovBogomazovInf.png |800px|thumb|center|Нахождение вектора индексов распределения по кластерам]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Рассмотрим этап вычисления ячейки &amp;lt;math&amp;gt; dist_{ij} &amp;lt;/math&amp;gt; матрицы более подробно. Он представляет из себя скалярное произведение d-мерных векторов &amp;lt;math&amp;gt; x_i &amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt; \mu_j &amp;lt;/math&amp;gt;. Ниже приведена граф для данной операции.&lt;br /&gt;
&lt;br /&gt;
[[Файл:EgorovBogomazovDist.png|600px|thumb|center|Операция вычисления расстояния]]&lt;br /&gt;
&lt;br /&gt;
На этапе &#039;&#039;&#039;3)&#039;&#039;&#039; происходит суммирование всех &amp;lt;math&amp;gt; x_l &amp;lt;/math&amp;gt; с одинаковым значением индекса в промежуточные суммы. Одновременно происходит подсчет количество элементов с фиксированным индексом. Затем происходит деление промежуточных сумм на соответствующее количество элементов в новом кластере, благодаря чему удается получить обновленные центроиды &amp;lt;math&amp;gt; \tilde{\mu}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[Файл:EgorovBogomazovNewCluster.png|800px|thumb|center|Обновление центроидов]]&lt;br /&gt;
&lt;br /&gt;
== Ресурс параллелизма алгоритма ==&lt;br /&gt;
&lt;br /&gt;
Для получения общей картины достаточно определить, в том числе и с помощью информационного графа, каким ресурсом параллелизма обладает каждый из этапов алгоритма:&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;2a)&#039;&#039;&#039; Нахождение каждой ячейки матрицы &amp;lt;math&amp;gt; dist &amp;lt;/math&amp;gt; может происходить полностью независимо, так как они находятся на одном ярусе. При рассмотрении операции вычисления значения конкретной ячейки &amp;lt;math&amp;gt; dist_{ij} &amp;lt;/math&amp;gt; можно заметить, что все операции умножения также независимы между собой, поэтому понадобится всего одно умножение. Конечный результат получается в результате суммирования всех слагаемых и достигается параллельно за &amp;lt;math&amp;gt; \log(d) &amp;lt;/math&amp;gt; бинарных операций сложения при помощи стандартного метода &#039;&#039;reduction&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;2b)&#039;&#039;&#039; Нахождение вектора распределений заключается в нахождении минимального элемента в каждой строке матрицы &amp;lt;math&amp;gt; dist &amp;lt;/math&amp;gt;. При использовании &#039;&#039;reduction&#039;&#039; эту операцию можно выполнить за &amp;lt;math&amp;gt; \log(k) &amp;lt;/math&amp;gt; бинарных операций сравнения.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;3)&#039;&#039;&#039; В случае, если существует методология быстрого разделения &#039;&#039;&#039;n&#039;&#039;&#039; объектов на &#039;&#039;&#039;k&#039;&#039;&#039; множеств при помощи вектора индексации (косвенной адресации), все &amp;lt;math&amp;gt; \tilde{S_i} &amp;lt;/math&amp;gt; могут быть обработаны параллельно. В рамках каждого отдельного &amp;lt;math&amp;gt; \tilde{S_i} &amp;lt;/math&amp;gt; можно проводить распараллеливание дальше, так как &amp;lt;math&amp;gt; x_{lj} &amp;lt;/math&amp;gt; также не зависят друг от друга. Таким образом, вычисление всех слагаемых для всех &amp;lt;math&amp;gt; \tilde{\mu_{ij}} &amp;lt;/math&amp;gt; может быть выполнено за одно параллельное деление, а нахождение суммы всех этих слагаемых для каждого &amp;lt;math&amp;gt; \tilde{\mu_{ij}} &amp;lt;/math&amp;gt; может быть выполнено за &amp;lt;math&amp;gt; O(log(n)) &amp;lt;/math&amp;gt; в худшем случае (при вхождении почти всех объектов в один кластер).&lt;br /&gt;
&lt;br /&gt;
Если же такой методологии не существует, то узким местом становится процесс распределения на множества согласно вектору &amp;lt;math&amp;gt;index&amp;lt;/math&amp;gt;, который можно выполнить за &amp;lt;math&amp;gt; n &amp;lt;/math&amp;gt; операций косвенных адресаций. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;4)&#039;&#039;&#039; Все сравнения для критерия останова также независимы между собой и могут быть выполнены за одну операцию сравнения, а финальный результат может быть получен за одну операцию сложения при работе над общей памятью (к примеру, прибавление единицы при несовпадении в общую память и сравнение ее с 0 по завершению) или за &amp;lt;math&amp;gt;\log(k*d)&amp;lt;/math&amp;gt; сложений иначе.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Так как количество итераций ограничено константой, то на сложность оно не влияет. В итоге, параллельная сложность алгоритма k-means такова:&lt;br /&gt;
* &amp;lt;math&amp;gt; O(\log(n*d)) &amp;lt;/math&amp;gt; операций сложения&lt;br /&gt;
* &amp;lt;math&amp;gt; O(\log(k)) &amp;lt;/math&amp;gt; операций сравнения&lt;br /&gt;
* &amp;lt;math&amp;gt; O(1) &amp;lt;/math&amp;gt; операций умножения и деления&lt;br /&gt;
&lt;br /&gt;
== Входные и выходные данные алгоритма ==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Входные данные&#039;&#039;&#039;: Количество кластеров &amp;lt;b&amp;gt;k&amp;lt;/b&amp;gt;, &amp;lt;b&amp;gt;n&amp;lt;/b&amp;gt; кластеризуемых элементов&lt;br /&gt;
&lt;br /&gt;
Дополнительные ограничения:&lt;br /&gt;
* &amp;lt;b&amp;gt;k&amp;lt;/b&amp;gt; — положительное число, т. е. &amp;lt;b&amp;gt;k &amp;gt; 0&amp;lt;/b&amp;gt;.&lt;br /&gt;
* Для кластеризуемых элементов определена метрика (расстояние между объектами)&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Объём входных данных&#039;&#039;&#039;: &amp;lt;b&amp;gt;n &amp;lt;math&amp;gt;\cdot&amp;lt;/math&amp;gt; d + 1&amp;lt;/b&amp;gt; (кластеризуемые объекты в виде векторов и число &amp;lt;b&amp;gt;k&amp;lt;/b&amp;gt;)&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Выходные данные&#039;&#039;&#039;: Массив, в который записаны принадлежности каждого элемента кластеру (допустим вывод в другой эквивалентной более удобной структуре).&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Объём выходных данных&#039;&#039;&#039;:  Размер массива равен &amp;lt;b&amp;gt;2 &amp;lt;math&amp;gt;\cdot&amp;lt;/math&amp;gt; n&amp;lt;/b&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Свойства алгоритма ==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Ограничения алгоритма&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Алгоритм эффективно работает только на небольших объемах данных.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Преимущества алгоритма&#039;&#039;&#039;&lt;br /&gt;
* Простота использования&lt;br /&gt;
* Быстрота использования&lt;br /&gt;
* Понятность и прозрачность описания&lt;br /&gt;
* Обладает вычислительной устойчивостью&lt;br /&gt;
* Предрасположенность к распараллеливанию&lt;br /&gt;
* Достаточно популярный, поэтому имеет множество реализаций и вариаций&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Недостатки алгоритма&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
* Нет проверки корректности выбора числа кластеров&lt;br /&gt;
* Алгоритм чувствителен к количеству кластеров&lt;br /&gt;
* Алгоритм чувствителен к выбору начальных элементов в качестве центроидов &lt;br /&gt;
* Алгоритм крайне чувствителен к выбросам по данным&lt;br /&gt;
* Медленная работа на больших объемах данных&lt;br /&gt;
&lt;br /&gt;
= ЧАСТЬ. Программная реализация алгоритма =&lt;br /&gt;
&lt;br /&gt;
== Масштабируемость алгоритма и его реализации ==&lt;br /&gt;
&lt;br /&gt;
== Существующие реализации алгоритма ==&lt;br /&gt;
&lt;br /&gt;
=== Бесплатный доступ ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Десктопные программы&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
* [http://www.cs.waikato.ac.nz/ml/weka/ Weka]&lt;br /&gt;
* [http://docs.orange.biolab.si/2/reference/rst/Orange.clustering.kmeans.html Orange]&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Фреймворки для языков&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;Python:&#039;&#039;&#039;&lt;br /&gt;
** [http://scikit-learn.org/ scikit-learn]&lt;br /&gt;
** [https://www.scipy.org/ SciPy]&lt;br /&gt;
* &#039;&#039;&#039;C++:&#039;&#039;&#039;&lt;br /&gt;
** [http://mlpack.org/ MLPACK]&lt;br /&gt;
** [http://docs.opencv.org/3.0-beta/doc/py_tutorials/py_ml/py_kmeans/py_kmeans_opencv/py_kmeans_opencv.html OpenCV]&lt;br /&gt;
** [https://www.gnu.org/software/octave/ Octave] &lt;br /&gt;
* &#039;&#039;&#039;C#:&#039;&#039;&#039;  &lt;br /&gt;
** [http://accord-framework.net/docs/html/T_Accord_MachineLearning_KMeans.htm Accord.NET]&lt;br /&gt;
* &#039;&#039;&#039;Java:&#039;&#039;&#039;&lt;br /&gt;
** [http://elki.dbs.ifi.lmu.de ELKI]&lt;br /&gt;
** [https://mahout.apache.org Mahout]&lt;br /&gt;
* &#039;&#039;&#039;Lua&#039;&#039;&#039;&lt;br /&gt;
** [http://torch.ch Torch]&lt;br /&gt;
&lt;br /&gt;
Языки [https://www.r-bloggers.com/k-means-clustering-in-r/ R] и [http://juliastats.github.io Julia] содержат алгоритм k-means в базовой реализации.&lt;br /&gt;
&lt;br /&gt;
=== Платный доступ/лицензия  ===&lt;br /&gt;
&lt;br /&gt;
Существует целый перечень мощных статистических и математических пакетов для разных ОС:&lt;br /&gt;
* [http://www.mathworks.com/help/stats/kmeans.html?requestedDomain=www.mathworks.com MATLAB]&lt;br /&gt;
* [http://mathworld.wolfram.com/K-MeansClusteringAlgorithm.html Mathematica]&lt;br /&gt;
* [http://www.stata.com/features/cluster-analysis/ Stata]&lt;br /&gt;
* [https://support.sas.com/rnd/app/stat/procedures/fastclus.html SAS]&lt;br /&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]&lt;br /&gt;
* [http://docs.rapidminer.com/studio/operators/modeling/segmentation/k_means.html RapidMiner]&lt;br /&gt;
* ...&lt;br /&gt;
&lt;br /&gt;
= Литература =&lt;br /&gt;
[1] Нейский И.М. Классификация и сравнение методов кластеризации http://it-claim.ru/Persons/Neyskiy/Article2_Neiskiy.pdf&lt;br /&gt;
&lt;br /&gt;
[2] https://ru.wikipedia.org/wiki/K-means&lt;br /&gt;
&lt;br /&gt;
[[en:Description of algorithm properties and structure]]&lt;/div&gt;</summary>
		<author><name>Богомазов Евгений</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%98%D0%BB%D1%8C%D1%8F_%D0%95%D0%B3%D0%BE%D1%80%D0%BE%D0%B2/%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_k-%D1%81%D1%80%D0%B5%D0%B4%D0%BD%D0%B8%D1%85&amp;diff=12033</id>
		<title>Участник:Илья Егоров/Алгоритм k-средних</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%98%D0%BB%D1%8C%D1%8F_%D0%95%D0%B3%D0%BE%D1%80%D0%BE%D0%B2/%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_k-%D1%81%D1%80%D0%B5%D0%B4%D0%BD%D0%B8%D1%85&amp;diff=12033"/>
		<updated>2016-10-15T20:56:15Z</updated>

		<summary type="html">&lt;p&gt;Богомазов Евгений: /* Информационный граф */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{algorithm&lt;br /&gt;
| name              = Алгоритм k-средних (k-means)&lt;br /&gt;
| serial_complexity = &amp;lt;math&amp;gt;O(n*k*d)&amp;lt;/math&amp;gt;&lt;br /&gt;
| input_data        = &amp;lt;math&amp;gt;n*d&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;quot;Илья Егоров — Евгений Богомазов&amp;quot;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
= ЧАСТЬ. Свойства и структура алгоритмов =&lt;br /&gt;
== Общее описание алгоритма ==&lt;br /&gt;
&lt;br /&gt;
Алгоритм кластеризации k-средних впервые был предложен в 1950-х годах математиками Гуго Штейнгаузом и Стюартом Ллойдом независимо друг от друга. Наибольшую популярность он получил после работы Маккуина.&lt;br /&gt;
&lt;br /&gt;
Алгоритм позволяет при заданном числе &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; построить &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластеров, расположенных на максимальном расстоянии друг от друга. Таким образом, наибольшей точности результат выполнения алгоритма достигает при полной осведомленности Пользователя о характере кластеризуемых объектов и, как следствие, при обладании максимально корректной информацией о числе кластеров.&lt;br /&gt;
&lt;br /&gt;
В общем случае выбор числа &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; может базироваться на любых значимых факторах, в том числе на результатах предшествующих исследований, теоретических соображениях или интуиции. &lt;br /&gt;
&lt;br /&gt;
== Математическое описание алгоритма ==&lt;br /&gt;
&#039;&#039;&#039;Исходные данные:&#039;&#039;&#039;&lt;br /&gt;
* Совокупность &amp;lt;b&amp;gt;n&amp;lt;/b&amp;gt; &amp;lt;b&amp;gt;d&amp;lt;/b&amp;gt;-мерных векторов &amp;lt;math&amp;gt; X = \{x_1 \dots x_n\} , &amp;lt;/math&amp;gt; где  &amp;lt;math&amp;gt; x_i = \{x_{i1} \dots x_{id}\} &amp;lt;/math&amp;gt;&lt;br /&gt;
* Предполагаемое количество кластеров &amp;lt;b&amp;gt;k&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Выходные данные:&#039;&#039;&#039;&lt;br /&gt;
* Разбиение X на множество &amp;lt;math&amp;gt; S = \{S_1 \dots S_k \}, \bigcup S_i = X, S_i \cap S_j = \emptyset, i \neq j &amp;lt;/math&amp;gt;&lt;br /&gt;
* k центров кластеров &amp;lt;math&amp;gt; \Mu = \{\mu_1 \dots \mu_k \} &amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt; \mu_i = \{\mu_{i1} \dots \mu_{id} \} &amp;lt;/math&amp;gt; такие, что&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; \begin{cases}\tilde{\mu_i} = \underset{y}{argmin } \sum_{x \in S_i} ||x-y||^2_E \\ \Mu = \underset{\tilde{\Mu}}{argmin } \sum_{i \in k} \sum_{x \in S_i} ||x-\tilde{\mu_i}||^2_E \end{cases} &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Алгоритм:&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
1) &amp;lt;math&amp;gt; \mu_{i} = random &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
2) &amp;lt;math&amp;gt; S_i = \{x \in S | \underset{j}{argmin } ||x-\mu_j||_E = i\} i = 1 \dots k &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
3) &amp;lt;math&amp;gt; \tilde{\mu_{i}} = E_{x \in S_i}(x) &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
4) Если для &amp;lt;math&amp;gt; \forall i:  \mu_i = \tilde{\mu_i} &amp;lt;/math&amp;gt; то алгоритм завершен, иначе &amp;lt;math&amp;gt; \mu_i = \tilde{\mu_i} &amp;lt;/math&amp;gt; и перейти на пункт 2)&lt;br /&gt;
&lt;br /&gt;
== Вычислительное ядро алгоритма ==&lt;br /&gt;
&lt;br /&gt;
Вычислительным ядром алгоритма является второй этап, а точнее нахождение матрицы расстояний между &amp;lt;math&amp;gt;X&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\Mu&amp;lt;/math&amp;gt;. Для &#039;&#039;&#039;d&#039;&#039;&#039;-мерного вектора &amp;lt;math&amp;gt;a:&amp;lt;/math&amp;gt; &lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;||a||=\sqrt{\sum_{i=1\dots d} a_i^2}&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; операций сложения и одну операция вычисления квадратного корня. Но так как эти расстояния используются только для сравнения, а &#039;&#039;sqrt&#039;&#039; является монотонно возрастающей функцией, то ее можно не вычислять. Поэтому нахождения матрицы расстояний потребует всего &amp;lt;math&amp;gt;n*k*d&amp;lt;/math&amp;gt; операций умножений и &amp;lt;math&amp;gt;n*k*(d-1)&amp;lt;/math&amp;gt; операций сложений.&lt;br /&gt;
&lt;br /&gt;
== Макроструктура алгоритма ==&lt;br /&gt;
&lt;br /&gt;
В алгоритме можно выделить следующие макрооперации: &lt;br /&gt;
*&#039;&#039;&#039;Вычисление расстояния между векторами&#039;&#039;&#039;,&lt;br /&gt;
*&#039;&#039;&#039;Суммирование векторов&#039;&#039;&#039;,&lt;br /&gt;
*&#039;&#039;&#039;Поиск минимума в векторе&#039;&#039;&#039;,&lt;br /&gt;
*&#039;&#039;&#039;Сравнение векторов&#039;&#039;&#039;,&lt;br /&gt;
*&#039;&#039;&#039;Деление вектора на скаляр&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;1)&#039;&#039;&#039; На шаге инициализации центроидов в общем случае (случайный выбор элементов) макроопераций не производится. Но так как правило определения количества кластеров &#039;&#039;&#039;k&#039;&#039;&#039; неоднозначно, то для некоторых вариантов макрооперации могут понадобиться. К примеру, существует класс стратегий поиска &#039;&#039;&#039;k&#039;&#039;&#039;, которые базируются на определении центра масс всех объектов, и для которых будут дополнительно выполняться макрооперации &#039;&#039;&#039;&amp;quot;Суммирование векторов&amp;quot;&#039;&#039;&#039; и &#039;&#039;&#039;&amp;quot;Деление вектора на скаляр&amp;quot;&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;2a)&#039;&#039;&#039; При составлении матрицы расстояний &#039;&#039;&#039; k &amp;lt;math&amp;gt; \cdot &amp;lt;/math&amp;gt;  n&#039;&#039;&#039; раз производится макрооперация &#039;&#039;&#039;&amp;quot;Вычисление расстояния между векторами&amp;quot;&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;2b)&#039;&#039;&#039; При нахождение вектора распределения объектов по кластерам &#039;&#039;&#039;n&#039;&#039;&#039; раз производится макрооперация &#039;&#039;&#039;&amp;quot;Поиск минимума в векторе&amp;quot;&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;3)&#039;&#039;&#039; При пересчете центроидов &#039;&#039;&#039;n - k&#039;&#039;&#039; раз производится макрооперация &#039;&#039;&#039;&amp;quot;Суммирование векторов&amp;quot;&#039;&#039;&#039; и &#039;&#039;&#039;k&#039;&#039;&#039; раз - &#039;&#039;&#039;&amp;quot;Деление вектора на скаляр&amp;quot;&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;4)&#039;&#039;&#039; Для проверки критерия останова требуется &#039;&#039;&#039;k&#039;&#039;&#039; раз произвести макрооперацию &#039;&#039;&#039;&amp;quot;Сравнение векторов&amp;quot;&#039;&#039;&#039; для сопоставления обновленных значений центроидов с уже имеющимися.&lt;br /&gt;
&lt;br /&gt;
== Схема реализации последовательного алгоритма ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Последовательность шагов алгоритма следующая:&lt;br /&gt;
&lt;br /&gt;
    &#039;&#039;&#039;1) Инициализация центроидов &amp;lt;math&amp;gt;\Mu&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt; iter = 1 &amp;lt;/math&amp;gt;, задание максимального количество итераций &amp;lt;math&amp;gt;maxiter&amp;lt;/math&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
        &lt;br /&gt;
    &#039;&#039;&#039;2a) Нахождение матрицы расстояний &#039;&#039;&#039;&amp;lt;math&amp;gt;dist:&amp;lt;/math&amp;gt;&lt;br /&gt;
    &lt;br /&gt;
        &amp;lt;math&amp;gt;dist_{ij} = \sum_{l = 1\dots d} (x_{il}-\mu_{jl})^2&amp;lt;/math&amp;gt;&lt;br /&gt;
        &lt;br /&gt;
    &#039;&#039;&#039;2b) Нахождение вектора распределения объектов по кластерам &#039;&#039;&#039;&amp;lt;math&amp;gt;index: &amp;lt;/math&amp;gt;&lt;br /&gt;
    &lt;br /&gt;
        &amp;lt;math&amp;gt;index_{i} =   \underset{j}{argmin }~dist_{ij} &amp;lt;/math&amp;gt;&lt;br /&gt;
    &lt;br /&gt;
    &#039;&#039;&#039;3) Пересчет центроидов &#039;&#039;&#039;&amp;lt;math&amp;gt;\tilde{\Mu}:&amp;lt;/math&amp;gt;&lt;br /&gt;
    &lt;br /&gt;
        &amp;lt;math&amp;gt;\tilde{\mu_{ij}} = \sum_{l \in S_i} \dfrac{x_{lj}}{|S_i|} &amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;S_i = \{l~|~l \in 1\dots n, index_l = i\}  &amp;lt;/math&amp;gt;&lt;br /&gt;
    &lt;br /&gt;
    &#039;&#039;&#039;4) Проверка критерия останова:&#039;&#039;&#039;&lt;br /&gt;
    &lt;br /&gt;
        &#039;&#039;&#039;Если&#039;&#039;&#039; &amp;lt;math&amp;gt; \exists i: \tilde{\mu_i} \neq \mu_i&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt; iter &amp;lt; maxiter &amp;lt;/math&amp;gt;,&lt;br /&gt;
    &lt;br /&gt;
        &#039;&#039;&#039;то&#039;&#039;&#039; &amp;lt;math&amp;gt; inc(iter), \Mu=\tilde{\Mu},&amp;lt;/math&amp;gt; &#039;&#039;&#039;GOTO 2.а.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
== Последовательная сложность алгоритма ==&lt;br /&gt;
&lt;br /&gt;
    &#039;&#039;&#039;1)&#039;&#039;&#039; Сложность инициализации в общем случае зависит от применяемого метода генерации/получения случайных чисел, но ей можно пренебречь&lt;br /&gt;
    &lt;br /&gt;
    &#039;&#039;&#039;2a)&#039;&#039;&#039; Вычисление матрицы расстояний требует &amp;lt;math&amp;gt; n*k*d &amp;lt;/math&amp;gt; операций умножения и &amp;lt;math&amp;gt; n*k*(d-1) &amp;lt;/math&amp;gt; операций сложения&lt;br /&gt;
    &lt;br /&gt;
    &#039;&#039;&#039;2b)&#039;&#039;&#039; Нахождение вектора распределения требует &amp;lt;math&amp;gt; n*(k-1) &amp;lt;/math&amp;gt; операций сравнения&lt;br /&gt;
    &lt;br /&gt;
    &#039;&#039;&#039;3)&#039;&#039;&#039; Для вычисления &amp;lt;math&amp;gt; \tilde{\Mu} &amp;lt;/math&amp;gt; требуется &amp;lt;math&amp;gt; (n - k + 1) * d &amp;lt;/math&amp;gt; операций сложения и &amp;lt;math&amp;gt; k * d &amp;lt;/math&amp;gt; операций деления&lt;br /&gt;
    &lt;br /&gt;
    &#039;&#039;&#039;4)&#039;&#039;&#039; Для критерия останова требуется &amp;lt;math&amp;gt; n*d &amp;lt;/math&amp;gt; сравнений&lt;br /&gt;
&lt;br /&gt;
Итого: так как максимальное количество итераций задается в алгоритме заранее и не зависит от входных данных, то количество итераций ограничено константой. Тогда сложность алгоритма:&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;math&amp;gt; O(n*k*d)&amp;lt;/math&amp;gt; операций сложения/вычитания&lt;br /&gt;
* &amp;lt;math&amp;gt; O(n*k*d)&amp;lt;/math&amp;gt; операций умножения, &amp;lt;math&amp;gt; O(k*d) &amp;lt;/math&amp;gt; операций деления&lt;br /&gt;
&lt;br /&gt;
== Информационный граф ==&lt;br /&gt;
&lt;br /&gt;
Рассмотрим вычислительные этапы алгоритма k-means. Это распределение объектов по кластерам и перерасчет центроидов.&lt;br /&gt;
&lt;br /&gt;
Распределение объектов по кластерам состоит из нахождения матрицы расстояний между &amp;lt;math&amp;gt;X&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\Mu&amp;lt;/math&amp;gt; (этапа &#039;&#039;&#039;2a)&#039;&#039;&#039;) и нахождения индекса минимального элемента в каждой строке (этап &#039;&#039;&#039;2b)&#039;&#039;&#039;). Ниже приведен информационный граф данного этапа.&lt;br /&gt;
&lt;br /&gt;
[[Файл:EgorovBogomazovInf.png |800px|thumb|center|Нахождение вектора индексов распределения по кластерам]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Рассмотрим этап вычисления ячейки &amp;lt;math&amp;gt; dist_{ij} &amp;lt;/math&amp;gt; матрицы более подробно. Он представляет из себя скалярное произведение d-мерных векторов &amp;lt;math&amp;gt; x_i &amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt; \mu_j &amp;lt;/math&amp;gt;. Ниже приведена граф для данной операции.&lt;br /&gt;
&lt;br /&gt;
[[Файл:EgorovBogomazovDist.png|600px|thumb|center|Операция вычисления расстояния]]&lt;br /&gt;
&lt;br /&gt;
На этапе &#039;&#039;&#039;3)&#039;&#039;&#039; происходит суммирование всех &amp;lt;math&amp;gt; x_l &amp;lt;/math&amp;gt; с одинаковым значением индекса в промежуточные суммы. Одновременно происходит подсчет количество элементов с фиксированным индексом. Затем происходит деление промежуточных сумм на соответствующее количество элементов в новом кластере, благодаря чему удается получить обновленные центроиды &amp;lt;math&amp;gt; \tilde{\mu}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[Файл:EgorovBogomazovNewCluster.png|800px|thumb|center|Обновление центроидов]]&lt;br /&gt;
&lt;br /&gt;
== Ресурс параллелизма алгоритма ==&lt;br /&gt;
&lt;br /&gt;
Для получения общей картины достаточно определить, в том числе и с помощью информационного графа, каким ресурсом параллелизма обладает каждый из этапов алгоритма:&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;2a)&#039;&#039;&#039; Нахождение каждой ячейки матрицы &amp;lt;math&amp;gt; dist &amp;lt;/math&amp;gt; может происходить полностью независимо, так как они находятся на одном ярусе. При рассмотрении операции вычисления значения конкретной ячейки &amp;lt;math&amp;gt; dist_{ij} &amp;lt;/math&amp;gt; можно заметить, что все операции умножения также независимы между собой, поэтому понадобится всего одно умножение. Конечный результат получается в результате суммирования всех слагаемых и достигается параллельно за &amp;lt;math&amp;gt; \log(d) &amp;lt;/math&amp;gt; бинарных операций сложения при помощи стандартного метода &#039;&#039;reduction&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;2b)&#039;&#039;&#039; Нахождение вектора распределений заключается в нахождении минимального элемента в каждой строке матрицы &amp;lt;math&amp;gt; dist &amp;lt;/math&amp;gt;. При использовании &#039;&#039;reduction&#039;&#039; эту операцию можно выполнить за &amp;lt;math&amp;gt; \log(k) &amp;lt;/math&amp;gt; бинарных операций сравнения.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;3)&#039;&#039;&#039; В случае, если существует методология быстрого разделения &#039;&#039;&#039;n&#039;&#039;&#039; объектов на &#039;&#039;&#039;k&#039;&#039;&#039; множеств при помощи вектора индексации (косвенной адресации), все &amp;lt;math&amp;gt; \tilde{S_i} &amp;lt;/math&amp;gt; могут быть обработаны параллельно. В рамках каждого отдельного &amp;lt;math&amp;gt; \tilde{S_i} &amp;lt;/math&amp;gt; можно проводить распараллеливание дальше, так как &amp;lt;math&amp;gt; x_{lj} &amp;lt;/math&amp;gt; также не зависят друг от друга. Таким образом, вычисление всех слагаемых для всех &amp;lt;math&amp;gt; \tilde{\mu_{ij}} &amp;lt;/math&amp;gt; может быть выполнено за одно параллельное деление, а нахождение суммы всех этих слагаемых для каждого &amp;lt;math&amp;gt; \tilde{\mu_{ij}} &amp;lt;/math&amp;gt; может быть выполнено за &amp;lt;math&amp;gt; O(log(n)) &amp;lt;/math&amp;gt; в худшем случае (при вхождении почти всех объектов в один кластер).&lt;br /&gt;
&lt;br /&gt;
Если же такой методологии не существует, то узким местом становится процесс распределения на множества согласно вектору &amp;lt;math&amp;gt;index&amp;lt;/math&amp;gt;, который можно выполнить за &amp;lt;math&amp;gt; n &amp;lt;/math&amp;gt; операций косвенных адресаций. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;4)&#039;&#039;&#039; Все сравнения для критерия останова также независимы между собой и могут быть выполнены за одну операцию сравнения, а финальный результат может быть получен за одну операцию сложения при работе над общей памятью (к примеру, прибавление единицы при несовпадении в общую память и сравнение ее с 0 по завершению) или за &amp;lt;math&amp;gt;\log(k*d)&amp;lt;/math&amp;gt; сложений иначе.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Так как количество итераций ограничено константой, то на сложность оно не влияет. В итоге, параллельная сложность алгоритма k-means такова:&lt;br /&gt;
* &amp;lt;math&amp;gt; O(\log(n*d)) &amp;lt;/math&amp;gt; операций сложения&lt;br /&gt;
* &amp;lt;math&amp;gt; O(\log(k)) &amp;lt;/math&amp;gt; операций сравнения&lt;br /&gt;
* &amp;lt;math&amp;gt; O(1) &amp;lt;/math&amp;gt; операций умножения и деления&lt;br /&gt;
&lt;br /&gt;
== Входные и выходные данные алгоритма ==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Входные данные&#039;&#039;&#039;: Количество кластеров &amp;lt;b&amp;gt;k&amp;lt;/b&amp;gt;, &amp;lt;b&amp;gt;n&amp;lt;/b&amp;gt; кластеризуемых элементов&lt;br /&gt;
&lt;br /&gt;
Дополнительные ограничения:&lt;br /&gt;
* &amp;lt;b&amp;gt;k&amp;lt;/b&amp;gt; — положительное число, т. е. &amp;lt;b&amp;gt;k &amp;gt; 0&amp;lt;/b&amp;gt;.&lt;br /&gt;
* Для кластеризуемых элементов определена метрика (расстояние между объектами)&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Объём входных данных&#039;&#039;&#039;: &amp;lt;b&amp;gt;n &amp;lt;math&amp;gt;\cdot&amp;lt;/math&amp;gt; d + 1&amp;lt;/b&amp;gt; (кластеризуемые объекты в виде векторов и число &amp;lt;b&amp;gt;k&amp;lt;/b&amp;gt;)&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Выходные данные&#039;&#039;&#039;: Массив, в который записаны принадлежности каждого элемента кластеру (допустим вывод в другой эквивалентной более удобной структуре).&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Объём выходных данных&#039;&#039;&#039;:  Размер массива равен &amp;lt;b&amp;gt;2 &amp;lt;math&amp;gt;\cdot&amp;lt;/math&amp;gt; n&amp;lt;/b&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Свойства алгоритма ==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Ограничения алгоритма&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Алгоритм эффективно работает только на небольших объемах данных.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Преимущества алгоритма&#039;&#039;&#039;&lt;br /&gt;
* Простота использования&lt;br /&gt;
* Быстрота использования&lt;br /&gt;
* Понятность и прозрачность описания&lt;br /&gt;
* Обладает вычислительной устойчивостью&lt;br /&gt;
* Предрасположенность к распараллеливанию&lt;br /&gt;
* Достаточно популярный, поэтому имеет множество реализаций и вариаций&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Недостатки алгоритма&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
* Нет проверки корректности выбора числа кластеров&lt;br /&gt;
* Алгоритм чувствителен к количеству кластеров&lt;br /&gt;
* Алгоритм чувствителен к выбору начальных элементов в качестве центроидов &lt;br /&gt;
* Алгоритм крайне чувствителен к выбросам по данным&lt;br /&gt;
* Медленная работа на больших объемах данных&lt;br /&gt;
&lt;br /&gt;
= ЧАСТЬ. Программная реализация алгоритма =&lt;br /&gt;
&lt;br /&gt;
== Масштабируемость алгоритма и его реализации ==&lt;br /&gt;
&lt;br /&gt;
== Существующие реализации алгоритма ==&lt;br /&gt;
&lt;br /&gt;
=== Бесплатный доступ ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Десктопные программы&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
* [http://www.cs.waikato.ac.nz/ml/weka/ Weka]&lt;br /&gt;
* [http://docs.orange.biolab.si/2/reference/rst/Orange.clustering.kmeans.html Orange]&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Фреймворки для языков&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;Python:&#039;&#039;&#039;&lt;br /&gt;
** [http://scikit-learn.org/ scikit-learn]&lt;br /&gt;
** [https://www.scipy.org/ SciPy]&lt;br /&gt;
* &#039;&#039;&#039;C++:&#039;&#039;&#039;&lt;br /&gt;
** [http://mlpack.org/ MLPACK]&lt;br /&gt;
** [http://docs.opencv.org/3.0-beta/doc/py_tutorials/py_ml/py_kmeans/py_kmeans_opencv/py_kmeans_opencv.html OpenCV]&lt;br /&gt;
** [https://www.gnu.org/software/octave/ Octave] &lt;br /&gt;
* &#039;&#039;&#039;C#:&#039;&#039;&#039;  &lt;br /&gt;
** [http://accord-framework.net/docs/html/T_Accord_MachineLearning_KMeans.htm Accord.NET]&lt;br /&gt;
* &#039;&#039;&#039;Java:&#039;&#039;&#039;&lt;br /&gt;
** [http://elki.dbs.ifi.lmu.de ELKI]&lt;br /&gt;
** [https://mahout.apache.org Mahout]&lt;br /&gt;
* &#039;&#039;&#039;Lua&#039;&#039;&#039;&lt;br /&gt;
** [http://torch.ch Torch]&lt;br /&gt;
&lt;br /&gt;
Языки [https://www.r-bloggers.com/k-means-clustering-in-r/ R] и [http://juliastats.github.io Julia] содержат алгоритм k-means в базовой реализации.&lt;br /&gt;
&lt;br /&gt;
=== Платный доступ/лицензия  ===&lt;br /&gt;
&lt;br /&gt;
Существует целый перечень мощных статистических и математических пакетов для разных ОС:&lt;br /&gt;
* [http://www.mathworks.com/help/stats/kmeans.html?requestedDomain=www.mathworks.com MATLAB]&lt;br /&gt;
* [http://mathworld.wolfram.com/K-MeansClusteringAlgorithm.html Mathematica]&lt;br /&gt;
* [http://www.stata.com/features/cluster-analysis/ Stata]&lt;br /&gt;
* [https://support.sas.com/rnd/app/stat/procedures/fastclus.html SAS]&lt;br /&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]&lt;br /&gt;
* [http://docs.rapidminer.com/studio/operators/modeling/segmentation/k_means.html RapidMiner]&lt;br /&gt;
* ...&lt;br /&gt;
&lt;br /&gt;
= Литература =&lt;br /&gt;
[1] Нейский И.М. Классификация и сравнение методов кластеризации http://it-claim.ru/Persons/Neyskiy/Article2_Neiskiy.pdf&lt;br /&gt;
&lt;br /&gt;
[2] https://ru.wikipedia.org/wiki/K-means&lt;br /&gt;
&lt;br /&gt;
[[en:Description of algorithm properties and structure]]&lt;/div&gt;</summary>
		<author><name>Богомазов Евгений</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%98%D0%BB%D1%8C%D1%8F_%D0%95%D0%B3%D0%BE%D1%80%D0%BE%D0%B2/%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_k-%D1%81%D1%80%D0%B5%D0%B4%D0%BD%D0%B8%D1%85&amp;diff=12010</id>
		<title>Участник:Илья Егоров/Алгоритм k-средних</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%98%D0%BB%D1%8C%D1%8F_%D0%95%D0%B3%D0%BE%D1%80%D0%BE%D0%B2/%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_k-%D1%81%D1%80%D0%B5%D0%B4%D0%BD%D0%B8%D1%85&amp;diff=12010"/>
		<updated>2016-10-15T20:54:13Z</updated>

		<summary type="html">&lt;p&gt;Богомазов Евгений: /* Информационный граф */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{algorithm&lt;br /&gt;
| name              = Алгоритм k-средних (k-means)&lt;br /&gt;
| serial_complexity = &amp;lt;math&amp;gt;O(n*k*d)&amp;lt;/math&amp;gt;&lt;br /&gt;
| input_data        = &amp;lt;math&amp;gt;n*d&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;quot;Илья Егоров — Евгений Богомазов&amp;quot;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
= ЧАСТЬ. Свойства и структура алгоритмов =&lt;br /&gt;
== Общее описание алгоритма ==&lt;br /&gt;
&lt;br /&gt;
Алгоритм кластеризации k-средних впервые был предложен в 1950-х годах математиками Гуго Штейнгаузом и Стюартом Ллойдом независимо друг от друга. Наибольшую популярность он получил после работы Маккуина.&lt;br /&gt;
&lt;br /&gt;
Алгоритм позволяет при заданном числе &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; построить &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластеров, расположенных на максимальном расстоянии друг от друга. Таким образом, наибольшей точности результат выполнения алгоритма достигает при полной осведомленности Пользователя о характере кластеризуемых объектов и, как следствие, при обладании максимально корректной информацией о числе кластеров.&lt;br /&gt;
&lt;br /&gt;
В общем случае выбор числа &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; может базироваться на любых значимых факторах, в том числе на результатах предшествующих исследований, теоретических соображениях или интуиции. &lt;br /&gt;
&lt;br /&gt;
== Математическое описание алгоритма ==&lt;br /&gt;
&#039;&#039;&#039;Исходные данные:&#039;&#039;&#039;&lt;br /&gt;
* Совокупность &amp;lt;b&amp;gt;n&amp;lt;/b&amp;gt; &amp;lt;b&amp;gt;d&amp;lt;/b&amp;gt;-мерных векторов &amp;lt;math&amp;gt; X = \{x_1 \dots x_n\} , &amp;lt;/math&amp;gt; где  &amp;lt;math&amp;gt; x_i = \{x_{i1} \dots x_{id}\} &amp;lt;/math&amp;gt;&lt;br /&gt;
* Предполагаемое количество кластеров &amp;lt;b&amp;gt;k&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Выходные данные:&#039;&#039;&#039;&lt;br /&gt;
* Разбиение X на множество &amp;lt;math&amp;gt; S = \{S_1 \dots S_k \}, \bigcup S_i = X, S_i \cap S_j = \emptyset, i \neq j &amp;lt;/math&amp;gt;&lt;br /&gt;
* k центров кластеров &amp;lt;math&amp;gt; \Mu = \{\mu_1 \dots \mu_k \} &amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt; \mu_i = \{\mu_{i1} \dots \mu_{id} \} &amp;lt;/math&amp;gt; такие, что&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; \begin{cases}\tilde{\mu_i} = \underset{y}{argmin } \sum_{x \in S_i} ||x-y||^2_E \\ \Mu = \underset{\tilde{\Mu}}{argmin } \sum_{i \in k} \sum_{x \in S_i} ||x-\tilde{\mu_i}||^2_E \end{cases} &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Алгоритм:&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
1) &amp;lt;math&amp;gt; \mu_{i} = random &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
2) &amp;lt;math&amp;gt; S_i = \{x \in S | \underset{j}{argmin } ||x-\mu_j||_E = i\} i = 1 \dots k &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
3) &amp;lt;math&amp;gt; \tilde{\mu_{i}} = E_{x \in S_i}(x) &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
4) Если для &amp;lt;math&amp;gt; \forall i:  \mu_i = \tilde{\mu_i} &amp;lt;/math&amp;gt; то алгоритм завершен, иначе &amp;lt;math&amp;gt; \mu_i = \tilde{\mu_i} &amp;lt;/math&amp;gt; и перейти на пункт 2)&lt;br /&gt;
&lt;br /&gt;
== Вычислительное ядро алгоритма ==&lt;br /&gt;
&lt;br /&gt;
Вычислительным ядром алгоритма является второй этап, а точнее нахождение матрицы расстояний между &amp;lt;math&amp;gt;X&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\Mu&amp;lt;/math&amp;gt;. Для &#039;&#039;&#039;d&#039;&#039;&#039;-мерного вектора &amp;lt;math&amp;gt;a:&amp;lt;/math&amp;gt; &lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;||a||=\sqrt{\sum_{i=1\dots d} a_i^2}&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; операций сложения и одну операция вычисления квадратного корня. Но так как эти расстояния используются только для сравнения, а &#039;&#039;sqrt&#039;&#039; является монотонно возрастающей функцией, то ее можно не вычислять. Поэтому нахождения матрицы расстояний потребует всего &amp;lt;math&amp;gt;n*k*d&amp;lt;/math&amp;gt; операций умножений и &amp;lt;math&amp;gt;n*k*(d-1)&amp;lt;/math&amp;gt; операций сложений.&lt;br /&gt;
&lt;br /&gt;
== Макроструктура алгоритма ==&lt;br /&gt;
&lt;br /&gt;
В алгоритме можно выделить следующие макрооперации: &lt;br /&gt;
*&#039;&#039;&#039;Вычисление расстояния между векторами&#039;&#039;&#039;,&lt;br /&gt;
*&#039;&#039;&#039;Суммирование векторов&#039;&#039;&#039;,&lt;br /&gt;
*&#039;&#039;&#039;Поиск минимума в векторе&#039;&#039;&#039;,&lt;br /&gt;
*&#039;&#039;&#039;Сравнение векторов&#039;&#039;&#039;,&lt;br /&gt;
*&#039;&#039;&#039;Деление вектора на скаляр&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;1)&#039;&#039;&#039; На шаге инициализации центроидов в общем случае (случайный выбор элементов) макроопераций не производится. Но так как правило определения количества кластеров &#039;&#039;&#039;k&#039;&#039;&#039; неоднозначно, то для некоторых вариантов макрооперации могут понадобиться. К примеру, существует класс стратегий поиска &#039;&#039;&#039;k&#039;&#039;&#039;, которые базируются на определении центра масс всех объектов, и для которых будут дополнительно выполняться макрооперации &#039;&#039;&#039;&amp;quot;Суммирование векторов&amp;quot;&#039;&#039;&#039; и &#039;&#039;&#039;&amp;quot;Деление вектора на скаляр&amp;quot;&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;2a)&#039;&#039;&#039; При составлении матрицы расстояний &#039;&#039;&#039; k &amp;lt;math&amp;gt; \cdot &amp;lt;/math&amp;gt;  n&#039;&#039;&#039; раз производится макрооперация &#039;&#039;&#039;&amp;quot;Вычисление расстояния между векторами&amp;quot;&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;2b)&#039;&#039;&#039; При нахождение вектора распределения объектов по кластерам &#039;&#039;&#039;n&#039;&#039;&#039; раз производится макрооперация &#039;&#039;&#039;&amp;quot;Поиск минимума в векторе&amp;quot;&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;3)&#039;&#039;&#039; При пересчете центроидов &#039;&#039;&#039;n - k&#039;&#039;&#039; раз производится макрооперация &#039;&#039;&#039;&amp;quot;Суммирование векторов&amp;quot;&#039;&#039;&#039; и &#039;&#039;&#039;k&#039;&#039;&#039; раз - &#039;&#039;&#039;&amp;quot;Деление вектора на скаляр&amp;quot;&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;4)&#039;&#039;&#039; Для проверки критерия останова требуется &#039;&#039;&#039;k&#039;&#039;&#039; раз произвести макрооперацию &#039;&#039;&#039;&amp;quot;Сравнение векторов&amp;quot;&#039;&#039;&#039; для сопоставления обновленных значений центроидов с уже имеющимися.&lt;br /&gt;
&lt;br /&gt;
== Схема реализации последовательного алгоритма ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Последовательность шагов алгоритма следующая:&lt;br /&gt;
&lt;br /&gt;
    &#039;&#039;&#039;1) Инициализация центроидов &amp;lt;math&amp;gt;\Mu&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt; iter = 1 &amp;lt;/math&amp;gt;, задание максимального количество итераций &amp;lt;math&amp;gt;maxiter&amp;lt;/math&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
        &lt;br /&gt;
    &#039;&#039;&#039;2a) Нахождение матрицы расстояний &#039;&#039;&#039;&amp;lt;math&amp;gt;dist:&amp;lt;/math&amp;gt;&lt;br /&gt;
    &lt;br /&gt;
        &amp;lt;math&amp;gt;dist_{ij} = \sum_{l = 1\dots d} (x_{il}-\mu_{jl})^2&amp;lt;/math&amp;gt;&lt;br /&gt;
        &lt;br /&gt;
    &#039;&#039;&#039;2b) Нахождение вектора распределения объектов по кластерам &#039;&#039;&#039;&amp;lt;math&amp;gt;index: &amp;lt;/math&amp;gt;&lt;br /&gt;
    &lt;br /&gt;
        &amp;lt;math&amp;gt;index_{i} =   \underset{j}{argmin }~dist_{ij} &amp;lt;/math&amp;gt;&lt;br /&gt;
    &lt;br /&gt;
    &#039;&#039;&#039;3) Пересчет центроидов &#039;&#039;&#039;&amp;lt;math&amp;gt;\tilde{\Mu}:&amp;lt;/math&amp;gt;&lt;br /&gt;
    &lt;br /&gt;
        &amp;lt;math&amp;gt;\tilde{\mu_{ij}} = \sum_{l \in S_i} \dfrac{x_{lj}}{|S_i|} &amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;S_i = \{l~|~l \in 1\dots n, index_l = i\}  &amp;lt;/math&amp;gt;&lt;br /&gt;
    &lt;br /&gt;
    &#039;&#039;&#039;4) Проверка критерия останова:&#039;&#039;&#039;&lt;br /&gt;
    &lt;br /&gt;
        &#039;&#039;&#039;Если&#039;&#039;&#039; &amp;lt;math&amp;gt; \exists i: \tilde{\mu_i} \neq \mu_i&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt; iter &amp;lt; maxiter &amp;lt;/math&amp;gt;,&lt;br /&gt;
    &lt;br /&gt;
        &#039;&#039;&#039;то&#039;&#039;&#039; &amp;lt;math&amp;gt; inc(iter), \Mu=\tilde{\Mu},&amp;lt;/math&amp;gt; &#039;&#039;&#039;GOTO 2.а.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
== Последовательная сложность алгоритма ==&lt;br /&gt;
&lt;br /&gt;
    &#039;&#039;&#039;1)&#039;&#039;&#039; Сложность инициализации в общем случае зависит от применяемого метода генерации/получения случайных чисел, но ей можно пренебречь&lt;br /&gt;
    &lt;br /&gt;
    &#039;&#039;&#039;2a)&#039;&#039;&#039; Вычисление матрицы расстояний требует &amp;lt;math&amp;gt; n*k*d &amp;lt;/math&amp;gt; операций умножения и &amp;lt;math&amp;gt; n*k*(d-1) &amp;lt;/math&amp;gt; операций сложения&lt;br /&gt;
    &lt;br /&gt;
    &#039;&#039;&#039;2b)&#039;&#039;&#039; Нахождение вектора распределения требует &amp;lt;math&amp;gt; n*(k-1) &amp;lt;/math&amp;gt; операций сравнения&lt;br /&gt;
    &lt;br /&gt;
    &#039;&#039;&#039;3)&#039;&#039;&#039; Для вычисления &amp;lt;math&amp;gt; \tilde{\Mu} &amp;lt;/math&amp;gt; требуется &amp;lt;math&amp;gt; (n - k + 1) * d &amp;lt;/math&amp;gt; операций сложения и &amp;lt;math&amp;gt; k * d &amp;lt;/math&amp;gt; операций деления&lt;br /&gt;
    &lt;br /&gt;
    &#039;&#039;&#039;4)&#039;&#039;&#039; Для критерия останова требуется &amp;lt;math&amp;gt; n*d &amp;lt;/math&amp;gt; сравнений&lt;br /&gt;
&lt;br /&gt;
Итого: так как максимальное количество итераций задается в алгоритме заранее и не зависит от входных данных, то количество итераций ограничено константой. Тогда сложность алгоритма:&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;math&amp;gt; O(n*k*d)&amp;lt;/math&amp;gt; операций сложения/вычитания&lt;br /&gt;
* &amp;lt;math&amp;gt; O(n*k*d)&amp;lt;/math&amp;gt; операций умножения, &amp;lt;math&amp;gt; O(k*d) &amp;lt;/math&amp;gt; операций деления&lt;br /&gt;
&lt;br /&gt;
== Информационный граф ==&lt;br /&gt;
&lt;br /&gt;
Рассмотрим вычислительные этапы алгоритма k-means. Это распределение объектов по кластерам и перерасчет центроидов.&lt;br /&gt;
&lt;br /&gt;
Распределение объектов по кластерам состоит из нахождения матрицы расстояний между &amp;lt;math&amp;gt;X&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\Mu&amp;lt;/math&amp;gt; (этапа 2a) и нахождения индекса минимального элемента в каждой строке (этап 2b). Ниже приведен информационный граф данного этапа.&lt;br /&gt;
&lt;br /&gt;
[[Файл:EgorovBogomazovInf.png |800px|thumb|center|Нахождение вектора индексов распределения по кластерам]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Рассмотрим этап вычисления ячейки &amp;lt;math&amp;gt; dist_{ij} &amp;lt;/math&amp;gt; матрицы более подробно. Он представляет из себя скалярное произведение d-мерных векторов &amp;lt;math&amp;gt; x_i &amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt; \mu_j &amp;lt;/math&amp;gt;. Ниже приведена граф для данной операции.&lt;br /&gt;
&lt;br /&gt;
[[Файл:EgorovBogomazovDist.png|600px|thumb|center|Операция вычисления расстояния]]&lt;br /&gt;
&lt;br /&gt;
На этапе 3) происходит суммирование всех &amp;lt;math&amp;gt; x_l &amp;lt;/math&amp;gt; с одинаковым значением индекса в промежуточные суммы. Одновременно происходит подсчет количество элементов с фиксированным индексом. Затем происходит деление промежуточных сумм на соответствующее количество элементов в новом кластере, благодаря чему удается получить обновленные центроиды &amp;lt;math&amp;gt; \tilde{\mu}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[Файл:EgorovBogomazovNewCluster.png|800px|thumb|center|Обновление центроидов]]&lt;br /&gt;
&lt;br /&gt;
== Ресурс параллелизма алгоритма ==&lt;br /&gt;
&lt;br /&gt;
Для получения общей картины достаточно определить, в том числе и с помощью информационного графа, каким ресурсом параллелизма обладает каждый из этапов алгоритма:&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;2a)&#039;&#039;&#039; Нахождение каждой ячейки матрицы &amp;lt;math&amp;gt; dist &amp;lt;/math&amp;gt; может происходить полностью независимо, так как они находятся на одном ярусе. При рассмотрении операции вычисления значения конкретной ячейки &amp;lt;math&amp;gt; dist_{ij} &amp;lt;/math&amp;gt; можно заметить, что все операции умножения также независимы между собой, поэтому понадобится всего одно умножение. Конечный результат получается в результате суммирования всех слагаемых и достигается параллельно за &amp;lt;math&amp;gt; \log(d) &amp;lt;/math&amp;gt; бинарных операций сложения при помощи стандартного метода &#039;&#039;reduction&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;2b)&#039;&#039;&#039; Нахождение вектора распределений заключается в нахождении минимального элемента в каждой строке матрицы &amp;lt;math&amp;gt; dist &amp;lt;/math&amp;gt;. При использовании &#039;&#039;reduction&#039;&#039; эту операцию можно выполнить за &amp;lt;math&amp;gt; \log(k) &amp;lt;/math&amp;gt; бинарных операций сравнения.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;3)&#039;&#039;&#039; В случае, если существует методология быстрого разделения &#039;&#039;&#039;n&#039;&#039;&#039; объектов на &#039;&#039;&#039;k&#039;&#039;&#039; множеств при помощи вектора индексации (косвенной адресации), все &amp;lt;math&amp;gt; \tilde{S_i} &amp;lt;/math&amp;gt; могут быть обработаны параллельно. В рамках каждого отдельного &amp;lt;math&amp;gt; \tilde{S_i} &amp;lt;/math&amp;gt; можно проводить распараллеливание дальше, так как &amp;lt;math&amp;gt; x_{lj} &amp;lt;/math&amp;gt; также не зависят друг от друга. Таким образом, вычисление всех слагаемых для всех &amp;lt;math&amp;gt; \tilde{\mu_{ij}} &amp;lt;/math&amp;gt; может быть выполнено за одно параллельное деление, а нахождение суммы всех этих слагаемых для каждого &amp;lt;math&amp;gt; \tilde{\mu_{ij}} &amp;lt;/math&amp;gt; может быть выполнено за &amp;lt;math&amp;gt; O(log(n)) &amp;lt;/math&amp;gt; в худшем случае (при вхождении почти всех объектов в один кластер).&lt;br /&gt;
&lt;br /&gt;
Если же такой методологии не существует, то узким местом становится процесс распределения на множества согласно вектору &amp;lt;math&amp;gt;index&amp;lt;/math&amp;gt;, который можно выполнить за &amp;lt;math&amp;gt; n &amp;lt;/math&amp;gt; операций косвенных адресаций. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;4)&#039;&#039;&#039; Все сравнения для критерия останова также независимы между собой и могут быть выполнены за одну операцию сравнения, а финальный результат может быть получен за одну операцию сложения при работе над общей памятью (к примеру, прибавление единицы при несовпадении в общую память и сравнение ее с 0 по завершению) или за &amp;lt;math&amp;gt;\log(k*d)&amp;lt;/math&amp;gt; сложений иначе.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Так как количество итераций ограничено константой, то на сложность оно не влияет. В итоге, параллельная сложность алгоритма k-means такова:&lt;br /&gt;
* &amp;lt;math&amp;gt; O(\log(n*d)) &amp;lt;/math&amp;gt; операций сложения&lt;br /&gt;
* &amp;lt;math&amp;gt; O(\log(k)) &amp;lt;/math&amp;gt; операций сравнения&lt;br /&gt;
* &amp;lt;math&amp;gt; O(1) &amp;lt;/math&amp;gt; операций умножения и деления&lt;br /&gt;
&lt;br /&gt;
== Входные и выходные данные алгоритма ==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Входные данные&#039;&#039;&#039;: Количество кластеров &amp;lt;b&amp;gt;k&amp;lt;/b&amp;gt;, &amp;lt;b&amp;gt;n&amp;lt;/b&amp;gt; кластеризуемых элементов&lt;br /&gt;
&lt;br /&gt;
Дополнительные ограничения:&lt;br /&gt;
* &amp;lt;b&amp;gt;k&amp;lt;/b&amp;gt; — положительное число, т. е. &amp;lt;b&amp;gt;k &amp;gt; 0&amp;lt;/b&amp;gt;.&lt;br /&gt;
* Для кластеризуемых элементов определена метрика (расстояние между объектами)&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Объём входных данных&#039;&#039;&#039;: &amp;lt;b&amp;gt;n &amp;lt;math&amp;gt;\cdot&amp;lt;/math&amp;gt; d + 1&amp;lt;/b&amp;gt; (кластеризуемые объекты в виде векторов и число &amp;lt;b&amp;gt;k&amp;lt;/b&amp;gt;)&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Выходные данные&#039;&#039;&#039;: Массив, в который записаны принадлежности каждого элемента кластеру (допустим вывод в другой эквивалентной более удобной структуре).&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Объём выходных данных&#039;&#039;&#039;:  Размер массива равен &amp;lt;b&amp;gt;2 &amp;lt;math&amp;gt;\cdot&amp;lt;/math&amp;gt; n&amp;lt;/b&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Свойства алгоритма ==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Ограничения алгоритма&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Алгоритм эффективно работает только на небольших объемах данных.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Преимущества алгоритма&#039;&#039;&#039;&lt;br /&gt;
* Простота использования&lt;br /&gt;
* Быстрота использования&lt;br /&gt;
* Понятность и прозрачность описания&lt;br /&gt;
* Обладает вычислительной устойчивостью&lt;br /&gt;
* Предрасположенность к распараллеливанию&lt;br /&gt;
* Достаточно популярный, поэтому имеет множество реализаций и вариаций&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Недостатки алгоритма&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
* Нет проверки корректности выбора числа кластеров&lt;br /&gt;
* Алгоритм чувствителен к количеству кластеров&lt;br /&gt;
* Алгоритм чувствителен к выбору начальных элементов в качестве центроидов &lt;br /&gt;
* Алгоритм крайне чувствителен к выбросам по данным&lt;br /&gt;
* Медленная работа на больших объемах данных&lt;br /&gt;
&lt;br /&gt;
= ЧАСТЬ. Программная реализация алгоритма =&lt;br /&gt;
&lt;br /&gt;
== Масштабируемость алгоритма и его реализации ==&lt;br /&gt;
&lt;br /&gt;
== Существующие реализации алгоритма ==&lt;br /&gt;
&lt;br /&gt;
=== Бесплатный доступ ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Десктопные программы&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
* [http://www.cs.waikato.ac.nz/ml/weka/ Weka]&lt;br /&gt;
* [http://docs.orange.biolab.si/2/reference/rst/Orange.clustering.kmeans.html Orange]&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Фреймворки для языков&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;Python:&#039;&#039;&#039;&lt;br /&gt;
** [http://scikit-learn.org/ scikit-learn]&lt;br /&gt;
** [https://www.scipy.org/ SciPy]&lt;br /&gt;
* &#039;&#039;&#039;C++:&#039;&#039;&#039;&lt;br /&gt;
** [http://mlpack.org/ MLPACK]&lt;br /&gt;
** [http://docs.opencv.org/3.0-beta/doc/py_tutorials/py_ml/py_kmeans/py_kmeans_opencv/py_kmeans_opencv.html OpenCV]&lt;br /&gt;
** [https://www.gnu.org/software/octave/ Octave] &lt;br /&gt;
* &#039;&#039;&#039;C#:&#039;&#039;&#039;  &lt;br /&gt;
** [http://accord-framework.net/docs/html/T_Accord_MachineLearning_KMeans.htm Accord.NET]&lt;br /&gt;
* &#039;&#039;&#039;Java:&#039;&#039;&#039;&lt;br /&gt;
** [http://elki.dbs.ifi.lmu.de ELKI]&lt;br /&gt;
** [https://mahout.apache.org Mahout]&lt;br /&gt;
* &#039;&#039;&#039;Lua&#039;&#039;&#039;&lt;br /&gt;
** [http://torch.ch Torch]&lt;br /&gt;
&lt;br /&gt;
Языки [https://www.r-bloggers.com/k-means-clustering-in-r/ R] и [http://juliastats.github.io Julia] содержат алгоритм k-means в базовой реализации.&lt;br /&gt;
&lt;br /&gt;
=== Платный доступ/лицензия  ===&lt;br /&gt;
&lt;br /&gt;
Существует целый перечень мощных статистических и математических пакетов для разных ОС:&lt;br /&gt;
* [http://www.mathworks.com/help/stats/kmeans.html?requestedDomain=www.mathworks.com MATLAB]&lt;br /&gt;
* [http://mathworld.wolfram.com/K-MeansClusteringAlgorithm.html Mathematica]&lt;br /&gt;
* [http://www.stata.com/features/cluster-analysis/ Stata]&lt;br /&gt;
* [https://support.sas.com/rnd/app/stat/procedures/fastclus.html SAS]&lt;br /&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]&lt;br /&gt;
* [http://docs.rapidminer.com/studio/operators/modeling/segmentation/k_means.html RapidMiner]&lt;br /&gt;
* ...&lt;br /&gt;
&lt;br /&gt;
= Литература =&lt;br /&gt;
[1] Нейский И.М. Классификация и сравнение методов кластеризации http://it-claim.ru/Persons/Neyskiy/Article2_Neiskiy.pdf&lt;br /&gt;
&lt;br /&gt;
[2] https://ru.wikipedia.org/wiki/K-means&lt;br /&gt;
&lt;br /&gt;
[[en:Description of algorithm properties and structure]]&lt;/div&gt;</summary>
		<author><name>Богомазов Евгений</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%98%D0%BB%D1%8C%D1%8F_%D0%95%D0%B3%D0%BE%D1%80%D0%BE%D0%B2/%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_k-%D1%81%D1%80%D0%B5%D0%B4%D0%BD%D0%B8%D1%85&amp;diff=11938</id>
		<title>Участник:Илья Егоров/Алгоритм k-средних</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%98%D0%BB%D1%8C%D1%8F_%D0%95%D0%B3%D0%BE%D1%80%D0%BE%D0%B2/%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_k-%D1%81%D1%80%D0%B5%D0%B4%D0%BD%D0%B8%D1%85&amp;diff=11938"/>
		<updated>2016-10-15T20:46:21Z</updated>

		<summary type="html">&lt;p&gt;Богомазов Евгений: /* Схема реализации последовательного алгоритма */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{algorithm&lt;br /&gt;
| name              = Алгоритм k-средних (k-means)&lt;br /&gt;
| serial_complexity = &amp;lt;math&amp;gt;O(n*k*d)&amp;lt;/math&amp;gt;&lt;br /&gt;
| input_data        = &amp;lt;math&amp;gt;n*d&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;quot;Илья Егоров — Евгений Богомазов&amp;quot;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
= ЧАСТЬ. Свойства и структура алгоритмов =&lt;br /&gt;
== Общее описание алгоритма ==&lt;br /&gt;
&lt;br /&gt;
Алгоритм кластеризации k-средних впервые был предложен в 1950-х годах математиками Гуго Штейнгаузом и Стюартом Ллойдом независимо друг от друга. Наибольшую популярность он получил после работы Маккуина.&lt;br /&gt;
&lt;br /&gt;
Алгоритм позволяет при заданном числе &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; построить &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластеров, расположенных на максимальном расстоянии друг от друга. Таким образом, наибольшей точности результат выполнения алгоритма достигает при полной осведомленности Пользователя о характере кластеризуемых объектов и, как следствие, при обладании максимально корректной информацией о числе кластеров.&lt;br /&gt;
&lt;br /&gt;
В общем случае выбор числа &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; может базироваться на любых значимых факторах, в том числе на результатах предшествующих исследований, теоретических соображениях или интуиции. &lt;br /&gt;
&lt;br /&gt;
== Математическое описание алгоритма ==&lt;br /&gt;
&#039;&#039;&#039;Исходные данные:&#039;&#039;&#039;&lt;br /&gt;
* Совокупность &amp;lt;b&amp;gt;n&amp;lt;/b&amp;gt; &amp;lt;b&amp;gt;d&amp;lt;/b&amp;gt;-мерных векторов &amp;lt;math&amp;gt; X = \{x_1 \dots x_n\} , &amp;lt;/math&amp;gt; где  &amp;lt;math&amp;gt; x_i = \{x_{i1} \dots x_{id}\} &amp;lt;/math&amp;gt;&lt;br /&gt;
* Предполагаемое количество кластеров &amp;lt;b&amp;gt;k&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Выходные данные:&#039;&#039;&#039;&lt;br /&gt;
* Разбиение X на множество &amp;lt;math&amp;gt; S = \{S_1 \dots S_k \}, \bigcup S_i = X, S_i \cap S_j = \emptyset, i \neq j &amp;lt;/math&amp;gt;&lt;br /&gt;
* k центров кластеров &amp;lt;math&amp;gt; \Mu = \{\mu_1 \dots \mu_k \} &amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt; \mu_i = \{\mu_{i1} \dots \mu_{id} \} &amp;lt;/math&amp;gt; такие, что&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; \begin{cases}\tilde{\mu_i} = \underset{y}{argmin } \sum_{x \in S_i} ||x-y||^2_E \\ \Mu = \underset{\tilde{\Mu}}{argmin } \sum_{i \in k} \sum_{x \in S_i} ||x-\tilde{\mu_i}||^2_E \end{cases} &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Алгоритм:&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
1) &amp;lt;math&amp;gt; \mu_{i} = random &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
2) &amp;lt;math&amp;gt; S_i = \{x \in S | \underset{j}{argmin } ||x-\mu_j||_E = i\} i = 1 \dots k &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
3) &amp;lt;math&amp;gt; \tilde{\mu_{i}} = E_{x \in S_i}(x) &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
4) Если для &amp;lt;math&amp;gt; \forall i:  \mu_i = \tilde{\mu_i} &amp;lt;/math&amp;gt; то алгоритм завершен, иначе &amp;lt;math&amp;gt; \mu_i = \tilde{\mu_i} &amp;lt;/math&amp;gt; и перейти на пункт 2)&lt;br /&gt;
&lt;br /&gt;
== Вычислительное ядро алгоритма ==&lt;br /&gt;
&lt;br /&gt;
Вычислительным ядром алгоритма является второй этап, а точнее нахождение матрицы расстояний между &amp;lt;math&amp;gt;X&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\Mu&amp;lt;/math&amp;gt;. Для &#039;&#039;&#039;d&#039;&#039;&#039;-мерного вектора &amp;lt;math&amp;gt;a:&amp;lt;/math&amp;gt; &lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;||a||=\sqrt{\sum_{i=1\dots d} a_i^2}&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; операций сложения и одну операция вычисления квадратного корня. Но так как эти расстояния используются только для сравнения, а &#039;&#039;sqrt&#039;&#039; является монотонно возрастающей функцией, то ее можно не вычислять. Поэтому нахождения матрицы расстояний потребует всего &amp;lt;math&amp;gt;n*k*d&amp;lt;/math&amp;gt; операций умножений и &amp;lt;math&amp;gt;n*k*(d-1)&amp;lt;/math&amp;gt; операций сложений.&lt;br /&gt;
&lt;br /&gt;
== Макроструктура алгоритма ==&lt;br /&gt;
&lt;br /&gt;
В алгоритме можно выделить следующие макрооперации: &lt;br /&gt;
*&#039;&#039;&#039;Вычисление расстояния между векторами&#039;&#039;&#039;,&lt;br /&gt;
*&#039;&#039;&#039;Суммирование векторов&#039;&#039;&#039;,&lt;br /&gt;
*&#039;&#039;&#039;Поиск минимума в векторе&#039;&#039;&#039;,&lt;br /&gt;
*&#039;&#039;&#039;Сравнение векторов&#039;&#039;&#039;,&lt;br /&gt;
*&#039;&#039;&#039;Деление вектора на скаляр&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;1)&#039;&#039;&#039; На шаге инициализации центроидов в общем случае (случайный выбор элементов) макроопераций не производится. Но так как правило определения количества кластеров &#039;&#039;&#039;k&#039;&#039;&#039; неоднозначно, то для некоторых вариантов макрооперации могут понадобиться. К примеру, существует класс стратегий поиска &#039;&#039;&#039;k&#039;&#039;&#039;, которые базируются на определении центра масс всех объектов, и для которых будут дополнительно выполняться макрооперации &#039;&#039;&#039;&amp;quot;Суммирование векторов&amp;quot;&#039;&#039;&#039; и &#039;&#039;&#039;&amp;quot;Деление вектора на скаляр&amp;quot;&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;2a)&#039;&#039;&#039; При составлении матрицы расстояний &#039;&#039;&#039; k &amp;lt;math&amp;gt; \cdot &amp;lt;/math&amp;gt;  n&#039;&#039;&#039; раз производится макрооперация &#039;&#039;&#039;&amp;quot;Вычисление расстояния между векторами&amp;quot;&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;2b)&#039;&#039;&#039; При нахождение вектора распределения объектов по кластерам &#039;&#039;&#039;n&#039;&#039;&#039; раз производится макрооперация &#039;&#039;&#039;&amp;quot;Поиск минимума в векторе&amp;quot;&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;3)&#039;&#039;&#039; При пересчете центроидов &#039;&#039;&#039;n - k&#039;&#039;&#039; раз производится макрооперация &#039;&#039;&#039;&amp;quot;Суммирование векторов&amp;quot;&#039;&#039;&#039; и &#039;&#039;&#039;k&#039;&#039;&#039; раз - &#039;&#039;&#039;&amp;quot;Деление вектора на скаляр&amp;quot;&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;4)&#039;&#039;&#039; Для проверки критерия останова требуется &#039;&#039;&#039;k&#039;&#039;&#039; раз произвести макрооперацию &#039;&#039;&#039;&amp;quot;Сравнение векторов&amp;quot;&#039;&#039;&#039; для сопоставления обновленных значений центроидов с уже имеющимися.&lt;br /&gt;
&lt;br /&gt;
== Схема реализации последовательного алгоритма ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Последовательность шагов алгоритма следующая:&lt;br /&gt;
&lt;br /&gt;
    &#039;&#039;&#039;1) Инициализация центроидов &amp;lt;math&amp;gt;\Mu&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt; iter = 1 &amp;lt;/math&amp;gt;, задание максимального количество итераций &amp;lt;math&amp;gt;maxiter&amp;lt;/math&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
        &lt;br /&gt;
    &#039;&#039;&#039;2a) Нахождение матрицы расстояний &#039;&#039;&#039;&amp;lt;math&amp;gt;dist:&amp;lt;/math&amp;gt;&lt;br /&gt;
    &lt;br /&gt;
        &amp;lt;math&amp;gt;dist_{ij} = \sum_{l = 1\dots d} (x_{il}-\mu_{jl})^2&amp;lt;/math&amp;gt;&lt;br /&gt;
        &lt;br /&gt;
    &#039;&#039;&#039;2b) Нахождение вектора распределения объектов по кластерам &#039;&#039;&#039;&amp;lt;math&amp;gt;index: &amp;lt;/math&amp;gt;&lt;br /&gt;
    &lt;br /&gt;
        &amp;lt;math&amp;gt;index_{i} =   \underset{j}{argmin }~dist_{ij} &amp;lt;/math&amp;gt;&lt;br /&gt;
    &lt;br /&gt;
    &#039;&#039;&#039;3) Пересчет центроидов &#039;&#039;&#039;&amp;lt;math&amp;gt;\tilde{\Mu}:&amp;lt;/math&amp;gt;&lt;br /&gt;
    &lt;br /&gt;
        &amp;lt;math&amp;gt;\tilde{\mu_{ij}} = \sum_{l \in S_i} \dfrac{x_{lj}}{|S_i|} &amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;S_i = \{l~|~l \in 1\dots n, index_l = i\}  &amp;lt;/math&amp;gt;&lt;br /&gt;
    &lt;br /&gt;
    &#039;&#039;&#039;4) Проверка критерия останова:&#039;&#039;&#039;&lt;br /&gt;
    &lt;br /&gt;
        &#039;&#039;&#039;Если&#039;&#039;&#039; &amp;lt;math&amp;gt; \exists i: \tilde{\mu_i} \neq \mu_i&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt; iter &amp;lt; maxiter &amp;lt;/math&amp;gt;,&lt;br /&gt;
    &lt;br /&gt;
        &#039;&#039;&#039;то&#039;&#039;&#039; &amp;lt;math&amp;gt; inc(iter), \Mu=\tilde{\Mu},&amp;lt;/math&amp;gt; &#039;&#039;&#039;GOTO 2.а.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
== Последовательная сложность алгоритма ==&lt;br /&gt;
&lt;br /&gt;
    &#039;&#039;&#039;1)&#039;&#039;&#039; Сложность инициализации в общем случае зависит от применяемого метода генерации/получения случайных чисел, но ей можно пренебречь&lt;br /&gt;
    &lt;br /&gt;
    &#039;&#039;&#039;2a)&#039;&#039;&#039; Вычисление матрицы расстояний требует &amp;lt;math&amp;gt; n*k*d &amp;lt;/math&amp;gt; операций умножения и &amp;lt;math&amp;gt; n*k*(d-1) &amp;lt;/math&amp;gt; операций сложения&lt;br /&gt;
    &lt;br /&gt;
    &#039;&#039;&#039;2b)&#039;&#039;&#039; Нахождение вектора распределения требует &amp;lt;math&amp;gt; n*(k-1) &amp;lt;/math&amp;gt; операций сравнения&lt;br /&gt;
    &lt;br /&gt;
    &#039;&#039;&#039;3)&#039;&#039;&#039; Для вычисления &amp;lt;math&amp;gt; \tilde{\Mu} &amp;lt;/math&amp;gt; требуется &amp;lt;math&amp;gt; (n - k + 1) * d &amp;lt;/math&amp;gt; операций сложения и &amp;lt;math&amp;gt; k * d &amp;lt;/math&amp;gt; операций деления&lt;br /&gt;
    &lt;br /&gt;
    &#039;&#039;&#039;4)&#039;&#039;&#039; Для критерия останова требуется &amp;lt;math&amp;gt; n*d &amp;lt;/math&amp;gt; сравнений&lt;br /&gt;
&lt;br /&gt;
Итого: так как максимальное количество итераций задается в алгоритме заранее и не зависит от входных данных, то количество итераций ограничено константой. Тогда сложность алгоритма:&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;math&amp;gt; O(n*k*d)&amp;lt;/math&amp;gt; операций сложения/вычитания&lt;br /&gt;
* &amp;lt;math&amp;gt; O(n*k*d)&amp;lt;/math&amp;gt; операций умножения, &amp;lt;math&amp;gt; O(k*d) &amp;lt;/math&amp;gt; операций деления&lt;br /&gt;
&lt;br /&gt;
== Информационный граф ==&lt;br /&gt;
&lt;br /&gt;
Рассмотрим вычислительные этапы алгоритма k-means. Это распределение объектов по кластерам и перерасчет центроидов.&lt;br /&gt;
&lt;br /&gt;
Распределение объектов по кластерам состоит из нахождения матрицы расстояний между &amp;lt;math&amp;gt;X&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\Mu&amp;lt;/math&amp;gt; (этапа 2a) и нахождения индекса минимального элемента в каждой строке (этап 2b). Ниже приведен информационный граф данного этапа.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Picture_1.png&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Рассмотрим этап вычисления ячейки &amp;lt;math&amp;gt; dist_{ij} &amp;lt;/math&amp;gt; матрицы более подробно. Он представляет из себя скалярное произведение d-мерных векторов &amp;lt;math&amp;gt; x_i &amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt; \mu_j &amp;lt;/math&amp;gt;. Ниже приведена граф для данной операции.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Picture_2.png&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
На этапе 3) происходит суммирование всех &amp;lt;math&amp;gt; x_l &amp;lt;/math&amp;gt; с одинаковым значением индекса в промежуточные суммы. Одновременно происходит подсчет количество элементов с фиксированным индексом. Затем происходит деление промежуточных сумм на соответствующее количество элементов в новом кластере, благодаря чему удается получить обновленные центроиды &amp;lt;math&amp;gt; \tilde{\mu}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Picture_3.png&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
== Ресурс параллелизма алгоритма ==&lt;br /&gt;
&lt;br /&gt;
Для получения общей картины достаточно определить, в том числе и с помощью информационного графа, каким ресурсом параллелизма обладает каждый из этапов алгоритма:&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;2a)&#039;&#039;&#039; Нахождение каждой ячейки матрицы &amp;lt;math&amp;gt; dist &amp;lt;/math&amp;gt; может происходить полностью независимо, так как они находятся на одном ярусе. При рассмотрении операции вычисления значения конкретной ячейки &amp;lt;math&amp;gt; dist_{ij} &amp;lt;/math&amp;gt; можно заметить, что все операции умножения также независимы между собой, поэтому понадобится всего одно умножение. Конечный результат получается в результате суммирования всех слагаемых и достигается параллельно за &amp;lt;math&amp;gt; \log(d) &amp;lt;/math&amp;gt; бинарных операций сложения при помощи стандартного метода &#039;&#039;reduction&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;2b)&#039;&#039;&#039; Нахождение вектора распределений заключается в нахождении минимального элемента в каждой строке матрицы &amp;lt;math&amp;gt; dist &amp;lt;/math&amp;gt;. При использовании &#039;&#039;reduction&#039;&#039; эту операцию можно выполнить за &amp;lt;math&amp;gt; \log(k) &amp;lt;/math&amp;gt; бинарных операций сравнения.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;3)&#039;&#039;&#039; В случае, если существует методология быстрого разделения &#039;&#039;&#039;n&#039;&#039;&#039; объектов на &#039;&#039;&#039;k&#039;&#039;&#039; множеств при помощи вектора индексации (косвенной адресации), все &amp;lt;math&amp;gt; \tilde{S_i} &amp;lt;/math&amp;gt; могут быть обработаны параллельно. В рамках каждого отдельного &amp;lt;math&amp;gt; \tilde{S_i} &amp;lt;/math&amp;gt; можно проводить распараллеливание дальше, так как &amp;lt;math&amp;gt; x_{lj} &amp;lt;/math&amp;gt; также не зависят друг от друга. Таким образом, вычисление всех слагаемых для всех &amp;lt;math&amp;gt; \tilde{\mu_{ij}} &amp;lt;/math&amp;gt; может быть выполнено за одно параллельное деление, а нахождение суммы всех этих слагаемых для каждого &amp;lt;math&amp;gt; \tilde{\mu_{ij}} &amp;lt;/math&amp;gt; может быть выполнено за &amp;lt;math&amp;gt; O(log(n)) &amp;lt;/math&amp;gt; в худшем случае (при вхождении почти всех объектов в один кластер).&lt;br /&gt;
&lt;br /&gt;
Если же такой методологии не существует, то узким местом становится процесс распределения на множества согласно вектору &amp;lt;math&amp;gt;index&amp;lt;/math&amp;gt;, который можно выполнить за &amp;lt;math&amp;gt; n &amp;lt;/math&amp;gt; операций косвенных адресаций. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;4)&#039;&#039;&#039; Все сравнения для критерия останова также независимы между собой и могут быть выполнены за одну операцию сравнения, а финальный результат может быть получен за одну операцию сложения при работе над общей памятью (к примеру, прибавление единицы при несовпадении в общую память и сравнение ее с 0 по завершению) или за &amp;lt;math&amp;gt;\log(k*d)&amp;lt;/math&amp;gt; сложений иначе.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Так как количество итераций ограничено константой, то на сложность оно не влияет. В итоге, параллельная сложность алгоритма k-means такова:&lt;br /&gt;
* &amp;lt;math&amp;gt; O(\log(n*d)) &amp;lt;/math&amp;gt; операций сложения&lt;br /&gt;
* &amp;lt;math&amp;gt; O(\log(k)) &amp;lt;/math&amp;gt; операций сравнения&lt;br /&gt;
* &amp;lt;math&amp;gt; O(1) &amp;lt;/math&amp;gt; операций умножения и деления&lt;br /&gt;
&lt;br /&gt;
== Входные и выходные данные алгоритма ==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Входные данные&#039;&#039;&#039;: Количество кластеров &amp;lt;b&amp;gt;k&amp;lt;/b&amp;gt;, &amp;lt;b&amp;gt;n&amp;lt;/b&amp;gt; кластеризуемых элементов&lt;br /&gt;
&lt;br /&gt;
Дополнительные ограничения:&lt;br /&gt;
* &amp;lt;b&amp;gt;k&amp;lt;/b&amp;gt; — положительное число, т. е. &amp;lt;b&amp;gt;k &amp;gt; 0&amp;lt;/b&amp;gt;.&lt;br /&gt;
* Для кластеризуемых элементов определена метрика (расстояние между объектами)&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Объём входных данных&#039;&#039;&#039;: &amp;lt;b&amp;gt;n &amp;lt;math&amp;gt;\cdot&amp;lt;/math&amp;gt; d + 1&amp;lt;/b&amp;gt; (кластеризуемые объекты в виде векторов и число &amp;lt;b&amp;gt;k&amp;lt;/b&amp;gt;)&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Выходные данные&#039;&#039;&#039;: Массив, в который записаны принадлежности каждого элемента кластеру (допустим вывод в другой эквивалентной более удобной структуре).&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Объём выходных данных&#039;&#039;&#039;:  Размер массива равен &amp;lt;b&amp;gt;2 &amp;lt;math&amp;gt;\cdot&amp;lt;/math&amp;gt; n&amp;lt;/b&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Свойства алгоритма ==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Ограничения алгоритма&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Алгоритм эффективно работает только на небольших объемах данных.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Преимущества алгоритма&#039;&#039;&#039;&lt;br /&gt;
* Простота использования&lt;br /&gt;
* Быстрота использования&lt;br /&gt;
* Понятность и прозрачность описания&lt;br /&gt;
* Обладает вычислительной устойчивостью&lt;br /&gt;
* Предрасположенность к распараллеливанию&lt;br /&gt;
* Достаточно популярный, поэтому имеет множество реализаций и вариаций&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Недостатки алгоритма&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
* Нет проверки корректности выбора числа кластеров&lt;br /&gt;
* Алгоритм чувствителен к количеству кластеров&lt;br /&gt;
* Алгоритм чувствителен к выбору начальных элементов в качестве центроидов &lt;br /&gt;
* Алгоритм крайне чувствителен к выбросам по данным&lt;br /&gt;
* Медленная работа на больших объемах данных&lt;br /&gt;
&lt;br /&gt;
= ЧАСТЬ. Программная реализация алгоритма =&lt;br /&gt;
&lt;br /&gt;
== Масштабируемость алгоритма и его реализации ==&lt;br /&gt;
&lt;br /&gt;
== Существующие реализации алгоритма ==&lt;br /&gt;
&lt;br /&gt;
=== Бесплатный доступ ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Десктопные программы&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
* [http://www.cs.waikato.ac.nz/ml/weka/ Weka]&lt;br /&gt;
* [http://docs.orange.biolab.si/2/reference/rst/Orange.clustering.kmeans.html Orange]&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Фреймворки для языков&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;Python:&#039;&#039;&#039;&lt;br /&gt;
** [http://scikit-learn.org/ scikit-learn]&lt;br /&gt;
** [https://www.scipy.org/ SciPy]&lt;br /&gt;
* &#039;&#039;&#039;C++:&#039;&#039;&#039;&lt;br /&gt;
** [http://mlpack.org/ MLPACK]&lt;br /&gt;
** [http://docs.opencv.org/3.0-beta/doc/py_tutorials/py_ml/py_kmeans/py_kmeans_opencv/py_kmeans_opencv.html OpenCV]&lt;br /&gt;
** [https://www.gnu.org/software/octave/ Octave] &lt;br /&gt;
* &#039;&#039;&#039;C#:&#039;&#039;&#039;  &lt;br /&gt;
** [http://accord-framework.net/docs/html/T_Accord_MachineLearning_KMeans.htm Accord.NET]&lt;br /&gt;
* &#039;&#039;&#039;Java:&#039;&#039;&#039;&lt;br /&gt;
** [http://elki.dbs.ifi.lmu.de ELKI]&lt;br /&gt;
** [https://mahout.apache.org Mahout]&lt;br /&gt;
* &#039;&#039;&#039;Lua&#039;&#039;&#039;&lt;br /&gt;
** [http://torch.ch Torch]&lt;br /&gt;
&lt;br /&gt;
Языки [https://www.r-bloggers.com/k-means-clustering-in-r/ R] и [http://juliastats.github.io Julia] содержат алгоритм k-means в базовой реализации.&lt;br /&gt;
&lt;br /&gt;
=== Платный доступ/лицензия  ===&lt;br /&gt;
&lt;br /&gt;
Существует целый перечень мощных статистических и математических пакетов для разных ОС:&lt;br /&gt;
* [http://www.mathworks.com/help/stats/kmeans.html?requestedDomain=www.mathworks.com MATLAB]&lt;br /&gt;
* [http://mathworld.wolfram.com/K-MeansClusteringAlgorithm.html Mathematica]&lt;br /&gt;
* [http://www.stata.com/features/cluster-analysis/ Stata]&lt;br /&gt;
* [https://support.sas.com/rnd/app/stat/procedures/fastclus.html SAS]&lt;br /&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]&lt;br /&gt;
* [http://docs.rapidminer.com/studio/operators/modeling/segmentation/k_means.html RapidMiner]&lt;br /&gt;
* ...&lt;br /&gt;
&lt;br /&gt;
= Литература =&lt;br /&gt;
[1] Нейский И.М. Классификация и сравнение методов кластеризации http://it-claim.ru/Persons/Neyskiy/Article2_Neiskiy.pdf&lt;br /&gt;
&lt;br /&gt;
[2] https://ru.wikipedia.org/wiki/K-means&lt;br /&gt;
&lt;br /&gt;
[[en:Description of algorithm properties and structure]]&lt;/div&gt;</summary>
		<author><name>Богомазов Евгений</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%98%D0%BB%D1%8C%D1%8F_%D0%95%D0%B3%D0%BE%D1%80%D0%BE%D0%B2/%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_k-%D1%81%D1%80%D0%B5%D0%B4%D0%BD%D0%B8%D1%85&amp;diff=11890</id>
		<title>Участник:Илья Егоров/Алгоритм k-средних</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%98%D0%BB%D1%8C%D1%8F_%D0%95%D0%B3%D0%BE%D1%80%D0%BE%D0%B2/%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_k-%D1%81%D1%80%D0%B5%D0%B4%D0%BD%D0%B8%D1%85&amp;diff=11890"/>
		<updated>2016-10-15T20:42:18Z</updated>

		<summary type="html">&lt;p&gt;Богомазов Евгений: /* Информационный граф */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{algorithm&lt;br /&gt;
| name              = Алгоритм k-средних (k-means)&lt;br /&gt;
| serial_complexity = &amp;lt;math&amp;gt;O(n*k*d)&amp;lt;/math&amp;gt;&lt;br /&gt;
| input_data        = &amp;lt;math&amp;gt;n*d&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;quot;Илья Егоров — Евгений Богомазов&amp;quot;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
= ЧАСТЬ. Свойства и структура алгоритмов =&lt;br /&gt;
== Общее описание алгоритма ==&lt;br /&gt;
&lt;br /&gt;
Алгоритм кластеризации k-средних впервые был предложен в 1950-х годах математиками Гуго Штейнгаузом и Стюартом Ллойдом независимо друг от друга. Наибольшую популярность он получил после работы Маккуина.&lt;br /&gt;
&lt;br /&gt;
Алгоритм позволяет при заданном числе &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; построить &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластеров, расположенных на максимальном расстоянии друг от друга. Таким образом, наибольшей точности результат выполнения алгоритма достигает при полной осведомленности Пользователя о характере кластеризуемых объектов и, как следствие, при обладании максимально корректной информацией о числе кластеров.&lt;br /&gt;
&lt;br /&gt;
В общем случае выбор числа &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; может базироваться на любых значимых факторах, в том числе на результатах предшествующих исследований, теоретических соображениях или интуиции. &lt;br /&gt;
&lt;br /&gt;
== Математическое описание алгоритма ==&lt;br /&gt;
&#039;&#039;&#039;Исходные данные:&#039;&#039;&#039;&lt;br /&gt;
* Совокупность &amp;lt;b&amp;gt;n&amp;lt;/b&amp;gt; &amp;lt;b&amp;gt;d&amp;lt;/b&amp;gt;-мерных векторов &amp;lt;math&amp;gt; X = \{x_1 \dots x_n\} , &amp;lt;/math&amp;gt; где  &amp;lt;math&amp;gt; x_i = \{x_{i1} \dots x_{id}\} &amp;lt;/math&amp;gt;&lt;br /&gt;
* Предполагаемое количество кластеров &amp;lt;b&amp;gt;k&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Выходные данные:&#039;&#039;&#039;&lt;br /&gt;
* Разбиение X на множество &amp;lt;math&amp;gt; S = \{S_1 \dots S_k \}, \bigcup S_i = X, S_i \cap S_j = \emptyset, i \neq j &amp;lt;/math&amp;gt;&lt;br /&gt;
* k центров кластеров &amp;lt;math&amp;gt; \Mu = \{\mu_1 \dots \mu_k \} &amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt; \mu_i = \{\mu_{i1} \dots \mu_{id} \} &amp;lt;/math&amp;gt; такие, что&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; \begin{cases}\tilde{\mu_i} = \underset{y}{argmin } \sum_{x \in S_i} ||x-y||^2_E \\ \Mu = \underset{\tilde{\Mu}}{argmin } \sum_{i \in k} \sum_{x \in S_i} ||x-\tilde{\mu_i}||^2_E \end{cases} &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Алгоритм:&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
1) &amp;lt;math&amp;gt; \mu_{i} = random &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
2) &amp;lt;math&amp;gt; S_i = \{x \in S | \underset{j}{argmin } ||x-\mu_j||_E = i\} i = 1 \dots k &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
3) &amp;lt;math&amp;gt; \tilde{\mu_{i}} = E_{x \in S_i}(x) &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
4) Если для &amp;lt;math&amp;gt; \forall i:  \mu_i = \tilde{\mu_i} &amp;lt;/math&amp;gt; то алгоритм завершен, иначе &amp;lt;math&amp;gt; \mu_i = \tilde{\mu_i} &amp;lt;/math&amp;gt; и перейти на пункт 2)&lt;br /&gt;
&lt;br /&gt;
== Вычислительное ядро алгоритма ==&lt;br /&gt;
&lt;br /&gt;
Вычислительным ядром алгоритма является второй этап, а точнее нахождение матрицы расстояний между &amp;lt;math&amp;gt;X&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\Mu&amp;lt;/math&amp;gt;. Для &#039;&#039;&#039;d&#039;&#039;&#039;-мерного вектора &amp;lt;math&amp;gt;a:&amp;lt;/math&amp;gt; &lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;||a||=\sqrt{\sum_{i=1\dots d} a_i^2}&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; операций сложения и одну операция вычисления квадратного корня. Но так как эти расстояния используются только для сравнения, а &#039;&#039;sqrt&#039;&#039; является монотонно возрастающей функцией, то ее можно не вычислять. Поэтому нахождения матрицы расстояний потребует всего &amp;lt;math&amp;gt;n*k*d&amp;lt;/math&amp;gt; операций умножений и &amp;lt;math&amp;gt;n*k*(d-1)&amp;lt;/math&amp;gt; операций сложений.&lt;br /&gt;
&lt;br /&gt;
== Макроструктура алгоритма ==&lt;br /&gt;
&lt;br /&gt;
В алгоритме можно выделить следующие макрооперации: &lt;br /&gt;
*&#039;&#039;&#039;Вычисление расстояния между векторами&#039;&#039;&#039;,&lt;br /&gt;
*&#039;&#039;&#039;Суммирование векторов&#039;&#039;&#039;,&lt;br /&gt;
*&#039;&#039;&#039;Поиск минимума в векторе&#039;&#039;&#039;,&lt;br /&gt;
*&#039;&#039;&#039;Сравнение векторов&#039;&#039;&#039;,&lt;br /&gt;
*&#039;&#039;&#039;Деление вектора на скаляр&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;1)&#039;&#039;&#039; На шаге инициализации центроидов в общем случае (случайный выбор элементов) макроопераций не производится. Но так как правило определения количества кластеров &#039;&#039;&#039;k&#039;&#039;&#039; неоднозначно, то для некоторых вариантов макрооперации могут понадобиться. К примеру, существует класс стратегий поиска &#039;&#039;&#039;k&#039;&#039;&#039;, которые базируются на определении центра масс всех объектов, и для которых будут дополнительно выполняться макрооперации &#039;&#039;&#039;&amp;quot;Суммирование векторов&amp;quot;&#039;&#039;&#039; и &#039;&#039;&#039;&amp;quot;Деление вектора на скаляр&amp;quot;&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;2a)&#039;&#039;&#039; При составлении матрицы расстояний &#039;&#039;&#039; k &amp;lt;math&amp;gt; \cdot &amp;lt;/math&amp;gt;  n&#039;&#039;&#039; раз производится макрооперация &#039;&#039;&#039;&amp;quot;Вычисление расстояния между векторами&amp;quot;&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;2b)&#039;&#039;&#039; При нахождение вектора распределения объектов по кластерам &#039;&#039;&#039;n&#039;&#039;&#039; раз производится макрооперация &#039;&#039;&#039;&amp;quot;Поиск минимума в векторе&amp;quot;&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;3)&#039;&#039;&#039; При пересчете центроидов &#039;&#039;&#039;n - k&#039;&#039;&#039; раз производится макрооперация &#039;&#039;&#039;&amp;quot;Суммирование векторов&amp;quot;&#039;&#039;&#039; и &#039;&#039;&#039;k&#039;&#039;&#039; раз - &#039;&#039;&#039;&amp;quot;Деление вектора на скаляр&amp;quot;&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;4)&#039;&#039;&#039; Для проверки критерия останова требуется &#039;&#039;&#039;k&#039;&#039;&#039; раз произвести макрооперацию &#039;&#039;&#039;&amp;quot;Сравнение векторов&amp;quot;&#039;&#039;&#039; для сопоставления обновленных значений центроидов с уже имеющимися.&lt;br /&gt;
&lt;br /&gt;
== Схема реализации последовательного алгоритма ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Последовательность шагов алгоритма следующая:&lt;br /&gt;
&lt;br /&gt;
    &#039;&#039;&#039;1) Инициализация центроидов &amp;lt;math&amp;gt;\Mu&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt; iter = 1 &amp;lt;/math&amp;gt;, задание максимального количество итераций &amp;lt;math&amp;gt;maxiter&amp;lt;/math&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
        &lt;br /&gt;
    &#039;&#039;&#039;2a) Нахождение матрицы расстояний &#039;&#039;&#039;&amp;lt;math&amp;gt;dist:&amp;lt;/math&amp;gt;&lt;br /&gt;
    &lt;br /&gt;
        &amp;lt;math&amp;gt;dist_{ij} = \sum_{l = 1\dots d} (x_{il}-\mu_{jl})^2&amp;lt;/math&amp;gt;&lt;br /&gt;
        &lt;br /&gt;
    &#039;&#039;&#039;2b) Нахождение вектора распределения объектов по кластерам &#039;&#039;&#039;&amp;lt;math&amp;gt;index: &amp;lt;/math&amp;gt;&lt;br /&gt;
    &lt;br /&gt;
        &amp;lt;math&amp;gt;index_{i} =   \underset{j}{argmin }~dist_{ij} &amp;lt;/math&amp;gt;&lt;br /&gt;
    &lt;br /&gt;
    &#039;&#039;&#039;3) Пересчет центроидов &#039;&#039;&#039;&amp;lt;math&amp;gt;\tilde{\Mu}:&amp;lt;/math&amp;gt;&lt;br /&gt;
    &lt;br /&gt;
        &amp;lt;math&amp;gt;\tilde{\mu_{ij}} = \sum_{l \in \tilde{S_i}} \dfrac{x_{lj}}{|\tilde{S_i}|} &amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;\tilde{S_i} = \{l~|~l \in 1\dots n, index_l = i\}  &amp;lt;/math&amp;gt;&lt;br /&gt;
    &lt;br /&gt;
    &#039;&#039;&#039;4) Проверка критерия останова:&#039;&#039;&#039;&lt;br /&gt;
    &lt;br /&gt;
        &#039;&#039;&#039;Если&#039;&#039;&#039; &amp;lt;math&amp;gt; \exists i: \tilde{\mu_i} \neq \mu_i&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt; iter &amp;lt; maxiter &amp;lt;/math&amp;gt;,&lt;br /&gt;
    &lt;br /&gt;
        &#039;&#039;&#039;то&#039;&#039;&#039; &amp;lt;math&amp;gt; inc(iter), \Mu=\tilde{\Mu},&amp;lt;/math&amp;gt; &#039;&#039;&#039;GOTO 2.а.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
== Последовательная сложность алгоритма ==&lt;br /&gt;
&lt;br /&gt;
    &#039;&#039;&#039;1)&#039;&#039;&#039; Сложность инициализации в общем случае зависит от применяемого метода генерации/получения случайных чисел, но ей можно пренебречь&lt;br /&gt;
    &lt;br /&gt;
    &#039;&#039;&#039;2a)&#039;&#039;&#039; Вычисление матрицы расстояний требует &amp;lt;math&amp;gt; n*k*d &amp;lt;/math&amp;gt; операций умножения и &amp;lt;math&amp;gt; n*k*(d-1) &amp;lt;/math&amp;gt; операций сложения&lt;br /&gt;
    &lt;br /&gt;
    &#039;&#039;&#039;2b)&#039;&#039;&#039; Нахождение вектора распределения требует &amp;lt;math&amp;gt; n*(k-1) &amp;lt;/math&amp;gt; операций сравнения&lt;br /&gt;
    &lt;br /&gt;
    &#039;&#039;&#039;3)&#039;&#039;&#039; Для вычисления &amp;lt;math&amp;gt; \tilde{\Mu} &amp;lt;/math&amp;gt; требуется &amp;lt;math&amp;gt; (n - k + 1) * d &amp;lt;/math&amp;gt; операций сложения и &amp;lt;math&amp;gt; k * d &amp;lt;/math&amp;gt; операций деления&lt;br /&gt;
    &lt;br /&gt;
    &#039;&#039;&#039;4)&#039;&#039;&#039; Для критерия останова требуется &amp;lt;math&amp;gt; n*d &amp;lt;/math&amp;gt; сравнений&lt;br /&gt;
&lt;br /&gt;
Итого: так как максимальное количество итераций задается в алгоритме заранее и не зависит от входных данных, то количество итераций ограничено константой. Тогда сложность алгоритма:&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;math&amp;gt; O(n*k*d)&amp;lt;/math&amp;gt; операций сложения/вычитания&lt;br /&gt;
* &amp;lt;math&amp;gt; O(n*k*d)&amp;lt;/math&amp;gt; операций умножения, &amp;lt;math&amp;gt; O(k*d) &amp;lt;/math&amp;gt; операций деления&lt;br /&gt;
&lt;br /&gt;
== Информационный граф ==&lt;br /&gt;
&lt;br /&gt;
Рассмотрим вычислительные этапы алгоритма k-means. Это распределение объектов по кластерам и перерасчет центроидов.&lt;br /&gt;
&lt;br /&gt;
Распределение объектов по кластерам состоит из нахождения матрицы расстояний между &amp;lt;math&amp;gt;X&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\Mu&amp;lt;/math&amp;gt; (этапа 2a) и нахождения индекса минимального элемента в каждой строке (этап 2b). Ниже приведен информационный граф данного этапа.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Picture_1.png&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Рассмотрим этап вычисления ячейки &amp;lt;math&amp;gt; dist_{ij} &amp;lt;/math&amp;gt; матрицы более подробно. Он представляет из себя скалярное произведение d-мерных векторов &amp;lt;math&amp;gt; x_i &amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt; \mu_j &amp;lt;/math&amp;gt;. Ниже приведена граф для данной операции.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Picture_2.png&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
На этапе 3) происходит суммирование всех &amp;lt;math&amp;gt; x_l &amp;lt;/math&amp;gt; с одинаковым значением индекса в промежуточные суммы. Одновременно происходит подсчет количество элементов с фиксированным индексом. Затем происходит деление промежуточных сумм на соответствующее количество элементов в новом кластере, благодаря чему удается получить обновленные центроиды &amp;lt;math&amp;gt; \tilde{\mu}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Picture_3.png&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
== Ресурс параллелизма алгоритма ==&lt;br /&gt;
&lt;br /&gt;
Для получения общей картины достаточно определить, в том числе и с помощью информационного графа, каким ресурсом параллелизма обладает каждый из этапов алгоритма:&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;2a)&#039;&#039;&#039; Нахождение каждой ячейки матрицы &amp;lt;math&amp;gt; dist &amp;lt;/math&amp;gt; может происходить полностью независимо, так как они находятся на одном ярусе. При рассмотрении операции вычисления значения конкретной ячейки &amp;lt;math&amp;gt; dist_{ij} &amp;lt;/math&amp;gt; можно заметить, что все операции умножения также независимы между собой, поэтому понадобится всего одно умножение. Конечный результат получается в результате суммирования всех слагаемых и достигается параллельно за &amp;lt;math&amp;gt; \log(d) &amp;lt;/math&amp;gt; бинарных операций сложения при помощи стандартного метода &#039;&#039;reduction&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;2b)&#039;&#039;&#039; Нахождение вектора распределений заключается в нахождении минимального элемента в каждой строке матрицы &amp;lt;math&amp;gt; dist &amp;lt;/math&amp;gt;. При использовании &#039;&#039;reduction&#039;&#039; эту операцию можно выполнить за &amp;lt;math&amp;gt; \log(k) &amp;lt;/math&amp;gt; бинарных операций сравнения.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;3)&#039;&#039;&#039; В случае, если существует методология быстрого разделения &#039;&#039;&#039;n&#039;&#039;&#039; объектов на &#039;&#039;&#039;k&#039;&#039;&#039; множеств при помощи вектора индексации (косвенной адресации), все &amp;lt;math&amp;gt; \tilde{S_i} &amp;lt;/math&amp;gt; могут быть обработаны параллельно. В рамках каждого отдельного &amp;lt;math&amp;gt; \tilde{S_i} &amp;lt;/math&amp;gt; можно проводить распараллеливание дальше, так как &amp;lt;math&amp;gt; x_{lj} &amp;lt;/math&amp;gt; также не зависят друг от друга. Таким образом, вычисление всех слагаемых для всех &amp;lt;math&amp;gt; \tilde{\mu_{ij}} &amp;lt;/math&amp;gt; может быть выполнено за одно параллельное деление, а нахождение суммы всех этих слагаемых для каждого &amp;lt;math&amp;gt; \tilde{\mu_{ij}} &amp;lt;/math&amp;gt; может быть выполнено за &amp;lt;math&amp;gt; O(log(n)) &amp;lt;/math&amp;gt; в худшем случае (при вхождении почти всех объектов в один кластер).&lt;br /&gt;
&lt;br /&gt;
Если же такой методологии не существует, то узким местом становится процесс распределения на множества согласно вектору &amp;lt;math&amp;gt;index&amp;lt;/math&amp;gt;, который можно выполнить за &amp;lt;math&amp;gt; n &amp;lt;/math&amp;gt; операций косвенных адресаций. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;4)&#039;&#039;&#039; Все сравнения для критерия останова также независимы между собой и могут быть выполнены за одну операцию сравнения, а финальный результат может быть получен за одну операцию сложения при работе над общей памятью (к примеру, прибавление единицы при несовпадении в общую память и сравнение ее с 0 по завершению) или за &amp;lt;math&amp;gt;\log(k*d)&amp;lt;/math&amp;gt; сложений иначе.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Так как количество итераций ограничено константой, то на сложность оно не влияет. В итоге, параллельная сложность алгоритма k-means такова:&lt;br /&gt;
* &amp;lt;math&amp;gt; O(\log(n*d)) &amp;lt;/math&amp;gt; операций сложения&lt;br /&gt;
* &amp;lt;math&amp;gt; O(\log(k)) &amp;lt;/math&amp;gt; операций сравнения&lt;br /&gt;
* &amp;lt;math&amp;gt; O(1) &amp;lt;/math&amp;gt; операций умножения и деления&lt;br /&gt;
&lt;br /&gt;
== Входные и выходные данные алгоритма ==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Входные данные&#039;&#039;&#039;: Количество кластеров &amp;lt;b&amp;gt;k&amp;lt;/b&amp;gt;, &amp;lt;b&amp;gt;n&amp;lt;/b&amp;gt; кластеризуемых элементов&lt;br /&gt;
&lt;br /&gt;
Дополнительные ограничения:&lt;br /&gt;
* &amp;lt;b&amp;gt;k&amp;lt;/b&amp;gt; — положительное число, т. е. &amp;lt;b&amp;gt;k &amp;gt; 0&amp;lt;/b&amp;gt;.&lt;br /&gt;
* Для кластеризуемых элементов определена метрика (расстояние между объектами)&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Объём входных данных&#039;&#039;&#039;: &amp;lt;b&amp;gt;n &amp;lt;math&amp;gt;\cdot&amp;lt;/math&amp;gt; d + 1&amp;lt;/b&amp;gt; (кластеризуемые объекты в виде векторов и число &amp;lt;b&amp;gt;k&amp;lt;/b&amp;gt;)&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Выходные данные&#039;&#039;&#039;: Массив, в который записаны принадлежности каждого элемента кластеру (допустим вывод в другой эквивалентной более удобной структуре).&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Объём выходных данных&#039;&#039;&#039;:  Размер массива равен &amp;lt;b&amp;gt;2 &amp;lt;math&amp;gt;\cdot&amp;lt;/math&amp;gt; n&amp;lt;/b&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Свойства алгоритма ==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Ограничения алгоритма&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Алгоритм эффективно работает только на небольших объемах данных.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Преимущества алгоритма&#039;&#039;&#039;&lt;br /&gt;
* Простота использования&lt;br /&gt;
* Быстрота использования&lt;br /&gt;
* Понятность и прозрачность описания&lt;br /&gt;
* Обладает вычислительной устойчивостью&lt;br /&gt;
* Предрасположенность к распараллеливанию&lt;br /&gt;
* Достаточно популярный, поэтому имеет множество реализаций и вариаций&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Недостатки алгоритма&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
* Нет проверки корректности выбора числа кластеров&lt;br /&gt;
* Алгоритм чувствителен к количеству кластеров&lt;br /&gt;
* Алгоритм чувствителен к выбору начальных элементов в качестве центроидов &lt;br /&gt;
* Алгоритм крайне чувствителен к выбросам по данным&lt;br /&gt;
* Медленная работа на больших объемах данных&lt;br /&gt;
&lt;br /&gt;
= ЧАСТЬ. Программная реализация алгоритма =&lt;br /&gt;
&lt;br /&gt;
== Масштабируемость алгоритма и его реализации ==&lt;br /&gt;
&lt;br /&gt;
== Существующие реализации алгоритма ==&lt;br /&gt;
&lt;br /&gt;
=== Бесплатный доступ ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Десктопные программы&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
* [http://www.cs.waikato.ac.nz/ml/weka/ Weka]&lt;br /&gt;
* [http://docs.orange.biolab.si/2/reference/rst/Orange.clustering.kmeans.html Orange]&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Фреймворки для языков&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;Python:&#039;&#039;&#039;&lt;br /&gt;
** [http://scikit-learn.org/ scikit-learn]&lt;br /&gt;
** [https://www.scipy.org/ SciPy]&lt;br /&gt;
* &#039;&#039;&#039;C++:&#039;&#039;&#039;&lt;br /&gt;
** [http://mlpack.org/ MLPACK]&lt;br /&gt;
** [http://docs.opencv.org/3.0-beta/doc/py_tutorials/py_ml/py_kmeans/py_kmeans_opencv/py_kmeans_opencv.html OpenCV]&lt;br /&gt;
** [https://www.gnu.org/software/octave/ Octave] &lt;br /&gt;
* &#039;&#039;&#039;C#:&#039;&#039;&#039;  &lt;br /&gt;
** [http://accord-framework.net/docs/html/T_Accord_MachineLearning_KMeans.htm Accord.NET]&lt;br /&gt;
* &#039;&#039;&#039;Java:&#039;&#039;&#039;&lt;br /&gt;
** [http://elki.dbs.ifi.lmu.de ELKI]&lt;br /&gt;
** [https://mahout.apache.org Mahout]&lt;br /&gt;
* &#039;&#039;&#039;Lua&#039;&#039;&#039;&lt;br /&gt;
** [http://torch.ch Torch]&lt;br /&gt;
&lt;br /&gt;
Языки [https://www.r-bloggers.com/k-means-clustering-in-r/ R] и [http://juliastats.github.io Julia] содержат алгоритм k-means в базовой реализации.&lt;br /&gt;
&lt;br /&gt;
=== Платный доступ/лицензия  ===&lt;br /&gt;
&lt;br /&gt;
Существует целый перечень мощных статистических и математических пакетов для разных ОС:&lt;br /&gt;
* [http://www.mathworks.com/help/stats/kmeans.html?requestedDomain=www.mathworks.com MATLAB]&lt;br /&gt;
* [http://mathworld.wolfram.com/K-MeansClusteringAlgorithm.html Mathematica]&lt;br /&gt;
* [http://www.stata.com/features/cluster-analysis/ Stata]&lt;br /&gt;
* [https://support.sas.com/rnd/app/stat/procedures/fastclus.html SAS]&lt;br /&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]&lt;br /&gt;
* [http://docs.rapidminer.com/studio/operators/modeling/segmentation/k_means.html RapidMiner]&lt;br /&gt;
* ...&lt;br /&gt;
&lt;br /&gt;
= Литература =&lt;br /&gt;
[1] Нейский И.М. Классификация и сравнение методов кластеризации http://it-claim.ru/Persons/Neyskiy/Article2_Neiskiy.pdf&lt;br /&gt;
&lt;br /&gt;
[2] https://ru.wikipedia.org/wiki/K-means&lt;br /&gt;
&lt;br /&gt;
[[en:Description of algorithm properties and structure]]&lt;/div&gt;</summary>
		<author><name>Богомазов Евгений</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%98%D0%BB%D1%8C%D1%8F_%D0%95%D0%B3%D0%BE%D1%80%D0%BE%D0%B2/%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_k-%D1%81%D1%80%D0%B5%D0%B4%D0%BD%D0%B8%D1%85&amp;diff=10413</id>
		<title>Участник:Илья Егоров/Алгоритм k-средних</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%98%D0%BB%D1%8C%D1%8F_%D0%95%D0%B3%D0%BE%D1%80%D0%BE%D0%B2/%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_k-%D1%81%D1%80%D0%B5%D0%B4%D0%BD%D0%B8%D1%85&amp;diff=10413"/>
		<updated>2016-10-15T16:03:18Z</updated>

		<summary type="html">&lt;p&gt;Богомазов Евгений: /* Математическое описание алгоритма */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{algorithm&lt;br /&gt;
| name              = Алгоритм k-средних (k-means)&lt;br /&gt;
| serial_complexity = &amp;lt;math&amp;gt;O(n*k*d)&amp;lt;/math&amp;gt;&lt;br /&gt;
| input_data        = &amp;lt;math&amp;gt;n*d&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;quot;Илья Егоров — Евгений Богомазов&amp;quot;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
= ЧАСТЬ. Свойства и структура алгоритмов =&lt;br /&gt;
== Общее описание алгоритма ==&lt;br /&gt;
&lt;br /&gt;
Алгоритм кластеризации k-средних впервые был предложен в 1950-х годах математиками Гуго Штейнгаузом и Стюартом Ллойдом независимо друг от друга. Наибольшую популярность он получил после работы Маккуина.&lt;br /&gt;
&lt;br /&gt;
Алгоритм позволяет при заданном числе &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; построить &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластеров, расположенных на максимальном расстоянии друг от друга. Таким образом, наибольшей точности результат выполнения алгоритма достигает при полной осведомленности Пользователя о характере кластеризуемых объектов и, как следствие, при обладании максимально корректной информацией о числе кластеров.&lt;br /&gt;
&lt;br /&gt;
В общем случае выбор числа &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; может базироваться на любых значимых факторах, в том числе на результатах предшествующих исследований, теоретических соображениях или интуиции. &lt;br /&gt;
&lt;br /&gt;
== Математическое описание алгоритма ==&lt;br /&gt;
&#039;&#039;&#039;Исходные данные:&#039;&#039;&#039;&lt;br /&gt;
* Совокупность &amp;lt;b&amp;gt;n&amp;lt;/b&amp;gt; &amp;lt;b&amp;gt;d&amp;lt;/b&amp;gt;-мерных векторов &amp;lt;math&amp;gt; X = \{x_1 \dots x_n\} , &amp;lt;/math&amp;gt; где  &amp;lt;math&amp;gt; x_i = \{x_{i1} \dots x_{id}\} &amp;lt;/math&amp;gt;&lt;br /&gt;
* Предполагаемое количество кластеров &amp;lt;b&amp;gt;k&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Выходные данные:&#039;&#039;&#039;&lt;br /&gt;
* Разбиение X на множество &amp;lt;math&amp;gt; S = \{S_1 \dots S_k \}, \bigcup S_i = X, S_i \cap S_j = \emptyset, i \neq j &amp;lt;/math&amp;gt;&lt;br /&gt;
* k центров кластеров &amp;lt;math&amp;gt; \Mu = \{\mu_1 \dots \mu_k \} &amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt; \mu_i = \{\mu_{i1} \dots \mu_{id} \} &amp;lt;/math&amp;gt; такие, что&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; \begin{cases}\tilde{\mu_i} = \underset{y}{argmin } \sum_{x \in S_i} ||x-y||^2_E \\ \Mu = \underset{\tilde{\Mu}}{argmin } \sum_{i \in k} \sum_{x \in S_i} ||x-\tilde{\mu_i}||^2_E \end{cases} &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Алгоритм:&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
1) &amp;lt;math&amp;gt; \mu_{i} = random &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
2) &amp;lt;math&amp;gt; S_i = \{x \in S | \underset{j}{argmin } ||x-\mu_j||_E = i\} i = 1 \dots k &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
3) &amp;lt;math&amp;gt; \tilde{\mu_{i}} = E_{x \in S_i}(x) &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
4) Если для &amp;lt;math&amp;gt; \forall i:  \mu_i = \tilde{\mu_i} &amp;lt;/math&amp;gt; то алгоритм завершен, иначе &amp;lt;math&amp;gt; \mu_i = \tilde{\mu_i} &amp;lt;/math&amp;gt; и перейти на пункт 2)&lt;br /&gt;
&lt;br /&gt;
== Вычислительное ядро алгоритма ==&lt;br /&gt;
&lt;br /&gt;
Вычислительным ядром алгоритма является второй этап, а точнее нахождение матрицы расстояний между &amp;lt;math&amp;gt;X&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\Mu&amp;lt;/math&amp;gt;. Для &#039;&#039;&#039;d&#039;&#039;&#039;-мерного вектора &amp;lt;math&amp;gt;a:&amp;lt;/math&amp;gt; &lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;||a||=\sqrt{\sum_{i=1\dots d} a_i^2}&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; операций сложения и одну операция вычисления квадратного корня. Но так как эти расстояния используются только для сравнения, а &#039;&#039;sqrt&#039;&#039; является монотонно возрастающей функцией, то ее можно не вычислять. Поэтому нахождения матрицы расстояний потребует всего &amp;lt;math&amp;gt;n*k*d&amp;lt;/math&amp;gt; операций умножений и &amp;lt;math&amp;gt;n*k*(d-1)&amp;lt;/math&amp;gt; операций сложений.&lt;br /&gt;
&lt;br /&gt;
== Макроструктура алгоритма ==&lt;br /&gt;
&lt;br /&gt;
Алгоритм k-средних базируется на алгоритме вычисления расстояния между векторами, расстояние на каждом шаге высчитывается &amp;lt;math&amp;gt;k\cdot n&amp;lt;/math&amp;gt; раз.&lt;br /&gt;
&lt;br /&gt;
Помимо этого, в конце каждого шага вычисляется центр масс объектов кластера, для всех объектов потребуется &amp;lt;math&amp;gt;n-1&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;
&lt;br /&gt;
&lt;br /&gt;
Последовательность шагов алгоритма следующая:&lt;br /&gt;
&lt;br /&gt;
    &#039;&#039;&#039;1) Инициализация центроидов &amp;lt;math&amp;gt;\Mu&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt; iter = 1 &amp;lt;/math&amp;gt;, задание максимального количество итераций &amp;lt;math&amp;gt;maxiter&amp;lt;/math&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
        &lt;br /&gt;
    &#039;&#039;&#039;2a) Нахождение матрицы расстояний &#039;&#039;&#039;&amp;lt;math&amp;gt;dist:&amp;lt;/math&amp;gt;&lt;br /&gt;
    &lt;br /&gt;
        &amp;lt;math&amp;gt;dist_{ij} = \sum_{l = 1\dots d} (x_{il}-\mu_{jl})^2&amp;lt;/math&amp;gt;&lt;br /&gt;
        &lt;br /&gt;
    &#039;&#039;&#039;2b) Нахождение вектора распределения объектов по кластерам &#039;&#039;&#039;&amp;lt;math&amp;gt;index: &amp;lt;/math&amp;gt;&lt;br /&gt;
    &lt;br /&gt;
        &amp;lt;math&amp;gt;index_{i} =   \underset{j}{argmin }~dist_{ij} &amp;lt;/math&amp;gt;&lt;br /&gt;
    &lt;br /&gt;
    &#039;&#039;&#039;3) Пересчет центроидов &#039;&#039;&#039;&amp;lt;math&amp;gt;\tilde{\Mu}:&amp;lt;/math&amp;gt;&lt;br /&gt;
    &lt;br /&gt;
        &amp;lt;math&amp;gt;\tilde{\mu_{ij}} = \sum_{l \in \tilde{S_i}} \dfrac{x_{lj}}{|\tilde{S_i}|} &amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;\tilde{S_i} = \{l~|~l \in 1\dots n, index_l = i\}  &amp;lt;/math&amp;gt;&lt;br /&gt;
    &lt;br /&gt;
    &#039;&#039;&#039;4) Проверка критерия останова:&#039;&#039;&#039;&lt;br /&gt;
    &lt;br /&gt;
        &#039;&#039;&#039;Если&#039;&#039;&#039; &amp;lt;math&amp;gt; \exists i: \tilde{\mu_i} \neq \mu_i&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt; iter &amp;lt; maxiter &amp;lt;/math&amp;gt;,&lt;br /&gt;
    &lt;br /&gt;
        &#039;&#039;&#039;то&#039;&#039;&#039; &amp;lt;math&amp;gt; inc(iter), \Mu=\tilde{\Mu},&amp;lt;/math&amp;gt; &#039;&#039;&#039;GOTO 2.а.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
== Последовательная сложность алгоритма ==&lt;br /&gt;
&lt;br /&gt;
    &#039;&#039;&#039;1)&#039;&#039;&#039; Сложность инициализации в общем случае зависит от применяемого метода генерации/получения случайных чисел, но ей можно пренебречь&lt;br /&gt;
    &lt;br /&gt;
    &#039;&#039;&#039;2a)&#039;&#039;&#039; Вычисление матрицы расстояний требует &amp;lt;math&amp;gt; n*k*d &amp;lt;/math&amp;gt; операций умножений и &amp;lt;math&amp;gt; n*k*(d-1) &amp;lt;/math&amp;gt; операций сложений&lt;br /&gt;
    &lt;br /&gt;
    &#039;&#039;&#039;2b)&#039;&#039;&#039; Нахождение вектора распределения требует &amp;lt;math&amp;gt; n*(k-1) &amp;lt;/math&amp;gt; операций сравнений&lt;br /&gt;
    &lt;br /&gt;
    &#039;&#039;&#039;3)&#039;&#039;&#039; Для вычисления &amp;lt;math&amp;gt; \tilde{\Mu} &amp;lt;/math&amp;gt; требуется &amp;lt;math&amp;gt; (n - k + 1) * d &amp;lt;/math&amp;gt; операций сложений и &amp;lt;math&amp;gt; k * d &amp;lt;/math&amp;gt; операций деления&lt;br /&gt;
    &lt;br /&gt;
    &#039;&#039;&#039;4)&#039;&#039;&#039; Для критерия останова требуется &amp;lt;math&amp;gt; n*d &amp;lt;/math&amp;gt; сравнений&lt;br /&gt;
&lt;br /&gt;
Итого: так как максимальное количество итераций задается в алгоритме заранее и не зависит от входных данных, то количество итераций ограничено константой. Тогда сложность алгоритма:&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;math&amp;gt; O(n*k*d)&amp;lt;/math&amp;gt; операций сложений/вычитаний&lt;br /&gt;
* &amp;lt;math&amp;gt; O(n*k*d)&amp;lt;/math&amp;gt; операций умножений, &amp;lt;math&amp;gt; O(k*d) &amp;lt;/math&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;
&#039;&#039;&#039;2a)&#039;&#039;&#039; Нахождение каждой ячейки матрицы &amp;lt;math&amp;gt; dist &amp;lt;/math&amp;gt; может происходить полностью независимо, так как они находятся на одном ярусе. При рассмотрении операции вычисления значения конкретной ячейки &amp;lt;math&amp;gt; dist_{ij} &amp;lt;/math&amp;gt; можно заметить, что все операции умножения также независимы между собой, поэтому понадобится всего одно умножение. Конечный результат получается в результате суммирования всех слагаемых и достигается параллельно за &amp;lt;math&amp;gt; \log(d) &amp;lt;/math&amp;gt; бинарных операций сложения при помощи стандартного метода &#039;&#039;reduction&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;2b)&#039;&#039;&#039; Нахождение вектора распределений заключается в нахождении минимального элемента в каждой строке матрицы &amp;lt;math&amp;gt; dist &amp;lt;/math&amp;gt;. При использовании &#039;&#039;reduction&#039;&#039; эту операцию можно выполнить за &amp;lt;math&amp;gt; \log(k) &amp;lt;/math&amp;gt; бинарных операций сравнения.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;3)&#039;&#039;&#039; В случае, если существует методология быстрого разделения &#039;&#039;&#039;n&#039;&#039;&#039; объектов на &#039;&#039;&#039;k&#039;&#039;&#039; множеств при помощи вектора индексации (косвенной адресации), все &amp;lt;math&amp;gt; \tilde{S_i} &amp;lt;/math&amp;gt; могут быть обработаны параллельно. В рамках каждого отдельного &amp;lt;math&amp;gt; \tilde{S_i} &amp;lt;/math&amp;gt; можно проводить распараллеливание дальше, так как &amp;lt;math&amp;gt; x_{lj} &amp;lt;/math&amp;gt; также не зависят друг от друга. Таким образом, вычисление всех слагаемых для всех &amp;lt;math&amp;gt; \tilde{\mu_{ij}} &amp;lt;/math&amp;gt; может быть выполнено за одно параллельное деление, а нахождение суммы всех этих слагаемых для каждого &amp;lt;math&amp;gt; \tilde{\mu_{ij}} &amp;lt;/math&amp;gt; может быть выполнено за &amp;lt;math&amp;gt; O(log(n)) &amp;lt;/math&amp;gt; в худшем случае (при вхождении почти всех объектов в один кластер).&lt;br /&gt;
&lt;br /&gt;
Если же такой методологии не существует, то узким местом становится процесс распределения на множества согласно вектору &amp;lt;math&amp;gt;index&amp;lt;/math&amp;gt;, который можно выполнить за &amp;lt;math&amp;gt; n &amp;lt;/math&amp;gt; операций косвенных адресаций. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;4)&#039;&#039;&#039; Все сравнения для критерия останова также независимы между собой и могут быть выполнены за одну операцию сравнения, а финальный результат может быть получен за одну операцию сложения при работе над общей памятью (к примеру, прибавление единицы при несовпадении в общую память и сравнение ее с 0 по завершению) или за &amp;lt;math&amp;gt;\log(k*d)&amp;lt;/math&amp;gt; сложений иначе.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Так как количество итераций ограничено константой, то на сложность оно не влияет. В итоге, параллельная сложность алгоритма k-means такова:&lt;br /&gt;
* &amp;lt;math&amp;gt; O(\log(n*d)) &amp;lt;/math&amp;gt; операций сложения&lt;br /&gt;
* &amp;lt;math&amp;gt; O(\log(k)) &amp;lt;/math&amp;gt; операций сравнения&lt;br /&gt;
* &amp;lt;math&amp;gt; O(1) &amp;lt;/math&amp;gt; операций умножения и деления&lt;br /&gt;
&lt;br /&gt;
== Входные и выходные данные алгоритма ==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Входные данные&#039;&#039;&#039;: Количество кластеров &amp;lt;b&amp;gt;k&amp;lt;/b&amp;gt;, &amp;lt;b&amp;gt;n&amp;lt;/b&amp;gt; кластеризуемых элементов&lt;br /&gt;
&lt;br /&gt;
Дополнительные ограничения:&lt;br /&gt;
* &amp;lt;b&amp;gt;k&amp;lt;/b&amp;gt; — положительное число, т. е. &amp;lt;b&amp;gt;k &amp;gt; 0&amp;lt;/b&amp;gt;.&lt;br /&gt;
* Для кластеризуемых элементов определена метрика (расстояние между объектами)&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Объём входных данных&#039;&#039;&#039;: &amp;lt;b&amp;gt;n &amp;lt;math&amp;gt;\cdot&amp;lt;/math&amp;gt; d + 1&amp;lt;/b&amp;gt; (кластеризуемые объекты в виде векторов и число &amp;lt;b&amp;gt;k&amp;lt;/b&amp;gt;)&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Выходные данные&#039;&#039;&#039;: Массив, в который записаны принадлежности каждого элемента кластеру (допустим вывод в другой эквивалентной более удобной структуре).&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Объём выходных данных&#039;&#039;&#039;:  Размер массива равен &amp;lt;b&amp;gt;2 &amp;lt;math&amp;gt;\cdot&amp;lt;/math&amp;gt; n&amp;lt;/b&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Свойства алгоритма ==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Ограничения алгоритма&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Алгоритм эффективно работает только на небольших объемах данных.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Преимущества алгоритма&#039;&#039;&#039;&lt;br /&gt;
* Простота использования&lt;br /&gt;
* Быстрота использования&lt;br /&gt;
* Понятность и прозрачность описания&lt;br /&gt;
* Обладает вычислительной устойчивостью&lt;br /&gt;
* Предрасположенность к распараллеливанию&lt;br /&gt;
* Достаточно популярный, поэтому имеет множество реализаций и вариаций&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Недостатки алгоритма&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
* Нет проверки корректности выбора числа кластеров&lt;br /&gt;
* Алгоритм чувствителен к количеству кластеров&lt;br /&gt;
* Алгоритм чувствителен к выбору начальных элементов в качестве центроидов &lt;br /&gt;
* Алгоритм крайне чувствителен к выбросам по данным&lt;br /&gt;
* Медленная работа на больших объемах данных&lt;br /&gt;
&lt;br /&gt;
= ЧАСТЬ. Программная реализация алгоритма =&lt;br /&gt;
&lt;br /&gt;
== Масштабируемость алгоритма и его реализации ==&lt;br /&gt;
&lt;br /&gt;
== Существующие реализации алгоритма ==&lt;br /&gt;
&lt;br /&gt;
=== Бесплатный доступ ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Десктопные программы&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
* [http://www.cs.waikato.ac.nz/ml/weka/ Weka]&lt;br /&gt;
* [http://docs.orange.biolab.si/2/reference/rst/Orange.clustering.kmeans.html Orange]&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Фреймворки для языков&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;Python:&#039;&#039;&#039;&lt;br /&gt;
** [http://scikit-learn.org/ scikit-learn]&lt;br /&gt;
** [https://www.scipy.org/ SciPy]&lt;br /&gt;
* &#039;&#039;&#039;C++:&#039;&#039;&#039;&lt;br /&gt;
** [http://mlpack.org/ MLPACK]&lt;br /&gt;
** [http://docs.opencv.org/3.0-beta/doc/py_tutorials/py_ml/py_kmeans/py_kmeans_opencv/py_kmeans_opencv.html OpenCV]&lt;br /&gt;
** [https://www.gnu.org/software/octave/ Octave] &lt;br /&gt;
* &#039;&#039;&#039;C#:&#039;&#039;&#039;  &lt;br /&gt;
** [http://accord-framework.net/docs/html/T_Accord_MachineLearning_KMeans.htm Accord.NET]&lt;br /&gt;
* &#039;&#039;&#039;Java:&#039;&#039;&#039;&lt;br /&gt;
** [http://elki.dbs.ifi.lmu.de ELKI]&lt;br /&gt;
** [https://mahout.apache.org Mahout]&lt;br /&gt;
* &#039;&#039;&#039;Lua&#039;&#039;&#039;&lt;br /&gt;
** [http://torch.ch Torch]&lt;br /&gt;
&lt;br /&gt;
Языки [https://www.r-bloggers.com/k-means-clustering-in-r/ R] и [http://juliastats.github.io Julia] содержат алгоритм k-means в базовой реализации.&lt;br /&gt;
&lt;br /&gt;
=== Платный доступ/лицензия  ===&lt;br /&gt;
&lt;br /&gt;
Существует целый перечень мощных статистических и математических пакетов для разных ОС:&lt;br /&gt;
* [http://www.mathworks.com/help/stats/kmeans.html?requestedDomain=www.mathworks.com MATLAB]&lt;br /&gt;
* [http://mathworld.wolfram.com/K-MeansClusteringAlgorithm.html Mathematica]&lt;br /&gt;
* [http://www.stata.com/features/cluster-analysis/ Stata]&lt;br /&gt;
* [https://support.sas.com/rnd/app/stat/procedures/fastclus.html SAS]&lt;br /&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]&lt;br /&gt;
* [http://docs.rapidminer.com/studio/operators/modeling/segmentation/k_means.html RapidMiner]&lt;br /&gt;
* ...&lt;br /&gt;
&lt;br /&gt;
= Литература =&lt;br /&gt;
[1] Нейский И.М. Классификация и сравнение методов кластеризации http://it-claim.ru/Persons/Neyskiy/Article2_Neiskiy.pdf&lt;br /&gt;
&lt;br /&gt;
[2] https://ru.wikipedia.org/wiki/K-means&lt;br /&gt;
&lt;br /&gt;
[[en:Description of algorithm properties and structure]]&lt;/div&gt;</summary>
		<author><name>Богомазов Евгений</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%98%D0%BB%D1%8C%D1%8F_%D0%95%D0%B3%D0%BE%D1%80%D0%BE%D0%B2/%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_k-%D1%81%D1%80%D0%B5%D0%B4%D0%BD%D0%B8%D1%85&amp;diff=10398</id>
		<title>Участник:Илья Егоров/Алгоритм k-средних</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%98%D0%BB%D1%8C%D1%8F_%D0%95%D0%B3%D0%BE%D1%80%D0%BE%D0%B2/%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_k-%D1%81%D1%80%D0%B5%D0%B4%D0%BD%D0%B8%D1%85&amp;diff=10398"/>
		<updated>2016-10-15T16:00:25Z</updated>

		<summary type="html">&lt;p&gt;Богомазов Евгений: /* Ресурс параллелизма алгоритма */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{algorithm&lt;br /&gt;
| name              = Алгоритм k-средних (k-means)&lt;br /&gt;
| serial_complexity = &amp;lt;math&amp;gt;O(n*k*d)&amp;lt;/math&amp;gt;&lt;br /&gt;
| input_data        = &amp;lt;math&amp;gt;n*d&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;quot;Илья Егоров — Евгений Богомазов&amp;quot;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
= ЧАСТЬ. Свойства и структура алгоритмов =&lt;br /&gt;
== Общее описание алгоритма ==&lt;br /&gt;
&lt;br /&gt;
Алгоритм кластеризации k-средних впервые был предложен в 1950-х годах математиками Гуго Штейнгаузом и Стюартом Ллойдом независимо друг от друга. Наибольшую популярность он получил после работы Маккуина.&lt;br /&gt;
&lt;br /&gt;
Алгоритм позволяет при заданном числе &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; построить &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластеров, расположенных на максимальном расстоянии друг от друга. Таким образом, наибольшей точности результат выполнения алгоритма достигает при полной осведомленности Пользователя о характере кластеризуемых объектов и, как следствие, при обладании максимально корректной информацией о числе кластеров.&lt;br /&gt;
&lt;br /&gt;
В общем случае выбор числа &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; может базироваться на любых значимых факторах, в том числе на результатах предшествующих исследований, теоретических соображениях или интуиции. &lt;br /&gt;
&lt;br /&gt;
== Математическое описание алгоритма ==&lt;br /&gt;
&#039;&#039;&#039;Исходные данные:&#039;&#039;&#039;&lt;br /&gt;
* Совокупность &amp;lt;b&amp;gt;n&amp;lt;/b&amp;gt; &amp;lt;b&amp;gt;d&amp;lt;/b&amp;gt;-мерных векторов &amp;lt;math&amp;gt; X = \{x_1 \dots x_n\} , &amp;lt;/math&amp;gt; где  &amp;lt;math&amp;gt; x_i = \{x_{i1} \dots x_{id}\} &amp;lt;/math&amp;gt;&lt;br /&gt;
* Предполагаемое количество кластеров &amp;lt;b&amp;gt;k&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Выходные данные:&#039;&#039;&#039;&lt;br /&gt;
* Разбиение X на множество &amp;lt;math&amp;gt; S = \{S_1 \dots S_k \}, \bigcup S_i = X, S_i \cap S_j = \emptyset, i \neq j &amp;lt;/math&amp;gt;&lt;br /&gt;
* k центров кластеров &amp;lt;math&amp;gt; \Mu = \{\mu_1 \dots \mu_k \} &amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt; \mu_i = \{\mu_{i1} \dots \mu_{id} \} &amp;lt;/math&amp;gt; такие, что&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; \begin{cases}\tilde{\mu_i} = \underset{y}{argmin } \sum_{x \in S_i} ||x-y||^2_E \\ \Mu = \underset{\tilde{\Mu}}{argmin } \sum_{i \in k} \sum_{x \in S_i} ||x-\tilde{\mu_i}||^2_E \end{cases} &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Алгоритм:&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
1) &amp;lt;math&amp;gt; \mu_{ij} = random &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
2) &amp;lt;math&amp;gt; S_i = \{x \in S | \underset{j}{argmin } ||x-\mu_j||_E = i\} i = 1 \dots k &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
3) &amp;lt;math&amp;gt; \tilde{\mu_{i}} = E_{x \in S_i}(x) &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
4) Если для &amp;lt;math&amp;gt; \forall i:  \mu_i = \tilde{\mu_i} &amp;lt;/math&amp;gt; то алгоритм завершен, иначе &amp;lt;math&amp;gt; \mu_i = \tilde{\mu_i} &amp;lt;/math&amp;gt; и перейти на пункт 2)&lt;br /&gt;
&lt;br /&gt;
== Вычислительное ядро алгоритма ==&lt;br /&gt;
&lt;br /&gt;
Вычислительным ядром алгоритма является второй этап, а точнее нахождение матрицы расстояний между &amp;lt;math&amp;gt;X&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\Mu&amp;lt;/math&amp;gt;. Для &#039;&#039;&#039;d&#039;&#039;&#039;-мерного вектора &amp;lt;math&amp;gt;a:&amp;lt;/math&amp;gt; &lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;||a||=\sqrt{\sum_{i=1\dots d} a_i^2}&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; операций сложения и одну операция вычисления квадратного корня. Но так как эти расстояния используются только для сравнения, а &#039;&#039;sqrt&#039;&#039; является монотонно возрастающей функцией, то ее можно не вычислять. Поэтому нахождения матрицы расстояний потребует всего &amp;lt;math&amp;gt;n*k*d&amp;lt;/math&amp;gt; операций умножений и &amp;lt;math&amp;gt;n*k*(d-1)&amp;lt;/math&amp;gt; операций сложений.&lt;br /&gt;
&lt;br /&gt;
== Макроструктура алгоритма ==&lt;br /&gt;
&lt;br /&gt;
Алгоритм k-средних базируется на алгоритме вычисления расстояния между векторами, расстояние на каждом шаге высчитывается &amp;lt;math&amp;gt;k\cdot n&amp;lt;/math&amp;gt; раз.&lt;br /&gt;
&lt;br /&gt;
Помимо этого, в конце каждого шага вычисляется центр масс объектов кластера, для всех объектов потребуется &amp;lt;math&amp;gt;n-1&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;
&lt;br /&gt;
&lt;br /&gt;
Последовательность шагов алгоритма следующая:&lt;br /&gt;
&lt;br /&gt;
    &#039;&#039;&#039;1) Инициализация центроидов &amp;lt;math&amp;gt;\Mu&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt; iter = 1 &amp;lt;/math&amp;gt;, задание максимального количество итераций &amp;lt;math&amp;gt;maxiter&amp;lt;/math&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
        &lt;br /&gt;
    &#039;&#039;&#039;2a) Нахождение матрицы расстояний &#039;&#039;&#039;&amp;lt;math&amp;gt;dist:&amp;lt;/math&amp;gt;&lt;br /&gt;
    &lt;br /&gt;
        &amp;lt;math&amp;gt;dist_{ij} = \sum_{l = 1\dots d} (x_{il}-\mu_{jl})^2&amp;lt;/math&amp;gt;&lt;br /&gt;
        &lt;br /&gt;
    &#039;&#039;&#039;2b) Нахождение вектора распределения объектов по кластерам &#039;&#039;&#039;&amp;lt;math&amp;gt;index: &amp;lt;/math&amp;gt;&lt;br /&gt;
    &lt;br /&gt;
        &amp;lt;math&amp;gt;index_{i} =   \underset{j}{argmin }~dist_{ij} &amp;lt;/math&amp;gt;&lt;br /&gt;
    &lt;br /&gt;
    &#039;&#039;&#039;3) Пересчет центроидов &#039;&#039;&#039;&amp;lt;math&amp;gt;\tilde{\Mu}:&amp;lt;/math&amp;gt;&lt;br /&gt;
    &lt;br /&gt;
        &amp;lt;math&amp;gt;\tilde{\mu_{ij}} = \sum_{l \in \tilde{S_i}} \dfrac{x_{lj}}{|\tilde{S_i}|} &amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;\tilde{S_i} = \{l~|~l \in 1\dots n, index_l = i\}  &amp;lt;/math&amp;gt;&lt;br /&gt;
    &lt;br /&gt;
    &#039;&#039;&#039;4) Проверка критерия останова:&#039;&#039;&#039;&lt;br /&gt;
    &lt;br /&gt;
        &#039;&#039;&#039;Если&#039;&#039;&#039; &amp;lt;math&amp;gt; \exists i: \tilde{\mu_i} \neq \mu_i&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt; iter &amp;lt; maxiter &amp;lt;/math&amp;gt;,&lt;br /&gt;
    &lt;br /&gt;
        &#039;&#039;&#039;то&#039;&#039;&#039; &amp;lt;math&amp;gt; inc(iter), \Mu=\tilde{\Mu},&amp;lt;/math&amp;gt; &#039;&#039;&#039;GOTO 2.а.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
== Последовательная сложность алгоритма ==&lt;br /&gt;
&lt;br /&gt;
    &#039;&#039;&#039;1)&#039;&#039;&#039; Сложность инициализации в общем случае зависит от применяемого метода генерации/получения случайных чисел, но ей можно пренебречь&lt;br /&gt;
    &lt;br /&gt;
    &#039;&#039;&#039;2a)&#039;&#039;&#039; Вычисление матрицы расстояний требует &amp;lt;math&amp;gt; n*k*d &amp;lt;/math&amp;gt; операций умножений и &amp;lt;math&amp;gt; n*k*(d-1) &amp;lt;/math&amp;gt; операций сложений&lt;br /&gt;
    &lt;br /&gt;
    &#039;&#039;&#039;2b)&#039;&#039;&#039; Нахождение вектора распределения требует &amp;lt;math&amp;gt; n*(k-1) &amp;lt;/math&amp;gt; операций сравнений&lt;br /&gt;
    &lt;br /&gt;
    &#039;&#039;&#039;3)&#039;&#039;&#039; Для вычисления &amp;lt;math&amp;gt; \tilde{\Mu} &amp;lt;/math&amp;gt; требуется &amp;lt;math&amp;gt; (n - k + 1) * d &amp;lt;/math&amp;gt; операций сложений и &amp;lt;math&amp;gt; k * d &amp;lt;/math&amp;gt; операций деления&lt;br /&gt;
    &lt;br /&gt;
    &#039;&#039;&#039;4)&#039;&#039;&#039; Для критерия останова требуется &amp;lt;math&amp;gt; n*d &amp;lt;/math&amp;gt; сравнений&lt;br /&gt;
&lt;br /&gt;
Итого: так как максимальное количество итераций задается в алгоритме заранее и не зависит от входных данных, то количество итераций ограничено константой. Тогда сложность алгоритма:&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;math&amp;gt; O(n*k*d)&amp;lt;/math&amp;gt; операций сложений/вычитаний&lt;br /&gt;
* &amp;lt;math&amp;gt; O(n*k*d)&amp;lt;/math&amp;gt; операций умножений, &amp;lt;math&amp;gt; O(k*d) &amp;lt;/math&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;
&#039;&#039;&#039;2a)&#039;&#039;&#039; Нахождение каждой ячейки матрицы &amp;lt;math&amp;gt; dist &amp;lt;/math&amp;gt; может происходить полностью независимо, так как они находятся на одном ярусе. При рассмотрении операции вычисления значения конкретной ячейки &amp;lt;math&amp;gt; dist_{ij} &amp;lt;/math&amp;gt; можно заметить, что все операции умножения также независимы между собой, поэтому понадобится всего одно умножение. Конечный результат получается в результате суммирования всех слагаемых и достигается параллельно за &amp;lt;math&amp;gt; \log(d) &amp;lt;/math&amp;gt; бинарных операций сложения при помощи стандартного метода &#039;&#039;reduction&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;2b)&#039;&#039;&#039; Нахождение вектора распределений заключается в нахождении минимального элемента в каждой строке матрицы &amp;lt;math&amp;gt; dist &amp;lt;/math&amp;gt;. При использовании &#039;&#039;reduction&#039;&#039; эту операцию можно выполнить за &amp;lt;math&amp;gt; \log(k) &amp;lt;/math&amp;gt; бинарных операций сравнения.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;3)&#039;&#039;&#039; В случае, если существует методология быстрого разделения &#039;&#039;&#039;n&#039;&#039;&#039; объектов на &#039;&#039;&#039;k&#039;&#039;&#039; множеств при помощи вектора индексации (косвенной адресации), все &amp;lt;math&amp;gt; \tilde{S_i} &amp;lt;/math&amp;gt; могут быть обработаны параллельно. В рамках каждого отдельного &amp;lt;math&amp;gt; \tilde{S_i} &amp;lt;/math&amp;gt; можно проводить распараллеливание дальше, так как &amp;lt;math&amp;gt; x_{lj} &amp;lt;/math&amp;gt; также не зависят друг от друга. Таким образом, вычисление всех слагаемых для всех &amp;lt;math&amp;gt; \tilde{\mu_{ij}} &amp;lt;/math&amp;gt; может быть выполнено за одно параллельное деление, а нахождение суммы всех этих слагаемых для каждого &amp;lt;math&amp;gt; \tilde{\mu_{ij}} &amp;lt;/math&amp;gt; может быть выполнено за &amp;lt;math&amp;gt; O(log(n)) &amp;lt;/math&amp;gt; в худшем случае (при вхождении почти всех объектов в один кластер).&lt;br /&gt;
&lt;br /&gt;
Если же такой методологии не существует, то узким местом становится процесс распределения на множества согласно вектору &amp;lt;math&amp;gt;index&amp;lt;/math&amp;gt;, который можно выполнить за &amp;lt;math&amp;gt; n &amp;lt;/math&amp;gt; операций косвенных адресаций. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;4)&#039;&#039;&#039; Все сравнения для критерия останова также независимы между собой и могут быть выполнены за одну операцию сравнения, а финальный результат может быть получен за одну операцию сложения при работе над общей памятью (к примеру, прибавление единицы при несовпадении в общую память и сравнение ее с 0 по завершению) или за &amp;lt;math&amp;gt;\log(k*d)&amp;lt;/math&amp;gt; сложений иначе.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Так как количество итераций ограничено константой, то на сложность оно не влияет. В итоге, параллельная сложность алгоритма k-means такова:&lt;br /&gt;
* &amp;lt;math&amp;gt; O(\log(n*d)) &amp;lt;/math&amp;gt; операций сложения&lt;br /&gt;
* &amp;lt;math&amp;gt; O(\log(k)) &amp;lt;/math&amp;gt; операций сравнения&lt;br /&gt;
* &amp;lt;math&amp;gt; O(1) &amp;lt;/math&amp;gt; операций умножения и деления&lt;br /&gt;
&lt;br /&gt;
== Входные и выходные данные алгоритма ==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Входные данные&#039;&#039;&#039;: Количество кластеров &amp;lt;b&amp;gt;k&amp;lt;/b&amp;gt;, &amp;lt;b&amp;gt;n&amp;lt;/b&amp;gt; кластеризуемых элементов&lt;br /&gt;
&lt;br /&gt;
Дополнительные ограничения:&lt;br /&gt;
* &amp;lt;b&amp;gt;k&amp;lt;/b&amp;gt; — положительное число, т. е. &amp;lt;b&amp;gt;k &amp;gt; 0&amp;lt;/b&amp;gt;.&lt;br /&gt;
* Для кластеризуемых элементов определена метрика (расстояние между объектами)&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Объём входных данных&#039;&#039;&#039;: &amp;lt;b&amp;gt;n &amp;lt;math&amp;gt;\cdot&amp;lt;/math&amp;gt; d + 1&amp;lt;/b&amp;gt; (кластеризуемые объекты в виде векторов и число &amp;lt;b&amp;gt;k&amp;lt;/b&amp;gt;)&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Выходные данные&#039;&#039;&#039;: Массив, в который записаны принадлежности каждого элемента кластеру (допустим вывод в другой эквивалентной более удобной структуре).&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Объём выходных данных&#039;&#039;&#039;:  Размер массива равен &amp;lt;b&amp;gt;2 &amp;lt;math&amp;gt;\cdot&amp;lt;/math&amp;gt; n&amp;lt;/b&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Свойства алгоритма ==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Ограничения алгоритма&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Алгоритм эффективно работает только на небольших объемах данных.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Преимущества алгоритма&#039;&#039;&#039;&lt;br /&gt;
* Простота использования&lt;br /&gt;
* Быстрота использования&lt;br /&gt;
* Понятность и прозрачность описания&lt;br /&gt;
* Обладает вычислительной устойчивостью&lt;br /&gt;
* Предрасположенность к распараллеливанию&lt;br /&gt;
* Достаточно популярный, поэтому имеет множество реализаций и вариаций&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Недостатки алгоритма&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
* Нет проверки корректности выбора числа кластеров&lt;br /&gt;
* Алгоритм чувствителен к количеству кластеров&lt;br /&gt;
* Алгоритм чувствителен к выбору начальных элементов в качестве центроидов &lt;br /&gt;
* Алгоритм крайне чувствителен к выбросам по данным&lt;br /&gt;
* Медленная работа на больших объемах данных&lt;br /&gt;
&lt;br /&gt;
= ЧАСТЬ. Программная реализация алгоритма =&lt;br /&gt;
&lt;br /&gt;
== Масштабируемость алгоритма и его реализации ==&lt;br /&gt;
&lt;br /&gt;
== Существующие реализации алгоритма ==&lt;br /&gt;
&lt;br /&gt;
=== Бесплатный доступ ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Десктопные программы&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
* [http://www.cs.waikato.ac.nz/ml/weka/ Weka]&lt;br /&gt;
* [http://docs.orange.biolab.si/2/reference/rst/Orange.clustering.kmeans.html Orange]&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Фреймворки для языков&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;Python:&#039;&#039;&#039;&lt;br /&gt;
** [http://scikit-learn.org/ scikit-learn]&lt;br /&gt;
** [https://www.scipy.org/ SciPy]&lt;br /&gt;
* &#039;&#039;&#039;C++:&#039;&#039;&#039;&lt;br /&gt;
** [http://mlpack.org/ MLPACK]&lt;br /&gt;
** [http://docs.opencv.org/3.0-beta/doc/py_tutorials/py_ml/py_kmeans/py_kmeans_opencv/py_kmeans_opencv.html OpenCV]&lt;br /&gt;
** [https://www.gnu.org/software/octave/ Octave] &lt;br /&gt;
* &#039;&#039;&#039;C#:&#039;&#039;&#039;  &lt;br /&gt;
** [http://accord-framework.net/docs/html/T_Accord_MachineLearning_KMeans.htm Accord.NET]&lt;br /&gt;
* &#039;&#039;&#039;Java:&#039;&#039;&#039;&lt;br /&gt;
** [http://elki.dbs.ifi.lmu.de ELKI]&lt;br /&gt;
** [https://mahout.apache.org Mahout]&lt;br /&gt;
* &#039;&#039;&#039;Lua&#039;&#039;&#039;&lt;br /&gt;
** [http://torch.ch Torch]&lt;br /&gt;
&lt;br /&gt;
Языки [https://www.r-bloggers.com/k-means-clustering-in-r/ R] и [http://juliastats.github.io Julia] содержат алгоритм k-means в базовой реализации.&lt;br /&gt;
&lt;br /&gt;
=== Платный доступ/лицензия  ===&lt;br /&gt;
&lt;br /&gt;
Существует целый перечень мощных статистических и математических пакетов для разных ОС:&lt;br /&gt;
* [http://www.mathworks.com/help/stats/kmeans.html?requestedDomain=www.mathworks.com MATLAB]&lt;br /&gt;
* [http://mathworld.wolfram.com/K-MeansClusteringAlgorithm.html Mathematica]&lt;br /&gt;
* [http://www.stata.com/features/cluster-analysis/ Stata]&lt;br /&gt;
* [https://support.sas.com/rnd/app/stat/procedures/fastclus.html SAS]&lt;br /&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]&lt;br /&gt;
* [http://docs.rapidminer.com/studio/operators/modeling/segmentation/k_means.html RapidMiner]&lt;br /&gt;
* ...&lt;br /&gt;
&lt;br /&gt;
= Литература =&lt;br /&gt;
[1] Нейский И.М. Классификация и сравнение методов кластеризации http://it-claim.ru/Persons/Neyskiy/Article2_Neiskiy.pdf&lt;br /&gt;
&lt;br /&gt;
[2] https://ru.wikipedia.org/wiki/K-means&lt;br /&gt;
&lt;br /&gt;
[[en:Description of algorithm properties and structure]]&lt;/div&gt;</summary>
		<author><name>Богомазов Евгений</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%98%D0%BB%D1%8C%D1%8F_%D0%95%D0%B3%D0%BE%D1%80%D0%BE%D0%B2/%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_k-%D1%81%D1%80%D0%B5%D0%B4%D0%BD%D0%B8%D1%85&amp;diff=10166</id>
		<title>Участник:Илья Егоров/Алгоритм k-средних</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%98%D0%BB%D1%8C%D1%8F_%D0%95%D0%B3%D0%BE%D1%80%D0%BE%D0%B2/%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_k-%D1%81%D1%80%D0%B5%D0%B4%D0%BD%D0%B8%D1%85&amp;diff=10166"/>
		<updated>2016-10-15T15:12:14Z</updated>

		<summary type="html">&lt;p&gt;Богомазов Евгений: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{algorithm&lt;br /&gt;
| name              = Алгоритм k-средних (k-means)&lt;br /&gt;
| serial_complexity = &amp;lt;math&amp;gt;O(n*k*d)&amp;lt;/math&amp;gt;&lt;br /&gt;
| input_data        = &amp;lt;math&amp;gt;n*d&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;quot;Илья Егоров — Евгений Богомазов&amp;quot;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
= ЧАСТЬ. Свойства и структура алгоритмов =&lt;br /&gt;
== Общее описание алгоритма ==&lt;br /&gt;
&lt;br /&gt;
Алгоритм кластеризации k-средних впервые был предложен в 1950-х годах математиками Гуго Штейнгаузом и Стюартом Ллойдом независимо друг от друга. Наибольшую популярность он получил после работы Маккуина.&lt;br /&gt;
&lt;br /&gt;
Алгоритм позволяет при заданном числе &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; построить &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластеров, расположенных на максимальном расстоянии друг от друга. Таким образом, наибольшей точности результат выполнения алгоритма достигает при полной осведомленности Пользователя о характере кластеризуемых объектов и, как следствие, при обладании максимально корректной информацией о числе кластеров.&lt;br /&gt;
&lt;br /&gt;
В общем случае выбор числа &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; может базироваться на любых значимых факторах, в том числе на результатах предшествующих исследований, теоретических соображениях или интуиции. &lt;br /&gt;
&lt;br /&gt;
== Математическое описание алгоритма ==&lt;br /&gt;
&#039;&#039;&#039;Исходные данные:&#039;&#039;&#039;&lt;br /&gt;
* Совокупность &amp;lt;b&amp;gt;n&amp;lt;/b&amp;gt; &amp;lt;b&amp;gt;d&amp;lt;/b&amp;gt;-мерных векторов &amp;lt;math&amp;gt; X = \{x_1 \dots x_n\} , &amp;lt;/math&amp;gt; где  &amp;lt;math&amp;gt; x_i = \{x_{i1} \dots x_{id}\} &amp;lt;/math&amp;gt;&lt;br /&gt;
* Предполагаемое количество кластеров &amp;lt;b&amp;gt;k&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Выходные данные:&#039;&#039;&#039;&lt;br /&gt;
* Разбиение X на множество &amp;lt;math&amp;gt; S = \{S_1 \dots S_k \}, \bigcup S_i = X, S_i \cap S_j = \emptyset, i \neq j &amp;lt;/math&amp;gt;&lt;br /&gt;
* k центров кластеров &amp;lt;math&amp;gt; \Mu = \{\mu_1 \dots \mu_k \} &amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt; \mu_i = \{\mu_{i1} \dots \mu_{id} \} &amp;lt;/math&amp;gt; такие, что&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; \begin{cases}\tilde{\mu_i} = \underset{y}{argmin } \sum_{x \in S_i} ||x-y||^2_E \\ \Mu = \underset{\tilde{\Mu}}{argmin } \sum_{i \in k} \sum_{x \in S_i} ||x-\tilde{\mu_i}||^2_E \end{cases} &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Алгоритм:&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
1) &amp;lt;math&amp;gt; \mu_{ij} = random &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
2) &amp;lt;math&amp;gt; S_i = \{x \in S | \underset{j}{argmin } ||x-\mu_j||_E = i\} i = 1 \dots k &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
3) &amp;lt;math&amp;gt; \tilde{\mu_{i}} = E_{x \in S_i}(x) &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
4) Если для &amp;lt;math&amp;gt; \forall i:  \mu_i = \tilde{\mu_i} &amp;lt;/math&amp;gt; то алгоритм завершен, иначе &amp;lt;math&amp;gt; \mu_i = \tilde{\mu_i} &amp;lt;/math&amp;gt; и перейти на пункт 2)&lt;br /&gt;
&lt;br /&gt;
== Вычислительное ядро алгоритма ==&lt;br /&gt;
&lt;br /&gt;
Вычислительным ядром алгоритма является второй этап, а точнее нахождение матрицы расстояний между &amp;lt;math&amp;gt;X&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\Mu&amp;lt;/math&amp;gt;. Для &#039;&#039;&#039;d&#039;&#039;&#039;-мерного вектора &amp;lt;math&amp;gt;a:&amp;lt;/math&amp;gt; &lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;||a||=\sqrt{\sum_{i=1\dots d} a_i^2}&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; операций сложения и одну операция вычисления квадратного корня. Но так как эти расстояния используются только для сравнения, а &#039;&#039;sqrt&#039;&#039; является монотонно возрастающей функцией, то ее можно не вычислять. Поэтому нахождения матрицы расстояний потребует всего &amp;lt;math&amp;gt;n*k*d&amp;lt;/math&amp;gt; операций умножений и &amp;lt;math&amp;gt;n*k*(d-1)&amp;lt;/math&amp;gt; операций сложений.&lt;br /&gt;
&lt;br /&gt;
== Макроструктура алгоритма ==&lt;br /&gt;
&lt;br /&gt;
Алгоритм k-средних базируется на алгоритме вычисления расстояния между векторами, расстояние на каждом шаге высчитывается &amp;lt;math&amp;gt;k\cdot n&amp;lt;/math&amp;gt; раз.&lt;br /&gt;
&lt;br /&gt;
Помимо этого, в конце каждого шага вычисляется центр масс объектов кластера, для всех объектов потребуется &amp;lt;math&amp;gt;n-1&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;
&lt;br /&gt;
&lt;br /&gt;
Последовательность шагов алгоритма следующая:&lt;br /&gt;
&lt;br /&gt;
    &#039;&#039;&#039;1. Инициализация центроидов &amp;lt;math&amp;gt;\Mu&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt; iter = 1 &amp;lt;/math&amp;gt;, задание максимального количество итераций &amp;lt;math&amp;gt;maxiter&amp;lt;/math&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
        &lt;br /&gt;
    &#039;&#039;&#039;2a. Нахождение матрицы расстояний &#039;&#039;&#039;&amp;lt;math&amp;gt;dist:&amp;lt;/math&amp;gt;&lt;br /&gt;
    &lt;br /&gt;
        &amp;lt;math&amp;gt;dist_{ij} = \sum_{l = 1\dots d} (x_{il}-\mu_{jl})^2&amp;lt;/math&amp;gt;&lt;br /&gt;
        &lt;br /&gt;
    &#039;&#039;&#039;2b. Нахождение вектора распределения объектов по кластерам &#039;&#039;&#039;&amp;lt;math&amp;gt;index: &amp;lt;/math&amp;gt;&lt;br /&gt;
    &lt;br /&gt;
        &amp;lt;math&amp;gt;index_{i} =   \underset{j}{argmin }~dist_{ij} &amp;lt;/math&amp;gt;&lt;br /&gt;
    &lt;br /&gt;
    &#039;&#039;&#039;3. Пересчет центроидов &#039;&#039;&#039;&amp;lt;math&amp;gt;\tilde{\Mu}:&amp;lt;/math&amp;gt;&lt;br /&gt;
    &lt;br /&gt;
        &amp;lt;math&amp;gt;\tilde{\mu_{ij}} = \sum_{l \in \tilde{S_i}} \dfrac{x_{lj}}{|\tilde{S_i}|} &amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;\tilde{S_i} = \{l~|~l \in 1\dots n, index_l = i\}  &amp;lt;/math&amp;gt;&lt;br /&gt;
    &lt;br /&gt;
    &#039;&#039;&#039;4. Проверка критерия останова:&#039;&#039;&#039;&lt;br /&gt;
    &lt;br /&gt;
        &#039;&#039;&#039;Если&#039;&#039;&#039; &amp;lt;math&amp;gt; \exists i: \tilde{\mu_i} \neq \mu_i&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt; iter &amp;lt; maxiter &amp;lt;/math&amp;gt;,&lt;br /&gt;
    &lt;br /&gt;
        &#039;&#039;&#039;то&#039;&#039;&#039; &amp;lt;math&amp;gt; inc(iter), \Mu=\tilde{\Mu},&amp;lt;/math&amp;gt; &#039;&#039;&#039;GOTO 2.а.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
== Последовательная сложность алгоритма ==&lt;br /&gt;
&lt;br /&gt;
    &#039;&#039;&#039;1)&#039;&#039;&#039; Сложность инициализации в общем случае зависит от применяемого метода генерации/получения случайных чисел, но ей можно пренебречь&lt;br /&gt;
    &lt;br /&gt;
    &#039;&#039;&#039;2a)&#039;&#039;&#039; Вычисление матрицы расстояний требует &amp;lt;math&amp;gt; n*k*d &amp;lt;/math&amp;gt; операций умножений и &amp;lt;math&amp;gt; n*k*(d-1) &amp;lt;/math&amp;gt; операций сложений&lt;br /&gt;
    &lt;br /&gt;
    &#039;&#039;&#039;2b)&#039;&#039;&#039; Нахождение вектора распределения требует &amp;lt;math&amp;gt; n*(k-1) &amp;lt;/math&amp;gt; операций сравнений&lt;br /&gt;
    &lt;br /&gt;
    &#039;&#039;&#039;3)&#039;&#039;&#039; Для вычисления &amp;lt;math&amp;gt; \tilde{\Mu} &amp;lt;/math&amp;gt; требуется &amp;lt;math&amp;gt; (n - k + 1) * d &amp;lt;/math&amp;gt; операций сложений и &amp;lt;math&amp;gt; k * d &amp;lt;/math&amp;gt; операций деления&lt;br /&gt;
    &lt;br /&gt;
    &#039;&#039;&#039;4)&#039;&#039;&#039; Для критерия останова требуется &amp;lt;math&amp;gt; n*d &amp;lt;/math&amp;gt; сравнений&lt;br /&gt;
&lt;br /&gt;
Итого: так как максимальное количество итераций задается в алгоритме заранее и не зависит от входных данных, то количество итераций ограничено константой. Тогда сложность алгоритма:&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;math&amp;gt; O(n*k*d)&amp;lt;/math&amp;gt; операций сложений/вычитаний&lt;br /&gt;
* &amp;lt;math&amp;gt; O(n*k*d)&amp;lt;/math&amp;gt; операций умножений, &amp;lt;math&amp;gt; O(k*d) &amp;lt;/math&amp;gt; операций делений&lt;br /&gt;
&lt;br /&gt;
== Информационный граф ==&lt;br /&gt;
&lt;br /&gt;
== Ресурс параллелизма алгоритма ==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Подправь стилистику!!!&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Для получения общей картины достаточно посмотреть, каким ресурсом параллелизма обладает каждый из этапов алгоритма с оглядкой на информационный граф:&lt;br /&gt;
&lt;br /&gt;
2a) Нахождение каждой ячейки матрицы &amp;lt;math&amp;gt; dist &amp;lt;/math&amp;gt; может происходить полностью независимо в виду нахождения их на одном ярусе. Рассмотрев вычисление конкретной ячейки &amp;lt;math&amp;gt; dist_{ij} &amp;lt;/math&amp;gt; можно заметить, &lt;br /&gt;
что все операции умножения также независимы между собой (поэтому понадобится всего одно умножение), а конечный результат получается в результате суммирования всех слагаемых. При помощи стандартной методологии reduction ее можно выполнить параллельно за &amp;lt;math&amp;gt; \log(d) &amp;lt;/math&amp;gt; бинарных операций сложения &lt;br /&gt;
&lt;br /&gt;
2b) Нахождение вектора распределений заключается в нахождение минимального элемента в каждой строке матрицы &amp;lt;math&amp;gt; dist &amp;lt;/math&amp;gt;. Снова при помощи reduction ее можно выполнить за &amp;lt;math&amp;gt; \log(k) &amp;lt;/math&amp;gt; бинарных операций сравнения&lt;br /&gt;
&lt;br /&gt;
3) При условии существовании методологии быстрого распределения n объектов на k множеств при помощи вектора индексации (косвенной адресации), то все &amp;lt;math&amp;gt; \tilde{S_i} &amp;lt;/math&amp;gt; могут быть обработаны параллельно. В рамках каждого отдельного &amp;lt;math&amp;gt; \tilde{S_i} &amp;lt;/math&amp;gt; можно проводить распараллеливание дальше, так как &amp;lt;math&amp;gt; x_{lj} &amp;lt;/math&amp;gt; также не зависят друг от друга, поэтому вычисление всех слагаемых для всех &amp;lt;math&amp;gt; \tilde{\mu_{ij}} &amp;lt;/math&amp;gt; может быть выполнено за одно параллельное деление, а нахождение суммы всех этих слагаемых для каждого &amp;lt;math&amp;gt; \tilde{\mu_{ij}} &amp;lt;/math&amp;gt; может быть выполнено за &amp;lt;math&amp;gt; O(log(n)) &amp;lt;/math&amp;gt; в худшем случае (при вхождение почти всех объектов в один кластер)&lt;br /&gt;
&lt;br /&gt;
Если же такой методологии не существуют, то узким местом становится распределения на множества согласно вектору &amp;lt;math&amp;gt;index&amp;lt;/math&amp;gt;, которое можно выполнить за &amp;lt;math&amp;gt; n &amp;lt;/math&amp;gt; операций косвенных адресаций. &lt;br /&gt;
&lt;br /&gt;
4) Все сравнения для критерия останова также независимы между собой и могут быть выполнены за одну операцию сравнения, финальный результат может быть получен за одну операцию сложения при работе над общей памятью(&#039;&#039;&#039;нужно ли объяснять как?&#039;&#039;&#039;, например прибавление единицы при несовпадении в общую память и сравнение ее с 0 по завершению (при этом пофиг на конфликты)) или за &amp;lt;math&amp;gt;\log(k*d)&amp;lt;/math&amp;gt; сложений иначе&lt;br /&gt;
&lt;br /&gt;
Так как количество итераций ограничено константой, то на сложность оно не влияет. Итого параллельная сложность алгоритма:&lt;br /&gt;
* &amp;lt;math&amp;gt; O(\log(n*d)) &amp;lt;/math&amp;gt; операций сложения&lt;br /&gt;
* &amp;lt;math&amp;gt; O(\log(k)) &amp;lt;/math&amp;gt; операций сравнения&lt;br /&gt;
* &amp;lt;math&amp;gt; O(1) &amp;lt;/math&amp;gt; операций умножений и делений&lt;br /&gt;
&lt;br /&gt;
== Входные и выходные данные алгоритма ==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Входные данные&#039;&#039;&#039;: Количество кластеров &amp;lt;b&amp;gt;k&amp;lt;/b&amp;gt;, &amp;lt;b&amp;gt;n&amp;lt;/b&amp;gt; кластеризуемых элементов&lt;br /&gt;
&lt;br /&gt;
Дополнительные ограничения:&lt;br /&gt;
* &amp;lt;b&amp;gt;k&amp;lt;/b&amp;gt; — положительное число, т. е. &amp;lt;b&amp;gt;k &amp;gt; 0&amp;lt;/b&amp;gt;.&lt;br /&gt;
* Для кластеризуемых элементов определена метрика (расстояние между объектами)&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Объём входных данных&#039;&#039;&#039;: &amp;lt;b&amp;gt;n &amp;lt;math&amp;gt;\cdot&amp;lt;/math&amp;gt; d + 1&amp;lt;/b&amp;gt; (кластеризуемые объекты в виде векторов и число &amp;lt;b&amp;gt;k&amp;lt;/b&amp;gt;)&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Выходные данные&#039;&#039;&#039;: Массив, в который записаны принадлежности каждого элемента кластеру (допустим вывод в другой эквивалентной более удобной структуре).&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Объём выходных данных&#039;&#039;&#039;:  Размер массива равен &amp;lt;b&amp;gt;2 &amp;lt;math&amp;gt;\cdot&amp;lt;/math&amp;gt; n&amp;lt;/b&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Свойства алгоритма ==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Ограничения алгоритма&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Алгоритм эффективно работает только на небольших объемах данных.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Преимущества алгоритма&#039;&#039;&#039;&lt;br /&gt;
* Простота использования&lt;br /&gt;
* Быстрота использования&lt;br /&gt;
* Понятность и прозрачность описания&lt;br /&gt;
* Обладает вычислительной устойчивостью&lt;br /&gt;
* Предрасположенность к распараллеливанию&lt;br /&gt;
* Достаточно популярный, поэтому имеет множество реализаций и вариаций&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Недостатки алгоритма&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
* Нет проверки корректности выбора числа кластеров&lt;br /&gt;
* Алгоритм чувствителен к количеству кластеров&lt;br /&gt;
* Алгоритм чувствителен к выбору начальных элементов в качестве центроидов &lt;br /&gt;
* Алгоритм крайне чувствителен к выбросам по данным&lt;br /&gt;
* Медленная работа на больших объемах данных&lt;br /&gt;
&lt;br /&gt;
= ЧАСТЬ. Программная реализация алгоритма =&lt;br /&gt;
&lt;br /&gt;
== Масштабируемость алгоритма и его реализации ==&lt;br /&gt;
&lt;br /&gt;
== Существующие реализации алгоритма ==&lt;br /&gt;
&lt;br /&gt;
=== Бесплатный доступ ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Десктопные программы&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
* [http://www.cs.waikato.ac.nz/ml/weka/ Weka]&lt;br /&gt;
* [http://docs.orange.biolab.si/2/reference/rst/Orange.clustering.kmeans.html Orange]&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Фреймворки для языков&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;Python:&#039;&#039;&#039;&lt;br /&gt;
** [http://scikit-learn.org/ scikit-learn]&lt;br /&gt;
** [https://www.scipy.org/ SciPy]&lt;br /&gt;
* &#039;&#039;&#039;C++:&#039;&#039;&#039;&lt;br /&gt;
** [http://mlpack.org/ MLPACK]&lt;br /&gt;
** [http://docs.opencv.org/3.0-beta/doc/py_tutorials/py_ml/py_kmeans/py_kmeans_opencv/py_kmeans_opencv.html OpenCV]&lt;br /&gt;
** [https://www.gnu.org/software/octave/ Octave] &lt;br /&gt;
* &#039;&#039;&#039;C#:&#039;&#039;&#039;  &lt;br /&gt;
** [http://accord-framework.net/docs/html/T_Accord_MachineLearning_KMeans.htm Accord.NET]&lt;br /&gt;
* &#039;&#039;&#039;Java:&#039;&#039;&#039;&lt;br /&gt;
** [http://elki.dbs.ifi.lmu.de ELKI]&lt;br /&gt;
** [https://mahout.apache.org Mahout]&lt;br /&gt;
* &#039;&#039;&#039;Lua&#039;&#039;&#039;&lt;br /&gt;
** [http://torch.ch Torch]&lt;br /&gt;
&lt;br /&gt;
Языки [https://www.r-bloggers.com/k-means-clustering-in-r/ R] и [http://juliastats.github.io Julia] содержат алгоритм k-means в базовой реализации.&lt;br /&gt;
&lt;br /&gt;
=== Платный доступ/лицензия  ===&lt;br /&gt;
&lt;br /&gt;
Существует целый перечень мощных статистических и математических пакетов для разных ОС:&lt;br /&gt;
* [http://www.mathworks.com/help/stats/kmeans.html?requestedDomain=www.mathworks.com MATLAB]&lt;br /&gt;
* [http://mathworld.wolfram.com/K-MeansClusteringAlgorithm.html Mathematica]&lt;br /&gt;
* [http://www.stata.com/features/cluster-analysis/ Stata]&lt;br /&gt;
* [https://support.sas.com/rnd/app/stat/procedures/fastclus.html SAS]&lt;br /&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]&lt;br /&gt;
* [http://docs.rapidminer.com/studio/operators/modeling/segmentation/k_means.html RapidMiner]&lt;br /&gt;
* ...&lt;br /&gt;
&lt;br /&gt;
= Литература =&lt;br /&gt;
[1] Нейский И.М. Классификация и сравнение методов кластеризации http://it-claim.ru/Persons/Neyskiy/Article2_Neiskiy.pdf&lt;br /&gt;
&lt;br /&gt;
[2] https://ru.wikipedia.org/wiki/K-means&lt;br /&gt;
&lt;br /&gt;
[[en:Description of algorithm properties and structure]]&lt;/div&gt;</summary>
		<author><name>Богомазов Евгений</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%98%D0%BB%D1%8C%D1%8F_%D0%95%D0%B3%D0%BE%D1%80%D0%BE%D0%B2/%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_k-%D1%81%D1%80%D0%B5%D0%B4%D0%BD%D0%B8%D1%85&amp;diff=9858</id>
		<title>Участник:Илья Егоров/Алгоритм k-средних</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%98%D0%BB%D1%8C%D1%8F_%D0%95%D0%B3%D0%BE%D1%80%D0%BE%D0%B2/%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_k-%D1%81%D1%80%D0%B5%D0%B4%D0%BD%D0%B8%D1%85&amp;diff=9858"/>
		<updated>2016-10-15T14:20:48Z</updated>

		<summary type="html">&lt;p&gt;Богомазов Евгений: /* Схема реализации последовательного алгоритма */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{algorithm&lt;br /&gt;
| name              = Алгоритм k-средних (k-means)&lt;br /&gt;
| serial_complexity = &amp;lt;math&amp;gt;O(n*k*d)&amp;lt;/math&amp;gt;&lt;br /&gt;
| input_data        = &amp;lt;math&amp;gt;n*d&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;quot;Илья Егоров — Евгений Богомазов&amp;quot;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
= ЧАСТЬ. Свойства и структура алгоритмов =&lt;br /&gt;
== Общее описание алгоритма ==&lt;br /&gt;
&lt;br /&gt;
Алгоритм кластеризации k-средних впервые был предложен в 1950-х годах математиками Гуго Штейнгаузом и Стюартом Ллойдом независимо друг от друга. Наибольшую популярность он получил после работы Маккуина.&lt;br /&gt;
&lt;br /&gt;
Алгоритм позволяет при заданном числе &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; построить &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластеров, расположенных на максимальном расстоянии друг от друга. Таким образом, наибольшей точности результат выполнения алгоритма достигает при полной осведомленности Пользователя о характере кластеризуемых объектов и, как следствие, при обладании максимально корректной информацией о числе кластеров.&lt;br /&gt;
&lt;br /&gt;
В общем случае выбор числа &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; может базироваться на любых значимых факторах, в том числе на результатах предшествующих исследований, теоретических соображениях или интуиции. &lt;br /&gt;
&lt;br /&gt;
== Математическое описание алгоритма ==&lt;br /&gt;
&#039;&#039;&#039;Исходные данные:&#039;&#039;&#039;&lt;br /&gt;
* Совокупность &amp;lt;b&amp;gt;n&amp;lt;/b&amp;gt; &amp;lt;b&amp;gt;d&amp;lt;/b&amp;gt;-мерных векторов &amp;lt;math&amp;gt; X = \{x_1 \dots x_n\} , &amp;lt;/math&amp;gt; где  &amp;lt;math&amp;gt; x_i = \{x_{i1} \dots x_{id}\} &amp;lt;/math&amp;gt;&lt;br /&gt;
* Предполагаемое количество кластеров &amp;lt;b&amp;gt;k&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Выходные данные:&#039;&#039;&#039;&lt;br /&gt;
* Разбиение X на множество &amp;lt;math&amp;gt; S = \{S_1 \dots S_k \}, \bigcup S_i = X, S_i \cap S_j = \emptyset, i \neq j &amp;lt;/math&amp;gt;&lt;br /&gt;
* k центров кластеров &amp;lt;math&amp;gt; \Mu = \{\mu_1 \dots \mu_k \} &amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt; \mu_i = \{\mu_{i1} \dots \mu_{id} \} &amp;lt;/math&amp;gt; такие, что&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; \begin{cases}\tilde{\mu_i} = \underset{y}{argmin } \sum_{x \in S_i} ||x-y||^2_E \\ \Mu = \underset{\tilde{\Mu}}{argmin } \sum_{i \in k} \sum_{x \in S_i} ||x-\tilde{\mu_i}||^2_E \end{cases} &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Алгоритм:&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
1) &amp;lt;math&amp;gt; \mu_{ij} = random &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
2) &amp;lt;math&amp;gt; S_i = \{x \in S | \underset{j}{argmin } ||x-\mu_j||_E = i\} i = 1 \dots k &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
3) &amp;lt;math&amp;gt; \tilde{\mu_{i}} = E_{x \in S_i}(x) &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
4) Если для &amp;lt;math&amp;gt; \forall i:  \mu_i = \tilde{\mu_i} &amp;lt;/math&amp;gt; то алгоритм завершен, иначе &amp;lt;math&amp;gt; \mu_i = \tilde{\mu_i} &amp;lt;/math&amp;gt; и перейти на пункт 2)&lt;br /&gt;
&lt;br /&gt;
== Вычислительное ядро алгоритма ==&lt;br /&gt;
&lt;br /&gt;
Вычислительным ядром алгоритма является второй этап, а точнее нахождение матрицы расстояний между &amp;lt;math&amp;gt;X&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\Mu&amp;lt;/math&amp;gt;. Для &#039;&#039;&#039;d&#039;&#039;&#039;-мерного вектора &amp;lt;math&amp;gt;a:&amp;lt;/math&amp;gt; &lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;||a||=\sqrt{\sum_{i=1\dots d} a_i^2}&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; операций сложения и одну операция вычисления квадратного корня. Но так как эти расстояния используются только для сравнения, а &#039;&#039;sqrt&#039;&#039; является монотонно возрастающей функцией, то ее можно не вычислять. Поэтому нахождения матрицы расстояний потребует всего &amp;lt;math&amp;gt;n*k*d&amp;lt;/math&amp;gt; операций умножений и &amp;lt;math&amp;gt;n*k*(d-1)&amp;lt;/math&amp;gt; операций сложений.&lt;br /&gt;
&lt;br /&gt;
== Макроструктура алгоритма ==&lt;br /&gt;
&lt;br /&gt;
Алгоритм k-средних базируется на алгоритме вычисления расстояния между векторами, расстояние на каждом шаге высчитывается &amp;lt;math&amp;gt;k\cdot n&amp;lt;/math&amp;gt; раз.&lt;br /&gt;
&lt;br /&gt;
Помимо этого, в конце каждого шага вычисляется центр масс объектов кластера, для всех объектов потребуется &amp;lt;math&amp;gt;n-1&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;
&lt;br /&gt;
&lt;br /&gt;
Последовательность шагов алгоритма следующая:&lt;br /&gt;
&lt;br /&gt;
    &#039;&#039;&#039;1. Инициализация центроидов &amp;lt;math&amp;gt;\Mu&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt; iter = 1 &amp;lt;/math&amp;gt;, задание максимального количество итераций &amp;lt;math&amp;gt;maxiter&amp;lt;/math&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
        &lt;br /&gt;
    &#039;&#039;&#039;2a. Нахождение матрицы расстояний &#039;&#039;&#039;&amp;lt;math&amp;gt;dist:&amp;lt;/math&amp;gt;&lt;br /&gt;
    &lt;br /&gt;
        &amp;lt;math&amp;gt;dist_{ij} = \sum_{l = 1\dots d} (x_{il}-\mu_{jl})^2&amp;lt;/math&amp;gt;&lt;br /&gt;
        &lt;br /&gt;
    &#039;&#039;&#039;2b. Нахождение вектора распределения объектов по кластерам &#039;&#039;&#039;&amp;lt;math&amp;gt;index: &amp;lt;/math&amp;gt;&lt;br /&gt;
    &lt;br /&gt;
        &amp;lt;math&amp;gt;index_{i} =   \underset{j}{argmin }~dist_{ij} &amp;lt;/math&amp;gt;&lt;br /&gt;
    &lt;br /&gt;
    &#039;&#039;&#039;3. Пересчет центроидов &#039;&#039;&#039;&amp;lt;math&amp;gt;\tilde{\Mu}:&amp;lt;/math&amp;gt;&lt;br /&gt;
    &lt;br /&gt;
        &amp;lt;math&amp;gt;\tilde{\mu_{ij}} = \sum_{l \in \tilde{S_i}} \dfrac{x_{lj}}{|\tilde{S_i}|} &amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;\tilde{S_i} = \{l~|~l \in 1\dots n, index_l = i\}  &amp;lt;/math&amp;gt;&lt;br /&gt;
    &lt;br /&gt;
    &#039;&#039;&#039;4. Проверка критерия останова:&#039;&#039;&#039;&lt;br /&gt;
    &lt;br /&gt;
        &#039;&#039;&#039;Если&#039;&#039;&#039; &amp;lt;math&amp;gt; \exists i: \tilde{\mu_i} \neq \mu_i&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt; iter &amp;lt; maxiter &amp;lt;/math&amp;gt;,&lt;br /&gt;
    &lt;br /&gt;
        &#039;&#039;&#039;то&#039;&#039;&#039; &amp;lt;math&amp;gt; inc(iter), \Mu=\tilde{\Mu},&amp;lt;/math&amp;gt; &#039;&#039;&#039;GOTO 2.а.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
== Последовательная сложность алгоритма ==&lt;br /&gt;
&lt;br /&gt;
    &#039;&#039;&#039;1)&#039;&#039;&#039; Сложность инициализации в общем случае зависит от применяемого метода генерации/получения случайных чисел, но ей можно пренебречь&lt;br /&gt;
    &lt;br /&gt;
    &#039;&#039;&#039;2a)&#039;&#039;&#039; Вычисление матрицы расстояний требует &amp;lt;math&amp;gt; n*k*d &amp;lt;/math&amp;gt; операций умножений и &amp;lt;math&amp;gt; n*k*(d-1) &amp;lt;/math&amp;gt; операций сложений&lt;br /&gt;
    &lt;br /&gt;
    &#039;&#039;&#039;2b)&#039;&#039;&#039; Нахождение вектора распределения требует &amp;lt;math&amp;gt; n*(k-1) &amp;lt;/math&amp;gt; операций сравнений&lt;br /&gt;
    &lt;br /&gt;
    &#039;&#039;&#039;3)&#039;&#039;&#039; Для вычисления &amp;lt;math&amp;gt; \tilde{\Mu} &amp;lt;/math&amp;gt; требуется &amp;lt;math&amp;gt; (n - k + 1) * d &amp;lt;/math&amp;gt; операций сложений и &amp;lt;math&amp;gt; k * d &amp;lt;/math&amp;gt; операций деления&lt;br /&gt;
    &lt;br /&gt;
    &#039;&#039;&#039;4)&#039;&#039;&#039; Для критерия останова требуется &amp;lt;math&amp;gt; n*d &amp;lt;/math&amp;gt; сравнений&lt;br /&gt;
&lt;br /&gt;
Итого: так как максимальное количество итераций задается в алгоритме заранее и не зависит от входных данных, то количество итераций ограничено константой. Тогда сложность алгоритма:&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;math&amp;gt; O(n*k*d)&amp;lt;/math&amp;gt; операций сложений/вычитаний&lt;br /&gt;
* &amp;lt;math&amp;gt; O(n*k*d)&amp;lt;/math&amp;gt; операций умножений, &amp;lt;math&amp;gt; O(k*d) &amp;lt;/math&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;
&#039;&#039;&#039;Входные данные&#039;&#039;&#039;: Количество кластеров &amp;lt;b&amp;gt;k&amp;lt;/b&amp;gt;, &amp;lt;b&amp;gt;n&amp;lt;/b&amp;gt; кластеризуемых элементов&lt;br /&gt;
&lt;br /&gt;
Дополнительные ограничения:&lt;br /&gt;
* &amp;lt;b&amp;gt;k&amp;lt;/b&amp;gt; — положительное число, т. е. &amp;lt;b&amp;gt;k &amp;gt; 0&amp;lt;/b&amp;gt;.&lt;br /&gt;
* Для кластеризуемых элементов определена метрика (расстояние между объектами)&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Объём входных данных&#039;&#039;&#039;: &amp;lt;b&amp;gt;n &amp;lt;math&amp;gt;\cdot&amp;lt;/math&amp;gt; d + 1&amp;lt;/b&amp;gt; (кластеризуемые объекты в виде векторов и число &amp;lt;b&amp;gt;k&amp;lt;/b&amp;gt;)&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Выходные данные&#039;&#039;&#039;: Массив, в который записаны принадлежности каждого элемента кластеру (допустим вывод в другой эквивалентной более удобной структуре).&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Объём выходных данных&#039;&#039;&#039;:  Размер массива равен &amp;lt;b&amp;gt;2 &amp;lt;math&amp;gt;\cdot&amp;lt;/math&amp;gt; n&amp;lt;/b&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Свойства алгоритма ==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Ограничения алгоритма&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Алгоритм эффективно работает только на небольших объемах данных.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Преимущества алгоритма&#039;&#039;&#039;&lt;br /&gt;
* Простота использования&lt;br /&gt;
* Быстрота использования&lt;br /&gt;
* Понятность и прозрачность описания&lt;br /&gt;
* Обладает вычислительной устойчивостью&lt;br /&gt;
* Предрасположенность к распараллеливанию&lt;br /&gt;
* Достаточно популярный, поэтому имеет множество реализаций и вариаций&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Недостатки алгоритма&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
* Нет проверки корректности выбора числа кластеров&lt;br /&gt;
* Алгоритм чувствителен к количеству кластеров&lt;br /&gt;
* Алгоритм чувствителен к выбору начальных элементов в качестве центроидов &lt;br /&gt;
* Алгоритм крайне чувствителен к выбросам по данным&lt;br /&gt;
* Медленная работа на больших объемах данных&lt;br /&gt;
&lt;br /&gt;
= ЧАСТЬ. Программная реализация алгоритма =&lt;br /&gt;
&lt;br /&gt;
== Масштабируемость алгоритма и его реализации ==&lt;br /&gt;
&lt;br /&gt;
== Существующие реализации алгоритма ==&lt;br /&gt;
&lt;br /&gt;
=== Бесплатный доступ ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Десктопные программы&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
* [http://www.cs.waikato.ac.nz/ml/weka/ Weka]&lt;br /&gt;
* [http://docs.orange.biolab.si/2/reference/rst/Orange.clustering.kmeans.html Orange]&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Фреймворки для языков&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;Python:&#039;&#039;&#039;&lt;br /&gt;
** [http://scikit-learn.org/ scikit-learn]&lt;br /&gt;
** [https://www.scipy.org/ SciPy]&lt;br /&gt;
* &#039;&#039;&#039;C++:&#039;&#039;&#039;&lt;br /&gt;
** [http://mlpack.org/ MLPACK]&lt;br /&gt;
** [http://docs.opencv.org/3.0-beta/doc/py_tutorials/py_ml/py_kmeans/py_kmeans_opencv/py_kmeans_opencv.html OpenCV]&lt;br /&gt;
** [https://www.gnu.org/software/octave/ Octave] &lt;br /&gt;
* &#039;&#039;&#039;C#:&#039;&#039;&#039;  &lt;br /&gt;
** [http://accord-framework.net/docs/html/T_Accord_MachineLearning_KMeans.htm Accord.NET]&lt;br /&gt;
* &#039;&#039;&#039;Java:&#039;&#039;&#039;&lt;br /&gt;
** [http://elki.dbs.ifi.lmu.de ELKI]&lt;br /&gt;
** [https://mahout.apache.org Mahout]&lt;br /&gt;
* &#039;&#039;&#039;Lua&#039;&#039;&#039;&lt;br /&gt;
** [http://torch.ch Torch]&lt;br /&gt;
&lt;br /&gt;
Языки [https://www.r-bloggers.com/k-means-clustering-in-r/ R] и [http://juliastats.github.io Julia] содержат алгоритм k-means в базовой реализации.&lt;br /&gt;
&lt;br /&gt;
=== Платный доступ/лицензия  ===&lt;br /&gt;
&lt;br /&gt;
Существует целый перечень мощных статистических и математических пакетов для разных ОС:&lt;br /&gt;
* [http://www.mathworks.com/help/stats/kmeans.html?requestedDomain=www.mathworks.com MATLAB]&lt;br /&gt;
* [http://mathworld.wolfram.com/K-MeansClusteringAlgorithm.html Mathematica]&lt;br /&gt;
* [http://www.stata.com/features/cluster-analysis/ Stata]&lt;br /&gt;
* [https://support.sas.com/rnd/app/stat/procedures/fastclus.html SAS]&lt;br /&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]&lt;br /&gt;
* [http://docs.rapidminer.com/studio/operators/modeling/segmentation/k_means.html RapidMiner]&lt;br /&gt;
* ...&lt;br /&gt;
&lt;br /&gt;
= Литература =&lt;br /&gt;
[1] Нейский И.М. Классификация и сравнение методов кластеризации http://it-claim.ru/Persons/Neyskiy/Article2_Neiskiy.pdf&lt;br /&gt;
&lt;br /&gt;
[2] https://ru.wikipedia.org/wiki/K-means&lt;br /&gt;
&lt;br /&gt;
[[en:Description of algorithm properties and structure]]&lt;/div&gt;</summary>
		<author><name>Богомазов Евгений</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%98%D0%BB%D1%8C%D1%8F_%D0%95%D0%B3%D0%BE%D1%80%D0%BE%D0%B2/%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_k-%D1%81%D1%80%D0%B5%D0%B4%D0%BD%D0%B8%D1%85&amp;diff=9840</id>
		<title>Участник:Илья Егоров/Алгоритм k-средних</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%98%D0%BB%D1%8C%D1%8F_%D0%95%D0%B3%D0%BE%D1%80%D0%BE%D0%B2/%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_k-%D1%81%D1%80%D0%B5%D0%B4%D0%BD%D0%B8%D1%85&amp;diff=9840"/>
		<updated>2016-10-15T14:14:27Z</updated>

		<summary type="html">&lt;p&gt;Богомазов Евгений: /* Схема реализации последовательного алгоритма */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{algorithm&lt;br /&gt;
| name              = Алгоритм k-средних (k-means)&lt;br /&gt;
| serial_complexity = &amp;lt;math&amp;gt;O(n*k*d)&amp;lt;/math&amp;gt;&lt;br /&gt;
| input_data        = &amp;lt;math&amp;gt;n*d&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;quot;Илья Егоров — Евгений Богомазов&amp;quot;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
= ЧАСТЬ. Свойства и структура алгоритмов =&lt;br /&gt;
== Общее описание алгоритма ==&lt;br /&gt;
&lt;br /&gt;
Алгоритм кластеризации k-средних впервые был предложен в 1950-х годах математиками Гуго Штейнгаузом и Стюартом Ллойдом независимо друг от друга. Наибольшую популярность он получил после работы Маккуина.&lt;br /&gt;
&lt;br /&gt;
Алгоритм позволяет при заданном числе &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; построить &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластеров, расположенных на максимальном расстоянии друг от друга. Таким образом, наибольшей точности результат выполнения алгоритма достигает при полной осведомленности Пользователя о характере кластеризуемых объектов и, как следствие, при обладании максимально корректной информацией о числе кластеров.&lt;br /&gt;
&lt;br /&gt;
В общем случае выбор числа &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; может базироваться на любых значимых факторах, в том числе на результатах предшествующих исследований, теоретических соображениях или интуиции. &lt;br /&gt;
&lt;br /&gt;
== Математическое описание алгоритма ==&lt;br /&gt;
&#039;&#039;&#039;Исходные данные:&#039;&#039;&#039;&lt;br /&gt;
* Совокупность &amp;lt;b&amp;gt;n&amp;lt;/b&amp;gt; &amp;lt;b&amp;gt;d&amp;lt;/b&amp;gt;-мерных векторов &amp;lt;math&amp;gt; X = \{x_1 \dots x_n\} , &amp;lt;/math&amp;gt; где  &amp;lt;math&amp;gt; x_i = \{x_{i1} \dots x_{id}\} &amp;lt;/math&amp;gt;&lt;br /&gt;
* Предполагаемое количество кластеров &amp;lt;b&amp;gt;k&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Выходные данные:&#039;&#039;&#039;&lt;br /&gt;
* Разбиение X на множество &amp;lt;math&amp;gt; S = \{S_1 \dots S_k \}, \bigcup S_i = X, S_i \cap S_j = \emptyset, i \neq j &amp;lt;/math&amp;gt;&lt;br /&gt;
* k центров кластеров &amp;lt;math&amp;gt; \Mu = \{\mu_1 \dots \mu_k \} &amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt; \mu_i = \{\mu_{i1} \dots \mu_{id} \} &amp;lt;/math&amp;gt; такие, что&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; \begin{cases}\tilde{\mu_i} = \underset{y}{argmin } \sum_{x \in S_i} ||x-y||^2_E \\ \Mu = \underset{\tilde{\Mu}}{argmin } \sum_{i \in k} \sum_{x \in S_i} ||x-\tilde{\mu_i}||^2_E \end{cases} &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Алгоритм:&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
1) &amp;lt;math&amp;gt; \mu_{ij} = random &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
2) &amp;lt;math&amp;gt; S_i = \{x \in S | \underset{j}{argmin } ||x-\mu_j||_E = i\} i = 1 \dots k &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
3) &amp;lt;math&amp;gt; \tilde{\mu_{i}} = E_{x \in S_i}(x) &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
4) Если для &amp;lt;math&amp;gt; \forall i:  \mu_i = \tilde{\mu_i} &amp;lt;/math&amp;gt; то алгоритм завершен, иначе &amp;lt;math&amp;gt; \mu_i = \tilde{\mu_i} &amp;lt;/math&amp;gt; и перейти на пункт 2)&lt;br /&gt;
&lt;br /&gt;
== Вычислительное ядро алгоритма ==&lt;br /&gt;
&lt;br /&gt;
Вычислительным ядром алгоритма является второй этап, а точнее нахождение матрицы расстояний между &amp;lt;math&amp;gt;X&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\Mu&amp;lt;/math&amp;gt;. Для &#039;&#039;&#039;d&#039;&#039;&#039;-мерного вектора &amp;lt;math&amp;gt;a:&amp;lt;/math&amp;gt; &lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;||a||=\sqrt{\sum_{i=1\dots d} a_i^2}&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; операций сложения и одну операция вычисления квадратного корня. Но так как эти расстояния используются только для сравнения, а &#039;&#039;sqrt&#039;&#039; является монотонно возрастающей функцией, то ее можно не вычислять. Поэтому нахождения матрицы расстояний потребует всего &amp;lt;math&amp;gt;n*k*d&amp;lt;/math&amp;gt; операций умножений и &amp;lt;math&amp;gt;n*k*(d-1)&amp;lt;/math&amp;gt; операций сложений.&lt;br /&gt;
&lt;br /&gt;
== Макроструктура алгоритма ==&lt;br /&gt;
&lt;br /&gt;
Алгоритм k-средних базируется на алгоритме вычисления расстояния между векторами, расстояние на каждом шаге высчитывается &amp;lt;math&amp;gt;k\cdot n&amp;lt;/math&amp;gt; раз.&lt;br /&gt;
&lt;br /&gt;
Помимо этого, в конце каждого шага вычисляется центр масс объектов кластера, для всех объектов потребуется &amp;lt;math&amp;gt;n-1&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;
&lt;br /&gt;
&lt;br /&gt;
Последовательность шагов алгоритма следующая:&lt;br /&gt;
&lt;br /&gt;
    &#039;&#039;&#039;1. Инициализация центроидов &amp;lt;math&amp;gt;\Mu&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt; iter = 1 &amp;lt;/math&amp;gt;, задание максимального количество итераций &amp;lt;math&amp;gt;maxiter&amp;lt;/math&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
        &lt;br /&gt;
    &#039;&#039;&#039;2a. Нахождение матрицы расстояний &#039;&#039;&#039;&amp;lt;math&amp;gt;dist:&amp;lt;/math&amp;gt;&lt;br /&gt;
    &lt;br /&gt;
        &amp;lt;math&amp;gt;dist_{ij} = \sum_{l = 1\dots d} (x_{il}-\mu_{jl})^2&amp;lt;/math&amp;gt;&lt;br /&gt;
        &lt;br /&gt;
    &#039;&#039;&#039;2b. Нахождение вектора распределения объектов по кластерам &#039;&#039;&#039;&amp;lt;math&amp;gt;index: &amp;lt;/math&amp;gt;&lt;br /&gt;
    &lt;br /&gt;
        &amp;lt;math&amp;gt;index_{i} =   \underset{j}{argmin }~dist_{ij} &amp;lt;/math&amp;gt;&lt;br /&gt;
    &lt;br /&gt;
    &#039;&#039;&#039;3. Пересчет центроидов &#039;&#039;&#039;&amp;lt;math&amp;gt;\tilde{\Mu}:&amp;lt;/math&amp;gt;&lt;br /&gt;
    &lt;br /&gt;
        &amp;lt;math&amp;gt;\tilde{\mu_{ij}} = \sum_{l \in T_i} \dfrac{x_{lj}}{|T_i|} &amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;T_i = \{l~|~l \in 1\dots n, index_l = i\}  &amp;lt;/math&amp;gt;&lt;br /&gt;
    &lt;br /&gt;
    &#039;&#039;&#039;4. Проверка критерия останова:&#039;&#039;&#039;&lt;br /&gt;
    &lt;br /&gt;
        &#039;&#039;&#039;Если&#039;&#039;&#039; &amp;lt;math&amp;gt; \exists i: \tilde{\mu_i} \neq \mu_i&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt; iter &amp;lt; maxiter &amp;lt;/math&amp;gt;,&lt;br /&gt;
    &lt;br /&gt;
        &#039;&#039;&#039;то&#039;&#039;&#039; &amp;lt;math&amp;gt; inc(iter), \Mu=\tilde{\Mu},&amp;lt;/math&amp;gt; &#039;&#039;&#039;GOTO 2.а.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
== Последовательная сложность алгоритма ==&lt;br /&gt;
&lt;br /&gt;
    &#039;&#039;&#039;1)&#039;&#039;&#039; Сложность инициализации в общем случае зависит от применяемого метода генерации/получения случайных чисел, но ей можно пренебречь&lt;br /&gt;
    &lt;br /&gt;
    &#039;&#039;&#039;2a)&#039;&#039;&#039; Вычисление матрицы расстояний требует &amp;lt;math&amp;gt; n*k*d &amp;lt;/math&amp;gt; операций умножений и &amp;lt;math&amp;gt; n*k*(d-1) &amp;lt;/math&amp;gt; операций сложений&lt;br /&gt;
    &lt;br /&gt;
    &#039;&#039;&#039;2b)&#039;&#039;&#039; Нахождение вектора распределения требует &amp;lt;math&amp;gt; n*(k-1) &amp;lt;/math&amp;gt; операций сравнений&lt;br /&gt;
    &lt;br /&gt;
    &#039;&#039;&#039;3)&#039;&#039;&#039; Для вычисления &amp;lt;math&amp;gt; \tilde{\Mu} &amp;lt;/math&amp;gt; требуется &amp;lt;math&amp;gt; (n - k + 1) * d &amp;lt;/math&amp;gt; операций сложений и &amp;lt;math&amp;gt; k * d &amp;lt;/math&amp;gt; операций деления&lt;br /&gt;
    &lt;br /&gt;
    &#039;&#039;&#039;4)&#039;&#039;&#039; Для критерия останова требуется &amp;lt;math&amp;gt; n*d &amp;lt;/math&amp;gt; сравнений&lt;br /&gt;
&lt;br /&gt;
Итого: так как максимальное количество итераций задается в алгоритме заранее и не зависит от входных данных, то количество итераций ограничено константой. Тогда сложность алгоритма:&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;math&amp;gt; O(n*k*d)&amp;lt;/math&amp;gt; операций сложений/вычитаний&lt;br /&gt;
* &amp;lt;math&amp;gt; O(n*k*d)&amp;lt;/math&amp;gt; операций умножений, &amp;lt;math&amp;gt; O(k*d) &amp;lt;/math&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;
&#039;&#039;&#039;Входные данные&#039;&#039;&#039;: Количество кластеров &amp;lt;b&amp;gt;k&amp;lt;/b&amp;gt;, &amp;lt;b&amp;gt;n&amp;lt;/b&amp;gt; кластеризуемых элементов&lt;br /&gt;
&lt;br /&gt;
Дополнительные ограничения:&lt;br /&gt;
* &amp;lt;b&amp;gt;k&amp;lt;/b&amp;gt; — положительное число, т. е. &amp;lt;b&amp;gt;k &amp;gt; 0&amp;lt;/b&amp;gt;.&lt;br /&gt;
* Для кластеризуемых элементов определена метрика (расстояние между объектами)&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Объём входных данных&#039;&#039;&#039;: &amp;lt;b&amp;gt;n &amp;lt;math&amp;gt;\cdot&amp;lt;/math&amp;gt; d + 1&amp;lt;/b&amp;gt; (кластеризуемые объекты в виде векторов и число &amp;lt;b&amp;gt;k&amp;lt;/b&amp;gt;)&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Выходные данные&#039;&#039;&#039;: Массив, в который записаны принадлежности каждого элемента кластеру (допустим вывод в другой эквивалентной более удобной структуре).&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Объём выходных данных&#039;&#039;&#039;:  Размер массива равен &amp;lt;b&amp;gt;2 &amp;lt;math&amp;gt;\cdot&amp;lt;/math&amp;gt; n&amp;lt;/b&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Свойства алгоритма ==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Ограничения алгоритма&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Алгоритм эффективно работает только на небольших объемах данных.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Преимущества алгоритма&#039;&#039;&#039;&lt;br /&gt;
* Простота использования&lt;br /&gt;
* Быстрота использования&lt;br /&gt;
* Понятность и прозрачность описания&lt;br /&gt;
* Обладает вычислительной устойчивостью&lt;br /&gt;
* Предрасположенность к распараллеливанию&lt;br /&gt;
* Достаточно популярный, поэтому имеет множество реализаций и вариаций&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Недостатки алгоритма&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
* Нет проверки корректности выбора числа кластеров&lt;br /&gt;
* Алгоритм чувствителен к количеству кластеров&lt;br /&gt;
* Алгоритм чувствителен к выбору начальных элементов в качестве центроидов &lt;br /&gt;
* Алгоритм крайне чувствителен к выбросам по данным&lt;br /&gt;
* Медленная работа на больших объемах данных&lt;br /&gt;
&lt;br /&gt;
= ЧАСТЬ. Программная реализация алгоритма =&lt;br /&gt;
&lt;br /&gt;
== Масштабируемость алгоритма и его реализации ==&lt;br /&gt;
&lt;br /&gt;
== Существующие реализации алгоритма ==&lt;br /&gt;
&lt;br /&gt;
=== Бесплатный доступ ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Десктопные программы&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
* [http://www.cs.waikato.ac.nz/ml/weka/ Weka]&lt;br /&gt;
* [http://docs.orange.biolab.si/2/reference/rst/Orange.clustering.kmeans.html Orange]&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Фреймворки для языков&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;Python:&#039;&#039;&#039;&lt;br /&gt;
** [http://scikit-learn.org/ scikit-learn]&lt;br /&gt;
** [https://www.scipy.org/ SciPy]&lt;br /&gt;
* &#039;&#039;&#039;C++:&#039;&#039;&#039;&lt;br /&gt;
** [http://mlpack.org/ MLPACK]&lt;br /&gt;
** [http://docs.opencv.org/3.0-beta/doc/py_tutorials/py_ml/py_kmeans/py_kmeans_opencv/py_kmeans_opencv.html OpenCV]&lt;br /&gt;
** [https://www.gnu.org/software/octave/ Octave] &lt;br /&gt;
* &#039;&#039;&#039;C#:&#039;&#039;&#039;  &lt;br /&gt;
** [http://accord-framework.net/docs/html/T_Accord_MachineLearning_KMeans.htm Accord.NET]&lt;br /&gt;
* &#039;&#039;&#039;Java:&#039;&#039;&#039;&lt;br /&gt;
** [http://elki.dbs.ifi.lmu.de ELKI]&lt;br /&gt;
** [https://mahout.apache.org Mahout]&lt;br /&gt;
* &#039;&#039;&#039;Lua&#039;&#039;&#039;&lt;br /&gt;
** [http://torch.ch Torch]&lt;br /&gt;
&lt;br /&gt;
Языки [https://www.r-bloggers.com/k-means-clustering-in-r/ R] и [http://juliastats.github.io Julia] содержат алгоритм k-means в базовой реализации.&lt;br /&gt;
&lt;br /&gt;
=== Платный доступ/лицензия  ===&lt;br /&gt;
&lt;br /&gt;
Существует целый перечень мощных статистических и математических пакетов для разных ОС:&lt;br /&gt;
* [http://www.mathworks.com/help/stats/kmeans.html?requestedDomain=www.mathworks.com MATLAB]&lt;br /&gt;
* [http://mathworld.wolfram.com/K-MeansClusteringAlgorithm.html Mathematica]&lt;br /&gt;
* [http://www.stata.com/features/cluster-analysis/ Stata]&lt;br /&gt;
* [https://support.sas.com/rnd/app/stat/procedures/fastclus.html SAS]&lt;br /&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]&lt;br /&gt;
* [http://docs.rapidminer.com/studio/operators/modeling/segmentation/k_means.html RapidMiner]&lt;br /&gt;
* ...&lt;br /&gt;
&lt;br /&gt;
= Литература =&lt;br /&gt;
[1] Нейский И.М. Классификация и сравнение методов кластеризации http://it-claim.ru/Persons/Neyskiy/Article2_Neiskiy.pdf&lt;br /&gt;
&lt;br /&gt;
[2] https://ru.wikipedia.org/wiki/K-means&lt;br /&gt;
&lt;br /&gt;
[[en:Description of algorithm properties and structure]]&lt;/div&gt;</summary>
		<author><name>Богомазов Евгений</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%98%D0%BB%D1%8C%D1%8F_%D0%95%D0%B3%D0%BE%D1%80%D0%BE%D0%B2/%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_k-%D1%81%D1%80%D0%B5%D0%B4%D0%BD%D0%B8%D1%85&amp;diff=8128</id>
		<title>Участник:Илья Егоров/Алгоритм k-средних</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%98%D0%BB%D1%8C%D1%8F_%D0%95%D0%B3%D0%BE%D1%80%D0%BE%D0%B2/%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_k-%D1%81%D1%80%D0%B5%D0%B4%D0%BD%D0%B8%D1%85&amp;diff=8128"/>
		<updated>2016-10-14T20:35:44Z</updated>

		<summary type="html">&lt;p&gt;Богомазов Евгений: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{algorithm&lt;br /&gt;
| name              = Алгоритм k-средних (k-means)&lt;br /&gt;
| serial_complexity = &amp;lt;math&amp;gt;O(n*k*d)&amp;lt;/math&amp;gt;&lt;br /&gt;
| input_data        = &amp;lt;math&amp;gt;n*d&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;quot;Илья Егоров — Евгений Богомазов&amp;quot;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
= ЧАСТЬ. Свойства и структура алгоритмов =&lt;br /&gt;
== Общее описание алгоритма ==&lt;br /&gt;
&lt;br /&gt;
Алгоритм кластеризации k-средних впервые был предложен в 1950-х годах математиками Гуго Штейнгаузом и Стюартом Ллойдом независимо друг от друга. Наибольшую популярность он получил после работы Маккуина.&lt;br /&gt;
&lt;br /&gt;
Алгоритм позволяет при заданном числе &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; построить &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластеров, расположенных на максимальном расстоянии друг от друга. Таким образом, наибольшей точности результат выполнения алгоритма достигает при полной осведомленности Пользователя о характере кластеризуемых объектов и, как следствие, при обладании максимально корректной информацией о числе кластеров.&lt;br /&gt;
&lt;br /&gt;
В общем случае выбор числа &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; может базироваться на любых значимых факторах, в том числе на результатах предшествующих исследований, теоретических соображениях или интуиции. &lt;br /&gt;
&lt;br /&gt;
== Математическое описание алгоритма ==&lt;br /&gt;
&#039;&#039;&#039;Исходные данные:&#039;&#039;&#039;&lt;br /&gt;
* Совокупность &amp;lt;b&amp;gt;n&amp;lt;/b&amp;gt; &amp;lt;b&amp;gt;d&amp;lt;/b&amp;gt;-мерных векторов &amp;lt;math&amp;gt; X = \{x_1 \dots x_n\} , &amp;lt;/math&amp;gt; где  &amp;lt;math&amp;gt; x_i = \{x_{i1} \dots x_{id}\} &amp;lt;/math&amp;gt;&lt;br /&gt;
* Предполагаемое количество кластеров &amp;lt;b&amp;gt;k&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Выходные данные:&#039;&#039;&#039;&lt;br /&gt;
* Разбиение X на множество &amp;lt;math&amp;gt; S = \{S_1 \dots S_k \}, \bigcup S_i = X, S_i \cap S_j = \emptyset, i \neq j &amp;lt;/math&amp;gt;&lt;br /&gt;
* k центров кластеров &amp;lt;math&amp;gt; \Mu = \{\mu_1 \dots \mu_k \} &amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt; \mu_i = \{\mu_{i1} \dots \mu_{id} \} &amp;lt;/math&amp;gt; такие, что&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; \begin{cases}\tilde{\mu_i} = \underset{y}{argmin } \sum_{x \in S_i} ||x-y||^2_E \\ \Mu = \underset{\tilde{\Mu}}{argmin } \sum_{i \in k} \sum_{x \in S_i} ||x-\tilde{\mu_i}||^2_E \end{cases} &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Алгоритм:&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
1) &amp;lt;math&amp;gt; \mu_{ij} = random &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
2) &amp;lt;math&amp;gt; S_i = \{x \in S | \underset{j}{argmin } ||x-\mu_j||_E = i\} i = 1 \dots k &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
3) &amp;lt;math&amp;gt; \tilde{\mu_{i}} = E_{x \in S_i}(x) &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
4) Если для &amp;lt;math&amp;gt; \forall i:  \mu_i = \tilde{\mu_i} &amp;lt;/math&amp;gt; то алгоритм завершен, иначе &amp;lt;math&amp;gt; \mu_i = \tilde{\mu_i} &amp;lt;/math&amp;gt; и перейти на пункт 2)&lt;br /&gt;
&lt;br /&gt;
== Вычислительное ядро алгоритма ==&lt;br /&gt;
&lt;br /&gt;
Вычислительным ядром алгоритма является второй этап, а точнее нахождение матрицы расстояний между &amp;lt;math&amp;gt;X&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\Mu&amp;lt;/math&amp;gt;. Для &#039;&#039;&#039;d&#039;&#039;&#039;-мерного вектора &amp;lt;math&amp;gt;a:&amp;lt;/math&amp;gt; &lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;||a||=\sqrt{\sum_{i=1\dots d} a_i^2}&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; операций сложения и одну операция вычисления квадратного корня. Но так как эти расстояния используются только для сравнения, а &#039;&#039;sqrt&#039;&#039; является монотонно возрастающей функцией, то ее можно не вычислять. Поэтому нахождения матрицы расстояний потребует всего &amp;lt;math&amp;gt;n*k*d&amp;lt;/math&amp;gt; операций умножений и &amp;lt;math&amp;gt;n*k*(d-1)&amp;lt;/math&amp;gt; операций сложений.&lt;br /&gt;
&lt;br /&gt;
== Макроструктура алгоритма ==&lt;br /&gt;
&lt;br /&gt;
Алгоритм k-средних базируется на алгоритме вычисления расстояния между векторами, расстояние на каждом шаге высчитывается &amp;lt;math&amp;gt;k\cdot n&amp;lt;/math&amp;gt; раз.&lt;br /&gt;
&lt;br /&gt;
Помимо этого, в конце каждого шага вычисляется центр масс объектов кластера, для всех объектов потребуется &amp;lt;math&amp;gt;n-1&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;
&lt;br /&gt;
&lt;br /&gt;
Последовательность шагов алгоритма следующая:&lt;br /&gt;
&lt;br /&gt;
    &#039;&#039;&#039;1. Инициализация центроидов &amp;lt;math&amp;gt;\Mu&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt; iter = 1 &amp;lt;/math&amp;gt;, задание максимального количество итераций &amp;lt;math&amp;gt;maxiter&amp;lt;/math&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
        &lt;br /&gt;
    &#039;&#039;&#039;2a. Нахождение матрицы расстояний &#039;&#039;&#039;&amp;lt;math&amp;gt;dist:&amp;lt;/math&amp;gt;&lt;br /&gt;
    &lt;br /&gt;
        &amp;lt;math&amp;gt;dist_{ij} = \sum_{l = 1\dots d} (x_{il}-\mu_{il})^2&amp;lt;/math&amp;gt;&lt;br /&gt;
        &lt;br /&gt;
    &#039;&#039;&#039;2b. Нахождение вектора распределения объектов по кластерам &#039;&#039;&#039;&amp;lt;math&amp;gt;index: &amp;lt;/math&amp;gt;&lt;br /&gt;
    &lt;br /&gt;
        &amp;lt;math&amp;gt;index_{i} =   \underset{j}{argmin }~dist_{ij} &amp;lt;/math&amp;gt;&lt;br /&gt;
    &lt;br /&gt;
    &#039;&#039;&#039;3. Пересчет центроидов &#039;&#039;&#039;&amp;lt;math&amp;gt;\tilde{\Mu}:&amp;lt;/math&amp;gt;&lt;br /&gt;
    &lt;br /&gt;
        &amp;lt;math&amp;gt;\tilde{\mu_{ij}} = \sum_{l \in T_i} \dfrac{x_{lj}}{|T_i|} &amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;T_i = \{l~|~l \in 1\dots n, index_l = i\}  &amp;lt;/math&amp;gt;&lt;br /&gt;
    &lt;br /&gt;
    &#039;&#039;&#039;4. Проверка критерия останова:&#039;&#039;&#039;&lt;br /&gt;
    &lt;br /&gt;
        &#039;&#039;&#039;Если&#039;&#039;&#039; &amp;lt;math&amp;gt; \exists i: \tilde{\mu_i} \neq \mu_i&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt; iter &amp;lt; maxiter &amp;lt;/math&amp;gt;,&lt;br /&gt;
    &lt;br /&gt;
        &#039;&#039;&#039;то&#039;&#039;&#039; &amp;lt;math&amp;gt; inc(iter), \Mu=\tilde{\Mu},&amp;lt;/math&amp;gt; &#039;&#039;&#039;GOTO 2.а.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
== Последовательная сложность алгоритма ==&lt;br /&gt;
&lt;br /&gt;
    &#039;&#039;&#039;1)&#039;&#039;&#039; Сложность инициализации в общем случае зависит от применяемого метода генерации/получения случайных чисел, но ей можно пренебречь&lt;br /&gt;
    &lt;br /&gt;
    &#039;&#039;&#039;2a)&#039;&#039;&#039; Вычисление матрицы расстояний требует &amp;lt;math&amp;gt; n*k*d &amp;lt;/math&amp;gt; операций умножений и &amp;lt;math&amp;gt; n*k*(d-1) &amp;lt;/math&amp;gt; операций сложений&lt;br /&gt;
    &lt;br /&gt;
    &#039;&#039;&#039;2b)&#039;&#039;&#039; Нахождение вектора распределения требует &amp;lt;math&amp;gt; n*(k-1) &amp;lt;/math&amp;gt; операций сравнений&lt;br /&gt;
    &lt;br /&gt;
    &#039;&#039;&#039;3)&#039;&#039;&#039; Для вычисления &amp;lt;math&amp;gt; \tilde{\Mu} &amp;lt;/math&amp;gt; требуется &amp;lt;math&amp;gt; (n - k + 1) * d &amp;lt;/math&amp;gt; операций сложений и &amp;lt;math&amp;gt; k * d &amp;lt;/math&amp;gt; операций деления&lt;br /&gt;
    &lt;br /&gt;
    &#039;&#039;&#039;4)&#039;&#039;&#039; Для критерия останова требуется &amp;lt;math&amp;gt; n*d &amp;lt;/math&amp;gt; сравнений&lt;br /&gt;
&lt;br /&gt;
Итого: так как максимальное количество итераций задается в алгоритме заранее и не зависит от входных данных, то количество итераций ограничено константой. Тогда сложность алгоритма:&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;math&amp;gt; O(n*k*d)&amp;lt;/math&amp;gt; операций сложений/вычитаний&lt;br /&gt;
* &amp;lt;math&amp;gt; O(n*k*d)&amp;lt;/math&amp;gt; операций умножений, &amp;lt;math&amp;gt; O(k*d) &amp;lt;/math&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;
&#039;&#039;&#039;Входные данные&#039;&#039;&#039;: Количество кластеров &amp;lt;b&amp;gt;k&amp;lt;/b&amp;gt;, &amp;lt;b&amp;gt;n&amp;lt;/b&amp;gt; кластеризуемых элементов&lt;br /&gt;
&lt;br /&gt;
Дополнительные ограничения:&lt;br /&gt;
* &amp;lt;b&amp;gt;k&amp;lt;/b&amp;gt; — положительное число, т. е. &amp;lt;b&amp;gt;k &amp;gt; 0&amp;lt;/b&amp;gt;.&lt;br /&gt;
* Для кластеризуемых элементов определена метрика (расстояние между объектами)&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Объём входных данных&#039;&#039;&#039;: &amp;lt;b&amp;gt;n &amp;lt;math&amp;gt;\cdot&amp;lt;/math&amp;gt; d + 1&amp;lt;/b&amp;gt; (кластеризуемые объекты в виде векторов и число &amp;lt;b&amp;gt;k&amp;lt;/b&amp;gt;)&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Выходные данные&#039;&#039;&#039;: Массив, в который записаны принадлежности каждого элемента кластеру (допустим вывод в другой эквивалентной более удобной структуре).&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Объём выходных данных&#039;&#039;&#039;:  Размер массива равен &amp;lt;b&amp;gt;2 &amp;lt;math&amp;gt;\cdot&amp;lt;/math&amp;gt; n&amp;lt;/b&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Свойства алгоритма ==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Ограничения алгоритма&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Алгоритм эффективно работает только на небольших объемах данных.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Преимущества алгоритма&#039;&#039;&#039;&lt;br /&gt;
* Простота использования&lt;br /&gt;
* Быстрота использования&lt;br /&gt;
* Понятность и прозрачность описания&lt;br /&gt;
* Обладает вычислительной устойчивостью&lt;br /&gt;
* Предрасположенность к распараллеливанию&lt;br /&gt;
* Достаточно популярный, поэтому имеет множество реализаций и вариаций&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Недостатки алгоритма&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
* Нет проверки корректности выбора числа кластеров&lt;br /&gt;
* Алгоритм чувствителен к количеству кластеров&lt;br /&gt;
* Алгоритм чувствителен к выбору начальных элементов в качестве центроидов &lt;br /&gt;
* Алгоритм крайне чувствителен к выбросам по данным&lt;br /&gt;
* Медленная работа на больших объемах данных&lt;br /&gt;
&lt;br /&gt;
= ЧАСТЬ. Программная реализация алгоритма =&lt;br /&gt;
&lt;br /&gt;
== Масштабируемость алгоритма и его реализации ==&lt;br /&gt;
&lt;br /&gt;
== Существующие реализации алгоритма ==&lt;br /&gt;
&lt;br /&gt;
=== Бесплатный доступ ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Десктопные программы&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
* [http://www.cs.waikato.ac.nz/ml/weka/ Weka]&lt;br /&gt;
* [http://docs.orange.biolab.si/2/reference/rst/Orange.clustering.kmeans.html Orange]&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Фреймворки для языков&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;Python:&#039;&#039;&#039;&lt;br /&gt;
** [http://scikit-learn.org/ scikit-learn]&lt;br /&gt;
** [https://www.scipy.org/ SciPy]&lt;br /&gt;
* &#039;&#039;&#039;C++:&#039;&#039;&#039;&lt;br /&gt;
** [http://mlpack.org/ MLPACK]&lt;br /&gt;
** [http://docs.opencv.org/3.0-beta/doc/py_tutorials/py_ml/py_kmeans/py_kmeans_opencv/py_kmeans_opencv.html OpenCV]&lt;br /&gt;
** [https://www.gnu.org/software/octave/ Octave] &lt;br /&gt;
* &#039;&#039;&#039;C#:&#039;&#039;&#039;  &lt;br /&gt;
** [http://accord-framework.net/docs/html/T_Accord_MachineLearning_KMeans.htm Accord.NET]&lt;br /&gt;
* &#039;&#039;&#039;Java:&#039;&#039;&#039;&lt;br /&gt;
** [http://elki.dbs.ifi.lmu.de ELKI]&lt;br /&gt;
** [https://mahout.apache.org Mahout]&lt;br /&gt;
* &#039;&#039;&#039;Lua&#039;&#039;&#039;&lt;br /&gt;
** [http://torch.ch Torch]&lt;br /&gt;
&lt;br /&gt;
Языки [https://www.r-bloggers.com/k-means-clustering-in-r/ R] и [http://juliastats.github.io Julia] содержат алгоритм k-means в базовой реализации.&lt;br /&gt;
&lt;br /&gt;
=== Платный доступ/лицензия  ===&lt;br /&gt;
&lt;br /&gt;
Существует целый перечень мощных статистических и математических пакетов для разных ОС:&lt;br /&gt;
* [http://www.mathworks.com/help/stats/kmeans.html?requestedDomain=www.mathworks.com MATLAB]&lt;br /&gt;
* [http://mathworld.wolfram.com/K-MeansClusteringAlgorithm.html Mathematica]&lt;br /&gt;
* [http://www.stata.com/features/cluster-analysis/ Stata]&lt;br /&gt;
* [https://support.sas.com/rnd/app/stat/procedures/fastclus.html SAS]&lt;br /&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]&lt;br /&gt;
* [http://docs.rapidminer.com/studio/operators/modeling/segmentation/k_means.html RapidMiner]&lt;br /&gt;
* ...&lt;br /&gt;
&lt;br /&gt;
= Литература =&lt;br /&gt;
[1] Нейский И.М. Классификация и сравнение методов кластеризации http://it-claim.ru/Persons/Neyskiy/Article2_Neiskiy.pdf&lt;br /&gt;
&lt;br /&gt;
[2] https://ru.wikipedia.org/wiki/K-means&lt;br /&gt;
&lt;br /&gt;
[[en:Description of algorithm properties and structure]]&lt;/div&gt;</summary>
		<author><name>Богомазов Евгений</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%98%D0%BB%D1%8C%D1%8F_%D0%95%D0%B3%D0%BE%D1%80%D0%BE%D0%B2/%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_k-%D1%81%D1%80%D0%B5%D0%B4%D0%BD%D0%B8%D1%85&amp;diff=8124</id>
		<title>Участник:Илья Егоров/Алгоритм k-средних</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%98%D0%BB%D1%8C%D1%8F_%D0%95%D0%B3%D0%BE%D1%80%D0%BE%D0%B2/%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_k-%D1%81%D1%80%D0%B5%D0%B4%D0%BD%D0%B8%D1%85&amp;diff=8124"/>
		<updated>2016-10-14T20:32:56Z</updated>

		<summary type="html">&lt;p&gt;Богомазов Евгений: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{algorithm&lt;br /&gt;
| name              = Алгоритм k-средних (k-means)&lt;br /&gt;
| serial_complexity = &amp;lt;math&amp;gt;O(n*k*d)&amp;lt;/math&amp;gt;&lt;br /&gt;
| input_data        = &amp;lt;math&amp;gt;n*d&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;quot;Илья Егоров — Евгений Богомазов&amp;quot;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
= ЧАСТЬ. Свойства и структура алгоритмов =&lt;br /&gt;
== Общее описание алгоритма ==&lt;br /&gt;
&lt;br /&gt;
Алгоритм кластеризации k-средних впервые был предложен в 1950-х годах математиками Гуго Штейнгаузом и Стюартом Ллойдом независимо друг от друга. Наибольшую популярность он получил после работы Маккуина.&lt;br /&gt;
&lt;br /&gt;
Алгоритм позволяет при заданном числе &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; построить &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластеров, расположенных на максимальном расстоянии друг от друга. Таким образом, наибольшей точности результат выполнения алгоритма достигает при полной осведомленности Пользователя о характере кластеризуемых объектов и, как следствие, при обладании максимально корректной информацией о числе кластеров.&lt;br /&gt;
&lt;br /&gt;
В общем случае выбор числа &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; может базироваться на любых значимых факторах, в том числе на результатах предшествующих исследований, теоретических соображениях или интуиции. &lt;br /&gt;
&lt;br /&gt;
== Математическое описание алгоритма ==&lt;br /&gt;
&#039;&#039;&#039;Исходные данные:&#039;&#039;&#039;&lt;br /&gt;
* Совокупность &amp;lt;b&amp;gt;n&amp;lt;/b&amp;gt; &amp;lt;b&amp;gt;d&amp;lt;/b&amp;gt;-мерных векторов &amp;lt;math&amp;gt; X = \{x_1 \dots x_n\} , &amp;lt;/math&amp;gt; где  &amp;lt;math&amp;gt; x_i = \{x_{i1} \dots x_{id}\} &amp;lt;/math&amp;gt;&lt;br /&gt;
* Предполагаемое количество кластеров &amp;lt;b&amp;gt;k&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Выходные данные:&#039;&#039;&#039;&lt;br /&gt;
* Разбиение X на множество &amp;lt;math&amp;gt; S = \{S_1 \dots S_k \}, \bigcup S_i = X, S_i \cap S_j = \emptyset, i \neq j &amp;lt;/math&amp;gt;&lt;br /&gt;
* k центров кластеров &amp;lt;math&amp;gt; \Mu = \{\mu_1 \dots \mu_k \} &amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt; \mu_i = \{\mu_{i1} \dots \mu_{id} \} &amp;lt;/math&amp;gt; такие, что&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; \begin{cases}\tilde{\mu_i} = \underset{y}{argmin } \sum_{x \in S_i} ||x-y||^2_E \\ \Mu = \underset{\tilde{\Mu}}{argmin } \sum_{i \in k} \sum_{x \in S_i} ||x-\tilde{\mu_i}||^2_E \end{cases} &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Алгоритм:&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
1) &amp;lt;math&amp;gt; \mu_{ij} = random &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
2) &amp;lt;math&amp;gt; S_i = \{x| \underset{j}{argmin } ||x-\mu_j||_E = i\} i = 1 \dots k &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
3) &amp;lt;math&amp;gt; \tilde{\mu_{i}} = E_{x \in S_i}(x) &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
4) Если для &amp;lt;math&amp;gt; \forall i:  \mu_i = \tilde{\mu_i} &amp;lt;/math&amp;gt; то алгоритм завершен, иначе &amp;lt;math&amp;gt; \mu_i = \tilde{\mu_i} &amp;lt;/math&amp;gt; и перейти на пункт 2)&lt;br /&gt;
&lt;br /&gt;
== Вычислительное ядро алгоритма ==&lt;br /&gt;
&lt;br /&gt;
Вычислительным ядром алгоритма является второй этап, а точнее нахождение матрицы расстояний между &amp;lt;math&amp;gt;X&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\Mu&amp;lt;/math&amp;gt;. Для &#039;&#039;&#039;d&#039;&#039;&#039;-мерного вектора &amp;lt;math&amp;gt;a:&amp;lt;/math&amp;gt; &lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;||a||=\sqrt{\sum_{i=1\dots d} a_i^2}&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; операций сложения и одну операция вычисления квадратного корня. Но так как эти расстояния используются только для сравнения, а &#039;&#039;sqrt&#039;&#039; является монотонно возрастающей функцией, то ее можно не вычислять. Поэтому нахождения матрицы расстояний потребует всего &amp;lt;math&amp;gt;n*k*d&amp;lt;/math&amp;gt; операций умножений и &amp;lt;math&amp;gt;n*k*(d-1)&amp;lt;/math&amp;gt; операций сложений.&lt;br /&gt;
&lt;br /&gt;
== Макроструктура алгоритма ==&lt;br /&gt;
&lt;br /&gt;
Алгоритм k-средних базируется на алгоритме вычисления расстояния между векторами, расстояние на каждом шаге высчитывается &amp;lt;math&amp;gt;k\cdot n&amp;lt;/math&amp;gt; раз.&lt;br /&gt;
&lt;br /&gt;
Помимо этого, в конце каждого шага вычисляется центр масс объектов кластера, для всех объектов потребуется &amp;lt;math&amp;gt;n-1&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;
&lt;br /&gt;
&lt;br /&gt;
Последовательность шагов алгоритма следующая:&lt;br /&gt;
&lt;br /&gt;
    &#039;&#039;&#039;1. Инициализация центроидов &amp;lt;math&amp;gt;\Mu&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt; iter = 1 &amp;lt;/math&amp;gt;, задание максимального количество итераций &amp;lt;math&amp;gt;maxiter&amp;lt;/math&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
        &lt;br /&gt;
    &#039;&#039;&#039;2a. Нахождение матрицы расстояний &#039;&#039;&#039;&amp;lt;math&amp;gt;dist:&amp;lt;/math&amp;gt;&lt;br /&gt;
    &lt;br /&gt;
        &amp;lt;math&amp;gt;dist_{ij} = \sum_{l = 1\dots d} (x_{il}-\mu_{il})^2&amp;lt;/math&amp;gt;&lt;br /&gt;
        &lt;br /&gt;
    &#039;&#039;&#039;2b. Нахождение вектора распределения объектов по кластерам &#039;&#039;&#039;&amp;lt;math&amp;gt;index: &amp;lt;/math&amp;gt;&lt;br /&gt;
    &lt;br /&gt;
        &amp;lt;math&amp;gt;index_{i} =   \underset{j}{argmin }~dist_{ij} &amp;lt;/math&amp;gt;&lt;br /&gt;
    &lt;br /&gt;
    &#039;&#039;&#039;3. Пересчет центроидов &#039;&#039;&#039;&amp;lt;math&amp;gt;\tilde{\Mu}:&amp;lt;/math&amp;gt;&lt;br /&gt;
    &lt;br /&gt;
        &amp;lt;math&amp;gt;\tilde{\mu_{ij}} = \sum_{l \in T_i} \dfrac{x_{lj}}{|T_i|} &amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;T_i = \{l~|~l \in 1\dots n, index_l = i\}  &amp;lt;/math&amp;gt;&lt;br /&gt;
    &lt;br /&gt;
    &#039;&#039;&#039;4. Проверка критерия останова:&#039;&#039;&#039;&lt;br /&gt;
    &lt;br /&gt;
        &#039;&#039;&#039;Если&#039;&#039;&#039; &amp;lt;math&amp;gt; \exists i: \tilde{\mu_i} \neq \mu_i&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt; iter &amp;lt; maxiter &amp;lt;/math&amp;gt;,&lt;br /&gt;
    &lt;br /&gt;
        &#039;&#039;&#039;то&#039;&#039;&#039; &amp;lt;math&amp;gt; inc(iter), \Mu=\tilde{\Mu},&amp;lt;/math&amp;gt; &#039;&#039;&#039;GOTO 2.а.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
== Последовательная сложность алгоритма ==&lt;br /&gt;
&lt;br /&gt;
    &#039;&#039;&#039;1)&#039;&#039;&#039; Сложность инициализации в общем случае зависит от применяемого метода генерации/получения случайных чисел, но ей можно пренебречь&lt;br /&gt;
    &lt;br /&gt;
    &#039;&#039;&#039;2a)&#039;&#039;&#039; Вычисление матрицы расстояний требует &amp;lt;math&amp;gt; n*k*d &amp;lt;/math&amp;gt; операций умножений и &amp;lt;math&amp;gt; n*k*(d-1) &amp;lt;/math&amp;gt; операций сложений&lt;br /&gt;
    &lt;br /&gt;
    &#039;&#039;&#039;2b)&#039;&#039;&#039; Нахождение вектора распределения требует &amp;lt;math&amp;gt; n*(k-1) &amp;lt;/math&amp;gt; операций сравнений&lt;br /&gt;
    &lt;br /&gt;
    &#039;&#039;&#039;3)&#039;&#039;&#039; Для вычисления &amp;lt;math&amp;gt; \tilde{\Mu} &amp;lt;/math&amp;gt; требуется &amp;lt;math&amp;gt; (n - k + 1) * d &amp;lt;/math&amp;gt; операций сложений и &amp;lt;math&amp;gt; k * d &amp;lt;/math&amp;gt; операций деления&lt;br /&gt;
    &lt;br /&gt;
    &#039;&#039;&#039;4)&#039;&#039;&#039; Для критерия останова требуется &amp;lt;math&amp;gt; n*d &amp;lt;/math&amp;gt; сравнений&lt;br /&gt;
&lt;br /&gt;
Итого: так как максимальное количество итераций задается в алгоритме заранее и не зависит от входных данных, то количество итераций ограничено константой. Тогда сложность алгоритма:&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;math&amp;gt; O(n*k*d)&amp;lt;/math&amp;gt; операций сложений/вычитаний&lt;br /&gt;
* &amp;lt;math&amp;gt; O(n*k*d)&amp;lt;/math&amp;gt; операций умножений, &amp;lt;math&amp;gt; O(k*d) &amp;lt;/math&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;
&#039;&#039;&#039;Входные данные&#039;&#039;&#039;: Количество кластеров &amp;lt;b&amp;gt;k&amp;lt;/b&amp;gt;, &amp;lt;b&amp;gt;n&amp;lt;/b&amp;gt; кластеризуемых элементов&lt;br /&gt;
&lt;br /&gt;
Дополнительные ограничения:&lt;br /&gt;
* &amp;lt;b&amp;gt;k&amp;lt;/b&amp;gt; — положительное число, т. е. &amp;lt;b&amp;gt;k &amp;gt; 0&amp;lt;/b&amp;gt;.&lt;br /&gt;
* Для кластеризуемых элементов определена метрика (расстояние между объектами)&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Объём входных данных&#039;&#039;&#039;: &amp;lt;b&amp;gt;n &amp;lt;math&amp;gt;\cdot&amp;lt;/math&amp;gt; d + 1&amp;lt;/b&amp;gt; (кластеризуемые объекты в виде векторов и число &amp;lt;b&amp;gt;k&amp;lt;/b&amp;gt;)&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Выходные данные&#039;&#039;&#039;: Массив, в который записаны принадлежности каждого элемента кластеру (допустим вывод в другой эквивалентной более удобной структуре).&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Объём выходных данных&#039;&#039;&#039;:  Размер массива равен &amp;lt;b&amp;gt;2 &amp;lt;math&amp;gt;\cdot&amp;lt;/math&amp;gt; n&amp;lt;/b&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Свойства алгоритма ==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Ограничения алгоритма&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Алгоритм эффективно работает только на небольших объемах данных.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Преимущества алгоритма&#039;&#039;&#039;&lt;br /&gt;
* Простота использования&lt;br /&gt;
* Быстрота использования&lt;br /&gt;
* Понятность и прозрачность описания&lt;br /&gt;
* Обладает вычислительной устойчивостью&lt;br /&gt;
* Предрасположенность к распараллеливанию&lt;br /&gt;
* Достаточно популярный, поэтому имеет множество реализаций и вариаций&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Недостатки алгоритма&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
* Нет проверки корректности выбора числа кластеров&lt;br /&gt;
* Алгоритм чувствителен к количеству кластеров&lt;br /&gt;
* Алгоритм чувствителен к выбору начальных элементов в качестве центроидов &lt;br /&gt;
* Алгоритм крайне чувствителен к выбросам по данным&lt;br /&gt;
* Медленная работа на больших объемах данных&lt;br /&gt;
&lt;br /&gt;
= ЧАСТЬ. Программная реализация алгоритма =&lt;br /&gt;
&lt;br /&gt;
== Масштабируемость алгоритма и его реализации ==&lt;br /&gt;
&lt;br /&gt;
== Существующие реализации алгоритма ==&lt;br /&gt;
&lt;br /&gt;
=== Бесплатный доступ ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Десктопные программы&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
* [http://www.cs.waikato.ac.nz/ml/weka/ Weka]&lt;br /&gt;
* [http://docs.orange.biolab.si/2/reference/rst/Orange.clustering.kmeans.html Orange]&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Фреймворки для языков&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;Python:&#039;&#039;&#039;&lt;br /&gt;
** [http://scikit-learn.org/ scikit-learn]&lt;br /&gt;
** [https://www.scipy.org/ SciPy]&lt;br /&gt;
* &#039;&#039;&#039;C++:&#039;&#039;&#039;&lt;br /&gt;
** [http://mlpack.org/ MLPACK]&lt;br /&gt;
** [http://docs.opencv.org/3.0-beta/doc/py_tutorials/py_ml/py_kmeans/py_kmeans_opencv/py_kmeans_opencv.html OpenCV]&lt;br /&gt;
** [https://www.gnu.org/software/octave/ Octave] &lt;br /&gt;
* &#039;&#039;&#039;C#:&#039;&#039;&#039;  &lt;br /&gt;
** [http://accord-framework.net/docs/html/T_Accord_MachineLearning_KMeans.htm Accord.NET]&lt;br /&gt;
* &#039;&#039;&#039;Java:&#039;&#039;&#039;&lt;br /&gt;
** [http://elki.dbs.ifi.lmu.de ELKI]&lt;br /&gt;
** [https://mahout.apache.org Mahout]&lt;br /&gt;
* &#039;&#039;&#039;Lua&#039;&#039;&#039;&lt;br /&gt;
** [http://torch.ch Torch]&lt;br /&gt;
&lt;br /&gt;
Языки [https://www.r-bloggers.com/k-means-clustering-in-r/ R] и [http://juliastats.github.io Julia] содержат алгоритм k-means в базовой реализации.&lt;br /&gt;
&lt;br /&gt;
=== Платный доступ/лицензия  ===&lt;br /&gt;
&lt;br /&gt;
Существует целый перечень мощных статистических и математических пакетов для разных ОС:&lt;br /&gt;
* [http://www.mathworks.com/help/stats/kmeans.html?requestedDomain=www.mathworks.com MATLAB]&lt;br /&gt;
* [http://mathworld.wolfram.com/K-MeansClusteringAlgorithm.html Mathematica]&lt;br /&gt;
* [http://www.stata.com/features/cluster-analysis/ Stata]&lt;br /&gt;
* [https://support.sas.com/rnd/app/stat/procedures/fastclus.html SAS]&lt;br /&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]&lt;br /&gt;
* [http://docs.rapidminer.com/studio/operators/modeling/segmentation/k_means.html RapidMiner]&lt;br /&gt;
* ...&lt;br /&gt;
&lt;br /&gt;
= Литература =&lt;br /&gt;
[1] Нейский И.М. Классификация и сравнение методов кластеризации http://it-claim.ru/Persons/Neyskiy/Article2_Neiskiy.pdf&lt;br /&gt;
&lt;br /&gt;
[2] https://ru.wikipedia.org/wiki/K-means&lt;br /&gt;
&lt;br /&gt;
[[en:Description of algorithm properties and structure]]&lt;/div&gt;</summary>
		<author><name>Богомазов Евгений</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%98%D0%BB%D1%8C%D1%8F_%D0%95%D0%B3%D0%BE%D1%80%D0%BE%D0%B2/%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_k-%D1%81%D1%80%D0%B5%D0%B4%D0%BD%D0%B8%D1%85&amp;diff=8100</id>
		<title>Участник:Илья Егоров/Алгоритм k-средних</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%98%D0%BB%D1%8C%D1%8F_%D0%95%D0%B3%D0%BE%D1%80%D0%BE%D0%B2/%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_k-%D1%81%D1%80%D0%B5%D0%B4%D0%BD%D0%B8%D1%85&amp;diff=8100"/>
		<updated>2016-10-14T20:17:23Z</updated>

		<summary type="html">&lt;p&gt;Богомазов Евгений: /* Свойства алгоритма */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{algorithm&lt;br /&gt;
| name              = Алгоритм k-средних (k-means)&lt;br /&gt;
| serial_complexity = &amp;lt;math&amp;gt;O()&amp;lt;/math&amp;gt;&lt;br /&gt;
| input_data        = &amp;lt;math&amp;gt;\frac{()}{}&amp;lt;/math&amp;gt;&lt;br /&gt;
| output_data       = &amp;lt;math&amp;gt;\frac{ ()}{}&amp;lt;/math&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&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;
Алгоритм кластеризации k-средних впервые был предложен в 1950-х годах математиками Гуго Штейнгаузом и Стюартом Ллойдом независимо друг от друга. Наибольшую популярность он получил после работы Маккуина.&lt;br /&gt;
&lt;br /&gt;
Алгоритм позволяет при заданном числе &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; построить &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластеров, расположенных на максимальном расстоянии друг от друга. Таким образом, наибольшей точности результат выполнения алгоритма достигает при полной осведомленности Пользователя о характере кластеризуемых объектов и, как следствие, при обладании максимально корректной информацией о числе кластеров.&lt;br /&gt;
&lt;br /&gt;
В общем случае выбор числа &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; может базироваться на любых значимых факторах, в том числе на результатах предшествующих исследований, теоретических соображениях или интуиции. &lt;br /&gt;
&lt;br /&gt;
== Математическое описание алгоритма ==&lt;br /&gt;
&#039;&#039;&#039;Исходные данные:&#039;&#039;&#039;&lt;br /&gt;
* Совокупность &amp;lt;b&amp;gt;n&amp;lt;/b&amp;gt; &amp;lt;b&amp;gt;d&amp;lt;/b&amp;gt;-мерных векторов &amp;lt;math&amp;gt; X = \{x_1 \dots x_n\} , &amp;lt;/math&amp;gt; где  &amp;lt;math&amp;gt; x_i = \{x_{i1} \dots x_{id}\} &amp;lt;/math&amp;gt;&lt;br /&gt;
* Предполагаемое количество кластеров &amp;lt;b&amp;gt;k&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Выходные данные:&#039;&#039;&#039;&lt;br /&gt;
* Разбиение X на множество &amp;lt;math&amp;gt; S = \{S_1 \dots S_k \}, \bigcup S_i = X, S_i \cap S_j = \emptyset, i \neq j &amp;lt;/math&amp;gt;&lt;br /&gt;
* k центров кластеров &amp;lt;math&amp;gt; \Mu = \{\mu_1 \dots \mu_k \} &amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt; \mu_i = \{\mu_{i1} \dots \mu_{id} \} &amp;lt;/math&amp;gt; такие, что&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; \begin{cases}\tilde{\mu_i} = \underset{y}{argmin } \sum_{x \in S_i} ||x-y||^2_E \\ \Mu = \underset{\tilde{\Mu}}{argmin } \sum_{i \in k} \sum_{x \in S_i} ||x-\tilde{\mu_i}||^2_E \end{cases} &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Алгоритм:&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
1) &amp;lt;math&amp;gt; \mu_{ij} = random &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
2) &amp;lt;math&amp;gt; S_i = \{x| \underset{j}{argmin } ||x-\mu_j||_E = i\} i = 1 \dots k &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
3) &amp;lt;math&amp;gt; \tilde{\mu_{i}} = E_{x \in S_i}(x) &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
4) Если для &amp;lt;math&amp;gt; \forall i:  \mu_i = \tilde{\mu_i} &amp;lt;/math&amp;gt; то алгоритм завершен, иначе &amp;lt;math&amp;gt; \mu_i = \tilde{\mu_i} &amp;lt;/math&amp;gt; и перейти на пункт 2)&lt;br /&gt;
&lt;br /&gt;
== Вычислительное ядро алгоритма ==&lt;br /&gt;
&lt;br /&gt;
Вычислительным ядром алгоритма является второй этап, а точнее нахождение матрицы расстояний между &amp;lt;math&amp;gt;X&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\Mu&amp;lt;/math&amp;gt;. Для &#039;&#039;&#039;d&#039;&#039;&#039;-мерного вектора &amp;lt;math&amp;gt;a:&amp;lt;/math&amp;gt; &lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;||a||=\sqrt{\sum_{i=1\dots d} a_i^2}&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; операций сложения и одну операция вычисления квадратного корня. Но так как эти расстояния используются только для сравнения, а &#039;&#039;sqrt&#039;&#039; является монотонно возрастающей функцией, то ее можно не вычислять. Поэтому нахождения матрицы расстояний потребует всего &amp;lt;math&amp;gt;n*k*d&amp;lt;/math&amp;gt; операций умножений и &amp;lt;math&amp;gt;n*k*(d-1)&amp;lt;/math&amp;gt; операций сложений.&lt;br /&gt;
&lt;br /&gt;
== Макроструктура алгоритма ==&lt;br /&gt;
&lt;br /&gt;
Алгоритм k-средних базируется на алгоритме вычисления расстояния между векторами, расстояние на каждом шаге высчитывается &amp;lt;math&amp;gt;k\cdot n&amp;lt;/math&amp;gt; раз.&lt;br /&gt;
&lt;br /&gt;
Помимо этого, в конце каждого шага вычисляется центр масс объектов кластера, для всех объектов потребуется &amp;lt;math&amp;gt;n-1&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;
&lt;br /&gt;
&lt;br /&gt;
Последовательность шагов алгоритма следующая:&lt;br /&gt;
&lt;br /&gt;
    &#039;&#039;&#039;1. Инициализация центроидов &amp;lt;math&amp;gt;\Mu&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt; iter = 1 &amp;lt;/math&amp;gt;, задание максимального количество итераций &amp;lt;math&amp;gt;maxiter&amp;lt;/math&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
        &lt;br /&gt;
    &#039;&#039;&#039;2a. Нахождение матрицы расстояний &#039;&#039;&#039;&amp;lt;math&amp;gt;dist:&amp;lt;/math&amp;gt;&lt;br /&gt;
    &lt;br /&gt;
        &amp;lt;math&amp;gt;dist_{ij} = \sum_{l = 1\dots d} (x_{il}-\mu_{il})^2&amp;lt;/math&amp;gt;&lt;br /&gt;
        &lt;br /&gt;
    &#039;&#039;&#039;2b. Нахождение вектора распределения объектов по кластерам &#039;&#039;&#039;&amp;lt;math&amp;gt;index: &amp;lt;/math&amp;gt;&lt;br /&gt;
    &lt;br /&gt;
        &amp;lt;math&amp;gt;index_{i} =   \underset{j}{argmin }~dist_{ij} &amp;lt;/math&amp;gt;&lt;br /&gt;
    &lt;br /&gt;
    &#039;&#039;&#039;3. Пересчет центроидов &#039;&#039;&#039;&amp;lt;math&amp;gt;\tilde{\Mu}:&amp;lt;/math&amp;gt;&lt;br /&gt;
    &lt;br /&gt;
        &amp;lt;math&amp;gt;\tilde{\mu_{ij}} = \sum_{l \in T_i} \dfrac{x_{lj}}{|T_i|} &amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;T_i = \{l~|~l \in 1\dots n, index_l = i\}  &amp;lt;/math&amp;gt;&lt;br /&gt;
    &lt;br /&gt;
    &#039;&#039;&#039;4. Проверка критерия останова:&#039;&#039;&#039;&lt;br /&gt;
    &lt;br /&gt;
        &#039;&#039;&#039;Если&#039;&#039;&#039; &amp;lt;math&amp;gt; \exists i: \tilde{\mu_i} \neq \mu_i&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt; iter &amp;lt; maxiter &amp;lt;/math&amp;gt;,&lt;br /&gt;
    &lt;br /&gt;
        &#039;&#039;&#039;то&#039;&#039;&#039; &amp;lt;math&amp;gt; inc(iter), \Mu=\tilde{\Mu},&amp;lt;/math&amp;gt; &#039;&#039;&#039;GOTO 2.а.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
== Последовательная сложность алгоритма ==&lt;br /&gt;
&lt;br /&gt;
    &#039;&#039;&#039;1)&#039;&#039;&#039; Сложность инициализации в общем случае зависит от применяемого метода генерации/получения случайных чисел, но ей можно пренебречь&lt;br /&gt;
    &lt;br /&gt;
    &#039;&#039;&#039;2a)&#039;&#039;&#039; Вычисление матрицы расстояний требует &amp;lt;math&amp;gt; n*k*d &amp;lt;/math&amp;gt; операций умножений и &amp;lt;math&amp;gt; n*k*(d-1) &amp;lt;/math&amp;gt; операций сложений&lt;br /&gt;
    &lt;br /&gt;
    &#039;&#039;&#039;2b)&#039;&#039;&#039; Нахождение вектора распределения требует &amp;lt;math&amp;gt; n*(k-1) &amp;lt;/math&amp;gt; операций сравнений&lt;br /&gt;
    &lt;br /&gt;
    &#039;&#039;&#039;3)&#039;&#039;&#039; Для вычисления &amp;lt;math&amp;gt; \tilde{\Mu} &amp;lt;/math&amp;gt; требуется &amp;lt;math&amp;gt; (n - k + 1) * d &amp;lt;/math&amp;gt; операций сложений и &amp;lt;math&amp;gt; k * d &amp;lt;/math&amp;gt; операций деления&lt;br /&gt;
    &lt;br /&gt;
    &#039;&#039;&#039;4)&#039;&#039;&#039; Для критерия останова требуется &amp;lt;math&amp;gt; n*d &amp;lt;/math&amp;gt; сравнений&lt;br /&gt;
&lt;br /&gt;
Итого: так как максимальное количество итераций задается в алгоритме заранее и не зависит от входных данных, то количество итераций ограничено константой. Тогда сложность алгоритма:&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;math&amp;gt; O(n*k*d)&amp;lt;/math&amp;gt; операций сложений/вычитаний&lt;br /&gt;
* &amp;lt;math&amp;gt; O(n*k*d)&amp;lt;/math&amp;gt; операций умножений, &amp;lt;math&amp;gt; O(k*d) &amp;lt;/math&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;
&#039;&#039;&#039;Входные данные&#039;&#039;&#039;: Количество кластеров &amp;lt;b&amp;gt;k&amp;lt;/b&amp;gt;, &amp;lt;b&amp;gt;n&amp;lt;/b&amp;gt; кластеризуемых элементов&lt;br /&gt;
&lt;br /&gt;
Дополнительные ограничения:&lt;br /&gt;
* &amp;lt;b&amp;gt;k&amp;lt;/b&amp;gt; — положительное число, т. е. &amp;lt;b&amp;gt;k &amp;gt; 0&amp;lt;/b&amp;gt;.&lt;br /&gt;
* Для кластеризуемых элементов определена метрика (расстояние между объектами)&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Объём входных данных&#039;&#039;&#039;: &amp;lt;b&amp;gt;n &amp;lt;math&amp;gt;\cdot&amp;lt;/math&amp;gt; d + 1&amp;lt;/b&amp;gt; (кластеризуемые объекты в виде векторов и число &amp;lt;b&amp;gt;k&amp;lt;/b&amp;gt;)&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Выходные данные&#039;&#039;&#039;: Массив, в который записаны принадлежности каждого элемента кластеру (допустим вывод в другой эквивалентной более удобной структуре).&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Объём выходных данных&#039;&#039;&#039;:  Размер массива равен &amp;lt;b&amp;gt;2 &amp;lt;math&amp;gt;\cdot&amp;lt;/math&amp;gt; n&amp;lt;/b&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Свойства алгоритма ==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Ограничения алгоритма&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Алгоритм эффективно работает только на небольших объемах данных.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Преимущества алгоритма&#039;&#039;&#039;&lt;br /&gt;
* Простота использования&lt;br /&gt;
* Быстрота использования&lt;br /&gt;
* Понятность и прозрачность описания&lt;br /&gt;
* Обладает вычислительной устойчивостью&lt;br /&gt;
* Предрасположенность к распараллеливанию&lt;br /&gt;
* Достаточно популярный, поэтому имеет множество реализаций и вариаций&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Недостатки алгоритма&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
* Нет проверки корректности выбора числа кластеров&lt;br /&gt;
* Алгоритм чувствителен к количеству кластеров&lt;br /&gt;
* Алгоритм чувствителен к выбору начальных элементов в качестве центроидов &lt;br /&gt;
* Алгоритм крайне чувствителен к выбросам по данным&lt;br /&gt;
* Медленная работа на больших объемах данных&lt;br /&gt;
&lt;br /&gt;
= ЧАСТЬ. Программная реализация алгоритма =&lt;br /&gt;
&lt;br /&gt;
== Масштабируемость алгоритма и его реализации ==&lt;br /&gt;
&lt;br /&gt;
== Существующие реализации алгоритма ==&lt;br /&gt;
&lt;br /&gt;
=== Бесплатный доступ ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Десктопные программы&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
* [http://www.cs.waikato.ac.nz/ml/weka/ Weka]&lt;br /&gt;
* [http://docs.orange.biolab.si/2/reference/rst/Orange.clustering.kmeans.html Orange]&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Фреймворки для языков&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;Python:&#039;&#039;&#039;&lt;br /&gt;
** [http://scikit-learn.org/ scikit-learn]&lt;br /&gt;
** [https://www.scipy.org/ SciPy]&lt;br /&gt;
* &#039;&#039;&#039;C++:&#039;&#039;&#039;&lt;br /&gt;
** [http://mlpack.org/ MLPACK]&lt;br /&gt;
** [http://docs.opencv.org/3.0-beta/doc/py_tutorials/py_ml/py_kmeans/py_kmeans_opencv/py_kmeans_opencv.html OpenCV]&lt;br /&gt;
** [https://www.gnu.org/software/octave/ Octave] &lt;br /&gt;
* &#039;&#039;&#039;C#:&#039;&#039;&#039;  &lt;br /&gt;
** [http://accord-framework.net/docs/html/T_Accord_MachineLearning_KMeans.htm Accord.NET]&lt;br /&gt;
* &#039;&#039;&#039;Java:&#039;&#039;&#039;&lt;br /&gt;
** [http://elki.dbs.ifi.lmu.de ELKI]&lt;br /&gt;
** [https://mahout.apache.org Mahout]&lt;br /&gt;
* &#039;&#039;&#039;Lua&#039;&#039;&#039;&lt;br /&gt;
** [http://torch.ch Torch]&lt;br /&gt;
&lt;br /&gt;
Языки [https://www.r-bloggers.com/k-means-clustering-in-r/ R] и [http://juliastats.github.io Julia] содержат алгоритм k-means в базовой реализации.&lt;br /&gt;
&lt;br /&gt;
=== Платный доступ/лицензия  ===&lt;br /&gt;
&lt;br /&gt;
Существует целый перечень мощных статистических и математических пакетов для разных ОС:&lt;br /&gt;
* [http://www.mathworks.com/help/stats/kmeans.html?requestedDomain=www.mathworks.com MATLAB]&lt;br /&gt;
* [http://mathworld.wolfram.com/K-MeansClusteringAlgorithm.html Mathematica]&lt;br /&gt;
* [http://www.stata.com/features/cluster-analysis/ Stata]&lt;br /&gt;
* [https://support.sas.com/rnd/app/stat/procedures/fastclus.html SAS]&lt;br /&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]&lt;br /&gt;
* [http://docs.rapidminer.com/studio/operators/modeling/segmentation/k_means.html RapidMiner]&lt;br /&gt;
* ...&lt;br /&gt;
&lt;br /&gt;
= Литература =&lt;br /&gt;
[1] Нейский И.М. Классификация и сравнение методов кластеризации http://it-claim.ru/Persons/Neyskiy/Article2_Neiskiy.pdf&lt;br /&gt;
&lt;br /&gt;
[2] https://ru.wikipedia.org/wiki/K-means&lt;br /&gt;
&lt;br /&gt;
[[en:Description of algorithm properties and structure]]&lt;/div&gt;</summary>
		<author><name>Богомазов Евгений</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%98%D0%BB%D1%8C%D1%8F_%D0%95%D0%B3%D0%BE%D1%80%D0%BE%D0%B2/%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_k-%D1%81%D1%80%D0%B5%D0%B4%D0%BD%D0%B8%D1%85&amp;diff=8097</id>
		<title>Участник:Илья Егоров/Алгоритм k-средних</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%98%D0%BB%D1%8C%D1%8F_%D0%95%D0%B3%D0%BE%D1%80%D0%BE%D0%B2/%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_k-%D1%81%D1%80%D0%B5%D0%B4%D0%BD%D0%B8%D1%85&amp;diff=8097"/>
		<updated>2016-10-14T20:15:50Z</updated>

		<summary type="html">&lt;p&gt;Богомазов Евгений: /* Математическое описание алгоритма */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{algorithm&lt;br /&gt;
| name              = Алгоритм k-средних (k-means)&lt;br /&gt;
| serial_complexity = &amp;lt;math&amp;gt;O()&amp;lt;/math&amp;gt;&lt;br /&gt;
| input_data        = &amp;lt;math&amp;gt;\frac{()}{}&amp;lt;/math&amp;gt;&lt;br /&gt;
| output_data       = &amp;lt;math&amp;gt;\frac{ ()}{}&amp;lt;/math&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&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;
Алгоритм кластеризации k-средних впервые был предложен в 1950-х годах математиками Гуго Штейнгаузом и Стюартом Ллойдом независимо друг от друга. Наибольшую популярность он получил после работы Маккуина.&lt;br /&gt;
&lt;br /&gt;
Алгоритм позволяет при заданном числе &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; построить &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластеров, расположенных на максимальном расстоянии друг от друга. Таким образом, наибольшей точности результат выполнения алгоритма достигает при полной осведомленности Пользователя о характере кластеризуемых объектов и, как следствие, при обладании максимально корректной информацией о числе кластеров.&lt;br /&gt;
&lt;br /&gt;
В общем случае выбор числа &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; может базироваться на любых значимых факторах, в том числе на результатах предшествующих исследований, теоретических соображениях или интуиции. &lt;br /&gt;
&lt;br /&gt;
== Математическое описание алгоритма ==&lt;br /&gt;
&#039;&#039;&#039;Исходные данные:&#039;&#039;&#039;&lt;br /&gt;
* Совокупность &amp;lt;b&amp;gt;n&amp;lt;/b&amp;gt; &amp;lt;b&amp;gt;d&amp;lt;/b&amp;gt;-мерных векторов &amp;lt;math&amp;gt; X = \{x_1 \dots x_n\} , &amp;lt;/math&amp;gt; где  &amp;lt;math&amp;gt; x_i = \{x_{i1} \dots x_{id}\} &amp;lt;/math&amp;gt;&lt;br /&gt;
* Предполагаемое количество кластеров &amp;lt;b&amp;gt;k&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Выходные данные:&#039;&#039;&#039;&lt;br /&gt;
* Разбиение X на множество &amp;lt;math&amp;gt; S = \{S_1 \dots S_k \}, \bigcup S_i = X, S_i \cap S_j = \emptyset, i \neq j &amp;lt;/math&amp;gt;&lt;br /&gt;
* k центров кластеров &amp;lt;math&amp;gt; \Mu = \{\mu_1 \dots \mu_k \} &amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt; \mu_i = \{\mu_{i1} \dots \mu_{id} \} &amp;lt;/math&amp;gt; такие, что&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; \begin{cases}\tilde{\mu_i} = \underset{y}{argmin } \sum_{x \in S_i} ||x-y||^2_E \\ \Mu = \underset{\tilde{\Mu}}{argmin } \sum_{i \in k} \sum_{x \in S_i} ||x-\tilde{\mu_i}||^2_E \end{cases} &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Алгоритм:&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
1) &amp;lt;math&amp;gt; \mu_{ij} = random &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
2) &amp;lt;math&amp;gt; S_i = \{x| \underset{j}{argmin } ||x-\mu_j||_E = i\} i = 1 \dots k &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
3) &amp;lt;math&amp;gt; \tilde{\mu_{i}} = E_{x \in S_i}(x) &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
4) Если для &amp;lt;math&amp;gt; \forall i:  \mu_i = \tilde{\mu_i} &amp;lt;/math&amp;gt; то алгоритм завершен, иначе &amp;lt;math&amp;gt; \mu_i = \tilde{\mu_i} &amp;lt;/math&amp;gt; и перейти на пункт 2)&lt;br /&gt;
&lt;br /&gt;
== Вычислительное ядро алгоритма ==&lt;br /&gt;
&lt;br /&gt;
Вычислительным ядром алгоритма является второй этап, а точнее нахождение матрицы расстояний между &amp;lt;math&amp;gt;X&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\Mu&amp;lt;/math&amp;gt;. Для &#039;&#039;&#039;d&#039;&#039;&#039;-мерного вектора &amp;lt;math&amp;gt;a:&amp;lt;/math&amp;gt; &lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;||a||=\sqrt{\sum_{i=1\dots d} a_i^2}&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; операций сложения и одну операция вычисления квадратного корня. Но так как эти расстояния используются только для сравнения, а &#039;&#039;sqrt&#039;&#039; является монотонно возрастающей функцией, то ее можно не вычислять. Поэтому нахождения матрицы расстояний потребует всего &amp;lt;math&amp;gt;n*k*d&amp;lt;/math&amp;gt; операций умножений и &amp;lt;math&amp;gt;n*k*(d-1)&amp;lt;/math&amp;gt; операций сложений.&lt;br /&gt;
&lt;br /&gt;
== Макроструктура алгоритма ==&lt;br /&gt;
&lt;br /&gt;
Алгоритм k-средних базируется на алгоритме вычисления расстояния между векторами, расстояние на каждом шаге высчитывается &amp;lt;math&amp;gt;k\cdot n&amp;lt;/math&amp;gt; раз.&lt;br /&gt;
&lt;br /&gt;
Помимо этого, в конце каждого шага вычисляется центр масс объектов кластера, для всех объектов потребуется &amp;lt;math&amp;gt;n-1&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;
&lt;br /&gt;
&lt;br /&gt;
Последовательность шагов алгоритма следующая:&lt;br /&gt;
&lt;br /&gt;
    &#039;&#039;&#039;1. Инициализация центроидов &amp;lt;math&amp;gt;\Mu&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt; iter = 1 &amp;lt;/math&amp;gt;, задание максимального количество итераций &amp;lt;math&amp;gt;maxiter&amp;lt;/math&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
        &lt;br /&gt;
    &#039;&#039;&#039;2a. Нахождение матрицы расстояний &#039;&#039;&#039;&amp;lt;math&amp;gt;dist:&amp;lt;/math&amp;gt;&lt;br /&gt;
    &lt;br /&gt;
        &amp;lt;math&amp;gt;dist_{ij} = \sum_{l = 1\dots d} (x_{il}-\mu_{il})^2&amp;lt;/math&amp;gt;&lt;br /&gt;
        &lt;br /&gt;
    &#039;&#039;&#039;2b. Нахождение вектора распределения объектов по кластерам &#039;&#039;&#039;&amp;lt;math&amp;gt;index: &amp;lt;/math&amp;gt;&lt;br /&gt;
    &lt;br /&gt;
        &amp;lt;math&amp;gt;index_{i} =   \underset{j}{argmin }~dist_{ij} &amp;lt;/math&amp;gt;&lt;br /&gt;
    &lt;br /&gt;
    &#039;&#039;&#039;3. Пересчет центроидов &#039;&#039;&#039;&amp;lt;math&amp;gt;\tilde{\Mu}:&amp;lt;/math&amp;gt;&lt;br /&gt;
    &lt;br /&gt;
        &amp;lt;math&amp;gt;\tilde{\mu_{ij}} = \sum_{l \in T_i} \dfrac{x_{lj}}{|T_i|} &amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;T_i = \{l~|~l \in 1\dots n, index_l = i\}  &amp;lt;/math&amp;gt;&lt;br /&gt;
    &lt;br /&gt;
    &#039;&#039;&#039;4. Проверка критерия останова:&#039;&#039;&#039;&lt;br /&gt;
    &lt;br /&gt;
        &#039;&#039;&#039;Если&#039;&#039;&#039; &amp;lt;math&amp;gt; \exists i: \tilde{\mu_i} \neq \mu_i&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt; iter &amp;lt; maxiter &amp;lt;/math&amp;gt;,&lt;br /&gt;
    &lt;br /&gt;
        &#039;&#039;&#039;то&#039;&#039;&#039; &amp;lt;math&amp;gt; inc(iter), \Mu=\tilde{\Mu},&amp;lt;/math&amp;gt; &#039;&#039;&#039;GOTO 2.а.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
== Последовательная сложность алгоритма ==&lt;br /&gt;
&lt;br /&gt;
    &#039;&#039;&#039;1)&#039;&#039;&#039; Сложность инициализации в общем случае зависит от применяемого метода генерации/получения случайных чисел, но ей можно пренебречь&lt;br /&gt;
    &lt;br /&gt;
    &#039;&#039;&#039;2a)&#039;&#039;&#039; Вычисление матрицы расстояний требует &amp;lt;math&amp;gt; n*k*d &amp;lt;/math&amp;gt; операций умножений и &amp;lt;math&amp;gt; n*k*(d-1) &amp;lt;/math&amp;gt; операций сложений&lt;br /&gt;
    &lt;br /&gt;
    &#039;&#039;&#039;2b)&#039;&#039;&#039; Нахождение вектора распределения требует &amp;lt;math&amp;gt; n*(k-1) &amp;lt;/math&amp;gt; операций сравнений&lt;br /&gt;
    &lt;br /&gt;
    &#039;&#039;&#039;3)&#039;&#039;&#039; Для вычисления &amp;lt;math&amp;gt; \tilde{\Mu} &amp;lt;/math&amp;gt; требуется &amp;lt;math&amp;gt; (n - k + 1) * d &amp;lt;/math&amp;gt; операций сложений и &amp;lt;math&amp;gt; k * d &amp;lt;/math&amp;gt; операций деления&lt;br /&gt;
    &lt;br /&gt;
    &#039;&#039;&#039;4)&#039;&#039;&#039; Для критерия останова требуется &amp;lt;math&amp;gt; n*d &amp;lt;/math&amp;gt; сравнений&lt;br /&gt;
&lt;br /&gt;
Итого: так как максимальное количество итераций задается в алгоритме заранее и не зависит от входных данных, то количество итераций ограничено константой. Тогда сложность алгоритма:&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;math&amp;gt; O(n*k*d)&amp;lt;/math&amp;gt; операций сложений/вычитаний&lt;br /&gt;
* &amp;lt;math&amp;gt; O(n*k*d)&amp;lt;/math&amp;gt; операций умножений, &amp;lt;math&amp;gt; O(k*d) &amp;lt;/math&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;
&#039;&#039;&#039;Входные данные&#039;&#039;&#039;: Количество кластеров &amp;lt;b&amp;gt;k&amp;lt;/b&amp;gt;, &amp;lt;b&amp;gt;n&amp;lt;/b&amp;gt; кластеризуемых элементов&lt;br /&gt;
&lt;br /&gt;
Дополнительные ограничения:&lt;br /&gt;
* &amp;lt;b&amp;gt;k&amp;lt;/b&amp;gt; — положительное число, т. е. &amp;lt;b&amp;gt;k &amp;gt; 0&amp;lt;/b&amp;gt;.&lt;br /&gt;
* Для кластеризуемых элементов определена метрика (расстояние между объектами)&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Объём входных данных&#039;&#039;&#039;: &amp;lt;b&amp;gt;n &amp;lt;math&amp;gt;\cdot&amp;lt;/math&amp;gt; d + 1&amp;lt;/b&amp;gt; (кластеризуемые объекты в виде векторов и число &amp;lt;b&amp;gt;k&amp;lt;/b&amp;gt;)&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Выходные данные&#039;&#039;&#039;: Массив, в который записаны принадлежности каждого элемента кластеру (допустим вывод в другой эквивалентной более удобной структуре).&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Объём выходных данных&#039;&#039;&#039;:  Размер массива равен &amp;lt;b&amp;gt;2 &amp;lt;math&amp;gt;\cdot&amp;lt;/math&amp;gt; n&amp;lt;/b&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Свойства алгоритма ==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Ограничения алгоритма&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Алгоритм эффективно работает только на небольших объемах данных.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Преимущества алгоритма&#039;&#039;&#039;&lt;br /&gt;
* Простота использования&lt;br /&gt;
* Быстрота использования&lt;br /&gt;
* Понятность и прозрачность описания&lt;br /&gt;
* Обладает вычислительной устойчивостью&lt;br /&gt;
* Предрасположенность к распараллеливанию&lt;br /&gt;
* Достаточно популярный, поэтому имеет множество реализаций и вариаций&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Недостатки алгоритма&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
* Нет проверки корректности выбора числа кластеров&lt;br /&gt;
* Алгоритм чувствителен к количеству кластеров&lt;br /&gt;
* Алгоритм чувствителен к выбору начальных элементов в качестве центроидов и на одном наборе данных в теории может демонстрировать разные результаты&lt;br /&gt;
* Алгоритм крайне чувствителен к выбросам по данным&lt;br /&gt;
* Медленная работа на больших объемах данных&lt;br /&gt;
&lt;br /&gt;
= ЧАСТЬ. Программная реализация алгоритма =&lt;br /&gt;
&lt;br /&gt;
== Масштабируемость алгоритма и его реализации ==&lt;br /&gt;
&lt;br /&gt;
== Существующие реализации алгоритма ==&lt;br /&gt;
&lt;br /&gt;
=== Бесплатный доступ ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Десктопные программы&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
* [http://www.cs.waikato.ac.nz/ml/weka/ Weka]&lt;br /&gt;
* [http://docs.orange.biolab.si/2/reference/rst/Orange.clustering.kmeans.html Orange]&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Фреймворки для языков&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;Python:&#039;&#039;&#039;&lt;br /&gt;
** [http://scikit-learn.org/ scikit-learn]&lt;br /&gt;
** [https://www.scipy.org/ SciPy]&lt;br /&gt;
* &#039;&#039;&#039;C++:&#039;&#039;&#039;&lt;br /&gt;
** [http://mlpack.org/ MLPACK]&lt;br /&gt;
** [http://docs.opencv.org/3.0-beta/doc/py_tutorials/py_ml/py_kmeans/py_kmeans_opencv/py_kmeans_opencv.html OpenCV]&lt;br /&gt;
** [https://www.gnu.org/software/octave/ Octave] &lt;br /&gt;
* &#039;&#039;&#039;C#:&#039;&#039;&#039;  &lt;br /&gt;
** [http://accord-framework.net/docs/html/T_Accord_MachineLearning_KMeans.htm Accord.NET]&lt;br /&gt;
* &#039;&#039;&#039;Java:&#039;&#039;&#039;&lt;br /&gt;
** [http://elki.dbs.ifi.lmu.de ELKI]&lt;br /&gt;
** [https://mahout.apache.org Mahout]&lt;br /&gt;
* &#039;&#039;&#039;Lua&#039;&#039;&#039;&lt;br /&gt;
** [http://torch.ch Torch]&lt;br /&gt;
&lt;br /&gt;
Языки [https://www.r-bloggers.com/k-means-clustering-in-r/ R] и [http://juliastats.github.io Julia] содержат алгоритм k-means в базовой реализации.&lt;br /&gt;
&lt;br /&gt;
=== Платный доступ/лицензия  ===&lt;br /&gt;
&lt;br /&gt;
Существует целый перечень мощных статистических и математических пакетов для разных ОС:&lt;br /&gt;
* [http://www.mathworks.com/help/stats/kmeans.html?requestedDomain=www.mathworks.com MATLAB]&lt;br /&gt;
* [http://mathworld.wolfram.com/K-MeansClusteringAlgorithm.html Mathematica]&lt;br /&gt;
* [http://www.stata.com/features/cluster-analysis/ Stata]&lt;br /&gt;
* [https://support.sas.com/rnd/app/stat/procedures/fastclus.html SAS]&lt;br /&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]&lt;br /&gt;
* [http://docs.rapidminer.com/studio/operators/modeling/segmentation/k_means.html RapidMiner]&lt;br /&gt;
* ...&lt;br /&gt;
&lt;br /&gt;
= Литература =&lt;br /&gt;
[1] Нейский И.М. Классификация и сравнение методов кластеризации http://it-claim.ru/Persons/Neyskiy/Article2_Neiskiy.pdf&lt;br /&gt;
&lt;br /&gt;
[2] https://ru.wikipedia.org/wiki/K-means&lt;br /&gt;
&lt;br /&gt;
[[en:Description of algorithm properties and structure]]&lt;/div&gt;</summary>
		<author><name>Богомазов Евгений</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%98%D0%BB%D1%8C%D1%8F_%D0%95%D0%B3%D0%BE%D1%80%D0%BE%D0%B2/%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_k-%D1%81%D1%80%D0%B5%D0%B4%D0%BD%D0%B8%D1%85&amp;diff=8083</id>
		<title>Участник:Илья Егоров/Алгоритм k-средних</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%98%D0%BB%D1%8C%D1%8F_%D0%95%D0%B3%D0%BE%D1%80%D0%BE%D0%B2/%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_k-%D1%81%D1%80%D0%B5%D0%B4%D0%BD%D0%B8%D1%85&amp;diff=8083"/>
		<updated>2016-10-14T20:05:53Z</updated>

		<summary type="html">&lt;p&gt;Богомазов Евгений: /* Свойства алгоритма */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{algorithm&lt;br /&gt;
| name              = Алгоритм k-средних (k-means)&lt;br /&gt;
| serial_complexity = &amp;lt;math&amp;gt;O()&amp;lt;/math&amp;gt;&lt;br /&gt;
| input_data        = &amp;lt;math&amp;gt;\frac{()}{}&amp;lt;/math&amp;gt;&lt;br /&gt;
| output_data       = &amp;lt;math&amp;gt;\frac{ ()}{}&amp;lt;/math&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&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;
Алгоритм кластеризации k-средних впервые был предложен в 1950-х годах математиками Гуго Штейнгаузом и Стюартом Ллойдом независимо друг от друга. Наибольшую популярность он получил после работы Маккуина.&lt;br /&gt;
&lt;br /&gt;
Алгоритм позволяет при заданном числе &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; построить &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластеров, расположенных на максимальном расстоянии друг от друга. Таким образом, наибольшей точности результат выполнения алгоритма достигает при полной осведомленности Пользователя о характере кластеризуемых объектов и, как следствие, при обладании максимально корректной информацией о числе кластеров.&lt;br /&gt;
&lt;br /&gt;
В общем случае выбор числа &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; может базироваться на любых значимых факторах, в том числе на результатах предшествующих исследований, теоретических соображениях или интуиции. &lt;br /&gt;
&lt;br /&gt;
== Математическое описание алгоритма ==&lt;br /&gt;
&#039;&#039;&#039;Исходные данные:&#039;&#039;&#039;&lt;br /&gt;
* Совокупность &amp;lt;b&amp;gt;n&amp;lt;/b&amp;gt; &amp;lt;b&amp;gt;d&amp;lt;/b&amp;gt;-мерных векторов &amp;lt;math&amp;gt; X = \{x_1 \dots x_n\} , &amp;lt;/math&amp;gt; где  &amp;lt;math&amp;gt; x_i = \{x_{i1} \dots x_{id}\} &amp;lt;/math&amp;gt;&lt;br /&gt;
* Предполагаемое количество кластеров &amp;lt;b&amp;gt;k&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Выходные данные:&#039;&#039;&#039;&lt;br /&gt;
* Разбиение X на множество &amp;lt;math&amp;gt; S = \{S_1 \dots S_k \}, \bigcup S_i = X, S_i \cap S_j = \emptyset, i \neq j &amp;lt;/math&amp;gt;&lt;br /&gt;
* k центров кластеров &amp;lt;math&amp;gt; \Mu = \{\mu_1 \dots \mu_k \} &amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt; \mu_i = \{\mu_{i1} \dots \mu_{id} \} &amp;lt;/math&amp;gt; такие, что&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; \begin{cases}\mu_i = argmin_y \sum_{x \in S_i} ||x-y||^2_E \\ \mu_i = argmin_\Mu \sum_{i \in k} \sum_{x \in S_i} ||x-\mu_i||^2_E \end{cases} &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Алгоритм:&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
1) &amp;lt;math&amp;gt; \mu_{ij} = random &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
2) &amp;lt;math&amp;gt; S_i = \{x| argmin_j ||x-\mu_j|| = i\} i = 1 \dots k &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
3) &amp;lt;math&amp;gt; \tilde{\mu_{i}} = E_{x \in S_i}(x) &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
4) Если для &amp;lt;math&amp;gt; \forall i:  \mu_i = \tilde{\mu_i} &amp;lt;/math&amp;gt; то алгоритм завершен, иначе &amp;lt;math&amp;gt; \mu_i = \tilde{\mu_i} &amp;lt;/math&amp;gt; и перейти на пункт 2)&lt;br /&gt;
&lt;br /&gt;
== Вычислительное ядро алгоритма ==&lt;br /&gt;
&lt;br /&gt;
Вычислительным ядром алгоритма является второй этап, а точнее нахождение матрицы расстояний между &amp;lt;math&amp;gt;X&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\Mu&amp;lt;/math&amp;gt;. Для &#039;&#039;&#039;d&#039;&#039;&#039;-мерного вектора &amp;lt;math&amp;gt;a:&amp;lt;/math&amp;gt; &lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;||a||=\sqrt{\sum_{i=1\dots d} a_i^2}&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; операций сложения и одну операция вычисления квадратного корня. Но так как эти расстояния используются только для сравнения, а &#039;&#039;sqrt&#039;&#039; является монотонно возрастающей функцией, то ее можно не вычислять. Поэтому нахождения матрицы расстояний потребует всего &amp;lt;math&amp;gt;n*k*d&amp;lt;/math&amp;gt; операций умножений и &amp;lt;math&amp;gt;n*k*(d-1)&amp;lt;/math&amp;gt; операций сложений.&lt;br /&gt;
&lt;br /&gt;
== Макроструктура алгоритма ==&lt;br /&gt;
&lt;br /&gt;
Алгоритм k-средних базируется на алгоритме вычисления расстояния между векторами, расстояние на каждом шаге высчитывается &amp;lt;math&amp;gt;k\cdot n&amp;lt;/math&amp;gt; раз.&lt;br /&gt;
&lt;br /&gt;
Помимо этого, в конце каждого шага вычисляется центр масс объектов кластера, для всех объектов потребуется &amp;lt;math&amp;gt;n-1&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;
&lt;br /&gt;
&lt;br /&gt;
Последовательность шагов алгоритма следующая:&lt;br /&gt;
&lt;br /&gt;
    &#039;&#039;&#039;1. Инициализация центроидов &amp;lt;math&amp;gt;\Mu&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt; iter = 1 &amp;lt;/math&amp;gt;, задание максимального количество итераций &amp;lt;math&amp;gt;maxiter&amp;lt;/math&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
        &lt;br /&gt;
    &#039;&#039;&#039;2a. Нахождение матрицы расстояний &#039;&#039;&#039;&amp;lt;math&amp;gt;dist:&amp;lt;/math&amp;gt;&lt;br /&gt;
    &lt;br /&gt;
        &amp;lt;math&amp;gt;dist_{ij} = \sum_{l = 1\dots d} (x_{il}-\mu_{il})^2&amp;lt;/math&amp;gt;&lt;br /&gt;
        &lt;br /&gt;
    &#039;&#039;&#039;2b. Нахождение вектора распределения объектов по кластерам &#039;&#039;&#039;&amp;lt;math&amp;gt;index: &amp;lt;/math&amp;gt;&lt;br /&gt;
    &lt;br /&gt;
        &amp;lt;math&amp;gt;index_{i} =   \underset{j}{argmin }~dist_{ij} &amp;lt;/math&amp;gt;&lt;br /&gt;
    &lt;br /&gt;
    &#039;&#039;&#039;3. Пересчет центроидов &#039;&#039;&#039;&amp;lt;math&amp;gt;\tilde{\Mu}:&amp;lt;/math&amp;gt;&lt;br /&gt;
    &lt;br /&gt;
        &amp;lt;math&amp;gt;\tilde{\mu_{ij}} = \sum_{l \in T_i} \dfrac{x_{lj}}{|T_i|} &amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;T_i = \{l~|~l \in 1\dots n, index_l = i\}  &amp;lt;/math&amp;gt;&lt;br /&gt;
    &lt;br /&gt;
    &#039;&#039;&#039;4. Проверка критерия останова:&#039;&#039;&#039;&lt;br /&gt;
    &lt;br /&gt;
        &#039;&#039;&#039;Если&#039;&#039;&#039; &amp;lt;math&amp;gt; \exists i: \tilde{\mu_i} \neq \mu_i&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt; iter &amp;lt; maxiter &amp;lt;/math&amp;gt;,&lt;br /&gt;
    &lt;br /&gt;
        &#039;&#039;&#039;то&#039;&#039;&#039; &amp;lt;math&amp;gt; inc(iter), \Mu=\tilde{\Mu},&amp;lt;/math&amp;gt; &#039;&#039;&#039;GOTO 2.а.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
== Последовательная сложность алгоритма ==&lt;br /&gt;
&lt;br /&gt;
    &#039;&#039;&#039;1)&#039;&#039;&#039; Сложность инициализации в общем случае зависит от применяемого метода генерации/получения случайных чисел, но ей можно пренебречь&lt;br /&gt;
    &lt;br /&gt;
    &#039;&#039;&#039;2a)&#039;&#039;&#039; Вычисление матрицы расстояний требует &amp;lt;math&amp;gt; n*k*d &amp;lt;/math&amp;gt; операций умножений и &amp;lt;math&amp;gt; n*k*(d-1) &amp;lt;/math&amp;gt; операций сложений&lt;br /&gt;
    &lt;br /&gt;
    &#039;&#039;&#039;2b)&#039;&#039;&#039; Нахождение вектора распределения требует &amp;lt;math&amp;gt; n*(k-1) &amp;lt;/math&amp;gt; операций сравнений&lt;br /&gt;
    &lt;br /&gt;
    &#039;&#039;&#039;3)&#039;&#039;&#039; Для вычисления &amp;lt;math&amp;gt; \tilde{\Mu} &amp;lt;/math&amp;gt; требуется &amp;lt;math&amp;gt; (n - k + 1) * d &amp;lt;/math&amp;gt; операций сложений и &amp;lt;math&amp;gt; k * d &amp;lt;/math&amp;gt; операций деления&lt;br /&gt;
    &lt;br /&gt;
    &#039;&#039;&#039;4)&#039;&#039;&#039; Для критерия останова требуется &amp;lt;math&amp;gt; n*d &amp;lt;/math&amp;gt; сравнений&lt;br /&gt;
&lt;br /&gt;
Итого: так как максимальное количество итераций задается в алгоритме заранее и не зависит от входных данных, то количество итераций ограничено константой. Тогда сложность алгоритма:&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;math&amp;gt; O(n*k*d)&amp;lt;/math&amp;gt; операций сложений/вычитаний&lt;br /&gt;
* &amp;lt;math&amp;gt; O(n*k*d)&amp;lt;/math&amp;gt; операций умножений, &amp;lt;math&amp;gt; O(k*d) &amp;lt;/math&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;
&#039;&#039;&#039;Входные данные&#039;&#039;&#039;: Количество кластеров &amp;lt;b&amp;gt;k&amp;lt;/b&amp;gt;, &amp;lt;b&amp;gt;n&amp;lt;/b&amp;gt; кластеризуемых элементов&lt;br /&gt;
&lt;br /&gt;
Дополнительные ограничения:&lt;br /&gt;
* &amp;lt;b&amp;gt;k&amp;lt;/b&amp;gt; — положительное число, т. е. &amp;lt;b&amp;gt;k &amp;gt; 0&amp;lt;/b&amp;gt;.&lt;br /&gt;
* Для кластеризуемых элементов определена метрика (расстояние между объектами)&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Объём входных данных&#039;&#039;&#039;: &amp;lt;b&amp;gt;n &amp;lt;math&amp;gt;\cdot&amp;lt;/math&amp;gt; d + 1&amp;lt;/b&amp;gt; (кластеризуемые объекты в виде векторов и число &amp;lt;b&amp;gt;k&amp;lt;/b&amp;gt;)&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Выходные данные&#039;&#039;&#039;: Массив, в который записаны принадлежности каждого элемента кластеру (допустим вывод в другой эквивалентной более удобной структуре).&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Объём выходных данных&#039;&#039;&#039;:  Размер массива равен &amp;lt;b&amp;gt;2 &amp;lt;math&amp;gt;\cdot&amp;lt;/math&amp;gt; n&amp;lt;/b&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Свойства алгоритма ==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Ограничения алгоритма&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Алгоритм эффективно работает только на небольших объемах данных.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Преимущества алгоритма&#039;&#039;&#039;&lt;br /&gt;
* Простота использования&lt;br /&gt;
* Быстрота использования&lt;br /&gt;
* Понятность и прозрачность описания&lt;br /&gt;
* Обладает вычислительной устойчивостью&lt;br /&gt;
* Предрасположенность к распараллеливанию&lt;br /&gt;
* Достаточно популярный, поэтому имеет множество реализаций и вариаций&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Недостатки алгоритма&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
* Нет проверки корректности выбора числа кластеров&lt;br /&gt;
* Алгоритм чувствителен к количеству кластеров&lt;br /&gt;
* Алгоритм чувствителен к выбору начальных элементов в качестве центроидов и на одном наборе данных в теории может демонстрировать разные результаты&lt;br /&gt;
* Алгоритм крайне чувствителен к выбросам по данным&lt;br /&gt;
* Медленная работа на больших объемах данных&lt;br /&gt;
&lt;br /&gt;
= ЧАСТЬ. Программная реализация алгоритма =&lt;br /&gt;
&lt;br /&gt;
== Масштабируемость алгоритма и его реализации ==&lt;br /&gt;
&lt;br /&gt;
== Существующие реализации алгоритма ==&lt;br /&gt;
&lt;br /&gt;
=== Бесплатный доступ ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Десктопные программы&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
* [http://www.cs.waikato.ac.nz/ml/weka/ Weka]&lt;br /&gt;
* [http://docs.orange.biolab.si/2/reference/rst/Orange.clustering.kmeans.html Orange]&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Фреймворки для языков&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;Python:&#039;&#039;&#039;&lt;br /&gt;
** [http://scikit-learn.org/ scikit-learn]&lt;br /&gt;
** [https://www.scipy.org/ SciPy]&lt;br /&gt;
* &#039;&#039;&#039;C++:&#039;&#039;&#039;&lt;br /&gt;
** [http://mlpack.org/ MLPACK]&lt;br /&gt;
** [http://docs.opencv.org/3.0-beta/doc/py_tutorials/py_ml/py_kmeans/py_kmeans_opencv/py_kmeans_opencv.html OpenCV]&lt;br /&gt;
** [https://www.gnu.org/software/octave/ Octave] &lt;br /&gt;
* &#039;&#039;&#039;C#:&#039;&#039;&#039;  &lt;br /&gt;
** [http://accord-framework.net/docs/html/T_Accord_MachineLearning_KMeans.htm Accord.NET]&lt;br /&gt;
* &#039;&#039;&#039;Java:&#039;&#039;&#039;&lt;br /&gt;
** [http://elki.dbs.ifi.lmu.de ELKI]&lt;br /&gt;
** [https://mahout.apache.org Mahout]&lt;br /&gt;
* &#039;&#039;&#039;Lua&#039;&#039;&#039;&lt;br /&gt;
** [http://torch.ch Torch]&lt;br /&gt;
&lt;br /&gt;
Языки [https://www.r-bloggers.com/k-means-clustering-in-r/ R] и [http://juliastats.github.io Julia] содержат алгоритм k-means в базовой реализации.&lt;br /&gt;
&lt;br /&gt;
=== Платный доступ/лицензия  ===&lt;br /&gt;
&lt;br /&gt;
Существует целый перечень мощных статистических и математических пакетов для разных ОС:&lt;br /&gt;
* [http://www.mathworks.com/help/stats/kmeans.html?requestedDomain=www.mathworks.com MATLAB]&lt;br /&gt;
* [http://mathworld.wolfram.com/K-MeansClusteringAlgorithm.html Mathematica]&lt;br /&gt;
* [http://www.stata.com/features/cluster-analysis/ Stata]&lt;br /&gt;
* [https://support.sas.com/rnd/app/stat/procedures/fastclus.html SAS]&lt;br /&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]&lt;br /&gt;
* [http://docs.rapidminer.com/studio/operators/modeling/segmentation/k_means.html RapidMiner]&lt;br /&gt;
* ...&lt;br /&gt;
&lt;br /&gt;
= Литература =&lt;br /&gt;
[1] Нейский И.М. Классификация и сравнение методов кластеризации http://it-claim.ru/Persons/Neyskiy/Article2_Neiskiy.pdf&lt;br /&gt;
&lt;br /&gt;
[2] https://ru.wikipedia.org/wiki/K-means&lt;br /&gt;
&lt;br /&gt;
[[en:Description of algorithm properties and structure]]&lt;/div&gt;</summary>
		<author><name>Богомазов Евгений</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%98%D0%BB%D1%8C%D1%8F_%D0%95%D0%B3%D0%BE%D1%80%D0%BE%D0%B2/%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_k-%D1%81%D1%80%D0%B5%D0%B4%D0%BD%D0%B8%D1%85&amp;diff=7839</id>
		<title>Участник:Илья Егоров/Алгоритм k-средних</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%98%D0%BB%D1%8C%D1%8F_%D0%95%D0%B3%D0%BE%D1%80%D0%BE%D0%B2/%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_k-%D1%81%D1%80%D0%B5%D0%B4%D0%BD%D0%B8%D1%85&amp;diff=7839"/>
		<updated>2016-10-14T17:45:07Z</updated>

		<summary type="html">&lt;p&gt;Богомазов Евгений: /* Последовательная сложность алгоритма */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{algorithm&lt;br /&gt;
| name              = Алгоритм k-средних (k-means)&lt;br /&gt;
| serial_complexity = &amp;lt;math&amp;gt;O()&amp;lt;/math&amp;gt;&lt;br /&gt;
| input_data        = &amp;lt;math&amp;gt;\frac{()}{}&amp;lt;/math&amp;gt;&lt;br /&gt;
| output_data       = &amp;lt;math&amp;gt;\frac{ ()}{}&amp;lt;/math&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&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;
Алгоритм кластеризации k-средних впервые был предложен в 1950-х годах математиками Гуго Штейнгаузом и Стюартом Ллойдом независимо друг от друга. Наибольшую популярность он получил после работы Маккуина.&lt;br /&gt;
&lt;br /&gt;
Алгоритм позволяет при заданном числе &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; построить &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластеров, расположенных на максимальном расстоянии друг от друга. Таким образом, наибольшей точности результат выполнения алгоритма достигает при полной осведомленности Пользователя о характере кластеризуемых объектов и, как следствие, при обладании максимально корректной информацией о числе кластеров.&lt;br /&gt;
&lt;br /&gt;
В общем случае выбор числа &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; может базироваться на любых значимых факторах, в том числе на результатах предшествующих исследований, теоретических соображениях или интуиции. &lt;br /&gt;
&lt;br /&gt;
== Математическое описание алгоритма ==&lt;br /&gt;
&#039;&#039;&#039;Исходные данные:&#039;&#039;&#039;&lt;br /&gt;
* Совокупность &amp;lt;b&amp;gt;n&amp;lt;/b&amp;gt; &amp;lt;b&amp;gt;d&amp;lt;/b&amp;gt;-мерных векторов &amp;lt;math&amp;gt; X = \{x_1 \dots x_n\} , &amp;lt;/math&amp;gt; где  &amp;lt;math&amp;gt; x_i = \{x_{i1} \dots x_{id}\} &amp;lt;/math&amp;gt;&lt;br /&gt;
* Предполагаемое количество кластеров &amp;lt;b&amp;gt;k&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Выходные данные:&#039;&#039;&#039;&lt;br /&gt;
* Разбиение X на множество &amp;lt;math&amp;gt; S = \{S_1 \dots S_k \}, \bigcup S_i = X, S_i \cap S_j = \emptyset, i \neq j &amp;lt;/math&amp;gt;&lt;br /&gt;
* k центров кластеров &amp;lt;math&amp;gt; \Mu = \{\mu_1 \dots \mu_k \} &amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt; \mu_i = \{\mu_{i1} \dots \mu_{id} \} &amp;lt;/math&amp;gt; такие, что&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; \begin{cases}\mu_i = argmin_y \sum_{x \in S_i} ||x-y||^2_E \\ \mu_i = argmin_\Mu \sum_{i \in k} \sum_{x \in S_i} ||x-\mu_i||^2_E \end{cases} &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Алгоритм:&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
1) &amp;lt;math&amp;gt; \mu_{ij} = random &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
2) &amp;lt;math&amp;gt; S_i = \{x| argmin_j ||x-\mu_j|| = i\} i = 1 \dots k &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
3) &amp;lt;math&amp;gt; \tilde{\mu_{i}} = E_{x \in S_i}(x) &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
4) Если для &amp;lt;math&amp;gt; \forall i:  \mu_i = \tilde{\mu_i} &amp;lt;/math&amp;gt; то алгоритм завершен, иначе &amp;lt;math&amp;gt; \mu_i = \tilde{\mu_i} &amp;lt;/math&amp;gt; и перейти на пункт 2)&lt;br /&gt;
&lt;br /&gt;
== Вычислительное ядро алгоритма ==&lt;br /&gt;
&lt;br /&gt;
Вычислительным ядром алгоритма является второй этап, а точнее нахождение матрицы расстояний между &amp;lt;math&amp;gt;X&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\Mu&amp;lt;/math&amp;gt;. Для &#039;&#039;&#039;d&#039;&#039;&#039;-мерного вектора &amp;lt;math&amp;gt;a:&amp;lt;/math&amp;gt; &lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;||a||=\sqrt{\sum_{i=1\dots d} a_i^2}&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; операций сложения и одну операция вычисления квадратного корня. Но так как эти расстояния используются только для сравнения, а &#039;&#039;sqrt&#039;&#039; является монотонно возрастающей функцией, то ее можно не вычислять. Поэтому нахождения матрицы расстояний потребует всего &amp;lt;math&amp;gt;n*k*d&amp;lt;/math&amp;gt; операций умножений и &amp;lt;math&amp;gt;n*k*(d-1)&amp;lt;/math&amp;gt; операций сложений.&lt;br /&gt;
&lt;br /&gt;
== Макроструктура алгоритма ==&lt;br /&gt;
&lt;br /&gt;
Алгоритм k-средних базируется на алгоритме вычисления расстояния между векторами, расстояние на каждом шаге высчитывается &amp;lt;math&amp;gt;k\cdot n&amp;lt;/math&amp;gt; раз.&lt;br /&gt;
&lt;br /&gt;
Помимо этого, в конце каждого шага вычисляется центр масс объектов кластера, для всех объектов потребуется &amp;lt;math&amp;gt;n-1&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;
&lt;br /&gt;
Последовательность шагов алгоритма следующая:&lt;br /&gt;
&lt;br /&gt;
    &#039;&#039;&#039;1. Шаг инициализации&#039;&#039;&#039;&lt;br /&gt;
        По какому-либо правилу выбираем &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; объектов для кластеризации, объявляем их центроидами&lt;br /&gt;
        &lt;br /&gt;
    &#039;&#039;&#039;2. Шаг классификации&#039;&#039;&#039;&lt;br /&gt;
        Классифицируем каждый объект на предмет принадлежности к кластеру:&lt;br /&gt;
        &lt;br /&gt;
        &amp;lt;math&amp;gt;a_i \in P \Leftrightarrow \left|a_i - s_P\right| \rightarrow \min_P&amp;lt;/math&amp;gt;&lt;br /&gt;
        &lt;br /&gt;
    &#039;&#039;&#039;3. Шаг перерасчета центроидов&#039;&#039;&#039;&lt;br /&gt;
        Вычисляем центр масс каждого из кластеров.&lt;br /&gt;
        &lt;br /&gt;
    &#039;&#039;&#039;3.а&#039;&#039;&#039; Если для какого-либо кластера его центр масс &#039;&#039;&#039;отличается&#039;&#039;&#039; от центроида, то &lt;br /&gt;
            * переносим центроид этого кластера во вновь образованный центр масс,&lt;br /&gt;
            * проделываем эту операцию для всех других кластеров&lt;br /&gt;
            * переходим к &#039;&#039;&#039;Шагу 2&#039;&#039;&#039;&lt;br /&gt;
        &lt;br /&gt;
    &#039;&#039;&#039;3.б&#039;&#039;&#039; Если для каждого кластера его центр масс &#039;&#039;&#039;совпадает&#039;&#039;&#039; с центроидом, то&lt;br /&gt;
            &#039;&#039;&#039;Выход из алгоритма&#039;&#039;&#039;, объекты классифицированы.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Альтернатива&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Последовательность шагов алгоритма следующая:&lt;br /&gt;
&lt;br /&gt;
    1) Инициализация центроидов &amp;lt;math&amp;gt;\Mu&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt; iter = 1 &amp;lt;/math&amp;gt;, задание максимального количество итераций &amp;lt;math&amp;gt;maxiter&amp;lt;/math&amp;gt;&lt;br /&gt;
    2a) Нахождение матрицы расстояний &amp;lt;math&amp;gt;dist: dist_{ij} = \sum_{l = 1\dots d} (x_{il}-\mu_{il})^2&amp;lt;/math&amp;gt;&lt;br /&gt;
    2b) Нахождение вектора распределения объектов по кластерам &amp;lt;math&amp;gt;index: index_{i} = argmin_{j} dist_{ij} &amp;lt;/math&amp;gt;&lt;br /&gt;
    3) Пересчет центроидов &amp;lt;math&amp;gt;\tilde{\Mu}: \tilde{\mu_{ij}} = \sum_{l \in T_i} x_{lj}/|T_i| &amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;T_i = \{l| l \in 1\dots n, index_l = i\}  &amp;lt;/math&amp;gt;&lt;br /&gt;
    4) Проверка критерия останова: если &amp;lt;math&amp;gt; \exists i: \tilde{\mu_i} \neq \mu_i&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt; iter &amp;lt; maxiter &amp;lt;/math&amp;gt;, то &amp;lt;math&amp;gt; inc(iter), \Mu=\tilde{\Mu}&amp;lt;/math&amp;gt;, goto 2a&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Альтернатива альтернативы&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
    &#039;&#039;&#039;1. Инициализация центроидов&#039;&#039;&#039;&lt;br /&gt;
    &lt;br /&gt;
        &amp;lt;math&amp;gt;\Mu&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt; iter = 1 &amp;lt;/math&amp;gt;, задание максимального количество итераций &amp;lt;math&amp;gt;maxiter&amp;lt;/math&amp;gt;&lt;br /&gt;
        &lt;br /&gt;
    &#039;&#039;&#039;2.а. Нахождение матрицы расстояний&#039;&#039;&#039;&lt;br /&gt;
    &lt;br /&gt;
        &amp;lt;math&amp;gt;dist: dist_{ij} = \sum_{l = 1\dots d} (x_{il}-\mu_{il})^2&amp;lt;/math&amp;gt;&lt;br /&gt;
        &lt;br /&gt;
    &#039;&#039;&#039;2.б. Нахождение вектора распределения объектов по кластерам&#039;&#039;&#039;&lt;br /&gt;
    &lt;br /&gt;
        &amp;lt;math&amp;gt;index: index_{i} =   \underset{j}{argmin } dist_{ij} &amp;lt;/math&amp;gt;&lt;br /&gt;
    &lt;br /&gt;
    &#039;&#039;&#039;3. Пересчет центроидов&#039;&#039;&#039;&lt;br /&gt;
    &lt;br /&gt;
        &amp;lt;math&amp;gt;\tilde{\Mu}: \tilde{\mu_{ij}} = \sum_{l \in T_i} x_{lj}/|T_i| &amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;T_i = \{l| l \in 1\dots n, index_l = i\}  &amp;lt;/math&amp;gt;&lt;br /&gt;
    &lt;br /&gt;
    &#039;&#039;&#039;4. Проверка критерия останова:&#039;&#039;&#039;&lt;br /&gt;
    &lt;br /&gt;
        &#039;&#039;&#039;Если&#039;&#039;&#039; &amp;lt;math&amp;gt; \exists i: \tilde{\mu_i} \neq \mu_i&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt; iter &amp;lt; maxiter &amp;lt;/math&amp;gt;,&lt;br /&gt;
    &lt;br /&gt;
        &#039;&#039;&#039;то&#039;&#039;&#039; &amp;lt;math&amp;gt; inc(iter), \Mu=\tilde{\Mu},&amp;lt;/math&amp;gt; &#039;&#039;&#039;GOTO 2.а.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
== Последовательная сложность алгоритма ==&lt;br /&gt;
&lt;br /&gt;
    1) Сложность инициализации в общем случае зависит от применяемого метода генерации/получения случайных чисел, но ей можно пренебречь &lt;br /&gt;
    2a) Вычисление матрицы расстояний требует &amp;lt;math&amp;gt; n*k*d &amp;lt;/math&amp;gt; операций умножений и &amp;lt;math&amp;gt; n*k*(d-1) &amp;lt;/math&amp;gt; операций сложений&lt;br /&gt;
    2b) Нахождение вектора распределения требует &amp;lt;math&amp;gt; n*(k-1) &amp;lt;/math&amp;gt; операций сравнений&lt;br /&gt;
    3) Для вычисления &amp;lt;math&amp;gt; \tilde{\Mu} &amp;lt;/math&amp;gt; требуется &amp;lt;math&amp;gt; (n - k + 1) * d &amp;lt;/math&amp;gt; операций сложений и &amp;lt;math&amp;gt; k * d &amp;lt;/math&amp;gt; операций деления&lt;br /&gt;
    4) Для критерия останова требуется &amp;lt;math&amp;gt; n*d &amp;lt;/math&amp;gt; сравнений&lt;br /&gt;
&lt;br /&gt;
Итого: так как максимальное количество итераций задается в алгоритме заранее и не зависит от входных данных, то количество итераций ограничено константой. Тогда сложность алгоритма:&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;math&amp;gt; O(n*k*d)&amp;lt;/math&amp;gt; операций сложений/вычитаний&lt;br /&gt;
* &amp;lt;math&amp;gt; O(n*k*d)&amp;lt;/math&amp;gt; операций умножений, &amp;lt;math&amp;gt; O(k*d) &amp;lt;/math&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;
&#039;&#039;&#039;Входные данные&#039;&#039;&#039;: Количество кластеров &amp;lt;b&amp;gt;k&amp;lt;/b&amp;gt;, &amp;lt;b&amp;gt;n&amp;lt;/b&amp;gt; кластеризуемых элементов&lt;br /&gt;
&lt;br /&gt;
Дополнительные ограничения:&lt;br /&gt;
* &amp;lt;b&amp;gt;k&amp;lt;/b&amp;gt; — положительное число, т. е. &amp;lt;b&amp;gt;k &amp;gt; 0&amp;lt;/b&amp;gt;.&lt;br /&gt;
* Для кластеризуемых элементов определена метрика (расстояние между объектами)&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Объём входных данных&#039;&#039;&#039;: &amp;lt;b&amp;gt;n &amp;lt;math&amp;gt;\cdot&amp;lt;/math&amp;gt; d + 1&amp;lt;/b&amp;gt; (кластеризуемые объекты в виде векторов и число &amp;lt;b&amp;gt;k&amp;lt;/b&amp;gt;)&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Выходные данные&#039;&#039;&#039;: Массив, в который записаны принадлежности каждого элемента кластеру (допустим вывод в другой эквивалентной более удобной структуре).&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Объём выходных данных&#039;&#039;&#039;:  Размер массива равен &amp;lt;b&amp;gt;2 &amp;lt;math&amp;gt;\cdot&amp;lt;/math&amp;gt; n&amp;lt;/b&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Свойства алгоритма ==&lt;br /&gt;
&lt;br /&gt;
Вычислительная мощность алгоритма на каждом шаге равна &amp;lt;math&amp;gt;k\cdot n&amp;lt;/math&amp;gt; (расстояние между элементом и центроидом &amp;lt;math&amp;gt;k\cdot n&amp;lt;/math&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;
[1] Нейский И.М. Классификация и сравнение методов кластеризации http://it-claim.ru/Persons/Neyskiy/Article2_Neiskiy.pdf&lt;br /&gt;
&lt;br /&gt;
[2] https://ru.wikipedia.org/wiki/K-means&lt;br /&gt;
&lt;br /&gt;
[[en:Description of algorithm properties and structure]]&lt;/div&gt;</summary>
		<author><name>Богомазов Евгений</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%98%D0%BB%D1%8C%D1%8F_%D0%95%D0%B3%D0%BE%D1%80%D0%BE%D0%B2/%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_k-%D1%81%D1%80%D0%B5%D0%B4%D0%BD%D0%B8%D1%85&amp;diff=7706</id>
		<title>Участник:Илья Егоров/Алгоритм k-средних</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%98%D0%BB%D1%8C%D1%8F_%D0%95%D0%B3%D0%BE%D1%80%D0%BE%D0%B2/%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_k-%D1%81%D1%80%D0%B5%D0%B4%D0%BD%D0%B8%D1%85&amp;diff=7706"/>
		<updated>2016-10-14T15:50:14Z</updated>

		<summary type="html">&lt;p&gt;Богомазов Евгений: /* Схема реализации последовательного алгоритма */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{algorithm&lt;br /&gt;
| name              = Алгоритм k-средних (k-means)&lt;br /&gt;
| serial_complexity = &amp;lt;math&amp;gt;O()&amp;lt;/math&amp;gt;&lt;br /&gt;
| input_data        = &amp;lt;math&amp;gt;\frac{()}{}&amp;lt;/math&amp;gt;&lt;br /&gt;
| output_data       = &amp;lt;math&amp;gt;\frac{ ()}{}&amp;lt;/math&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&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;
Алгоритм кластеризации k-средних впервые был предложен в 1950-х годах математиками Гуго Штейнгаузом и Стюартом Ллойдом независимо друг от друга. Наибольшую популярность он получил после работы Маккуина.&lt;br /&gt;
&lt;br /&gt;
Алгоритм позволяет при заданном числе &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; построить &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластеров, расположенных на максимальном расстоянии друг от друга. Таким образом, наибольшей точности результат выполнения алгоритма достигает при полной осведомленности Пользователя о характере кластеризуемых объектов и, как следствие, при обладании максимально корректной информацией о числе кластеров.&lt;br /&gt;
&lt;br /&gt;
В общем случае выбор числа &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; может базироваться на любых значимых факторах, в том числе на результатах предшествующих исследований, теоретических соображениях или интуиции. &lt;br /&gt;
&lt;br /&gt;
== Математическое описание алгоритма ==&lt;br /&gt;
&#039;&#039;&#039;Исходные данные:&#039;&#039;&#039;&lt;br /&gt;
* Совокупность &amp;lt;b&amp;gt;n&amp;lt;/b&amp;gt; &amp;lt;b&amp;gt;d&amp;lt;/b&amp;gt;-мерных векторов &amp;lt;math&amp;gt; X = \{x_1 \dots x_n\} , &amp;lt;/math&amp;gt; где  &amp;lt;math&amp;gt; x_i = \{x_{i1} \dots x_{id}\} &amp;lt;/math&amp;gt;&lt;br /&gt;
* Предполагаемое количество кластеров &amp;lt;b&amp;gt;k&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Выходные данные:&#039;&#039;&#039;&lt;br /&gt;
* Разбиение X на множество &amp;lt;math&amp;gt; S = \{S_1 \dots S_k \}, \bigcup S_i = X, S_i \cap S_j = \emptyset, i \neq j &amp;lt;/math&amp;gt;&lt;br /&gt;
* k центров кластеров &amp;lt;math&amp;gt; \Mu = \{\mu_1 \dots \mu_k \} &amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt; \mu_i = \{\mu_{i1} \dots \mu_{id} \} &amp;lt;/math&amp;gt; такие, что&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; \begin{cases}\mu_i = argmin_y \sum_{x \in S_i} ||x-y||^2_E \\ \mu_i = argmin_\Mu \sum_{i \in k} \sum_{x \in S_i} ||x-\mu_i||^2_E \end{cases} &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Алгоритм:&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
1) &amp;lt;math&amp;gt; \mu_{ij} = random &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
2) &amp;lt;math&amp;gt; S_i = \{x| argmin_j ||x-\mu_j|| = i\} i = 1 \dots k &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
3) &amp;lt;math&amp;gt; \tilde{\mu_{i}} = E_{x \in S_i}(x) &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
4) Если для &amp;lt;math&amp;gt; \forall i:  \mu_i = \tilde{\mu_i} &amp;lt;/math&amp;gt; то алгоритм завершен, иначе &amp;lt;math&amp;gt; \mu_i = \tilde{\mu_i} &amp;lt;/math&amp;gt; и перейти на пункт 2)&lt;br /&gt;
&lt;br /&gt;
== Вычислительное ядро алгоритма ==&lt;br /&gt;
&lt;br /&gt;
Вычислительным ядром алгоритма является второй этап, а точнее нахождение матрицы расстояний между &amp;lt;math&amp;gt;X&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\Mu&amp;lt;/math&amp;gt;. Для &#039;&#039;&#039;d&#039;&#039;&#039;-мерного вектора &amp;lt;math&amp;gt;a:&amp;lt;/math&amp;gt; &lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;||a||=\sqrt{\sum_{i=1\dots d} a_i^2}&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; операций сложения и одну операция вычисления квадратного корня. Но так как эти расстояния используются только для сравнения, а &#039;&#039;sqrt&#039;&#039; является монотонно возрастающей функцией, то ее можно не вычислять. Поэтому нахождения матрицы расстояний потребует всего &amp;lt;math&amp;gt;n*k*d&amp;lt;/math&amp;gt; операций умножений и &amp;lt;math&amp;gt;n*k*(d-1)&amp;lt;/math&amp;gt; операций сложений.&lt;br /&gt;
&lt;br /&gt;
== Макроструктура алгоритма ==&lt;br /&gt;
&lt;br /&gt;
Алгоритм k-средних базируется на алгоритме вычисления расстояния между векторами, расстояние на каждом шаге высчитывается &amp;lt;math&amp;gt;k\cdot n&amp;lt;/math&amp;gt; раз.&lt;br /&gt;
&lt;br /&gt;
Помимо этого, в конце каждого шага вычисляется центр масс объектов кластера, для всех объектов потребуется &amp;lt;math&amp;gt;n-1&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;
&lt;br /&gt;
Последовательность шагов алгоритма следующая:&lt;br /&gt;
&lt;br /&gt;
    &#039;&#039;&#039;1. Шаг инициализации&#039;&#039;&#039;&lt;br /&gt;
        По какому-либо правилу выбираем &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; объектов для кластеризации, объявляем их центроидами&lt;br /&gt;
        &lt;br /&gt;
    &#039;&#039;&#039;2. Шаг классификации&#039;&#039;&#039;&lt;br /&gt;
        Классифицируем каждый объект на предмет принадлежности к кластеру:&lt;br /&gt;
        &lt;br /&gt;
        &amp;lt;math&amp;gt;a_i \in P \Leftrightarrow \left|a_i - s_P\right| \rightarrow \min_P&amp;lt;/math&amp;gt;&lt;br /&gt;
        &lt;br /&gt;
    &#039;&#039;&#039;3. Шаг перерасчета центроидов&#039;&#039;&#039;&lt;br /&gt;
        Вычисляем центр масс каждого из кластеров.&lt;br /&gt;
        &lt;br /&gt;
    &#039;&#039;&#039;3.а&#039;&#039;&#039; Если для какого-либо кластера его центр масс &#039;&#039;&#039;отличается&#039;&#039;&#039; от центроида, то &lt;br /&gt;
            * переносим центроид этого кластера во вновь образованный центр масс,&lt;br /&gt;
            * проделываем эту операцию для всех других кластеров&lt;br /&gt;
            * переходим к &#039;&#039;&#039;Шагу 2&#039;&#039;&#039;&lt;br /&gt;
        &lt;br /&gt;
    &#039;&#039;&#039;3.б&#039;&#039;&#039; Если для каждого кластера его центр масс &#039;&#039;&#039;совпадает&#039;&#039;&#039; с центроидом, то&lt;br /&gt;
            &#039;&#039;&#039;Выход из алгоритма&#039;&#039;&#039;, объекты классифицированы.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Альтернатива&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Последовательность шагов алгоритма следующая:&lt;br /&gt;
&lt;br /&gt;
    1) Инициализация центроидов &amp;lt;math&amp;gt;\Mu&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt; iter = 1 &amp;lt;/math&amp;gt;, задание максимального количество итераций &amp;lt;math&amp;gt;maxiter&amp;lt;/math&amp;gt;&lt;br /&gt;
    2a) Нахождение матрицы расстояний &amp;lt;math&amp;gt;dist: dist_{ij} = \sum_{l = 1\dots d} (x_{il}-\mu_{il})^2&amp;lt;/math&amp;gt;&lt;br /&gt;
    2b) Нахождение вектора распределения объектов по кластерам &amp;lt;math&amp;gt;index: index_{i} = argmin_{j} dist_{ij} &amp;lt;/math&amp;gt;&lt;br /&gt;
    3) Пересчет центроидов &amp;lt;math&amp;gt;\tilde{\Mu}: \tilde{\mu_{ij}} = \sum_{l \in T_i} x_{lj}/|T_i| &amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;T_i = \{l| l \in 1\dots n, index_l = i\}  &amp;lt;/math&amp;gt;&lt;br /&gt;
    4) Проверка критерия останова: если &amp;lt;math&amp;gt; \exists i: \tilde{\mu_i} \neq \mu_i&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt; iter &amp;lt; maxiter &amp;lt;/math&amp;gt;, то &amp;lt;math&amp;gt; inc(iter), \Mu=\tilde{\Mu}&amp;lt;/math&amp;gt;, goto 2a&lt;br /&gt;
&lt;br /&gt;
== Последовательная сложность алгоритма ==&lt;br /&gt;
&lt;br /&gt;
    &#039;&#039;&#039;1. Шаг инициализации&#039;&#039;&#039;&lt;br /&gt;
        &lt;br /&gt;
        Сложность выбора &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; центроидов &amp;lt;math&amp;gt;O(1)&amp;lt;/math&amp;gt;&lt;br /&gt;
       &lt;br /&gt;
   &#039;&#039;&#039;2. Шаг классификации&#039;&#039;&#039;&lt;br /&gt;
       &lt;br /&gt;
        Для каждого из &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;объектов требуется выполнить &amp;lt;math&amp;gt;k*dim&amp;lt;/math&amp;gt; операций умножения и &amp;lt;math&amp;gt;k*(k - 1)&amp;lt;/math&amp;gt; операций сложения. То есть сложность вычисления расстояний на каждой итерации &amp;lt;math&amp;gt;O(n*k*(dim + k - 1)&amp;lt;/math&amp;gt;.&lt;br /&gt;
        &lt;br /&gt;
        После этого нужно найти кластер, расстояние до которого минимально. Сложность такого поиска &amp;lt;math&amp;gt;O(n*k)&amp;lt;/math&amp;gt;&lt;br /&gt;
        &lt;br /&gt;
        &#039;&#039;&#039;Суммарная сложность шага &amp;lt;math&amp;gt;O(n*k*(dim + k - 1)&amp;lt;/math&amp;gt;.&#039;&#039;&#039;&lt;br /&gt;
       &lt;br /&gt;
   &#039;&#039;&#039;3. Шаг перерасчета центроидов&#039;&#039;&#039;&lt;br /&gt;
       &lt;br /&gt;
       Для вычисления центра масс каждого из кластеров требуется совершить &amp;lt;math&amp;gt;(n - 1)*dim&amp;lt;/math&amp;gt; операцию сложения и &amp;lt;math&amp;gt;k*dim&amp;lt;/math&amp;gt; операций деления. Сложность шага &amp;lt;math&amp;gt;O((n + k - 1)*dim)&amp;lt;/math&amp;gt;&lt;br /&gt;
       &lt;br /&gt;
   3.а Обновление центроидов потребует &amp;lt;math&amp;gt;k*dim&amp;lt;/math&amp;gt; операций вычитания, сложность шага &amp;lt;math&amp;gt;O(k*dim)&amp;lt;/math&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;
&#039;&#039;&#039;Входные данные&#039;&#039;&#039;: Количество кластеров &amp;lt;b&amp;gt;k&amp;lt;/b&amp;gt;, &amp;lt;b&amp;gt;n&amp;lt;/b&amp;gt; кластеризуемых элементов&lt;br /&gt;
&lt;br /&gt;
Дополнительные ограничения:&lt;br /&gt;
* &amp;lt;b&amp;gt;k&amp;lt;/b&amp;gt; — положительное число, т. е. &amp;lt;b&amp;gt;k &amp;gt; 0&amp;lt;/b&amp;gt;.&lt;br /&gt;
* Для кластеризуемых элементов определена метрика (расстояние между объектами)&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Объём входных данных&#039;&#039;&#039;: &amp;lt;b&amp;gt;n &amp;lt;math&amp;gt;\cdot&amp;lt;/math&amp;gt; d + 1&amp;lt;/b&amp;gt; (кластеризуемые объекты в виде векторов и число &amp;lt;b&amp;gt;k&amp;lt;/b&amp;gt;)&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Выходные данные&#039;&#039;&#039;: Массив, в который записаны принадлежности каждого элемента кластеру (допустим вывод в другой эквивалентной более удобной структуре).&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Объём выходных данных&#039;&#039;&#039;:  Размер массива равен &amp;lt;b&amp;gt;2 &amp;lt;math&amp;gt;\cdot&amp;lt;/math&amp;gt; n&amp;lt;/b&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Свойства алгоритма ==&lt;br /&gt;
&lt;br /&gt;
Вычислительная мощность алгоритма на каждом шаге равна &amp;lt;math&amp;gt;k\cdot n&amp;lt;/math&amp;gt; (расстояние между элементом и центроидом &amp;lt;math&amp;gt;k\cdot n&amp;lt;/math&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;
[1] Нейский И.М. Классификация и сравнение методов кластеризации http://it-claim.ru/Persons/Neyskiy/Article2_Neiskiy.pdf&lt;br /&gt;
&lt;br /&gt;
[2] https://ru.wikipedia.org/wiki/K-means&lt;br /&gt;
&lt;br /&gt;
[[en:Description of algorithm properties and structure]]&lt;/div&gt;</summary>
		<author><name>Богомазов Евгений</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%98%D0%BB%D1%8C%D1%8F_%D0%95%D0%B3%D0%BE%D1%80%D0%BE%D0%B2/%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_k-%D1%81%D1%80%D0%B5%D0%B4%D0%BD%D0%B8%D1%85&amp;diff=7634</id>
		<title>Участник:Илья Егоров/Алгоритм k-средних</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%98%D0%BB%D1%8C%D1%8F_%D0%95%D0%B3%D0%BE%D1%80%D0%BE%D0%B2/%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_k-%D1%81%D1%80%D0%B5%D0%B4%D0%BD%D0%B8%D1%85&amp;diff=7634"/>
		<updated>2016-10-14T15:03:25Z</updated>

		<summary type="html">&lt;p&gt;Богомазов Евгений: /* Вычислительное ядро алгоритма */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{algorithm&lt;br /&gt;
| name              = Алгоритм k-средних (k-means)&lt;br /&gt;
| serial_complexity = &amp;lt;math&amp;gt;O()&amp;lt;/math&amp;gt;&lt;br /&gt;
| input_data        = &amp;lt;math&amp;gt;\frac{()}{}&amp;lt;/math&amp;gt;&lt;br /&gt;
| output_data       = &amp;lt;math&amp;gt;\frac{ ()}{}&amp;lt;/math&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&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;
Алгоритм кластеризации k-средних впервые был предложен в 1950-х годах математиками Гуго Штейнгаузом и Стюартом Ллойдом независимо друг от друга. Наибольшую популярность он получил после работы Маккуина.&lt;br /&gt;
&lt;br /&gt;
Алгоритм позволяет при заданном числе &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; построить &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластеров, расположенных на максимальном расстоянии друг от друга. Таким образом, наибольшей точности результат выполнения алгоритма достигает при полной осведомленности Пользователя о характере кластеризуемых объектов и, как следствие, при обладании максимально корректной информацией о числе кластеров.&lt;br /&gt;
&lt;br /&gt;
В общем случае выбор числа &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; может базироваться на любых значимых факторах, в том числе на результатах предшествующих исследований, теоретических соображениях или интуиции. &lt;br /&gt;
&lt;br /&gt;
== Математическое описание алгоритма ==&lt;br /&gt;
&#039;&#039;&#039;Исходные данные:&#039;&#039;&#039;&lt;br /&gt;
* Совокупность &amp;lt;b&amp;gt;n&amp;lt;/b&amp;gt; &amp;lt;b&amp;gt;d&amp;lt;/b&amp;gt;-мерных векторов &amp;lt;math&amp;gt; X = \{x_1 \dots x_n\} , &amp;lt;/math&amp;gt; где  &amp;lt;math&amp;gt; x_i = \{x_{i1} \dots x_{id}\} &amp;lt;/math&amp;gt;&lt;br /&gt;
* Предполагаемое количество кластеров &amp;lt;b&amp;gt;k&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Выходные данные:&#039;&#039;&#039;&lt;br /&gt;
* Разбиение X на множество &amp;lt;math&amp;gt; S = \{S_1 \dots S_k \}, \bigcup S_i = X, S_i \cap S_j = \emptyset, i \neq j &amp;lt;/math&amp;gt;&lt;br /&gt;
* k центров кластеров &amp;lt;math&amp;gt; \Mu = \{\mu_1 \dots \mu_k \} &amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt; \mu_i = \{\mu_{i1} \dots \mu_{id} \} &amp;lt;/math&amp;gt; такие, что&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; \begin{cases}\mu_i = argmin_y \sum_{x \in S_i} ||x-y||^2_E \\ \mu_i = argmin_\Mu \sum_{i \in k} \sum_{x \in S_i} ||x-\mu_i||^2_E \end{cases} &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Алгоритм:&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
1) &amp;lt;math&amp;gt; \mu_{ij} = random &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
2) &amp;lt;math&amp;gt; S_i = \{x| argmin_j ||x-\mu_j|| = i\} i = 1 \dots k &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
3) &amp;lt;math&amp;gt; \tilde{\mu_{i}} = E_{x \in S_i}(x) &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
4) Если для &amp;lt;math&amp;gt; \forall i:  \mu_i = \tilde{\mu_i} &amp;lt;/math&amp;gt; то алгоритм завершен, иначе &amp;lt;math&amp;gt; \mu_i = \tilde{\mu_i} &amp;lt;/math&amp;gt; и перейти на пункт 2)&lt;br /&gt;
&lt;br /&gt;
== Вычислительное ядро алгоритма ==&lt;br /&gt;
&lt;br /&gt;
Основное время работы алгоритма приходится на вычисление расстояний от каждого объекта до каждого из центроидов. Эту операцию придется повторять до тех пор, пока центроиды смещаются.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Альтернатива&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Вычислительным ядром алгоритма является второй этап, а точнее нахождение матрицы расстояний между &amp;lt;math&amp;gt;X&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\Mu&amp;lt;/math&amp;gt;. Для &#039;&#039;&#039;d&#039;&#039;&#039;-мерного вектора &amp;lt;math&amp;gt;a:&amp;lt;/math&amp;gt; &lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;||a||=\sqrt{\sum_{i=1\dots d} a_i^2}&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; операций сложения и одну операция вычисления квадратного корня. Но так как эти расстояния используются только для сравнения, а &#039;&#039;sqrt&#039;&#039; является монотонно возрастающей функцией, то ее можно не вычислять. Поэтому нахождения матрицы расстояний потребует всего &amp;lt;math&amp;gt;n*k*d&amp;lt;/math&amp;gt; операций умножений и &amp;lt;math&amp;gt;n*k*(d-1)&amp;lt;/math&amp;gt; операций сложений.&lt;br /&gt;
&lt;br /&gt;
== Макроструктура алгоритма ==&lt;br /&gt;
&lt;br /&gt;
Алгоритм k-средних базируется на алгоритме вычисления расстояния между векторами, расстояние на каждом шаге высчитывается &amp;lt;math&amp;gt;k\cdot n&amp;lt;/math&amp;gt; раз.&lt;br /&gt;
&lt;br /&gt;
Помимо этого, в конце каждого шага вычисляется центр масс объектов кластера, для всех объектов потребуется &amp;lt;math&amp;gt;n-1&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;
&lt;br /&gt;
Последовательность шагов алгоритма следующая:&lt;br /&gt;
&lt;br /&gt;
    &#039;&#039;&#039;1. Шаг инициализации&#039;&#039;&#039;&lt;br /&gt;
        По какому-либо правилу выбираем &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; объектов для кластеризации, объявляем их центроидами&lt;br /&gt;
        &lt;br /&gt;
    &#039;&#039;&#039;2. Шаг классификации&#039;&#039;&#039;&lt;br /&gt;
        Классифицируем каждый объект на предмет принадлежности к кластеру:&lt;br /&gt;
        &lt;br /&gt;
        &amp;lt;math&amp;gt;a_i \in P \Leftrightarrow \left|a_i - s_P\right| \rightarrow \min_P&amp;lt;/math&amp;gt;&lt;br /&gt;
        &lt;br /&gt;
    &#039;&#039;&#039;3. Шаг перерасчета центроидов&#039;&#039;&#039;&lt;br /&gt;
        Вычисляем центр масс каждого из кластеров.&lt;br /&gt;
        &lt;br /&gt;
    &#039;&#039;&#039;3.а&#039;&#039;&#039; Если для какого-либо кластера его центр масс &#039;&#039;&#039;отличается&#039;&#039;&#039; от центроида, то &lt;br /&gt;
            * переносим центроид этого кластера во вновь образованный центр масс,&lt;br /&gt;
            * проделываем эту операцию для всех других кластеров&lt;br /&gt;
            * переходим к &#039;&#039;&#039;Шагу 2&#039;&#039;&#039;&lt;br /&gt;
        &lt;br /&gt;
    &#039;&#039;&#039;3.б&#039;&#039;&#039; Если для каждого кластера его центр масс &#039;&#039;&#039;совпадает&#039;&#039;&#039; с центроидом, то&lt;br /&gt;
            &#039;&#039;&#039;Выход из алгоритма&#039;&#039;&#039;, объекты классифицированы.&lt;br /&gt;
&lt;br /&gt;
== Последовательная сложность алгоритма ==&lt;br /&gt;
&lt;br /&gt;
    &#039;&#039;&#039;1. Шаг инициализации&#039;&#039;&#039;&lt;br /&gt;
        &lt;br /&gt;
        Сложность выбора &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; центроидов &amp;lt;math&amp;gt;O(1)&amp;lt;/math&amp;gt;&lt;br /&gt;
       &lt;br /&gt;
   &#039;&#039;&#039;2. Шаг классификации&#039;&#039;&#039;&lt;br /&gt;
       &lt;br /&gt;
        Для каждого из &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;объектов требуется выполнить &amp;lt;math&amp;gt;k*dim&amp;lt;/math&amp;gt; операций умножения и &amp;lt;math&amp;gt;k*(k - 1)&amp;lt;/math&amp;gt; операций сложения. То есть сложность вычисления расстояний на каждой итерации &amp;lt;math&amp;gt;O(n*k*(dim + k - 1)&amp;lt;/math&amp;gt;.&lt;br /&gt;
        &lt;br /&gt;
        После этого нужно найти кластер, расстояние до которого минимально. Сложность такого поиска &amp;lt;math&amp;gt;O(n*k)&amp;lt;/math&amp;gt;&lt;br /&gt;
        &lt;br /&gt;
        &#039;&#039;&#039;Суммарная сложность шага &amp;lt;math&amp;gt;O(n*k*(dim + k - 1)&amp;lt;/math&amp;gt;.&#039;&#039;&#039;&lt;br /&gt;
       &lt;br /&gt;
   &#039;&#039;&#039;3. Шаг перерасчета центроидов&#039;&#039;&#039;&lt;br /&gt;
       &lt;br /&gt;
       Для вычисления центра масс каждого из кластеров требуется совершить &amp;lt;math&amp;gt;(n - 1)*dim&amp;lt;/math&amp;gt; операцию сложения и &amp;lt;math&amp;gt;k*dim&amp;lt;/math&amp;gt; операций деления. Сложность шага &amp;lt;math&amp;gt;O((n + k - 1)*dim)&amp;lt;/math&amp;gt;&lt;br /&gt;
       &lt;br /&gt;
   3.а Обновление центроидов потребует &amp;lt;math&amp;gt;k*dim&amp;lt;/math&amp;gt; операций вычитания, сложность шага &amp;lt;math&amp;gt;O(k*dim)&amp;lt;/math&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;
&#039;&#039;&#039;Входные данные&#039;&#039;&#039;: Количество кластеров &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;m&amp;lt;/math&amp;gt;кластеризуемых элементов&lt;br /&gt;
Дополнительные ограничения:&lt;br /&gt;
* &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; — положительное число, т. е. &amp;lt;math&amp;gt;k &amp;gt; 0&amp;lt;/math&amp;gt;.&lt;br /&gt;
* Для кластеризуемых элементов определена метрика (расстояние между объектами)&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Объём входных данных&#039;&#039;&#039;: &amp;lt;math&amp;gt;n\cdot dim + 1&amp;lt;/math&amp;gt; (кластеризуемые объекты в виде векторов и число &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt;)&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Выходные данные&#039;&#039;&#039;: Массив, в который записаны принадлежности каждого элемента кластеру (допустим вывод в другой эквивалентной более удобной структуре).&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Объём выходных данных&#039;&#039;&#039;:  Размер массива равен &amp;lt;math&amp;gt;2\cdot n&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Свойства алгоритма ==&lt;br /&gt;
&lt;br /&gt;
Вычислительная мощность алгоритма на каждом шаге равна &amp;lt;math&amp;gt;k\cdot n&amp;lt;/math&amp;gt; (расстояние между элементом и центроидом &amp;lt;math&amp;gt;k\cdot n&amp;lt;/math&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;
[1] Нейский И.М. Классификация и сравнение методов кластеризации http://it-claim.ru/Persons/Neyskiy/Article2_Neiskiy.pdf&lt;br /&gt;
&lt;br /&gt;
[2] https://ru.wikipedia.org/wiki/K-means&lt;br /&gt;
&lt;br /&gt;
[[en:Description of algorithm properties and structure]]&lt;/div&gt;</summary>
		<author><name>Богомазов Евгений</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%98%D0%BB%D1%8C%D1%8F_%D0%95%D0%B3%D0%BE%D1%80%D0%BE%D0%B2/%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_k-%D1%81%D1%80%D0%B5%D0%B4%D0%BD%D0%B8%D1%85&amp;diff=7633</id>
		<title>Участник:Илья Егоров/Алгоритм k-средних</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%98%D0%BB%D1%8C%D1%8F_%D0%95%D0%B3%D0%BE%D1%80%D0%BE%D0%B2/%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_k-%D1%81%D1%80%D0%B5%D0%B4%D0%BD%D0%B8%D1%85&amp;diff=7633"/>
		<updated>2016-10-14T15:02:50Z</updated>

		<summary type="html">&lt;p&gt;Богомазов Евгений: /* Вычислительное ядро алгоритма */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{algorithm&lt;br /&gt;
| name              = Алгоритм k-средних (k-means)&lt;br /&gt;
| serial_complexity = &amp;lt;math&amp;gt;O()&amp;lt;/math&amp;gt;&lt;br /&gt;
| input_data        = &amp;lt;math&amp;gt;\frac{()}{}&amp;lt;/math&amp;gt;&lt;br /&gt;
| output_data       = &amp;lt;math&amp;gt;\frac{ ()}{}&amp;lt;/math&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&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;
Алгоритм кластеризации k-средних впервые был предложен в 1950-х годах математиками Гуго Штейнгаузом и Стюартом Ллойдом независимо друг от друга. Наибольшую популярность он получил после работы Маккуина.&lt;br /&gt;
&lt;br /&gt;
Алгоритм позволяет при заданном числе &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; построить &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластеров, расположенных на максимальном расстоянии друг от друга. Таким образом, наибольшей точности результат выполнения алгоритма достигает при полной осведомленности Пользователя о характере кластеризуемых объектов и, как следствие, при обладании максимально корректной информацией о числе кластеров.&lt;br /&gt;
&lt;br /&gt;
В общем случае выбор числа &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; может базироваться на любых значимых факторах, в том числе на результатах предшествующих исследований, теоретических соображениях или интуиции. &lt;br /&gt;
&lt;br /&gt;
== Математическое описание алгоритма ==&lt;br /&gt;
&#039;&#039;&#039;Исходные данные:&#039;&#039;&#039;&lt;br /&gt;
* Совокупность &amp;lt;b&amp;gt;n&amp;lt;/b&amp;gt; &amp;lt;b&amp;gt;d&amp;lt;/b&amp;gt;-мерных векторов &amp;lt;math&amp;gt; X = \{x_1 \dots x_n\} , &amp;lt;/math&amp;gt; где  &amp;lt;math&amp;gt; x_i = \{x_{i1} \dots x_{id}\} &amp;lt;/math&amp;gt;&lt;br /&gt;
* Предполагаемое количество кластеров &amp;lt;b&amp;gt;k&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Выходные данные:&#039;&#039;&#039;&lt;br /&gt;
* Разбиение X на множество &amp;lt;math&amp;gt; S = \{S_1 \dots S_k \}, \bigcup S_i = X, S_i \cap S_j = \emptyset, i \neq j &amp;lt;/math&amp;gt;&lt;br /&gt;
* k центров кластеров &amp;lt;math&amp;gt; \Mu = \{\mu_1 \dots \mu_k \} &amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt; \mu_i = \{\mu_{i1} \dots \mu_{id} \} &amp;lt;/math&amp;gt; такие, что&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; \begin{cases}\mu_i = argmin_y \sum_{x \in S_i} ||x-y||^2_E \\ \mu_i = argmin_\Mu \sum_{i \in k} \sum_{x \in S_i} ||x-\mu_i||^2_E \end{cases} &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Алгоритм:&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
1) &amp;lt;math&amp;gt; \mu_{ij} = random &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
2) &amp;lt;math&amp;gt; S_i = \{x| argmin_j ||x-\mu_j|| = i\} i = 1 \dots k &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
3) &amp;lt;math&amp;gt; \tilde{\mu_{i}} = E_{x \in S_i}(x) &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
4) Если для &amp;lt;math&amp;gt; \forall i:  \mu_i = \tilde{\mu_i} &amp;lt;/math&amp;gt; то алгоритм завершен, иначе &amp;lt;math&amp;gt; \mu_i = \tilde{\mu_i} &amp;lt;/math&amp;gt; и перейти на пункт 2)&lt;br /&gt;
&lt;br /&gt;
== Вычислительное ядро алгоритма ==&lt;br /&gt;
&lt;br /&gt;
Основное время работы алгоритма приходится на вычисление расстояний от каждого объекта до каждого из центроидов. Эту операцию придется повторять до тех пор, пока центроиды смещаются.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Альтернатива&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Вычислительным ядром алгоритма является второй этап, а точнее нахождение матрицы расстояний между &amp;lt;math&amp;gt;X&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\Mu&amp;lt;/math&amp;gt;. Для &#039;&#039;&#039;d&#039;&#039;&#039;-мерного вектора &amp;lt;math&amp;gt;a:&amp;lt;/math&amp;gt; &lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;||a||=\sqrt{\sum_{i=1\dots d} a_i^2}&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; операций сложения и одну операция вычисления квадратного корня. Но так как эти расстояния используются только для сравнения, а &#039;&#039;sqrt&#039;&#039; является монотонно возрастающей функцией, то ее можно не вычислять. Поэтому нахождения матрицы расстояний потребует всего &amp;lt;math&amp;gt;d*n*k&amp;lt;/math&amp;gt; операций умножений и &amp;lt;math&amp;gt;n*k*(d-1)&amp;lt;/math&amp;gt; операций сложений.&lt;br /&gt;
&lt;br /&gt;
== Макроструктура алгоритма ==&lt;br /&gt;
&lt;br /&gt;
Алгоритм k-средних базируется на алгоритме вычисления расстояния между векторами, расстояние на каждом шаге высчитывается &amp;lt;math&amp;gt;k\cdot n&amp;lt;/math&amp;gt; раз.&lt;br /&gt;
&lt;br /&gt;
Помимо этого, в конце каждого шага вычисляется центр масс объектов кластера, для всех объектов потребуется &amp;lt;math&amp;gt;n-1&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;
&lt;br /&gt;
Последовательность шагов алгоритма следующая:&lt;br /&gt;
&lt;br /&gt;
    &#039;&#039;&#039;1. Шаг инициализации&#039;&#039;&#039;&lt;br /&gt;
        По какому-либо правилу выбираем &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; объектов для кластеризации, объявляем их центроидами&lt;br /&gt;
        &lt;br /&gt;
    &#039;&#039;&#039;2. Шаг классификации&#039;&#039;&#039;&lt;br /&gt;
        Классифицируем каждый объект на предмет принадлежности к кластеру:&lt;br /&gt;
        &lt;br /&gt;
        &amp;lt;math&amp;gt;a_i \in P \Leftrightarrow \left|a_i - s_P\right| \rightarrow \min_P&amp;lt;/math&amp;gt;&lt;br /&gt;
        &lt;br /&gt;
    &#039;&#039;&#039;3. Шаг перерасчета центроидов&#039;&#039;&#039;&lt;br /&gt;
        Вычисляем центр масс каждого из кластеров.&lt;br /&gt;
        &lt;br /&gt;
    &#039;&#039;&#039;3.а&#039;&#039;&#039; Если для какого-либо кластера его центр масс &#039;&#039;&#039;отличается&#039;&#039;&#039; от центроида, то &lt;br /&gt;
            * переносим центроид этого кластера во вновь образованный центр масс,&lt;br /&gt;
            * проделываем эту операцию для всех других кластеров&lt;br /&gt;
            * переходим к &#039;&#039;&#039;Шагу 2&#039;&#039;&#039;&lt;br /&gt;
        &lt;br /&gt;
    &#039;&#039;&#039;3.б&#039;&#039;&#039; Если для каждого кластера его центр масс &#039;&#039;&#039;совпадает&#039;&#039;&#039; с центроидом, то&lt;br /&gt;
            &#039;&#039;&#039;Выход из алгоритма&#039;&#039;&#039;, объекты классифицированы.&lt;br /&gt;
&lt;br /&gt;
== Последовательная сложность алгоритма ==&lt;br /&gt;
&lt;br /&gt;
    &#039;&#039;&#039;1. Шаг инициализации&#039;&#039;&#039;&lt;br /&gt;
        &lt;br /&gt;
        Сложность выбора &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; центроидов &amp;lt;math&amp;gt;O(1)&amp;lt;/math&amp;gt;&lt;br /&gt;
       &lt;br /&gt;
   &#039;&#039;&#039;2. Шаг классификации&#039;&#039;&#039;&lt;br /&gt;
       &lt;br /&gt;
        Для каждого из &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;объектов требуется выполнить &amp;lt;math&amp;gt;k*dim&amp;lt;/math&amp;gt; операций умножения и &amp;lt;math&amp;gt;k*(k - 1)&amp;lt;/math&amp;gt; операций сложения. То есть сложность вычисления расстояний на каждой итерации &amp;lt;math&amp;gt;O(n*k*(dim + k - 1)&amp;lt;/math&amp;gt;.&lt;br /&gt;
        &lt;br /&gt;
        После этого нужно найти кластер, расстояние до которого минимально. Сложность такого поиска &amp;lt;math&amp;gt;O(n*k)&amp;lt;/math&amp;gt;&lt;br /&gt;
        &lt;br /&gt;
        &#039;&#039;&#039;Суммарная сложность шага &amp;lt;math&amp;gt;O(n*k*(dim + k - 1)&amp;lt;/math&amp;gt;.&#039;&#039;&#039;&lt;br /&gt;
       &lt;br /&gt;
   &#039;&#039;&#039;3. Шаг перерасчета центроидов&#039;&#039;&#039;&lt;br /&gt;
       &lt;br /&gt;
       Для вычисления центра масс каждого из кластеров требуется совершить &amp;lt;math&amp;gt;(n - 1)*dim&amp;lt;/math&amp;gt; операцию сложения и &amp;lt;math&amp;gt;k*dim&amp;lt;/math&amp;gt; операций деления. Сложность шага &amp;lt;math&amp;gt;O((n + k - 1)*dim)&amp;lt;/math&amp;gt;&lt;br /&gt;
       &lt;br /&gt;
   3.а Обновление центроидов потребует &amp;lt;math&amp;gt;k*dim&amp;lt;/math&amp;gt; операций вычитания, сложность шага &amp;lt;math&amp;gt;O(k*dim)&amp;lt;/math&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;
&#039;&#039;&#039;Входные данные&#039;&#039;&#039;: Количество кластеров &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;m&amp;lt;/math&amp;gt;кластеризуемых элементов&lt;br /&gt;
Дополнительные ограничения:&lt;br /&gt;
* &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; — положительное число, т. е. &amp;lt;math&amp;gt;k &amp;gt; 0&amp;lt;/math&amp;gt;.&lt;br /&gt;
* Для кластеризуемых элементов определена метрика (расстояние между объектами)&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Объём входных данных&#039;&#039;&#039;: &amp;lt;math&amp;gt;n\cdot dim + 1&amp;lt;/math&amp;gt; (кластеризуемые объекты в виде векторов и число &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt;)&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Выходные данные&#039;&#039;&#039;: Массив, в который записаны принадлежности каждого элемента кластеру (допустим вывод в другой эквивалентной более удобной структуре).&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Объём выходных данных&#039;&#039;&#039;:  Размер массива равен &amp;lt;math&amp;gt;2\cdot n&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Свойства алгоритма ==&lt;br /&gt;
&lt;br /&gt;
Вычислительная мощность алгоритма на каждом шаге равна &amp;lt;math&amp;gt;k\cdot n&amp;lt;/math&amp;gt; (расстояние между элементом и центроидом &amp;lt;math&amp;gt;k\cdot n&amp;lt;/math&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;
[1] Нейский И.М. Классификация и сравнение методов кластеризации http://it-claim.ru/Persons/Neyskiy/Article2_Neiskiy.pdf&lt;br /&gt;
&lt;br /&gt;
[2] https://ru.wikipedia.org/wiki/K-means&lt;br /&gt;
&lt;br /&gt;
[[en:Description of algorithm properties and structure]]&lt;/div&gt;</summary>
		<author><name>Богомазов Евгений</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%98%D0%BB%D1%8C%D1%8F_%D0%95%D0%B3%D0%BE%D1%80%D0%BE%D0%B2/%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_k-%D1%81%D1%80%D0%B5%D0%B4%D0%BD%D0%B8%D1%85&amp;diff=7513</id>
		<title>Участник:Илья Егоров/Алгоритм k-средних</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%98%D0%BB%D1%8C%D1%8F_%D0%95%D0%B3%D0%BE%D1%80%D0%BE%D0%B2/%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_k-%D1%81%D1%80%D0%B5%D0%B4%D0%BD%D0%B8%D1%85&amp;diff=7513"/>
		<updated>2016-10-14T13:29:34Z</updated>

		<summary type="html">&lt;p&gt;Богомазов Евгений: /* Математическое описание алгоритма */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{algorithm&lt;br /&gt;
| name              = Алгоритм k-средних (k-means)&lt;br /&gt;
| serial_complexity = &amp;lt;math&amp;gt;O()&amp;lt;/math&amp;gt;&lt;br /&gt;
| input_data        = &amp;lt;math&amp;gt;\frac{()}{}&amp;lt;/math&amp;gt;&lt;br /&gt;
| output_data       = &amp;lt;math&amp;gt;\frac{ ()}{}&amp;lt;/math&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&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;
Алгоритм кластеризации k-средних впервые был предложен в 1950-х годах математиками Гуго Штейнгаузом и Стюартом Ллойдом независимо друг от друга. Наибольшую популярность он получил после работы Маккуина.&lt;br /&gt;
&lt;br /&gt;
Алгоритм позволяет при заданном числе &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; построить &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластеров, расположенных на максимальном расстоянии друг от друга. Таким образом, наибольшей точности результат выполнения алгоритма достигает при полной осведомленности Пользователя о характере кластеризуемых объектов и, как следствие, при обладании максимально корректной информацией о числе кластеров.&lt;br /&gt;
&lt;br /&gt;
В общем случае выбор числа &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; может базироваться на любых значимых факторах, в том числе на результатах предшествующих исследований, теоретических соображениях или интуиции. &lt;br /&gt;
&lt;br /&gt;
== Математическое описание алгоритма ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Исходные данные:&#039;&#039;&#039; &lt;br /&gt;
* &amp;lt;math&amp;gt;\{a_i\}, i = 1 \dots m&amp;lt;/math&amp;gt; — множество из &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; объектов, подлежащих кластеризации и определяющихся вектором длины &amp;lt;math&amp;gt;dim&amp;lt;/math&amp;gt;,&lt;br /&gt;
* &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; — предполагаемое количество кластеров.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Вычисляемые данные:&#039;&#039;&#039;&lt;br /&gt;
* Центр предполагаемого кластера (центроид) — на первом шаге объявляется равным случайному объекту, а затем сдвигается в центр масс элементов кластера.&lt;br /&gt;
&lt;br /&gt;
Если &amp;lt;math&amp;gt;\{s_1 \dots s_k\}&amp;lt;/math&amp;gt; — центроиды, где &amp;lt;math&amp;gt;1 \dots k&amp;lt;/math&amp;gt; — номера кластеров, то объект &amp;lt;math&amp;gt;a&amp;lt;/math&amp;gt; относится к кластеру &amp;lt;math&amp;gt;P&amp;lt;/math&amp;gt;, если суммарное квадратичное отклонение точек кластеров от центров этих кластеров минимально:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;a_i \in P \Leftrightarrow \left|a_i - s_P\right| \rightarrow \min_P&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Альтернатива:&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Исходные данные:&#039;&#039;&#039;&lt;br /&gt;
* Совокупность &amp;lt;b&amp;gt;n&amp;lt;/b&amp;gt; &amp;lt;b&amp;gt;d&amp;lt;/b&amp;gt;-мерных векторов &amp;lt;math&amp;gt; X = \{x_1 \dots x_n\} , &amp;lt;/math&amp;gt; где  &amp;lt;math&amp;gt; x_i = \{x_{i1} \dots x_{id}\} &amp;lt;/math&amp;gt;&lt;br /&gt;
* Предполагаемое количество кластеров &amp;lt;b&amp;gt;k&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Выходные данные:&#039;&#039;&#039;&lt;br /&gt;
* Разбиение X на множество &amp;lt;math&amp;gt; S = \{S_1 \dots S_k \}, \bigcup S_i = X, S_i \cap S_j = \emptyset, i \neq j &amp;lt;/math&amp;gt;&lt;br /&gt;
* k центров кластеров &amp;lt;math&amp;gt; \Mu = \{\mu_1 \dots \mu_k \} &amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt; \mu_i = \{\mu_{i1} \dots \mu_{id} \} &amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt; \mu_i = argmin_y \sum_{x \in S_i} ||x-y||^2_E &amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt; argmin_\Mu \sum_{i \in k} \sum_{x \in S_i} ||x-\mu_i||^2_E &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Алгоритм:&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
1) &amp;lt;math&amp;gt; \mu_{ij} = random &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
2) &amp;lt;math&amp;gt; S_i = \{x| argmin_j ||x-\mu_j|| = i\} i = 1 \dots k &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
3) &amp;lt;math&amp;gt; \tilde{\mu_{i}} = E_{x \in S_i}(x) &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
4) Если для &amp;lt;math&amp;gt; \forall i:  \mu_i = \tilde{\mu_i} &amp;lt;/math&amp;gt; то алгоритм завершен, иначе &amp;lt;math&amp;gt; \mu_i = \tilde{\mu_i} &amp;lt;/math&amp;gt; и перейти на пункт 2)&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-средних базируется на алгоритме вычисления расстояния между векторами, расстояние на каждом шаге высчитывается &amp;lt;math&amp;gt;k\cdot n&amp;lt;/math&amp;gt; раз.&lt;br /&gt;
&lt;br /&gt;
Помимо этого, в конце каждого шага вычисляется центр масс объектов кластера, для всех объектов потребуется &amp;lt;math&amp;gt;n-1&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;
&lt;br /&gt;
Последовательность шагов алгоритма следующая:&lt;br /&gt;
&lt;br /&gt;
    &#039;&#039;&#039;1. Шаг инициализации&#039;&#039;&#039;&lt;br /&gt;
        По какому-либо правилу выбираем &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; объектов для кластеризации, объявляем их центроидами&lt;br /&gt;
        &lt;br /&gt;
    &#039;&#039;&#039;2. Шаг классификации&#039;&#039;&#039;&lt;br /&gt;
        Классифицируем каждый объект на предмет принадлежности к кластеру:&lt;br /&gt;
        &lt;br /&gt;
        &amp;lt;math&amp;gt;a_i \in P \Leftrightarrow \left|a_i - s_P\right| \rightarrow \min_P&amp;lt;/math&amp;gt;&lt;br /&gt;
        &lt;br /&gt;
    &#039;&#039;&#039;3. Шаг перерасчета центроидов&#039;&#039;&#039;&lt;br /&gt;
        Вычисляем центр масс каждого из кластеров.&lt;br /&gt;
        &lt;br /&gt;
    &#039;&#039;&#039;3.а&#039;&#039;&#039; Если для какого-либо кластера его центр масс &#039;&#039;&#039;отличается&#039;&#039;&#039; от центроида, то &lt;br /&gt;
            * переносим центроид этого кластера во вновь образованный центр масс,&lt;br /&gt;
            * проделываем эту операцию для всех других кластеров&lt;br /&gt;
            * переходим к &#039;&#039;&#039;Шагу 2&#039;&#039;&#039;&lt;br /&gt;
        &lt;br /&gt;
    &#039;&#039;&#039;3.б&#039;&#039;&#039; Если для каждого кластера его центр масс &#039;&#039;&#039;совпадает&#039;&#039;&#039; с центроидом, то&lt;br /&gt;
            &#039;&#039;&#039;Выход из алгоритма&#039;&#039;&#039;, объекты классифицированы.&lt;br /&gt;
&lt;br /&gt;
== Последовательная сложность алгоритма ==&lt;br /&gt;
&lt;br /&gt;
    &#039;&#039;&#039;1. Шаг инициализации&#039;&#039;&#039;&lt;br /&gt;
        &lt;br /&gt;
        Сложность выбора &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; центроидов &amp;lt;math&amp;gt;O(1)&amp;lt;/math&amp;gt;&lt;br /&gt;
       &lt;br /&gt;
   &#039;&#039;&#039;2. Шаг классификации&#039;&#039;&#039;&lt;br /&gt;
       &lt;br /&gt;
        Для каждого из &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;объектов требуется выполнить &amp;lt;math&amp;gt;k*dim&amp;lt;/math&amp;gt; операций умножения и &amp;lt;math&amp;gt;k*(k - 1)&amp;lt;/math&amp;gt; операций сложения. То есть сложность вычисления расстояний на каждой итерации &amp;lt;math&amp;gt;O(n*k*(dim + k - 1)&amp;lt;/math&amp;gt;.&lt;br /&gt;
        &lt;br /&gt;
        После этого нужно найти кластер, расстояние до которого минимально. Сложность такого поиска &amp;lt;math&amp;gt;O(n*k)&amp;lt;/math&amp;gt;&lt;br /&gt;
        &lt;br /&gt;
        &#039;&#039;&#039;Суммарная сложность шага &amp;lt;math&amp;gt;O(n*k*(dim + k - 1)&amp;lt;/math&amp;gt;.&#039;&#039;&#039;&lt;br /&gt;
       &lt;br /&gt;
   &#039;&#039;&#039;3. Шаг перерасчета центроидов&#039;&#039;&#039;&lt;br /&gt;
       &lt;br /&gt;
       Для вычисления центра масс каждого из кластеров требуется совершить &amp;lt;math&amp;gt;(n - 1)*dim&amp;lt;/math&amp;gt; операцию сложения и &amp;lt;math&amp;gt;k*dim&amp;lt;/math&amp;gt; операций деления. Сложность шага &amp;lt;math&amp;gt;O((n + k - 1)*dim)&amp;lt;/math&amp;gt;&lt;br /&gt;
       &lt;br /&gt;
   3.а Обновление центроидов потребует &amp;lt;math&amp;gt;k*dim&amp;lt;/math&amp;gt; операций вычитания, сложность шага &amp;lt;math&amp;gt;O(k*dim)&amp;lt;/math&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;
&#039;&#039;&#039;Входные данные&#039;&#039;&#039;: Количество кластеров &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;m&amp;lt;/math&amp;gt;кластеризуемых элементов&lt;br /&gt;
Дополнительные ограничения:&lt;br /&gt;
* &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; — положительное число, т. е. &amp;lt;math&amp;gt;k &amp;gt; 0&amp;lt;/math&amp;gt;.&lt;br /&gt;
* Для кластеризуемых элементов определена метрика (расстояние между объектами)&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Объём входных данных&#039;&#039;&#039;: &amp;lt;math&amp;gt;n\cdot dim + 1&amp;lt;/math&amp;gt; (кластеризуемые объекты в виде векторов и число &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt;)&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Выходные данные&#039;&#039;&#039;: Массив, в который записаны принадлежности каждого элемента кластеру (допустим вывод в другой эквивалентной более удобной структуре).&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Объём выходных данных&#039;&#039;&#039;:  Размер массива равен &amp;lt;math&amp;gt;2\cdot n&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Свойства алгоритма ==&lt;br /&gt;
&lt;br /&gt;
Вычислительная мощность алгоритма на каждом шаге равна &amp;lt;math&amp;gt;k\cdot n&amp;lt;/math&amp;gt; (расстояние между элементом и центроидом &amp;lt;math&amp;gt;k\cdot n&amp;lt;/math&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;
[1] Нейский И.М. Классификация и сравнение методов кластеризации http://it-claim.ru/Persons/Neyskiy/Article2_Neiskiy.pdf&lt;br /&gt;
&lt;br /&gt;
[2] https://ru.wikipedia.org/wiki/K-means&lt;br /&gt;
&lt;br /&gt;
[[en:Description of algorithm properties and structure]]&lt;/div&gt;</summary>
		<author><name>Богомазов Евгений</name></author>
	</entry>
</feed>