<?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=Parkhomenko</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=Parkhomenko"/>
	<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/Parkhomenko"/>
	<updated>2026-10-22T23:25:58Z</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:Parkhomenko/%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=20981</id>
		<title>Участник:Parkhomenko/Алгоритм 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:Parkhomenko/%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=20981"/>
		<updated>2016-12-15T11:24:01Z</updated>

		<summary type="html">&lt;p&gt;Parkhomenko: /* Масштабируемость алгоритма и его реализации */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt; {{Assignment|Zhum}}&lt;br /&gt;
{{algorithm&lt;br /&gt;
| name              = Алгоритм k средних&lt;br /&gt;
| serial_complexity = &amp;lt;math&amp;gt;O(tnkd)&amp;lt;/math&amp;gt;&lt;br /&gt;
| input_data        = &amp;lt;math&amp;gt;nd&amp;lt;/math&amp;gt;&lt;br /&gt;
| output_data       = &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;&lt;br /&gt;
| pf_height         = &amp;lt;math&amp;gt;O(t \cdot \log nkd)&amp;lt;/math&amp;gt;&lt;br /&gt;
| pf_width          = &amp;lt;math&amp;gt;O(nkd)&amp;lt;/math&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
Основные авторы описания: [[Участник:Parkhomenko|П.А.Пархоменко]] ([[#Общее описание алгоритма|1.1]], [[#Вычислительное ядро алгоритма|1.3]], [[#Последовательная сложность алгоритма|1.6]], [[#Ресурс параллелизма алгоритма|1.8]], [[#Входные и выходные данные алгоритма|1.9]], [[#Свойства алгоритма|1.10]], [[#Масштабируемость алгоритма и его реализации|2.4]]), [[Участник:Ivan.mashonskiy|И.Д.Машонский]] ([[#Математическое описание алгоритма|1.2]], [[#Макроструктура алгоритма|1.4]], [[#Схема реализации последовательного алгоритма|1.5]], [[#Информационный граф|1.7]], [[#Ресурс параллелизма алгоритма|1.8]], [[#Свойства алгоритма|1.10]], [[#Существующие реализации алгоритма|2.7]])&lt;br /&gt;
== Свойства и структура алгоритмов ==&lt;br /&gt;
&lt;br /&gt;
=== Общее описание алгоритма ===&lt;br /&gt;
Алгоритм k средних (англ. k-means) - один из алгоритмов машинного обучения, решающий задачу кластеризации. Он был изобретен в середине 1950-х математиком Гуго Штейнгаузом&amp;lt;ref&amp;gt;Steinhaus H. (1956). Sur la division des corps materiels en parties. Bull. Acad. Polon. Sci., C1. III vol IV: 801—804.&amp;lt;/ref&amp;gt; и Стюартом Ллойдом&amp;lt;ref&amp;gt;Lloyd S. (1957). Least square quantization in PCM’s. Bell Telephone Laboratories Paper.&amp;lt;/ref&amp;gt;. Алгоритм стал особо популярным после публикации Маккуина&amp;lt;ref&amp;gt;MacQueen J. (1967). Some methods for classification and analysis of multivariate observations. In Proc. 5th Berkeley Symp. on Math. Statistics and Probability, pages 281—297.&amp;lt;/ref&amp;gt;, в которой впервые был использован термин “k-means”.&lt;br /&gt;
&lt;br /&gt;
Задача алгоритма кластеризации заключается в разбиении N объектов (d-мерных векторов) на K групп (кластеров). Каждый вектор может принадлежать только одному кластеру. Количество кластеров K фиксировано, оно задается в качестве параметра.&lt;br /&gt;
&lt;br /&gt;
K-means является итерационным алгоритмом, разновидностью EM-алгоритма. Основная идея работы алгоритма заключается в проведении некоторого количества итераций, на каждой из которых происходит пересчет центра масс для каждого кластера, полученного на предыдущей итерации. После этого векторы перераспределяются по кластерам: вектор относится к тому кластеру, расстояние до центра масс которого минимально. Алгоритм завершает работу в том случае, если на очередной итерации центры масс кластеров не изменились.&lt;br /&gt;
&lt;br /&gt;
=== Математическое описание алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Исходные данные: множество d-мерных векторов (наблюдений) &amp;lt;math&amp;gt;X&amp;lt;/math&amp;gt;&amp;amp;nbsp;=&amp;amp;nbsp;&amp;lt;math&amp;gt;\{x_1, x_2, ..., x_n\}&amp;lt;/math&amp;gt;, число кластеров &amp;lt;math&amp;gt;k \in \mathbb{N}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
В результате работы алгоритма исходное множество векторов &amp;lt;math&amp;gt;X&amp;lt;/math&amp;gt; разбивается на &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; непересекающихся множеств (кластеров) &amp;lt;math&amp;gt;S_1, S_2, ..., S_k&amp;lt;/math&amp;gt;, таких что &amp;lt;math&amp;gt;X = {\bigcup \limits _{i = 1}^k S_i} &amp;lt;/math&amp;gt; и значение &amp;lt;math&amp;gt;\sum_{i=1}^{k} \sum_{\mathbf x \in S_i} \left\| \mathbf x - \mu_i \right\|^2 &amp;lt;/math&amp;gt; — минимально для всех возможных наборов &amp;lt;math&amp;gt;S_1, S_2, ..., S_k&amp;lt;/math&amp;gt;.&lt;br /&gt;
Под &amp;lt;math&amp;gt;\mu_i&amp;lt;/math&amp;gt; здесь подразумевается центр масс векторов из множества &amp;lt;math&amp;gt;S_i&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Первоначальные значения центров масс &amp;lt;math&amp;gt;\mu_1^{(1)}, ..., \mu_k^{(1)}&amp;lt;/math&amp;gt; определяются в начале работы алгоритма случайным образом среди векторов множества &amp;lt;math&amp;gt;X&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Алгоритм заключается в попеременном применении двух шагов &amp;lt;ref&amp;gt;MacKay, David (2003). &amp;quot;Chapter 20. An Example Inference Task: Clustering&amp;quot; (PDF). Information Theory, Inference and Learning Algorithms. Cambridge University Press. pp. 284–292.&amp;lt;/ref&amp;gt;: &#039;&#039;&#039;распределения&#039;&#039;&#039; векторов по кластерам и &#039;&#039;&#039;обновления&#039;&#039;&#039; центров масс каждого кластера&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Распределение векторов по кластерам&#039;&#039;&#039;: на данном шаге каждый вектор распределяется в один из кластеров &amp;lt;math&amp;gt;S_i^{(t)}&amp;lt;/math&amp;gt;: &lt;br /&gt;
::&amp;lt;math&amp;gt;S_i^{(t)} = \big \{ x_p : \big \| x_p - \mu^{(t)}_i \big \|^2 \le \big \| x_p - \mu^{(t)}_j \big \|^2 \ \forall j, 1 \le j \le k \big\},&amp;lt;/math&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Обновление центров масс&#039;&#039;&#039;: на данном шаге вычисляются новые центры масс для кластеров, полученных на предыдущем шаге.&lt;br /&gt;
::&amp;lt;math&amp;gt;\mu^{(t+1)}_i = \frac{1}{|S^{(t)}_i|} \sum_{x_j \in S^{(t)}_i} x_j &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Алгоритм завершается, когда на очередном шаге не происходит изменения центров масс кластеров.&lt;br /&gt;
&lt;br /&gt;
=== Вычислительное ядро алгоритма ===&lt;br /&gt;
Вычислительное ядро последовательного алгоритма k-means состоит из двух операций, повторяющихся на каждой итерации алгоритма:&lt;br /&gt;
* пересчета центров масс кластеров;&lt;br /&gt;
* соотнесения каждого вектора к одному из кластеров.&lt;br /&gt;
&lt;br /&gt;
Пересчет центра масс кластера заключается в нахождении d-мерного вектора, являющегося средним арифметическим d-мерных векторов, принадлежащих кластеру. Эту операцию необходимо выполнять для каждого из K кластеров.&lt;br /&gt;
&lt;br /&gt;
Для соотнесения вектора к одному из кластеров, необходимо для каждого из N вектора посчитать расстояние до центров масс всех K кластеров. Для нахождения расстояния между двумя d-мерными векторами p и q используется Евклидова метрика: &amp;lt;math&amp;gt;\sqrt{\sum_{k=1}^d (p_k-q_k)^2}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Макроструктура алгоритма ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Инициализация центров масс кластеров&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
В начале алгоритма осуществляется инициализация центров масс &amp;lt;math&amp;gt;\mu_1^{(1)}, ..., \mu_k^{(1)}&amp;lt;/math&amp;gt;, которая может быть реализована двумя возможными способами &amp;lt;ref&amp;gt;Hamerly, G.; Elkan, C. (2002). &amp;quot;Alternatives to the k-means algorithm that find better clusterings&amp;quot; (PDF). Proceedings of the eleventh international conference on Information and knowledge management (CIKM).&amp;lt;/ref&amp;gt;: &lt;br /&gt;
* случайный выбор центров масс среди исходных наблюдений &amp;lt;math&amp;gt;x_1, x_2, ..., x_n&amp;lt;/math&amp;gt;;&lt;br /&gt;
* все наблюдения случайным образом распределяются по кластерам &amp;lt;math&amp;gt;S_1, S_2, ..., S_k&amp;lt;/math&amp;gt;, а затем для каждого кластера выполняется операция обновления центра масс.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Распределение векторов по кластерам&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
На шаге распределения векторов по кластерам производится операция нахождения квадратов расстояний между векторами кластера и центром масс кластера: &lt;br /&gt;
::&amp;lt;math&amp;gt;\rho = \big \| x_p - \mu^{(t)}_i \big \|^2&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Обновление центров масс кластеров&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
На шаге обновления центров масс производится операция суммирования векторов кластера:&lt;br /&gt;
::&amp;lt;math&amp;gt;\mu^{(t+1)}_i = \frac{1}{|S^{(t)}_i|} \sum_{x_j \in S^{(t)}_i} x_j &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Схема реализации последовательного алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Последовательность исполнения метода следующая:&lt;br /&gt;
# Инициализируются центры масс &amp;lt;math&amp;gt;\mu_1^{(1)}, ..., \mu_k^{(1)}&amp;lt;/math&amp;gt;&lt;br /&gt;
# &amp;lt;math&amp;gt;t := 1&amp;lt;/math&amp;gt;&lt;br /&gt;
# Для каждого вектора &amp;lt;math&amp;gt;x_i, i = 1, 2, ..., n&amp;lt;/math&amp;gt; вычисляется &amp;lt;br/&amp;gt;&amp;lt;math&amp;gt;m = \underset{j \in \{1, 2, ..., k\}} {\operatorname{arg\,min}} \big \| x_i - \mu^{(t)}_j \big \|^2&amp;lt;/math&amp;gt;, &amp;lt;br/&amp;gt;вектор &amp;lt;math&amp;gt;x_i&amp;lt;/math&amp;gt; распределяется в кластер &amp;lt;math&amp;gt;S^{(t)}_m&amp;lt;/math&amp;gt;&lt;br /&gt;
# Для каждого &amp;lt;math&amp;gt;j = 1, 2, ..., k&amp;lt;/math&amp;gt; вычисляется &amp;lt;br/&amp;gt;&amp;lt;math&amp;gt;\mu^{(t+1)}_j = \frac{1}{|S^{(t)}_i|} \sum_{x_j \in S^{(t)}_i} x_j &amp;lt;/math&amp;gt;&lt;br /&gt;
#  Если &amp;lt;math&amp;gt;\mu^{(t)}_j = \mu^{(t+1)}_j, j = 1, 2, ..., k&amp;lt;/math&amp;gt;, завершить выполнение алгоритма, иначе &amp;lt;math&amp;gt;t := t + 1&amp;lt;/math&amp;gt;, переход на шаг 3.&lt;br /&gt;
&lt;br /&gt;
=== Последовательная сложность алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Для вычисления центра массы кластера, содержащего &amp;lt;math&amp;gt;n_i&amp;lt;/math&amp;gt; d-мерных векторов, необходимо:&lt;br /&gt;
* &amp;lt;math&amp;gt;n_i \cdot (d - 1)&amp;lt;/math&amp;gt; операций сложения&lt;br /&gt;
* &amp;lt;math&amp;gt;d&amp;lt;/math&amp;gt; операций деления&lt;br /&gt;
&lt;br /&gt;
Для определения центров масс всех k кластеров требуется:&lt;br /&gt;
* &amp;lt;math&amp;gt;n \cdot (d - 1)&amp;lt;/math&amp;gt; операций сложения&lt;br /&gt;
* &amp;lt;math&amp;gt;k \cdot d&amp;lt;/math&amp;gt; операций деления&lt;br /&gt;
&lt;br /&gt;
Для определения расстояния между двумя d-мерными векторами, требуется:&lt;br /&gt;
* &amp;lt;math&amp;gt;d&amp;lt;/math&amp;gt; операций вычитания&lt;br /&gt;
* &amp;lt;math&amp;gt;d&amp;lt;/math&amp;gt; операций умножения&lt;br /&gt;
* &amp;lt;math&amp;gt;d - 1&amp;lt;/math&amp;gt; операций сложения&lt;br /&gt;
&lt;br /&gt;
Для определения кластера для n d-мерного векторов, необходимо:&lt;br /&gt;
* &amp;lt;math&amp;gt;n \cdot k \cdot d&amp;lt;/math&amp;gt; операций вычитания&lt;br /&gt;
* &amp;lt;math&amp;gt;n \cdot k \cdot d&amp;lt;/math&amp;gt; операций умножения&lt;br /&gt;
* &amp;lt;math&amp;gt;n \cdot k \cdot (d - 1)&amp;lt;/math&amp;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; операций умножения/деления&lt;br /&gt;
&lt;br /&gt;
Сложность всего алгоритма, состоящего из &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt; итераций: &amp;lt;math&amp;gt;O(t  n  k  d)&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Информационный граф ===&lt;br /&gt;
&lt;br /&gt;
В данном разделе описывается информационный граф алгоритма k-средних при &amp;lt;math&amp;gt;n = 3, k = 2&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
На рисунке 1 показана общая структура алгоритма: в качестве входных данных выступает матрица, строками которой являются входные векторы &amp;lt;math&amp;gt;x_1, x_2, x_3&amp;lt;/math&amp;gt;, на выходе получается массив из &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; чисел, где элемент с номером &amp;lt;math&amp;gt;i = 1, 2, 3&amp;lt;/math&amp;gt; обозначает номер кластера, которому принадлежит вектор &amp;lt;math&amp;gt;x_i&amp;lt;/math&amp;gt;. На шаге &amp;lt;math&amp;gt;init&amp;lt;/math&amp;gt; происходит инициализация значений центров масс кластеров, после этого осуществляется итеративное повторение этапов распределения векторов по кластерам (&amp;lt;math&amp;gt;as&amp;lt;/math&amp;gt;) и обновления значений центров масс кластеров (&amp;lt;math&amp;gt;up&amp;lt;/math&amp;gt;). Когда на очередном шаге обновления центров масс кластеров значения центров масс не изменяются, алгоритм завершает работу, и в качестве выходных данных выступают номера кластеров для каждого из входных векторов.&lt;br /&gt;
[[file:k_means_main.png|thumb|center|400px|Рисунок 1. Общая схема работы алгоритма k-средних]]&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Распределение векторов по кластерам.&#039;&#039;&#039; На рисунке 2 изображен информационный граф для этапа распределения векторов по кластерам. В качестве входных данных выступают строки входной матрицы (входные векторы) &amp;lt;math&amp;gt;x_1, x_2, x_3&amp;lt;/math&amp;gt; и текущие значения центров масс кластеров &amp;lt;math&amp;gt;\mu_1, \mu_2&amp;lt;/math&amp;gt; (вычисленные на этапе инициализации или предшествующего этапа обновления центров масс кластеров). В качестве выходных данных выступают числа &amp;lt;math&amp;gt;m_1, m_2, m_3&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;m_i, i = 1, 2, 3&amp;lt;/math&amp;gt; - номер кластера, содержащего вектор &amp;lt;math&amp;gt;x_i&amp;lt;/math&amp;gt;. Вершинами с пометкой &amp;lt;math&amp;gt;sub&amp;lt;/math&amp;gt; обозначены операции векторной разности, вершинами &amp;lt;math&amp;gt;sn&amp;lt;/math&amp;gt; - операция вычисления квадрата нормы вектора, вершинами &amp;lt;math&amp;gt;am&amp;lt;/math&amp;gt; - операция &amp;lt;math&amp;gt;\underset{i \in \{1, 2\}} {\operatorname{arg\,min}}  p_i&amp;lt;/math&amp;gt;.&lt;br /&gt;
[[file:k_means_info_graph_as.png|thumb|center|400px|Рисунок 2. Граф алгоритма для этапа распределения векторов по кластерам]]&lt;br /&gt;
&#039;&#039;&#039;Обновление центров масс кластеров.&#039;&#039;&#039; На рисунке 3 представлен информационный граф для этапа обновления центров масс кластеров. В качестве входных данных выступают строки входной матрицы (входные векторы) &amp;lt;math&amp;gt;x_1, x_2, x_3&amp;lt;/math&amp;gt; с соответствующими номерами кластеров &amp;lt;math&amp;gt;m_1, m_2, m_3&amp;lt;/math&amp;gt;, содержащих эти векторы. В качестве выходных данных здесь выступают обновленные значения центров масс кластеров: &amp;lt;math&amp;gt;\mu_1, \mu_2&amp;lt;/math&amp;gt;. Вершинами с пометками &amp;lt;math&amp;gt;s_i, i = 1, 2&amp;lt;/math&amp;gt; обозначены операции суммирования векторов, принадлежащих кластеру &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt;. Вершинами с пометками &amp;lt;math&amp;gt;cs_i, i = 1, 2&amp;lt;/math&amp;gt; обозначены операции вычисления выражения &amp;lt;math&amp;gt;1 / |S_i|&amp;lt;/math&amp;gt;, где за &amp;lt;math&amp;gt;S_i&amp;lt;/math&amp;gt; обозначен кластер с номером &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt;. Вершинами с пометкой &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt; обозначена операция произведения.&lt;br /&gt;
[[file:k_means_info_graph_up.png|thumb|center|400px|Рисунок 3. Граф алгоритма для этапа обновления центров масс кластеров]]&lt;br /&gt;
&lt;br /&gt;
=== Ресурс параллелизма алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Алгоритм кластеризации k средних имеет место массовый параллелизм: в основе каждого из основных этапов алгоритма (распределения векторов по кластерам и обновления центров масс кластеров) лежат циклы, итерации которых являются информационно независимыми.&lt;br /&gt;
Учитывая данный факт можно оценить параллельную сложность алгоритма в предположении доступности неограниченного числа необходимых процессоров.&lt;br /&gt;
&lt;br /&gt;
В силу особенностей алгоритма k средних порядок выполнения основных этапов существенен, что не позволяет выполнять их параллельно. Таким образом, итоговая сложность параллельного алгоритма будет определяться, исходя из формулы &amp;lt;math&amp;gt;T = t \cdot (T_{as} + T_{up})&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;T_{as}&amp;lt;/math&amp;gt; - параллельная сложность этапа распределения векторов по кластерам, &amp;lt;math&amp;gt;T_{up}&amp;lt;/math&amp;gt; - параллельная сложность этапа обновления центров масс кластеров, &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt; - общее число итераций алгоритма.&lt;br /&gt;
&lt;br /&gt;
Параллельная сложность этапа распределения векторов по кластерам с учетом доступности неограниченного числа процессоров вычисляется следующим образом: так как вычисление значений &amp;lt;math&amp;gt;\big \| x_i - \mu^{(t)}_j \big \|^2&amp;lt;/math&amp;gt; для каждой пары векторов &amp;lt;math&amp;gt;x_i, i = 1, 2, ..., n&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\mu^{(t)}_j, j = 1, 2, ..., k&amp;lt;/math&amp;gt; можно выполнять независимо и для вычисления этого выражения требуется &amp;lt;math&amp;gt;O(\log d)&amp;lt;/math&amp;gt; операций в соответствии с [[Нахождение_частных_сумм_элементов_массива_сдваиванием | параллельной реализацией нахождения сумм элементов массива сдваиванием]]. Параллельная сложность реализации операции нахождения минимума из &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; элементов определяется как &amp;lt;math&amp;gt;O(\log k)&amp;lt;/math&amp;gt;. Таким образом, сложность этапа распределения векторов по кластерам &amp;lt;math&amp;gt;O(\log kd)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Параллельная сложность этапа обновления центров масс кластеров вычисляется следующим образом: так как обновление значений каждого из центров масс кластеров можно выполнять независимо, параллельная сложность определяется сложностью обновления центра масс самого большого кластера. В худшем случае для нахождения значения выражения &amp;lt;math&amp;gt;\mu^{(t+1)}_j = \frac{1}{|S^{(t)}_i|} \sum_{x_j \in S^{(t)}_i} x_j &amp;lt;/math&amp;gt; требуется &amp;lt;math&amp;gt;O(\log n)&amp;lt;/math&amp;gt; операций.&lt;br /&gt;
&lt;br /&gt;
С учетом вышесказанного, итоговая параллельная сложность алгоритма k средних определяется выражением &amp;lt;math&amp;gt;O(t \cdot \log nkd)&amp;lt;/math&amp;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;k&amp;lt;/math&amp;gt; - количество кластеров;&lt;br /&gt;
* матрица координат векторов &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; размерностью &amp;lt;math&amp;gt;n * d&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Объем входных данных&#039;&#039;&#039;:&lt;br /&gt;
* &amp;lt;math&amp;gt;n * d&amp;lt;/math&amp;gt; вещественных чисел (если координаты вещественные числа), &amp;lt;math&amp;gt;1&amp;lt;/math&amp;gt; целое неотрицательное число.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Выходные данные&#039;&#039;&#039;:&lt;br /&gt;
* вектор длины &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; - для каждого вектора указан номер кластера.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Объем выходных данных&#039;&#039;&#039;: &lt;br /&gt;
* &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; целых неотрицательных чисел.&lt;br /&gt;
&lt;br /&gt;
=== Свойства алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Соотношение последовательной и параллельной сложности алгоритма равно &amp;lt;math&amp;gt;\frac{O(tnkd)}{O(t \cdot \log nkd)}&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Число операций алгоритма k средних оценивается как &amp;lt;math&amp;gt;O(tnkd)&amp;lt;/math&amp;gt;, суммарный объем входных и выходных данных равен &amp;lt;math&amp;gt;n(d+1)&amp;lt;/math&amp;gt;. Следовательно, вычислительная мощность алгоритма линейна по &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; и линейна по &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Стоит отметить следующие ключевые особенности алгоритма k средних:&lt;br /&gt;
* Алгоритм прост в реализации и имеет высокую скорость работы по сравнению с другими алгоритмами кластеризации (при удачном выборе начальных значений центров масс кластеров)&lt;br /&gt;
* В качестве метрики используется евклидово расстояние, а в качестве меры разброса кластера используется дисперсия&lt;br /&gt;
* Количество кластеров k является входным параметром алгоритма, поэтому неправильный выбор этого параметра может негативно повлиять на качество кластеризации&lt;br /&gt;
* Сходимость алгоритма к локальному минимуму может породить некорректный конечный результат работы&lt;br /&gt;
* Алгоритм очень чувствителен к выбору начальных центров масс кластеров: классический вариант подразумевает случайный их выбор, что может являться источником погрешности. Из этого и предыдущего свойства следует то, что алгоритм не является устойчивым.&lt;br /&gt;
&lt;br /&gt;
Как и любой другой алгоритм кластеризации, результат работы алгоритма k средних зависит от того, удовлетворяет ли входной набор данных предположениям, на которые опираются алгоритмы кластеризации. Таким образом, на одних наборах данных алгоритм может показывать хорошие результаты, но на других выдавать некорректные результаты.&lt;br /&gt;
&lt;br /&gt;
Алгоритм не является детерминированным, в силу того, что он чувствителен к выбору начальных центров масс кластеров, который осуществляется, как правило, случайным образом и тем самым вносит различия в работу алгоритма от запуска к запуску.&lt;br /&gt;
&lt;br /&gt;
== Программная реализация алгоритма ==&lt;br /&gt;
&lt;br /&gt;
=== Особенности реализации последовательного алгоритма ===&lt;br /&gt;
&lt;br /&gt;
=== Локальность данных и вычислений ===&lt;br /&gt;
&lt;br /&gt;
=== Возможные способы и особенности параллельной реализации алгоритма ===&lt;br /&gt;
&lt;br /&gt;
=== Масштабируемость алгоритма и его реализации ===&lt;br /&gt;
Исследование масштабируемости алгоритма k-means в зависимости от количества используемых процессов было проведено в статье Кумара&amp;lt;ref&amp;gt;Kumar, J., Mills, R. T., Hoffman, F. M., &amp;amp; Hargrove, W. W. (2011). Parallel k-means clustering for quantitative ecoregion delineation using large data sets. Procedia Computer Science, 4, 1602-1611.&amp;lt;/ref&amp;gt;. Исследование происходило на суперкомпьютере Jaguar - Cray XT5&amp;lt;ref&amp;gt;https://www.top500.org/system/176029&amp;lt;/ref&amp;gt;. На момент экспериментов данный суперкомпьютер имел следующую конфигурацию: 18,688 вычислительных узлов с двумя шестнадцатиядерными процессорами AMD Opteron 2435 (Istanbul) 2.6 GHz, 16 GB of DDR2-800 оперативной памяти, и SeaStar 2+ роутер. Всего он состоял из 224,256 вычислительных ядер, 300 TB памяти, и пиковой производительностью 2.3 petaflops.&lt;br /&gt;
&lt;br /&gt;
Реализация алгоритма была выполнена на языке программирования C с использованием MPI.&lt;br /&gt;
&lt;br /&gt;
Объем данных составлял 84 гигабайта, количество объектов (d-мерных векторов) n равнялось 1,024,767,667, размерность векторов d равнялась 22, количество кластеров k равнялось 1000. &lt;br /&gt;
&lt;br /&gt;
На рисунке 4 показана зависимости времени работы алгоритма кластеризации k-means в зависимости от количества используемых процессоров. Можно отметить, что время, затраченное на чтение данных и запись результатов кластеризации, практически не изменяется с увеличением количества задействованных процессоров. Время же работы самого алгоритма кластеризации уменьшается с увеличением количества процессоров.&lt;br /&gt;
[[Файл:k-means-proc-scalability.png|thumb|center|700px|Рисунок 4. Зависимости времени работы алгоритма кластеризации k-means в зависимости от количества используемых процессоров.]]&lt;br /&gt;
&lt;br /&gt;
Также было произведено самостоятельное исследование масштабируемости алгоритма. Исследование производилось на суперкомпьютере &amp;quot;Blue Gene/P&amp;quot;&amp;lt;ref&amp;gt;http://hpc.cmc.msu.ru/bgp&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Набор и границы значений изменяемых параметров запуска реализации алгоритма:&lt;br /&gt;
&lt;br /&gt;
* число процессоров [1, 2, 4, 8, 16, 32, 64, 128, 256, 512];&lt;br /&gt;
* количество объектов [5000, 10000, 25000, 50000].&lt;br /&gt;
&lt;br /&gt;
Был использован набор данных &#039;&#039;Dataset for Sensorless Drive Diagnosis Data Set&#039;&#039;&amp;lt;ref&amp;gt;PASCHKE, Fabian ; BAYER, Christian ; BATOR, Martyna ; MÃ–NKS, Uwe ; DICKS, Alexander ; ENGE-ROSENBLATT, Olaf ; LOHWEG, Volker: Sensorlose ZustandsÃ¼berwachung an Synchronmotoren, Bd. 46. In: HOFFMANN, Frank; HÃœLLERMEIER, Eyke (Hrsg.): Proceedings 23. Workshop Computational Intelligence. Karlsruhe : KIT Scientific Publishing, 2013 (Schriftenreihe des Instituts fÃ¼r Angewandte Informatik - Automatisierungstechnik am Karlsruher Institut fÃ¼r Technologie, 46), S. 211-225&amp;lt;/ref&amp;gt; из репозитория &#039;&#039;Machine learning repository&#039;&#039;&amp;lt;ref&amp;gt;https://archive.ics.uci.edu/ml/datasets/Dataset+for+Sensorless+Drive+Diagnosis&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Исследуемый набор данных содержит векторы, размерность которых равна 49. Компоненты векторов являются вещественными числами. Количество кластеров равно 11. Пропущенные значения отсутствуют.&lt;br /&gt;
&lt;br /&gt;
Для исследования масштабируемости алгоритма была использована реализация на языке C с использованием MPI&amp;lt;ref&amp;gt;http://users.eecs.northwestern.edu/~wkliao/Kmeans/index.html&amp;lt;/ref&amp;gt;. Код можно найти здесь: https://github.com/serban/kmeans. Данная реализация предоставляет возможность распараллеливать решение задачи с помощью технологий MPI, OpenMP И CUDA. Для запуска MPI-версии программы использовалась цель &amp;quot;mpi_main&amp;quot; Makefile.&lt;br /&gt;
&lt;br /&gt;
На рисунке 5 показана зависимости времени работы алгоритма кластеризации k-means в зависимости от количества используемых процессоров (использовались логарифмические оси). Разными цветами помечены запуски, соответствующие разным количествам объектам, участвующих в кластеризации. Можно видеть близкое к линейному увеличение времени работы программы в зависимости от количества процессоров. Также можно видеть увеличение времени работы алгоритма при увеличении количества объектов.&lt;br /&gt;
[[Файл:Plot_1.png|thumb|center|900px|Рисунок 5. Зависимости времени работы алгоритма кластеризации k-means в зависимости от количества используемых процессоров.]]&lt;br /&gt;
&lt;br /&gt;
На рисунке 6 показана эта же зависимость, только в трехмерном пространстве. Аналогично с рисунком 5, были использованы логарифмические оси. Как и в случае двумерного рисунка, можно видеть близкое к линейному увеличение времени работы программы.&lt;br /&gt;
[[Файл:Kmeans-3d.png|thumb|center|900px|Рисунок 6. Зависимости времени работы алгоритма кластеризации k-means в зависимости от количества используемых процессоров.]]&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-средних:&lt;br /&gt;
* [http://scikit-learn.org/ scikit-learn] библиотека машинного обучения для языка Python.&lt;br /&gt;
* [https://www.scipy.org/ SciPy] библиотека на языке Python, содержащая большое число реализаций различных алгоритмов, в том числе &#039;&#039;k&#039;&#039;-средних.&lt;br /&gt;
* [http://elki.dbs.ifi.lmu.de ELKI] библиотека для анализа данных на языке программирования Java, содержит различные алгоритмы кластеризации, в том числе &#039;&#039;k&#039;&#039;-средних.&lt;br /&gt;
* [http://mlpack.org MLPACK] библиотека машинного обучения для C++, содержит реализацию алгоритма &#039;&#039;k&#039;&#039;-средних.&lt;br /&gt;
* [https://github.com/JuliaStats/Clustering.jl Julia k-means] реализация алгоритма &#039;&#039;k&#039;&#039;-средних на языке программирования Julia.&lt;br /&gt;
* [http://opencv.org/ OpenCV] библиотека содержит реализацию &#039;&#039;k&#039;&#039;-средних.&lt;br /&gt;
* [http://mahout.apache.org Apache Mahout] содержит реализацию алгоритма &#039;&#039;k&#039;&#039;-средних на базе MapReduce.&lt;br /&gt;
* [http://www.cs.waikato.ac.nz/~ml/weka Weka] библиотека и инструмент для анализа данных на языке Java.&lt;br /&gt;
* [http://torch.ch/ Torch] библиотека машинного обучения на базе языка программирования Lua.&lt;br /&gt;
* [https://spark.apache.org/ Apache Spark MLlib] содержит распределенную реализацию алгоритма &#039;&#039;k&#039;&#039;-средних.&lt;br /&gt;
* [http://www.accord-framework.net/ Accord.NET] содержит несколько различных реализаций &#039;&#039;k&#039;&#039;-средних на языке C#.&lt;br /&gt;
* [https://www.r-bloggers.com/k-means-clustering-in-r/ R k-means] реализация &#039;&#039;k&#039;&#039;-средних на языке R.&lt;br /&gt;
&lt;br /&gt;
== Литература ==&lt;br /&gt;
&amp;lt;references \&amp;gt;&lt;/div&gt;</summary>
		<author><name>Parkhomenko</name></author>
	</entry>
	<entry>
		<id>https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A4%D0%B0%D0%B9%D0%BB:Kmeans-3d.png&amp;diff=20980</id>
		<title>Файл:Kmeans-3d.png</title>
		<link rel="alternate" type="text/html" href="https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A4%D0%B0%D0%B9%D0%BB:Kmeans-3d.png&amp;diff=20980"/>
		<updated>2016-12-15T11:18:47Z</updated>

		<summary type="html">&lt;p&gt;Parkhomenko: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Parkhomenko</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:Parkhomenko/%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=20502</id>
		<title>Участник:Parkhomenko/Алгоритм 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:Parkhomenko/%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=20502"/>
		<updated>2016-12-09T21:37:13Z</updated>

		<summary type="html">&lt;p&gt;Parkhomenko: /* Масштабируемость алгоритма и его реализации */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt; {{Assignment|Zhum}}&lt;br /&gt;
{{algorithm&lt;br /&gt;
| name              = Алгоритм k средних&lt;br /&gt;
| serial_complexity = &amp;lt;math&amp;gt;O(tnkd)&amp;lt;/math&amp;gt;&lt;br /&gt;
| input_data        = &amp;lt;math&amp;gt;nd&amp;lt;/math&amp;gt;&lt;br /&gt;
| output_data       = &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;&lt;br /&gt;
| pf_height         = &amp;lt;math&amp;gt;O(t \cdot \log nkd)&amp;lt;/math&amp;gt;&lt;br /&gt;
| pf_width          = &amp;lt;math&amp;gt;O(nkd)&amp;lt;/math&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
Основные авторы описания: [[Участник:Parkhomenko|П.А.Пархоменко]] ([[#Общее описание алгоритма|1.1]], [[#Вычислительное ядро алгоритма|1.3]], [[#Последовательная сложность алгоритма|1.6]], [[#Ресурс параллелизма алгоритма|1.8]], [[#Входные и выходные данные алгоритма|1.9]], [[#Свойства алгоритма|1.10]], [[#Масштабируемость алгоритма и его реализации|2.4]]), [[Участник:Ivan.mashonskiy|И.Д.Машонский]] ([[#Математическое описание алгоритма|1.2]], [[#Макроструктура алгоритма|1.4]], [[#Схема реализации последовательного алгоритма|1.5]], [[#Информационный граф|1.7]], [[#Ресурс параллелизма алгоритма|1.8]], [[#Свойства алгоритма|1.10]], [[#Существующие реализации алгоритма|2.7]])&lt;br /&gt;
== Свойства и структура алгоритмов ==&lt;br /&gt;
&lt;br /&gt;
=== Общее описание алгоритма ===&lt;br /&gt;
Алгоритм k средних (англ. k-means) - один из алгоритмов машинного обучения, решающий задачу кластеризации. Он был изобретен в середине 1950-х математиком Гуго Штейнгаузом&amp;lt;ref&amp;gt;Steinhaus H. (1956). Sur la division des corps materiels en parties. Bull. Acad. Polon. Sci., C1. III vol IV: 801—804.&amp;lt;/ref&amp;gt; и Стюартом Ллойдом&amp;lt;ref&amp;gt;Lloyd S. (1957). Least square quantization in PCM’s. Bell Telephone Laboratories Paper.&amp;lt;/ref&amp;gt;. Алгоритм стал особо популярным после публикации Маккуина&amp;lt;ref&amp;gt;MacQueen J. (1967). Some methods for classification and analysis of multivariate observations. In Proc. 5th Berkeley Symp. on Math. Statistics and Probability, pages 281—297.&amp;lt;/ref&amp;gt;, в которой впервые был использован термин “k-means”.&lt;br /&gt;
&lt;br /&gt;
Задача алгоритма кластеризации заключается в разбиении N объектов (d-мерных векторов) на K групп (кластеров). Каждый вектор может принадлежать только одному кластеру. Количество кластеров K фиксировано, оно задается в качестве параметра.&lt;br /&gt;
&lt;br /&gt;
K-means является итерационным алгоритмом, разновидностью EM-алгоритма. Основная идея работы алгоритма заключается в проведении некоторого количества итераций, на каждой из которых происходит пересчет центра масс для каждого кластера, полученного на предыдущей итерации. После этого векторы перераспределяются по кластерам: вектор относится к тому кластеру, расстояние до центра масс которого минимально. Алгоритм завершает работу в том случае, если на очередной итерации центры масс кластеров не изменились.&lt;br /&gt;
&lt;br /&gt;
=== Математическое описание алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Исходные данные: множество d-мерных векторов (наблюдений) &amp;lt;math&amp;gt;X&amp;lt;/math&amp;gt;&amp;amp;nbsp;=&amp;amp;nbsp;&amp;lt;math&amp;gt;\{x_1, x_2, ..., x_n\}&amp;lt;/math&amp;gt;, число кластеров &amp;lt;math&amp;gt;k \in \mathbb{N}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
В результате работы алгоритма исходное множество векторов &amp;lt;math&amp;gt;X&amp;lt;/math&amp;gt; разбивается на &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; непересекающихся множеств (кластеров) &amp;lt;math&amp;gt;S_1, S_2, ..., S_k&amp;lt;/math&amp;gt;, таких что &amp;lt;math&amp;gt;X = {\bigcup \limits _{i = 1}^k S_i} &amp;lt;/math&amp;gt; и значение &amp;lt;math&amp;gt;\sum_{i=1}^{k} \sum_{\mathbf x \in S_i} \left\| \mathbf x - \mu_i \right\|^2 &amp;lt;/math&amp;gt; — минимально для всех возможных наборов &amp;lt;math&amp;gt;S_1, S_2, ..., S_k&amp;lt;/math&amp;gt;.&lt;br /&gt;
Под &amp;lt;math&amp;gt;\mu_i&amp;lt;/math&amp;gt; здесь подразумевается центр масс векторов из множества &amp;lt;math&amp;gt;S_i&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Первоначальные значения центров масс &amp;lt;math&amp;gt;\mu_1^{(1)}, ..., \mu_k^{(1)}&amp;lt;/math&amp;gt; определяются в начале работы алгоритма случайным образом среди векторов множества &amp;lt;math&amp;gt;X&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Алгоритм заключается в попеременном применении двух шагов &amp;lt;ref&amp;gt;MacKay, David (2003). &amp;quot;Chapter 20. An Example Inference Task: Clustering&amp;quot; (PDF). Information Theory, Inference and Learning Algorithms. Cambridge University Press. pp. 284–292.&amp;lt;/ref&amp;gt;: &#039;&#039;&#039;распределения&#039;&#039;&#039; векторов по кластерам и &#039;&#039;&#039;обновления&#039;&#039;&#039; центров масс каждого кластера&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Распределение векторов по кластерам&#039;&#039;&#039;: на данном шаге каждый вектор распределяется в один из кластеров &amp;lt;math&amp;gt;S_i^{(t)}&amp;lt;/math&amp;gt;: &lt;br /&gt;
::&amp;lt;math&amp;gt;S_i^{(t)} = \big \{ x_p : \big \| x_p - \mu^{(t)}_i \big \|^2 \le \big \| x_p - \mu^{(t)}_j \big \|^2 \ \forall j, 1 \le j \le k \big\},&amp;lt;/math&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Обновление центров масс&#039;&#039;&#039;: на данном шаге вычисляются новые центры масс для кластеров, полученных на предыдущем шаге.&lt;br /&gt;
::&amp;lt;math&amp;gt;\mu^{(t+1)}_i = \frac{1}{|S^{(t)}_i|} \sum_{x_j \in S^{(t)}_i} x_j &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Алгоритм завершается, когда на очередном шаге не происходит изменения центров масс кластеров.&lt;br /&gt;
&lt;br /&gt;
=== Вычислительное ядро алгоритма ===&lt;br /&gt;
Вычислительное ядро последовательного алгоритма k-means состоит из двух операций, повторяющихся на каждой итерации алгоритма:&lt;br /&gt;
* пересчета центров масс кластеров;&lt;br /&gt;
* соотнесения каждого вектора к одному из кластеров.&lt;br /&gt;
&lt;br /&gt;
Пересчет центра масс кластера заключается в нахождении d-мерного вектора, являющегося средним арифметическим d-мерных векторов, принадлежащих кластеру. Эту операцию необходимо выполнять для каждого из K кластеров.&lt;br /&gt;
&lt;br /&gt;
Для соотнесения вектора к одному из кластеров, необходимо для каждого из N вектора посчитать расстояние до центров масс всех K кластеров. Для нахождения расстояния между двумя d-мерными векторами p и q используется Евклидова метрика: &amp;lt;math&amp;gt;\sqrt{\sum_{k=1}^d (p_k-q_k)^2}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Макроструктура алгоритма ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Инициализация центров масс кластеров&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
В начале алгоритма осуществляется инициализация центров масс &amp;lt;math&amp;gt;\mu_1^{(1)}, ..., \mu_k^{(1)}&amp;lt;/math&amp;gt;, которая может быть реализована двумя возможными способами &amp;lt;ref&amp;gt;Hamerly, G.; Elkan, C. (2002). &amp;quot;Alternatives to the k-means algorithm that find better clusterings&amp;quot; (PDF). Proceedings of the eleventh international conference on Information and knowledge management (CIKM).&amp;lt;/ref&amp;gt;: &lt;br /&gt;
* случайный выбор центров масс среди исходных наблюдений &amp;lt;math&amp;gt;x_1, x_2, ..., x_n&amp;lt;/math&amp;gt;;&lt;br /&gt;
* все наблюдения случайным образом распределяются по кластерам &amp;lt;math&amp;gt;S_1, S_2, ..., S_k&amp;lt;/math&amp;gt;, а затем для каждого кластера выполняется операция обновления центра масс.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Распределение векторов по кластерам&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
На шаге распределения векторов по кластерам производится операция нахождения квадратов расстояний между векторами кластера и центром масс кластера: &lt;br /&gt;
::&amp;lt;math&amp;gt;\rho = \big \| x_p - \mu^{(t)}_i \big \|^2&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Обновление центров масс кластеров&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
На шаге обновления центров масс производится операция суммирования векторов кластера:&lt;br /&gt;
::&amp;lt;math&amp;gt;\mu^{(t+1)}_i = \frac{1}{|S^{(t)}_i|} \sum_{x_j \in S^{(t)}_i} x_j &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Схема реализации последовательного алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Последовательность исполнения метода следующая:&lt;br /&gt;
# Инициализируются центры масс &amp;lt;math&amp;gt;\mu_1^{(1)}, ..., \mu_k^{(1)}&amp;lt;/math&amp;gt;&lt;br /&gt;
# &amp;lt;math&amp;gt;t := 1&amp;lt;/math&amp;gt;&lt;br /&gt;
# Для каждого вектора &amp;lt;math&amp;gt;x_i, i = 1, 2, ..., n&amp;lt;/math&amp;gt; вычисляется &amp;lt;br/&amp;gt;&amp;lt;math&amp;gt;m = \underset{j \in \{1, 2, ..., k\}} {\operatorname{arg\,min}} \big \| x_i - \mu^{(t)}_j \big \|^2&amp;lt;/math&amp;gt;, &amp;lt;br/&amp;gt;вектор &amp;lt;math&amp;gt;x_i&amp;lt;/math&amp;gt; распределяется в кластер &amp;lt;math&amp;gt;S^{(t)}_m&amp;lt;/math&amp;gt;&lt;br /&gt;
# Для каждого &amp;lt;math&amp;gt;j = 1, 2, ..., k&amp;lt;/math&amp;gt; вычисляется &amp;lt;br/&amp;gt;&amp;lt;math&amp;gt;\mu^{(t+1)}_j = \frac{1}{|S^{(t)}_i|} \sum_{x_j \in S^{(t)}_i} x_j &amp;lt;/math&amp;gt;&lt;br /&gt;
#  Если &amp;lt;math&amp;gt;\mu^{(t)}_j = \mu^{(t+1)}_j, j = 1, 2, ..., k&amp;lt;/math&amp;gt;, завершить выполнение алгоритма, иначе &amp;lt;math&amp;gt;t := t + 1&amp;lt;/math&amp;gt;, переход на шаг 3.&lt;br /&gt;
&lt;br /&gt;
=== Последовательная сложность алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Для вычисления центра массы кластера, содержащего &amp;lt;math&amp;gt;n_i&amp;lt;/math&amp;gt; d-мерных векторов, необходимо:&lt;br /&gt;
* &amp;lt;math&amp;gt;n_i \cdot (d - 1)&amp;lt;/math&amp;gt; операций сложения&lt;br /&gt;
* &amp;lt;math&amp;gt;d&amp;lt;/math&amp;gt; операций деления&lt;br /&gt;
&lt;br /&gt;
Для определения центров масс всех k кластеров требуется:&lt;br /&gt;
* &amp;lt;math&amp;gt;n \cdot (d - 1)&amp;lt;/math&amp;gt; операций сложения&lt;br /&gt;
* &amp;lt;math&amp;gt;k \cdot d&amp;lt;/math&amp;gt; операций деления&lt;br /&gt;
&lt;br /&gt;
Для определения расстояния между двумя d-мерными векторами, требуется:&lt;br /&gt;
* &amp;lt;math&amp;gt;d&amp;lt;/math&amp;gt; операций вычитания&lt;br /&gt;
* &amp;lt;math&amp;gt;d&amp;lt;/math&amp;gt; операций умножения&lt;br /&gt;
* &amp;lt;math&amp;gt;d - 1&amp;lt;/math&amp;gt; операций сложения&lt;br /&gt;
&lt;br /&gt;
Для определения кластера для n d-мерного векторов, необходимо:&lt;br /&gt;
* &amp;lt;math&amp;gt;n \cdot k \cdot d&amp;lt;/math&amp;gt; операций вычитания&lt;br /&gt;
* &amp;lt;math&amp;gt;n \cdot k \cdot d&amp;lt;/math&amp;gt; операций умножения&lt;br /&gt;
* &amp;lt;math&amp;gt;n \cdot k \cdot (d - 1)&amp;lt;/math&amp;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; операций умножения/деления&lt;br /&gt;
&lt;br /&gt;
Сложность всего алгоритма, состоящего из &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt; итераций: &amp;lt;math&amp;gt;O(t  n  k  d)&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Информационный граф ===&lt;br /&gt;
&lt;br /&gt;
В данном разделе описывается информационный граф алгоритма k-средних при &amp;lt;math&amp;gt;n = 3, k = 2&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
На рисунке 1 показана общая структура алгоритма: в качестве входных данных выступает матрица, строками которой являются входные векторы &amp;lt;math&amp;gt;x_1, x_2, x_3&amp;lt;/math&amp;gt;, на выходе получается массив из &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; чисел, где элемент с номером &amp;lt;math&amp;gt;i = 1, 2, 3&amp;lt;/math&amp;gt; обозначает номер кластера, которому принадлежит вектор &amp;lt;math&amp;gt;x_i&amp;lt;/math&amp;gt;. На шаге &amp;lt;math&amp;gt;init&amp;lt;/math&amp;gt; происходит инициализация значений центров масс кластеров, после этого осуществляется итеративное повторение этапов распределения векторов по кластерам (&amp;lt;math&amp;gt;as&amp;lt;/math&amp;gt;) и обновления значений центров масс кластеров (&amp;lt;math&amp;gt;up&amp;lt;/math&amp;gt;). Когда на очередном шаге обновления центров масс кластеров значения центров масс не изменяются, алгоритм завершает работу, и в качестве выходных данных выступают номера кластеров для каждого из входных векторов.&lt;br /&gt;
[[file:k_means_main.png|thumb|center|400px|Рисунок 1. Общая схема работы алгоритма k-средних]]&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Распределение векторов по кластерам.&#039;&#039;&#039; На рисунке 2 изображен информационный граф для этапа распределения векторов по кластерам. В качестве входных данных выступают строки входной матрицы (входные векторы) &amp;lt;math&amp;gt;x_1, x_2, x_3&amp;lt;/math&amp;gt; и текущие значения центров масс кластеров &amp;lt;math&amp;gt;\mu_1, \mu_2&amp;lt;/math&amp;gt; (вычисленные на этапе инициализации или предшествующего этапа обновления центров масс кластеров). В качестве выходных данных выступают числа &amp;lt;math&amp;gt;m_1, m_2, m_3&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;m_i, i = 1, 2, 3&amp;lt;/math&amp;gt; - номер кластера, содержащего вектор &amp;lt;math&amp;gt;x_i&amp;lt;/math&amp;gt;. Вершинами с пометкой &amp;lt;math&amp;gt;sub&amp;lt;/math&amp;gt; обозначены операции векторной разности, вершинами &amp;lt;math&amp;gt;sn&amp;lt;/math&amp;gt; - операция вычисления квадрата нормы вектора, вершинами &amp;lt;math&amp;gt;am&amp;lt;/math&amp;gt; - операция &amp;lt;math&amp;gt;\underset{i \in \{1, 2\}} {\operatorname{arg\,min}}  p_i&amp;lt;/math&amp;gt;.&lt;br /&gt;
[[file:k_means_info_graph_as.png|thumb|center|400px|Рисунок 2. Граф алгоритма для этапа распределения векторов по кластерам]]&lt;br /&gt;
&#039;&#039;&#039;Обновление центров масс кластеров.&#039;&#039;&#039; На рисунке 3 представлен информационный граф для этапа обновления центров масс кластеров. В качестве входных данных выступают строки входной матрицы (входные векторы) &amp;lt;math&amp;gt;x_1, x_2, x_3&amp;lt;/math&amp;gt; с соответствующими номерами кластеров &amp;lt;math&amp;gt;m_1, m_2, m_3&amp;lt;/math&amp;gt;, содержащих эти векторы. В качестве выходных данных здесь выступают обновленные значения центров масс кластеров: &amp;lt;math&amp;gt;\mu_1, \mu_2&amp;lt;/math&amp;gt;. Вершинами с пометками &amp;lt;math&amp;gt;s_i, i = 1, 2&amp;lt;/math&amp;gt; обозначены операции суммирования векторов, принадлежащих кластеру &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt;. Вершинами с пометками &amp;lt;math&amp;gt;cs_i, i = 1, 2&amp;lt;/math&amp;gt; обозначены операции вычисления выражения &amp;lt;math&amp;gt;1 / |S_i|&amp;lt;/math&amp;gt;, где за &amp;lt;math&amp;gt;S_i&amp;lt;/math&amp;gt; обозначен кластер с номером &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt;. Вершинами с пометкой &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt; обозначена операция произведения.&lt;br /&gt;
[[file:k_means_info_graph_up.png|thumb|center|400px|Рисунок 3. Граф алгоритма для этапа обновления центров масс кластеров]]&lt;br /&gt;
&lt;br /&gt;
=== Ресурс параллелизма алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Алгоритм кластеризации k средних имеет место массовый параллелизм: в основе каждого из основных этапов алгоритма (распределения векторов по кластерам и обновления центров масс кластеров) лежат циклы, итерации которых являются информационно независимыми.&lt;br /&gt;
Учитывая данный факт можно оценить параллельную сложность алгоритма в предположении доступности неограниченного числа необходимых процессоров.&lt;br /&gt;
&lt;br /&gt;
В силу особенностей алгоритма k средних порядок выполнения основных этапов существенен, что не позволяет выполнять их параллельно. Таким образом, итоговая сложность параллельного алгоритма будет определяться, исходя из формулы &amp;lt;math&amp;gt;T = t \cdot (T_{as} + T_{up})&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;T_{as}&amp;lt;/math&amp;gt; - параллельная сложность этапа распределения векторов по кластерам, &amp;lt;math&amp;gt;T_{up}&amp;lt;/math&amp;gt; - параллельная сложность этапа обновления центров масс кластеров, &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt; - общее число итераций алгоритма.&lt;br /&gt;
&lt;br /&gt;
Параллельная сложность этапа распределения векторов по кластерам с учетом доступности неограниченного числа процессоров вычисляется следующим образом: так как вычисление значений &amp;lt;math&amp;gt;\big \| x_i - \mu^{(t)}_j \big \|^2&amp;lt;/math&amp;gt; для каждой пары векторов &amp;lt;math&amp;gt;x_i, i = 1, 2, ..., n&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\mu^{(t)}_j, j = 1, 2, ..., k&amp;lt;/math&amp;gt; можно выполнять независимо и для вычисления этого выражения требуется &amp;lt;math&amp;gt;O(\log d)&amp;lt;/math&amp;gt; операций в соответствии с [[Нахождение_частных_сумм_элементов_массива_сдваиванием | параллельной реализацией нахождения сумм элементов массива сдваиванием]]. Параллельная сложность реализации операции нахождения минимума из &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; элементов определяется как &amp;lt;math&amp;gt;O(\log k)&amp;lt;/math&amp;gt;. Таким образом, сложность этапа распределения векторов по кластерам &amp;lt;math&amp;gt;O(\log kd)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Параллельная сложность этапа обновления центров масс кластеров вычисляется следующим образом: так как обновление значений каждого из центров масс кластеров можно выполнять независимо, параллельная сложность определяется сложностью обновления центра масс самого большого кластера. В худшем случае для нахождения значения выражения &amp;lt;math&amp;gt;\mu^{(t+1)}_j = \frac{1}{|S^{(t)}_i|} \sum_{x_j \in S^{(t)}_i} x_j &amp;lt;/math&amp;gt; требуется &amp;lt;math&amp;gt;O(\log n)&amp;lt;/math&amp;gt; операций.&lt;br /&gt;
&lt;br /&gt;
С учетом вышесказанного, итоговая параллельная сложность алгоритма k средних определяется выражением &amp;lt;math&amp;gt;O(t \cdot \log nkd)&amp;lt;/math&amp;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;k&amp;lt;/math&amp;gt; - количество кластеров;&lt;br /&gt;
* матрица координат векторов &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; размерностью &amp;lt;math&amp;gt;n * d&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Объем входных данных&#039;&#039;&#039;:&lt;br /&gt;
* &amp;lt;math&amp;gt;n * d&amp;lt;/math&amp;gt; вещественных чисел (если координаты вещественные числа), &amp;lt;math&amp;gt;1&amp;lt;/math&amp;gt; целое неотрицательное число.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Выходные данные&#039;&#039;&#039;:&lt;br /&gt;
* вектор длины &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; - для каждого вектора указан номер кластера.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Объем выходных данных&#039;&#039;&#039;: &lt;br /&gt;
* &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; целых неотрицательных чисел.&lt;br /&gt;
&lt;br /&gt;
=== Свойства алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Соотношение последовательной и параллельной сложности алгоритма равно &amp;lt;math&amp;gt;\frac{O(tnkd)}{O(t \cdot \log nkd)}&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Число операций алгоритма k средних оценивается как &amp;lt;math&amp;gt;O(tnkd)&amp;lt;/math&amp;gt;, суммарный объем входных и выходных данных равен &amp;lt;math&amp;gt;n(d+1)&amp;lt;/math&amp;gt;. Следовательно, вычислительная мощность алгоритма линейна по &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; и линейна по &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Стоит отметить следующие ключевые особенности алгоритма k средних:&lt;br /&gt;
* Алгоритм прост в реализации и имеет высокую скорость работы по сравнению с другими алгоритмами кластеризации (при удачном выборе начальных значений центров масс кластеров)&lt;br /&gt;
* В качестве метрики используется евклидово расстояние, а в качестве меры разброса кластера используется дисперсия&lt;br /&gt;
* Количество кластеров k является входным параметром алгоритма, поэтому неправильный выбор этого параметра может негативно повлиять на качество кластеризации&lt;br /&gt;
* Сходимость алгоритма к локальному минимуму может породить некорректный конечный результат работы&lt;br /&gt;
* Алгоритм очень чувствителен к выбору начальных центров масс кластеров: классический вариант подразумевает случайный их выбор, что может являться источником погрешности. Из этого и предыдущего свойства следует то, что алгоритм не является устойчивым.&lt;br /&gt;
&lt;br /&gt;
Как и любой другой алгоритм кластеризации, результат работы алгоритма k средних зависит от того, удовлетворяет ли входной набор данных предположениям, на которые опираются алгоритмы кластеризации. Таким образом, на одних наборах данных алгоритм может показывать хорошие результаты, но на других выдавать некорректные результаты.&lt;br /&gt;
&lt;br /&gt;
Алгоритм не является детерминированным, в силу того, что он чувствителен к выбору начальных центров масс кластеров, который осуществляется, как правило, случайным образом и тем самым вносит различия в работу алгоритма от запуска к запуску.&lt;br /&gt;
&lt;br /&gt;
== Программная реализация алгоритма ==&lt;br /&gt;
&lt;br /&gt;
=== Особенности реализации последовательного алгоритма ===&lt;br /&gt;
&lt;br /&gt;
=== Локальность данных и вычислений ===&lt;br /&gt;
&lt;br /&gt;
=== Возможные способы и особенности параллельной реализации алгоритма ===&lt;br /&gt;
&lt;br /&gt;
=== Масштабируемость алгоритма и его реализации ===&lt;br /&gt;
Исследование масштабируемости алгоритма k-means в зависимости от количества используемых процессов было проведено в статье Кумара&amp;lt;ref&amp;gt;Kumar, J., Mills, R. T., Hoffman, F. M., &amp;amp; Hargrove, W. W. (2011). Parallel k-means clustering for quantitative ecoregion delineation using large data sets. Procedia Computer Science, 4, 1602-1611.&amp;lt;/ref&amp;gt;. Исследование происходило на суперкомпьютере Jaguar - Cray XT5&amp;lt;ref&amp;gt;https://www.top500.org/system/176029&amp;lt;/ref&amp;gt;. На момент экспериментов данный суперкомпьютер имел следующую конфигурацию: 18,688 вычислительных узлов с двумя шестнадцатиядерными процессорами AMD Opteron 2435 (Istanbul) 2.6 GHz, 16 GB of DDR2-800 оперативной памяти, и SeaStar 2+ роутер. Всего он состоял из 224,256 вычислительных ядер, 300 TB памяти, и пиковой производительностью 2.3 petaflops.&lt;br /&gt;
&lt;br /&gt;
Реализация алгоритма была выполнена на языке программирования C с использованием MPI.&lt;br /&gt;
&lt;br /&gt;
Объем данных составлял 84 гигабайта, количество объектов (d-мерных векторов) n равнялось 1,024,767,667, размерность векторов d равнялась 22, количество кластеров k равнялось 1000. &lt;br /&gt;
&lt;br /&gt;
На рисунке 4 показана зависимости времени работы алгоритма кластеризации k-means в зависимости от количества используемых процессоров. Можно отметить, что время, затраченное на чтение данных и запись результатов кластеризации, практически не изменяется с увеличением количества задействованных процессоров. Время же работы самого алгоритма кластеризации уменьшается с увеличением количества процессоров.&lt;br /&gt;
[[Файл:k-means-proc-scalability.png|thumb|center|700px|Рисунок 4. Зависимости времени работы алгоритма кластеризации k-means в зависимости от количества используемых процессоров.]]&lt;br /&gt;
&lt;br /&gt;
Также было произведено самостоятельное исследование масштабируемости алгоритма. Исследование производилось на суперкомпьютере &amp;quot;Blue Gene/P&amp;quot;&amp;lt;ref&amp;gt;http://hpc.cmc.msu.ru/bgp&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Набор и границы значений изменяемых параметров запуска реализации алгоритма:&lt;br /&gt;
&lt;br /&gt;
* число процессоров [1, 2, 4, 8, 16, 32, 64, 128, 256, 512];&lt;br /&gt;
* количество объектов [5000, 10000, 25000, 50000].&lt;br /&gt;
&lt;br /&gt;
Был использован набор данных &#039;&#039;Dataset for Sensorless Drive Diagnosis Data Set&#039;&#039;&amp;lt;ref&amp;gt;PASCHKE, Fabian ; BAYER, Christian ; BATOR, Martyna ; MÃ–NKS, Uwe ; DICKS, Alexander ; ENGE-ROSENBLATT, Olaf ; LOHWEG, Volker: Sensorlose ZustandsÃ¼berwachung an Synchronmotoren, Bd. 46. In: HOFFMANN, Frank; HÃœLLERMEIER, Eyke (Hrsg.): Proceedings 23. Workshop Computational Intelligence. Karlsruhe : KIT Scientific Publishing, 2013 (Schriftenreihe des Instituts fÃ¼r Angewandte Informatik - Automatisierungstechnik am Karlsruher Institut fÃ¼r Technologie, 46), S. 211-225&amp;lt;/ref&amp;gt; из репозитория &#039;&#039;Machine learning repository&#039;&#039;&amp;lt;ref&amp;gt;https://archive.ics.uci.edu/ml/datasets/Dataset+for+Sensorless+Drive+Diagnosis&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Исследуемый набор данных содержит векторы, размерность которых равна 49. Компоненты векторов являются вещественными числами. Количество кластеров равно 11. Пропущенные значения отсутствуют.&lt;br /&gt;
&lt;br /&gt;
Для исследования масштабируемости алгоритма была использована реализация на языке C с использованием MPI&amp;lt;ref&amp;gt;http://users.eecs.northwestern.edu/~wkliao/Kmeans/index.html&amp;lt;/ref&amp;gt;. Код можно найти здесь: https://github.com/serban/kmeans. Данная реализация предоставляет возможность распараллеливать решение задачи с помощью технологий MPI, OpenMP И CUDA. Для запуска MPI-версии программы использовалась цель &amp;quot;mpi_main&amp;quot; Makefile.&lt;br /&gt;
&lt;br /&gt;
На рисунке 5 показана зависимости времени работы алгоритма кластеризации k-means в зависимости от количества используемых процессоров (использовались логарифмические оси). Разными цветами помечены запуски, соответствующие разным количествам объектам, участвующих в кластеризации. Можно видеть близкое к линейному увеличение времени работы программы в зависимости от количества процессоров. Также можно видеть увеличение времени работы алгоритма при увеличении количества объектов.&lt;br /&gt;
[[Файл:Plot_1.png|thumb|center|900px|Рисунок 5. Зависимости времени работы алгоритма кластеризации k-means в зависимости от количества используемых процессоров.]]&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-средних:&lt;br /&gt;
* [http://scikit-learn.org/ scikit-learn] библиотека машинного обучения для языка Python.&lt;br /&gt;
* [https://www.scipy.org/ SciPy] библиотека на языке Python, содержащая большое число реализаций различных алгоритмов, в том числе &#039;&#039;k&#039;&#039;-средних.&lt;br /&gt;
* [http://elki.dbs.ifi.lmu.de ELKI] библиотека для анализа данных на языке программирования Java, содержит различные алгоритмы кластеризации, в том числе &#039;&#039;k&#039;&#039;-средних.&lt;br /&gt;
* [http://mlpack.org MLPACK] библиотека машинного обучения для C++, содержит реализацию алгоритма &#039;&#039;k&#039;&#039;-средних.&lt;br /&gt;
* [https://github.com/JuliaStats/Clustering.jl Julia k-means] реализация алгоритма &#039;&#039;k&#039;&#039;-средних на языке программирования Julia.&lt;br /&gt;
* [http://opencv.org/ OpenCV] библиотека содержит реализацию &#039;&#039;k&#039;&#039;-средних.&lt;br /&gt;
* [http://mahout.apache.org Apache Mahout] содержит реализацию алгоритма &#039;&#039;k&#039;&#039;-средних на базе MapReduce.&lt;br /&gt;
* [http://www.cs.waikato.ac.nz/~ml/weka Weka] библиотека и инструмент для анализа данных на языке Java.&lt;br /&gt;
* [http://torch.ch/ Torch] библиотека машинного обучения на базе языка программирования Lua.&lt;br /&gt;
* [https://spark.apache.org/ Apache Spark MLlib] содержит распределенную реализацию алгоритма &#039;&#039;k&#039;&#039;-средних.&lt;br /&gt;
* [http://www.accord-framework.net/ Accord.NET] содержит несколько различных реализаций &#039;&#039;k&#039;&#039;-средних на языке C#.&lt;br /&gt;
* [https://www.r-bloggers.com/k-means-clustering-in-r/ R k-means] реализация &#039;&#039;k&#039;&#039;-средних на языке R.&lt;br /&gt;
&lt;br /&gt;
== Литература ==&lt;br /&gt;
&amp;lt;references \&amp;gt;&lt;/div&gt;</summary>
		<author><name>Parkhomenko</name></author>
	</entry>
	<entry>
		<id>https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A4%D0%B0%D0%B9%D0%BB:Plot_1.png&amp;diff=20501</id>
		<title>Файл:Plot 1.png</title>
		<link rel="alternate" type="text/html" href="https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A4%D0%B0%D0%B9%D0%BB:Plot_1.png&amp;diff=20501"/>
		<updated>2016-12-09T21:20:35Z</updated>

		<summary type="html">&lt;p&gt;Parkhomenko: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Parkhomenko</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:Parkhomenko/%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=18035</id>
		<title>Участник:Parkhomenko/Алгоритм 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:Parkhomenko/%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=18035"/>
		<updated>2016-11-17T22:02:36Z</updated>

		<summary type="html">&lt;p&gt;Parkhomenko: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Assignment}}&lt;br /&gt;
&lt;br /&gt;
{{algorithm&lt;br /&gt;
| name              = Алгоритм k средних&lt;br /&gt;
| serial_complexity = &amp;lt;math&amp;gt;O(tnkd)&amp;lt;/math&amp;gt;&lt;br /&gt;
| input_data        = &amp;lt;math&amp;gt;nd&amp;lt;/math&amp;gt;&lt;br /&gt;
| output_data       = &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;&lt;br /&gt;
| pf_height         = &amp;lt;math&amp;gt;O(t * \log kdn)&amp;lt;/math&amp;gt;&lt;br /&gt;
| pf_width          = &amp;lt;math&amp;gt;O(kdn)&amp;lt;/math&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
Основные авторы описания: [[Участник:Parkhomenko|П.А.Пархоменко]] ([[#Общее описание алгоритма|1.1]], [[#Вычислительное ядро алгоритма|1.3]], [[#Последовательная сложность алгоритма|1.6]], [[#Ресурс параллелизма алгоритма|1.8]], [[#Входные и выходные данные алгоритма|1.9]], [[#Свойства алгоритма|1.10]], [[#Масштабируемость алгоритма и его реализации|2.4]]), [[Участник:Ivan.mashonskiy|И.Д.Машонский]] ([[#Математическое описание алгоритма|1.2]], [[#Макроструктура алгоритма|1.4]], [[#Схема реализации последовательного алгоритма|1.5]], [[#Информационный граф|1.7]], [[#Ресурс параллелизма алгоритма|1.8]], [[#Свойства алгоритма|1.10]], [[#Существующие реализации алгоритма|2.7]])&lt;br /&gt;
== Свойства и структура алгоритмов ==&lt;br /&gt;
&lt;br /&gt;
=== Общее описание алгоритма ===&lt;br /&gt;
Алгоритм k средних (англ. k-means) - один из алгоритмов машинного обучения, решающий задачу кластеризации. Он был изобретен в середине 1950-х математиком Гуго Штейнгаузом&amp;lt;ref&amp;gt;Steinhaus H. (1956). Sur la division des corps materiels en parties. Bull. Acad. Polon. Sci., C1. III vol IV: 801—804.&amp;lt;/ref&amp;gt; и Стюартом Ллойдом&amp;lt;ref&amp;gt;Lloyd S. (1957). Least square quantization in PCM’s. Bell Telephone Laboratories Paper.&amp;lt;/ref&amp;gt;. Алгоритм стал особо популярным после публикации Маккуина&amp;lt;ref&amp;gt;MacQueen J. (1967). Some methods for classification and analysis of multivariate observations. In Proc. 5th Berkeley Symp. on Math. Statistics and Probability, pages 281—297.&amp;lt;/ref&amp;gt;, в которой впервые был использован термин “k-means”.&lt;br /&gt;
&lt;br /&gt;
Задача алгоритма кластеризации заключается в разбиении N объектов (d-мерных векторов) на K групп (кластеров). Каждый вектор может принадлежать только одному кластеру. Количество кластеров K фиксировано, оно задается в качестве параметра.&lt;br /&gt;
&lt;br /&gt;
K-means является итерационным алгоритмом, разновидностью EM-алгоритма. Основная идея работы алгоритма заключается в проведении некоторого количества итераций, на каждой из которых происходит пересчет центра масс для каждого кластера, полученного на предыдущей итерации. После этого векторы перераспределяются по кластерам: вектор относится к тому кластеру, расстояние до центра масс которого минимально. Алгоритм завершает работу в том случае, если на очередной итерации центры масс кластеров не изменились.&lt;br /&gt;
&lt;br /&gt;
=== Математическое описание алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Исходные данные: множество d-мерных векторов (наблюдений) &amp;lt;math&amp;gt;X&amp;lt;/math&amp;gt;&amp;amp;nbsp;=&amp;amp;nbsp;&amp;lt;math&amp;gt;\{x_1, x_2, ..., x_n\}&amp;lt;/math&amp;gt;, число кластеров &amp;lt;math&amp;gt;k \in \mathbb{N}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
В результате работы алгоритма исходное множество векторов &amp;lt;math&amp;gt;X&amp;lt;/math&amp;gt; разбивается на &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; непересекающихся множеств (кластеров) &amp;lt;math&amp;gt;S_1, S_2, ..., S_k&amp;lt;/math&amp;gt;, таких что &amp;lt;math&amp;gt;X = {\bigcup \limits _{i = 1}^k S_i} &amp;lt;/math&amp;gt; и значение &amp;lt;math&amp;gt;\sum_{i=1}^{k} \sum_{\mathbf x \in S_i} \left\| \mathbf x - \mu_i \right\|^2 &amp;lt;/math&amp;gt; — минимально для всех возможных наборов &amp;lt;math&amp;gt;S_1, S_2, ..., S_k&amp;lt;/math&amp;gt;.&lt;br /&gt;
Под &amp;lt;math&amp;gt;\mu_i&amp;lt;/math&amp;gt; здесь подразумевается центр масс векторов из множества &amp;lt;math&amp;gt;S_i&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Первоначальные значения центров масс &amp;lt;math&amp;gt;\mu_1^{(1)}, ..., \mu_k^{(1)}&amp;lt;/math&amp;gt; определяются в начале работы алгоритма случайным образом среди векторов множества &amp;lt;math&amp;gt;X&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Алгоритм заключается в попеременном применении двух шагов &amp;lt;ref&amp;gt;MacKay, David (2003). &amp;quot;Chapter 20. An Example Inference Task: Clustering&amp;quot; (PDF). Information Theory, Inference and Learning Algorithms. Cambridge University Press. pp. 284–292.&amp;lt;/ref&amp;gt;: &#039;&#039;&#039;распределения&#039;&#039;&#039; векторов по кластерам и &#039;&#039;&#039;обновления&#039;&#039;&#039; центров масс каждого кластера&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Распределение векторов по кластерам&#039;&#039;&#039;: на данном шаге каждый вектор распределяется в один из кластеров &amp;lt;math&amp;gt;S_i^{(t)}&amp;lt;/math&amp;gt;: &lt;br /&gt;
::&amp;lt;math&amp;gt;S_i^{(t)} = \big \{ x_p : \big \| x_p - \mu^{(t)}_i \big \|^2 \le \big \| x_p - \mu^{(t)}_j \big \|^2 \ \forall j, 1 \le j \le k \big\},&amp;lt;/math&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Обновление центров масс&#039;&#039;&#039;: на данном шаге вычисляются новые центры масс для кластеров, полученных на предыдущем шаге.&lt;br /&gt;
::&amp;lt;math&amp;gt;\mu^{(t+1)}_i = \frac{1}{|S^{(t)}_i|} \sum_{x_j \in S^{(t)}_i} x_j &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Алгоритм завершается, когда на очередном шаге не происходит изменения центров масс кластеров.&lt;br /&gt;
&lt;br /&gt;
=== Вычислительное ядро алгоритма ===&lt;br /&gt;
Вычислительное ядро последовательного алгоритма k-means состоит из двух операций, повторяющихся на каждой итерации алгоритма:&lt;br /&gt;
* пересчета центров масс кластеров;&lt;br /&gt;
* соотнесения каждого вектора к одному из кластеров.&lt;br /&gt;
&lt;br /&gt;
Пересчет центра масс кластера заключается в нахождении d-мерного вектора, являющегося средним арифметическим d-мерных векторов, принадлежащих кластеру. Эту операцию необходимо выполнять для каждого из K кластеров.&lt;br /&gt;
&lt;br /&gt;
Для соотнесения вектора к одному из кластеров, необходимо для каждого из N вектора посчитать расстояние до центров масс всех K кластеров. Для нахождения расстояния между двумя d-мерными векторами p и q используется Евклидова метрика: &amp;lt;math&amp;gt;\sqrt{\sum_{k=1}^d (p_k-q_k)^2}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Макроструктура алгоритма ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Инициализация центров масс кластеров&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
В начале алгоритма осуществляется инициализация центров масс &amp;lt;math&amp;gt;\mu_1^{(1)}, ..., \mu_k^{(1)}&amp;lt;/math&amp;gt;, которая может быть реализована двумя возможными способами &amp;lt;ref&amp;gt;Hamerly, G.; Elkan, C. (2002). &amp;quot;Alternatives to the k-means algorithm that find better clusterings&amp;quot; (PDF). Proceedings of the eleventh international conference on Information and knowledge management (CIKM).&amp;lt;/ref&amp;gt;: &lt;br /&gt;
* случайный выбор центров масс среди исходных наблюдений &amp;lt;math&amp;gt;x_1, x_2, ..., x_n&amp;lt;/math&amp;gt;;&lt;br /&gt;
* все наблюдения случайным образом распределяются по кластерам &amp;lt;math&amp;gt;S_1, S_2, ..., S_k&amp;lt;/math&amp;gt;, а затем для каждого кластера выполняется операция обновления центра масс.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Распределение векторов по кластерам&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
На шаге распределения векторов по кластерам производится операция нахождения квадратов расстояний между векторами кластера и центром масс кластера: &lt;br /&gt;
::&amp;lt;math&amp;gt;\rho = \big \| x_p - \mu^{(t)}_i \big \|^2&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Обновление центров масс кластеров&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
На шаге обновления центров масс производится операция суммирования векторов кластера:&lt;br /&gt;
::&amp;lt;math&amp;gt;\mu^{(t+1)}_i = \frac{1}{|S^{(t)}_i|} \sum_{x_j \in S^{(t)}_i} x_j &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Схема реализации последовательного алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Последовательность исполнения метода следующая:&lt;br /&gt;
# Инициализируются центры масс &amp;lt;math&amp;gt;\mu_1^{(1)}, ..., \mu_k^{(1)}&amp;lt;/math&amp;gt;&lt;br /&gt;
# &amp;lt;math&amp;gt;t := 1&amp;lt;/math&amp;gt;&lt;br /&gt;
# Для каждого вектора &amp;lt;math&amp;gt;x_i, i = 1, 2, ..., n&amp;lt;/math&amp;gt; вычисляется &amp;lt;br/&amp;gt;&amp;lt;math&amp;gt;m = \underset{j \in \{1, 2, ..., k\}} {\operatorname{arg\,min}} \big \| x_i - \mu^{(t)}_j \big \|^2&amp;lt;/math&amp;gt;, &amp;lt;br/&amp;gt;вектор &amp;lt;math&amp;gt;x_i&amp;lt;/math&amp;gt; распределяется в кластер &amp;lt;math&amp;gt;S^{(t)}_m&amp;lt;/math&amp;gt;&lt;br /&gt;
# Для каждого &amp;lt;math&amp;gt;j = 1, 2, ..., k&amp;lt;/math&amp;gt; вычисляется &amp;lt;br/&amp;gt;&amp;lt;math&amp;gt;\mu^{(t+1)}_j = \frac{1}{|S^{(t)}_i|} \sum_{x_j \in S^{(t)}_i} x_j &amp;lt;/math&amp;gt;&lt;br /&gt;
#  Если &amp;lt;math&amp;gt;\mu^{(t)}_j = \mu^{(t+1)}_j, j = 1, 2, ..., k&amp;lt;/math&amp;gt;, завершить выполнение алгоритма, иначе &amp;lt;math&amp;gt;t := t + 1&amp;lt;/math&amp;gt;, переход на шаг 3.&lt;br /&gt;
&lt;br /&gt;
=== Последовательная сложность алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Для вычисления центра массы кластера, содержащего &amp;lt;math&amp;gt;n_i&amp;lt;/math&amp;gt; d-мерных векторов, необходимо:&lt;br /&gt;
* &amp;lt;math&amp;gt;n_i * (d - 1)&amp;lt;/math&amp;gt; операций сложения&lt;br /&gt;
* &amp;lt;math&amp;gt;d&amp;lt;/math&amp;gt; операций деления&lt;br /&gt;
&lt;br /&gt;
Для определения центров масс всех k кластеров требуется:&lt;br /&gt;
* &amp;lt;math&amp;gt;n * (d - 1)&amp;lt;/math&amp;gt; операций сложения&lt;br /&gt;
* &amp;lt;math&amp;gt;k * d&amp;lt;/math&amp;gt; операций деления&lt;br /&gt;
&lt;br /&gt;
Для определения расстояния между двумя d-мерными векторами, требуется:&lt;br /&gt;
* &amp;lt;math&amp;gt;d&amp;lt;/math&amp;gt; операций вычитания&lt;br /&gt;
* &amp;lt;math&amp;gt;d&amp;lt;/math&amp;gt; операций умножения&lt;br /&gt;
* &amp;lt;math&amp;gt;d - 1&amp;lt;/math&amp;gt; операций сложения&lt;br /&gt;
&lt;br /&gt;
Для определения кластера для n d-мерного векторов, необходимо:&lt;br /&gt;
* &amp;lt;math&amp;gt;n * k * d&amp;lt;/math&amp;gt; операций вычитания&lt;br /&gt;
* &amp;lt;math&amp;gt;n * k * d&amp;lt;/math&amp;gt; операций умножения&lt;br /&gt;
* &amp;lt;math&amp;gt;n * k * (d - 1)&amp;lt;/math&amp;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; операций умножения/деления&lt;br /&gt;
&lt;br /&gt;
Сложность всего алгоритма, состоящего из &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt; итераций: &amp;lt;math&amp;gt;O(t * n * k * d)&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Информационный граф ===&lt;br /&gt;
&lt;br /&gt;
В данном разделе описывается информационный граф алгоритма k-средних при &amp;lt;math&amp;gt;n = 3, k = 2&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
На рисунке 1 показана общая структура алгоритма: в качестве входных данных выступает матрица, строками которой являются входные векторы &amp;lt;math&amp;gt;x_1, x_2, x_3&amp;lt;/math&amp;gt;, на выходе получается массив из &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; чисел, где элемент с номером &amp;lt;math&amp;gt;i = 1, 2, 3&amp;lt;/math&amp;gt; обозначает номер кластера, которому принадлежит вектор &amp;lt;math&amp;gt;x_i&amp;lt;/math&amp;gt;. На шаге &amp;lt;math&amp;gt;init&amp;lt;/math&amp;gt; происходит инициализация значений центров масс кластеров, после этого осуществляется итеративное повторение этапов распределения векторов по кластерам (&amp;lt;math&amp;gt;as&amp;lt;/math&amp;gt;) и обновления значений центров масс кластеров (&amp;lt;math&amp;gt;up&amp;lt;/math&amp;gt;). Когда на очередном шаге обновления центров масс кластеров значения центров масс не изменяются, алгоритм завершает работу, и в качестве выходных данных выступают номера кластеров для каждого из входных векторов.&lt;br /&gt;
[[file:k_means_main.png|thumb|center|400px|Рисунок 1. Общая схема работы алгоритма k-средних]]&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Распределение векторов по кластерам.&#039;&#039;&#039; На рисунке 2 изображен информационный граф для этапа распределения векторов по кластерам. В качестве входных данных выступают строки входной матрицы (входные векторы) &amp;lt;math&amp;gt;x_1, x_2, x_3&amp;lt;/math&amp;gt; и текущие значения центров масс кластеров &amp;lt;math&amp;gt;\mu_1, \mu_2&amp;lt;/math&amp;gt; (вычисленные на этапе инициализации или предшествующего этапа обновления центров масс кластеров). В качестве выходных данных выступают числа &amp;lt;math&amp;gt;m_1, m_2, m_3&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;m_i, i = 1, 2, 3&amp;lt;/math&amp;gt; - номер кластера, содержащего вектор &amp;lt;math&amp;gt;x_i&amp;lt;/math&amp;gt;. Вершинами с пометкой &amp;lt;math&amp;gt;sub&amp;lt;/math&amp;gt; обозначены операции векторной разности, вершинами &amp;lt;math&amp;gt;sn&amp;lt;/math&amp;gt; - операция вычисления квадрата нормы вектора, вершинами &amp;lt;math&amp;gt;am&amp;lt;/math&amp;gt; - операция &amp;lt;math&amp;gt;\underset{i \in \{1, 2\}} {\operatorname{arg\,min}}  p_i&amp;lt;/math&amp;gt;.&lt;br /&gt;
[[file:k_means_info_graph_as.png|thumb|center|400px|Рисунок 2. Граф алгоритма для этапа распределения векторов по кластерам]]&lt;br /&gt;
&#039;&#039;&#039;Обновление центров масс кластеров.&#039;&#039;&#039; На рисунке 3 представлен информационный граф для этапа обновления центров масс кластеров. В качестве входных данных выступают строки входной матрицы (входные векторы) &amp;lt;math&amp;gt;x_1, x_2, x_3&amp;lt;/math&amp;gt; с соответствующими номерами кластеров &amp;lt;math&amp;gt;m_1, m_2, m_3&amp;lt;/math&amp;gt;, содержащих эти векторы. В качестве выходных данных здесь выступают обновленные значения центров масс кластеров: &amp;lt;math&amp;gt;\mu_1, \mu_2&amp;lt;/math&amp;gt;. Вершинами с пометками &amp;lt;math&amp;gt;s_i, i = 1, 2&amp;lt;/math&amp;gt; обозначены операции суммирования векторов, принадлежащих кластеру &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt;. Вершинами с пометками &amp;lt;math&amp;gt;cs_i, i = 1, 2&amp;lt;/math&amp;gt; обозначены операции вычисления выражения &amp;lt;math&amp;gt;1 / |S_i|&amp;lt;/math&amp;gt;, где за &amp;lt;math&amp;gt;S_i&amp;lt;/math&amp;gt; обозначен кластер с номером &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt;. Вершинами с пометкой &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt; обозначена операция произведения.&lt;br /&gt;
[[file:k_means_info_graph_up.png|thumb|center|400px|Рисунок 3. Граф алгоритма для этапа обновления центров масс кластеров]]&lt;br /&gt;
&lt;br /&gt;
=== Ресурс параллелизма алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Алгоритм кластеризации k средних имеет место массовый параллелизм: в основе каждого из основных этапов алгоритма (распределения векторов по кластерам и обновления центров масс кластеров) лежат циклы, итерации которых являются информационно независимыми.&lt;br /&gt;
Учитывая данный факт можно оценить параллельную сложность алгоритма в предположении доступности неограниченного числа необходимых процессоров.&lt;br /&gt;
&lt;br /&gt;
В силу особенностей алгоритма k средних порядок выполнения основных этапов существенен, что не позволяет выполнять их параллельно. Таким образом, итоговая сложность параллельного алгоритма будет определяться, исходя из формулы &amp;lt;math&amp;gt;T = t * (T_{as} + T_{up})&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;T_{as}&amp;lt;/math&amp;gt; - параллельная сложность этапа распределения векторов по кластерам, &amp;lt;math&amp;gt;T_{up}&amp;lt;/math&amp;gt; - параллельная сложность этапа обновления центров масс кластеров, &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt; - общее число итераций алгоритма.&lt;br /&gt;
&lt;br /&gt;
Параллельная сложность этапа распределения векторов по кластерам с учетом доступности неограниченного числа процессоров вычисляется следующим образом: так как вычисление значений &amp;lt;math&amp;gt;\big \| x_i - \mu^{(t)}_j \big \|^2&amp;lt;/math&amp;gt; для каждой пары векторов &amp;lt;math&amp;gt;x_i, i = 1, 2, ..., n&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\mu^{(t)}_j, j = 1, 2, ..., k&amp;lt;/math&amp;gt; можно выполнять независимо и для вычисления этого выражения требуется &amp;lt;math&amp;gt;O(\log d)&amp;lt;/math&amp;gt; операций в соответствии с [[Нахождение_частных_сумм_элементов_массива_сдваиванием | параллельной реализацией нахождения сумм элементов массива сдваиванием]]. Параллельная сложность реализации операции нахождения минимума из &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; элементов определяется как &amp;lt;math&amp;gt;O(\log k)&amp;lt;/math&amp;gt;. Таким образом, сложность этапа распределения векторов по кластерам &amp;lt;math&amp;gt;O(\log kd)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Параллельная сложность этапа обновления центров масс кластеров вычисляется следующим образом: так как обновление значений каждого из центров масс кластеров можно выполнять независимо, параллельная сложность определяется сложностью обновления центра масс самого большого кластера. В худшем случае для нахождения значения выражения &amp;lt;math&amp;gt;\mu^{(t+1)}_j = \frac{1}{|S^{(t)}_i|} \sum_{x_j \in S^{(t)}_i} x_j &amp;lt;/math&amp;gt; требуется &amp;lt;math&amp;gt;O(\log n)&amp;lt;/math&amp;gt; операций.&lt;br /&gt;
&lt;br /&gt;
С учетом вышесказанного, итоговая параллельная сложность алгоритма k средних определяется выражением &amp;lt;math&amp;gt;O(t * \log kdn)&amp;lt;/math&amp;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;k&amp;lt;/math&amp;gt; - количество кластеров;&lt;br /&gt;
* матрица координат векторов &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; размерностью &amp;lt;math&amp;gt;n * d&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Объем входных данных&#039;&#039;&#039;:&lt;br /&gt;
* &amp;lt;math&amp;gt;n * d&amp;lt;/math&amp;gt; вещественных чисел (если координаты вещественные числа), &amp;lt;math&amp;gt;1&amp;lt;/math&amp;gt; целое неотрицательное число.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Выходные данные&#039;&#039;&#039;:&lt;br /&gt;
* вектор длины &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; - для каждого вектора указан номер кластера.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Объем выходных данных&#039;&#039;&#039;: &lt;br /&gt;
* &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; целых неотрицательных чисел.&lt;br /&gt;
&lt;br /&gt;
=== Свойства алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Соотношение последовательной и параллельной сложности алгоритма равно &amp;lt;math&amp;gt;\frac{O(tnkd)}{O(t * \log kdn)}&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Число операций алгоритма k средних оценивается как &amp;lt;math&amp;gt;O(tnkd)&amp;lt;/math&amp;gt;, суммарный объем входных и выходных данных равен &amp;lt;math&amp;gt;n(d+1)&amp;lt;/math&amp;gt;. Следовательно, вычислительная мощность алгоритма линейна по &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; и линейна по &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Стоит отметить следующие ключевые особенности алгоритма k средних:&lt;br /&gt;
* Алгоритм прост в реализации и имеет высокую скорость работы по сравнению с другими алгоритмами кластеризации (при удачном выборе начальных значений центров масс кластеров)&lt;br /&gt;
* В качестве метрики используется евклидово расстояние, а в качестве меры разброса кластера используется дисперсия&lt;br /&gt;
* Количество кластеров k является входным параметром алгоритма, поэтому неправильный выбор этого параметра может негативно повлиять на качество кластеризации&lt;br /&gt;
* Сходимость алгоритма к локальному минимуму может породить некорректный конечный результат работы&lt;br /&gt;
* Алгоритм очень чувствителен к выбору начальных центров масс кластеров: классический вариант подразумевает случайный их выбор, что может являться источником погрешности. Из этого и предыдущего свойства следует то, что алгоритм не является устойчивым.&lt;br /&gt;
&lt;br /&gt;
Как и любой другой алгоритм кластеризации, результат работы алгоритма k средних зависит от того, удовлетворяет ли входной набор данных предположениям, на которые опираются алгоритмы кластеризации. Таким образом, на одних наборах данных алгоритм может показывать хорошие результаты, но на других выдавать некорректные результаты.&lt;br /&gt;
&lt;br /&gt;
Алгоритм не является детерминированным, в силу того, что он чувствителен к выбору начальных центров масс кластеров, который осуществляется, как правило, случайным образом и тем самым вносит различия в работу алгоритма от запуска к запуску.&lt;br /&gt;
&lt;br /&gt;
== Программная реализация алгоритма ==&lt;br /&gt;
&lt;br /&gt;
=== Особенности реализации последовательного алгоритма ===&lt;br /&gt;
&lt;br /&gt;
=== Локальность данных и вычислений ===&lt;br /&gt;
&lt;br /&gt;
=== Возможные способы и особенности параллельной реализации алгоритма ===&lt;br /&gt;
&lt;br /&gt;
=== Масштабируемость алгоритма и его реализации ===&lt;br /&gt;
Исследование масштабируемости алгоритма k-means в зависимости от количества используемых процессов было проведено в статье Кумара&amp;lt;ref&amp;gt;Kumar, J., Mills, R. T., Hoffman, F. M., &amp;amp; Hargrove, W. W. (2011). Parallel k-means clustering for quantitative ecoregion delineation using large data sets. Procedia Computer Science, 4, 1602-1611.&amp;lt;/ref&amp;gt;. Исследование происходило на суперкомпьютере Jaguar - Cray XT5&amp;lt;ref&amp;gt;https://www.top500.org/system/176029&amp;lt;/ref&amp;gt;. На момент экспериментов данный суперкомпьютер имел следующую конфигурацию: 18,688 вычислительных узлов с двумя шестнадцатиядерными процессорами AMD Opteron 2435 (Istanbul) 2.6 GHz, 16 GB of DDR2-800 оперативной памяти, и SeaStar 2+ роутер. Всего он состоял из 224,256 вычислительных ядер, 300 TB памяти, и пиковой производительностью 2.3 petaflops.&lt;br /&gt;
&lt;br /&gt;
Реализация алгоритма была выполнена на языке программирования C с использованием MPI.&lt;br /&gt;
&lt;br /&gt;
Объем данных составлял 84 гигабайта, количество объектов (d-мерных векторов) n равнялось 1,024,767,667, размерность векторов d равнялась 22, количество кластеров k равнялось 1000. &lt;br /&gt;
&lt;br /&gt;
На рисунке 4 показана зависимости времени работы алгоритма кластеризации k-means в зависимости от количества используемых процессоров. Можно отметить, что время, затраченное на чтение данных и запись результатов кластеризации, практически не изменяется с увеличением количества задействованных процессоров. Время же работы самого алгоритма кластеризации уменьшается с увеличением количества процессоров.&lt;br /&gt;
[[Файл:k-means-proc-scalability.png|thumb|center|700px|Рисунок 4. Зависимости времени работы алгоритма кластеризации k-means в зависимости от количества используемых процессоров.]]&lt;br /&gt;
&lt;br /&gt;
Также было произведено самостоятельное исследование масштабируемости алгоритма. Исследование производилось на суперкомпьютере &amp;quot;Blue Gene/P&amp;quot;&amp;lt;ref&amp;gt;http://hpc.cmc.msu.ru/bgp&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Набор и границы значений изменяемых параметров запуска реализации алгоритма:&lt;br /&gt;
&lt;br /&gt;
* число процессоров [1, 2, 4, 8, 16, 32, 64, 128, 256, 512];&lt;br /&gt;
* количество объектов [5000, 10000, 25000, 50000].&lt;br /&gt;
&lt;br /&gt;
Был использован набор данных &#039;&#039;Dataset for Sensorless Drive Diagnosis Data Set&#039;&#039;&amp;lt;ref&amp;gt;PASCHKE, Fabian ; BAYER, Christian ; BATOR, Martyna ; MÃ–NKS, Uwe ; DICKS, Alexander ; ENGE-ROSENBLATT, Olaf ; LOHWEG, Volker: Sensorlose ZustandsÃ¼berwachung an Synchronmotoren, Bd. 46. In: HOFFMANN, Frank; HÃœLLERMEIER, Eyke (Hrsg.): Proceedings 23. Workshop Computational Intelligence. Karlsruhe : KIT Scientific Publishing, 2013 (Schriftenreihe des Instituts fÃ¼r Angewandte Informatik - Automatisierungstechnik am Karlsruher Institut fÃ¼r Technologie, 46), S. 211-225&amp;lt;/ref&amp;gt; из репозитория &#039;&#039;Machine learning repository&#039;&#039;&amp;lt;ref&amp;gt;https://archive.ics.uci.edu/ml/datasets/Dataset+for+Sensorless+Drive+Diagnosis&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Исследуемый набор данных содержит векторы, размерность которых равна 49. Компоненты векторов являются вещественными числами. Количество кластеров равно 11. Пропущенные значения отсутствуют.&lt;br /&gt;
&lt;br /&gt;
Для исследования масштабируемости алгоритма была использована реализация на языке C с использованием MPI&amp;lt;ref&amp;gt;http://users.eecs.northwestern.edu/~wkliao/Kmeans/index.html&amp;lt;/ref&amp;gt;. Код можно найти здесь: https://github.com/serban/kmeans.&lt;br /&gt;
&lt;br /&gt;
На рисунке 5 показана зависимости времени работы алгоритма кластеризации k-means в зависимости от количества используемых процессоров. Можно видеть, что при увеличении количества процессоров в N раз, время работы алгоритма уменьшается примерно в N раз (при условии, что количество объектов остается неизменным). Также можно отметить, что при фиксированном количестве процессоров, зависимость времени работы алгоритма от количества объектов также близка к линейной.&lt;br /&gt;
[[Файл:Heatmap_kmeans.png|thumb|center|900px|Рисунок 5. Зависимости времени работы алгоритма кластеризации k-means в зависимости от количества используемых процессоров.]]&lt;br /&gt;
&lt;br /&gt;
На рисунке 6 показана зависимости времени работы алгоритма кластеризации k-means в зависимости от количества используемых процессоров (при фиксированном количестве объектов, равном 50000). При визуализации была использована логарифмическая шкала. Можно отметить, что при заданном наборе данных можно наблюдать линейную зависимость времени работы алгоритма от количества используемых процессоров, что согласуется с теоретической оценкой сложности последовательной версии алгоритма.&lt;br /&gt;
[[Файл:50000kmeans.png|thumb|center|900px|Рисунок 6. Зависимости времени работы алгоритма кластеризации k-means в зависимости от количества используемых процессоров (количество объектов равно 50000).]]&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-средних:&lt;br /&gt;
* [http://scikit-learn.org/ scikit-learn] библиотека машинного обучения для языка Python.&lt;br /&gt;
* [https://www.scipy.org/ SciPy] библиотека на языке Python, содержащая большое число реализаций различных алгоритмов, в том числе &#039;&#039;k&#039;&#039;-средних.&lt;br /&gt;
* [http://elki.dbs.ifi.lmu.de ELKI] библиотека для анализа данных на языке программирования Java, содержит различные алгоритмы кластеризации, в том числе &#039;&#039;k&#039;&#039;-средних.&lt;br /&gt;
* [http://mlpack.org MLPACK] библиотека машинного обучения для C++, содержит реализацию алгоритма &#039;&#039;k&#039;&#039;-средних.&lt;br /&gt;
* [https://github.com/JuliaStats/Clustering.jl Julia k-means] реализация алгоритма &#039;&#039;k&#039;&#039;-средних на языке программирования Julia.&lt;br /&gt;
* [http://opencv.org/ OpenCV] библиотека содержит реализацию &#039;&#039;k&#039;&#039;-средних.&lt;br /&gt;
* [http://mahout.apache.org Apache Mahout] содержит реализацию алгоритма &#039;&#039;k&#039;&#039;-средних на базе MapReduce.&lt;br /&gt;
* [http://www.cs.waikato.ac.nz/~ml/weka Weka] библиотека и инструмент для анализа данных на языке Java.&lt;br /&gt;
* [http://torch.ch/ Torch] библиотека машинного обучения на базе языка программирования Lua.&lt;br /&gt;
* [https://spark.apache.org/ Apache Spark MLlib] содержит распределенную реализацию алгоритма &#039;&#039;k&#039;&#039;-средних.&lt;br /&gt;
* [http://www.accord-framework.net/ Accord.NET] содержит несколько различных реализаций &#039;&#039;k&#039;&#039;-средних на языке C#.&lt;br /&gt;
* [https://www.r-bloggers.com/k-means-clustering-in-r/ R k-means] реализация &#039;&#039;k&#039;&#039;-средних на языке R.&lt;br /&gt;
&lt;br /&gt;
== Литература ==&lt;br /&gt;
&amp;lt;references \&amp;gt;&lt;/div&gt;</summary>
		<author><name>Parkhomenko</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:Parkhomenko/%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=18034</id>
		<title>Участник:Parkhomenko/Алгоритм 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:Parkhomenko/%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=18034"/>
		<updated>2016-11-17T21:57:52Z</updated>

		<summary type="html">&lt;p&gt;Parkhomenko: /* Масштабируемость алгоритма и его реализации */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
{{algorithm&lt;br /&gt;
| name              = Алгоритм k средних&lt;br /&gt;
| serial_complexity = &amp;lt;math&amp;gt;O(tnkd)&amp;lt;/math&amp;gt;&lt;br /&gt;
| input_data        = &amp;lt;math&amp;gt;nd&amp;lt;/math&amp;gt;&lt;br /&gt;
| output_data       = &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;&lt;br /&gt;
| pf_height         = &amp;lt;math&amp;gt;O(t * \log kdn)&amp;lt;/math&amp;gt;&lt;br /&gt;
| pf_width          = &amp;lt;math&amp;gt;O(kdn)&amp;lt;/math&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
Основные авторы описания: [[Участник:Parkhomenko|П.А.Пархоменко]] ([[#Общее описание алгоритма|1.1]], [[#Вычислительное ядро алгоритма|1.3]], [[#Последовательная сложность алгоритма|1.6]], [[#Ресурс параллелизма алгоритма|1.8]], [[#Входные и выходные данные алгоритма|1.9]], [[#Свойства алгоритма|1.10]], [[#Масштабируемость алгоритма и его реализации|2.4]]), [[Участник:Ivan.mashonskiy|И.Д.Машонский]] ([[#Математическое описание алгоритма|1.2]], [[#Макроструктура алгоритма|1.4]], [[#Схема реализации последовательного алгоритма|1.5]], [[#Информационный граф|1.7]], [[#Ресурс параллелизма алгоритма|1.8]], [[#Свойства алгоритма|1.10]], [[#Существующие реализации алгоритма|2.7]])&lt;br /&gt;
== Свойства и структура алгоритмов ==&lt;br /&gt;
&lt;br /&gt;
=== Общее описание алгоритма ===&lt;br /&gt;
Алгоритм k средних (англ. k-means) - один из алгоритмов машинного обучения, решающий задачу кластеризации. Он был изобретен в середине 1950-х математиком Гуго Штейнгаузом&amp;lt;ref&amp;gt;Steinhaus H. (1956). Sur la division des corps materiels en parties. Bull. Acad. Polon. Sci., C1. III vol IV: 801—804.&amp;lt;/ref&amp;gt; и Стюартом Ллойдом&amp;lt;ref&amp;gt;Lloyd S. (1957). Least square quantization in PCM’s. Bell Telephone Laboratories Paper.&amp;lt;/ref&amp;gt;. Алгоритм стал особо популярным после публикации Маккуина&amp;lt;ref&amp;gt;MacQueen J. (1967). Some methods for classification and analysis of multivariate observations. In Proc. 5th Berkeley Symp. on Math. Statistics and Probability, pages 281—297.&amp;lt;/ref&amp;gt;, в которой впервые был использован термин “k-means”.&lt;br /&gt;
&lt;br /&gt;
Задача алгоритма кластеризации заключается в разбиении N объектов (d-мерных векторов) на K групп (кластеров). Каждый вектор может принадлежать только одному кластеру. Количество кластеров K фиксировано, оно задается в качестве параметра.&lt;br /&gt;
&lt;br /&gt;
K-means является итерационным алгоритмом, разновидностью EM-алгоритма. Основная идея работы алгоритма заключается в проведении некоторого количества итераций, на каждой из которых происходит пересчет центра масс для каждого кластера, полученного на предыдущей итерации. После этого векторы перераспределяются по кластерам: вектор относится к тому кластеру, расстояние до центра масс которого минимально. Алгоритм завершает работу в том случае, если на очередной итерации центры масс кластеров не изменились.&lt;br /&gt;
&lt;br /&gt;
=== Математическое описание алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Исходные данные: множество d-мерных векторов (наблюдений) &amp;lt;math&amp;gt;X&amp;lt;/math&amp;gt;&amp;amp;nbsp;=&amp;amp;nbsp;&amp;lt;math&amp;gt;\{x_1, x_2, ..., x_n\}&amp;lt;/math&amp;gt;, число кластеров &amp;lt;math&amp;gt;k \in \mathbb{N}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
В результате работы алгоритма исходное множество векторов &amp;lt;math&amp;gt;X&amp;lt;/math&amp;gt; разбивается на &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; непересекающихся множеств (кластеров) &amp;lt;math&amp;gt;S_1, S_2, ..., S_k&amp;lt;/math&amp;gt;, таких что &amp;lt;math&amp;gt;X = {\bigcup \limits _{i = 1}^k S_i} &amp;lt;/math&amp;gt; и значение &amp;lt;math&amp;gt;\sum_{i=1}^{k} \sum_{\mathbf x \in S_i} \left\| \mathbf x - \mu_i \right\|^2 &amp;lt;/math&amp;gt; — минимально для всех возможных наборов &amp;lt;math&amp;gt;S_1, S_2, ..., S_k&amp;lt;/math&amp;gt;.&lt;br /&gt;
Под &amp;lt;math&amp;gt;\mu_i&amp;lt;/math&amp;gt; здесь подразумевается центр масс векторов из множества &amp;lt;math&amp;gt;S_i&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Первоначальные значения центров масс &amp;lt;math&amp;gt;\mu_1^{(1)}, ..., \mu_k^{(1)}&amp;lt;/math&amp;gt; определяются в начале работы алгоритма случайным образом среди векторов множества &amp;lt;math&amp;gt;X&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Алгоритм заключается в попеременном применении двух шагов &amp;lt;ref&amp;gt;MacKay, David (2003). &amp;quot;Chapter 20. An Example Inference Task: Clustering&amp;quot; (PDF). Information Theory, Inference and Learning Algorithms. Cambridge University Press. pp. 284–292.&amp;lt;/ref&amp;gt;: &#039;&#039;&#039;распределения&#039;&#039;&#039; векторов по кластерам и &#039;&#039;&#039;обновления&#039;&#039;&#039; центров масс каждого кластера&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Распределение векторов по кластерам&#039;&#039;&#039;: на данном шаге каждый вектор распределяется в один из кластеров &amp;lt;math&amp;gt;S_i^{(t)}&amp;lt;/math&amp;gt;: &lt;br /&gt;
::&amp;lt;math&amp;gt;S_i^{(t)} = \big \{ x_p : \big \| x_p - \mu^{(t)}_i \big \|^2 \le \big \| x_p - \mu^{(t)}_j \big \|^2 \ \forall j, 1 \le j \le k \big\},&amp;lt;/math&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Обновление центров масс&#039;&#039;&#039;: на данном шаге вычисляются новые центры масс для кластеров, полученных на предыдущем шаге.&lt;br /&gt;
::&amp;lt;math&amp;gt;\mu^{(t+1)}_i = \frac{1}{|S^{(t)}_i|} \sum_{x_j \in S^{(t)}_i} x_j &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Алгоритм завершается, когда на очередном шаге не происходит изменения центров масс кластеров.&lt;br /&gt;
&lt;br /&gt;
=== Вычислительное ядро алгоритма ===&lt;br /&gt;
Вычислительное ядро последовательного алгоритма k-means состоит из двух операций, повторяющихся на каждой итерации алгоритма:&lt;br /&gt;
* пересчета центров масс кластеров;&lt;br /&gt;
* соотнесения каждого вектора к одному из кластеров.&lt;br /&gt;
&lt;br /&gt;
Пересчет центра масс кластера заключается в нахождении d-мерного вектора, являющегося средним арифметическим d-мерных векторов, принадлежащих кластеру. Эту операцию необходимо выполнять для каждого из K кластеров.&lt;br /&gt;
&lt;br /&gt;
Для соотнесения вектора к одному из кластеров, необходимо для каждого из N вектора посчитать расстояние до центров масс всех K кластеров. Для нахождения расстояния между двумя d-мерными векторами p и q используется Евклидова метрика: &amp;lt;math&amp;gt;\sqrt{\sum_{k=1}^d (p_k-q_k)^2}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Макроструктура алгоритма ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Инициализация центров масс кластеров&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
В начале алгоритма осуществляется инициализация центров масс &amp;lt;math&amp;gt;\mu_1^{(1)}, ..., \mu_k^{(1)}&amp;lt;/math&amp;gt;, которая может быть реализована двумя возможными способами &amp;lt;ref&amp;gt;Hamerly, G.; Elkan, C. (2002). &amp;quot;Alternatives to the k-means algorithm that find better clusterings&amp;quot; (PDF). Proceedings of the eleventh international conference on Information and knowledge management (CIKM).&amp;lt;/ref&amp;gt;: &lt;br /&gt;
* случайный выбор центров масс среди исходных наблюдений &amp;lt;math&amp;gt;x_1, x_2, ..., x_n&amp;lt;/math&amp;gt;;&lt;br /&gt;
* все наблюдения случайным образом распределяются по кластерам &amp;lt;math&amp;gt;S_1, S_2, ..., S_k&amp;lt;/math&amp;gt;, а затем для каждого кластера выполняется операция обновления центра масс.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Распределение векторов по кластерам&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
На шаге распределения векторов по кластерам производится операция нахождения квадратов расстояний между векторами кластера и центром масс кластера: &lt;br /&gt;
::&amp;lt;math&amp;gt;\rho = \big \| x_p - \mu^{(t)}_i \big \|^2&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Обновление центров масс кластеров&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
На шаге обновления центров масс производится операция суммирования векторов кластера:&lt;br /&gt;
::&amp;lt;math&amp;gt;\mu^{(t+1)}_i = \frac{1}{|S^{(t)}_i|} \sum_{x_j \in S^{(t)}_i} x_j &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Схема реализации последовательного алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Последовательность исполнения метода следующая:&lt;br /&gt;
# Инициализируются центры масс &amp;lt;math&amp;gt;\mu_1^{(1)}, ..., \mu_k^{(1)}&amp;lt;/math&amp;gt;&lt;br /&gt;
# &amp;lt;math&amp;gt;t := 1&amp;lt;/math&amp;gt;&lt;br /&gt;
# Для каждого вектора &amp;lt;math&amp;gt;x_i, i = 1, 2, ..., n&amp;lt;/math&amp;gt; вычисляется &amp;lt;br/&amp;gt;&amp;lt;math&amp;gt;m = \underset{j \in \{1, 2, ..., k\}} {\operatorname{arg\,min}} \big \| x_i - \mu^{(t)}_j \big \|^2&amp;lt;/math&amp;gt;, &amp;lt;br/&amp;gt;вектор &amp;lt;math&amp;gt;x_i&amp;lt;/math&amp;gt; распределяется в кластер &amp;lt;math&amp;gt;S^{(t)}_m&amp;lt;/math&amp;gt;&lt;br /&gt;
# Для каждого &amp;lt;math&amp;gt;j = 1, 2, ..., k&amp;lt;/math&amp;gt; вычисляется &amp;lt;br/&amp;gt;&amp;lt;math&amp;gt;\mu^{(t+1)}_j = \frac{1}{|S^{(t)}_i|} \sum_{x_j \in S^{(t)}_i} x_j &amp;lt;/math&amp;gt;&lt;br /&gt;
#  Если &amp;lt;math&amp;gt;\mu^{(t)}_j = \mu^{(t+1)}_j, j = 1, 2, ..., k&amp;lt;/math&amp;gt;, завершить выполнение алгоритма, иначе &amp;lt;math&amp;gt;t := t + 1&amp;lt;/math&amp;gt;, переход на шаг 3.&lt;br /&gt;
&lt;br /&gt;
=== Последовательная сложность алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Для вычисления центра массы кластера, содержащего &amp;lt;math&amp;gt;n_i&amp;lt;/math&amp;gt; d-мерных векторов, необходимо:&lt;br /&gt;
* &amp;lt;math&amp;gt;n_i * (d - 1)&amp;lt;/math&amp;gt; операций сложения&lt;br /&gt;
* &amp;lt;math&amp;gt;d&amp;lt;/math&amp;gt; операций деления&lt;br /&gt;
&lt;br /&gt;
Для определения центров масс всех k кластеров требуется:&lt;br /&gt;
* &amp;lt;math&amp;gt;n * (d - 1)&amp;lt;/math&amp;gt; операций сложения&lt;br /&gt;
* &amp;lt;math&amp;gt;k * d&amp;lt;/math&amp;gt; операций деления&lt;br /&gt;
&lt;br /&gt;
Для определения расстояния между двумя d-мерными векторами, требуется:&lt;br /&gt;
* &amp;lt;math&amp;gt;d&amp;lt;/math&amp;gt; операций вычитания&lt;br /&gt;
* &amp;lt;math&amp;gt;d&amp;lt;/math&amp;gt; операций умножения&lt;br /&gt;
* &amp;lt;math&amp;gt;d - 1&amp;lt;/math&amp;gt; операций сложения&lt;br /&gt;
&lt;br /&gt;
Для определения кластера для n d-мерного векторов, необходимо:&lt;br /&gt;
* &amp;lt;math&amp;gt;n * k * d&amp;lt;/math&amp;gt; операций вычитания&lt;br /&gt;
* &amp;lt;math&amp;gt;n * k * d&amp;lt;/math&amp;gt; операций умножения&lt;br /&gt;
* &amp;lt;math&amp;gt;n * k * (d - 1)&amp;lt;/math&amp;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; операций умножения/деления&lt;br /&gt;
&lt;br /&gt;
Сложность всего алгоритма, состоящего из &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt; итераций: &amp;lt;math&amp;gt;O(t * n * k * d)&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Информационный граф ===&lt;br /&gt;
&lt;br /&gt;
В данном разделе описывается информационный граф алгоритма k-средних при &amp;lt;math&amp;gt;n = 3, k = 2&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
На рисунке 1 показана общая структура алгоритма: в качестве входных данных выступает матрица, строками которой являются входные векторы &amp;lt;math&amp;gt;x_1, x_2, x_3&amp;lt;/math&amp;gt;, на выходе получается массив из &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; чисел, где элемент с номером &amp;lt;math&amp;gt;i = 1, 2, 3&amp;lt;/math&amp;gt; обозначает номер кластера, которому принадлежит вектор &amp;lt;math&amp;gt;x_i&amp;lt;/math&amp;gt;. На шаге &amp;lt;math&amp;gt;init&amp;lt;/math&amp;gt; происходит инициализация значений центров масс кластеров, после этого осуществляется итеративное повторение этапов распределения векторов по кластерам (&amp;lt;math&amp;gt;as&amp;lt;/math&amp;gt;) и обновления значений центров масс кластеров (&amp;lt;math&amp;gt;up&amp;lt;/math&amp;gt;). Когда на очередном шаге обновления центров масс кластеров значения центров масс не изменяются, алгоритм завершает работу, и в качестве выходных данных выступают номера кластеров для каждого из входных векторов.&lt;br /&gt;
[[file:k_means_main.png|thumb|center|400px|Рисунок 1. Общая схема работы алгоритма k-средних]]&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Распределение векторов по кластерам.&#039;&#039;&#039; На рисунке 2 изображен информационный граф для этапа распределения векторов по кластерам. В качестве входных данных выступают строки входной матрицы (входные векторы) &amp;lt;math&amp;gt;x_1, x_2, x_3&amp;lt;/math&amp;gt; и текущие значения центров масс кластеров &amp;lt;math&amp;gt;\mu_1, \mu_2&amp;lt;/math&amp;gt; (вычисленные на этапе инициализации или предшествующего этапа обновления центров масс кластеров). В качестве выходных данных выступают числа &amp;lt;math&amp;gt;m_1, m_2, m_3&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;m_i, i = 1, 2, 3&amp;lt;/math&amp;gt; - номер кластера, содержащего вектор &amp;lt;math&amp;gt;x_i&amp;lt;/math&amp;gt;. Вершинами с пометкой &amp;lt;math&amp;gt;sub&amp;lt;/math&amp;gt; обозначены операции векторной разности, вершинами &amp;lt;math&amp;gt;sn&amp;lt;/math&amp;gt; - операция вычисления квадрата нормы вектора, вершинами &amp;lt;math&amp;gt;am&amp;lt;/math&amp;gt; - операция &amp;lt;math&amp;gt;\underset{i \in \{1, 2\}} {\operatorname{arg\,min}}  p_i&amp;lt;/math&amp;gt;.&lt;br /&gt;
[[file:k_means_info_graph_as.png|thumb|center|400px|Рисунок 2. Граф алгоритма для этапа распределения векторов по кластерам]]&lt;br /&gt;
&#039;&#039;&#039;Обновление центров масс кластеров.&#039;&#039;&#039; На рисунке 3 представлен информационный граф для этапа обновления центров масс кластеров. В качестве входных данных выступают строки входной матрицы (входные векторы) &amp;lt;math&amp;gt;x_1, x_2, x_3&amp;lt;/math&amp;gt; с соответствующими номерами кластеров &amp;lt;math&amp;gt;m_1, m_2, m_3&amp;lt;/math&amp;gt;, содержащих эти векторы. В качестве выходных данных здесь выступают обновленные значения центров масс кластеров: &amp;lt;math&amp;gt;\mu_1, \mu_2&amp;lt;/math&amp;gt;. Вершинами с пометками &amp;lt;math&amp;gt;s_i, i = 1, 2&amp;lt;/math&amp;gt; обозначены операции суммирования векторов, принадлежащих кластеру &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt;. Вершинами с пометками &amp;lt;math&amp;gt;cs_i, i = 1, 2&amp;lt;/math&amp;gt; обозначены операции вычисления выражения &amp;lt;math&amp;gt;1 / |S_i|&amp;lt;/math&amp;gt;, где за &amp;lt;math&amp;gt;S_i&amp;lt;/math&amp;gt; обозначен кластер с номером &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt;. Вершинами с пометкой &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt; обозначена операция произведения.&lt;br /&gt;
[[file:k_means_info_graph_up.png|thumb|center|400px|Рисунок 3. Граф алгоритма для этапа обновления центров масс кластеров]]&lt;br /&gt;
&lt;br /&gt;
=== Ресурс параллелизма алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Алгоритм кластеризации k средних имеет место массовый параллелизм: в основе каждого из основных этапов алгоритма (распределения векторов по кластерам и обновления центров масс кластеров) лежат циклы, итерации которых являются информационно независимыми.&lt;br /&gt;
Учитывая данный факт можно оценить параллельную сложность алгоритма в предположении доступности неограниченного числа необходимых процессоров.&lt;br /&gt;
&lt;br /&gt;
В силу особенностей алгоритма k средних порядок выполнения основных этапов существенен, что не позволяет выполнять их параллельно. Таким образом, итоговая сложность параллельного алгоритма будет определяться, исходя из формулы &amp;lt;math&amp;gt;T = t * (T_{as} + T_{up})&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;T_{as}&amp;lt;/math&amp;gt; - параллельная сложность этапа распределения векторов по кластерам, &amp;lt;math&amp;gt;T_{up}&amp;lt;/math&amp;gt; - параллельная сложность этапа обновления центров масс кластеров, &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt; - общее число итераций алгоритма.&lt;br /&gt;
&lt;br /&gt;
Параллельная сложность этапа распределения векторов по кластерам с учетом доступности неограниченного числа процессоров вычисляется следующим образом: так как вычисление значений &amp;lt;math&amp;gt;\big \| x_i - \mu^{(t)}_j \big \|^2&amp;lt;/math&amp;gt; для каждой пары векторов &amp;lt;math&amp;gt;x_i, i = 1, 2, ..., n&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\mu^{(t)}_j, j = 1, 2, ..., k&amp;lt;/math&amp;gt; можно выполнять независимо и для вычисления этого выражения требуется &amp;lt;math&amp;gt;O(\log d)&amp;lt;/math&amp;gt; операций в соответствии с [[Нахождение_частных_сумм_элементов_массива_сдваиванием | параллельной реализацией нахождения сумм элементов массива сдваиванием]]. Параллельная сложность реализации операции нахождения минимума из &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; элементов определяется как &amp;lt;math&amp;gt;O(\log k)&amp;lt;/math&amp;gt;. Таким образом, сложность этапа распределения векторов по кластерам &amp;lt;math&amp;gt;O(\log kd)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Параллельная сложность этапа обновления центров масс кластеров вычисляется следующим образом: так как обновление значений каждого из центров масс кластеров можно выполнять независимо, параллельная сложность определяется сложностью обновления центра масс самого большого кластера. В худшем случае для нахождения значения выражения &amp;lt;math&amp;gt;\mu^{(t+1)}_j = \frac{1}{|S^{(t)}_i|} \sum_{x_j \in S^{(t)}_i} x_j &amp;lt;/math&amp;gt; требуется &amp;lt;math&amp;gt;O(\log n)&amp;lt;/math&amp;gt; операций.&lt;br /&gt;
&lt;br /&gt;
С учетом вышесказанного, итоговая параллельная сложность алгоритма k средних определяется выражением &amp;lt;math&amp;gt;O(t * \log kdn)&amp;lt;/math&amp;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;k&amp;lt;/math&amp;gt; - количество кластеров;&lt;br /&gt;
* матрица координат векторов &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; размерностью &amp;lt;math&amp;gt;n * d&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Объем входных данных&#039;&#039;&#039;:&lt;br /&gt;
* &amp;lt;math&amp;gt;n * d&amp;lt;/math&amp;gt; вещественных чисел (если координаты вещественные числа), &amp;lt;math&amp;gt;1&amp;lt;/math&amp;gt; целое неотрицательное число.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Выходные данные&#039;&#039;&#039;:&lt;br /&gt;
* вектор длины &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; - для каждого вектора указан номер кластера.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Объем выходных данных&#039;&#039;&#039;: &lt;br /&gt;
* &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; целых неотрицательных чисел.&lt;br /&gt;
&lt;br /&gt;
=== Свойства алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Соотношение последовательной и параллельной сложности алгоритма равно &amp;lt;math&amp;gt;\frac{O(tnkd)}{O(t * \log kdn)}&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Число операций алгоритма k средних оценивается как &amp;lt;math&amp;gt;O(tnkd)&amp;lt;/math&amp;gt;, суммарный объем входных и выходных данных равен &amp;lt;math&amp;gt;n(d+1)&amp;lt;/math&amp;gt;. Следовательно, вычислительная мощность алгоритма линейна по &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; и линейна по &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Стоит отметить следующие ключевые особенности алгоритма k средних:&lt;br /&gt;
* Алгоритм прост в реализации и имеет высокую скорость работы по сравнению с другими алгоритмами кластеризации (при удачном выборе начальных значений центров масс кластеров)&lt;br /&gt;
* В качестве метрики используется евклидово расстояние, а в качестве меры разброса кластера используется дисперсия&lt;br /&gt;
* Количество кластеров k является входным параметром алгоритма, поэтому неправильный выбор этого параметра может негативно повлиять на качество кластеризации&lt;br /&gt;
* Сходимость алгоритма к локальному минимуму может породить некорректный конечный результат работы&lt;br /&gt;
* Алгоритм очень чувствителен к выбору начальных центров масс кластеров: классический вариант подразумевает случайный их выбор, что может являться источником погрешности. Из этого и предыдущего свойства следует то, что алгоритм не является устойчивым.&lt;br /&gt;
&lt;br /&gt;
Как и любой другой алгоритм кластеризации, результат работы алгоритма k средних зависит от того, удовлетворяет ли входной набор данных предположениям, на которые опираются алгоритмы кластеризации. Таким образом, на одних наборах данных алгоритм может показывать хорошие результаты, но на других выдавать некорректные результаты.&lt;br /&gt;
&lt;br /&gt;
Алгоритм не является детерминированным, в силу того, что он чувствителен к выбору начальных центров масс кластеров, который осуществляется, как правило, случайным образом и тем самым вносит различия в работу алгоритма от запуска к запуску.&lt;br /&gt;
&lt;br /&gt;
== Программная реализация алгоритма ==&lt;br /&gt;
&lt;br /&gt;
=== Особенности реализации последовательного алгоритма ===&lt;br /&gt;
&lt;br /&gt;
=== Локальность данных и вычислений ===&lt;br /&gt;
&lt;br /&gt;
=== Возможные способы и особенности параллельной реализации алгоритма ===&lt;br /&gt;
&lt;br /&gt;
=== Масштабируемость алгоритма и его реализации ===&lt;br /&gt;
Исследование масштабируемости алгоритма k-means в зависимости от количества используемых процессов было проведено в статье Кумара&amp;lt;ref&amp;gt;Kumar, J., Mills, R. T., Hoffman, F. M., &amp;amp; Hargrove, W. W. (2011). Parallel k-means clustering for quantitative ecoregion delineation using large data sets. Procedia Computer Science, 4, 1602-1611.&amp;lt;/ref&amp;gt;. Исследование происходило на суперкомпьютере Jaguar - Cray XT5&amp;lt;ref&amp;gt;https://www.top500.org/system/176029&amp;lt;/ref&amp;gt;. На момент экспериментов данный суперкомпьютер имел следующую конфигурацию: 18,688 вычислительных узлов с двумя шестнадцатиядерными процессорами AMD Opteron 2435 (Istanbul) 2.6 GHz, 16 GB of DDR2-800 оперативной памяти, и SeaStar 2+ роутер. Всего он состоял из 224,256 вычислительных ядер, 300 TB памяти, и пиковой производительностью 2.3 petaflops.&lt;br /&gt;
&lt;br /&gt;
Реализация алгоритма была выполнена на языке программирования C с использованием MPI.&lt;br /&gt;
&lt;br /&gt;
Объем данных составлял 84 гигабайта, количество объектов (d-мерных векторов) n равнялось 1,024,767,667, размерность векторов d равнялась 22, количество кластеров k равнялось 1000. &lt;br /&gt;
&lt;br /&gt;
На рисунке 4 показана зависимости времени работы алгоритма кластеризации k-means в зависимости от количества используемых процессоров. Можно отметить, что время, затраченное на чтение данных и запись результатов кластеризации, практически не изменяется с увеличением количества задействованных процессоров. Время же работы самого алгоритма кластеризации уменьшается с увеличением количества процессоров.&lt;br /&gt;
[[Файл:k-means-proc-scalability.png|thumb|center|700px|Рисунок 4. Зависимости времени работы алгоритма кластеризации k-means в зависимости от количества используемых процессоров.]]&lt;br /&gt;
&lt;br /&gt;
Также было произведено самостоятельное исследование масштабируемости алгоритма. Исследование производилось на суперкомпьютере &amp;quot;Blue Gene/P&amp;quot;&amp;lt;ref&amp;gt;http://hpc.cmc.msu.ru/bgp&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Набор и границы значений изменяемых параметров запуска реализации алгоритма:&lt;br /&gt;
&lt;br /&gt;
* число процессоров [1, 2, 4, 8, 16, 32, 64, 128, 256, 512];&lt;br /&gt;
* количество объектов [5000, 10000, 25000, 50000].&lt;br /&gt;
&lt;br /&gt;
Был использован набор данных &#039;&#039;Dataset for Sensorless Drive Diagnosis Data Set&#039;&#039;&amp;lt;ref&amp;gt;PASCHKE, Fabian ; BAYER, Christian ; BATOR, Martyna ; MÃ–NKS, Uwe ; DICKS, Alexander ; ENGE-ROSENBLATT, Olaf ; LOHWEG, Volker: Sensorlose ZustandsÃ¼berwachung an Synchronmotoren, Bd. 46. In: HOFFMANN, Frank; HÃœLLERMEIER, Eyke (Hrsg.): Proceedings 23. Workshop Computational Intelligence. Karlsruhe : KIT Scientific Publishing, 2013 (Schriftenreihe des Instituts fÃ¼r Angewandte Informatik - Automatisierungstechnik am Karlsruher Institut fÃ¼r Technologie, 46), S. 211-225&amp;lt;/ref&amp;gt; из репозитория &#039;&#039;Machine learning repository&#039;&#039;&amp;lt;ref&amp;gt;https://archive.ics.uci.edu/ml/datasets/Dataset+for+Sensorless+Drive+Diagnosis&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Исследуемый набор данных содержит векторы, размерность которых равна 49. Компоненты векторов являются вещественными числами. Количество кластеров равно 11. Пропущенные значения отсутствуют.&lt;br /&gt;
&lt;br /&gt;
Для исследования масштабируемости алгоритма была использована реализация на языке C с использованием MPI&amp;lt;ref&amp;gt;http://users.eecs.northwestern.edu/~wkliao/Kmeans/index.html&amp;lt;/ref&amp;gt;. Код можно найти здесь: https://github.com/serban/kmeans.&lt;br /&gt;
&lt;br /&gt;
На рисунке 5 показана зависимости времени работы алгоритма кластеризации k-means в зависимости от количества используемых процессоров. Можно видеть, что при увеличении количества процессоров в N раз, время работы алгоритма уменьшается примерно в N раз (при условии, что количество объектов остается неизменным). Также можно отметить, что при фиксированном количестве процессоров, зависимость времени работы алгоритма от количества объектов также близка к линейной.&lt;br /&gt;
[[Файл:Heatmap_kmeans.png|thumb|center|900px|Рисунок 5. Зависимости времени работы алгоритма кластеризации k-means в зависимости от количества используемых процессоров.]]&lt;br /&gt;
&lt;br /&gt;
На рисунке 6 показана зависимости времени работы алгоритма кластеризации k-means в зависимости от количества используемых процессоров (при фиксированном количестве объектов, равном 50000). При визуализации была использована логарифмическая шкала. Можно отметить, что при заданном наборе данных можно наблюдать линейную зависимость времени работы алгоритма от количества используемых процессоров, что согласуется с теоретической оценкой сложности последовательной версии алгоритма.&lt;br /&gt;
[[Файл:50000kmeans.png|thumb|center|900px|Рисунок 6. Зависимости времени работы алгоритма кластеризации k-means в зависимости от количества используемых процессоров (количество объектов равно 50000).]]&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-средних:&lt;br /&gt;
* [http://scikit-learn.org/ scikit-learn] библиотека машинного обучения для языка Python.&lt;br /&gt;
* [https://www.scipy.org/ SciPy] библиотека на языке Python, содержащая большое число реализаций различных алгоритмов, в том числе &#039;&#039;k&#039;&#039;-средних.&lt;br /&gt;
* [http://elki.dbs.ifi.lmu.de ELKI] библиотека для анализа данных на языке программирования Java, содержит различные алгоритмы кластеризации, в том числе &#039;&#039;k&#039;&#039;-средних.&lt;br /&gt;
* [http://mlpack.org MLPACK] библиотека машинного обучения для C++, содержит реализацию алгоритма &#039;&#039;k&#039;&#039;-средних.&lt;br /&gt;
* [https://github.com/JuliaStats/Clustering.jl Julia k-means] реализация алгоритма &#039;&#039;k&#039;&#039;-средних на языке программирования Julia.&lt;br /&gt;
* [http://opencv.org/ OpenCV] библиотека содержит реализацию &#039;&#039;k&#039;&#039;-средних.&lt;br /&gt;
* [http://mahout.apache.org Apache Mahout] содержит реализацию алгоритма &#039;&#039;k&#039;&#039;-средних на базе MapReduce.&lt;br /&gt;
* [http://www.cs.waikato.ac.nz/~ml/weka Weka] библиотека и инструмент для анализа данных на языке Java.&lt;br /&gt;
* [http://torch.ch/ Torch] библиотека машинного обучения на базе языка программирования Lua.&lt;br /&gt;
* [https://spark.apache.org/ Apache Spark MLlib] содержит распределенную реализацию алгоритма &#039;&#039;k&#039;&#039;-средних.&lt;br /&gt;
* [http://www.accord-framework.net/ Accord.NET] содержит несколько различных реализаций &#039;&#039;k&#039;&#039;-средних на языке C#.&lt;br /&gt;
* [https://www.r-bloggers.com/k-means-clustering-in-r/ R k-means] реализация &#039;&#039;k&#039;&#039;-средних на языке R.&lt;br /&gt;
&lt;br /&gt;
== Литература ==&lt;br /&gt;
&amp;lt;references \&amp;gt;&lt;/div&gt;</summary>
		<author><name>Parkhomenko</name></author>
	</entry>
	<entry>
		<id>https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A4%D0%B0%D0%B9%D0%BB:Heatmap_kmeans.png&amp;diff=18033</id>
		<title>Файл:Heatmap kmeans.png</title>
		<link rel="alternate" type="text/html" href="https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A4%D0%B0%D0%B9%D0%BB:Heatmap_kmeans.png&amp;diff=18033"/>
		<updated>2016-11-17T21:45:27Z</updated>

		<summary type="html">&lt;p&gt;Parkhomenko: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Parkhomenko</name></author>
	</entry>
	<entry>
		<id>https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A4%D0%B0%D0%B9%D0%BB:50000kmeans.png&amp;diff=18032</id>
		<title>Файл:50000kmeans.png</title>
		<link rel="alternate" type="text/html" href="https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A4%D0%B0%D0%B9%D0%BB:50000kmeans.png&amp;diff=18032"/>
		<updated>2016-11-17T21:45:01Z</updated>

		<summary type="html">&lt;p&gt;Parkhomenko: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Parkhomenko</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:Parkhomenko/%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=5643</id>
		<title>Участник:Parkhomenko/Алгоритм 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:Parkhomenko/%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=5643"/>
		<updated>2016-10-12T09:48:11Z</updated>

		<summary type="html">&lt;p&gt;Parkhomenko: /* Масштабируемость алгоритма и его реализации */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{algorithm&lt;br /&gt;
| name              = Алгоритм k средних&lt;br /&gt;
| serial_complexity = &amp;lt;math&amp;gt;O(m*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;
Основные авторы описания: [[Участник:Parkhomenko|П.А.Пархоменко]], [[Участник:Ivan.mashonskiy|И.Д.Машонский]]&lt;br /&gt;
== Свойства и структура алгоритмов ==&lt;br /&gt;
&lt;br /&gt;
=== Общее описание алгоритма ===&lt;br /&gt;
Алгоритм k средних (англ. k-means) - один из алгоритмов машинного обучения, решающий задачу кластеризации. Он был изобретен в середине 1950-х математиком Гуго Штейнгаузом&amp;lt;ref&amp;gt;Steinhaus H. (1956). Sur la division des corps materiels en parties. Bull. Acad. Polon. Sci., C1. III vol IV: 801—804.&amp;lt;/ref&amp;gt; и Стюартом Ллойдом&amp;lt;ref&amp;gt;Lloyd S. (1957). Least square quantization in PCM’s. Bell Telephone Laboratories Paper.&amp;lt;/ref&amp;gt;. Алгоритм стал особо популярным после публикации Маккуина&amp;lt;ref&amp;gt;MacQueen J. (1967). Some methods for classification and analysis of multivariate observations. In Proc. 5th Berkeley Symp. on Math. Statistics and Probability, pages 281—297.&amp;lt;/ref&amp;gt;, в которой впервые был использован термин “k-means”.&lt;br /&gt;
&lt;br /&gt;
Задача алгоритма кластеризации заключается в разбиении N объектов (d-мерных векторов) на K групп (кластеров). Каждый вектор может принадлежать только одному кластеру. Количество кластеров K фиксировано, оно задается в качестве параметра.&lt;br /&gt;
&lt;br /&gt;
K-means является итерационным алгоритмом, разновидностью EM-алгоритма. Основная идея работы алгоритма заключается в проведении некоторого количества итераций, на каждой из которых происходит пересчет центра масс для каждого кластера, полученного на предыдущей итерации. После этого векторы перераспределяются по кластерам: вектор относится к тому кластеру, расстояние до центра масс которого минимально. Алгоритм завершает работу в том случае, если на очередной итерации центры масс кластеров не изменились.&lt;br /&gt;
&lt;br /&gt;
=== Математическое описание алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Исходные данные: множество d-мерных векторов (наблюдений) &amp;lt;math&amp;gt;X&amp;lt;/math&amp;gt;&amp;amp;nbsp;=&amp;amp;nbsp;&amp;lt;math&amp;gt;\{x_1, x_2, ..., x_n\}&amp;lt;/math&amp;gt;, число кластеров &amp;lt;math&amp;gt;k \in \mathbb{N}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
В результате работы алгоритма исходное множество векторов &amp;lt;math&amp;gt;X&amp;lt;/math&amp;gt; разбивается на &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; непересекающихся множеств (кластеров) &amp;lt;math&amp;gt;S_1, S_2, ..., S_k&amp;lt;/math&amp;gt;, таких что &amp;lt;math&amp;gt;X = {\bigcup \limits _{i = 1}^k S_i} &amp;lt;/math&amp;gt; и значение &amp;lt;math&amp;gt;\sum_{i=1}^{k} \sum_{\mathbf x \in S_i} \left\| \mathbf x - \mu_i \right\|^2 &amp;lt;/math&amp;gt; — минимально для всех возможных наборов &amp;lt;math&amp;gt;S_1, S_2, ..., S_k&amp;lt;/math&amp;gt;.&lt;br /&gt;
Под &amp;lt;math&amp;gt;\mu_i&amp;lt;/math&amp;gt; здесь подразумевается центр масс векторов из множества &amp;lt;math&amp;gt;S_i&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Первоначальные значения центров масс &amp;lt;math&amp;gt;\mu_1^{(1)}, ..., \mu_k^{(1)}&amp;lt;/math&amp;gt; определяются в начале работы алгоритма случайным образом среди векторов множества &amp;lt;math&amp;gt;X&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Алгоритм заключается в попеременном применении двух шагов: &#039;&#039;&#039;распределения&#039;&#039;&#039; векторов по кластерам и &#039;&#039;&#039;обновления&#039;&#039;&#039; центров масс каждого кластера&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Распределение векторов по кластерам&#039;&#039;&#039;: на данном шаге каждый вектор распределяется в один из кластеров &amp;lt;math&amp;gt;S_i^{(t)}&amp;lt;/math&amp;gt;: &lt;br /&gt;
::&amp;lt;math&amp;gt;S_i^{(t)} = \big \{ x_p : \big \| x_p - \mu^{(t)}_i \big \|^2 \le \big \| x_p - \mu^{(t)}_j \big \|^2 \ \forall j, 1 \le j \le k \big\},&amp;lt;/math&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Обновление центров масс&#039;&#039;&#039;: на данном шаге вычисляются новые центры масс для кластеров, полученных на предыдущем шаге.&lt;br /&gt;
::&amp;lt;math&amp;gt;\mu^{(t+1)}_i = \frac{1}{|S^{(t)}_i|} \sum_{x_j \in S^{(t)}_i} x_j &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Алгоритм завершается, когда на очередном шаге не происходит изменения центров масс кластеров.&lt;br /&gt;
&lt;br /&gt;
=== Вычислительное ядро алгоритма ===&lt;br /&gt;
Вычислительное ядро последовательного алгоритма k-means состоит из двух операций, повторяющихся на каждой итерации алгоритма:&lt;br /&gt;
* пересчета центров масс кластеров;&lt;br /&gt;
* соотнесения каждого вектора к одному из кластеров.&lt;br /&gt;
&lt;br /&gt;
Пересчет центра масс кластера заключается в нахождении d-мерного вектора, являющегося средним арифметическим d-мерных векторов, принадлежащих кластеру. Эту операцию необходимо выполнять для каждого из K кластеров.&lt;br /&gt;
&lt;br /&gt;
Для соотнесения вектора к одному из кластеров, необходимо для каждого из N вектора посчитать расстояние до центров масс всех K кластеров. Для нахождения расстояния между двумя d-мерными векторами p и q используется Евклидова метрика: &amp;lt;math&amp;gt;\sqrt{\sum_{k=1}^d (p_k-q_k)^2}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Макроструктура алгоритма ===&lt;br /&gt;
&lt;br /&gt;
В начале алгоритма осуществляется инициализация центров масс &amp;lt;math&amp;gt;\mu_1^{(1)}, ..., \mu_k^{(1)}&amp;lt;/math&amp;gt;, которая может быть реализована двумя возможными способами: &lt;br /&gt;
* случайный выбор центров масс среди исходных наблюдений &amp;lt;math&amp;gt;x_1, x_2, ..., x_n&amp;lt;/math&amp;gt;;&lt;br /&gt;
* все наблюдения случайным образом распределяются по кластерам &amp;lt;math&amp;gt;S_1, S_2, ..., S_k&amp;lt;/math&amp;gt;, а затем для каждого кластера выполняется операция обновления центра масс.&lt;br /&gt;
&lt;br /&gt;
На шаге распределения векторов по кластерам производится операция нахождения квадратов расстояний между векторами кластера и центром масс кластера: &lt;br /&gt;
::&amp;lt;math&amp;gt;\rho = \big \| x_p - \mu^{(t)}_i \big \|^2&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
На шаге обновления центров масс производится операция суммирования векторов кластера:&lt;br /&gt;
::&amp;lt;math&amp;gt;\mu^{(t+1)}_i = \frac{1}{|S^{(t)}_i|} \sum_{x_j \in S^{(t)}_i} x_j &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Схема реализации последовательного алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Последовательность исполнения метода следующая:&lt;br /&gt;
# Инициализируются центры масс &amp;lt;math&amp;gt;\mu_1^{(1)}, ..., \mu_k^{(1)}&amp;lt;/math&amp;gt;&lt;br /&gt;
# &amp;lt;math&amp;gt;t := 1&amp;lt;/math&amp;gt;&lt;br /&gt;
# Для каждого вектора &amp;lt;math&amp;gt;x_i, i = 1, 2, ..., n&amp;lt;/math&amp;gt; вычисляется &amp;lt;br/&amp;gt;&amp;lt;math&amp;gt;m = \underset{j \in \{1, 2, ..., k\}} {\operatorname{arg\,min}} \big \| x_i - \mu^{(t)}_j \big \|^2&amp;lt;/math&amp;gt;, &amp;lt;br/&amp;gt;вектор &amp;lt;math&amp;gt;x_i&amp;lt;/math&amp;gt; распределяется в кластер &amp;lt;math&amp;gt;S^{(t)}_m&amp;lt;/math&amp;gt;&lt;br /&gt;
# Для каждого &amp;lt;math&amp;gt;j = 1, 2, ..., k&amp;lt;/math&amp;gt; вычисляется &amp;lt;br/&amp;gt;&amp;lt;math&amp;gt;\mu^{(t+1)}_j = \frac{1}{|S^{(t)}_i|} \sum_{x_j \in S^{(t)}_i} x_j &amp;lt;/math&amp;gt;&lt;br /&gt;
#  Если &amp;lt;math&amp;gt;\mu^{(t)}_j = \mu^{(t+1)}_j, j = 1, 2, ..., k&amp;lt;/math&amp;gt;, завершить выполнение алгоритма, иначе &amp;lt;math&amp;gt;t := t + 1&amp;lt;/math&amp;gt;, переход на шаг 3.&lt;br /&gt;
&lt;br /&gt;
=== Последовательная сложность алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Для вычисления центра массы кластера, содержащего &amp;lt;math&amp;gt;n_i&amp;lt;/math&amp;gt; d-мерных векторов, необходимо:&lt;br /&gt;
* &amp;lt;math&amp;gt;n_i * (d - 1)&amp;lt;/math&amp;gt; операций сложения&lt;br /&gt;
* &amp;lt;math&amp;gt;d&amp;lt;/math&amp;gt; операций деления&lt;br /&gt;
&lt;br /&gt;
Для определения центров масс всех k кластеров требуется:&lt;br /&gt;
* &amp;lt;math&amp;gt;n * (d - 1)&amp;lt;/math&amp;gt; операций сложения&lt;br /&gt;
* &amp;lt;math&amp;gt;k * d&amp;lt;/math&amp;gt; операций деления&lt;br /&gt;
&lt;br /&gt;
Для определения расстояния между двумя d-мерными векторами, требуется:&lt;br /&gt;
* &amp;lt;math&amp;gt;d&amp;lt;/math&amp;gt; операций вычитания&lt;br /&gt;
* &amp;lt;math&amp;gt;d&amp;lt;/math&amp;gt; операций умножения&lt;br /&gt;
* &amp;lt;math&amp;gt;d - 1&amp;lt;/math&amp;gt; операций сложения&lt;br /&gt;
&lt;br /&gt;
Для определения кластера для n d-мерного векторов, необходимо:&lt;br /&gt;
* &amp;lt;math&amp;gt;n * k * d&amp;lt;/math&amp;gt; операций вычитания&lt;br /&gt;
* &amp;lt;math&amp;gt;n * k * d&amp;lt;/math&amp;gt; операций умножения&lt;br /&gt;
* &amp;lt;math&amp;gt;n * k * (d - 1)&amp;lt;/math&amp;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; операций умножения/деления&lt;br /&gt;
&lt;br /&gt;
Сложность всего алгоритма, состоящего из m итераций: &amp;lt;math&amp;gt;O(m * n * k * d)&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Информационный граф ===&lt;br /&gt;
&lt;br /&gt;
В данном разделе описывается информационный граф алгоритма k-средних при &amp;lt;math&amp;gt;n = 3, k = 2&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
На рисунке 1 показана общая структура алгоритма: в качестве входных данных выступает матрица, строками которой являются входные векторы &amp;lt;math&amp;gt;x_1, x_2, x_3&amp;lt;/math&amp;gt;, на выходе получается массив из &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; чисел, где элемент с номером &amp;lt;math&amp;gt;i = 1, 2, 3&amp;lt;/math&amp;gt; обозначает номер кластера, которому принадлежит вектор &amp;lt;math&amp;gt;x_i&amp;lt;/math&amp;gt;. На шаге &amp;lt;math&amp;gt;init&amp;lt;/math&amp;gt; происходит инициализация значений центров масс кластеров, после этого осуществляется итеративное повторение этапов распределения векторов по кластерам (&amp;lt;math&amp;gt;as&amp;lt;/math&amp;gt;) и обновления значений центров масс кластеров (&amp;lt;math&amp;gt;up&amp;lt;/math&amp;gt;).&lt;br /&gt;
[[file:k_means_schema.svg|thumb|center||Рисунок 1. Общая схема работы алгоритма k-средних]]&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Распределение векторов по кластерам.&#039;&#039;&#039; На рисунке 2 изображен информационный граф для этапа распределения векторов по кластерам. В качестве входных данных выступают строки входной матрицы (входные векторы) &amp;lt;math&amp;gt;x_1, x_2, x_3&amp;lt;/math&amp;gt; и текущие значения центров масс кластеров &amp;lt;math&amp;gt;\mu_1, \mu_2&amp;lt;/math&amp;gt; (вычисленные на этапе инициализации или предшествующего этапа обновления центров масс кластеров). В качестве выходных данных выступают числа &amp;lt;math&amp;gt;m_1, m_2, m_3&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;m_i, i = 1, 2, 3&amp;lt;/math&amp;gt; - номер кластера, содержащего вектор &amp;lt;math&amp;gt;x_i&amp;lt;/math&amp;gt;. Вершинами с пометкой &amp;lt;math&amp;gt;sub&amp;lt;/math&amp;gt; обозначены операции векторной разности, врешинами &amp;lt;math&amp;gt;sn&amp;lt;/math&amp;gt; - операция вычисления квадрата нормы вектора, вершинами &amp;lt;math&amp;gt;am&amp;lt;/math&amp;gt; - операция &amp;lt;math&amp;gt;\underset{i \in \{1, 2\}} {\operatorname{arg\,min}}  p_i&amp;lt;/math&amp;gt;.&lt;br /&gt;
[[file:k_means_info_graph_as.svg|thumb|center||Рисунок 2. Граф алгоритма для этапа распределения векторов по кластерам]]&lt;br /&gt;
&#039;&#039;&#039;Обновление центро масс кластеров.&#039;&#039;&#039; На рисунке 3 представлен информационный граф для этапа обновления центров масс кластеров. В качестве входных данных выступают строки входной матрицы (входные векторы) &amp;lt;math&amp;gt;x_1, x_2, x_3&amp;lt;/math&amp;gt; с соответствующими номерами кластеров &amp;lt;math&amp;gt;m_1, m_2, m_3&amp;lt;/math&amp;gt;, содержащих эти векторы. В качестве выходных данных здесь выступают обновленные значения центров масс кластеров: &amp;lt;math&amp;gt;\mu_1, \mu_2&amp;lt;/math&amp;gt;. Вершинами с пометками &amp;lt;math&amp;gt;s_i, i = 1, 2&amp;lt;/math&amp;gt; обозначены операции суммирования векторов, принадлежащих кластеру &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt;. Вершинами с пометками &amp;lt;math&amp;gt;cs_i, i = 1, 2&amp;lt;/math&amp;gt; обозначены операции вычисления выражения &amp;lt;math&amp;gt;1 / |S_i|&amp;lt;/math&amp;gt;, где за &amp;lt;math&amp;gt;S_i&amp;lt;/math&amp;gt; обозначен кластер с номером &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt;. Вершинами с пометкой &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt; обозначена операция произведения.&lt;br /&gt;
[[file:k_means_info_graph_up.svg|thumb|center||Рисунок 3. Граф алгоритма для этапа обновления центров масс кластеров]]&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;
* целое неотрицательное число &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; - количество кластеров;&lt;br /&gt;
* матрица координат векторов &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; размерностью &amp;lt;math&amp;gt;n * d&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Объем входных данных&#039;&#039;&#039;:&lt;br /&gt;
* &amp;lt;math&amp;gt;n * d&amp;lt;/math&amp;gt; вещественных чисел (если координаты вещественные числа), &amp;lt;math&amp;gt;1&amp;lt;/math&amp;gt; целое неотрицательное число.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Выходные данные&#039;&#039;&#039;:&lt;br /&gt;
* вектор длины &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; - для каждого вектора указан номер кластера.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Объем выходных данных&#039;&#039;&#039;: &lt;br /&gt;
* &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; целых неотрицательных чисел.&lt;br /&gt;
&lt;br /&gt;
=== Свойства алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Стоит отметить следующие ключевые особенности алгоритма k средних:&lt;br /&gt;
* Алгоритм прост в реализации и имеет высокую скорость работы по сравнению с другими алгоритмами кластеризации (при удачном выборе начальных значений центров масс кластеров)&lt;br /&gt;
* В качестве метрики используется евклидово расстояние, а в качестве меры разброса кластера используется дисперсия&lt;br /&gt;
* Количество кластеров k является входным параметром алгоритма, поэтому неправильный выбор этого параметра может негативно повлиять на качество кластеризации&lt;br /&gt;
* Сходимость алгоритма к локальному минимуму может породить некорректный конечный результат работы&lt;br /&gt;
* Алгоритм очень чувствителен к выбору начальных центров масс кластеров: классический вариант подразумевает случайный их выбор, что может являться источником погрешности. Из этого и предыдущего свойства следует то, что алгоритм не является устойчивым.&lt;br /&gt;
&lt;br /&gt;
Как и любой другой алгоритм кластеризации, результат работы алгоритма k средних зависит от того, удовлетворяет ли входной набор данных предположениям, на которые опираются алгоритмы кластеризации. Таким образом, на одних наборах данных алгоритм может показывать хорошие результаты, но на других выдавать некорректные результаты.&lt;br /&gt;
&lt;br /&gt;
Алгоритм не является детерминированным, в силу того, что он чувствителен к выбору начальных центров масс кластеров, который осуществляется, как правило, случайным образом и тем самым вносит различия в работу алгоритма от запуска к запуску.&lt;br /&gt;
&lt;br /&gt;
== Программная реализация алгоритма ==&lt;br /&gt;
&lt;br /&gt;
=== Особенности реализации последовательного алгоритма ===&lt;br /&gt;
&lt;br /&gt;
=== Локальность данных и вычислений ===&lt;br /&gt;
&lt;br /&gt;
=== Возможные способы и особенности параллельной реализации алгоритма ===&lt;br /&gt;
&lt;br /&gt;
=== Масштабируемость алгоритма и его реализации ===&lt;br /&gt;
Исследование масштабируемости алгоритма k-means в зависимости от количества используемых процессов было проведено в статье Кумара&amp;lt;ref&amp;gt;Kumar J. et al. Parallel k-means clustering for quantitative ecoregion delineation using large data sets //Procedia Computer Science. – 2011. – Т. 4. – С. 1602-1611.&amp;lt;/ref&amp;gt;. Исследование происходило на суперкомпьютере Jaguar - Cray XT5&amp;lt;ref&amp;gt;https://www.top500.org/system/176029&amp;lt;/ref&amp;gt;. На момент экспериментов данный суперкомпьютер имел следующую конфигурацию: 18,688 вычислительных узлов с двумя шестнадцатиядерными процессорами AMD Opteron 2435 (Istanbul) 2.6 GHz, 16 GB of DDR2-800 оперативной памяти, и SeaStar 2+ роутер. Всего он состоял из 224,256 вычислительных ядер, 300 TB памяти, и пиковой производительностью 2.3 petaflops.&lt;br /&gt;
&lt;br /&gt;
Реализация алгоритма была выполнена на языке программирования C с использованием MPI.&lt;br /&gt;
&lt;br /&gt;
Объем данных составлял 84 гигабайта, количество объектов (m-мерных векторов) n равнялось 1,024,767,667, размерность векторов m равнялось 22, количество кластеров k равнялось 1000. &lt;br /&gt;
&lt;br /&gt;
На рисунке 4 показана зависимости времени работы алгоритма кластеризации k-means в зависимости от количества используемых процессоров. Можно отметить, что время, затраченное на чтение данных и запись результатов кластеризации, практически не изменяется с увеличением количества задействованных процессоров. Время же работы самого алгоритма кластеризации уменьшается с увеличением количества процессоров.&lt;br /&gt;
[[Файл:k-means-proc-scalability.png|thumb|center|700px|Рисунок 4. Зависимости времени работы алгоритма кластеризации k-means в зависимости от количества используемых процессоров.]]&lt;br /&gt;
&lt;br /&gt;
Ниже представлены результаты исследования времени работы алгоритма k-means в зависимости от количества кластеров k и количества векторов n. Для исследования использовалась реализация k-means на языке программирования C (с использованием OpenMP). Тестирование происходило на 8 процессорах. Затраченное время считалось как среднее арифметическое 5 запусков алгоритма.&lt;br /&gt;
&lt;br /&gt;
На рисунке 5 показана зависимость времени работы алгоритма от количества кластеров k. Количество векторов n равно 100000.&lt;br /&gt;
[[Файл:K-means-k.png|thumb|center|700px|Рисунок 5. Зависимости времени работы алгоритма кластеризации k-means в зависимости от количества кластеров k.]]&lt;br /&gt;
&lt;br /&gt;
На рисунке 6 показана зависимость времени работы алгоритма от количества векторов n. Количество кластеров k равно 160.&lt;br /&gt;
[[Файл:K-means-n.png|thumb|center|700px|Рисунок 6. Зависимости времени работы алгоритма кластеризации k-means в зависимости от количества векторов n.]]&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-средних:&lt;br /&gt;
* [http://scikit-learn.org/ scikit-learn] библиотека машинного обучения для языка Python.&lt;br /&gt;
* [https://www.scipy.org/ SciPy] библиотека на языке Python, содержащая большое число реализаций различных алгоритмов, в том числе &#039;&#039;k&#039;&#039;-средних.&lt;br /&gt;
* [http://elki.dbs.ifi.lmu.de ELKI] библиотека для анализа данных на языке программирования Java, содержит различные алгоритмы кластеризации, в том числе &#039;&#039;k&#039;&#039;-средних.&lt;br /&gt;
* [http://mlpack.org MLPACK] библиотека машинного обучения для C++, содержит реализацию алгоритма &#039;&#039;k&#039;&#039;-средних.&lt;br /&gt;
* [https://github.com/JuliaStats/Clustering.jl Julia k-means] реализация алгоритма &#039;&#039;k&#039;&#039;-средних на языке программирования Julia.&lt;br /&gt;
* [http://opencv.org/ OpenCV] библиотека содержит реализацию &#039;&#039;k&#039;&#039;-средних.&lt;br /&gt;
* [http://mahout.apache.org Apache Mahout] содержит реализацию алгоритма &#039;&#039;k&#039;&#039;-средних на базе MapReduce.&lt;br /&gt;
* [http://www.cs.waikato.ac.nz/~ml/weka Weka] библиотека и инструмент для анализа данных на языке Java.&lt;br /&gt;
* [http://torch.ch/ Torch] библиотека машинного обучения на базе языка программирования Lua.&lt;br /&gt;
* [https://spark.apache.org/ Apache Spark MLlib] содержит распределенную реализацию алгоритма &#039;&#039;k&#039;&#039;-средних.&lt;br /&gt;
* [http://www.accord-framework.net/ Accord.NET] содержит несколько различных реализаций &#039;&#039;k&#039;&#039;-средних на языке C#.&lt;br /&gt;
* [https://www.r-bloggers.com/k-means-clustering-in-r/ R k-means] реализация &#039;&#039;k&#039;&#039;-средних на языке R.&lt;br /&gt;
&lt;br /&gt;
== Литература ==&lt;br /&gt;
&amp;lt;references \&amp;gt;&lt;/div&gt;</summary>
		<author><name>Parkhomenko</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:Parkhomenko/%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=5640</id>
		<title>Участник:Parkhomenko/Алгоритм 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:Parkhomenko/%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=5640"/>
		<updated>2016-10-12T09:45:29Z</updated>

		<summary type="html">&lt;p&gt;Parkhomenko: /* Масштабируемость алгоритма и его реализации */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{algorithm&lt;br /&gt;
| name              = Алгоритм k средних&lt;br /&gt;
| serial_complexity = &amp;lt;math&amp;gt;O(m*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;
Основные авторы описания: [[Участник:Parkhomenko|П.А.Пархоменко]], [[Участник:Ivan.mashonskiy|И.Д.Машонский]]&lt;br /&gt;
== Свойства и структура алгоритмов ==&lt;br /&gt;
&lt;br /&gt;
=== Общее описание алгоритма ===&lt;br /&gt;
Алгоритм k средних (англ. k-means) - один из алгоритмов машинного обучения, решающий задачу кластеризации. Он был изобретен в середине 1950-х математиком Гуго Штейнгаузом&amp;lt;ref&amp;gt;Steinhaus H. (1956). Sur la division des corps materiels en parties. Bull. Acad. Polon. Sci., C1. III vol IV: 801—804.&amp;lt;/ref&amp;gt; и Стюартом Ллойдом&amp;lt;ref&amp;gt;Lloyd S. (1957). Least square quantization in PCM’s. Bell Telephone Laboratories Paper.&amp;lt;/ref&amp;gt;. Алгоритм стал особо популярным после публикации Маккуина&amp;lt;ref&amp;gt;MacQueen J. (1967). Some methods for classification and analysis of multivariate observations. In Proc. 5th Berkeley Symp. on Math. Statistics and Probability, pages 281—297.&amp;lt;/ref&amp;gt;, в которой впервые был использован термин “k-means”.&lt;br /&gt;
&lt;br /&gt;
Задача алгоритма кластеризации заключается в разбиении N объектов (d-мерных векторов) на K групп (кластеров). Каждый вектор может принадлежать только одному кластеру. Количество кластеров K фиксировано, оно задается в качестве параметра.&lt;br /&gt;
&lt;br /&gt;
K-means является итерационным алгоритмом, разновидностью EM-алгоритма. Основная идея работы алгоритма заключается в проведении некоторого количества итераций, на каждой из которых происходит пересчет центра масс для каждого кластера, полученного на предыдущей итерации. После этого векторы перераспределяются по кластерам: вектор относится к тому кластеру, расстояние до центра масс которого минимально. Алгоритм завершает работу в том случае, если на очередной итерации центры масс кластеров не изменились.&lt;br /&gt;
&lt;br /&gt;
=== Математическое описание алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Исходные данные: множество d-мерных векторов (наблюдений) &amp;lt;math&amp;gt;X&amp;lt;/math&amp;gt;&amp;amp;nbsp;=&amp;amp;nbsp;&amp;lt;math&amp;gt;\{x_1, x_2, ..., x_n\}&amp;lt;/math&amp;gt;, число кластеров &amp;lt;math&amp;gt;k \in \mathbb{N}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
В результате работы алгоритма исходное множество векторов &amp;lt;math&amp;gt;X&amp;lt;/math&amp;gt; разбивается на &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; непересекающихся множеств (кластеров) &amp;lt;math&amp;gt;S_1, S_2, ..., S_k&amp;lt;/math&amp;gt;, таких что &amp;lt;math&amp;gt;X = {\bigcup \limits _{i = 1}^k S_i} &amp;lt;/math&amp;gt; и значение &amp;lt;math&amp;gt;\sum_{i=1}^{k} \sum_{\mathbf x \in S_i} \left\| \mathbf x - \mu_i \right\|^2 &amp;lt;/math&amp;gt; — минимально для всех возможных наборов &amp;lt;math&amp;gt;S_1, S_2, ..., S_k&amp;lt;/math&amp;gt;.&lt;br /&gt;
Под &amp;lt;math&amp;gt;\mu_i&amp;lt;/math&amp;gt; здесь подразумевается центр масс векторов из множества &amp;lt;math&amp;gt;S_i&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Первоначальные значения центров масс &amp;lt;math&amp;gt;\mu_1^{(1)}, ..., \mu_k^{(1)}&amp;lt;/math&amp;gt; определяются в начале работы алгоритма случайным образом среди векторов множества &amp;lt;math&amp;gt;X&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Алгоритм заключается в попеременном применении двух шагов: &#039;&#039;&#039;распределения&#039;&#039;&#039; векторов по кластерам и &#039;&#039;&#039;обновления&#039;&#039;&#039; центров масс каждого кластера&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Распределение векторов по кластерам&#039;&#039;&#039;: на данном шаге каждый вектор распределяется в один из кластеров &amp;lt;math&amp;gt;S_i^{(t)}&amp;lt;/math&amp;gt;: &lt;br /&gt;
::&amp;lt;math&amp;gt;S_i^{(t)} = \big \{ x_p : \big \| x_p - \mu^{(t)}_i \big \|^2 \le \big \| x_p - \mu^{(t)}_j \big \|^2 \ \forall j, 1 \le j \le k \big\},&amp;lt;/math&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Обновление центров масс&#039;&#039;&#039;: на данном шаге вычисляются новые центры масс для кластеров, полученных на предыдущем шаге.&lt;br /&gt;
::&amp;lt;math&amp;gt;\mu^{(t+1)}_i = \frac{1}{|S^{(t)}_i|} \sum_{x_j \in S^{(t)}_i} x_j &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Алгоритм завершается, когда на очередном шаге не происходит изменения центров масс кластеров.&lt;br /&gt;
&lt;br /&gt;
=== Вычислительное ядро алгоритма ===&lt;br /&gt;
Вычислительное ядро последовательного алгоритма k-means состоит из двух операций, повторяющихся на каждой итерации алгоритма:&lt;br /&gt;
* пересчета центров масс кластеров;&lt;br /&gt;
* соотнесения каждого вектора к одному из кластеров.&lt;br /&gt;
&lt;br /&gt;
Пересчет центра масс кластера заключается в нахождении d-мерного вектора, являющегося средним арифметическим d-мерных векторов, принадлежащих кластеру. Эту операцию необходимо выполнять для каждого из K кластеров.&lt;br /&gt;
&lt;br /&gt;
Для соотнесения вектора к одному из кластеров, необходимо для каждого из N вектора посчитать расстояние до центров масс всех K кластеров. Для нахождения расстояния между двумя d-мерными векторами p и q используется Евклидова метрика: &amp;lt;math&amp;gt;\sqrt{\sum_{k=1}^d (p_k-q_k)^2}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Макроструктура алгоритма ===&lt;br /&gt;
&lt;br /&gt;
В начале алгоритма осуществляется инициализация центров масс &amp;lt;math&amp;gt;\mu_1^{(1)}, ..., \mu_k^{(1)}&amp;lt;/math&amp;gt;, которая может быть реализована двумя возможными способами: &lt;br /&gt;
* случайный выбор центров масс среди исходных наблюдений &amp;lt;math&amp;gt;x_1, x_2, ..., x_n&amp;lt;/math&amp;gt;;&lt;br /&gt;
* все наблюдения случайным образом распределяются по кластерам &amp;lt;math&amp;gt;S_1, S_2, ..., S_k&amp;lt;/math&amp;gt;, а затем для каждого кластера выполняется операция обновления центра масс.&lt;br /&gt;
&lt;br /&gt;
На шаге распределения векторов по кластерам производится операция нахождения квадратов расстояний между векторами кластера и центром масс кластера: &lt;br /&gt;
::&amp;lt;math&amp;gt;\rho = \big \| x_p - \mu^{(t)}_i \big \|^2&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
На шаге обновления центров масс производится операция суммирования векторов кластера:&lt;br /&gt;
::&amp;lt;math&amp;gt;\mu^{(t+1)}_i = \frac{1}{|S^{(t)}_i|} \sum_{x_j \in S^{(t)}_i} x_j &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Схема реализации последовательного алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Последовательность исполнения метода следующая:&lt;br /&gt;
# Инициализируются центры масс &amp;lt;math&amp;gt;\mu_1^{(1)}, ..., \mu_k^{(1)}&amp;lt;/math&amp;gt;&lt;br /&gt;
# &amp;lt;math&amp;gt;t := 1&amp;lt;/math&amp;gt;&lt;br /&gt;
# Для каждого вектора &amp;lt;math&amp;gt;x_i, i = 1, 2, ..., n&amp;lt;/math&amp;gt; вычисляется &amp;lt;br/&amp;gt;&amp;lt;math&amp;gt;m = \underset{j \in \{1, 2, ..., k\}} {\operatorname{arg\,min}} \big \| x_i - \mu^{(t)}_j \big \|^2&amp;lt;/math&amp;gt;, &amp;lt;br/&amp;gt;вектор &amp;lt;math&amp;gt;x_i&amp;lt;/math&amp;gt; распределяется в кластер &amp;lt;math&amp;gt;S^{(t)}_m&amp;lt;/math&amp;gt;&lt;br /&gt;
# Для каждого &amp;lt;math&amp;gt;j = 1, 2, ..., k&amp;lt;/math&amp;gt; вычисляется &amp;lt;br/&amp;gt;&amp;lt;math&amp;gt;\mu^{(t+1)}_j = \frac{1}{|S^{(t)}_i|} \sum_{x_j \in S^{(t)}_i} x_j &amp;lt;/math&amp;gt;&lt;br /&gt;
#  Если &amp;lt;math&amp;gt;\mu^{(t)}_j = \mu^{(t+1)}_j, j = 1, 2, ..., k&amp;lt;/math&amp;gt;, завершить выполнение алгоритма, иначе &amp;lt;math&amp;gt;t := t + 1&amp;lt;/math&amp;gt;, переход на шаг 3.&lt;br /&gt;
&lt;br /&gt;
=== Последовательная сложность алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Для вычисления центра массы кластера, содержащего &amp;lt;math&amp;gt;n_i&amp;lt;/math&amp;gt; d-мерных векторов, необходимо:&lt;br /&gt;
* &amp;lt;math&amp;gt;n_i * (d - 1)&amp;lt;/math&amp;gt; операций сложения&lt;br /&gt;
* &amp;lt;math&amp;gt;d&amp;lt;/math&amp;gt; операций деления&lt;br /&gt;
&lt;br /&gt;
Для определения центров масс всех k кластеров требуется:&lt;br /&gt;
* &amp;lt;math&amp;gt;n * (d - 1)&amp;lt;/math&amp;gt; операций сложения&lt;br /&gt;
* &amp;lt;math&amp;gt;k * d&amp;lt;/math&amp;gt; операций деления&lt;br /&gt;
&lt;br /&gt;
Для определения расстояния между двумя d-мерными векторами, требуется:&lt;br /&gt;
* &amp;lt;math&amp;gt;d&amp;lt;/math&amp;gt; операций вычитания&lt;br /&gt;
* &amp;lt;math&amp;gt;d&amp;lt;/math&amp;gt; операций умножения&lt;br /&gt;
* &amp;lt;math&amp;gt;d - 1&amp;lt;/math&amp;gt; операций сложения&lt;br /&gt;
&lt;br /&gt;
Для определения кластера для n d-мерного векторов, необходимо:&lt;br /&gt;
* &amp;lt;math&amp;gt;n * k * d&amp;lt;/math&amp;gt; операций вычитания&lt;br /&gt;
* &amp;lt;math&amp;gt;n * k * d&amp;lt;/math&amp;gt; операций умножения&lt;br /&gt;
* &amp;lt;math&amp;gt;n * k * (d - 1)&amp;lt;/math&amp;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; операций умножения/деления&lt;br /&gt;
&lt;br /&gt;
Сложность всего алгоритма, состоящего из m итераций: &amp;lt;math&amp;gt;O(m * n * k * d)&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Информационный граф ===&lt;br /&gt;
&lt;br /&gt;
В данном разделе описывается информационный граф алгоритма k-средних при &amp;lt;math&amp;gt;n = 3, k = 2&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
На рисунке 1 показана общая структура алгоритма: в качестве входных данных выступает матрица, строками которой являются входные векторы &amp;lt;math&amp;gt;x_1, x_2, x_3&amp;lt;/math&amp;gt;, на выходе получается массив из &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; чисел, где элемент с номером &amp;lt;math&amp;gt;i = 1, 2, 3&amp;lt;/math&amp;gt; обозначает номер кластера, которому принадлежит вектор &amp;lt;math&amp;gt;x_i&amp;lt;/math&amp;gt;. На шаге &amp;lt;math&amp;gt;init&amp;lt;/math&amp;gt; происходит инициализация значений центров масс кластеров, после этого осуществляется итеративное повторение этапов распределения векторов по кластерам (&amp;lt;math&amp;gt;as&amp;lt;/math&amp;gt;) и обновления значений центров масс кластеров (&amp;lt;math&amp;gt;up&amp;lt;/math&amp;gt;).&lt;br /&gt;
[[file:k_means_schema.svg|thumb|center||Рисунок 1. Общая схема работы алгоритма k-средних]]&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Распределение векторов по кластерам.&#039;&#039;&#039; На рисунке 2 изображен информационный граф для этапа распределения векторов по кластерам. В качестве входных данных выступают строки входной матрицы (входные векторы) &amp;lt;math&amp;gt;x_1, x_2, x_3&amp;lt;/math&amp;gt; и текущие значения центров масс кластеров &amp;lt;math&amp;gt;\mu_1, \mu_2&amp;lt;/math&amp;gt; (вычисленные на этапе инициализации или предшествующего этапа обновления центров масс кластеров). В качестве выходных данных выступают числа &amp;lt;math&amp;gt;m_1, m_2, m_3&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;m_i, i = 1, 2, 3&amp;lt;/math&amp;gt; - номер кластера, содержащего вектор &amp;lt;math&amp;gt;x_i&amp;lt;/math&amp;gt;. Вершинами с пометкой &amp;lt;math&amp;gt;sub&amp;lt;/math&amp;gt; обозначены операции векторной разности, врешинами &amp;lt;math&amp;gt;sn&amp;lt;/math&amp;gt; - операция вычисления квадрата нормы вектора, вершинами &amp;lt;math&amp;gt;am&amp;lt;/math&amp;gt; - операция &amp;lt;math&amp;gt;\underset{i \in \{1, 2\}} {\operatorname{arg\,min}}  p_i&amp;lt;/math&amp;gt;.&lt;br /&gt;
[[file:k_means_info_graph_as.svg|thumb|center||Рисунок 2. Граф алгоритма для этапа распределения векторов по кластерам]]&lt;br /&gt;
&#039;&#039;&#039;Обновление центро масс кластеров.&#039;&#039;&#039; На рисунке 3 представлен информационный граф для этапа обновления центров масс кластеров. В качестве входных данных выступают строки входной матрицы (входные векторы) &amp;lt;math&amp;gt;x_1, x_2, x_3&amp;lt;/math&amp;gt; с соответствующими номерами кластеров &amp;lt;math&amp;gt;m_1, m_2, m_3&amp;lt;/math&amp;gt;, содержащих эти векторы. В качестве выходных данных здесь выступают обновленные значения центров масс кластеров: &amp;lt;math&amp;gt;\mu_1, \mu_2&amp;lt;/math&amp;gt;. Вершинами с пометками &amp;lt;math&amp;gt;s_i, i = 1, 2&amp;lt;/math&amp;gt; обозначены операции суммирования векторов, принадлежащих кластеру &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt;. Вершинами с пометками &amp;lt;math&amp;gt;cs_i, i = 1, 2&amp;lt;/math&amp;gt; обозначены операции вычисления выражения &amp;lt;math&amp;gt;1 / |S_i|&amp;lt;/math&amp;gt;, где за &amp;lt;math&amp;gt;S_i&amp;lt;/math&amp;gt; обозначен кластер с номером &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt;. Вершинами с пометкой &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt; обозначена операция произведения.&lt;br /&gt;
[[file:k_means_info_graph_up.svg|thumb|center||Рисунок 3. Граф алгоритма для этапа обновления центров масс кластеров]]&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;
* целое неотрицательное число &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; - количество кластеров;&lt;br /&gt;
* матрица координат векторов &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; размерностью &amp;lt;math&amp;gt;n * d&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Объем входных данных&#039;&#039;&#039;:&lt;br /&gt;
* &amp;lt;math&amp;gt;n * d&amp;lt;/math&amp;gt; вещественных чисел (если координаты вещественные числа), &amp;lt;math&amp;gt;1&amp;lt;/math&amp;gt; целое неотрицательное число.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Выходные данные&#039;&#039;&#039;:&lt;br /&gt;
* вектор длины &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; - для каждого вектора указан номер кластера.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Объем выходных данных&#039;&#039;&#039;: &lt;br /&gt;
* &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; целых неотрицательных чисел.&lt;br /&gt;
&lt;br /&gt;
=== Свойства алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Стоит отметить следующие ключевые особенности алгоритма k средних:&lt;br /&gt;
* Алгоритм прост в реализации и имеет высокую скорость работы по сравнению с другими алгоритмами кластеризации (при удачном выборе начальных значений центров масс кластеров)&lt;br /&gt;
* В качестве метрики используется евклидово расстояние, а в качестве меры разброса кластера используется дисперсия&lt;br /&gt;
* Количество кластеров k является входным параметром алгоритма, поэтому неправильный выбор этого параметра может негативно повлиять на качество кластеризации&lt;br /&gt;
* Сходимость алгоритма к локальному минимуму может породить некорректный конечный результат работы&lt;br /&gt;
* Алгоритм очень чувствителен к выбору начальных центров масс кластеров: классический вариант подразумевает случайный их выбор, что может являться источником погрешности. Из этого и предыдущего свойства следует то, что алгоритм не является устойчивым.&lt;br /&gt;
&lt;br /&gt;
Как и любой другой алгоритм кластеризации, результат работы алгоритма k средних зависит от того, удовлетворяет ли входной набор данных предположениям, на которые опираются алгоритмы кластеризации. Таким образом, на одних наборах данных алгоритм может показывать хорошие результаты, но на других выдавать некорректные результаты.&lt;br /&gt;
&lt;br /&gt;
Алгоритм не является детерминированным, в силу того, что он чувствителен к выбору начальных центров масс кластеров, который осуществляется, как правило, случайным образом и тем самым вносит различия в работу алгоритма от запуска к запуску.&lt;br /&gt;
&lt;br /&gt;
== Программная реализация алгоритма ==&lt;br /&gt;
&lt;br /&gt;
=== Особенности реализации последовательного алгоритма ===&lt;br /&gt;
&lt;br /&gt;
=== Локальность данных и вычислений ===&lt;br /&gt;
&lt;br /&gt;
=== Возможные способы и особенности параллельной реализации алгоритма ===&lt;br /&gt;
&lt;br /&gt;
=== Масштабируемость алгоритма и его реализации ===&lt;br /&gt;
Исследование масштабируемости алгоритма k-means в зависимости от количества используемых процессов было проведено в статье Кумара&amp;lt;ref&amp;gt;Kumar J. et al. Parallel k-means clustering for quantitative ecoregion delineation using large data sets //Procedia Computer Science. – 2011. – Т. 4. – С. 1602-1611.&amp;lt;/ref&amp;gt;. Исследование происходило на суперкомпьютере Jaguar - Cray XT5&amp;lt;ref&amp;gt;https://www.top500.org/system/176029&amp;lt;/ref&amp;gt;. На момент экспериментов данный суперкомпьютер имел следующую конфигурацию: 18,688 вычислительных узлов с двумя шестнадцатиядерными процессорами AMD Opteron 2435 (Istanbul) 2.6 GHz, 16 GB of DDR2-800 оперативной памяти, и SeaStar 2+ роутер. Всего он состоял из 224,256 вычислительных ядер, 300 TB памяти, и пиковой производительностью 2.3 petaflops.&lt;br /&gt;
&lt;br /&gt;
Реализация алгоритма была выполнена на языке программирования C с использованием MPI.&lt;br /&gt;
&lt;br /&gt;
Объем данных составлял 84 гигабайта, количество объектов (m-мерных векторов) n равнялось 1,024,767,667, размерность векторов m равнялось 22, количество кластеров k равнялось 1000. &lt;br /&gt;
&lt;br /&gt;
На рисунке 4 показана зависимости времени работы алгоритма кластеризации k-means в зависимости от количества используемых процессоров. Можно отметить, что время, затраченное на чтение данных и запись результатов кластеризации, практически не изменяется с увеличением количества задействованных процессоров. Время же работы самого алгоритма кластеризации уменьшается с увеличением количества процессоров.&lt;br /&gt;
[[Файл:k-means-proc-scalability.png|thumb|center|700px|Рисунок 4. Зависимости времени работы алгоритма кластеризации k-means в зависимости от количества используемых процессоров.]]&lt;br /&gt;
&lt;br /&gt;
Ниже представлены результаты исследования времени работы алгоритма k-means в зависимости от количества кластеров k и количества векторов n. Для исследования использовалась реализация k-means на языке программирования C (с использованием OpenMP). Тестирование происходило на 8 процессорах. Затраченное время считалось как среднее арифметическое 5 запусков алгоритма.&lt;br /&gt;
&lt;br /&gt;
На рисунке 5 показана зависимость времени работы алгоритма от количества кластеров k. Количество векторов n равно 100000.&lt;br /&gt;
[[Файл:k-means-k.png|thumb|center|700px|Рисунок 5. Зависимости времени работы алгоритма кластеризации k-means в зависимости от количества кластеров k.]]&lt;br /&gt;
&lt;br /&gt;
На рисунке 6 показана зависимость времени работы алгоритма от количества векторов n. Количество кластеров k равно 160.&lt;br /&gt;
[[Файл:k-means-n.png|thumb|center|700px|Рисунок 6. Зависимости времени работы алгоритма кластеризации k-means в зависимости от количества векторов n.]]&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-средних:&lt;br /&gt;
* [http://scikit-learn.org/ scikit-learn] библиотека машинного обучения для языка Python.&lt;br /&gt;
* [https://www.scipy.org/ SciPy] библиотека на языке Python, содержащая большое число реализаций различных алгоритмов, в том числе &#039;&#039;k&#039;&#039;-средних.&lt;br /&gt;
* [http://elki.dbs.ifi.lmu.de ELKI] библиотека для анализа данных на языке программирования Java, содержит различные алгоритмы кластеризации, в том числе &#039;&#039;k&#039;&#039;-средних.&lt;br /&gt;
* [http://mlpack.org MLPACK] библиотека машинного обучения для C++, содержит реализацию алгоритма &#039;&#039;k&#039;&#039;-средних.&lt;br /&gt;
* [https://github.com/JuliaStats/Clustering.jl Julia k-means] реализация алгоритма &#039;&#039;k&#039;&#039;-средних на языке программирования Julia.&lt;br /&gt;
* [http://opencv.org/ OpenCV] библиотека содержит реализацию &#039;&#039;k&#039;&#039;-средних.&lt;br /&gt;
* [http://mahout.apache.org Apache Mahout] содержит реализацию алгоритма &#039;&#039;k&#039;&#039;-средних на базе MapReduce.&lt;br /&gt;
* [http://www.cs.waikato.ac.nz/~ml/weka Weka] библиотека и инструмент для анализа данных на языке Java.&lt;br /&gt;
* [http://torch.ch/ Torch] библиотека машинного обучения на базе языка программирования Lua.&lt;br /&gt;
* [https://spark.apache.org/ Apache Spark MLlib] содержит распределенную реализацию алгоритма &#039;&#039;k&#039;&#039;-средних.&lt;br /&gt;
* [http://www.accord-framework.net/ Accord.NET] содержит несколько различных реализаций &#039;&#039;k&#039;&#039;-средних на языке C#.&lt;br /&gt;
* [https://www.r-bloggers.com/k-means-clustering-in-r/ R k-means] реализация &#039;&#039;k&#039;&#039;-средних на языке R.&lt;br /&gt;
&lt;br /&gt;
== Литература ==&lt;br /&gt;
&amp;lt;references \&amp;gt;&lt;/div&gt;</summary>
		<author><name>Parkhomenko</name></author>
	</entry>
	<entry>
		<id>https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%9E%D0%B1%D1%81%D1%83%D0%B6%D0%B4%D0%B5%D0%BD%D0%B8%D0%B5_%D1%83%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA%D0%B0:Lineprinter&amp;diff=5619</id>
		<title>Обсуждение участника:Lineprinter</title>
		<link rel="alternate" type="text/html" href="https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%9E%D0%B1%D1%81%D1%83%D0%B6%D0%B4%D0%B5%D0%BD%D0%B8%D0%B5_%D1%83%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA%D0%B0:Lineprinter&amp;diff=5619"/>
		<updated>2016-10-12T09:19:14Z</updated>

		<summary type="html">&lt;p&gt;Parkhomenko: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Перенос ==&lt;br /&gt;
&lt;br /&gt;
Статья:[[Алгоритм_Ланцоша_с_полной_переортогонализацией]];&lt;br /&gt;
Выполняет:[[Участник:Sfedotov| Федотов С.А.]]&lt;br /&gt;
&lt;br /&gt;
Статья:[[Алгоритм_k-средних]]&lt;br /&gt;
Выполняют: Богомазов Евгений, [[Участник:Илья_Егоров|Егоров Илья]]&lt;br /&gt;
&lt;br /&gt;
Статья: algowiki-project.org/ru/Решение_задачи_Коши_для_системы_ОДУ_методом_Рунге-Кутты_4_порядка;&lt;br /&gt;
Выполняют: Алимов Дамир и Антон Лесничий&lt;br /&gt;
&lt;br /&gt;
Статья: Алгоритм кластеризации, основанный на минимальном остовном дереве;&lt;br /&gt;
Выполняет: Стандрик Антон Сергеевич (Astandrik)&lt;br /&gt;
&lt;br /&gt;
Статья: [[Нахождение_собственных_чисел_квадратной_матрицы_методом_QR_разложения_(3)|Нахождение собственных чисел квадратной матрицы методом QR разложения (3)]];&lt;br /&gt;
Выполняют: [[Участник:Смирнова_Александра|Смирнова А.С.]], [[Участник:Александра_Киямова|Киямова А.]]&lt;br /&gt;
&lt;br /&gt;
Статья: [[Метод_Якоби_вычисления_сингулярных_чисел_и_векторов]];&lt;br /&gt;
Выполняют: [[Участница:Почернина_Елена| Почернина Елена]] и [[Участница:Светлана|Костюкова Светлана]]&lt;br /&gt;
&lt;br /&gt;
Статья: [[Метод_Ньютона_для_решения_систем_нелинейных_уравнений(2)]];&lt;br /&gt;
Выполняют: [[Участник:Oleggium|Гирняк О.Р.]], [[Участник:Dimx19|Васильков Д.А.]]&lt;br /&gt;
&lt;br /&gt;
Статья: [[Алгоритм_кластеризации_с_использованием_представлений]];&lt;br /&gt;
Выполняют: [[Участник:Cookie|Шатков С.А.]], [[Антохина Ю.А.]]&lt;br /&gt;
&lt;br /&gt;
Статья: [[Быстрое_преобразование_Фурье_(FFT)|Быстрое преобразование Фурье (FFT)]];&lt;br /&gt;
Выполняют: [[Участник:Victoria_Stepanischeva|Степанищева Виктория]] и [[Участник:Igor_Munkin|Мунькин Игорь]]&lt;br /&gt;
&lt;br /&gt;
Статья: [[Быстрое_дискретное_преобразование_Фурье|Быстрое_дискретное_преобразование_Фурье]];&lt;br /&gt;
Выполняют: [[Участник:ivanov.kir.m | К.М.Иванов]], [[Участник:Pumpkin | А.C.Сапин]]&lt;br /&gt;
&lt;br /&gt;
Статья:[[Алгоритм_k_средних]]&lt;br /&gt;
Выполняют: [[Участник:Parkhomenko|Пархоменко Павел]], [[Участник:ivan.mashonskiy|Машонский Иван]]&lt;/div&gt;</summary>
		<author><name>Parkhomenko</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:Parkhomenko/%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=5603</id>
		<title>Участник:Parkhomenko/Алгоритм 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:Parkhomenko/%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=5603"/>
		<updated>2016-10-12T08:29:48Z</updated>

		<summary type="html">&lt;p&gt;Parkhomenko: /* Масштабируемость алгоритма и его реализации */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{algorithm&lt;br /&gt;
| name              = Алгоритм k средних&lt;br /&gt;
| serial_complexity = &amp;lt;math&amp;gt;O(m*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;
Основные авторы описания: [[Участник:Parkhomenko|П.А.Пархоменко]], [[Участник:Ivan.mashonskiy|И.Д.Машонский]]&lt;br /&gt;
== Свойства и структура алгоритмов ==&lt;br /&gt;
&lt;br /&gt;
=== Общее описание алгоритма ===&lt;br /&gt;
Алгоритм k средних (англ. k-means) - один из алгоритмов машинного обучения, решающий задачу кластеризации. Он был изобретен в середине 1950-х математиком Гуго Штейнгаузом&amp;lt;ref&amp;gt;Steinhaus H. (1956). Sur la division des corps materiels en parties. Bull. Acad. Polon. Sci., C1. III vol IV: 801—804.&amp;lt;/ref&amp;gt; и Стюартом Ллойдом&amp;lt;ref&amp;gt;Lloyd S. (1957). Least square quantization in PCM’s. Bell Telephone Laboratories Paper.&amp;lt;/ref&amp;gt;. Алгоритм стал особо популярным после публикации Маккуина&amp;lt;ref&amp;gt;MacQueen J. (1967). Some methods for classification and analysis of multivariate observations. In Proc. 5th Berkeley Symp. on Math. Statistics and Probability, pages 281—297.&amp;lt;/ref&amp;gt;, в которой впервые был использован термин “k-means”.&lt;br /&gt;
&lt;br /&gt;
Задача алгоритма кластеризации заключается в разбиении N объектов (d-мерных векторов) на K групп (кластеров). Каждый вектор может принадлежать только одному кластеру. Количество кластеров K фиксировано, оно задается в качестве параметра.&lt;br /&gt;
&lt;br /&gt;
K-means является итерационным алгоритмом, разновидностью EM-алгоритма. Основная идея работы алгоритма заключается в проведении некоторого количества итераций, на каждой из которых происходит пересчет центра масс для каждого кластера, полученного на предыдущей итерации. После этого векторы перераспределяются по кластерам: вектор относится к тому кластеру, расстояние до центра масс которого минимально. Алгоритм завершает работу в том случае, если на очередной итерации центры масс кластеров не изменились.&lt;br /&gt;
&lt;br /&gt;
=== Математическое описание алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Исходные данные: множество d-мерных векторов (наблюдений) &amp;lt;math&amp;gt;X&amp;lt;/math&amp;gt;&amp;amp;nbsp;=&amp;amp;nbsp;&amp;lt;math&amp;gt;\{x_1, x_2, ..., x_n\}&amp;lt;/math&amp;gt;, число кластеров &amp;lt;math&amp;gt;k \in \mathbb{N}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
В результате работы алгоритма исходное множество векторов &amp;lt;math&amp;gt;X&amp;lt;/math&amp;gt; разбивается на &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; непересекающихся множеств (кластеров) &amp;lt;math&amp;gt;S_1, S_2, ..., S_k&amp;lt;/math&amp;gt;, таких что &amp;lt;math&amp;gt;X = {\bigcup \limits _{i = 1}^k S_i} &amp;lt;/math&amp;gt; и значение &amp;lt;math&amp;gt;\sum_{i=1}^{k} \sum_{\mathbf x \in S_i} \left\| \mathbf x - \mu_i \right\|^2 &amp;lt;/math&amp;gt; — минимально для всех возможных наборов &amp;lt;math&amp;gt;S_1, S_2, ..., S_k&amp;lt;/math&amp;gt;.&lt;br /&gt;
Под &amp;lt;math&amp;gt;\mu_i&amp;lt;/math&amp;gt; здесь подразумевается центр масс векторов из множества &amp;lt;math&amp;gt;S_i&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Первоначальные значения центров масс &amp;lt;math&amp;gt;\mu_1^{(1)}, ..., \mu_k^{(1)}&amp;lt;/math&amp;gt; определяются в начале работы алгоритма случайным образом среди векторов множества &amp;lt;math&amp;gt;X&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Алгоритм заключается в попеременном применении двух шагов: &#039;&#039;&#039;распределения&#039;&#039;&#039; векторов по кластерам и &#039;&#039;&#039;обновления&#039;&#039;&#039; центров масс каждого кластера&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Распределение векторов по кластерам&#039;&#039;&#039;: на данном шаге каждый вектор распределяется в один из кластеров &amp;lt;math&amp;gt;S_i^{(t)}&amp;lt;/math&amp;gt;: &lt;br /&gt;
::&amp;lt;math&amp;gt;S_i^{(t)} = \big \{ x_p : \big \| x_p - \mu^{(t)}_i \big \|^2 \le \big \| x_p - \mu^{(t)}_j \big \|^2 \ \forall j, 1 \le j \le k \big\},&amp;lt;/math&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Обновление центров масс&#039;&#039;&#039;: на данном шаге вычисляются новые центры масс для кластеров, полученных на предыдущем шаге.&lt;br /&gt;
::&amp;lt;math&amp;gt;\mu^{(t+1)}_i = \frac{1}{|S^{(t)}_i|} \sum_{x_j \in S^{(t)}_i} x_j &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Алгоритм завершается, когда на очередном шаге не происходит изменения центров масс кластеров.&lt;br /&gt;
&lt;br /&gt;
=== Вычислительное ядро алгоритма ===&lt;br /&gt;
Вычислительное ядро последовательного алгоритма k-means состоит из двух операций, повторяющихся на каждой итерации алгоритма:&lt;br /&gt;
* пересчета центров масс кластеров;&lt;br /&gt;
* соотнесения каждого вектора к одному из кластеров.&lt;br /&gt;
&lt;br /&gt;
Пересчет центра масс кластера заключается в нахождении d-мерного вектора, являющегося средним арифметическим d-мерных векторов, принадлежащих кластеру. Эту операцию необходимо выполнять для каждого из K кластеров.&lt;br /&gt;
&lt;br /&gt;
Для соотнесения вектора к одному из кластеров, необходимо для каждого из N вектора посчитать расстояние до центров масс всех K кластеров. Для нахождения расстояния между двумя d-мерными векторами p и q используется Евклидова метрика: &amp;lt;math&amp;gt;\sqrt{\sum_{k=1}^d (p_k-q_k)^2}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Макроструктура алгоритма ===&lt;br /&gt;
&lt;br /&gt;
В начале алгоритма осуществляется инициализация центров масс &amp;lt;math&amp;gt;\mu_1^{(1)}, ..., \mu_k^{(1)}&amp;lt;/math&amp;gt;, которая может быть реализована двумя возможными способами: &lt;br /&gt;
* случайный выбор центров масс среди исходных наблюдений &amp;lt;math&amp;gt;x_1, x_2, ..., x_n&amp;lt;/math&amp;gt;;&lt;br /&gt;
* все наблюдения случайным образом распределяются по кластерам &amp;lt;math&amp;gt;S_1, S_2, ..., S_k&amp;lt;/math&amp;gt;, а затем для каждого кластера выполняется операция обновления центра масс.&lt;br /&gt;
&lt;br /&gt;
На шаге распределения векторов по кластерам производится операция нахождения квадратов расстояний между векторами кластера и центром масс кластера: &lt;br /&gt;
::&amp;lt;math&amp;gt;\rho = \big \| x_p - \mu^{(t)}_i \big \|^2&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
На шаге обновления центров масс производится операция суммирования векторов кластера:&lt;br /&gt;
::&amp;lt;math&amp;gt;\mu^{(t+1)}_i = \frac{1}{|S^{(t)}_i|} \sum_{x_j \in S^{(t)}_i} x_j &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Схема реализации последовательного алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Последовательность исполнения метода следующая:&lt;br /&gt;
# Инициализируются центры масс &amp;lt;math&amp;gt;\mu_1^{(1)}, ..., \mu_k^{(1)}&amp;lt;/math&amp;gt;&lt;br /&gt;
# &amp;lt;math&amp;gt;t := 1&amp;lt;/math&amp;gt;&lt;br /&gt;
# Для каждого вектора &amp;lt;math&amp;gt;x_i, i = 1, 2, ..., n&amp;lt;/math&amp;gt; вычисляется &amp;lt;br/&amp;gt;&amp;lt;math&amp;gt;m = \underset{j \in \{1, 2, ..., k\}} {\operatorname{arg\,min}} \big \| x_i - \mu^{(t)}_j \big \|^2&amp;lt;/math&amp;gt;, &amp;lt;br/&amp;gt;вектор &amp;lt;math&amp;gt;x_i&amp;lt;/math&amp;gt; распределяется в кластер &amp;lt;math&amp;gt;S^{(t)}_m&amp;lt;/math&amp;gt;&lt;br /&gt;
# Для каждого &amp;lt;math&amp;gt;j = 1, 2, ..., k&amp;lt;/math&amp;gt; вычисляется &amp;lt;br/&amp;gt;&amp;lt;math&amp;gt;\mu^{(t+1)}_j = \frac{1}{|S^{(t)}_i|} \sum_{x_j \in S^{(t)}_i} x_j &amp;lt;/math&amp;gt;&lt;br /&gt;
#  Если &amp;lt;math&amp;gt;\mu^{(t)}_j = \mu^{(t+1)}_j, j = 1, 2, ..., k&amp;lt;/math&amp;gt;, завершить выполнение алгоритма, иначе &amp;lt;math&amp;gt;t := t + 1&amp;lt;/math&amp;gt;, переход на шаг 3.&lt;br /&gt;
&lt;br /&gt;
=== Последовательная сложность алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Для вычисления центра массы кластера, содержащего &amp;lt;math&amp;gt;n_i&amp;lt;/math&amp;gt; d-мерных векторов, необходимо:&lt;br /&gt;
* &amp;lt;math&amp;gt;n_i * (d - 1)&amp;lt;/math&amp;gt; операций сложения&lt;br /&gt;
* &amp;lt;math&amp;gt;d&amp;lt;/math&amp;gt; операций деления&lt;br /&gt;
&lt;br /&gt;
Для определения центров масс всех k кластеров требуется:&lt;br /&gt;
* &amp;lt;math&amp;gt;n * (d - 1)&amp;lt;/math&amp;gt; операций сложения&lt;br /&gt;
* &amp;lt;math&amp;gt;k * d&amp;lt;/math&amp;gt; операций деления&lt;br /&gt;
&lt;br /&gt;
Для определения расстояния между двумя d-мерными векторами, требуется:&lt;br /&gt;
* &amp;lt;math&amp;gt;d&amp;lt;/math&amp;gt; операций вычитания&lt;br /&gt;
* &amp;lt;math&amp;gt;d&amp;lt;/math&amp;gt; операций умножения&lt;br /&gt;
* &amp;lt;math&amp;gt;d - 1&amp;lt;/math&amp;gt; операций сложения&lt;br /&gt;
&lt;br /&gt;
Для определения кластера для n d-мерного векторов, необходимо:&lt;br /&gt;
* &amp;lt;math&amp;gt;n * k * d&amp;lt;/math&amp;gt; операций вычитания&lt;br /&gt;
* &amp;lt;math&amp;gt;n * k * d&amp;lt;/math&amp;gt; операций умножения&lt;br /&gt;
* &amp;lt;math&amp;gt;n * k * (d - 1)&amp;lt;/math&amp;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; операций умножения/деления&lt;br /&gt;
&lt;br /&gt;
Сложность всего алгоритма, состоящего из m итераций: &amp;lt;math&amp;gt;O(m * n * k * d)&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Информационный граф ===&lt;br /&gt;
&lt;br /&gt;
В данном разделе описывается информационный граф алгоритма k-средних при &amp;lt;math&amp;gt;n = 3, k = 2&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
На рисунке 1 показана общая структура алгоритма: в качестве входных данных выступает матрица, строками которой являются входные векторы &amp;lt;math&amp;gt;x_1, x_2, x_3&amp;lt;/math&amp;gt;, на выходе получается массив из &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; чисел, где элемент с номером &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt; обозначает номер кластера, которому принадлежит вектор &amp;lt;math&amp;gt;x_i&amp;lt;/math&amp;gt;. На шаге init происходит инициализация значений центров масс кластеров, после этого осуществляется итеративное повторение этапов распределения векторов по кластерам (as) и обновления значений центров масс кластеров (up).&lt;br /&gt;
&lt;br /&gt;
[[file:k_means_info_graph_as.svg|thumb|center||Рисунок 2. Граф алгоритма для этапа распределения векторов по кластерам]]&lt;br /&gt;
[[file:k_means_info_graph_up.svg|thumb|center||Рисунок 3. Граф алгоритма для этапа обновления центров масс кластеров]]&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;
* целое неотрицательное число &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; - количество кластеров;&lt;br /&gt;
* матрица координат векторов &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; размерностью &amp;lt;math&amp;gt;n * d&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Объем входных данных&#039;&#039;&#039;:&lt;br /&gt;
* &amp;lt;math&amp;gt;n * d&amp;lt;/math&amp;gt; вещественных чисел (если координаты вещественные числа), &amp;lt;math&amp;gt;1&amp;lt;/math&amp;gt; целое неотрицательное число.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Выходные данные&#039;&#039;&#039;:&lt;br /&gt;
* вектор длины &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; - для каждого вектора указан номер кластера.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Объем выходных данных&#039;&#039;&#039;: &lt;br /&gt;
* &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; целых неотрицательных чисел.&lt;br /&gt;
&lt;br /&gt;
=== Свойства алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Стоит отметить следующие ключевые особенности алгоритма k средних:&lt;br /&gt;
* Алгоритм прост в реализации и имеет высокую скорость работы по сравнению с другими алгоритмами кластеризации (при удачном выборе начальных значений центров масс кластеров)&lt;br /&gt;
* В качестве метрики используется евклидово расстояние, а в качестве меры разброса кластера используется дисперсия&lt;br /&gt;
* Количество кластеров k является входным параметром алгоритма, поэтому неправильный выбор этого параметра может негативно повлиять на качество кластеризации&lt;br /&gt;
* Сходимость алгоритма к локальному минимуму может породить некорректный конечный результат работы&lt;br /&gt;
* Алгоритм очень чувствителен к выбору начальных центров масс кластеров: классический вариант подразумевает случайный их выбор, что может являться источником погрешности. Из этого и предыдущего свойства следует то, что алгоритм не является устойчивым.&lt;br /&gt;
&lt;br /&gt;
Как и любой другой алгоритм кластеризации, результат работы алгоритма k средних зависит от того, удовлетворяет ли входной набор данных предположениям, на которые опираются алгоритмы кластеризации. Таким образом, на одних наборах данных алгоритм может показывать хорошие результаты, но на других выдавать некорректные результаты.&lt;br /&gt;
&lt;br /&gt;
Алгоритм не является детерминированным, в силу того, что он чувствителен к выбору начальных центров масс кластеров, который осуществляется, как правило, случайным образом и тем самым вносит различия в работу алгоритма от запуска к запуску.&lt;br /&gt;
&lt;br /&gt;
== Программная реализация алгоритма ==&lt;br /&gt;
&lt;br /&gt;
=== Особенности реализации последовательного алгоритма ===&lt;br /&gt;
&lt;br /&gt;
=== Локальность данных и вычислений ===&lt;br /&gt;
&lt;br /&gt;
=== Возможные способы и особенности параллельной реализации алгоритма ===&lt;br /&gt;
&lt;br /&gt;
=== Масштабируемость алгоритма и его реализации ===&lt;br /&gt;
Исследование масштабируемости алгоритма k-means в зависимости от количества используемых процессов было проведено в статье Кумара&amp;lt;ref&amp;gt;Kumar J. et al. Parallel k-means clustering for quantitative ecoregion delineation using large data sets //Procedia Computer Science. – 2011. – Т. 4. – С. 1602-1611.&amp;lt;/ref&amp;gt;. Исследование происходило на суперкомпьютере Jaguar - Cray XT5&amp;lt;ref&amp;gt;https://www.top500.org/system/176029&amp;lt;/ref&amp;gt;. На момент экспериментов данный суперкомпьютер имел следующую конфигурацию: 18,688 вычислительных узлов с двумя шестнадцатиядерными процессорами AMD Opteron 2435 (Istanbul) 2.6 GHz, 16 GB of DDR2-800 оперативной памяти, и SeaStar 2+ роутер. Всего он состоял из 224,256 вычислительных ядер, 300 TB памяти, и пиковой производительностью 2.3 petaflops.&lt;br /&gt;
&lt;br /&gt;
Реализация алгоритма была выполнена на языке программирования C с использованием MPI.&lt;br /&gt;
&lt;br /&gt;
Объем данных составлял 84 гигабайта, количество объектов (m-мерных векторов) n равнялось 1,024,767,667, размерность векторов m равнялось 22, количество кластеров k равнялось 1000. &lt;br /&gt;
&lt;br /&gt;
На рисунке 4 показана зависимости времени работы алгоритма кластеризации k-means в зависимости от количества используемых процессоров. Можно отметить, что время, затраченное на чтение данных и запись результатов кластеризации, практически не изменяется с увеличением количества задействованных процессоров. Время же работы самого алгоритма кластеризации уменьшается с увеличением количества процессоров.&lt;br /&gt;
[[Файл:k-means-proc-scalability.png|thumb|center|700px|Рисунок 4. Зависимости времени работы алгоритма кластеризации k-means в зависимости от количества используемых процессоров.]]&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-средних:&lt;br /&gt;
* [http://scikit-learn.org/ scikit-learn] библиотека машинного обучения для языка Python.&lt;br /&gt;
* [https://www.scipy.org/ SciPy] библиотека на языке Python, содержащая большое число реализаций различных алгоритмов, в том числе &#039;&#039;k&#039;&#039;-средних.&lt;br /&gt;
* [http://elki.dbs.ifi.lmu.de ELKI] библиотека для анализа данных на языке программирования Java, содержит различные алгоритмы кластеризации, в том числе &#039;&#039;k&#039;&#039;-средних.&lt;br /&gt;
* [http://mlpack.org MLPACK] библиотека машинного обучения для C++, содержит реализацию алгоритма &#039;&#039;k&#039;&#039;-средних.&lt;br /&gt;
* [https://github.com/JuliaStats/Clustering.jl Julia k-means] реализация алгоритма &#039;&#039;k&#039;&#039;-средних на языке программирования Julia.&lt;br /&gt;
* [http://opencv.org/ OpenCV] библиотека содержит реализацию &#039;&#039;k&#039;&#039;-средних.&lt;br /&gt;
* [http://mahout.apache.org Apache Mahout] содержит реализацию алгоритма &#039;&#039;k&#039;&#039;-средних на базе MapReduce.&lt;br /&gt;
* [http://www.cs.waikato.ac.nz/~ml/weka Weka] библиотека и инструмент для анализа данных на языке Java.&lt;br /&gt;
* [http://torch.ch/ Torch] библиотека машинного обучения на базе языка программирования Lua.&lt;br /&gt;
* [https://spark.apache.org/ Apache Spark MLlib] содержит распределенную реализацию алгоритма &#039;&#039;k&#039;&#039;-средних.&lt;br /&gt;
* [http://www.accord-framework.net/ Accord.NET] содержит несколько различных реализаций &#039;&#039;k&#039;&#039;-средних на языке C#.&lt;br /&gt;
* [https://www.r-bloggers.com/k-means-clustering-in-r/ R k-means] реализация &#039;&#039;k&#039;&#039;-средних на языке R.&lt;br /&gt;
&lt;br /&gt;
== Литература ==&lt;br /&gt;
&amp;lt;references \&amp;gt;&lt;/div&gt;</summary>
		<author><name>Parkhomenko</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:Parkhomenko/%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=4394</id>
		<title>Участник:Parkhomenko/Алгоритм 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:Parkhomenko/%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=4394"/>
		<updated>2016-09-29T14:42:09Z</updated>

		<summary type="html">&lt;p&gt;Parkhomenko: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{algorithm&lt;br /&gt;
| name              = Алгоритм k средних&lt;br /&gt;
| serial_complexity = &amp;lt;math&amp;gt;O(m*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;
Основные авторы описания: [[Участник:Parkhomenko|П.А.Пархоменко]], [[Участник:Ivan.mashonskiy|И.Д.Машонский]]&lt;br /&gt;
== ЧАСТЬ. Свойства и структура алгоритмов ==&lt;br /&gt;
&lt;br /&gt;
=== Общее описание алгоритма ===&lt;br /&gt;
Алгоритм k средних (англ. k-means) - один из алгоритмов машинного обучения, решающий задачу кластеризации. Он был изобретен в середине 1950-х математиком Гуго Штейнгаузом&amp;lt;ref&amp;gt;Steinhaus H. (1956). Sur la division des corps materiels en parties. Bull. Acad. Polon. Sci., C1. III vol IV: 801—804.&amp;lt;/ref&amp;gt; и Стюартом Ллойдом&amp;lt;ref&amp;gt;Lloyd S. (1957). Least square quantization in PCM’s. Bell Telephone Laboratories Paper.&amp;lt;/ref&amp;gt;. Алгоритм стал особо популярным после публикации Маккуина&amp;lt;ref&amp;gt;MacQueen J. (1967). Some methods for classification and analysis of multivariate observations. In Proc. 5th Berkeley Symp. on Math. Statistics and Probability, pages 281—297.&amp;lt;/ref&amp;gt;, в которой впервые был использован термин “k-means”.&lt;br /&gt;
&lt;br /&gt;
Задача алгоритма кластеризации заключается в разбиении N объектов (d-мерных векторов) на K групп (кластеров). Каждый вектор может принадлежать только одному кластеру. Количество кластеров K фиксировано, оно задается в качестве параметра.&lt;br /&gt;
&lt;br /&gt;
K-means является итерационным алгоритмом, разновидностью EM-алгоритма. Основная идея работы алгоритма заключается в проведении некоторого количества итераций, на каждой из которых происходит пересчет центра масс для каждого кластера, полученного на предыдущей итерации. После этого векторы перераспределяются по кластерам: вектор относится к тому кластеру, расстояние до центра масс которого минимально. Алгоритм завершает работу в том случае, если на очередной итерации центры масс кластеров не изменились.&lt;br /&gt;
&lt;br /&gt;
=== Математическое описание алгоритма ===&lt;br /&gt;
&lt;br /&gt;
=== Вычислительное ядро алгоритма ===&lt;br /&gt;
Вычислительное ядро последовательного алгоритма k-means состоит из двух операций, повторяющихся на каждой итерации алгоритма:&lt;br /&gt;
* пересчета центров масс кластеров;&lt;br /&gt;
* соотнесения каждого вектора к одному из кластеров.&lt;br /&gt;
&lt;br /&gt;
Пересчет центра масс кластера заключается в нахождении d-мерного вектора, являющегося средним арифметическим d-мерных векторов, принадлежащих кластеру. Эту операцию необходимо выполнять для каждого из K кластеров.&lt;br /&gt;
&lt;br /&gt;
Для соотнесения вектора к одному из кластеров, необходимо для каждого из N вектора посчитать расстояние до центров масс всех K кластеров. Для нахождения расстояния между двумя d-мерными векторами p и q используется Евклидова метрика: &amp;lt;math&amp;gt;\sqrt{\sum_{k=1}^d (p_k-q_k)^2}&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;
Для вычисления центра массы кластера, содержащего &amp;lt;math&amp;gt;n_i&amp;lt;/math&amp;gt; d-мерных векторов, необходимо:&lt;br /&gt;
* &amp;lt;math&amp;gt;n_i * (d - 1)&amp;lt;/math&amp;gt; операций сложения&lt;br /&gt;
* &amp;lt;math&amp;gt;d&amp;lt;/math&amp;gt; операций деления&lt;br /&gt;
&lt;br /&gt;
Для определения центров масс всех k кластеров требуется:&lt;br /&gt;
* &amp;lt;math&amp;gt;n * (d - 1)&amp;lt;/math&amp;gt; операций сложения&lt;br /&gt;
* &amp;lt;math&amp;gt;k * d&amp;lt;/math&amp;gt; операций деления&lt;br /&gt;
&lt;br /&gt;
Для определения расстояния между двумя d-мерными векторами, требуется:&lt;br /&gt;
* &amp;lt;math&amp;gt;d&amp;lt;/math&amp;gt; операций вычитания&lt;br /&gt;
* &amp;lt;math&amp;gt;d&amp;lt;/math&amp;gt; операций умножения&lt;br /&gt;
* &amp;lt;math&amp;gt;d - 1&amp;lt;/math&amp;gt; операций сложения&lt;br /&gt;
&lt;br /&gt;
Для определения кластера для n d-мерного векторов, необходимо:&lt;br /&gt;
* &amp;lt;math&amp;gt;n * k * d&amp;lt;/math&amp;gt; операций вычитания&lt;br /&gt;
* &amp;lt;math&amp;gt;n * k * d&amp;lt;/math&amp;gt; операций умножения&lt;br /&gt;
* &amp;lt;math&amp;gt;n * k * (d - 1)&amp;lt;/math&amp;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; операций умножения/деления&lt;br /&gt;
&lt;br /&gt;
Сложность всего алгоритма, состоящего из m итераций: &amp;lt;math&amp;gt;O(m * n * 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;:&lt;br /&gt;
* целое неотрицательное число &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; - количество кластеров;&lt;br /&gt;
* матрица координат векторов &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; размерностью &amp;lt;math&amp;gt;n * d&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Объем входных данных&#039;&#039;&#039;:&lt;br /&gt;
* &amp;lt;math&amp;gt;n * d&amp;lt;/math&amp;gt; вещественных чисел (если координаты вещественные числа), &amp;lt;math&amp;gt;1&amp;lt;/math&amp;gt; целое неотрицательное число.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Выходные данные&#039;&#039;&#039;:&lt;br /&gt;
* вектор длины &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; - для каждого вектора указан номер кластера.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Объем выходных данных&#039;&#039;&#039;: &lt;br /&gt;
* &amp;lt;math&amp;gt;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;
&lt;br /&gt;
=== Возможные способы и особенности параллельной реализации алгоритма ===&lt;br /&gt;
&lt;br /&gt;
=== Масштабируемость алгоритма и его реализации ===&lt;br /&gt;
&lt;br /&gt;
=== Динамические характеристики и эффективность реализации алгоритма ===&lt;br /&gt;
&lt;br /&gt;
=== Выводы для классов архитектур ===&lt;br /&gt;
&lt;br /&gt;
=== Существующие реализации алгоритма ===&lt;br /&gt;
&lt;br /&gt;
== Литература ==&lt;br /&gt;
&amp;lt;references \&amp;gt;&lt;/div&gt;</summary>
		<author><name>Parkhomenko</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:Parkhomenko/%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=4393</id>
		<title>Участник:Parkhomenko/Алгоритм 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:Parkhomenko/%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=4393"/>
		<updated>2016-09-29T14:41:21Z</updated>

		<summary type="html">&lt;p&gt;Parkhomenko: /* Входные и выходные данные алгоритма */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{algorithm&lt;br /&gt;
| name              = Алгоритм k средних&lt;br /&gt;
| serial_complexity = &amp;lt;math&amp;gt;O(m*n*k*d)&amp;lt;/math&amp;gt;&lt;br /&gt;
| input_data        = &amp;lt;math&amp;gt;&amp;lt;/math&amp;gt;&lt;br /&gt;
| output_data       = &amp;lt;math&amp;gt;&amp;lt;/math&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
Основные авторы описания: [[Участник:Parkhomenko|П.А.Пархоменко]], [[Участник:Ivan.mashonskiy|И.Д.Машонский]]&lt;br /&gt;
== ЧАСТЬ. Свойства и структура алгоритмов ==&lt;br /&gt;
&lt;br /&gt;
=== Общее описание алгоритма ===&lt;br /&gt;
Алгоритм k средних (англ. k-means) - один из алгоритмов машинного обучения, решающий задачу кластеризации. Он был изобретен в середине 1950-х математиком Гуго Штейнгаузом&amp;lt;ref&amp;gt;Steinhaus H. (1956). Sur la division des corps materiels en parties. Bull. Acad. Polon. Sci., C1. III vol IV: 801—804.&amp;lt;/ref&amp;gt; и Стюартом Ллойдом&amp;lt;ref&amp;gt;Lloyd S. (1957). Least square quantization in PCM’s. Bell Telephone Laboratories Paper.&amp;lt;/ref&amp;gt;. Алгоритм стал особо популярным после публикации Маккуина&amp;lt;ref&amp;gt;MacQueen J. (1967). Some methods for classification and analysis of multivariate observations. In Proc. 5th Berkeley Symp. on Math. Statistics and Probability, pages 281—297.&amp;lt;/ref&amp;gt;, в которой впервые был использован термин “k-means”.&lt;br /&gt;
&lt;br /&gt;
Задача алгоритма кластеризации заключается в разбиении N объектов (d-мерных векторов) на K групп (кластеров). Каждый вектор может принадлежать только одному кластеру. Количество кластеров K фиксировано, оно задается в качестве параметра.&lt;br /&gt;
&lt;br /&gt;
K-means является итерационным алгоритмом, разновидностью EM-алгоритма. Основная идея работы алгоритма заключается в проведении некоторого количества итераций, на каждой из которых происходит пересчет центра масс для каждого кластера, полученного на предыдущей итерации. После этого векторы перераспределяются по кластерам: вектор относится к тому кластеру, расстояние до центра масс которого минимально. Алгоритм завершает работу в том случае, если на очередной итерации центры масс кластеров не изменились.&lt;br /&gt;
&lt;br /&gt;
=== Математическое описание алгоритма ===&lt;br /&gt;
&lt;br /&gt;
=== Вычислительное ядро алгоритма ===&lt;br /&gt;
Вычислительное ядро последовательного алгоритма k-means состоит из двух операций, повторяющихся на каждой итерации алгоритма:&lt;br /&gt;
* пересчета центров масс кластеров;&lt;br /&gt;
* соотнесения каждого вектора к одному из кластеров.&lt;br /&gt;
&lt;br /&gt;
Пересчет центра масс кластера заключается в нахождении d-мерного вектора, являющегося средним арифметическим d-мерных векторов, принадлежащих кластеру. Эту операцию необходимо выполнять для каждого из K кластеров.&lt;br /&gt;
&lt;br /&gt;
Для соотнесения вектора к одному из кластеров, необходимо для каждого из N вектора посчитать расстояние до центров масс всех K кластеров. Для нахождения расстояния между двумя d-мерными векторами p и q используется Евклидова метрика: &amp;lt;math&amp;gt;\sqrt{\sum_{k=1}^d (p_k-q_k)^2}&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;
Для вычисления центра массы кластера, содержащего &amp;lt;math&amp;gt;n_i&amp;lt;/math&amp;gt; d-мерных векторов, необходимо:&lt;br /&gt;
* &amp;lt;math&amp;gt;n_i * (d - 1)&amp;lt;/math&amp;gt; операций сложения&lt;br /&gt;
* &amp;lt;math&amp;gt;d&amp;lt;/math&amp;gt; операций деления&lt;br /&gt;
&lt;br /&gt;
Для определения центров масс всех k кластеров требуется:&lt;br /&gt;
* &amp;lt;math&amp;gt;n * (d - 1)&amp;lt;/math&amp;gt; операций сложения&lt;br /&gt;
* &amp;lt;math&amp;gt;k * d&amp;lt;/math&amp;gt; операций деления&lt;br /&gt;
&lt;br /&gt;
Для определения расстояния между двумя d-мерными векторами, требуется:&lt;br /&gt;
* &amp;lt;math&amp;gt;d&amp;lt;/math&amp;gt; операций вычитания&lt;br /&gt;
* &amp;lt;math&amp;gt;d&amp;lt;/math&amp;gt; операций умножения&lt;br /&gt;
* &amp;lt;math&amp;gt;d - 1&amp;lt;/math&amp;gt; операций сложения&lt;br /&gt;
&lt;br /&gt;
Для определения кластера для n d-мерного векторов, необходимо:&lt;br /&gt;
* &amp;lt;math&amp;gt;n * k * d&amp;lt;/math&amp;gt; операций вычитания&lt;br /&gt;
* &amp;lt;math&amp;gt;n * k * d&amp;lt;/math&amp;gt; операций умножения&lt;br /&gt;
* &amp;lt;math&amp;gt;n * k * (d - 1)&amp;lt;/math&amp;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; операций умножения/деления&lt;br /&gt;
&lt;br /&gt;
Сложность всего алгоритма, состоящего из m итераций: &amp;lt;math&amp;gt;O(m * n * 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;:&lt;br /&gt;
* целое неотрицательное число &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; - количество кластеров;&lt;br /&gt;
* матрица координат векторов &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; размерностью &amp;lt;math&amp;gt;n * d&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Объем входных данных&#039;&#039;&#039;:&lt;br /&gt;
* &amp;lt;math&amp;gt;n * d&amp;lt;/math&amp;gt; вещественных чисел (если координаты вещественные числа), &amp;lt;math&amp;gt;1&amp;lt;/math&amp;gt; целое неотрицательное число.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Выходные данные&#039;&#039;&#039;:&lt;br /&gt;
* вектор длины &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; - для каждого вектора указан номер кластера.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Объем выходных данных&#039;&#039;&#039;: &lt;br /&gt;
* &amp;lt;math&amp;gt;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;
&lt;br /&gt;
=== Возможные способы и особенности параллельной реализации алгоритма ===&lt;br /&gt;
&lt;br /&gt;
=== Масштабируемость алгоритма и его реализации ===&lt;br /&gt;
&lt;br /&gt;
=== Динамические характеристики и эффективность реализации алгоритма ===&lt;br /&gt;
&lt;br /&gt;
=== Выводы для классов архитектур ===&lt;br /&gt;
&lt;br /&gt;
=== Существующие реализации алгоритма ===&lt;br /&gt;
&lt;br /&gt;
== Литература ==&lt;br /&gt;
&amp;lt;references \&amp;gt;&lt;/div&gt;</summary>
		<author><name>Parkhomenko</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:Parkhomenko/%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=4392</id>
		<title>Участник:Parkhomenko/Алгоритм 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:Parkhomenko/%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=4392"/>
		<updated>2016-09-29T14:35:59Z</updated>

		<summary type="html">&lt;p&gt;Parkhomenko: /* Последовательная сложность алгоритма */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{algorithm&lt;br /&gt;
| name              = Алгоритм k средних&lt;br /&gt;
| serial_complexity = &amp;lt;math&amp;gt;O(m*n*k*d)&amp;lt;/math&amp;gt;&lt;br /&gt;
| input_data        = &amp;lt;math&amp;gt;&amp;lt;/math&amp;gt;&lt;br /&gt;
| output_data       = &amp;lt;math&amp;gt;&amp;lt;/math&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
Основные авторы описания: [[Участник:Parkhomenko|П.А.Пархоменко]], [[Участник:Ivan.mashonskiy|И.Д.Машонский]]&lt;br /&gt;
== ЧАСТЬ. Свойства и структура алгоритмов ==&lt;br /&gt;
&lt;br /&gt;
=== Общее описание алгоритма ===&lt;br /&gt;
Алгоритм k средних (англ. k-means) - один из алгоритмов машинного обучения, решающий задачу кластеризации. Он был изобретен в середине 1950-х математиком Гуго Штейнгаузом&amp;lt;ref&amp;gt;Steinhaus H. (1956). Sur la division des corps materiels en parties. Bull. Acad. Polon. Sci., C1. III vol IV: 801—804.&amp;lt;/ref&amp;gt; и Стюартом Ллойдом&amp;lt;ref&amp;gt;Lloyd S. (1957). Least square quantization in PCM’s. Bell Telephone Laboratories Paper.&amp;lt;/ref&amp;gt;. Алгоритм стал особо популярным после публикации Маккуина&amp;lt;ref&amp;gt;MacQueen J. (1967). Some methods for classification and analysis of multivariate observations. In Proc. 5th Berkeley Symp. on Math. Statistics and Probability, pages 281—297.&amp;lt;/ref&amp;gt;, в которой впервые был использован термин “k-means”.&lt;br /&gt;
&lt;br /&gt;
Задача алгоритма кластеризации заключается в разбиении N объектов (d-мерных векторов) на K групп (кластеров). Каждый вектор может принадлежать только одному кластеру. Количество кластеров K фиксировано, оно задается в качестве параметра.&lt;br /&gt;
&lt;br /&gt;
K-means является итерационным алгоритмом, разновидностью EM-алгоритма. Основная идея работы алгоритма заключается в проведении некоторого количества итераций, на каждой из которых происходит пересчет центра масс для каждого кластера, полученного на предыдущей итерации. После этого векторы перераспределяются по кластерам: вектор относится к тому кластеру, расстояние до центра масс которого минимально. Алгоритм завершает работу в том случае, если на очередной итерации центры масс кластеров не изменились.&lt;br /&gt;
&lt;br /&gt;
=== Математическое описание алгоритма ===&lt;br /&gt;
&lt;br /&gt;
=== Вычислительное ядро алгоритма ===&lt;br /&gt;
Вычислительное ядро последовательного алгоритма k-means состоит из двух операций, повторяющихся на каждой итерации алгоритма:&lt;br /&gt;
* пересчета центров масс кластеров;&lt;br /&gt;
* соотнесения каждого вектора к одному из кластеров.&lt;br /&gt;
&lt;br /&gt;
Пересчет центра масс кластера заключается в нахождении d-мерного вектора, являющегося средним арифметическим d-мерных векторов, принадлежащих кластеру. Эту операцию необходимо выполнять для каждого из K кластеров.&lt;br /&gt;
&lt;br /&gt;
Для соотнесения вектора к одному из кластеров, необходимо для каждого из N вектора посчитать расстояние до центров масс всех K кластеров. Для нахождения расстояния между двумя d-мерными векторами p и q используется Евклидова метрика: &amp;lt;math&amp;gt;\sqrt{\sum_{k=1}^d (p_k-q_k)^2}&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;
Для вычисления центра массы кластера, содержащего &amp;lt;math&amp;gt;n_i&amp;lt;/math&amp;gt; d-мерных векторов, необходимо:&lt;br /&gt;
* &amp;lt;math&amp;gt;n_i * (d - 1)&amp;lt;/math&amp;gt; операций сложения&lt;br /&gt;
* &amp;lt;math&amp;gt;d&amp;lt;/math&amp;gt; операций деления&lt;br /&gt;
&lt;br /&gt;
Для определения центров масс всех k кластеров требуется:&lt;br /&gt;
* &amp;lt;math&amp;gt;n * (d - 1)&amp;lt;/math&amp;gt; операций сложения&lt;br /&gt;
* &amp;lt;math&amp;gt;k * d&amp;lt;/math&amp;gt; операций деления&lt;br /&gt;
&lt;br /&gt;
Для определения расстояния между двумя d-мерными векторами, требуется:&lt;br /&gt;
* &amp;lt;math&amp;gt;d&amp;lt;/math&amp;gt; операций вычитания&lt;br /&gt;
* &amp;lt;math&amp;gt;d&amp;lt;/math&amp;gt; операций умножения&lt;br /&gt;
* &amp;lt;math&amp;gt;d - 1&amp;lt;/math&amp;gt; операций сложения&lt;br /&gt;
&lt;br /&gt;
Для определения кластера для n d-мерного векторов, необходимо:&lt;br /&gt;
* &amp;lt;math&amp;gt;n * k * d&amp;lt;/math&amp;gt; операций вычитания&lt;br /&gt;
* &amp;lt;math&amp;gt;n * k * d&amp;lt;/math&amp;gt; операций умножения&lt;br /&gt;
* &amp;lt;math&amp;gt;n * k * (d - 1)&amp;lt;/math&amp;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; операций умножения/деления&lt;br /&gt;
&lt;br /&gt;
Сложность всего алгоритма, состоящего из m итераций: &amp;lt;math&amp;gt;O(m * n * 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;
=== Свойства алгоритма ===&lt;br /&gt;
&lt;br /&gt;
== ЧАСТЬ. Программная реализация алгоритма ==&lt;br /&gt;
&lt;br /&gt;
=== Особенности реализации последовательного алгоритма ===&lt;br /&gt;
&lt;br /&gt;
=== Локальность данных и вычислений ===&lt;br /&gt;
&lt;br /&gt;
=== Возможные способы и особенности параллельной реализации алгоритма ===&lt;br /&gt;
&lt;br /&gt;
=== Масштабируемость алгоритма и его реализации ===&lt;br /&gt;
&lt;br /&gt;
=== Динамические характеристики и эффективность реализации алгоритма ===&lt;br /&gt;
&lt;br /&gt;
=== Выводы для классов архитектур ===&lt;br /&gt;
&lt;br /&gt;
=== Существующие реализации алгоритма ===&lt;br /&gt;
&lt;br /&gt;
== Литература ==&lt;br /&gt;
&amp;lt;references \&amp;gt;&lt;/div&gt;</summary>
		<author><name>Parkhomenko</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:Parkhomenko/%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=4391</id>
		<title>Участник:Parkhomenko/Алгоритм 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:Parkhomenko/%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=4391"/>
		<updated>2016-09-29T14:10:35Z</updated>

		<summary type="html">&lt;p&gt;Parkhomenko: /* Вычислительное ядро алгоритма */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{algorithm&lt;br /&gt;
| name              = Алгоритм k средних&lt;br /&gt;
| serial_complexity = &amp;lt;math&amp;gt;O(m*n*k*d)&amp;lt;/math&amp;gt;&lt;br /&gt;
| input_data        = &amp;lt;math&amp;gt;&amp;lt;/math&amp;gt;&lt;br /&gt;
| output_data       = &amp;lt;math&amp;gt;&amp;lt;/math&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
Основные авторы описания: [[Участник:Parkhomenko|П.А.Пархоменко]], [[Участник:Ivan.mashonskiy|И.Д.Машонский]]&lt;br /&gt;
== ЧАСТЬ. Свойства и структура алгоритмов ==&lt;br /&gt;
&lt;br /&gt;
=== Общее описание алгоритма ===&lt;br /&gt;
Алгоритм k средних (англ. k-means) - один из алгоритмов машинного обучения, решающий задачу кластеризации. Он был изобретен в середине 1950-х математиком Гуго Штейнгаузом&amp;lt;ref&amp;gt;Steinhaus H. (1956). Sur la division des corps materiels en parties. Bull. Acad. Polon. Sci., C1. III vol IV: 801—804.&amp;lt;/ref&amp;gt; и Стюартом Ллойдом&amp;lt;ref&amp;gt;Lloyd S. (1957). Least square quantization in PCM’s. Bell Telephone Laboratories Paper.&amp;lt;/ref&amp;gt;. Алгоритм стал особо популярным после публикации Маккуина&amp;lt;ref&amp;gt;MacQueen J. (1967). Some methods for classification and analysis of multivariate observations. In Proc. 5th Berkeley Symp. on Math. Statistics and Probability, pages 281—297.&amp;lt;/ref&amp;gt;, в которой впервые был использован термин “k-means”.&lt;br /&gt;
&lt;br /&gt;
Задача алгоритма кластеризации заключается в разбиении N объектов (d-мерных векторов) на K групп (кластеров). Каждый вектор может принадлежать только одному кластеру. Количество кластеров K фиксировано, оно задается в качестве параметра.&lt;br /&gt;
&lt;br /&gt;
K-means является итерационным алгоритмом, разновидностью EM-алгоритма. Основная идея работы алгоритма заключается в проведении некоторого количества итераций, на каждой из которых происходит пересчет центра масс для каждого кластера, полученного на предыдущей итерации. После этого векторы перераспределяются по кластерам: вектор относится к тому кластеру, расстояние до центра масс которого минимально. Алгоритм завершает работу в том случае, если на очередной итерации центры масс кластеров не изменились.&lt;br /&gt;
&lt;br /&gt;
=== Математическое описание алгоритма ===&lt;br /&gt;
&lt;br /&gt;
=== Вычислительное ядро алгоритма ===&lt;br /&gt;
Вычислительное ядро последовательного алгоритма k-means состоит из двух операций, повторяющихся на каждой итерации алгоритма:&lt;br /&gt;
* пересчета центров масс кластеров;&lt;br /&gt;
* соотнесения каждого вектора к одному из кластеров.&lt;br /&gt;
&lt;br /&gt;
Пересчет центра масс кластера заключается в нахождении d-мерного вектора, являющегося средним арифметическим d-мерных векторов, принадлежащих кластеру. Эту операцию необходимо выполнять для каждого из K кластеров.&lt;br /&gt;
&lt;br /&gt;
Для соотнесения вектора к одному из кластеров, необходимо для каждого из N вектора посчитать расстояние до центров масс всех K кластеров. Для нахождения расстояния между двумя d-мерными векторами p и q используется Евклидова метрика: &amp;lt;math&amp;gt;\sqrt{\sum_{k=1}^d (p_k-q_k)^2}&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;
&lt;br /&gt;
=== Ресурс параллелизма алгоритма ===&lt;br /&gt;
&lt;br /&gt;
=== Входные и выходные данные алгоритма ===&lt;br /&gt;
&lt;br /&gt;
=== Свойства алгоритма ===&lt;br /&gt;
&lt;br /&gt;
== ЧАСТЬ. Программная реализация алгоритма ==&lt;br /&gt;
&lt;br /&gt;
=== Особенности реализации последовательного алгоритма ===&lt;br /&gt;
&lt;br /&gt;
=== Локальность данных и вычислений ===&lt;br /&gt;
&lt;br /&gt;
=== Возможные способы и особенности параллельной реализации алгоритма ===&lt;br /&gt;
&lt;br /&gt;
=== Масштабируемость алгоритма и его реализации ===&lt;br /&gt;
&lt;br /&gt;
=== Динамические характеристики и эффективность реализации алгоритма ===&lt;br /&gt;
&lt;br /&gt;
=== Выводы для классов архитектур ===&lt;br /&gt;
&lt;br /&gt;
=== Существующие реализации алгоритма ===&lt;br /&gt;
&lt;br /&gt;
== Литература ==&lt;br /&gt;
&amp;lt;references \&amp;gt;&lt;/div&gt;</summary>
		<author><name>Parkhomenko</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:Parkhomenko/%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=4390</id>
		<title>Участник:Parkhomenko/Алгоритм 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:Parkhomenko/%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=4390"/>
		<updated>2016-09-29T13:34:20Z</updated>

		<summary type="html">&lt;p&gt;Parkhomenko: /* Общее описание алгоритма */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{algorithm&lt;br /&gt;
| name              = Алгоритм k средних&lt;br /&gt;
| serial_complexity = &amp;lt;math&amp;gt;O(m*n*k*d)&amp;lt;/math&amp;gt;&lt;br /&gt;
| input_data        = &amp;lt;math&amp;gt;&amp;lt;/math&amp;gt;&lt;br /&gt;
| output_data       = &amp;lt;math&amp;gt;&amp;lt;/math&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
Основные авторы описания: [[Участник:Parkhomenko|П.А.Пархоменко]], [[Участник:Ivan.mashonskiy|И.Д.Машонский]]&lt;br /&gt;
== ЧАСТЬ. Свойства и структура алгоритмов ==&lt;br /&gt;
&lt;br /&gt;
=== Общее описание алгоритма ===&lt;br /&gt;
Алгоритм k средних (англ. k-means) - один из алгоритмов машинного обучения, решающий задачу кластеризации. Он был изобретен в середине 1950-х математиком Гуго Штейнгаузом&amp;lt;ref&amp;gt;Steinhaus H. (1956). Sur la division des corps materiels en parties. Bull. Acad. Polon. Sci., C1. III vol IV: 801—804.&amp;lt;/ref&amp;gt; и Стюартом Ллойдом&amp;lt;ref&amp;gt;Lloyd S. (1957). Least square quantization in PCM’s. Bell Telephone Laboratories Paper.&amp;lt;/ref&amp;gt;. Алгоритм стал особо популярным после публикации Маккуина&amp;lt;ref&amp;gt;MacQueen J. (1967). Some methods for classification and analysis of multivariate observations. In Proc. 5th Berkeley Symp. on Math. Statistics and Probability, pages 281—297.&amp;lt;/ref&amp;gt;, в которой впервые был использован термин “k-means”.&lt;br /&gt;
&lt;br /&gt;
Задача алгоритма кластеризации заключается в разбиении N объектов (d-мерных векторов) на K групп (кластеров). Каждый вектор может принадлежать только одному кластеру. Количество кластеров K фиксировано, оно задается в качестве параметра.&lt;br /&gt;
&lt;br /&gt;
K-means является итерационным алгоритмом, разновидностью EM-алгоритма. Основная идея работы алгоритма заключается в проведении некоторого количества итераций, на каждой из которых происходит пересчет центра масс для каждого кластера, полученного на предыдущей итерации. После этого векторы перераспределяются по кластерам: вектор относится к тому кластеру, расстояние до центра масс которого минимально. Алгоритм завершает работу в том случае, если на очередной итерации центры масс кластеров не изменились.&lt;br /&gt;
&lt;br /&gt;
=== Математическое описание алгоритма ===&lt;br /&gt;
&lt;br /&gt;
=== Вычислительное ядро алгоритма ===&lt;br /&gt;
&lt;br /&gt;
=== Макроструктура алгоритма ===&lt;br /&gt;
&lt;br /&gt;
=== Схема реализации последовательного алгоритма ===&lt;br /&gt;
&lt;br /&gt;
=== Последовательная сложность алгоритма ===&lt;br /&gt;
&lt;br /&gt;
=== Информационный граф ===&lt;br /&gt;
&lt;br /&gt;
=== Ресурс параллелизма алгоритма ===&lt;br /&gt;
&lt;br /&gt;
=== Входные и выходные данные алгоритма ===&lt;br /&gt;
&lt;br /&gt;
=== Свойства алгоритма ===&lt;br /&gt;
&lt;br /&gt;
== ЧАСТЬ. Программная реализация алгоритма ==&lt;br /&gt;
&lt;br /&gt;
=== Особенности реализации последовательного алгоритма ===&lt;br /&gt;
&lt;br /&gt;
=== Локальность данных и вычислений ===&lt;br /&gt;
&lt;br /&gt;
=== Возможные способы и особенности параллельной реализации алгоритма ===&lt;br /&gt;
&lt;br /&gt;
=== Масштабируемость алгоритма и его реализации ===&lt;br /&gt;
&lt;br /&gt;
=== Динамические характеристики и эффективность реализации алгоритма ===&lt;br /&gt;
&lt;br /&gt;
=== Выводы для классов архитектур ===&lt;br /&gt;
&lt;br /&gt;
=== Существующие реализации алгоритма ===&lt;br /&gt;
&lt;br /&gt;
== Литература ==&lt;br /&gt;
&amp;lt;references \&amp;gt;&lt;/div&gt;</summary>
		<author><name>Parkhomenko</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:Parkhomenko/%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=4389</id>
		<title>Участник:Parkhomenko/Алгоритм 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:Parkhomenko/%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=4389"/>
		<updated>2016-09-29T13:23:29Z</updated>

		<summary type="html">&lt;p&gt;Parkhomenko: Новая страница: «{{algorithm | name              = Алгоритм k средних | serial_complexity = &amp;lt;math&amp;gt;O(m*n*k*d)&amp;lt;/math&amp;gt; | input_data        = &amp;lt;math&amp;gt;&amp;lt;/math&amp;gt; | output_dat…»&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{algorithm&lt;br /&gt;
| name              = Алгоритм k средних&lt;br /&gt;
| serial_complexity = &amp;lt;math&amp;gt;O(m*n*k*d)&amp;lt;/math&amp;gt;&lt;br /&gt;
| input_data        = &amp;lt;math&amp;gt;&amp;lt;/math&amp;gt;&lt;br /&gt;
| output_data       = &amp;lt;math&amp;gt;&amp;lt;/math&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
Основные авторы описания: [[Участник:Parkhomenko|П.А.Пархоменко]], [[Участник:Ivan.mashonskiy|И.Д.Машонский]]&lt;br /&gt;
== ЧАСТЬ. Свойства и структура алгоритмов ==&lt;br /&gt;
&lt;br /&gt;
=== Общее описание алгоритма ===&lt;br /&gt;
&lt;br /&gt;
=== Математическое описание алгоритма ===&lt;br /&gt;
&lt;br /&gt;
=== Вычислительное ядро алгоритма ===&lt;br /&gt;
&lt;br /&gt;
=== Макроструктура алгоритма ===&lt;br /&gt;
&lt;br /&gt;
=== Схема реализации последовательного алгоритма ===&lt;br /&gt;
&lt;br /&gt;
=== Последовательная сложность алгоритма ===&lt;br /&gt;
&lt;br /&gt;
=== Информационный граф ===&lt;br /&gt;
&lt;br /&gt;
=== Ресурс параллелизма алгоритма ===&lt;br /&gt;
&lt;br /&gt;
=== Входные и выходные данные алгоритма ===&lt;br /&gt;
&lt;br /&gt;
=== Свойства алгоритма ===&lt;br /&gt;
&lt;br /&gt;
== ЧАСТЬ. Программная реализация алгоритма ==&lt;br /&gt;
&lt;br /&gt;
=== Особенности реализации последовательного алгоритма ===&lt;br /&gt;
&lt;br /&gt;
=== Локальность данных и вычислений ===&lt;br /&gt;
&lt;br /&gt;
=== Возможные способы и особенности параллельной реализации алгоритма ===&lt;br /&gt;
&lt;br /&gt;
=== Масштабируемость алгоритма и его реализации ===&lt;br /&gt;
&lt;br /&gt;
=== Динамические характеристики и эффективность реализации алгоритма ===&lt;br /&gt;
&lt;br /&gt;
=== Выводы для классов архитектур ===&lt;br /&gt;
&lt;br /&gt;
=== Существующие реализации алгоритма ===&lt;br /&gt;
&lt;br /&gt;
== Литература ==&lt;br /&gt;
&amp;lt;references \&amp;gt;&lt;/div&gt;</summary>
		<author><name>Parkhomenko</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:Parkhomenko&amp;diff=4387</id>
		<title>Участник:Parkhomenko</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:Parkhomenko&amp;diff=4387"/>
		<updated>2016-09-29T12:56:59Z</updated>

		<summary type="html">&lt;p&gt;Parkhomenko: Новая страница: «Пархоменко Павел Андреевич, СП ВМК МГУ, 628 группа»&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Пархоменко Павел Андреевич, СП ВМК МГУ, 628 группа&lt;/div&gt;</summary>
		<author><name>Parkhomenko</name></author>
	</entry>
</feed>